diff --git a/.changeset/nine-coats-remember.md b/.changeset/nine-coats-remember.md new file mode 100644 index 000000000..9a0dced7f --- /dev/null +++ b/.changeset/nine-coats-remember.md @@ -0,0 +1,5 @@ +--- +"@rabbitholegg/questdk-plugin-zora": minor +--- + +use referral param in validation and simulations diff --git a/packages/zora/src/Zora.test.ts b/packages/zora/src/Zora.test.ts index f625c295e..da228ff7b 100644 --- a/packages/zora/src/Zora.test.ts +++ b/packages/zora/src/Zora.test.ts @@ -264,6 +264,7 @@ describe('Given the getMintIntent function', () => { contractAddress: CONTRACT_ADDRESS, amount: BigInt('10'), recipient: RECIPIENT_ADDRESS, + referral: ZORA_DEPLOYER_ADDRESS, } const result = await getMintIntent(mint) @@ -278,10 +279,10 @@ describe('Given the getMintIntent function', () => { test('returns a TransactionRequest with correct properties when tokenId is null', async () => { const mint: MintIntentParams = { chainId: 1, - contractAddress: CONTRACT_ADDRESS, amount: BigInt('10'), recipient: RECIPIENT_ADDRESS, + referral: ZORA_DEPLOYER_ADDRESS, } const result = await getMintIntent(mint) @@ -406,6 +407,7 @@ describe('simulateMint function', () => { tokenId: 10, amount: BigInt(1), recipient: '0xf70da97812CB96acDF810712Aa562db8dfA3dbEF', + referral: ZORA_DEPLOYER_ADDRESS, } const value = parseEther('0.000777') const account = '0xf70da97812CB96acDF810712Aa562db8dfA3dbEF' @@ -424,7 +426,7 @@ describe('simulateMint function', () => { _account: Address, ) => ({ request: { - address: '0x8704c8b68e577d54be3c16341fbd31bac47c7471', + address: '0x553f0a63858a9000212cdbd0c40cf7861b692dc0', value: parseEther('0.000777'), }, }), @@ -433,10 +435,11 @@ describe('simulateMint function', () => { const mint: MintIntentParams = { chainId: Chains.BLAST, - contractAddress: '0x8704c8b68e577d54be3c16341fbd31bac47c7471', + contractAddress: '0x553f0a63858a9000212cdbd0c40cf7861b692dc0', tokenId: 1, amount: BigInt(1), recipient: '0xf70da97812CB96acDF810712Aa562db8dfA3dbEF', + referral: ZORA_DEPLOYER_ADDRESS, } const value = parseEther('0.000777') const account = '0xf70da97812CB96acDF810712Aa562db8dfA3dbEF' @@ -454,6 +457,7 @@ describe('simulateMint function', () => { tokenId: 1, amount: BigInt(1), recipient: '0xf70da97812CB96acDF810712Aa562db8dfA3dbEF', + referral: ZORA_DEPLOYER_ADDRESS, } const value = parseEther('0.000777') const account = '0xf70da97812CB96acDF810712Aa562db8dfA3dbEF' diff --git a/packages/zora/src/Zora.ts b/packages/zora/src/Zora.ts index c30ea5d6f..0e6703273 100644 --- a/packages/zora/src/Zora.ts +++ b/packages/zora/src/Zora.ts @@ -93,7 +93,8 @@ export const create = async ( export const mint = async ( mint: MintActionParams, ): Promise => { - const { chainId, contractAddress, tokenId, amount, recipient } = mint + const { chainId, contractAddress, tokenId, amount, recipient, referral } = + mint const universalMinter = zoraUniversalMinterAddress[ @@ -126,6 +127,16 @@ export const mint = async ( tokenId, }) } + if (referral) { + andArray1155.push({ + $or: [ + { mintReferral: referral }, + { + rewardsRecipients: [referral], + }, + ], + }) + } const ERC721_FILTER_ABSTRACT = { $abiAbstract: ZORA_MINTER_ABI_721, @@ -177,7 +188,8 @@ export const mint = async ( export const getMintIntent = async ( mint: MintIntentParams, ): Promise => { - const { chainId, contractAddress, tokenId, amount, recipient } = mint + const { chainId, contractAddress, tokenId, amount, recipient, referral } = + mint let data let fixedPriceSaleStratAddress = FIXED_PRICE_SALE_STRATS[chainId] @@ -197,7 +209,7 @@ export const getMintIntent = async ( fixedPriceSaleStratAddress, tokenId, amount, - [ZORA_DEPLOYER_ADDRESS], + [referral ?? ZORA_DEPLOYER_ADDRESS], pad(recipient), ] // Assume it's an 1155 mint @@ -228,7 +240,8 @@ export const simulateMint = async ( account?: Address, client?: PublicClient, ): Promise => { - const { chainId, contractAddress, tokenId, amount, recipient } = mint + const { chainId, contractAddress, tokenId, amount, recipient, referral } = + mint const _client = client ?? createPublicClient({ @@ -260,7 +273,7 @@ export const simulateMint = async ( )}` // Check if the implementation contracts bytecode contains valid function selectors - const bytecode = await _client.getBytecode({ address: implementationAddress }) + const bytecode = await _client.getCode({ address: implementationAddress }) const containsSelector = FUNCTION_SELECTORS.some((selector) => bytecode?.includes(selector), ) @@ -286,7 +299,7 @@ export const simulateMint = async ( fixedPriceSaleStratAddress, _tokenId, amount, - [ZORA_DEPLOYER_ADDRESS], + [referral ?? ZORA_DEPLOYER_ADDRESS], pad(recipient), ] const result = await _client.simulateContract({ diff --git a/packages/zora/src/test-setup.ts b/packages/zora/src/test-setup.ts index 05ea4c96c..13e58a31f 100644 --- a/packages/zora/src/test-setup.ts +++ b/packages/zora/src/test-setup.ts @@ -3,6 +3,7 @@ import { CREATE_COLLECTION_BASE, CREATE_COLLECTION_ZORA, LAYER_ZERO_MINT, + MINT, MINT_BATCH_WITHOUT_FEES, MINT_WITH_REWARDS, MINT_WITH_REWARDS_1155, @@ -16,6 +17,7 @@ export const passingTestCasesMint = [ createTestCase(MINT_WITH_REWARDS_1155, 'Minting with rewards 1155'), createTestCase(MINT_BATCH_WITHOUT_FEES, 'When using the batch mint function'), createTestCase(BATCH_MINT_ARB, 'when using batch mint function on arbitrum'), + createTestCase(MINT, 'when using mint function'), createTestCase(MINT_WITH_REWARDS, 'when contractAddress is checksummed', { contractAddress: getAddress(MINT_WITH_REWARDS.params.contractAddress), }), @@ -61,6 +63,12 @@ export const failingTestCasesMint = [ }, ), createTestCase(ZERO_QUANTITY, 'when quantity minted is 0'), + createTestCase(MINT_WITH_REWARDS, 'when referral is incorrect', { + referral: '0xDEAD0940159fB3368F5b06b34212C0cDF4e2C032', + }), + createTestCase(MINT, 'when referral is incorrect', { + referral: '0xDEAD0940159fB3368F5b06b34212C0cDF4e2C032', + }), ] export const passingTestCasesCreate = [ diff --git a/packages/zora/src/test-transactions.ts b/packages/zora/src/test-transactions.ts index 56f7e9043..70d16626c 100644 --- a/packages/zora/src/test-transactions.ts +++ b/packages/zora/src/test-transactions.ts @@ -3,6 +3,7 @@ import type { CreateActionParams, } from '@rabbitholegg/questdk' import { Chains, type TestParams } from '@rabbitholegg/questdk-plugin-utils' +import { zeroAddress } from 'viem' export const BASIC_PURCHASE: TestParams = { transaction: { @@ -21,6 +22,25 @@ export const BASIC_PURCHASE: TestParams = { }, } +export const MINT: TestParams = { + transaction: { + chainId: 7777777, // Zora + from: '0xeE520B72e4772E9bcb29a7B5940ACeC3d82AC9B1', + to: '0x8057c6bf3bc3adfc20b0deaf1898d5294d9701e8', + hash: '0x6e4e91536b59f1027913a77e2bb93ee362de64f95a41467c642ab8b1c0182804', + input: + '0x359f130200000000000000000000000004e2516a2c207e84a1839755675dfd8ef6302f0a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000ee520b72e4772e9bcb29a7b5940acec3d82ac9b1', + value: '777000000000000', // 0.000777 ETH + }, + params: { + chainId: Chains.ZORA, + contractAddress: '0x8057C6Bf3bc3aDfc20B0dEaf1898d5294d9701e8', + amount: '1', + tokenId: 1, + referral: zeroAddress, + }, +} + export const MINT_WITH_REWARDS: TestParams = { transaction: { chainId: 1, // Ethereum @@ -53,6 +73,7 @@ export const MINT_WITH_REWARDS_1155: TestParams = { contractAddress: '0x4c0c2dd31d2661e8bcec60a42e803dcc6f81baad', amount: '1', tokenId: 25, + referral: zeroAddress, }, } @@ -71,6 +92,7 @@ export const MINT_BATCH_WITHOUT_FEES: TestParams = { contractAddress: '0xe538598941e4a25f471aef9b1b5dffd6ee0fda54', amount: '1', tokenId: 2, + referral: zeroAddress, }, } @@ -98,7 +120,7 @@ export const EXPECTED_ENCODED_DATA_1155 = export const BATCH_MINT_ARB: TestParams = { transaction: { - chainId: 42161, // Optimism + chainId: 42161, // Arbitrum from: '0x1671b592610fb7427ed788b66fa3e9217ff41047', hash: '0x4c0d898b6f3864332e3e47a3924cad33491b8df0a05590d13175823ee62ef07c', input: diff --git a/packages/zora/src/types.ts b/packages/zora/src/types.ts index 29155187e..1b10f5acf 100644 --- a/packages/zora/src/types.ts +++ b/packages/zora/src/types.ts @@ -1,8 +1,9 @@ -import { z } from 'zod' import { type FilterOperator, EthAddressSchema, } from '@rabbitholegg/questdk-plugin-utils' +import { type Address } from 'viem' +import { z } from 'zod' export const PremintResponseSchema = z.array( z.object({ @@ -49,3 +50,6 @@ export type AndArrayItem = | { quantity: string | number | bigint | FilterOperator } | RecipientCondition | { tokenId: string | number } + | { mintReferral: Address } + | { rewardsRecipients: Address[] } + | { $or: AndArrayItem[] }