import {z} from 'zod' export type CreateApiV2EventsEmulateArgs = {'Accept-Language'?: string | undefined, ignore_signature_check?: boolean | undefined, body: {boc: unknown}}; export type CreateApiV2EventsEmulateOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const accountAddress = z.object({address: z.string(), icon: z.string().optional(), is_scam: z.boolean(), is_wallet: z.boolean(), name: z.string().optional()}); export const addExtensionAction = z.object({extension: z.string(), wallet: accountAddress}); export const currencyType = z.enum(["native", "extra_currency", "jetton", "fiat"]); export const trustType = z.enum(["whitelist", "graylist", "blacklist", "none"]); export const price = z.object({currency_type: currencyType, decimals: z.number().int(), image: z.string(), jetton: z.string().optional(), token_name: z.string(), value: z.string(), verification: trustType}); export const nftApprovedBy = z.array(z.enum(["getgems", "tonkeeper"])); export const imagePreview = z.object({resolution: z.string(), url: z.string()}); export const sale = z.object({address: z.string(), market: accountAddress, owner: accountAddress.optional(), price: price}); export const nftItem = z.object({address: z.string(), approved_by: nftApprovedBy, code_hash: z.string().optional(), collection: z.object({address: z.string(), description: z.string(), name: z.string()}).optional(), data_hash: z.string().optional(), dns: z.string().optional(), include_cnft: z.boolean().optional(), index: z.number().int(), metadata: z.record(z.string(), z.unknown()), owner: accountAddress.optional(), previews: z.array(imagePreview).optional(), sale: sale.optional(), trust: trustType, verified: z.boolean()}); export const auctionBidAction = z.object({amount: price, auction: accountAddress, auction_type: z.enum(["DNS.ton", "DNS.tg", "NUMBER.tg", "getgems"]), bidder: accountAddress, nft: nftItem.optional()}); export const buyXTRAction = z.object({amount: z.string(), recipient: accountAddress}); export const contractDeployAction = z.object({address: z.string(), interfaces: z.array(z.string())}); export const poolImplementationType = z.enum(["whales", "tf", "liquidTF", "ffvault"]); export const depositStakeAction = z.object({amount: z.number().int(), implementation: poolImplementationType, pool: accountAddress, stake_meta: price.optional(), staker: accountAddress}); export const protocol = z.object({image: z.string().optional(), name: z.string()}); export const depositTokenStakeAction = z.object({protocol: protocol, stake_meta: price.optional(), staker: accountAddress}); export const depositXTRAction = z.object({amount: z.string(), recipient: accountAddress}); export const domainRenewAction = z.object({contract_address: z.string(), domain: z.string(), renewer: accountAddress}); export const electionsDepositStakeAction = z.object({amount: z.number().int(), staker: accountAddress}); export const electionsRecoverStakeAction = z.object({amount: z.number().int(), staker: accountAddress}); export const ecPreview = z.object({decimals: z.number().int(), id: z.number().int(), image: z.string(), symbol: z.string()}); export const encryptedComment = z.object({cipher_text: z.string(), encryption_type: z.string()}); export const extraCurrencyTransferAction = z.object({amount: z.string(), comment: z.string().optional(), currency: ecPreview, encrypted_comment: encryptedComment.optional(), recipient: accountAddress, sender: accountAddress}); export const scaledUI = z.object({denominator: z.string(), numerator: z.string()}); export const jettonVerificationType = z.enum(["whitelist", "graylist", "blacklist", "none"]); export const jettonPreview = z.object({address: z.string(), custom_payload_api_uri: z.string().optional(), decimals: z.number().int(), description: z.string().optional(), image: z.string(), name: z.string(), scaled_ui: scaledUI.optional(), score: z.number().int(), symbol: z.string(), verification: jettonVerificationType}); export const refund = z.object({origin: z.string(), type: z.enum(["DNS.ton", "DNS.tg", "GetGems"])}); export const flawedJettonTransferAction = z.object({comment: z.string().optional(), encrypted_comment: encryptedComment.optional(), jetton: jettonPreview, received_amount: z.string(), recipient: accountAddress.optional(), recipients_wallet: z.string(), refund: refund.optional(), sender: accountAddress.optional(), senders_wallet: z.string(), sent_amount: z.string()}); export const gasRelayAction = z.object({amount: z.number().int(), relayer: accountAddress, target: accountAddress}); export const jettonBurnAction = z.object({amount: z.string(), jetton: jettonPreview, sender: accountAddress, senders_wallet: z.string()}); export const jettonMintAction = z.object({amount: z.string(), jetton: jettonPreview, recipient: accountAddress, recipients_wallet: z.string()}); export const jettonSwapAction = z.object({amount_in: z.string(), amount_out: z.string(), dex: z.string(), gram_in: z.number().int().optional(), gram_out: z.number().int().optional(), jetton_master_in: jettonPreview.optional(), jetton_master_out: jettonPreview.optional(), router: accountAddress, ton_in: z.number().int().optional(), ton_out: z.number().int().optional(), user_wallet: accountAddress}); export const jettonTransferAction = z.object({amount: z.string(), comment: z.string().optional(), encrypted_comment: encryptedComment.optional(), jetton: jettonPreview, recipient: accountAddress.optional(), recipients_wallet: z.string(), refund: refund.optional(), sender: accountAddress.optional(), senders_wallet: z.string()}); export const vaultDepositInfo = z.object({price: price, vault: z.string()}); export const liquidityDepositAction = z.object({from: accountAddress, protocol: protocol, tokens: z.array(vaultDepositInfo)}); export const nftItemTransferAction = z.object({comment: z.string().optional(), encrypted_comment: encryptedComment.optional(), nft: z.string(), payload: z.string().optional(), recipient: accountAddress.optional(), refund: refund.optional(), sender: accountAddress.optional()}); export const nftPurchaseAction = z.object({amount: price, auction_type: z.enum(["DNS.ton", "DNS.tg", "NUMBER.tg", "getgems"]), buyer: accountAddress, nft: nftItem, seller: accountAddress}); export const oraclePriceFeed = z.object({display_symbol: z.string(), id: z.string(), rate: z.number().optional()}); export const oracleRequestAction = z.object({price_feeds: z.array(oraclePriceFeed), requester: accountAddress, response_to: accountAddress}); export const metadata = z.object({decryption_key: z.string().optional(), encrypted_binary: z.string()}); export const purchaseAction = z.object({amount: price, destination: accountAddress, invoice_id: z.string(), metadata: metadata, source: accountAddress}); export const removeExtensionAction = z.object({extension: z.string(), wallet: accountAddress}); export const setSignatureAllowedAction = z.object({allowed: z.boolean(), wallet: accountAddress}); export const smartContractAction = z.object({contract: accountAddress, executor: accountAddress, gram_attached: z.number().int(), operation: z.string(), payload: z.string().optional(), refund: refund.optional(), ton_attached: z.number().int().optional()}); export const subscriptionAction = z.object({admin: accountAddress, amount: z.number().int().optional(), beneficiary: accountAddress, initial: z.boolean(), price: price, subscriber: accountAddress, subscription: z.string()}); export const tonTransferAction = z.object({amount: z.number().int(), comment: z.string().optional(), encrypted_comment: encryptedComment.optional(), recipient: accountAddress, refund: refund.optional(), sender: accountAddress}); export const unSubscriptionAction = z.object({admin: accountAddress, beneficiary: accountAddress, subscriber: accountAddress, subscription: z.string()}); export const withdrawStakeAction = z.object({amount: z.number().int(), implementation: poolImplementationType, pool: accountAddress, staker: accountAddress}); export const withdrawStakeRequestAction = z.object({amount: z.number().int().optional(), implementation: poolImplementationType, pool: accountAddress, stake_meta: price.optional(), staker: accountAddress}); export const withdrawTokenStakeRequestAction = z.object({protocol: protocol, stake_meta: price.optional(), staker: accountAddress}); export const withdrawXTRAction = z.object({amount: z.string(), user: accountAddress}); export const actionSimplePreview = z.object({accounts: z.array(accountAddress), action_image: z.string().optional(), description: z.string(), fiat_value: z.string().optional(), name: z.string(), value: z.string().optional(), value_image: z.string().optional()}); export const action = z.object({AddExtension: addExtensionAction.optional(), AuctionBid: auctionBidAction.optional(), BuyXTR: buyXTRAction.optional(), ContractDeploy: contractDeployAction.optional(), DepositStake: depositStakeAction.optional(), DepositTokenStake: depositTokenStakeAction.optional(), DepositXTR: depositXTRAction.optional(), DomainRenew: domainRenewAction.optional(), ElectionsDepositStake: electionsDepositStakeAction.optional(), ElectionsRecoverStake: electionsRecoverStakeAction.optional(), ExtraCurrencyTransfer: extraCurrencyTransferAction.optional(), FlawedJettonTransfer: flawedJettonTransferAction.optional(), GasRelay: gasRelayAction.optional(), JettonBurn: jettonBurnAction.optional(), JettonMint: jettonMintAction.optional(), JettonSwap: jettonSwapAction.optional(), JettonTransfer: jettonTransferAction.optional(), LiquidityDeposit: liquidityDepositAction.optional(), NftItemTransfer: nftItemTransferAction.optional(), NftPurchase: nftPurchaseAction.optional(), OracleRequest: oracleRequestAction.optional(), Purchase: purchaseAction.optional(), RemoveExtension: removeExtensionAction.optional(), SetSignatureAllowedAction: setSignatureAllowedAction.optional(), SmartContractExec: smartContractAction.optional(), Subscribe: subscriptionAction.optional(), TonTransfer: tonTransferAction.optional(), UnSubscribe: unSubscriptionAction.optional(), WithdrawStake: withdrawStakeAction.optional(), WithdrawStakeRequest: withdrawStakeRequestAction.optional(), WithdrawTokenStakeRequest: withdrawTokenStakeRequestAction.optional(), WithdrawXTR: withdrawXTRAction.optional(), base_transactions: z.array(z.string()), simple_preview: actionSimplePreview, status: z.enum(["ok", "failed"]), type: z.enum(["TonTransfer", "ExtraCurrencyTransfer", "ContractDeploy", "JettonTransfer", "FlawedJettonTransfer", "JettonBurn", "JettonMint", "NftItemTransfer", "Subscribe", "UnSubscribe", "AuctionBid", "NftPurchase", "DepositStake", "WithdrawStake", "WithdrawStakeRequest", "ElectionsDepositStake", "ElectionsRecoverStake", "JettonSwap", "SmartContractExec", "DomainRenew", "Purchase", "AddExtension", "RemoveExtension", "SetSignatureAllowedAction", "GasRelay", "DepositTokenStake", "WithdrawTokenStakeRequest", "LiquidityDeposit", "OracleRequest", "BuyXTR", "DepositXTR", "WithdrawXTR", "Unknown"])}); export const valueFlow = z.object({account: accountAddress, fees: z.number().int(), gram: z.number().int(), jettons: z.array(z.object({account: accountAddress, jetton: jettonPreview, qty: z.string(), quantity: z.number().int()})).optional(), ton: z.number().int().optional()}); export const event = z.object({actions: z.array(action), event_id: z.string(), ext_msg_hash: z.string().optional(), in_progress: z.boolean(), is_scam: z.boolean(), last_slice_id: z.number().int().optional(), lt: z.number().int(), progress: z.number().gte(0).lte(1), timestamp: z.number().int(), value_flow: z.array(valueFlow)}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Emulate sending message to retrieve general blockchain events * * POST /v2/events/emulate */ export const createApiV2EventsEmulate = async (args: CreateApiV2EventsEmulateArgs, options?: CreateApiV2EventsEmulateOptions) => { const {baseUrl = "https://tonapi.io", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['Accept-Language'] != null) headers.set("Accept-Language", String(args['Accept-Language'])) if (args.ignore_signature_check != null) query.append("ignore_signature_check", String(args.ignore_signature_check)) const url = `${baseUrl.replace(/\/+$/, '')}/v2/events/emulate${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(event, await res.json()) };