UNPKG

@ton-api/ton-adapter

Version:
1 lines 12.3 kB
{"version":3,"sources":["../src/tonapi-adapter.ts"],"sourcesContent":["import {\n Address,\n beginCell,\n Cell,\n comment,\n Contract,\n ContractProvider,\n ContractState,\n external,\n openContract,\n OpenedContract,\n storeMessage,\n toNano,\n Transaction,\n TupleItem,\n TupleReader,\n loadTransaction,\n ExtraCurrency\n} from '@ton/core';\nimport {\n AccountStatus as TonApiAccountStatus,\n TonApiClient,\n BlockchainRawAccount,\n AccountStatus\n} from '@ton-api/client';\nimport { Buffer } from 'buffer';\n\nexport class ContractAdapter {\n constructor(private readonly tonapi: TonApiClient) {}\n\n /**\n * Open smart contract\n * @param contract contract\n * @returns opened contract\n */\n open<T extends Contract>(contract: T) {\n return openContract<T>(contract, args =>\n createProvider(this.tonapi, args.address, args.init)\n );\n }\n\n /**\n * Create provider\n * @param address address\n * @param init optional init data\n * @returns provider\n */\n provider(address: Address, init?: { code?: Cell; data?: Cell } | null) {\n return createProvider(this.tonapi, address, init ? init : null);\n }\n}\ntype LoclaBlockchainRawAccount = Partial<Pick<BlockchainRawAccount, 'lastTransactionLt'>> &\n Omit<BlockchainRawAccount, 'lastTransactionLt'>;\n\nfunction createProvider(\n tonapi: TonApiClient,\n address: Address,\n init: { code?: Cell | null; data?: Cell | null } | null\n): ContractProvider {\n return {\n async getState(): Promise<ContractState> {\n // Load state\n const account: LoclaBlockchainRawAccount = await tonapi.blockchain\n .getBlockchainRawAccount(address)\n .catch((error: Error) => {\n if (error.message !== 'entity not found') {\n throw new Error(`Account request failed: ${error.message}`, error);\n }\n\n const mockResult: LoclaBlockchainRawAccount = {\n address: address,\n balance: 0n,\n lastTransactionLt: undefined,\n status: AccountStatus.Uninit,\n storage: {\n usedCells: 1,\n usedBits: 95,\n usedPublicCells: 0,\n lastPaid: Math.floor(new Date().getTime() / 1000),\n duePayment: 0n\n }\n };\n\n return mockResult;\n });\n\n // Convert state\n const last =\n account.lastTransactionHash !== undefined && account.lastTransactionLt !== undefined\n ? {\n lt: account.lastTransactionLt,\n hash: Buffer.from(account.lastTransactionHash, 'base64')\n }\n : null;\n\n const stateGetters: Record<\n TonApiAccountStatus,\n (account: LoclaBlockchainRawAccount) => ContractState['state']\n > = {\n active: account => ({\n type: 'active',\n code: account.code?.toBoc() ?? null,\n data: account.data?.toBoc() ?? null\n }),\n uninit: () => ({\n type: 'uninit'\n }),\n nonexist: () => ({\n type: 'uninit'\n }),\n frozen: () => {\n throw new Error(`Frozen accounts are not supported by TonApi`);\n }\n };\n\n const extraCurrency: ExtraCurrency | null = account.extraBalance\n ? Object.fromEntries(\n Object.entries(account.extraBalance).map(([k, v]) => [Number(k), BigInt(v)])\n )\n : null;\n\n return {\n balance: account.balance,\n extracurrency: extraCurrency,\n last: last,\n state: stateGetters[account.status](account)\n };\n },\n async get(name, args) {\n if (typeof name !== 'string') {\n throw new Error('Method name must be a string for TonClient provider');\n }\n\n if (args.some(arg => arg.type === 'tuple')) {\n throw new Error('Tuples as get parameters are not supported by tonapi');\n }\n\n const result = await tonapi.blockchain.execGetMethodForBlockchainAccount(\n address,\n name,\n { args: args.map(TupleItemToTonapiString) }\n );\n\n return {\n stack: new TupleReader(result.stack)\n };\n },\n async external(message) {\n // Resolve init\n let neededInit: { code?: Cell | null; data?: Cell | null } | null = null;\n if (init && (await tonapi.accounts.getAccount(address)).status !== 'active') {\n neededInit = init;\n }\n\n // Send with state init\n const ext = external({\n to: address,\n init: neededInit ? { code: neededInit.code, data: neededInit.data } : null,\n body: message\n });\n const boc = beginCell().store(storeMessage(ext)).endCell();\n\n await tonapi.blockchain.sendBlockchainMessage({ boc });\n },\n async internal(via, message) {\n // Resolve init\n let neededInit: { code?: Cell | null; data?: Cell | null } | null = null;\n if (init && (await tonapi.accounts.getAccount(address)).status !== 'active') {\n neededInit = init;\n }\n\n // Resolve bounce\n let bounce = true;\n if (message.bounce !== null && message.bounce !== undefined) {\n bounce = message.bounce;\n }\n\n // Resolve value\n let value: bigint;\n if (typeof message.value === 'string') {\n value = toNano(message.value);\n } else {\n value = message.value;\n }\n\n // Resolve body\n let body: Cell | null = null;\n if (typeof message.body === 'string') {\n body = comment(message.body);\n } else if (message.body) {\n body = message.body;\n }\n\n // Send internal message\n await via.send({\n to: address,\n value,\n bounce,\n sendMode: message.sendMode,\n init: neededInit,\n body\n });\n },\n open<T extends Contract>(contract: T): OpenedContract<T> {\n return openContract(contract, params =>\n createProvider(tonapi, params.address, params.init)\n );\n },\n getTransactions(\n address: Address,\n lt: bigint,\n hash: Buffer,\n limit?: number\n ): Promise<Transaction[]> {\n console.info(\n 'hash param in getTransactions action ignored, beacause not supported',\n hash.toString('hex')\n );\n return tonapi.blockchain\n .getBlockchainAccountTransactions(address, {\n before_lt: lt + 1n,\n limit\n })\n .then(({ transactions }) =>\n transactions.map(transaction => loadTransaction(transaction.raw.asSlice()))\n );\n }\n };\n}\n\nfunction TupleItemToTonapiString(item: TupleItem): string {\n switch (item.type) {\n case 'int':\n return '0x' + item.value.toString(16);\n case 'nan':\n return 'NaN';\n case 'null':\n return 'Null';\n case 'cell':\n case 'builder':\n return item.cell.toBoc().toString('base64');\n case 'slice':\n return item.cell.toBoc().toString('hex');\n case 'tuple':\n throw new Error('Tuple is not supported in TonApi get method parameters');\n default:\n throw new Error(`Unknown type ${(item as { type: string }).type}`);\n }\n}\n"],"mappings":"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","names":["account","address"]}