diff --git a/README.md b/README.md index 7e34270..d19a679 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ## What is Mobile Minting? -Mobile Minting unlocks mobile payments for onchain purchases and powers minting in the Floor app. +Mobile Minting unlocks mobile payments for onchain purchases and powers minting in the Rally app (formerly known as Floor!). **📱 Users pay in-app with In-App Purchases** @@ -16,9 +16,9 @@ _Example Mobile Minting user experience._ ## What is this repository? This repository is a **public, contributable collection of Ingestors** that teach Mobile Minting how to support mints from new platforms. -Historically, only Floor could choose what mints users could mint through Floor based on our roadmap, or partnerships, now anyone can build support for any minting platform / product and (provided it meets some safety & reliability checks) it can be included in Mobile Minting. +Historically, only Rally could choose what mints users could mint through Rally based on our roadmap, or partnerships, now anyone can build support for any minting platform / product and (provided it meets some safety & reliability checks) it can be included in Mobile Minting. -This library is included in Floor's platform and executed in a sandboxed environment for indexing mints. +This library is included in Rally's platform and executed in a sandboxed environment for indexing mints.
@@ -68,13 +68,13 @@ Today, Mobile Minting supports the following creator platforms: Base - ✅ + 💥 Failing - ✅ + 💥 Failing - ❌ + 💥 Failing @@ -218,7 +218,7 @@ A MintTemplate is a standard format for expressing the details of a mint. It's u _Mapping of MintTemplate fields to an in-app mint._ -Once you generate a MintTemplate, Floor will do all the additional work to get the mint live: +Once you generate a MintTemplate, Rally will do all the additional work to get the mint live: * Map priceWei to an in-app purchase * Simulate the transaction in multiple scenarios to ensure success @@ -281,7 +281,7 @@ In this example we make a template, relying on `getMintMetadataFromSomewhere()` }); ``` -_Note: You will typically want to implement either +_Note: You will typically want to implement either `createMintForContract` or `createMintTemplateForUrl`, and then call that one from the other._ You can then build the MintTemplate from the builder. @@ -350,7 +350,7 @@ yarn dry-run some-erc-1155-ingestor contract 8453:contractAddress:tokenId ``` # Submitting a Mobile Minting Ingestor -Once you've written a Mobile Minting Ingestor, it needs to be Pull Requested to this repository to be included in the production Floor Mobile Minting ingestion fleet. +Once you've written a Mobile Minting Ingestor, it needs to be Pull Requested to this repository to be included in the production Rally Mobile Minting ingestion fleet. ### Before you submit - [ ] Ensure your generated MintTemplate works 😄 @@ -370,7 +370,7 @@ We're excited to see new platforms supported, so will quickly jump to help! ### Hopes and dreams Mobile Minting started out entirely internal & this is our first experiment in decentralizing it & making it more accessible. -In time, we hope to continue down this path, but for now all ingestors will be reviewed by the Floor engineering team & accepted on the basis of safety, cost & other considerations by Floor. +In time, we hope to continue down this path, but for now all ingestors will be reviewed by the Rally engineering team & accepted on the basis of safety, cost & other considerations by Rally. We hope to see people (other companies!?) emerge for whom Mobile Minting, and a unified standard for expressing onchain mints is useful, and look forward to working with them to continue this mission. diff --git a/package.json b/package.json index 05680ee..86f3913 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@floornfts/mobile-minting", - "version": "1.2.0", + "version": "1.2.3", "repository": "git://github.com/floornfts/mobile-minting.git", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/src/ingestors/highlight/index.ts b/src/ingestors/highlight/index.ts index d9a87c2..46e1715 100644 --- a/src/ingestors/highlight/index.ts +++ b/src/ingestors/highlight/index.ts @@ -15,32 +15,34 @@ const CONTRACT_ADDRESS = '0x8087039152c472Fa74F47398628fF002994056EA'; export class HighlightIngestor implements MintIngestor { async supportsUrl(resources: MintIngestorResources, url: string): Promise { - const id = url.split('/').pop(); - if (!id) { - return false; - } - - const collection = await getHighlightCollectionById(resources, id); - - if (!collection || collection.chainId !== 8453) { - return false; - } - - const urlPattern = /^https:\/\/highlight\.xyz\/mint\/[a-f0-9]{24}$/; - return ( - new URL(url).hostname === 'www.highlight.xyz' || new URL(url).hostname === 'highlight.xyz' || urlPattern.test(url) - ); + return false; + // const id = url.split('/').pop(); + // if (!id) { + // return false; + // } + + // const collection = await getHighlightCollectionById(resources, id); + + // if (!collection || collection.chainId !== 8453) { + // return false; + // } + + // const urlPattern = /^https:\/\/highlight\.xyz\/mint\/[a-f0-9]{24}$/; + // return ( + // new URL(url).hostname === 'www.highlight.xyz' || new URL(url).hostname === 'highlight.xyz' || urlPattern.test(url) + // ); } async supportsContract(resources: MintIngestorResources, contractOptions: MintContractOptions): Promise { - if (contractOptions.chainId !== 8453) { - return false; - } - const collection = await getHighlightCollectionByAddress(resources, contractOptions); - if (!collection) { - return false; - } - return true; + return false; + // if (contractOptions.chainId !== 8453) { + // return false; + // } + // const collection = await getHighlightCollectionByAddress(resources, contractOptions); + // if (!collection) { + // return false; + // } + // return true; } async createMintForContract( @@ -80,7 +82,7 @@ export class HighlightIngestor implements MintIngestor { throw new MintIngestorError(MintIngestionErrorName.MissingRequiredData, 'Error finding creator'); } - const collectionId = collection.highlightCollection?.id; + const collectionId = collection.highlightCollection?.id || collection.id; if (!collectionId) { throw new MintIngestorError(MintIngestionErrorName.MissingRequiredData, 'Collection id not available'); @@ -93,6 +95,8 @@ export class HighlightIngestor implements MintIngestor { imageUrl: creator?.creatorAccountSettings?.displayAvatar, }); + mintBuilder.setMintOutputContract({ chainId: 8453, address: collection.highlightCollection.address }); + const vectorId = await getHighlightVectorId(resources, collectionId); if (!vectorId) { @@ -109,9 +113,10 @@ export class HighlightIngestor implements MintIngestor { chainId: 8453, contractAddress: CONTRACT_ADDRESS, contractMethod: 'vectorMint721', - contractParams: `[${vectorId}, 1, address]`, + contractParams: `[${vectorId}, quantity, address]`, abi: MINT_CONTRACT_ABI, priceWei: totalPriceWei, + supportsQuantity: true, }); const metadata = await getHighlightMetadata(+vectorId, resources.alchemy); diff --git a/src/ingestors/highlight/offchain-metadata.ts b/src/ingestors/highlight/offchain-metadata.ts index 001cac1..2ddccd2 100644 --- a/src/ingestors/highlight/offchain-metadata.ts +++ b/src/ingestors/highlight/offchain-metadata.ts @@ -27,7 +27,6 @@ export const getHighlightCollectionById = async ( marketplaceId accountId address - symbol chainId status baseUri diff --git a/src/ingestors/highlight/types.ts b/src/ingestors/highlight/types.ts index 1265c14..32d9a72 100644 --- a/src/ingestors/highlight/types.ts +++ b/src/ingestors/highlight/types.ts @@ -9,7 +9,7 @@ export type Collection = { symbol: string; chainId: number; status: string; - baseUri: string, + baseUri: string; }; export type CollectionByAddress1 = { @@ -23,8 +23,8 @@ export type CollectionByAddress1 = { symbol: string; description: string; sampleImages: string[]; - creator: string; -} + creator: string; +}; export type CollectionByAddress2 = { chainId: number; @@ -36,7 +36,8 @@ export type CollectionByAddress2 = { owner: string; imageUrl: string; animationUrl: string; - } -} + address: string; + }; +}; -export type CollectionByAddress = CollectionByAddress1 & CollectionByAddress2 +export type CollectionByAddress = CollectionByAddress1 & CollectionByAddress2; diff --git a/src/ingestors/index.ts b/src/ingestors/index.ts index dbabfda..fda2eac 100644 --- a/src/ingestors/index.ts +++ b/src/ingestors/index.ts @@ -15,6 +15,8 @@ export type MintIngestionMap = { }; export const ALL_MINT_INGESTORS: MintIngestionMap = { + 'zora-internal': new ZoraInternalIngestor(), + rodeo: new RodeoIngestor(), 'prohibition-daily': new ProhibitionDailyIngestor(), fxhash: new FxHashIngestor(), manifold: new ManifoldIngestor(), @@ -22,9 +24,7 @@ export const ALL_MINT_INGESTORS: MintIngestionMap = { transient: new TransientIngestor(), highlight: new HighlightIngestor(), foundation: new FoundationIngestor(), - 'coinbase-wallet': new CoinbaseWalletIngestor(), - 'zora-internal': new ZoraInternalIngestor(), - rodeo: new RodeoIngestor(), + 'coinbase-wallet': new CoinbaseWalletIngestor() }; export * from './'; diff --git a/src/ingestors/rodeo/index.ts b/src/ingestors/rodeo/index.ts index 82bd45e..8e84b3e 100644 --- a/src/ingestors/rodeo/index.ts +++ b/src/ingestors/rodeo/index.ts @@ -74,11 +74,13 @@ export class RodeoIngestor implements MintIngestor { mintBuilder.setName(name).setDescription(description).setFeaturedImageUrl(image); const totalPrice = await getRodeoFeeInEth(sale_terms_id, user.address, mintAddress, resources.alchemy); + const tokenIdNum = parseInt(tokenId); mintBuilder.setMintOutputContract({ chainId, address: contractAddress, + tokenId: isNaN(tokenIdNum) ? null : tokenIdNum, }); - + mintBuilder.setCreator({ name: user.name, imageUrl: user.image, @@ -93,6 +95,7 @@ export class RodeoIngestor implements MintIngestor { priceWei: totalPrice, mintFeePerTokenWei: totalPrice, supportsQuantity: true, + tokenId: tokenIdNum }); const startDate = public_sale_start_at ? new Date(public_sale_start_at) : new Date(); diff --git a/src/ingestors/zora-internal/zora-metadata.ts b/src/ingestors/zora-internal/zora-metadata.ts index 58d4b8b..59df4d4 100644 --- a/src/ingestors/zora-internal/zora-metadata.ts +++ b/src/ingestors/zora-internal/zora-metadata.ts @@ -141,13 +141,13 @@ export class ZoraMetadataProvider { const mintFeePerTokenWei = mintPriceWei; if (mintType === 'ZORA_TIMED') { //mint(address mintTo, uint256 quantity, address collection, uint256 tokenId, address mintReferral, string comment) - params = `[address, quantity, "${tokenDetails.collection.address}", tokenId, "${FLOOR_REFERRER_REWARDS_ADDRESS}", "Minted on floor.fun"]`; + params = `[address, quantity, "${tokenDetails.collection.address}", tokenId, "${FLOOR_REFERRER_REWARDS_ADDRESS}", "Minted on rally.xyz"]`; contractAddress = ZORA_TIMED_MINT_STRATEGY_ADDRESS; method = 'mint'; abi = ZORA_TIMED_MINT_ABI; supportsQuantity = true; if (parseInt(mintPriceWei) <= 111000000000000) { - defaultQuantity = 11; + defaultQuantity = 1; mintPriceWei = (BigInt(mintPriceWei) * BigInt(defaultQuantity)).toString(); } } else if (mintType === 'FIXED_PRICE') { diff --git a/test/ingestors/foundation.test.ts b/test/ingestors/foundation.test.ts index 0f35a15..30660f5 100644 --- a/test/ingestors/foundation.test.ts +++ b/test/ingestors/foundation.test.ts @@ -66,7 +66,9 @@ describe('foundation', function () { expect(mintInstructions.contractParams).to.equal( '["0x89E63F58da71E9CD4DA439C3D1194917c67eb869", 1, address, "0x0000000000000000000000000000000000000000"]', ); - expect(mintInstructions.priceWei).to.equal('7700000000000000'); + + // This has now ended and the API returns 0 for the price + expect(mintInstructions.priceWei).to.equal('0'); expect(template.featuredImageUrl).to.equal( 'https://f8n-production-collection-assets.imgix.net/8453/0x89E63F58da71E9CD4DA439C3D1194917c67eb869/pre_reveal/nft.jpg', diff --git a/test/ingestors/highlight.test.ts b/test/ingestors/highlight.test.ts index f5f861f..6a774d2 100644 --- a/test/ingestors/highlight.test.ts +++ b/test/ingestors/highlight.test.ts @@ -7,22 +7,29 @@ import { basicIngestorTests } from '../shared/basic-ingestor-tests'; const resources = mintIngestorResources(); -describe('highlight', function () { - basicIngestorTests(new HighlightIngestor(), resources, { - successUrls: [ - 'https://highlight.xyz/mint/665fa33f07b3436991e55632', - 'https://highlight.xyz/mint/66856628ff8a01fdccc132f4', - ], - failureUrls: [ - 'https://highlight.xyz/mint/66963c500b48236f1acf322b', - 'https://foundation.app/mint/base/the-billows', - ], - successContracts: [ - { chainId: 8453, contractAddress: '0x0E5DDe3De7cf2761d8a81Ee68F48410425e2dBbA' }, - { chainId: 8453, contractAddress: '0xBE96B2572CA0F1ac8ec6323Bc9037AffD270bA7F' }, - ], - failureContracts: [{ chainId: 5000, contractAddress: '0x62F8C536De24ED32611f128f64F6eAbd9b82176c' }], - }); +describe.skip('highlight', function () { + basicIngestorTests( + new HighlightIngestor(), + resources, + { + successUrls: [ + 'https://highlight.xyz/mint/66856628ff8a01fdccc132f4', + 'https://highlight.xyz/mint/66d03b0eaae45d4534822482', + ], + failureUrls: [ + 'https://highlight.xyz/mint/66963c500b48236f1acf322b', + 'https://foundation.app/mint/base/the-billows', + ], + successContracts: [ + { chainId: 8453, contractAddress: '0x0E5DDe3De7cf2761d8a81Ee68F48410425e2dBbA' }, + { chainId: 8453, contractAddress: '0x7022a51D648CEB4f4D290a81A0E543979a003e86' }, + ], + failureContracts: [{ chainId: 5000, contractAddress: '0x62F8C536De24ED32611f128f64F6eAbd9b82176c' }], + }, + { + '8453': '0x124F956', + }, + ); it('supportsUrl: Returns false for an unsupported URL', async function () { const ingestor = new HighlightIngestor(); const url = 'https://example.com'; @@ -45,7 +52,7 @@ describe('highlight', function () { it('createMintTemplateForUrl: Returns a mint template for a supported URL', async function () { const ingestor = new HighlightIngestor(); - const url = 'https://highlight.xyz/mint/665fa33f07b3436991e55632'; + const url = 'https://highlight.xyz/mint/66856628ff8a01fdccc132f4'; const resources = mintIngestorResources(); const template = await ingestor.createMintTemplateForUrl(resources, url); @@ -53,32 +60,31 @@ describe('highlight', function () { const builder = new MintTemplateBuilder(template); builder.validateMintTemplate(); - expect(template.name).to.equal('COMBAT MODE by Emily Xie'); - expect(template.description).to.contain( - 'It depicts two creatures in battle, melding the nostalgia of old school video games with the contemporary possibilities of digital illustration.', - ); + expect(template.name).to.equal('Based Fren$'); + expect(template.description).to.contain('3,333 Based Fren$ muy basados'); const mintInstructions = template.mintInstructions as EVMMintInstructions; expect(mintInstructions.contractAddress).to.equal('0x8087039152c472Fa74F47398628fF002994056EA'); + expect(template.mintOutputContract?.address).to.equal('0x0E5DDe3De7cf2761d8a81Ee68F48410425e2dBbA'); expect(mintInstructions.contractMethod).to.equal('vectorMint721'); - expect(mintInstructions.contractParams).to.equal('[866, 1, address]'); - expect(mintInstructions.priceWei).to.equal('2100000000000000'); + expect(mintInstructions.contractParams).to.equal('[1176, quantity, address]'); + expect(mintInstructions.priceWei).to.equal('800000000000000'); expect(template.featuredImageUrl).to.equal( - 'https://img.reservoir.tools/images/v2/base/z9JRSpLYGu7%2BCZoKWtAuANCXTgWBry4OTpgBkNYv7UVX%2FOELQ1B1IQGOoFgJBPmEzWQJa5hKPeiypcjXnSgXVEhZJDeOg9vk5slunBxp8ABMKIlkw3COL8nejLu9cx7f5QrJHJecqNaXIZCHlWY311DY%2F4e9zjeJnyY%2Fvp3J%2FivCSdJShfdu2%2FoCfqed8TvVTrlrElK7Wp8owCwKnZNhaw%3D%3D', + 'https://img.reservoir.tools/images/v2/base/z9JRSpLYGu7%2BCZoKWtAuAI37ZMpGmBWtUpAQDl1tI6DEJRvIrkDVCqzOxkdek%2BfesLtA3sYS0SXZeU4voi8R9rQD1uumcaPxveg8%2B3UfVgFBR82zeA%2FzrfIHHRUbhHMTK4V08qvpcJ5dRYdYVwRvZPTKTulv78c%2FB6vgLUkdfSX0ND53Mjp2wUysnfKmYO5rOIxPwl1ACpM%2BOQDWOOSOzg%3D%3D', ); if (template.creator) { - expect(template.creator.name).to.equal('Emily Xie'); - expect(template.creator.walletAddress).to.equal('0x591a0b1994e8880215b89c5b9cd8d0738e5c0f1e'); + expect(template.creator.name).to.equal('Nxsh'); + expect(template.creator.walletAddress).to.equal('0xf5977a695e85d3046ed8ce03dd3b562e40532200'); expect(template.creator.imageUrl).to.equal( - 'https://highlight-creator-assets.highlight.xyz/main/image/91eaf712-b9de-49e4-8674-85f37dd823e0.png', + 'https://highlight-creator-assets.highlight.xyz/main/image/e5eca4b9-1b8e-4ebf-8cd5-e0f6d618e15a.png', ); } expect(template.marketingUrl).to.equal(url); - expect(template.availableForPurchaseStart?.getTime()).to.equal(+new Date('2024-06-05T16:00:00.000Z')); - expect(template.availableForPurchaseEnd?.getTime()).to.equal(+new Date('2024-08-31T16:00:00.000Z')); + expect(template.availableForPurchaseStart?.getTime()).to.equal(+new Date(1720042380000)); + expect(template.availableForPurchaseEnd?.getTime()).to.equal(+new Date(1893456000000)); }); it.skip('createMintTemplateForUrl: Returns a mint template for a supported URL with free price', async function () { diff --git a/test/ingestors/rarible.test.ts b/test/ingestors/rarible.test.ts index 165947f..3091038 100644 --- a/test/ingestors/rarible.test.ts +++ b/test/ingestors/rarible.test.ts @@ -5,180 +5,194 @@ import { EVMMintInstructions } from "../../src/lib/types/mint-template"; import { MintTemplateBuilder } from "../../src/lib/builder/mint-template-builder"; import { basicIngestorTests } from "../shared/basic-ingestor-tests"; -describe("rarible", function () { - this.timeout(60000); +describe('rarible', function () { + this.timeout(60000); - const supportedUrls = [ - "https://rarible.com/collection/base/0x7ab45Ce14349b5b66f7d8ECA627A29397BC4d26B/drops", - "https://rarible.com/collection/base/0x4aDca8bCD15aeEB58949fEE1a38fAEf7d5138121/drops", - ]; - const notSupportedUrls = [ - "https://example.com", - "https://basescan.org", - "https://etherscan.org", - "https://farcaster.xyz", - "https://opensea.io", - ]; + const supportedUrls = [ + 'https://rarible.com/collection/base/0x7ab45Ce14349b5b66f7d8ECA627A29397BC4d26B/drops', + 'https://rarible.com/collection/base/0x4aDca8bCD15aeEB58949fEE1a38fAEf7d5138121/drops', + ]; + const notSupportedUrls = [ + 'https://example.com', + 'https://basescan.org', + 'https://etherscan.org', + 'https://farcaster.xyz', + 'https://opensea.io', + ]; - const chainId = 8453; - const blockHeight = 13332646; + const chainId = 8453; + const blockHeight = 13332646; - const suppContract = [ - { chainId, contractAddress: "0x1F4dcFc919863324887225dD4E7E92112dff64D9"}, - { chainId, contractAddress: "0x968ca01b5C32234F4d6Bfd44fF079BE14789bA10"}, - { chainId, contractAddress: "0x2F35A1080b1c4cC74D0203fe12c2494291E17153"}, - { chainId, contractAddress: "0x2F35A1080b1c4cC74D0203fe12c2494291E17153"}, - { chainId, contractAddress: "0x0F257E0068CBfa1fB160c660144258F9A8766484"}, - ]; - const notSuppContract = [ - { chainId, contractAddress: "0x6140F00e4Ff3936702E68744f2b5978885464cbB"}, - { chainId, contractAddress: "0x9EF36A5969C71E41fdFEc2090F11D96d95812cD1"}, - { chainId, contractAddress: "0x3B8114EDC4A43492d2543130d2a75d7558afc1B9"}, - { chainId, contractAddress: "0x5c9E9B603eA654734e5BebE78CC230f16BD21d2b"}, - { chainId, contractAddress: "0x16144DeFf95a67147b96B4bC2c4b5C4fA3cCe055"}, - ]; - const suppContractAddrNotBase = [ - "0xf0315618b07b35262a181dfa277f0dc254c283c0", - "0x1e878f25c11b92a90Ca00daa651E4A041fc14cae", - "0x1e878f25c11b92a90Ca00daa651E4A041fc14cae", - "0x6f20bE53858C299F2e43E0DCB8aDd9deD169360A", - "0xa79030c95de01C1b92352755dDc849cDdFdb5915" - ]; - basicIngestorTests( - new RaribleIngestor(), - mintIngestorResources(), - { - successUrls: supportedUrls, - failureUrls: notSupportedUrls, - successContracts: suppContract, - failureContracts: notSuppContract, - }, - { - 8453: `0x${blockHeight.toString(16)}`, - } - ); - - it("supportsUrl: Returns false for an unsupported URL", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); - for (const url of notSupportedUrls) { - const result = await ingestor.supportsUrl(resources, url); - expect(result).to.be.false; - } - }); - it("supportsUrl: Returns true for a supported URL", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); + const suppContract = [ + { chainId, contractAddress: '0x1F4dcFc919863324887225dD4E7E92112dff64D9' }, + { chainId, contractAddress: '0x968ca01b5C32234F4d6Bfd44fF079BE14789bA10' }, + { chainId, contractAddress: '0x2F35A1080b1c4cC74D0203fe12c2494291E17153' }, + { chainId, contractAddress: '0x2F35A1080b1c4cC74D0203fe12c2494291E17153' }, + { chainId, contractAddress: '0x0F257E0068CBfa1fB160c660144258F9A8766484' }, + ]; + const notSuppContract = [ + { chainId, contractAddress: '0x6140F00e4Ff3936702E68744f2b5978885464cbB' }, + { chainId, contractAddress: '0x9EF36A5969C71E41fdFEc2090F11D96d95812cD1' }, + { chainId, contractAddress: '0x3B8114EDC4A43492d2543130d2a75d7558afc1B9' }, + { chainId, contractAddress: '0x5c9E9B603eA654734e5BebE78CC230f16BD21d2b' }, + { chainId, contractAddress: '0x16144DeFf95a67147b96B4bC2c4b5C4fA3cCe055' }, + ]; + const suppContractAddrNotBase = [ + '0xf0315618b07b35262a181dfa277f0dc254c283c0', + '0x1e878f25c11b92a90Ca00daa651E4A041fc14cae', + '0x1e878f25c11b92a90Ca00daa651E4A041fc14cae', + '0x6f20bE53858C299F2e43E0DCB8aDd9deD169360A', + '0xa79030c95de01C1b92352755dDc849cDdFdb5915', + ]; + basicIngestorTests( + new RaribleIngestor(), + mintIngestorResources(), + { + successUrls: supportedUrls, + failureUrls: notSupportedUrls, + successContracts: suppContract, + failureContracts: notSuppContract, + }, + { + 8453: `0x${blockHeight.toString(16)}`, + }, + ); - for (const url of supportedUrls) { - const result = await ingestor.supportsUrl(resources, url); - expect(result).to.be.true; - } - }); - it("supportsContract: Returns false for a unsupported contract", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); - for (const contract of notSuppContract) { - const result = await ingestor.supportsContract(resources, contract); - expect(result).to.be.false; - } - }); - it("supportsContract: Returns true for a supported contract", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); - for (const contract of suppContract) { - const result = await ingestor.supportsContract(resources, contract); - expect(result).to.be.true; - } - }); - it("supportsContract: Returns false for a non base chain supported contract", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); - for (const addr of suppContractAddrNotBase) { - const contract = { - chainId, - contractAddress: addr, - }; - const result = await ingestor.supportsContract(resources, contract); - expect(result).to.be.false; - } - }); - it("createMintForContract: Returns a mint template for a supported base contract", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); - const addressIdx = 0; - const contract = { - chainId: chainId, - url: `https://rarible.com/collection/base/${suppContract[addressIdx].contractAddress}/drops`, - contractAddress: suppContract[addressIdx].contractAddress - }; - const template = await ingestor.createMintForContract(resources, contract); - const builder = new MintTemplateBuilder(template); - builder.validateMintTemplate(); + it('supportsUrl: Returns false for an unsupported URL', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); + for (const url of notSupportedUrls) { + const result = await ingestor.supportsUrl(resources, url); + expect(result).to.be.false; + } + }); + it('supportsUrl: Returns true for a supported URL', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); - expect(template.name).to.equal("BASED DEGEN"); - expect(template.description).to.contain("Watch out, Degens in the house!"); - const mintInstructions = template.mintInstructions as EVMMintInstructions; - expect(mintInstructions.contractAddress).to.equal("0x1F4dcFc919863324887225dD4E7E92112dff64D9"); - expect(mintInstructions.contractMethod).to.equal("claim"); - expect(mintInstructions.contractParams).to.equal('[address, 1, "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed", "425000000000000000000", [["0x0000000000000000000000000000000000000000000000000000000000000000"], 0, "425000000000000000000", "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed"], "0x"]'); - expect(template.featuredImageUrl).to.equal("ipfs://bafybeiaviu3k3ohx7kzouz5q4i3h5eccivzckaldiywq7wepujg4vuo4ga/new.gif"); - expect(template.marketingUrl).to.equal(contract.url); - expect(template.creator?.name).to.equal("ZafGod.eth"); - expect(template.creator?.imageUrl).to.equal("https://ipfs.raribleuserdata.com/ipfs/QmaM3Lvd8kiwCekq6cuhWh5SA7RpbN2upQM1R6QoefWHuS"); - expect(template.creator?.description).to.equal("Artist-- 👽 \nJoin the club on discord https://discord.gg/muHgNMa9XH"); - expect(template.creator?.websiteUrl).to.equal("https://rarible.com/artshop"); - expect(template.creator?.walletAddress).to.equal("0xe744D23107c9C98df5311ff8C1C8637Ec3ECF9F3"); - expect(template.availableForPurchaseStart?.getTime()).to.equal(1721221200000); - expect(template.availableForPurchaseEnd?.getTime()).to.equal(1721480400000); - }); - it("createMintTemplateForUrl: Returns a mint template for a supported URL", async function () { - const ingestor = new RaribleIngestor(); - const resources = mintIngestorResources(); - const addressIdx = 1; + for (const url of supportedUrls) { + const result = await ingestor.supportsUrl(resources, url); + expect(result).to.be.true; + } + }); + it('supportsContract: Returns false for a unsupported contract', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); + for (const contract of notSuppContract) { + const result = await ingestor.supportsContract(resources, contract); + expect(result).to.be.false; + } + }); + it('supportsContract: Returns true for a supported contract', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); + for (const contract of suppContract) { + const result = await ingestor.supportsContract(resources, contract); + expect(result).to.be.true; + } + }); + it('supportsContract: Returns false for a non base chain supported contract', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); + for (const addr of suppContractAddrNotBase) { const contract = { - chainId: chainId, - url: `https://rarible.com/collection/base/${suppContract[addressIdx].contractAddress}/drops`, - contractAddress: suppContract[addressIdx].contractAddress + chainId, + contractAddress: addr, }; - const template = await ingestor.createMintTemplateForUrl(resources, contract.url); - const builder = new MintTemplateBuilder(template); - builder.validateMintTemplate(); - - expect(template.name).to.equal("Project Phäros"); - expect(template.description).to.contain("Founded by Matt Monday, Project Phäros is a collection of 10K PFP-style NFTs that place a high focus on culture and lore as a means to create a series of products and experiences for not only the holders, but the participants in the culture the community stands behind. In collaboration with Monday, artist PSSYPPL has created and illustrated the trait base for all of the individual NFTs, with influences from anime, streetwear, rap music, gaming and sneaker culture.\n\nProject Phäros offers access to an immersive experience that gives holders a peak into the brand's world building by way of physical products. Our first offering was Koodos.xyz in 2022. \"Koodos\" is an album and art piece all in one showcasing augmented reality, artwork, a comic, and actual popcorn into one complete experience.\n\nIn addition to digital products Phäros offers \"Cultura\", a music festival held in the beautiful city of Charleston, SC. Powered by our parent company S.W.I.M. LLC, the festival features a variety of Hip Hop, RnB, & Dance musicians from across the globe. This event is open to the public but offered to Phäros holders as a premium VIP ticket.\n\nGoing forward our intentions are to build out the world of Phäros by sticking to a roadmap that continues to build upon the foundation established strictly in culture and culture only."); - const mintInstructions = template.mintInstructions as EVMMintInstructions; - expect(mintInstructions.contractAddress).to.equal("0x968ca01b5C32234F4d6Bfd44fF079BE14789bA10"); - expect(mintInstructions.contractMethod).to.equal("claim"); - expect(mintInstructions.contractParams).to.equal('[address, 1, "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "25650000000000000", [["0x0000000000000000000000000000000000000000000000000000000000000000"], 0, "25650000000000000", "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"], "0x"]'); - expect(template.featuredImageUrl).to.equal("ipfs://bafybeiak3uyymizjs3jhwn4ld5zjverl3dlyxeneleh5ppn56l37sj76ue/Project_Pharos_Logo_(BW).png"); - expect(template.marketingUrl).to.equal(contract.url); - expect(template.creator?.name).to.equal("Matt Monday"); - expect(template.creator?.imageUrl).to.equal(""); - expect(template.creator?.description).to.equal("Matt Monday is an artist & creative director. "); - expect(template.creator?.websiteUrl).to.equal("https://rarible.com/musebymonday"); - expect(template.creator?.walletAddress).to.equal("0xa48F751B466706F84746D23f3AeC7357Ed20000D"); - expect(template.availableForPurchaseStart?.getTime()).to.equal(1720800000000); - expect(template.availableForPurchaseEnd?.getTime()).to.equal(1725163200000); - }); - it("createMintTemplateForUrl: Throws error if incompatible URL", async function () { - const ingestor = new RaribleIngestor(); - const url = "https://twitter.com/yungwknd"; - const resources = mintIngestorResources(); - - let error: unknown; - - try { - await ingestor.createMintTemplateForUrl(resources, url); - } catch (err: unknown) { - error = err; - } - - expect(error).to.be.an("error"); - if (error instanceof Error) { - expect(error.message).to.equal("Incompatible URL"); - } else { - throw new Error("Unexpected error type"); - } - }); + const result = await ingestor.supportsContract(resources, contract); + expect(result).to.be.false; + } + }); + it('createMintForContract: Returns a mint template for a supported base contract', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); + const addressIdx = 0; + const contract = { + chainId: chainId, + url: `https://rarible.com/collection/base/${suppContract[addressIdx].contractAddress}/drops`, + contractAddress: suppContract[addressIdx].contractAddress, + }; + const template = await ingestor.createMintForContract(resources, contract); + const builder = new MintTemplateBuilder(template); + builder.validateMintTemplate(); + + expect(template.name).to.equal('BASED DEGEN'); + expect(template.description).to.contain('Watch out, Degens in the house!'); + const mintInstructions = template.mintInstructions as EVMMintInstructions; + expect(mintInstructions.contractAddress).to.equal('0x1F4dcFc919863324887225dD4E7E92112dff64D9'); + expect(mintInstructions.contractMethod).to.equal('claim'); + expect(mintInstructions.contractParams).to.equal( + '[address, 1, "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed", "425000000000000000000", [["0x0000000000000000000000000000000000000000000000000000000000000000"], 0, "425000000000000000000", "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed"], "0x"]', + ); + expect(template.featuredImageUrl).to.equal( + 'ipfs://bafybeiaviu3k3ohx7kzouz5q4i3h5eccivzckaldiywq7wepujg4vuo4ga/new.gif', + ); + expect(template.marketingUrl).to.equal(contract.url); + expect(template.creator?.name).to.equal('ZafGod.eth'); + expect(template.creator?.imageUrl).to.equal( + 'https://ipfs.raribleuserdata.com/ipfs/QmaM3Lvd8kiwCekq6cuhWh5SA7RpbN2upQM1R6QoefWHuS', + ); + expect(template.creator?.description).to.equal( + 'Artist-- 👽 \nJoin the club on discord https://discord.gg/muHgNMa9XH', + ); + expect(template.creator?.websiteUrl).to.equal('https://rarible.com/artshop'); + expect(template.creator?.walletAddress).to.equal('0xe744D23107c9C98df5311ff8C1C8637Ec3ECF9F3'); + expect(template.availableForPurchaseStart?.getTime()).to.equal(1721221200000); + expect(template.availableForPurchaseEnd?.getTime()).to.equal(1721480400000); + }); + it('createMintTemplateForUrl: Returns a mint template for a supported URL', async function () { + const ingestor = new RaribleIngestor(); + const resources = mintIngestorResources(); + const addressIdx = 1; + const contract = { + chainId: chainId, + url: `https://rarible.com/collection/base/${suppContract[addressIdx].contractAddress}/drops`, + contractAddress: suppContract[addressIdx].contractAddress, + }; + const template = await ingestor.createMintTemplateForUrl(resources, contract.url); + const builder = new MintTemplateBuilder(template); + builder.validateMintTemplate(); + + expect(template.name).to.equal('Project Phäros'); + expect(template.description).to.contain( + 'Founded by Matt Monday, Project Phäros is a collection of 10K PFP-style NFTs that place a high focus on culture and lore as a means to create a series of products and experiences for not only the holders, but the participants in the culture the community stands behind. In collaboration with Monday, artist PSSYPPL has created and illustrated the trait base for all of the individual NFTs, with influences from anime, streetwear, rap music, gaming and sneaker culture.\n\nProject Phäros offers access to an immersive experience that gives holders a peak into the brand\'s world building by way of physical products. Our first offering was Koodos.xyz in 2022. "Koodos" is an album and art piece all in one showcasing augmented reality, artwork, a comic, and actual popcorn into one complete experience.\n\nIn addition to digital products Phäros offers "Cultura", a music festival held in the beautiful city of Charleston, SC. Powered by our parent company S.W.I.M. LLC, the festival features a variety of Hip Hop, RnB, & Dance musicians from across the globe. This event is open to the public but offered to Phäros holders as a premium VIP ticket.\n\nGoing forward our intentions are to build out the world of Phäros by sticking to a roadmap that continues to build upon the foundation established strictly in culture and culture only.', + ); + const mintInstructions = template.mintInstructions as EVMMintInstructions; + expect(mintInstructions.contractAddress).to.equal('0x968ca01b5C32234F4d6Bfd44fF079BE14789bA10'); + expect(mintInstructions.contractMethod).to.equal('claim'); + expect(mintInstructions.contractParams).to.equal( + '[address, 1, "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "25650000000000000", [["0x0000000000000000000000000000000000000000000000000000000000000000"], 0, "25650000000000000", "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"], "0x"]', + ); + expect(template.featuredImageUrl).to.equal( + 'ipfs://bafybeiak3uyymizjs3jhwn4ld5zjverl3dlyxeneleh5ppn56l37sj76ue/Project_Pharos_Logo_(BW).png', + ); + expect(template.marketingUrl).to.equal(contract.url); + expect(template.creator?.name).to.equal('Matt Monday'); + expect(template.creator?.imageUrl).to.equal(''); + expect(template.creator?.description).to.equal('Matt Monday is an artist & creative director. '); + expect(template.creator?.websiteUrl).to.equal('https://rarible.com/musebymonday'); + expect(template.creator?.walletAddress).to.equal('0xa48F751B466706F84746D23f3AeC7357Ed20000D'); + expect(template.availableForPurchaseStart?.getTime()).to.equal(1720800000000); + expect(template.availableForPurchaseEnd?.getTime()).to.equal(0); + }); + it('createMintTemplateForUrl: Throws error if incompatible URL', async function () { + const ingestor = new RaribleIngestor(); + const url = 'https://twitter.com/yungwknd'; + const resources = mintIngestorResources(); + + let error: unknown; + + try { + await ingestor.createMintTemplateForUrl(resources, url); + } catch (err: unknown) { + error = err; + } + + expect(error).to.be.an('error'); + if (error instanceof Error) { + expect(error.message).to.equal('Incompatible URL'); + } else { + throw new Error('Unexpected error type'); + } + }); }); \ No newline at end of file