From 931fed327bdd4c14348ac56dc8d337704ac9e631 Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:17:21 -0700 Subject: [PATCH 01/10] feat(pods): implement getUri function in utils --- packages/pods/src/utils.ts | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/packages/pods/src/utils.ts b/packages/pods/src/utils.ts index 9c1631c8c..d12e6b079 100644 --- a/packages/pods/src/utils.ts +++ b/packages/pods/src/utils.ts @@ -35,3 +35,40 @@ export async function getLatestTokenId( return 1 } } + +export async function getUri( + client: PublicClient, + contractAddress: Address, + tokenId?: number, +): Promise { + if (tokenId == null) { + return (await client.readContract({ + address: contractAddress, + abi: [ + { + inputs: [], + name: 'contractURI', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + ], + functionName: 'contractURI', + })) as string + } + + return (await client.readContract({ + address: contractAddress, + abi: [ + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'uri', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + ], + functionName: 'uri', + args: [BigInt(tokenId)], + })) as string +} From 69de56d98ffcb541889517292c743667d07317ee Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:17:44 -0700 Subject: [PATCH 02/10] test(pods): add tests for getExternalUrl function --- packages/pods/src/Pods.test.ts | 37 ++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/pods/src/Pods.test.ts b/packages/pods/src/Pods.test.ts index 78832edac..b74b830fc 100644 --- a/packages/pods/src/Pods.test.ts +++ b/packages/pods/src/Pods.test.ts @@ -4,9 +4,9 @@ import { type MintIntentParams, } from '@rabbitholegg/questdk-plugin-utils' import { apply } from '@rabbitholegg/questdk' -import { type Address, parseEther } from 'viem' +import { type Address, parseEther, getAddress, zeroAddress } from 'viem' import { describe, expect, test, vi } from 'vitest' -import { getMintIntent, mint } from './Pods' +import { getExternalUrl, getMintIntent, mint } from './Pods' import { failingTestCases, passingTestCases } from './test-setup' import { EXPECTED_ENCODED_DATA_1155 } from './test-transactions' @@ -201,3 +201,36 @@ describe('simulateMint function', () => { expect(request.value).toBe(value) }) }) + +describe('getExternalUrl function', () => { + test('should return correct url for mint w/tokenId', async () => { + const params = { + chainId: Chains.BASE, + contractAddress: getAddress('0x7e0b40af1d6f26f2141b90170c513e57b5edd74e'), + tokenId: 21, + referral: getAddress('0x1234567890123456789012345678901234567890'), + } + const result = await getExternalUrl(params) + expect(result).toBe('https://pods.media/mint-podcast/why-social-needs-a-layer-2-ft-ryan-li-of-cyber?referrer=0x1234567890123456789012345678901234567890') + }) + + test('should return correct url for mint w/out tokenId', async () => { + const params = { + chainId: Chains.BASE, + contractAddress: getAddress('0x7e0b40af1d6f26f2141b90170c513e57b5edd74e'), + referral: getAddress('0x1234567890123456789012345678901234567890'), + } + const result = await getExternalUrl(params) + expect(result).toBe('https://pods.media/mint-podcast?referrer=0x1234567890123456789012345678901234567890') + }) + + test('should return fallback url if error occurs', async () => { + const params = { + chainId: Chains.BASE, + contractAddress: zeroAddress, + referral: getAddress('0x1234567890123456789012345678901234567890'), + } + const result = await getExternalUrl(params) + expect(result).toBe('https://pods.media') + }) +}) From 965f598e0c40742cef2eeeacfcce1f8a2627ac03 Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:18:08 -0700 Subject: [PATCH 03/10] feat(pods): implement getExternalUrl function --- packages/pods/src/Pods.ts | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/pods/src/Pods.ts b/packages/pods/src/Pods.ts index aba53407d..1af4eab66 100644 --- a/packages/pods/src/Pods.ts +++ b/packages/pods/src/Pods.ts @@ -1,10 +1,11 @@ +import axios from 'axios' import { FEES_ABI, ZORA_MINTER_ABI_1155 } from './abi' import { CHAIN_ID_ARRAY } from './chain-ids' import { FIXED_PRICE_SALE_STRATS, ZORA_DEPLOYER_ADDRESS, } from './contract-addresses' -import { type AndArrayItem, getLatestTokenId } from './utils' +import { type AndArrayItem, getLatestTokenId, getUri } from './utils' import { type MintActionParams, type TransactionFilter, @@ -180,6 +181,39 @@ export const getFees = async ( } } +export const getExternalUrl = async ( + params: MintActionParams, +): Promise => { + const { chainId, contractAddress, tokenId, referral } = params + + try { + const client = createPublicClient({ + chain: chainIdToViemChain(chainId), + transport: http(), + }) as PublicClient + + const uri = await getUri(client, contractAddress, tokenId) + console.log('uri', uri) + const cid = uri.split('/').slice(2).join('/') + + const { data } = await axios.get(`https://arweave.net/${cid}`) + + // different properties depending uri function. At least one of these will be defined + const baseUrl = data.external_link ?? data.external_url + + return referral ? `${baseUrl}?referrer=${referral}` : baseUrl + } catch (error) { + console.error('an error occurred fetching data from the contract') + if (error instanceof Error) { + console.error(error.message) + } else { + console.error(error) + } + // fallback to default pods url + return 'https://pods.media' + } +} + export const getSupportedTokenAddresses = async ( _chainId: number, ): Promise => { From 542a2ab909019fc1052eb7b33e12ba2893716d62 Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:19:04 -0700 Subject: [PATCH 04/10] feat(pods): export getExternalUrl from plugin --- packages/pods/src/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/pods/src/index.ts b/packages/pods/src/index.ts index 167165fab..f1ba85a0f 100644 --- a/packages/pods/src/index.ts +++ b/packages/pods/src/index.ts @@ -6,6 +6,7 @@ import { } from '@rabbitholegg/questdk-plugin-utils' import { + getExternalUrl, getFees, getMintIntent, getProjectFees, @@ -13,7 +14,7 @@ import { getSupportedTokenAddresses, mint, simulateMint, -} from './Pods.js' +} from './Pods' export const Pods: IActionPlugin = { pluginId: 'pods', @@ -24,6 +25,8 @@ export const Pods: IActionPlugin = { mint, getProjectFees: async (params: ActionParams) => getProjectFees(params as unknown as MintActionParams), + getExternalUrl: async (params: ActionParams) => + getExternalUrl(params as unknown as MintActionParams), getFees: async (params: ActionParams) => getFees(params as unknown as MintActionParams), getMintIntent, From 6a692b75ad1fb0d4eab3fdb80a3bb54abd08f09e Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:19:40 -0700 Subject: [PATCH 05/10] chore: generate changeset --- .changeset/light-rabbits-develop.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/light-rabbits-develop.md diff --git a/.changeset/light-rabbits-develop.md b/.changeset/light-rabbits-develop.md new file mode 100644 index 000000000..e7eeec645 --- /dev/null +++ b/.changeset/light-rabbits-develop.md @@ -0,0 +1,5 @@ +--- +"@rabbitholegg/questdk-plugin-pods": minor +--- + +implement getExternalUrl for pods From 5ce15a958566e69131f15330943ffc98eb8dd4a0 Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:21:14 -0700 Subject: [PATCH 06/10] chore: format --- packages/pods/src/Pods.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pods/src/Pods.test.ts b/packages/pods/src/Pods.test.ts index b74b830fc..2b43c7f78 100644 --- a/packages/pods/src/Pods.test.ts +++ b/packages/pods/src/Pods.test.ts @@ -211,7 +211,9 @@ describe('getExternalUrl function', () => { referral: getAddress('0x1234567890123456789012345678901234567890'), } const result = await getExternalUrl(params) - expect(result).toBe('https://pods.media/mint-podcast/why-social-needs-a-layer-2-ft-ryan-li-of-cyber?referrer=0x1234567890123456789012345678901234567890') + expect(result).toBe( + 'https://pods.media/mint-podcast/why-social-needs-a-layer-2-ft-ryan-li-of-cyber?referrer=0x1234567890123456789012345678901234567890', + ) }) test('should return correct url for mint w/out tokenId', async () => { @@ -221,7 +223,9 @@ describe('getExternalUrl function', () => { referral: getAddress('0x1234567890123456789012345678901234567890'), } const result = await getExternalUrl(params) - expect(result).toBe('https://pods.media/mint-podcast?referrer=0x1234567890123456789012345678901234567890') + expect(result).toBe( + 'https://pods.media/mint-podcast?referrer=0x1234567890123456789012345678901234567890', + ) }) test('should return fallback url if error occurs', async () => { From 90f7620e07180f131ef89194f3e2f91a17f0f6f2 Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:23:07 -0700 Subject: [PATCH 07/10] chore: fix typo --- packages/pods/src/Pods.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pods/src/Pods.ts b/packages/pods/src/Pods.ts index 1af4eab66..94e750663 100644 --- a/packages/pods/src/Pods.ts +++ b/packages/pods/src/Pods.ts @@ -198,7 +198,7 @@ export const getExternalUrl = async ( const { data } = await axios.get(`https://arweave.net/${cid}`) - // different properties depending uri function. At least one of these will be defined + // different properties depending on uri function. At least one of these will be defined const baseUrl = data.external_link ?? data.external_url return referral ? `${baseUrl}?referrer=${referral}` : baseUrl From c97e1f08a67c4e51556928d74a1fd76f74d91a2c Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:23:37 -0700 Subject: [PATCH 08/10] chore: fix typo --- packages/pods/src/Pods.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pods/src/Pods.ts b/packages/pods/src/Pods.ts index 94e750663..811c0c968 100644 --- a/packages/pods/src/Pods.ts +++ b/packages/pods/src/Pods.ts @@ -198,7 +198,7 @@ export const getExternalUrl = async ( const { data } = await axios.get(`https://arweave.net/${cid}`) - // different properties depending on uri function. At least one of these will be defined + // different properties depending on uri function. One of these will be defined const baseUrl = data.external_link ?? data.external_url return referral ? `${baseUrl}?referrer=${referral}` : baseUrl From f318e67837b805874c500ef5d3658fc9b657ee32 Mon Sep 17 00:00:00 2001 From: mmackz Date: Mon, 15 Jul 2024 15:24:12 -0700 Subject: [PATCH 09/10] chore: remove console.log --- packages/pods/src/Pods.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pods/src/Pods.ts b/packages/pods/src/Pods.ts index 811c0c968..345254eea 100644 --- a/packages/pods/src/Pods.ts +++ b/packages/pods/src/Pods.ts @@ -193,7 +193,6 @@ export const getExternalUrl = async ( }) as PublicClient const uri = await getUri(client, contractAddress, tokenId) - console.log('uri', uri) const cid = uri.split('/').slice(2).join('/') const { data } = await axios.get(`https://arweave.net/${cid}`) From 575cc9dc9b59b3eac620c1b4d9147549e126aead Mon Sep 17 00:00:00 2001 From: mmackz Date: Tue, 16 Jul 2024 11:36:16 -0700 Subject: [PATCH 10/10] test(pods): add additional test w/o referral attached --- packages/pods/src/Pods.test.ts | 15 ++++++++++++++- packages/pods/src/Pods.ts | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/pods/src/Pods.test.ts b/packages/pods/src/Pods.test.ts index 2b43c7f78..03509a891 100644 --- a/packages/pods/src/Pods.test.ts +++ b/packages/pods/src/Pods.test.ts @@ -9,6 +9,7 @@ import { describe, expect, test, vi } from 'vitest' import { getExternalUrl, getMintIntent, mint } from './Pods' import { failingTestCases, passingTestCases } from './test-setup' import { EXPECTED_ENCODED_DATA_1155 } from './test-transactions' +import { ZORA_DEPLOYER_ADDRESS } from './contract-addresses' describe('Given the pods plugin', () => { describe('When handling the mint', () => { @@ -203,7 +204,7 @@ describe('simulateMint function', () => { }) describe('getExternalUrl function', () => { - test('should return correct url for mint w/tokenId', async () => { + test('should return correct url for mint w/tokenId and referral', async () => { const params = { chainId: Chains.BASE, contractAddress: getAddress('0x7e0b40af1d6f26f2141b90170c513e57b5edd74e'), @@ -216,6 +217,18 @@ describe('getExternalUrl function', () => { ) }) + test('should return correct url for mint w/tokenId and w/o referral', async () => { + const params = { + chainId: Chains.BASE, + contractAddress: getAddress('0x7e0b40af1d6f26f2141b90170c513e57b5edd74e'), + tokenId: 21, + } + const result = await getExternalUrl(params) + expect(result).toBe( + `https://pods.media/mint-podcast/why-social-needs-a-layer-2-ft-ryan-li-of-cyber?referrer=${ZORA_DEPLOYER_ADDRESS}`, + ) + }) + test('should return correct url for mint w/out tokenId', async () => { const params = { chainId: Chains.BASE, diff --git a/packages/pods/src/Pods.ts b/packages/pods/src/Pods.ts index 345254eea..19240a662 100644 --- a/packages/pods/src/Pods.ts +++ b/packages/pods/src/Pods.ts @@ -200,7 +200,7 @@ export const getExternalUrl = async ( // different properties depending on uri function. One of these will be defined const baseUrl = data.external_link ?? data.external_url - return referral ? `${baseUrl}?referrer=${referral}` : baseUrl + return `${baseUrl}?referrer=${referral ?? ZORA_DEPLOYER_ADDRESS}` } catch (error) { console.error('an error occurred fetching data from the contract') if (error instanceof Error) {