/** * API response types shared between browser and iframe packages */ import type { FeatureFlags, GDriveConfig, PasskeyConfig, RpcConfig } from './common' // Asset response types export interface GetAssetsResponse { nativeBalance: { balance: string decimals: number name: string rawBalance: string symbol: string metadata: Record } tokenBalances: { balance: string decimals: number name: string rawBalance: string symbol: string metadata: Record }[] nfts?: NFTAsset[] } export interface NFTAsset { nftId: string name: string description: string imageUrl: string chain: string contractAddress: string tokenId: string collection: { name: string description: string | null imageUrl: string } lastSale: { price: number currency: string date: string } | null rarity: { rank: number | null score: number | null } floorPrice: { price: number currency: string } | null detailedInfo: { ownerCount: number tokenCount: number createdDate: string | null attributes: Attribute[] owners: Owner[] extendedCollectionInfo: ExtendedCollectionInfo extendedSaleInfo: ExtendedSaleInfo | null marketplaceInfo: MarketplaceInfo[] mediaInfo: MediaInfo } } interface Attribute { traitType: string value: string | number displayType: string | null } interface Owner { ownerAddress: string quantity: number firstAcquiredDate: string lastAcquiredDate: string } interface ExtendedCollectionInfo { bannerImageUrl: string | null externalUrl: string | null twitterUsername: string | null discordUrl: string | null instagramUsername: string | null mediumUsername: string | null telegramUrl: string | null distinctOwnerCount: number distinctNftCount: number totalQuantity: number } interface ExtendedSaleInfo { fromAddress: string toAddress: string priceUsdCents: number transaction: string marketplaceId: string marketplaceName: string } interface MarketplaceInfo { marketplaceId: string marketplaceName: string marketplaceCollectionId: string nftUrl: string collectionUrl: string verified: boolean | null floorPrice: { value: number paymentToken: { paymentTokenId: string name: string symbol: string address: string | null decimals: number } valueUsdCents: number | null } | null } interface MediaInfo { previews: { imageSmallUrl: string imageMediumUrl: string imageLargeUrl: string imageOpengraphUrl: string blurhash: string predominantColor: string } animationUrl: string | null backgroundColor: string | null } // Iframe configuration types export type IframeLogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug' export interface IframeConfigurationOptions { autoApprove: boolean featureFlags?: FeatureFlags gdrive?: GDriveConfig passkey?: PasskeyConfig host: string mpcHost: string mpcVersion: string /** When set to 'none', the iframe SDK will not log to the console. Passed from parent via portal:configure. */ logLevel?: IframeLogLevel /** RPC endpoint map (CAIP-2 chainId → URL). Passed from parent so the iframe can proxy RPC calls. */ rpcConfig?: RpcConfig /** * Optional RPC map used only for iframe-proxied JSON-RPC (receipt polling, Solana status, etc.). * When set, the iframe `fetch`es these URLs instead of {@link rpcConfig}. The parent still uses * `rpcConfig` for signing (`mpc.sign` / `getRpcUrl`). Use in local dev when the gateway URL must * match presignature but the iframe origin is blocked by CORS (e.g. same-origin or local proxy). */ iframeRpcConfig?: RpcConfig // One of these three is required for authentication apiKey?: string authToken?: string authUrl?: string } // Storage types export interface StorageHashes { android: string default: string ios: string react_native: string web_sdk: string } // Swaps types export interface SwapsRequest { apiKey?: string chainId: string } export type SourcesRequest = SwapsRequest // Portal API error export interface PortalApiErrorBody { error: string }