Skip to content

Commit

Permalink
Multi-chain Alchemy instance. Add ETH support for Manifold
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismaddern committed Aug 29, 2024
1 parent 8459d7a commit 117ca07
Show file tree
Hide file tree
Showing 15 changed files with 437 additions and 323 deletions.
24 changes: 14 additions & 10 deletions src/ingestors/coinbase-wallet/onchain-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { Alchemy, Contract } from 'alchemy-sdk';
import { Contract } from 'alchemy-sdk';
import { MINT_CONTRACT_ABI } from './abi';
import { CollectionMetadata } from './types';
import { AlchemyMultichainClient } from '../../../src/lib/rpc/alchemy-multichain';
import { NETWORKS } from '../../../src/lib/simulation/simulation';

const getContract = async (chainId: number, contractAddress: string, alchemy: Alchemy): Promise<Contract> => {
const ethersProvider = await alchemy.config.getProvider();
const getContract = async (
chainId: number,
contractAddress: string,
alchemy: AlchemyMultichainClient,
): Promise<Contract> => {
const ethersProvider = await alchemy.forNetwork(NETWORKS[chainId]).config.getProvider();
const contract = new Contract(contractAddress, MINT_CONTRACT_ABI, ethersProvider);
return contract;
};

export const getCoinbaseWalletMetadata = async (
chainId: number,
contractAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
): Promise<CollectionMetadata | undefined> => {
try {
const contract = await getContract(chainId, contractAddress, alchemy);
Expand All @@ -21,26 +27,24 @@ export const getCoinbaseWalletMetadata = async (
...metadata,
cost: parseInt(String(metadata.cost)),
startTime: parseInt(String(metadata.startTime)),
endTime: parseInt(String(metadata.endTime))
endTime: parseInt(String(metadata.endTime)),
};
} catch (error) {
console.log(error)
console.log(error);
}
};

export const getCoinbaseWalletPriceInWei = async (
chainId: number,
contractAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
): Promise<string | undefined> => {
try {
const contract = await getContract(chainId, contractAddress, alchemy);
const price = await contract.functions.cost(1);

return `${parseInt(String(price))}`;

} catch (error) {
console.log(error)
console.log(error);
}
};

16 changes: 10 additions & 6 deletions src/ingestors/foundation/onchain-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Alchemy, Contract } from 'alchemy-sdk';
import { FOUNDATION_MINT_ABI } from './abi';
import { AlchemyMultichainClient } from 'src/lib/rpc/alchemy-multichain';
import { NETWORKS } from '../../../src/lib/simulation/simulation';

const getContract = async (chainId: number, contractAddress: string, alchemy: Alchemy): Promise<Contract> => {
const ethersProvider = await alchemy.config.getProvider();
const getContract = async (
chainId: number,
contractAddress: string,
alchemy: AlchemyMultichainClient,
): Promise<Contract> => {
const ethersProvider = await alchemy.forNetwork(NETWORKS[chainId]).config.getProvider();
const contract = new Contract(contractAddress, FOUNDATION_MINT_ABI, ethersProvider);
return contract;
};
Expand All @@ -11,10 +17,9 @@ export const getFoundationMintPriceInWei = async (
chainId: number,
contractAddress: string,
dropAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
saleType: 'FIXED_PRICE_DROP' | string,
): Promise<string | undefined> => {

try {
const contract = await getContract(chainId, contractAddress, alchemy);
const saleData =
Expand All @@ -26,6 +31,5 @@ export const getFoundationMintPriceInWei = async (
const totalFee = parseInt(tokenPrice.toString()) + parseInt(saleData.mintFeePerNftInWei.toString());

return `${totalFee}`;
} catch (error) {
}
} catch (error) {}
};
14 changes: 9 additions & 5 deletions src/ingestors/highlight/onchain-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { Alchemy, Contract } from 'alchemy-sdk';
import { Alchemy, Contract, Network } from 'alchemy-sdk';
import { MINT_CONTRACT_ABI } from './abi';
import { AlchemyMultichainClient } from 'src/lib/rpc/alchemy-multichain';

const CONTRACT_ADDRESS = '0x8087039152c472Fa74F47398628fF002994056EA';

const getContract = async (alchemy: Alchemy): Promise<Contract> => {
const ethersProvider = await alchemy.config.getProvider();
const getContract = async (alchemy: AlchemyMultichainClient): Promise<Contract> => {
const ethersProvider = await alchemy.forNetwork(Network.BASE_MAINNET).config.getProvider();
const contract = new Contract(CONTRACT_ADDRESS, MINT_CONTRACT_ABI, ethersProvider);
return contract;
};

export const getHighlightMintPriceInWei = async (vectorId: number, alchemy: Alchemy): Promise<string | undefined> => {
export const getHighlightMintPriceInWei = async (
vectorId: number,
alchemy: AlchemyMultichainClient,
): Promise<string | undefined> => {
try {
const contract = await getContract(alchemy);
const data = await contract.functions.getAbridgedVector(vectorId);
Expand All @@ -26,7 +30,7 @@ export const getHighlightMintPriceInWei = async (vectorId: number, alchemy: Alch

export const getHighlightMetadata = async (
vectorId: number,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
): Promise<{ startTimestamp: number; endTimestamp: number } | undefined> => {
try {
const contract = await getContract(alchemy);
Expand Down
10 changes: 7 additions & 3 deletions src/ingestors/manifold/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class ManifoldIngestor implements MintIngestor {
configuration = {
supportsContractIsExpensive: true,
};
supportedChainIds = [8453, 1];

async supportsUrl(resources: MintIngestorResources, url: string): Promise<boolean> {
if (new URL(url).hostname !== 'app.manifold.xyz') {
Expand All @@ -25,7 +26,7 @@ export class ManifoldIngestor implements MintIngestor {
const { publicData } = data || {};
const { network: chainId, contract: contractAddress } = publicData || {};

if (chainId !== 8453) {
if (!this.supportedChainIds.includes(chainId)) {
return false;
}

Expand All @@ -42,7 +43,7 @@ export class ManifoldIngestor implements MintIngestor {
return false;
}

if (chainId !== 8453) {
if (!this.supportedChainIds.includes(chainId)) {
return false;
}

Expand All @@ -67,7 +68,10 @@ export class ManifoldIngestor implements MintIngestor {
const { chainId, contractAddress } = await manifoldOnchainDataFromUrl(url, resources.alchemy, resources.fetcher);

if (!chainId || !contractAddress) {
throw new MintIngestorError(MintIngestionErrorName.MissingRequiredData, 'Missing required data, mint expired, or sold out');
throw new MintIngestorError(
MintIngestionErrorName.MissingRequiredData,
'Missing required data, mint expired, or sold out',
);
}

return this.createMintForContract(resources, { chainId, contractAddress, url });
Expand Down
59 changes: 33 additions & 26 deletions src/ingestors/manifold/offchain-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Axios } from 'axios';
import { Alchemy } from 'alchemy-sdk';
import { getContract } from './onchain-metadata';
import { MANIFOLD_CLAIMS_ERC115_SPECIFIC_ABI, MANIFOLD_CLAIMS_ERC721_SPECIFIC_ABI } from './abi';

import { AlchemyMultichainClient } from '../../../src/lib/rpc/alchemy-multichain';

const MANIFOLD_LAZY_PAYABLE_CLAIM_CONTRACT_1155 = '0x26BBEA7803DcAc346D5F5f135b57Cf2c752A02bE';
const MANIFOLD_LAZY_PAYABLE_CLAIM_CONTRACT_721 = '0x23aA05a271DEBFFAA3D75739aF5581f744b326E4';

export const manifoldOnchainDataFromUrl = async (
url: any,
alchemy: Alchemy,
fetcher: Axios
url: any,
alchemy: AlchemyMultichainClient,
fetcher: Axios,
): Promise<any> => {
const slug = url.match(/\/c\/([^\/]+)/)?.[1];
if (!slug) return false;
Expand All @@ -20,6 +19,7 @@ export const manifoldOnchainDataFromUrl = async (
`https://apps.api.manifoldxyz.dev/public/instance/data?appId=2522713783&instanceSlug=${slug}`,
);
const { id, creator, publicData } = data || {};

const {
asset,
network: chainId,
Expand Down Expand Up @@ -64,35 +64,42 @@ export const manifoldOnchainDataFromUrl = async (

// Check if mint sold out
switch (spec) {
case 'ERC721':
{
const contract = await getContract(chainId, MANIFOLD_LAZY_PAYABLE_CLAIM_CONTRACT_721, alchemy, MANIFOLD_CLAIMS_ERC721_SPECIFIC_ABI);
const response = await contract.functions.getClaim(contractAddress, id);
const total = response[0][0];
const totalMax = response[0][1];
case 'ERC721': {
const contract = await getContract(
chainId,
MANIFOLD_LAZY_PAYABLE_CLAIM_CONTRACT_721,
alchemy,
MANIFOLD_CLAIMS_ERC721_SPECIFIC_ABI,
);
const response = await contract.functions.getClaim(contractAddress, id);
const total = response[0][0];
const totalMax = response[0][1];

if (total == totalMax) return false;
if (total == totalMax) return false;

break;
}

case 'ERC1155':
{
const contract = await getContract(chainId, MANIFOLD_LAZY_PAYABLE_CLAIM_CONTRACT_1155, alchemy, MANIFOLD_CLAIMS_ERC115_SPECIFIC_ABI);
const response = await contract.functions.getClaim(contractAddress, id);
const total = response[0][0];
const totalMax = response[0][1];
break;
}

if (total == totalMax) return false;

break;
}
case 'ERC1155': {
const contract = await getContract(
chainId,
MANIFOLD_LAZY_PAYABLE_CLAIM_CONTRACT_1155,
alchemy,
MANIFOLD_CLAIMS_ERC115_SPECIFIC_ABI,
);
const response = await contract.functions.getClaim(contractAddress, id);
const total = response[0][0];
const totalMax = response[0][1];

if (total == totalMax) return false;

break;
}

default:
return false; // Unknown spec
}


return {
instanceId: id,
creatorName: publicData.asset.created_by,
Expand Down
24 changes: 14 additions & 10 deletions src/ingestors/manifold/onchain-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { Alchemy, Contract } from 'alchemy-sdk';
import { Contract } from 'alchemy-sdk';
import axios, { AxiosInstance } from 'axios';
import { MANIFOLD_CLAIMS_ABI } from './abi';
import { AlchemyMultichainClient } from '../../../src/lib/rpc/alchemy-multichain';
import { NETWORKS } from '../../../src/lib/simulation/simulation';

// fetch contract instance
export const getContract = async (chainId: number, contractAddress: string, alchemy: Alchemy, abi: any): Promise<Contract> => {
const ethersProvider = await alchemy.config.getProvider();
export const getContract = async (
chainId: number,
contractAddress: string,
alchemy: AlchemyMultichainClient,
abi: any,
): Promise<Contract> => {
const ethersProvider = await alchemy.forNetwork(NETWORKS[chainId]).config.getProvider();
const contract = new Contract(contractAddress, abi, ethersProvider);
return contract;
};
Expand All @@ -18,10 +25,9 @@ const convertNameToUrl = (name: string): string => {
export const urlForValidManifoldContract = async (
chainId: number,
contractAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
fetcher: AxiosInstance = axios,
): Promise<string | undefined> => {

let name: string;
try {
const contract = await getContract(chainId, contractAddress, alchemy, MANIFOLD_CLAIMS_ABI);
Expand Down Expand Up @@ -49,9 +55,7 @@ export const urlForValidManifoldContract = async (
}
};

export const getManifoldMintPriceInEth = async (
mintPrice: number
): Promise<any> => {
export const getManifoldMintPriceInEth = async (mintPrice: number): Promise<any> => {
// fee amount is standard
const feePrice = 500000000000000;

Expand All @@ -62,11 +66,11 @@ export const getManifoldMintPriceInEth = async (
export const getManifoldMintOwner = async (
chainId: number,
contractAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
): Promise<any> => {
const contract = await getContract(chainId, contractAddress, alchemy, MANIFOLD_CLAIMS_ABI);
const response = await contract.functions.owner();
const owner = response[0];

return owner;
};
18 changes: 12 additions & 6 deletions src/ingestors/prohibition-daily/onchain-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { Alchemy, Contract } from 'alchemy-sdk';
import { Contract } from 'alchemy-sdk';
import { PROHIBITION_DAILY_ABI } from './abi';
import { AlchemyMultichainClient } from '../../../src/lib/rpc/alchemy-multichain';
import { NETWORKS } from '../../../src/lib/simulation/simulation';

const getContract = async (chainId: number, contractAddress: string, alchemy: Alchemy): Promise<Contract> => {
const ethersProvider = await alchemy.config.getProvider();
const getContract = async (
chainId: number,
contractAddress: string,
alchemy: AlchemyMultichainClient,
): Promise<Contract> => {
const ethersProvider = await alchemy.forNetwork(NETWORKS[chainId]).config.getProvider();
const contract = new Contract(contractAddress, PROHIBITION_DAILY_ABI, ethersProvider);
return contract;
};

export const getProhibitionContractMetadata = async (
chainId: number,
contractAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
): Promise<any> => {
const contract = await getContract(chainId, contractAddress, alchemy);
const metadata = await contract.functions.contractURI();
Expand All @@ -31,7 +37,7 @@ export const getProhibitionContractMetadata = async (
export const getProhibitionMintPriceInEth = async (
chainId: number,
contractAddress: string,
alchemy: Alchemy,
alchemy: AlchemyMultichainClient,
): Promise<any> => {
const contract = await getContract(chainId, contractAddress, alchemy);
const feePrice = await contract.functions.mintFee(1);
Expand Down
Loading

0 comments on commit 117ca07

Please sign in to comment.