Skip to content

Commit

Permalink
Merge pull request #483 from rabbitholegg/matthew/boost-4267-implemen…
Browse files Browse the repository at this point in the history
…t-getexternalurl-pods

feat(pods): implement `getExternalUrl` function
  • Loading branch information
mmackz authored Jul 16, 2024
2 parents 3f68afb + e1af8e1 commit 2e23def
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/light-rabbits-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rabbitholegg/questdk-plugin-pods": minor
---

implement getExternalUrl for pods
54 changes: 52 additions & 2 deletions packages/pods/src/Pods.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ 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'
import { ZORA_DEPLOYER_ADDRESS } from './contract-addresses'

describe('Given the pods plugin', () => {
describe('When handling the mint', () => {
Expand Down Expand Up @@ -201,3 +202,52 @@ describe('simulateMint function', () => {
expect(request.value).toBe(value)
})
})

describe('getExternalUrl function', () => {
test('should return correct url for mint w/tokenId and referral', 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/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,
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')
})
})
35 changes: 34 additions & 1 deletion packages/pods/src/Pods.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -180,6 +181,38 @@ export const getFees = async (
}
}

export const getExternalUrl = async (
params: MintActionParams,
): Promise<string> => {
const { chainId, contractAddress, tokenId, referral } = params

try {
const client = createPublicClient({
chain: chainIdToViemChain(chainId),
transport: http(),
}) as PublicClient

const uri = await getUri(client, contractAddress, tokenId)
const cid = uri.split('/').slice(2).join('/')

const { data } = await axios.get(`https://arweave.net/${cid}`)

// different properties depending on uri function. One of these will be defined
const baseUrl = data.external_link ?? data.external_url

return `${baseUrl}?referrer=${referral ?? ZORA_DEPLOYER_ADDRESS}`
} 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<Address[]> => {
Expand Down
5 changes: 4 additions & 1 deletion packages/pods/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import {
} from '@rabbitholegg/questdk-plugin-utils'

import {
getExternalUrl,
getFees,
getMintIntent,
getProjectFees,
getSupportedChainIds,
getSupportedTokenAddresses,
mint,
simulateMint,
} from './Pods.js'
} from './Pods'

export const Pods: IActionPlugin = {
pluginId: 'pods',
Expand All @@ -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,
Expand Down
37 changes: 37 additions & 0 deletions packages/pods/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,40 @@ export async function getLatestTokenId(
return 1
}
}

export async function getUri(
client: PublicClient,
contractAddress: Address,
tokenId?: number,
): Promise<string> {
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
}

0 comments on commit 2e23def

Please sign in to comment.