@manifoldxyz/client-sdk
Version:
Manifold Client SDK for headless purchasing and display of Manifold products
1,543 lines (1,475 loc) • 78.6 kB
TypeScript
import { Account } from 'viem';
import { Chain } from 'viem';
import { Config } from '@wagmi/core';
import { ContractTransaction } from 'ethers';
import type * as ethers from 'ethers';
import { ethers as ethers_2 } from 'ethers';
import { InstancePreview } from '@manifoldxyz/studio-apps-client-public';
import { providers } from 'ethers';
import { PublicClient } from 'viem';
import { PublicInstance } from '@manifoldxyz/studio-apps-client-public';
import { Transport } from 'viem';
import { Wallet } from 'ethers';
import { WalletClient } from 'viem';
/**
* Adapter type enumeration for different Web3 libraries
*/
export declare type AdapterType = 'ethers5' | 'ethers6' | 'viem' | 'wagmi';
export declare type Address = string;
export declare interface AllocationParams {
recipientAddress: Address;
}
export declare interface AllocationResponse {
isEligible: boolean;
reason?: string;
quantity: number | null;
}
/**
* Basic API configuration
*/
export declare interface ApiConfig {
/** Manifold API base URL */
manifoldUrl: string;
/** Studio apps client URL */
studioAppsUrl: string;
/** Request timeout in ms */
timeout: number;
/** Maximum retry attempts */
maxRetries: number;
}
export declare enum AppId {
BLIND_MINT_1155 = 2526777015,
EDITION = 2522713783,
BURN_REDEEM = 2520944311
}
export declare enum AppType {
EDITION = "edition",
BURN_REDEEM = "burn-redeem",
BLIND_MINT = "blind-mint"
}
/**
* Represents an NFT asset with metadata and media.
*
* @public
*/
export declare interface Asset {
/**
* Name of the asset.
*/
name: string;
/**
* Description of the asset.
*/
description?: string;
/**
* Additional metadata attributes (key-value pairs).
*/
attributes?: object;
image?: string;
image_url?: string;
image_preview?: string;
animation?: string;
animation_preview: string;
}
export declare type AudienceRestriction = 'allowlist' | 'none' | 'redemption-codes';
/**
* Audience type enum
*/
export declare type AudienceType = 'None' | 'Allowlist' | 'RedemptionCode';
/**
* Base interface for all Manifold product types.
*
* @typeParam T - The type of public data specific to each product type
*
* @public
*/
export declare interface BaseProduct<T> {
/**
* Unique instance ID for this product.
*/
id: number;
/**
* Product type identifier (Edition, BurnRedeem, or BlindMint).
*/
type: AppType;
/**
* Off-chain data including metadata, configuration, and media.
*/
data: PublicInstance<T>;
/**
* Preview data for the product including title, description, and thumbnail.
*/
previewData: InstancePreview;
}
export declare interface BlindMintInventory {
totalSupply: number;
totalPurchased: number;
}
/**
* Enhanced BlindMint On-Chain Data with gacha-specific extensions
* Based on CONTRACT_PATTERNS.md analysis
*/
export declare interface BlindMintOnchainData {
/** Total number of tokens that can be minted */
totalSupply: number;
/** Current number of tokens minted */
totalMinted: number;
/** Mint start timestamp */
startDate?: Date;
/** Mint end timestamp */
endDate?: Date;
/** Audience type for access control */
audienceType: 'None' | 'Allowlist' | 'RedemptionCode';
/** Cost per token */
cost: Money;
/** Address that receives payments */
paymentReceiver: Address;
/** Number of unique token variations available */
tokenVariations: number;
/** Starting token ID for the collection */
startingTokenId: string;
}
export declare interface BlindMintPayload {
quantity: number;
}
/**
* Pool item configuration (legacy support)
*/
export declare interface BlindMintPool {
/** Series index */
seriesIndex: number;
/** Token metadata */
metadata: Asset;
}
/**
* BlindMint Product interface - extends BaseProduct
* This is the main product interface for BlindMint products
*/
export declare interface BlindMintProduct extends BaseProduct<BlindMintPublicData> {
/** Product type identifier */
type: AppType.BLIND_MINT;
/** Instance data with BlindMint-specific public data */
data: PublicInstance<BlindMintPublicData>;
/** Cached on-chain data */
onchainData?: BlindMintOnchainData;
getAllocations(params: AllocationParams): Promise<AllocationResponse>;
preparePurchase(params: PreparePurchaseParams<BlindMintPayload>): Promise<PreparedPurchase>;
purchase(params: PurchaseParams): Promise<Receipt>;
getStatus(): Promise<ProductStatus>;
getPreviewMedia(): Promise<Media | undefined>;
getMetadata(): Promise<ProductMetadata>;
getInventory(): Promise<ProductInventory>;
getRules(): Promise<ProductRule>;
getProvenance(): Promise<ProductProvenance>;
fetchOnchainData(): Promise<BlindMintOnchainData>;
getTokenVariations(): Promise<TokenVariation[]>;
getTierProbabilities(): Promise<GachaTier[]>;
getClaimableTokens(walletAddress: Address): Promise<ClaimableToken[]>;
}
export declare type BlindMintPublicData = Omit<BlindMintPublicDataResponse, 'contract'> & {
/**
* Smart contract details for the NFT.
*/
contract: Contract;
};
/**
* BlindMint Public Data - off-chain configuration
* This is the main public data structure for BlindMint products
*/
export declare interface BlindMintPublicDataResponse {
/** Display name for the mint */
name: string;
/** Description of the mint */
description?: string;
/** Network ID where the contract is deployed */
network: number;
/** Contract details */
contract: ManifoldContract;
/** Claim extension contract address */
extensionAddress1155: {
value: Address;
version: number;
};
/** Price configuration */
price?: {
value: string;
decimals: number;
currency: string;
erc20: string;
symbol: string;
name: string;
};
/** Tier probability configuration */
tierProbabilities: BlindMintTierProbability[];
/** Pool of available tokens */
pool: BlindMintPool[];
}
export declare type BlindMintStatus = ProductStatus;
/**
* Tier probability configuration (legacy support)
*/
export declare interface BlindMintTierProbability {
/** Tier group identifier */
group: string;
/** Token indices in this tier */
indices: number[];
/** Probability rate */
rate: number;
}
/**
* Basic caching configuration
*/
export declare interface CacheConfig {
/** Whether caching is enabled */
enabled: boolean;
/** Cache TTL in seconds */
ttl: number;
/** Maximum cache size in MB */
maxSizeMB: number;
}
/**
* Claimable merkle information for a wallet
*/
export declare interface ClaimableMerkleInfo {
/** Available mint indices */
mintIndices: number[];
/** Whether the address is in the allowlist */
isInAllowlist: boolean;
/** Corresponding merkle proofs */
merkleProofs: string[][];
}
export declare interface ClaimableToken {
tokenId: number;
metadata: Asset;
tier: string;
isClaimable: boolean;
proofs?: string[];
}
/**
* Claim Extension Contract Interface
* Based on CONTRACT_PATTERNS.md dual-provider architecture
*/
export declare interface ClaimExtensionContract {
/** Network ID where contract is deployed */
readonly networkId: number;
/** Contract address */
readonly contractAddress: Address;
/** Creator contract address */
readonly creatorContractAddress: Address;
/** Claim index within the creator contract */
readonly claimIndex: number;
getClaim(spec: ClaimType): Promise<OnChainClaimData>;
getClaimForToken(tokenId: number): Promise<OnChainClaimData>;
getTotalMinted(): Promise<number>;
getWalletMinted(walletAddress: Address): Promise<number>;
getClaimState(): Promise<ClaimState>;
mint(quantity: number, paymentAmount: bigint, walletAddress: Address): Promise<TransactionResponse>;
mintWithProofs(quantity: number, paymentAmount: bigint, walletAddress: Address, merkleProofs: string[]): Promise<TransactionResponse>;
estimateGasMint(walletAddress: Address, quantity: number, paymentAmount: bigint): Promise<bigint>;
estimateGasMintWithProofs(walletAddress: Address, quantity: number, paymentAmount: bigint, merkleProofs: string[]): Promise<bigint>;
isValidNetwork(): boolean;
switchToCorrectNetwork(): Promise<void>;
}
/**
* Processed claim state with computed values
*/
declare interface ClaimState {
/** Current status */
status: ClaimStatus;
/** Whether claim is currently active */
isActive: boolean;
/** Whether claim has started */
hasStarted: boolean;
/** Whether claim has ended */
hasEnded: boolean;
/** Total minted vs total supply */
mintProgress: {
minted: number;
total: number;
percentage: number;
};
/** Time-based information */
timing: {
startDate: Date | null;
endDate: Date | null;
timeUntilStart?: number;
timeUntilEnd?: number;
};
}
declare type ClaimStatus = 'not-started' | 'active' | 'ended' | 'sold-out' | 'paused';
declare type ClaimType = 'erc721' | 'erc1155';
/**
* Configuration options for initializing the Manifold SDK client.
*
* @public
*/
export declare interface ClientConfig {
/**
* Public provider for read-only blockchain interactions.
* Required for fetching balances, estimating gas, and reading contracts.
*
* @example
* ```typescript
* // Using Ethers v5
* import { Ethers5PublicClient } from '@manifoldxyz/client-sdk/adapters';
* const provider = new ethers.providers.JsonRpcProvider('...');
* const publicProvider = new Ethers5PublicClient({ provider });
*
* // Using Viem
* import { ViemPublicClient } from '@manifoldxyz/client-sdk/adapters';
* const publicClient = createPublicClient({ ... });
* const publicProvider = new ViemPublicClient({ publicClient });
*
* const client = createClient({ publicProvider });
* ```
*/
publicProvider: IPublicProvider;
/**
* Enable debug logging for SDK operations.
* Useful for troubleshooting and development.
*
* @defaultValue false
*/
debug?: boolean;
/* Excluded from this release type: environment */
}
/**
* Main error class for the Manifold SDK.
*
* Extends the standard Error class with typed error codes and
* additional details for debugging.
*
* @example
* ```typescript
* try {
* const product = await client.getProduct('invalid-id');
* } catch (error) {
* if (error instanceof ClientSDKError) {
* console.log('Error code:', error.code);
* console.log('Message:', error.message);
* console.log('Details:', error.details);
*
* // Handle specific error types
* switch (error.code) {
* case ErrorCode.NOT_FOUND:
* console.log('Product not found');
* break;
* case ErrorCode.INSUFFICIENT_FUNDS:
* console.log('Not enough balance');
* break;
* }
* }
* }
* ```
*
* @public
*/
export declare class ClientSDKError extends Error {
code: ErrorCode;
details?: unknown | undefined;
/**
* Creates a new ClientSDKError.
*
* @param code - Error code from the ErrorCode enum
* @param message - Human-readable error message
* @param details - Optional additional error details (metadata, original error, etc.)
*/
constructor(code: ErrorCode, message: string, details?: unknown | undefined);
}
/**
* Smart contract information for an NFT.
*
* @public
*/
export declare interface Contract {
/**
* Contract name (e.g., "Cool Cats").
*/
name: string;
/**
* Token symbol (e.g., "COOL").
*/
symbol: string;
/**
* Ethereum contract address.
*/
contractAddress: string;
/**
* Network ID where contract is deployed.
*/
networkId: number;
/**
* Token specification: 'erc721' or 'erc1155'.
*/
spec: ContractSpec;
/**
* Explorer links for the contract.
*/
explorer: Explorer;
}
/**
* Options for contract method calls
* Based on timeout and fallback patterns from CONTRACT_PATTERNS.md
*/
export declare interface ContractCallOptions {
/** Gas limit for the transaction */
gasLimit?: bigint;
/** Gas price in wei */
gasPrice?: bigint;
/** Value to send with transaction (for payable methods) */
value?: bigint;
/** Use bridge provider instead of wallet provider */
useBridge?: boolean;
/** Use unchecked mode (for WalletConnect compatibility) */
unchecked?: boolean;
/** Timeout in milliseconds (default: 1500) */
timeout?: number;
/** Number of retry attempts on failure */
retries?: number;
}
declare type ContractSpec = 'erc721' | 'erc1155';
/**
* Aggregated price information for a purchase, including native currency and ERC20 totals.
* @params totalUSD - Total converted price in USD as a string
* @params total - Total price broken down by native currency and ERC20 tokens
* @params breakdown - Detailed breakdown of costs (product price, platform fees, etc.)
*/
export declare type Cost = {
totalUSD: string;
total: {
native: Money;
erc20s: Money[];
};
breakdown: {
product: Money;
platformFee: Money;
};
};
export declare function createAccountEthers5(provider: {
signer?: providers.JsonRpcSigner;
wallet?: Wallet;
}): Ethers5Account;
export declare function createAccountViem(provider: {
walletClient: WalletClient<Transport, Chain, Account>;
}): ViemAccount;
/**
* Creates a new Manifold SDK client instance for interacting with Manifold products.
*
* The client provides methods to fetch product data, check eligibility, prepare purchases,
* and execute transactions for NFT products on the Manifold platform.
*
* @param config - Configuration object for the client
* @param config.publicProvider - Required provider for blockchain interactions
* @param config.debug - Enable debug logging for troubleshooting (default: false)
*
* @returns A configured ManifoldClient instance
*
* @example
* ```typescript
* // Using Ethers v5
* import { Ethers5PublicClient } from '@manifoldxyz/client-sdk/adapters';
* const provider = new ethers.providers.JsonRpcProvider('...');
* const publicProvider = new Ethers5PublicClient({ provider });
* const client = createClient({ publicProvider });
*
* // Using Viem
* import { ViemPublicClient } from '@manifoldxyz/client-sdk/adapters';
* const publicClient = createPublicClient({ ... });
* const publicProvider = new ViemPublicClient({ publicClient });
* const client = createClient({ publicProvider });
* ```
*
* @public
*/
export declare function createClient(config: ClientConfig): ManifoldClient;
/**
* Helper function to create an Ethers5PublicProvider
* Supports both single provider and multi-network provider configurations with fallback support
*
* @param config - Map of network IDs to providers (single provider or array of providers for fallback)
* @returns Ethers5PublicProvider instance
*
* @example
* // Multiple providers for different networks
* const providers = {
* 1: new ethers.providers.JsonRpcProvider('https://mainnet...'),
* 8453: new ethers.providers.JsonRpcProvider('https://base...'),
* };
* const publicClient = createPublicProvider(providers);
*
* @example
* // With fallback providers as arrays
* const providers = {
* 1: [
* new ethers.providers.JsonRpcProvider('https://primary-rpc...'),
* new ethers.providers.JsonRpcProvider('https://backup-rpc...'),
* ],
* 8453: new ethers.providers.JsonRpcProvider('https://base...'),
* };
* const publicClient = createPublicProvider(providers);
*/
export declare function createPublicProviderEthers5(config: Record<number, providers.JsonRpcProvider | providers.JsonRpcProvider[]>): Ethers5PublicProvider;
/**
* Helper function to create a ViemPublicProvider
* Supports both single client and multi-network client configurations with fallback support
*
* @param config - Map of network IDs to PublicClients (single client or array of clients for fallback)
* @returns ViemPublicProvider instance
*
* @example
* // Multiple providers for different networks
* const providers = {
* 1: createPublicProvider({ chain: mainnet, ... }),
* 8453: createPublicProvider({ chain: base, ... }),
* };
* const publicProvider = createPublicProvider(providers);
*
* @example
* // With fallback providers as arrays
* const providers = {
* 1: [
* createPublicProvider({ chain: mainnet, transport: http('PRIMARY_RPC') }),
* createPublicProvider({ chain: mainnet, transport: http('BACKUP_RPC') }),
* ],
* 8453: createPublicProvider({ chain: base, ... }),
* };
* const publicProvider = createPublicProvider(providers);
*/
export declare function createPublicProviderViem(config: Record<number, PublicClient | PublicClient[]>): ViemPublicProvider;
/**
* Create a Wagmi public provider
*
* @param params - Object containing Wagmi config
* @returns WagmiPublicProvider instance
*
* @example
* ```typescript
* import { createConfig, http } from '@wagmi/core';
* import { mainnet, base } from '@wagmi/core/chains';
* import { createPublicProvider } from '@manifoldxyz/client-sdk/adapters/wagmi-adapter';
*
* const config = createConfig({
* chains: [mainnet, base],
* transports: {
* [mainnet.id]: http(),
* [base.id]: http(),
* },
* });
*
* const provider = createPublicProvider({ config });
* ```
*/
export declare function createPublicProviderWagmi(params: {
config: Config;
}): WagmiPublicProvider;
/**
* Represents a Manifold creator/workspace.
*
* @public
*/
export declare interface Creator {
/**
* Unique identifier of the workspace.
*/
id: string;
/**
* URL-friendly slug for the workspace.
*/
slug: string;
/**
* Ethereum wallet address of the workspace.
*/
address: string;
/**
* Display name of the workspace.
*/
name?: string;
}
/**
* Edition claim contract interface for ERC721 and ERC1155
*/
export declare type EditionClaimContract = ethers.Contract & {
MINT_FEE(): Promise<ethers.BigNumber>;
MINT_FEE_MERKLE(): Promise<ethers.BigNumber>;
getClaim(creatorContractAddress: string, instanceId: number | ethers.BigNumberish): Promise<EditionClaimData>;
getTotalMints(minter: string, creatorContractAddress: string, instanceId: number | ethers.BigNumberish): Promise<number>;
mintProxy(creatorContractAddress: string, instanceId: number | ethers.BigNumberish, mintCount: number, mintIndices: number[], merkleProofs: string[][], mintFor: string, options?: ethers.Overrides): Promise<ethers.ContractTransaction>;
mint(creatorContractAddress: string, instanceId: number | ethers.BigNumberish, mintIndex: number, merkleProof: string[], mintFor: string, options?: ethers.Overrides): Promise<ethers.ContractTransaction>;
mintBatch(creatorContractAddress: string, instanceId: number | ethers.BigNumberish, mintCount: number, mintIndices: number[], merkleProofs: string[][], mintFor: string, options?: ethers.Overrides): Promise<ethers.ContractTransaction>;
checkMintIndex(creatorContractAddress: string, instanceId: number | ethers.BigNumberish, mintIndex: number): Promise<boolean>;
checkMintIndices(creatorContractAddress: string, instanceId: number | ethers.BigNumberish, mintIndices: number[]): Promise<boolean[]>;
getClaimForToken(creatorContractAddress: string, tokenId: number | ethers.BigNumberish): Promise<{
instanceId: ethers.BigNumber;
claim: EditionClaimData;
}>;
tokenURI(creatorContractAddress: string, tokenId: number | ethers.BigNumberish): Promise<string>;
};
export declare type EditionClaimData = ERC721ClaimData | ERC1155ClaimData;
export declare type EditionOnchainData = IERC721EditionOnchainData | IERC1155EditionOnchainData;
export declare interface EditionPayload {
quantity: number;
redemptionCode?: string;
}
/**
* Edition product type for standard NFT mints.
*
* Edition products allow creators to sell fixed or open edition NFTs
* with optional allowlists, redemption codes, and pricing tiers.
*
* @public
*/
export declare interface EditionProduct extends BaseProduct<EditionPublicData> {
/**
* Product type identifier.
*/
type: AppType.EDITION;
/**
* Off-chain product data.
*/
data: PublicInstance<EditionPublicData>;
/**
* On-chain data (pricing, supply, etc.). Populated after calling fetchOnchainData().
*/
onchainData?: EditionOnchainData;
/**
* Check allocation eligibility for a wallet address.
* @param params - Parameters including recipient address
* @returns Allocation details including eligibility and quantity
*/
getAllocations(params: AllocationParams): Promise<AllocationResponse>;
/**
* Prepare a purchase transaction with eligibility check and cost calculation.
* @param params - Purchase parameters including address and quantity
* @returns Prepared transaction details with cost breakdown
*/
preparePurchase(params: PreparePurchaseParams<EditionPayload>): Promise<PreparedPurchase>;
/**
* Execute a purchase transaction.
* @param params - Purchase execution parameters
* @returns Receipt details including transaction and minted token information
*/
purchase(params: PurchaseParams): Promise<Omit<Receipt, 'order'> & {
order: TokenOrder;
}>;
/**
* Get current product status (active, paused, completed, upcoming).
* @returns Current product status
*/
getStatus(): Promise<ProductStatus>;
/**
* Get preview media for the product.
* @returns Media URLs for preview
*/
getPreviewMedia(): Promise<Media | undefined>;
/**
* Get product metadata (name, description).
* @returns Product metadata
*/
getMetadata(): Promise<ProductMetadata>;
/**
* Get inventory information (supply, minted count).
* @returns Inventory details
*/
getInventory(): Promise<ProductInventory>;
/**
* Get product rules (dates, limits, restrictions).
* @returns Product rule configuration
*/
getRules(): Promise<ProductRule>;
/**
* Get provenance information (creator, contract details).
* @returns Provenance details
*/
getProvenance(): Promise<ProductProvenance>;
/**
* Fetch and populate on-chain data.
* @returns On-chain data including pricing and supply
*/
fetchOnchainData(): Promise<EditionOnchainData>;
}
export declare type EditionPublicData = Omit<EditionPublicDataResponse, 'contract'> & {
/**
* Smart contract details for the NFT.
*/
contract: Contract;
};
/**
* Public configuration data for Edition products.
*
* @public
*/
export declare type EditionPublicDataResponse = {
/**
* Title of the Edition product.
*/
title: string;
/**
* Description of the Edition product.
*/
description?: string;
/**
* Primary media asset for the Edition.
*/
asset: Asset;
/**
* Network ID where the product is deployed.
*/
network: number;
/**
* Smart contract details for the NFT.
*/
contract: ManifoldContract;
extensionAddress721: {
value: string;
version: number;
};
extensionAddress1155: {
value: string;
version: number;
};
/**
* Allowlist configuration for the Edition.
*/
instanceAllowlist?: {
merkleTreeId?: number;
};
};
/**
* Token specification enum for Edition products
*/
export declare enum EditionSpec {
ERC721 = "ERC721",
ERC1155 = "ERC1155"
}
/**
* Claim data structure for ERC1155 Edition claims
*/
export declare interface ERC1155ClaimData {
total: number;
totalMax: number;
walletMax: number;
startDate: number;
endDate: number;
storageProtocol: number;
merkleRoot: string;
location: string;
tokenId: bigint;
cost: bigint;
paymentReceiver: string;
erc20: string;
signingAddress: string;
}
/**
* ERC20 Contract Interface for payment tokens
*/
export declare interface ERC20Contract {
/** Network ID where contract is deployed */
readonly networkId: number;
/** ERC20 contract address */
readonly contractAddress: Address;
getBalance(walletAddress: Address): Promise<bigint>;
getAllowance(owner: Address, spender: Address): Promise<bigint>;
getERC20Symbol(): Promise<string>;
getERC20Decimals(): Promise<number>;
getERC20Name(): Promise<string>;
getTotalSupply(): Promise<bigint>;
approve(spender: Address, amount: bigint): Promise<TransactionResponse>;
transfer(to: Address, amount: bigint): Promise<TransactionResponse>;
estimateGasApprove(spender: Address, amount: bigint): Promise<bigint>;
estimateGasTransfer(to: Address, amount: bigint): Promise<bigint>;
}
/**
* Claim data structure for ERC721 Edition claims
*/
export declare interface ERC721ClaimData {
total: number;
totalMax: number;
walletMax: number;
startDate: number;
endDate: number;
storageProtocol: number;
contractVersion: number;
identical: boolean;
merkleRoot: string;
location: string;
cost: bigint;
paymentReceiver: string;
erc20: string;
signingAddress: string;
}
/**
* Error codes used throughout the Manifold SDK.
*
* Organized by category for easier troubleshooting:
* - Network: Issues with blockchain network connectivity
* - Resource: Problems finding or accessing resources
* - Input: Validation failures for user input
* - Transaction: Blockchain transaction issues
* - Sale Status: Product availability problems
* - API: External API communication errors
*
* @public
*/
export declare enum ErrorCode {
/** Network not supported by the SDK */
UNSUPPORTED_NETWORK = "UNSUPPORTED_NETWORK",
/** Connected to wrong network for this operation */
WRONG_NETWORK = "WRONG_NETWORK",
/** General network connectivity issue */
NETWORK_ERROR = "NETWORK_ERROR",
/** RPC URL not configured for required network */
MISSING_RPC_URL = "MISSING_RPC_URL",
/** Product or resource not found */
NOT_FOUND = "NOT_FOUND",
/** Specific resource not found */
RESOURCE_NOT_FOUND = "RESOURCE_NOT_FOUND",
/** Invalid input parameters */
INVALID_INPUT = "INVALID_INPUT",
/** Required tokens not provided for burn/redeem */
MISSING_TOKENS = "MISSING_TOKENS",
/** Input validation failed */
VALIDATION_FAILED = "VALIDATION_FAILED",
/** Product type not supported */
UNSUPPORTED_TYPE = "UNSUPPORTED_TYPE",
/** Gas estimation failed */
ESTIMATION_FAILED = "ESTIMATION_FAILED",
/** Transaction failed to execute */
TRANSACTION_FAILED = "TRANSACTION_FAILED",
/** Transaction reverted on-chain */
TRANSACTION_REVERTED = "TRANSACTION_REVERTED",
/** User rejected transaction */
TRANSACTION_REJECTED = "TRANSACTION_REJECTED",
/** Transaction replaced by another */
TRANSACTION_REPLACED = "TRANSACTION_REPLACED",
/** Transaction still pending */
TRANSACTION_PENDING = "TRANSACTION_PENDING",
/** Insufficient balance for transaction */
INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
/** Gas estimation failed */
GAS_ESTIMATION_FAILED = "GAS_ESTIMATION_FAILED",
/** Gas price too low for network */
GAS_PRICE_TOO_LOW = "GAS_PRICE_TOO_LOW",
/** Nonce mismatch error */
NONCE_ERROR = "NONCE_ERROR",
/** Smart contract execution error */
CONTRACT_ERROR = "CONTRACT_ERROR",
/** Ledger wallet specific error (often blind signing disabled) */
LEDGER_ERROR = "LEDGER_ERROR",
/** General hardware wallet error */
HARDWARE_WALLET_ERROR = "HARDWARE_WALLET_ERROR",
/** Wallet not eligible to purchase */
NOT_ELIGIBLE = "NOT_ELIGIBLE",
/** Product sold out */
SOLD_OUT = "SOLD_OUT",
/** Wallet purchase limit reached */
LIMIT_REACHED = "LIMIT_REACHED",
/** Sale has ended */
ENDED = "ENDED",
/** Sale hasn't started yet */
NOT_STARTED = "NOT_STARTED",
/** External API error */
API_ERROR = "API_ERROR",
/** API rate limit exceeded */
RATE_LIMITED = "RATE_LIMITED",
/** Invalid API response format */
INVALID_RESPONSE = "INVALID_RESPONSE",
/** Request timeout */
TIMEOUT = "TIMEOUT",
/** Product type not yet implemented */
UNSUPPORTED_PRODUCT_TYPE = "PRODUCT_TYPE_NOT_SUPPORTED",
/** Unknown error occurred */
UNKNOWN_ERROR = "UNKNOWN_ERROR"
}
/**
* Account adapter implementation for ethers.js v5.x
*
* Provides a unified interface for wallet operations across different Web3 libraries.
* This adapter specifically handles ethers v5 Provider and Signer instances.
*
* @example
* ```typescript
* import { ethers } from 'ethers'; // v5
* import { Ethers5Account } from '@manifoldxyz/client-sdk/adapters';
*
* // Browser wallet (MetaMask, etc.)
* const provider = new ethers.providers.Web3Provider(window.ethereum);
* const signer = provider.getSigner();
* const adapter = new Ethers5Account({ signer });
*
* // Private key wallet (server-side)
* const wallet = new ethers.Wallet(privateKey, provider);
* const adapter = new Ethers5Account({ wallet });
*
* // Use unified interface for purchases
* const balance = await adapter.getBalance();
* const tx = await adapter.sendTransaction(txRequest);
* ```
*
* @public
*/
export declare class Ethers5Account implements IAccount {
readonly adapterType: AdapterType;
private _signer;
private _wallet;
_address: string | undefined;
/**
* Initialize adapter with ethers v5 provider or signer.
*
* @param provider - Provider configuration
* @param provider.signer - ethers v5 JsonRpcSigner (for browser wallets)
* @param provider.wallet - ethers v5 Wallet (for private key wallets)
*
* @throws {ClientSDKError} When:
* - Neither signer nor wallet is provided
* - Both signer and wallet are provided
*
* @example
* ```typescript
* // Browser wallet
* const signer = provider.getSigner();
* const adapter = new Ethers5Account({ signer });
*
* // Private key wallet
* const wallet = new ethers.Wallet(privateKey);
* const adapter = new Ethers5Account({ wallet });
* ```
*/
constructor(provider: {
signer?: ethers_2.providers.JsonRpcSigner;
wallet?: ethers_2.Wallet;
});
/**
* Get wallet address (cached after first call)
*/
getAddress(): Promise<string>;
/**
* Send a transaction through the connected wallet
*
* @param request - Universal transaction request
* @returns Promise resolving to universal transaction response
* @throws {ClientSDKError} When transaction fails or is rejected
*/
sendTransaction(request: UniversalTransactionRequest): Promise<string>;
sendTransactionWithConfirmation(request: UniversalTransactionRequest, options?: {
confirmations?: number;
}): Promise<UniversalTransactionResponse>;
/**
* Get token balance for connected wallet
*
* @param tokenAddress - ERC-20 token address (optional, defaults to native token)
* @returns Promise resolving to Money instance with balance
* @throws {ClientSDKError} When balance query fails
*/
getBalance(networkId: number, tokenAddress?: string): Promise<Money>;
/**
* Switch to a different network
*
* @param chainId - Target network ID to switch to
* @returns Promise resolving when network switch is complete
* @throws {ClientSDKError} When network switch fails or is rejected
*/
switchNetwork(chainId: number): Promise<void>;
/**
* Sign a message with the connected wallet
*
* @param message - Message to sign
* @returns Promise resolving to signature string
* @throws {ClientSDKError} When signing fails or is rejected
*/
signMessage(message: string): Promise<string>;
/**
* Send raw RPC calls to the wallet provider
* Useful for wallet-specific methods like adding custom networks, tokens, etc.
*
* @param method - RPC method name (e.g., 'wallet_addEthereumChain')
* @param params - Method parameters
* @returns Promise resolving to the RPC response
* @throws {ClientSDKError} When RPC call fails or is not supported
*/
sendCalls(method: string, params?: unknown[]): Promise<unknown>;
_getProvider(networkId?: number): Promise<ethers_2.providers.JsonRpcSigner | ethers_2.Wallet>;
/**
* Check ERC20 token balance
*/
_checkERC20Balance(tokenAddress: string, ownerAddress: string, provider: ethers_2.providers.JsonRpcSigner | ethers_2.Wallet): Promise<ethers_2.BigNumber>;
/**
* Convert universal transaction request to ethers v5 format
*/
private _convertToEthersRequest;
/**
* Convert ethers v5 transaction response to universal format
*/
private _convertToUniversalResponse;
private _handleReplacementTransaction;
}
export declare class Ethers5PublicProvider implements IPublicProvider {
private providers;
constructor(providers: Record<number, providers.JsonRpcProvider | providers.JsonRpcProvider[]>);
private executeWithFallback;
getBalance(params: {
address: string;
networkId: number;
tokenAddress?: string;
}): Promise<bigint>;
subscribeToContractEvents(params: {
contractAddress: string;
abi: readonly unknown[];
networkId: number;
topics: string[];
callback: (log: unknown) => void;
}): Promise<() => void>;
estimateContractGas(params: {
contractAddress: string;
abi: readonly unknown[];
functionName: string;
args?: readonly unknown[];
from: string;
value?: bigint;
networkId: number;
}): Promise<bigint>;
readContract<T = unknown>(params: {
contractAddress: string;
abi: readonly unknown[];
functionName: string;
args?: readonly unknown[];
networkId: number;
}): Promise<T>;
private _ensureConnectedNetwork;
}
/**
* External explorer links for a contract or token.
*
* @public
*/
export declare interface Explorer {
/**
* Etherscan explorer URL.
*/
etherscanUrl: string;
/**
* Manifold gallery URL.
*/
manifoldUrl?: string;
/**
* OpenSea marketplace URL.
*/
openseaUrl?: string;
}
export declare interface FloorPriceConfig {
enabled: boolean;
source: 'opensea' | 'manifold' | 'custom';
updateInterval: number;
}
export declare interface GachaTier {
/** Tier identifier */
id: string;
/** Tier name (Common, Rare, Legendary, etc.) */
name: string;
/** Probability as percentage (0-100) */
probability: number;
/** Token IDs included in this tier */
tokenIds: number[];
/** Tier-specific metadata */
metadata?: Record<string, unknown>;
}
export declare interface GasBuffer {
fixed?: bigint;
multiplier?: number;
}
export declare interface HttpRPCs {
[networkId: number]: string;
}
/**
* Main account adapter interface that abstracts wallet operations across
* different Web3 libraries. Provides a unified API for transaction sending,
* balance queries, and network management.
*
* This interface is the core abstraction that allows the Manifold SDK to work
* with ethers v5, ethers v6, and viem without breaking changes.
*
* @example
* ```typescript
* // Create adapter with explicit factory method
* const account = AccountAdapterFactory.fromEthers5(signer);
*
* // Use unified interface
* const balance = await account.getBalance();
* const networkId = await account.getConnectedNetworkId();
*
* // Send transaction
* const response = await account.sendTransaction({
* to: '0x742d35cc6488ad532a3b33a8b3c9f9b8eb8c5b3a',
* value: '1000000000000000000', // 1 ETH
* data: '0xa9059cbb...'
* });
* ```
*/
export declare interface IAccount {
/**
* Wallet address (checksummed)
*/
_address: string | undefined;
/**
* Adapter type identifier for debugging and type checking
* @readonly
*/
readonly adapterType: AdapterType;
/**
* Get wallet address asynchronously
*/
getAddress(): Promise<string>;
/**
* Send a transaction through the connected wallet
*
* @param request - Universal transaction request
* @returns Promise resolving to universal transaction response
* @throws {AccountAdapterError} When transaction fails or is rejected
*
* @example
* ```typescript
* const response = await adapter.sendTransaction({
* to: '0x742d35cc6488ad532a3b33a8b3c9f9b8eb8c5b3a',
* value: '1000000000000000000', // 1 ETH in wei
* gasLimit: '21000'
* });
* ```
*/
sendTransaction(request: UniversalTransactionRequest): Promise<string>;
/**
* Send a transaction and wait for confirmation
*
* @param request - Universal transaction request
* @param options - Confirmation options
* @returns Promise resolving to normalized confirmation result
* @throws {AccountAdapterError} When transaction submission or confirmation fails
*/
sendTransactionWithConfirmation(request: UniversalTransactionRequest, options?: {
confirmations?: number;
}): Promise<UniversalTransactionResponse>;
/**
* Get token balance for connected wallet
*
* @param tokenAddress - ERC-20 token address (optional, defaults to native token)
* @returns Promise resolving to Money instance with balance
* @throws {AccountAdapterError} When balance query fails
*
* @example
* ```typescript
* // Get native token balance (ETH, MATIC, etc.)
* const ethBalance = await adapter.getBalance();
*
* // Get ERC-20 token balance
* const usdcBalance = await adapter.getBalance('0xA0b86a33E6441d7B2c15e9A9d98b56e3F42E9b9B');
* ```
*/
getBalance(networkId: number, tokenAddress?: string): Promise<Money>;
/**
* Switch to a different network
*
* @param chainId - Target network ID to switch to
* @returns Promise resolving when network switch is complete
* @throws {AccountAdapterError} When network switch fails or is rejected
*
* @example
* ```typescript
* // Switch to Polygon
* await adapter.switchNetwork(137);
*
* // Verify switch was successful
* const newNetworkId = await adapter.getConnectedNetworkId();
* console.log(`Now connected to network: ${newNetworkId}`);
* ```
*/
switchNetwork(chainId: number): Promise<void>;
/**
* Sign a message with the connected wallet
*
* @param message - Message to sign
* @returns Promise resolving to signature string
* @throws {AccountAdapterError} When signing fails or is rejected
*
* @example
* ```typescript
* const signature = await adapter.signMessage('Hello, Web3!');
* console.log(`Signature: ${signature}`);
* ```
*/
signMessage(message: string): Promise<string>;
/**
* Sign typed data (EIP-712) with the connected wallet (optional enhancement)
*
* @param typedData - EIP-712 typed data payload
* @returns Promise resolving to signature string
* @throws {AccountAdapterError} When signing fails or is rejected
*/
signTypedData?(typedData: TypedDataPayload): Promise<string>;
/**
* Send raw RPC calls to the wallet provider
* Useful for wallet-specific methods like adding custom networks, tokens, etc.
*
* @param method - RPC method name (e.g., 'wallet_addEthereumChain')
* @param params - Method parameters
* @returns Promise resolving to the RPC response
* @throws {AccountAdapterError} When RPC call fails or is not supported
*
* @example
* ```typescript
* // Add a custom network
* await adapter.sendCalls('wallet_addEthereumChain', [{
* chainId: '0x89',
* chainName: 'Polygon',
* nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
* rpcUrls: ['https://polygon-rpc.com'],
* blockExplorerUrls: ['https://polygonscan.com']
* }]);
* ```
*/
sendCalls(method: string, params?: unknown[]): Promise<unknown>;
}
/**
* On-chain data for 1155 Edition products.
*
* @public
*/
export declare type IERC1155EditionOnchainData = {
tokenId: string;
} & IERCCoreEditionOnchainData;
/**
* On-chain data for 721 Edition products.
*
* @public
*/
export declare type IERC721EditionOnchainData = {
identical: boolean;
} & IERCCoreEditionOnchainData;
export declare type IERCCoreEditionOnchainData = {
/**
* Total supply available (null = unlimited).
*/
totalMax: number | null;
/**
* Total number of tokens minted.
*/
total: number;
/**
* Maximum tokens per wallet (null = unlimited).
*/
walletMax: number | null;
/**
* Sale start date (null = no start date).
*/
startDate: Date | null;
/**
* Sale end date (null = no end date).
*/
endDate: Date | null;
/**
* Audience restriction type.
*/
audienceType: AudienceType;
/**
* Cost per token.
*/
cost: Money;
/**
* Platform fee per mint for standard mints.
*/
platformFee: Money;
/**
* Platform fee per mint for merkle/allowlist mints.
*/
merklePlatformFee: Money;
signingAddress: string;
/**
* Address receiving payments.
*/
paymentReceiver: string;
/**
* Metadata location.
*/
location: string;
/**
* Merkle root for allowlist verification.
*/
merkleRoot: string;
/**
* Storage protocol for metadata.
*/
storageProtocol: number;
};
/* Excluded from this release type: InstanceData */
/**
* Public provider interface for read-only blockchain interactions.
* Provides a unified API for balance queries, gas estimation, and contract reads
* across different Web3 libraries (ethers, viem, etc).
*
* This interface abstracts the underlying provider implementation and provides
* a consistent way to interact with the blockchain for read operations.
*
* @example
* ```typescript
* const provider = new Ethers5PublicClient({ provider: ethersProvider });
*
* // Get balance
* const balance = await provider.getBalance({
* address: '0x742d35cc6488ad532a3b33a8b3c9f9b8eb8c5b3a',
* networkId: 1
* });
*
* // Estimate gas for contract call
* const gasEstimate = await provider.estimateContractGas({
* address: '0x...',
* abi: contractAbi,
* functionName: 'transfer',
* args: [recipient, amount],
* from: '0x...'
* });
* ```
*
* @public
*/
export declare interface IPublicProvider {
/**
* Get the balance of an address (native token or ERC20).
*
* @param params - Balance query parameters
* @param params.address - The address to query balance for
* @param params.networkId - The network ID to query on
* @param params.tokenAddress - Optional ERC20 token address (omit for native token)
* @returns Promise resolving to balance as bigint
*
* @example
* ```typescript
* // Get native token balance
* const ethBalance = await provider.getBalance({
* address: '0x...',
* networkId: 1
* });
*
* // Get ERC20 token balance
* const usdcBalance = await provider.getBalance({
* address: '0x...',
* networkId: 1,
* tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
* });
* ```
*/
getBalance(params: {
address: string;
networkId: number;
tokenAddress?: string;
}): Promise<bigint>;
/**
* Estimate gas for a contract function call.
*
* @param params - Gas estimation parameters
* @param params.contractAddress - The contract address
* @param params.abi - Contract ABI (can be partial, only needs the function being called)
* @param params.functionName - Name of the function to call
* @param params.args - Function arguments
* @param params.from - The address that would send the transaction
* @param params.value - Optional ETH value to send with the call (for payable functions)
* @param params.networkId - The network ID for the estimation
* @returns Promise resolving to estimated gas as bigint
*
* @example
* ```typescript
* const gasEstimate = await provider.estimateContractGas({
* contractAddress: '0x...',
* abi: erc20Abi,
* functionName: 'transfer',
* args: ['0xrecipient...', '1000000'],
* from: '0xsender...',
* networkId: 1
* });
* ```
*/
estimateContractGas(params: {
contractAddress: string;
abi: readonly unknown[];
functionName: string;
args?: readonly unknown[];
from: string;
value?: bigint;
networkId: number;
}): Promise<bigint>;
/**
* Read data from a contract (call a view/pure function).
*
* @param params - Contract read parameters
* @param params.contractAddress - The contract address
* @param params.abi - Contract ABI (can be partial, only needs the function being called)
* @param params.functionName - Name of the function to call
* @param params.args - Function arguments
* @param params.networkId - The network ID for the read
* @returns Promise resolving to the function return value
*
* @example
* ```typescript
* // Read ERC20 balance
* const balance = await provider.readContract({
* contractAddress: '0xUSDC...',
* abi: erc20Abi,
* functionName: 'balanceOf',
* args: ['0xholder...'],
* networkId: 1
* });
*
* // Read contract state
* const totalSupply = await provider.readContract({
* contractAddress: '0x...',
* abi: nftAbi,
* functionName: 'totalSupply',
* networkId: 1
* });
* ```
*/
readContract<T = unknown>(params: {
contractAddress: string;
abi: readonly unknown[];
functionName: string;
args?: readonly unknown[];
networkId: number;
}): Promise<T>;
/**
* Subscribe to contract events (logs) matching specified topics.
*
* @param params - Event watching parameters
* @param params.contractAddress - The contract address
* @param params.abi - Contract ABI (can be partial, only needs the events being watched)
* @param params.networkId - The network ID to watch on
* @param params.topics - Array of topics to filter events
* @param params.callback - Callback function invoked with each matching log
* @returns Promise resolving to an unsubscribe function
*
* @example
* ```typescript
* // Subscribe to Transfer events
* const unsubscribe = await provider.subscribeToContractEvents({
* contractAddress: '0x...',
* abi: erc20Abi,
* networkId: 1,
* topics: ['0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'], // Transfer event signature
* callback: (log) => {
* console.log('Transfer event:', log);
* }
* });
*
* // Later: unsubscribe from events
* unsubscribe();
* ```
*/
subscribeToContractEvents(params: {
contractAddress: string;
abi: readonly unknown[];
networkId: number;
topics: string[];
callback: (log: unknown) => void;
}): Promise<() => void>;
}
export declare function isBlindMintProduct(product: Product): product is BlindMintProduct;
export declare function isEditionProduct(product: Product): product is EditionProduct;
/**
* Type guard to check if claim data is for ERC1155
*/
export declare function isERC1155ClaimData(data: Edition