From 106f3ef188166e70baf7139c7e279ca475b59156 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Mon, 10 Nov 2025 15:47:54 +0000 Subject: [PATCH 01/27] refactor: implement {data, error} response pattern BREAKING CHANGE: All API methods now return {data, error} instead of throwing - Add TonApiError with type field (http_error, network_error, parsing_error) - Rename error fields for better ergonomics (message, code, status, url) - Fix SDK parsing errors (Address.parse, Cell.fromHex, BigInt) - Add typecheck scripts to package.json --- examples/emulate.ts | 23 +- examples/gasless.ts | 47 +- examples/send-jetton.ts | 7 +- package-lock.json | 1170 ++++++++--------- package.json | 3 + packages/client/package.json | 1 + packages/client/src/client.ts | 119 +- packages/client/src/templates/http-client.ejs | 4 +- .../client/src/templates/procedure-call.ejs | 2 +- packages/client/src/templates/utils.ejs | 113 +- packages/ton-adapter/src/tonapi-adapter.ts | 100 +- tests/adapters/utils/contract.ts | 5 +- tests/client/client.test.ts | 37 +- tests/client/errors.test.ts | 73 +- tests/client/parse-address.test.ts | 12 +- tests/client/parse-bigint.test.ts | 23 +- tests/client/parse-cell.test.ts | 22 +- tests/client/parse-tuple.test.ts | 22 +- tests/client/services.test.ts | 34 +- tsconfig.json | 23 + turbo.json | 3 + 21 files changed, 1041 insertions(+), 802 deletions(-) create mode 100644 tsconfig.json diff --git a/examples/emulate.ts b/examples/emulate.ts index ed4d5de..5db4161 100644 --- a/examples/emulate.ts +++ b/examples/emulate.ts @@ -22,8 +22,20 @@ const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9Y const recipientAddress = Address.parse('UQDNzlh0XSZdb5_Qrlx5QjyZHVAO74v5oMeVVrtF_5Vt1rIt'); // Get wallet's seqno and public key -const { seqno } = await ta.wallet.getAccountSeqno(senderAddress); -const { publicKey: publicKeyHex } = await ta.accounts.getAccountPublicKey(senderAddress); +const { data: seqnoData, error: seqnoError } = await ta.wallet.getAccountSeqno(senderAddress); +if (seqnoError) { + console.error('Error getting seqno:', seqnoError.message); + process.exit(1); +} + +const { data: publicKeyData, error: publicKeyError } = await ta.accounts.getAccountPublicKey(senderAddress); +if (publicKeyError) { + console.error('Error getting public key:', publicKeyError.message); + process.exit(1); +} + +const seqno = seqnoData.seqno; +const publicKeyHex = publicKeyData.publicKey; // Emulate transaction from wallet_v4 address const wallet = WalletContractV4.create({ @@ -73,9 +85,14 @@ const bocExternalMessage = beginCell() .endCell(); // Emulate transaction -const emulateTrace = await ta.emulation.emulateMessageToTrace( +const { data: emulateTrace, error: emulateError } = await ta.emulation.emulateMessageToTrace( { boc: bocExternalMessage }, { ignore_signature_check: true } // Ignore signature for execute message from other account ); +if (emulateError) { + console.error('Error emulating message:', emulateError.message); + process.exit(1); +} + console.log(emulateTrace); diff --git a/examples/gasless.ts b/examples/gasless.ts index a6c347d..e0f9113 100644 --- a/examples/gasless.ts +++ b/examples/gasless.ts @@ -47,13 +47,15 @@ const contract = provider.open(wallet); console.log('Wallet address:', wallet.address.toString()); -const jettonWalletAddressResult = await ta.blockchain.execGetMethodForBlockchainAccount( - usdtMaster, - 'get_wallet_address', - { +const { data: jettonWalletAddressResult, error: getWalletError } = + await ta.blockchain.execGetMethodForBlockchainAccount(usdtMaster, 'get_wallet_address', { args: [wallet.address.toRawString()] - } -); + }); + +if (getWalletError) { + console.error('Error getting jetton wallet:', getWalletError.message); + process.exit(1); +} const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address); @@ -90,11 +92,16 @@ const messageToEstimate = beginCell() // we send a single message containing a transfer from our wallet to a desired destination. // as a result of estimation, TonAPI returns a list of messages that we need to sign. // the first message is a fee transfer to the relay address, the second message is our original transfer. -const params = await ta.gasless.gaslessEstimate(usdtMaster, { +const { data: params, error: estimateError } = await ta.gasless.gaslessEstimate(usdtMaster, { walletAddress: wallet.address, walletPublicKey: keyPair.publicKey.toString('hex'), messages: [{ boc: messageToEstimate }] -}); //.catch(error => console.error(error)); +}); + +if (estimateError) { + console.error('Error estimating gasless transfer:', estimateError.message); + process.exit(1); +} console.log('Estimated transfer:', params); @@ -129,16 +136,24 @@ const extMessage = beginCell() .endCell(); // Send a gasless transfer -ta.gasless - .gaslessSend({ - walletPublicKey: keyPair.publicKey.toString('hex'), - boc: extMessage - }) - .then(() => console.log('A gasless transfer sent!')) - .catch(error => console.error(error.message)); +const { data: sendResult, error: sendError } = await ta.gasless.gaslessSend({ + walletPublicKey: keyPair.publicKey.toString('hex'), + boc: extMessage +}); + +if (sendError) { + console.error('Error sending gasless transfer:', sendError.message, sendError.status); +} else { + console.log('A gasless transfer sent!'); +} async function printConfigAndReturnRelayAddress(): Promise
{ - const cfg = await ta.gasless.gaslessConfig(); + const { data: cfg, error } = await ta.gasless.gaslessConfig(); + + if (error) { + console.error('Error getting gasless config:', error.message); + process.exit(1); + } console.log('Available jettons for gasless transfer'); console.log(cfg.gasJettons.map(gasJetton => gasJetton.masterId)); diff --git a/examples/send-jetton.ts b/examples/send-jetton.ts index 96e9e60..1e126f5 100644 --- a/examples/send-jetton.ts +++ b/examples/send-jetton.ts @@ -32,12 +32,17 @@ const wallet = WalletContractV5R1.create({ workchain: 0, publicKey: keyPair.publ const contract = adapter.open(wallet); // Open the wallet contract using the adapter // Get the sender's jetton wallet address from the jetton master contract -const jettonWalletAddressResult = await ta.blockchain.execGetMethodForBlockchainAccount( +const { data: jettonWalletAddressResult, error } = await ta.blockchain.execGetMethodForBlockchainAccount( jettonMaster, 'get_wallet_address', { args: [wallet.address.toRawString()] } ); +if (error) { + console.error('Error getting jetton wallet address:', error.message); + process.exit(1); +} + const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address); // Extract the jetton wallet address // Create payload for the jetton transfer diff --git a/package-lock.json b/package-lock.json index 81724a9..bb641b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,6 +86,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -522,14 +523,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", - "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "dev": true, "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } @@ -600,16 +598,17 @@ "dev": true }, "node_modules/@changesets/apply-release-plan": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.6.tgz", - "integrity": "sha512-TKhVLtiwtQOgMAC0fCJfmv93faiViKSDqr8oMEqrnNs99gtSC1sZh/aEMS9a+dseU1ESZRCK+ofLgGY7o0fw/Q==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.13.tgz", + "integrity": "sha512-BIW7bofD2yAWoE8H4V40FikC+1nNFEKBisMECccS16W1rt6qqhNTBDmIw5HaqmMgtLNz9e7oiALiEUuKrQ4oHg==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/config": "^3.0.4", + "@changesets/config": "^3.1.1", "@changesets/get-version-range-type": "^0.4.0", - "@changesets/git": "^3.0.2", - "@changesets/should-skip-package": "^0.1.1", - "@changesets/types": "^6.0.0", + "@changesets/git": "^3.0.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", @@ -625,6 +624,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -639,6 +639,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -648,6 +649,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -663,6 +665,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -672,58 +675,62 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/@changesets/assemble-release-plan": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.5.tgz", - "integrity": "sha512-IgvBWLNKZd6k4t72MBTBK3nkygi0j3t3zdC1zrfusYo0KpdsvnDjrMM9vPnTCLCMlfNs55jRL4gIMybxa64FCQ==", + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.9.tgz", + "integrity": "sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==", "dev": true, + "license": "MIT", "dependencies": { "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.1.2", - "@changesets/should-skip-package": "^0.1.1", - "@changesets/types": "^6.0.0", + "@changesets/get-dependents-graph": "^2.1.3", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "semver": "^7.5.3" } }, "node_modules/@changesets/changelog-git": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz", - "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz", + "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/types": "^6.0.0" + "@changesets/types": "^6.1.0" } }, "node_modules/@changesets/cli": { - "version": "2.27.10", - "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.10.tgz", - "integrity": "sha512-PfeXjvs9OfQJV8QSFFHjwHX3QnUL9elPEQ47SgkiwzLgtKGyuikWjrdM+lO9MXzOE22FO9jEGkcs4b+B6D6X0Q==", + "version": "2.29.7", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.29.7.tgz", + "integrity": "sha512-R7RqWoaksyyKXbKXBTbT4REdy22yH81mcFK6sWtqSanxUCbUi9Uf+6aqxZtDQouIqPdem2W56CdxXgsxdq7FLQ==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/apply-release-plan": "^7.0.6", - "@changesets/assemble-release-plan": "^6.0.5", - "@changesets/changelog-git": "^0.2.0", - "@changesets/config": "^3.0.4", + "@changesets/apply-release-plan": "^7.0.13", + "@changesets/assemble-release-plan": "^6.0.9", + "@changesets/changelog-git": "^0.2.1", + "@changesets/config": "^3.1.1", "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.1.2", - "@changesets/get-release-plan": "^4.0.5", - "@changesets/git": "^3.0.2", + "@changesets/get-dependents-graph": "^2.1.3", + "@changesets/get-release-plan": "^4.0.13", + "@changesets/git": "^3.0.4", "@changesets/logger": "^0.1.1", - "@changesets/pre": "^2.0.1", - "@changesets/read": "^0.6.2", - "@changesets/should-skip-package": "^0.1.1", - "@changesets/types": "^6.0.0", - "@changesets/write": "^0.3.2", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.5", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@changesets/write": "^0.4.0", + "@inquirer/external-editor": "^1.0.0", "@manypkg/get-packages": "^1.1.3", "ansi-colors": "^4.1.3", "ci-info": "^3.7.0", - "enquirer": "^2.3.0", - "external-editor": "^3.1.0", + "enquirer": "^2.4.1", "fs-extra": "^7.0.1", "mri": "^1.2.0", "p-limit": "^2.2.0", @@ -738,6 +745,20 @@ "changeset": "bin.js" } }, + "node_modules/@changesets/cli/node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/@changesets/cli/node_modules/fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", @@ -795,15 +816,16 @@ } }, "node_modules/@changesets/config": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.4.tgz", - "integrity": "sha512-+DiIwtEBpvvv1z30f8bbOsUQGuccnZl9KRKMM/LxUHuDu5oEjmN+bJQ1RIBKNJjfYMQn8RZzoPiX0UgPaLQyXw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.1.tgz", + "integrity": "sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==", "dev": true, + "license": "MIT", "dependencies": { "@changesets/errors": "^0.2.0", - "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-dependents-graph": "^2.1.3", "@changesets/logger": "^0.1.1", - "@changesets/types": "^6.0.0", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "fs-extra": "^7.0.1", "micromatch": "^4.0.8" @@ -814,6 +836,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -828,6 +851,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -837,6 +861,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -846,33 +871,36 @@ "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", "dev": true, + "license": "MIT", "dependencies": { "extendable-error": "^0.1.5" } }, "node_modules/@changesets/get-dependents-graph": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz", - "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.3.tgz", + "integrity": "sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/types": "^6.0.0", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "picocolors": "^1.1.0", "semver": "^7.5.3" } }, "node_modules/@changesets/get-release-plan": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.5.tgz", - "integrity": "sha512-E6wW7JoSMcctdVakut0UB76FrrN3KIeJSXvB+DHMFo99CnC3ZVnNYDCVNClMlqAhYGmLmAj77QfApaI3ca4Fkw==", + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.13.tgz", + "integrity": "sha512-DWG1pus72FcNeXkM12tx+xtExyH/c9I1z+2aXlObH3i9YA7+WZEVaiHzHl03thpvAgWTRaH64MpfHxozfF7Dvg==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/assemble-release-plan": "^6.0.5", - "@changesets/config": "^3.0.4", - "@changesets/pre": "^2.0.1", - "@changesets/read": "^0.6.2", - "@changesets/types": "^6.0.0", + "@changesets/assemble-release-plan": "^6.0.9", + "@changesets/config": "^3.1.1", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.5", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3" } }, @@ -880,13 +908,15 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@changesets/git": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.2.tgz", - "integrity": "sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz", + "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==", "dev": true, + "license": "MIT", "dependencies": { "@changesets/errors": "^0.2.0", "@manypkg/get-packages": "^1.1.3", @@ -900,17 +930,19 @@ "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", "dev": true, + "license": "MIT", "dependencies": { "picocolors": "^1.1.0" } }, "node_modules/@changesets/parse": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz", - "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.1.tgz", + "integrity": "sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/types": "^6.0.0", + "@changesets/types": "^6.1.0", "js-yaml": "^3.13.1" } }, @@ -919,6 +951,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -928,6 +961,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -937,13 +971,14 @@ } }, "node_modules/@changesets/pre": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz", - "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz", + "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==", "dev": true, + "license": "MIT", "dependencies": { "@changesets/errors": "^0.2.0", - "@changesets/types": "^6.0.0", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "fs-extra": "^7.0.1" } @@ -953,6 +988,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -967,6 +1003,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -976,20 +1013,22 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/@changesets/read": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.2.tgz", - "integrity": "sha512-wjfQpJvryY3zD61p8jR87mJdyx2FIhEcdXhKUqkja87toMrP/3jtg/Yg29upN+N4Ckf525/uvV7a4tzBlpk6gg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.5.tgz", + "integrity": "sha512-UPzNGhsSjHD3Veb0xO/MwvasGe8eMyNrR/sT9gR8Q3DhOQZirgKhhXv/8hVsI0QpPjR004Z9iFxoJU6in3uGMg==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/git": "^3.0.2", + "@changesets/git": "^3.0.4", "@changesets/logger": "^0.1.1", - "@changesets/parse": "^0.4.0", - "@changesets/types": "^6.0.0", + "@changesets/parse": "^0.4.1", + "@changesets/types": "^6.1.0", "fs-extra": "^7.0.1", "p-filter": "^2.1.0", "picocolors": "^1.1.0" @@ -1000,6 +1039,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1014,6 +1054,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -1023,35 +1064,39 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, "node_modules/@changesets/should-skip-package": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz", - "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz", + "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/types": "^6.0.0", + "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3" } }, "node_modules/@changesets/types": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz", - "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==", - "dev": true + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz", + "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==", + "dev": true, + "license": "MIT" }, "node_modules/@changesets/write": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", - "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz", + "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==", "dev": true, + "license": "MIT", "dependencies": { - "@changesets/types": "^6.0.0", + "@changesets/types": "^6.1.0", "fs-extra": "^7.0.1", - "human-id": "^1.0.2", + "human-id": "^4.1.1", "prettier": "^2.7.1" } }, @@ -1060,6 +1105,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1074,6 +1120,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -1083,6 +1130,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -1098,36 +1146,11 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", @@ -1601,10 +1624,11 @@ } }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1651,10 +1675,11 @@ } }, "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1700,6 +1725,52 @@ "node": ">=10.13.0" } }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor/node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2239,10 +2310,11 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2726,6 +2798,7 @@ "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", "@types/node": "^12.7.1", @@ -2737,13 +2810,15 @@ "version": "12.20.55", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@manypkg/find-root/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -2757,6 +2832,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -2771,6 +2847,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -2780,6 +2857,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -2792,6 +2870,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -2807,6 +2886,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -2819,6 +2899,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -2828,6 +2909,7 @@ "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.5.5", "@changesets/types": "^4.0.1", @@ -2841,13 +2923,15 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@manypkg/get-packages/node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -2862,6 +2946,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -2871,6 +2956,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.0.0" } @@ -2915,7 +3001,6 @@ "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.3.1.tgz", "integrity": "sha512-MtHlsdErSz0Z1j8j+qAKUafWzMs3XcHgXmJomjUzect1jS/HtmbcDvdMv9GwVtk+67JD+7ca2CWjk2atv6dZdw==", "dev": true, - "peer": true, "dependencies": { "@nx/devkit": "17.3.1" } @@ -2925,7 +3010,6 @@ "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.3.1.tgz", "integrity": "sha512-bohZt2rzqCz2ITOpQ6H7sYlHhxn3NftHDz0a0QVVDJojjpak73r8XV0zCk2yUN2T8HdRJVyYLyAqDENl9X48pA==", "dev": true, - "peer": true, "dependencies": { "nx": "17.3.1", "tslib": "^2.3.0" @@ -2939,7 +3023,6 @@ "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.3.1.tgz", "integrity": "sha512-E44feT7x/pGTzMWSndjTAoBXvZYEdy2SU99O14LdW7atUK4gv0glKUfyq6nNFULrs6r173WKfJgfmJDL3l78lg==", "dev": true, - "peer": true, "dependencies": { "@nrwl/devkit": "17.3.1", "ejs": "^3.1.7", @@ -2959,7 +3042,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, - "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -2982,7 +3064,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10" } @@ -2999,7 +3080,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3016,7 +3096,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3033,7 +3112,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3050,7 +3128,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3067,7 +3144,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3084,7 +3160,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3101,7 +3176,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3118,7 +3192,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3135,7 +3208,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3503,6 +3575,7 @@ "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.60.1.tgz", "integrity": "sha512-8FwybYbfkk57C3l9gvnlRhRBHbLYmeu0LbB1z9N+dhDz0Z+FJW8w0TJlks8CgHrAFxsT3FlR2LsqFnsauMp38w==", "license": "MIT", + "peer": true, "dependencies": { "symbol.inspect": "1.0.1" }, @@ -3514,6 +3587,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/@ton/crypto/-/crypto-3.3.0.tgz", "integrity": "sha512-/A6CYGgA/H36OZ9BbTaGerKtzWp50rg67ZCH2oIjV1NcrBaCK9Z343M+CxedvM7Haf3f/Ee9EhxyeTp0GKMUpA==", + "peer": true, "dependencies": { "@ton/crypto-primitives": "2.1.0", "jssha": "3.2.0", @@ -3546,38 +3620,6 @@ "@ton/crypto": ">=3.2.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3742,6 +3784,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.20.0", @@ -3777,6 +3820,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.20.0", "@typescript-eslint/types": "6.20.0", @@ -4030,7 +4074,6 @@ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", "dev": true, - "peer": true, "dependencies": { "js-yaml": "^3.10.0", "tslib": "^2.4.0" @@ -4044,7 +4087,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "peer": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -4054,7 +4096,6 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4068,7 +4109,6 @@ "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", "dev": true, - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4081,6 +4121,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4097,20 +4138,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", @@ -4196,14 +4223,6 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -4346,23 +4365,14 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true, - "engines": { - "node": ">= 4.0.0" - } + "license": "MIT" }, "node_modules/available-typed-arrays": { "version": "1.0.6", @@ -4377,14 +4387,14 @@ } }, "node_modules/axios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", - "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, @@ -4605,6 +4615,7 @@ "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", "dev": true, + "license": "MIT", "dependencies": { "is-windows": "^1.0.0" }, @@ -4624,10 +4635,11 @@ } }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -4663,6 +4675,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001580", "electron-to-chromium": "^1.4.648", @@ -4766,6 +4779,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/call-me-maybe": { "version": "1.0.2", "dev": true, @@ -4962,6 +4989,7 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -5352,14 +5380,6 @@ "node": ">=8" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -5480,7 +5500,6 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -5507,6 +5526,7 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -5534,17 +5554,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", @@ -5595,7 +5604,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz", "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -5608,17 +5616,30 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", "dev": true, - "peer": true, "engines": { "node": ">=12" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/eastasianwidth": { "version": "0.2.0", @@ -5631,7 +5652,6 @@ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, - "peer": true, "dependencies": { "jake": "^10.8.5" }, @@ -5676,7 +5696,6 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "peer": true, "dependencies": { "once": "^1.4.0" } @@ -5763,22 +5782,57 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-module-lexer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", - "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -5822,6 +5876,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -5877,6 +5932,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5975,6 +6031,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -6033,6 +6090,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, + "peer": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -6060,10 +6118,11 @@ } }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6215,10 +6274,11 @@ } }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6458,7 +6518,8 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/external-editor": { "version": "3.1.0", @@ -6593,7 +6654,6 @@ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, - "peer": true, "dependencies": { "minimatch": "^5.0.1" } @@ -6603,7 +6663,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6653,7 +6712,6 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "peer": true, "bin": { "flat": "cli.js" } @@ -6673,10 +6731,11 @@ } }, "node_modules/flat-cache/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6793,13 +6852,16 @@ } }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -6810,15 +6872,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -6902,15 +6962,25 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6925,6 +6995,20 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -7083,12 +7167,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7161,10 +7246,11 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -7173,10 +7259,14 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.1.tgz", - "integrity": "sha512-6J4rC9ROz0UkOpjn0BRtSSqlewDTDYJNQvy8N8RSrPCduUWId1o9BQPEVII/KKBqRk/ZIQff1YbRkUDCH2N5Sg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { "node": ">= 0.4" }, @@ -7185,10 +7275,11 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -7229,10 +7320,14 @@ "license": "MIT" }, "node_modules/human-id": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", - "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", - "dev": true + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.1.2.tgz", + "integrity": "sha512-v/J+4Z/1eIJovEBdlV5TYj1IR+ZiohcYGRY+qN/oC9dAfKzVT023N/Bgw37hrKCoVRBvk3bqyzpr2PP5YeTMSg==", + "dev": true, + "license": "MIT", + "bin": { + "human-id": "dist/cli.js" + } }, "node_modules/human-signals": { "version": "2.1.0", @@ -7729,6 +7824,7 @@ "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", "dev": true, + "license": "MIT", "dependencies": { "better-path-resolve": "1.0.0" }, @@ -7807,6 +7903,7 @@ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7945,7 +8042,6 @@ "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, - "peer": true, "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -7964,7 +8060,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -7976,11 +8071,11 @@ } }, "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7991,7 +8086,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -8008,7 +8102,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -8020,15 +8113,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jake/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -8038,7 +8129,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -8051,7 +8141,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8064,6 +8153,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -8364,10 +8454,11 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9176,10 +9267,11 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9798,8 +9890,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jsonfile": { "version": "6.1.0", @@ -9964,7 +10055,8 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -10109,6 +10201,16 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/meow": { "version": "12.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", @@ -10154,6 +10256,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -10163,6 +10266,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -10332,8 +10436,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-readfiles": { "version": "0.2.0", @@ -10391,7 +10494,6 @@ "integrity": "sha512-D7moIq+0D9WSjQmkVsce7GxKF603XASGBTApX6+fAdl2KN3aGG8zPlOEE55sVT0/OsdHeoHXPmydL/egTpG2WQ==", "dev": true, "hasInstallScript": true, - "peer": true, "dependencies": { "@nrwl/tao": "17.3.1", "@yarnpkg/lockfile": "^1.1.0", @@ -10462,7 +10564,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -10478,7 +10579,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10495,7 +10595,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10507,15 +10606,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/nx/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -10525,7 +10622,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -10538,7 +10634,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", "dev": true, - "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -10548,7 +10643,6 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", "dev": true, - "peer": true, "dependencies": { "bl": "^4.0.3", "chalk": "^4.1.0", @@ -10571,7 +10665,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, - "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -10587,7 +10680,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -10600,7 +10692,6 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, - "peer": true, "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -10809,7 +10900,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "peer": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -10945,13 +11035,15 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", "dev": true, + "license": "MIT", "dependencies": { "p-map": "^2.0.0" }, @@ -10994,6 +11086,7 @@ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -11042,25 +11135,25 @@ } }, "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.1.tgz", + "integrity": "sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==", "dev": true, + "license": "MIT", "dependencies": { "@yarnpkg/lockfile": "^1.1.0", "chalk": "^4.1.2", "ci-info": "^3.7.0", "cross-spawn": "^7.0.3", "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", + "fs-extra": "^10.0.0", "json-stable-stringify": "^1.0.2", "klaw-sync": "^6.0.0", "minimist": "^1.2.6", "open": "^7.4.2", - "rimraf": "^2.6.3", "semver": "^7.5.3", "slash": "^2.0.0", - "tmp": "^0.0.33", + "tmp": "^0.2.4", "yaml": "^2.2.2" }, "bin": { @@ -11086,16 +11179,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/patch-package/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/patch-package/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -11131,39 +11214,18 @@ "dev": true }, "node_modules/patch-package/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, + "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/patch-package/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12" } }, "node_modules/patch-package/node_modules/has-flag": { @@ -11175,18 +11237,6 @@ "node": ">=8" } }, - "node_modules/patch-package/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/patch-package/node_modules/open": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", @@ -11203,19 +11253,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/patch-package/node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -11237,18 +11274,6 @@ "node": ">=8" } }, - "node_modules/patch-package/node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/patch-package/node_modules/yaml": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", @@ -11367,6 +11392,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -11464,6 +11490,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -11487,6 +11514,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -11809,6 +11837,7 @@ "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.5", "js-yaml": "^3.6.1", @@ -11824,6 +11853,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -11833,6 +11863,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -11877,12 +11908,6 @@ "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -12356,6 +12381,7 @@ "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", "dev": true, + "license": "SEE LICENSE IN LICENSE", "dependencies": { "cross-spawn": "^7.0.5", "signal-exit": "^4.0.1" @@ -12366,6 +12392,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -12609,7 +12636,6 @@ "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", "dev": true, - "peer": true, "dependencies": { "duplexer": "^0.1.1", "minimist": "^1.2.0", @@ -12753,7 +12779,6 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, - "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -12798,10 +12823,11 @@ } }, "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -12899,14 +12925,14 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.3", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -12916,11 +12942,14 @@ } }, "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "picomatch": "^3 || ^4" }, @@ -12931,11 +12960,12 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -12974,77 +13004,13 @@ } }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "peer": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/tmp/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "peer": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/tmp/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/tmp/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" - } - }, - "node_modules/tmp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "peer": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=14.14" } }, "node_modules/tmpl": { @@ -13156,51 +13122,6 @@ "node": ">=6" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -13360,20 +13281,6 @@ "webidl-conversions": "^4.0.2" } }, - "node_modules/tsup/node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/tsx": { "version": "4.19.3", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", @@ -13604,6 +13511,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13709,14 +13617,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -13764,16 +13664,51 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-node/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite-node/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vite-node/node_modules/vite": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz", - "integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -13836,21 +13771,6 @@ } } }, - "node_modules/vite-node/node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/vitest": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz", @@ -13948,16 +13868,52 @@ } } }, + "node_modules/vitest/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vitest/node_modules/vite": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz", - "integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -14020,21 +13976,6 @@ } } }, - "node_modules/vitest/node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -14322,17 +14263,6 @@ "node": ">=12" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -14454,7 +14384,7 @@ }, "packages/ton-adapter": { "name": "@ton-api/ton-adapter", - "version": "0.4.0", + "version": "0.4.1", "license": "MIT", "devDependencies": { "@ton-api/client": "^0.4.0", diff --git a/package.json b/package.json index 9e8d939..2d6e021 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,9 @@ "build:client": "turbo run build --filter=@ton-api/client", "build:adapters": "turbo run build --filter=@ton-api/ton-adapter", "build:watch": "turbo run build:watch", + "typecheck": "npm run typecheck:tests && turbo run typecheck", + "typecheck:tests": "tsc --noEmit", + "typecheck:client": "turbo run typecheck --filter=@ton-api/client", "lint": "turbo run lint", "lint:fix": "turbo run lint:fix", "clean": "turbo run clean && rimraf node_modules" diff --git a/packages/client/package.json b/packages/client/package.json index adf950e..3e9da22 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -32,6 +32,7 @@ }, "scripts": { "build": "npm run clean && npx tsx ./src/generate.ts && npx tsc", + "typecheck": "npx tsc --noEmit", "patch": "npm run build && git diff --quiet || (npm version patch && npm run build)", "prepublishOnly": "npm run build && git diff --quiet || (echo 'Error: Uncommitted changes detected.' && exit 1)", "clean": "rimraf ./dist" diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index bd31ca0..52b9493 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3539,6 +3539,8 @@ class HttpClient { this.abortControllers.delete(cancelToken); } + // Return result object instead of throwing + // prepareResponse will handle error conversion if (!response.ok) throw result; return result.data; }); @@ -5782,6 +5784,28 @@ const components = { }; type ComponentRef = keyof typeof components; +export interface TonApiError { + /** Human-readable error message */ + message: string; + + /** Error type for programmatic handling */ + type?: 'http_error' | 'network_error' | 'parsing_error'; + + /** Error code from API response (for http_error) */ + code?: string; + + /** HTTP status code (for http_error) */ + status?: number; + + /** Request URL for debugging */ + url?: string; + + /** Original error/response for advanced debugging */ + cause?: unknown; +} + +export type Result = { data: T; error: null } | { data: null; error: TonApiError }; + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, match => match[1]?.toUpperCase() ?? ''); } @@ -5798,35 +5822,86 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } -async function prepareResponse(promise: Promise, orSchema?: any): Promise { +async function prepareResponse(promise: Promise, orSchema?: any): Promise> { return await promise - .then(obj => prepareResponseData(obj, orSchema)) + .then(obj => { + try { + // Parse and transform response data + const data = prepareResponseData(obj, orSchema); + return { data, error: null } as Result; + } catch (parseError: unknown) { + // SDK parsing error (Address.parse, Cell.fromHex, BigInt conversion, etc.) + const message = + parseError instanceof Error + ? `SDK parsing error: ${parseError.message}` + : 'SDK parsing error: Unknown error'; + + return { + data: null, + error: { + message, + type: 'parsing_error', + cause: parseError + } + } as Result; + } + }) .catch(async response => { - let errorMessage: string = 'Unknown error occurred'; - + // Network error (fetch failed) if (response instanceof Error) { - errorMessage = response.message || 'Unknown fetch error'; - } else if ( - response && - typeof response === 'object' && - typeof response.error === 'string' - ) { - try { - const errorJson = JSONParse(response.error); - errorMessage = - typeof errorJson === 'string' - ? errorJson - : errorJson?.error || `Wrong error response: ${response.error}`; - } catch (jsonParseError: unknown) { - if (jsonParseError instanceof Error) { - errorMessage = `Failed to parse error response: ${jsonParseError.message}`; - } else { - errorMessage = 'Failed to parse error response: Unknown parsing error'; + return { + data: null, + error: { + message: response.message || 'Network error', + type: 'network_error', + cause: response + } + } as Result; + } + + // HTTP error with response + if (response && typeof response === 'object' && response.status !== undefined) { + const status = response.status; + const url = response.url; + let message: string = 'Request failed'; + let code: string | undefined = undefined; + + if (typeof response.error === 'string') { + try { + const errorJson = JSONParse(response.error); + + if (typeof errorJson === 'string') { + message = errorJson; + } else if (errorJson && typeof errorJson === 'object') { + message = errorJson.error || errorJson.message || 'Request failed'; + code = errorJson.code || errorJson.error_code; + } + } catch (jsonParseError: unknown) { + message = 'Failed to parse error response'; } } + + return { + data: null, + error: { + message, + type: 'http_error', + code, + status, + url, + cause: response + } + } as Result; } - throw new Error(errorMessage, { cause: response }); + // Unknown error + return { + data: null, + error: { + message: 'Unknown error occurred', + cause: response + } + } as Result; }); } diff --git a/packages/client/src/templates/http-client.ejs b/packages/client/src/templates/http-client.ejs index 0918511..e319333 100644 --- a/packages/client/src/templates/http-client.ejs +++ b/packages/client/src/templates/http-client.ejs @@ -277,7 +277,7 @@ class HttpClient { return r; } r.error = data as E; - + return r; }) .catch(e => { @@ -289,6 +289,8 @@ class HttpClient { this.abortControllers.delete(cancelToken); } + // Return result object instead of throwing + // prepareResponse will handle error conversion if (!response.ok) throw result; return result.data; }); diff --git a/packages/client/src/templates/procedure-call.ejs b/packages/client/src/templates/procedure-call.ejs index 5c3226e..7bb2ef5 100644 --- a/packages/client/src/templates/procedure-call.ejs +++ b/packages/client/src/templates/procedure-call.ejs @@ -71,7 +71,7 @@ const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || n const responseFormatTmpl = responseContentKind[successResponse.contentKind] || null; const securityTmpl = security ? 'true' : null; -const describeReturnType = () => !config.toJS ? '' : `Promise`; +const describeReturnType = () => !config.toJS ? '' : `Promise>`; const reducedPathParams = addressType.map((name) => `const ${name} = ${getNameAddressFromId(name)}.toRawString();`).join('\n'); diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index a332a6e..50d8a54 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -1,5 +1,29 @@ type ComponentRef = keyof typeof components; +export interface TonApiError { + /** Human-readable error message */ + message: string; + + /** Error type for programmatic handling */ + type?: 'http_error' | 'network_error' | 'parsing_error'; + + /** Error code from API response (for http_error) */ + code?: string; + + /** HTTP status code (for http_error) */ + status?: number; + + /** Request URL for debugging */ + url?: string; + + /** Original error/response for advanced debugging */ + cause?: unknown; +} + +export type Result = + | { data: T; error: null } + | { data: null; error: TonApiError }; + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, (match) => match[1]?.toUpperCase() ?? ''); } @@ -16,30 +40,85 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } -async function prepareResponse(promise: Promise, orSchema?: any): Promise { +async function prepareResponse(promise: Promise, orSchema?: any): Promise> { return await promise - .then(obj => prepareResponseData(obj, orSchema)) - .catch(async response => { - let errorMessage: string = 'Unknown error occurred'; + .then(obj => { + try { + // Parse and transform response data + const data = prepareResponseData(obj, orSchema); + return { data, error: null } as Result; + } catch (parseError: unknown) { + // SDK parsing error (Address.parse, Cell.fromHex, BigInt conversion, etc.) + const message = parseError instanceof Error + ? `SDK parsing error: ${parseError.message}` + : 'SDK parsing error: Unknown error'; + return { + data: null, + error: { + message, + type: 'parsing_error', + cause: parseError + } + } as Result; + } + }) + .catch(async response => { + // Network error (fetch failed) if (response instanceof Error) { - errorMessage = response.message || 'Unknown fetch error'; - } else if (response && typeof response === 'object' && typeof response.error === 'string') { - try { - const errorJson = JSONParse(response.error); - errorMessage = typeof errorJson === 'string' - ? errorJson : - errorJson?.error || `Wrong error response: ${response.error}`; - } catch (jsonParseError: unknown) { - if (jsonParseError instanceof Error) { - errorMessage = `Failed to parse error response: ${jsonParseError.message}`; - } else { - errorMessage = 'Failed to parse error response: Unknown parsing error'; + return { + data: null, + error: { + message: response.message || 'Network error', + type: 'network_error', + cause: response + } + } as Result; + } + + // HTTP error with response + if (response && typeof response === 'object' && response.status !== undefined) { + const status = response.status; + const url = response.url; + let message: string = 'Request failed'; + let code: string | undefined = undefined; + + if (typeof response.error === 'string') { + try { + const errorJson = JSONParse(response.error); + + if (typeof errorJson === 'string') { + message = errorJson; + } else if (errorJson && typeof errorJson === 'object') { + message = errorJson.error || errorJson.message || 'Request failed'; + code = errorJson.code || errorJson.error_code; + } + } catch (jsonParseError: unknown) { + message = 'Failed to parse error response'; } } + + return { + data: null, + error: { + message, + type: 'http_error', + code, + status, + url, + cause: response + } + } as Result; } - throw new Error(errorMessage, { cause: response }); + // Unknown error + return { + data: null, + error: { + message: 'Unknown error occurred', + cause: response + } + } as Result; }); } diff --git a/packages/ton-adapter/src/tonapi-adapter.ts b/packages/ton-adapter/src/tonapi-adapter.ts index 7cd185a..ddfa5b8 100644 --- a/packages/ton-adapter/src/tonapi-adapter.ts +++ b/packages/ton-adapter/src/tonapi-adapter.ts @@ -60,29 +60,33 @@ function createProvider( return { async getState(): Promise { // Load state - const account: LoclaBlockchainRawAccount = await tonapi.blockchain - .getBlockchainRawAccount(address) - .catch((error: Error) => { - if (error.message !== 'entity not found') { - throw new Error(`Account request failed: ${error.message}`, error); + const { data: accountData, error: accountError } = + await tonapi.blockchain.getBlockchainRawAccount(address); + + let account: LoclaBlockchainRawAccount; + if (accountError) { + if (accountError.message !== 'entity not found') { + throw new Error(`Account request failed: ${accountError.message}`, accountError); + } + + const mockResult: LoclaBlockchainRawAccount = { + address: address, + balance: 0n, + lastTransactionLt: undefined, + status: AccountStatus.Uninit, + storage: { + usedCells: 1, + usedBits: 95, + usedPublicCells: 0, + lastPaid: Math.floor(new Date().getTime() / 1000), + duePayment: 0n } + }; - const mockResult: LoclaBlockchainRawAccount = { - address: address, - balance: 0n, - lastTransactionLt: undefined, - status: AccountStatus.Uninit, - storage: { - usedCells: 1, - usedBits: 95, - usedPublicCells: 0, - lastPaid: Math.floor(new Date().getTime() / 1000), - duePayment: 0n - } - }; - - return mockResult; - }); + account = mockResult; + } else { + account = accountData; + } // Convert state const last = @@ -135,12 +139,16 @@ function createProvider( throw new Error('Tuples as get parameters are not supported by tonapi'); } - const result = await tonapi.blockchain.execGetMethodForBlockchainAccount( + const { data: result, error } = await tonapi.blockchain.execGetMethodForBlockchainAccount( address, name, { args: args.map(TupleItemToTonapiString) } ); + if (error) { + throw new Error(`Get method execution failed: ${error.message}`, error); + } + return { stack: new TupleReader(result.stack) }; @@ -148,8 +156,15 @@ function createProvider( async external(message) { // Resolve init let neededInit: { code?: Cell | null; data?: Cell | null } | null = null; - if (init && (await tonapi.accounts.getAccount(address)).status !== 'active') { - neededInit = init; + if (init) { + const { data: accountInfo, error: accountError } = + await tonapi.accounts.getAccount(address); + if (accountError) { + throw new Error(`Failed to get account info: ${accountError.message}`, accountError); + } + if (accountInfo.status !== 'active') { + neededInit = init; + } } // Send with state init @@ -160,13 +175,23 @@ function createProvider( }); const boc = beginCell().store(storeMessage(ext)).endCell(); - await tonapi.blockchain.sendBlockchainMessage({ boc }); + const { error: sendError } = await tonapi.blockchain.sendBlockchainMessage({ boc }); + if (sendError) { + throw new Error(`Failed to send blockchain message: ${sendError.message}`, sendError); + } }, async internal(via, message) { // Resolve init let neededInit: { code?: Cell | null; data?: Cell | null } | null = null; - if (init && (await tonapi.accounts.getAccount(address)).status !== 'active') { - neededInit = init; + if (init) { + const { data: accountInfo, error: accountError } = + await tonapi.accounts.getAccount(address); + if (accountError) { + throw new Error(`Failed to get account info: ${accountError.message}`, accountError); + } + if (accountInfo.status !== 'active') { + neededInit = init; + } } // Resolve bounce @@ -206,7 +231,7 @@ function createProvider( createProvider(tonapi, params.address, params.init) ); }, - getTransactions( + async getTransactions( address: Address, lt: bigint, hash: Buffer, @@ -216,14 +241,21 @@ function createProvider( 'hash param in getTransactions action ignored, beacause not supported', hash.toString('hex') ); - return tonapi.blockchain - .getBlockchainAccountTransactions(address, { + const { data: result, error } = await tonapi.blockchain.getBlockchainAccountTransactions( + address, + { before_lt: lt + 1n, limit - }) - .then(({ transactions }) => - transactions.map(transaction => loadTransaction(transaction.raw.asSlice())) - ); + } + ); + + if (error) { + throw new Error(`Failed to get account transactions: ${error.message}`, error); + } + + return result.transactions.map(transaction => + loadTransaction(transaction.raw.asSlice()) + ); } }; } diff --git a/tests/adapters/utils/contract.ts b/tests/adapters/utils/contract.ts index 6dbc66f..97cf6f9 100644 --- a/tests/adapters/utils/contract.ts +++ b/tests/adapters/utils/contract.ts @@ -37,10 +37,13 @@ export class WalletItem implements Contract { } static async createFromAddress(address: Address) { - const accountData = await ta.blockchain.execGetMethodForBlockchainAccount( + const { data: accountData, error } = await ta.blockchain.execGetMethodForBlockchainAccount( address, 'get_public_key' ); + if (error) { + throw new Error(`Failed to get public key: ${error.message}`); + } const workchain = address.workChain; const publicKey = BigInt(accountData.decoded.public_key); const bufferPublicKey = Buffer.from(publicKey.toString(16), 'hex'); diff --git a/tests/client/client.test.ts b/tests/client/client.test.ts index 7b582dc..77ce20a 100644 --- a/tests/client/client.test.ts +++ b/tests/client/client.test.ts @@ -15,8 +15,9 @@ test('Client status test', async () => { indexing_latency: 8 }); - const res = await ta.utilities.status(); - expect(res).toBeDefined(); + const { data, error } = await ta.utilities.status(); + expect(error).toBeNull(); + expect(data).toBeDefined(); }); test('Client apiKey test', async () => { @@ -25,8 +26,9 @@ test('Client apiKey test', async () => { indexing_latency: 8 }); - const res = await taWithApiKey.utilities.status(); - expect(res).toBeDefined(); + const { data, error } = await taWithApiKey.utilities.status(); + expect(error).toBeNull(); + expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -49,8 +51,9 @@ test('Client apiKey missing test', async () => { }; const localTa = new TonApiClient(config); - const res = await localTa.utilities.status(); - expect(res).toBeDefined(); + const { data, error } = await localTa.utilities.status(); + expect(error).toBeNull(); + expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -73,8 +76,9 @@ test('Client fallback test', async () => { }; const localTa = new TonApiClient(config); - const res = await localTa.blockchain.status(); - expect(res).toBeDefined(); + const { data, error } = await localTa.blockchain.status(); + expect(error).toBeNull(); + expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -92,8 +96,9 @@ test('Client x-tonapi-client header test', async () => { indexing_latency: 8 }); - const res = await ta.utilities.status(); - expect(res).toBeDefined(); + const { data, error } = await ta.utilities.status(); + expect(error).toBeNull(); + expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -138,11 +143,12 @@ test('Client post method in fetch', async () => { 'UQAW2nxA69WYdMr90utDmpeZFwvG4XYcc9iibAP5sZnlojRO' ]; - const res = await ta.accounts.getAccounts({ + const { data, error } = await ta.accounts.getAccounts({ accountIds: accountIds.map(id => Address.parse(id)) }); - expect(res).toBeDefined(); + expect(error).toBeNull(); + expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -158,8 +164,9 @@ test('Client response type for schema outside component (with snake_case)', asyn }); const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9YvxsnV'); - const res = await ta.accounts.getAccountPublicKey(senderAddress); + const { data, error } = await ta.accounts.getAccountPublicKey(senderAddress); - expect(res).toBeDefined(); - expect(res.publicKey).toBe('9544d2cccdd17e06e27f14fd531f803378d27f64710fd6aadc418c53d0660ec6'); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.publicKey).toBe('9544d2cccdd17e06e27f14fd531f803378d27f64710fd6aadc418c53d0660ec6'); }); diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index 1a0b3c8..bfeb46a 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -17,8 +17,9 @@ test('should return a successful response with JSON data', async () => { const mockData = { status: 'ok', uptime: 123456 }; const fetchSpy = mockFetch(mockData); - const result = await ta.utilities.status(); - expect(result).toEqual(mockData); + const { data, error } = await ta.utilities.status(); + expect(error).toBeNull(); + expect(data).toEqual(mockData); expect(fetchSpy).toHaveBeenCalledWith( expect.stringContaining('/v2/status'), expect.any(Object) @@ -29,30 +30,46 @@ test('should handle an error response with a JSON message', async () => { const mockError = { error: 'Invalid request' }; vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - await expect(ta.utilities.status()).rejects.toThrow('Invalid request'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Invalid request'); + expect(error?.status).toBe(400); + expect(error?.type).toBe('http_error'); }); test('should handle an error response with a string message', async () => { vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse('Simple error message', 500)); - await expect(ta.utilities.status()).rejects.toThrow('Simple error message'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Simple error message'); + expect(error?.status).toBe(500); + expect(error?.type).toBe('http_error'); }); -test('should include a cause in the error object', async () => { +test('should include cause in the error object', async () => { const mockError = { error: 'Invalid request' }; vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - await expect(ta.utilities.status()).rejects.toMatchObject({ - message: 'Invalid request', - cause: expect.any(Object) - }); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Invalid request'); + expect(error?.cause).toBeDefined(); + expect(error?.type).toBe('http_error'); }); test('should handle an error response without JSON', async () => { const mockError = new Error('Network failure'); vi.spyOn(global, 'fetch').mockRejectedValueOnce(mockError); - await expect(ta.utilities.status()).rejects.toThrow('Network failure'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Network failure'); + expect(error?.type).toBe('network_error'); }); test('should handle an error response with invalid JSON', async () => { @@ -62,38 +79,58 @@ test('should handle an error response with invalid JSON', async () => { }); vi.spyOn(global, 'fetch').mockResolvedValueOnce(response); - await expect(ta.utilities.status()).rejects.toThrow('Failed to parse error response'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toContain('Failed to parse error response'); + expect(error?.status).toBe(400); + expect(error?.type).toBe('http_error'); }); test('should handle an unknown error type (object)', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce({ message: 'Some unknown error' } as any); - await expect(ta.utilities.status()).rejects.toThrow('Unknown error occurred'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Unknown error occurred'); }); test('should handle an unknown error type (string)', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce('Some unknown error' as any); - await expect(ta.utilities.status()).rejects.toThrow('Unknown error occurred'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Unknown error occurred'); }); test('should handle null as an error', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce(null as any); - await expect(ta.utilities.status()).rejects.toThrow('Unknown error occurred'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Unknown error occurred'); }); test('should handle undefined as an error', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce(undefined as any); - await expect(ta.utilities.status()).rejects.toThrow('Unknown error occurred'); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Unknown error occurred'); }); test('should handle a JSON error response without an error field', async () => { const mockError = { message: 'Some error without error field' }; vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - await expect(ta.utilities.status()).rejects.toThrow( - `Wrong error response: {\"message\":\"Some error without error field\"}` - ); + const { data, error } = await ta.utilities.status(); + expect(data).toBeNull(); + expect(error).not.toBeNull(); + expect(error?.message).toBe('Some error without error field'); + expect(error?.status).toBe(400); + expect(error?.type).toBe('http_error'); }); diff --git a/tests/client/parse-address.test.ts b/tests/client/parse-address.test.ts index 9e757ae..0314245 100644 --- a/tests/client/parse-address.test.ts +++ b/tests/client/parse-address.test.ts @@ -14,10 +14,11 @@ test('Address simple in params & response', async () => { const addressString = 'UQC62nZpm36EFzADVfXDVd_4OpbFyc1D3w3ZvCPHLni8Dst4'; const addressObject = Address.parse(addressString); const addressRawString = addressObject.toRawString(); - const res = await ta.blockchain.getBlockchainRawAccount(addressObject); + const { data, error } = await ta.blockchain.getBlockchainRawAccount(addressObject); - expect(res).toBeDefined(); - expect(Address.isAddress(res.address)).toBe(true); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(Address.isAddress(data?.address)).toBe(true); expect(fetchSpy).toHaveBeenCalledWith( expect.stringContaining(addressRawString), expect.any(Object) @@ -33,9 +34,10 @@ test('Address in request body test', async () => { ]; const accountIds = addressStrings.map(str => Address.parse(str)); - const res = await ta.accounts.getAccounts({ accountIds }); + const { data, error } = await ta.accounts.getAccounts({ accountIds }); - expect(res).toBeDefined(); + expect(error).toBeNull(); + expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ diff --git a/tests/client/parse-bigint.test.ts b/tests/client/parse-bigint.test.ts index daaf1e0..775861f 100644 --- a/tests/client/parse-bigint.test.ts +++ b/tests/client/parse-bigint.test.ts @@ -16,23 +16,24 @@ test('BigInt parse data in number test', async () => { '0:7c9fc62291740a143086c807fe322accfd12737b3c2243676228176707c7ce40' ]; const accountIds = addressStrings.map(addr => Address.parse(addr)); - const res = await ta.accounts.getAccounts({ accountIds }); - const { accounts } = res; + const { data, error } = await ta.accounts.getAccounts({ accountIds }); - expect(res).toBeDefined(); - expect(accounts).toHaveLength(2); - expect(accounts[0].balance).toBe(471698230471698230471698230471698230n); - expect(typeof accounts[0].balance).toBe('bigint'); - expect(accounts[1].balance).toBe(47602800n); - expect(typeof accounts[1].balance).toBe('bigint'); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.accounts).toHaveLength(2); + expect(data?.accounts[0]?.balance).toBe(471698230471698230471698230471698230n); + expect(typeof data?.accounts[0]?.balance).toBe('bigint'); + expect(data?.accounts[1]?.balance).toBe(47602800n); + expect(typeof data?.accounts[1]?.balance).toBe('bigint'); }); test('BigInt parse data in string test', async () => { mockFetch(getJettonInfo); const usdtJettonAddress = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); - const res = await ta.jettons.getJettonInfo(usdtJettonAddress); + const { data, error } = await ta.jettons.getJettonInfo(usdtJettonAddress); - expect(res).toBeDefined(); - expect(typeof res.totalSupply).toBe('bigint'); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(typeof data?.totalSupply).toBe('bigint'); }); diff --git a/tests/client/parse-cell.test.ts b/tests/client/parse-cell.test.ts index d6899ab..90ba9ea 100644 --- a/tests/client/parse-cell.test.ts +++ b/tests/client/parse-cell.test.ts @@ -13,11 +13,12 @@ test('Cell hex in response test', async () => { const addressString = '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'; const addressObject = Address.parse(addressString); - const res = await ta.blockchain.getBlockchainRawAccount(addressObject); + const { data, error } = await ta.blockchain.getBlockchainRawAccount(addressObject); - expect(res).toBeDefined(); - expect(res.code).toBeDefined(); - expect(res.code).toBeInstanceOf(Cell); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.code).toBeDefined(); + expect(data?.code).toBeInstanceOf(Cell); }); test('Cell hex in request body test', async () => { @@ -56,19 +57,20 @@ test('Cell base64 in response test', async () => { const addressString = 'EQDW6q4sRqQwNCmW4qwUpeFSU1Xhd6l3xwJ6jjknBPzxKNtT'; const addressObject = Address.parse(addressString); - const res = await ta.blockchain.execGetMethodForBlockchainAccount( + const { data, error } = await ta.blockchain.execGetMethodForBlockchainAccount( addressObject, 'royalty_params' ); - const cellTupleItem = res.stack[2]; + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.success).toBeDefined(); - expect(res).toBeDefined(); - expect(res.success).toBeDefined(); + const cellTupleItem = data?.stack[2]; expect(cellTupleItem).toBeDefined(); - expect(cellTupleItem.type).toBe('cell'); + expect(cellTupleItem?.type).toBe('cell'); - if (guardCell(cellTupleItem)) { + if (cellTupleItem && guardCell(cellTupleItem)) { expect(cellTupleItem.cell).toBeDefined(); expect(cellTupleItem.cell).toBeInstanceOf(Cell); } else { diff --git a/tests/client/parse-tuple.test.ts b/tests/client/parse-tuple.test.ts index b6d13eb..4b5a685 100644 --- a/tests/client/parse-tuple.test.ts +++ b/tests/client/parse-tuple.test.ts @@ -17,27 +17,29 @@ test('Tuple test', async () => { const addressString = 'Ef_X4pRKtgXOXYMOXNgXNRdlhkNKJ9bTKMfqvj6HDIiQG98F'; const addressObject = Address.parse(addressString); - const res = await ta.blockchain.execGetMethodForBlockchainAccount( + const { data, error } = await ta.blockchain.execGetMethodForBlockchainAccount( addressObject, 'list_nominators' ); - const highLevelTuple = res.stack[0]; - expect(res).toBeDefined(); - expect(res.success).toBeDefined(); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.success).toBeDefined(); + + const highLevelTuple = data?.stack[0]; expect(highLevelTuple).toBeDefined(); - expect(highLevelTuple.type).toBeDefined(); - expect(highLevelTuple.type).toBe('tuple'); + expect(highLevelTuple?.type).toBeDefined(); + expect(highLevelTuple?.type).toBe('tuple'); - if (guardTuple(highLevelTuple)) { + if (highLevelTuple && guardTuple(highLevelTuple)) { expect(highLevelTuple.items).toBeDefined(); const secondLevelTupleFirst = highLevelTuple.items[0]; expect(secondLevelTupleFirst).toBeDefined(); - expect(secondLevelTupleFirst.type).toBeDefined(); - expect(secondLevelTupleFirst.type).toBe('tuple'); + expect(secondLevelTupleFirst?.type).toBeDefined(); + expect(secondLevelTupleFirst?.type).toBe('tuple'); - if (guardTuple(secondLevelTupleFirst)) { + if (secondLevelTupleFirst && guardTuple(secondLevelTupleFirst)) { expect(secondLevelTupleFirst.items).toBeDefined(); } else { throw new Error('Second Tuple guard failed'); diff --git a/tests/client/services.test.ts b/tests/client/services.test.ts index 5670441..26e1654 100644 --- a/tests/client/services.test.ts +++ b/tests/client/services.test.ts @@ -13,19 +13,18 @@ test('getChartRates, should correct parse array in pair', async () => { const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; const addressObject = Address.parse(addressString); - const points = await ta.rates - .getChartRates({ - token: addressObject, - currency: 'rub' - }) - .then(res => res.points); - - expect(points).toBeDefined(); - expect(Array.isArray(points)).toBe(true); + const { data, error } = await ta.rates.getChartRates({ + token: addressObject, + currency: 'rub' + }); - expect(points.length).toBeGreaterThan(0); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.points).toBeDefined(); + expect(Array.isArray(data?.points)).toBe(true); + expect(data?.points?.length).toBeGreaterThan(0); - points.forEach(point => { + data?.points?.forEach(point => { expect(Array.isArray(point)).toBe(true); expect(point.length).toBe(2); @@ -41,15 +40,16 @@ test('getChartRates, should correct parse array in pair', async () => { test('getRates, additionalProperties should be not convert to camelCase', async () => { mockFetch(getRates); - const res = await ta.rates.getRates({ + const { data, error } = await ta.rates.getRates({ tokens: ['TON,TOKEN_WITH_UNDERSCORE'], currencies: ['USD', 'EUR'] }); - expect(res).toBeDefined(); - expect(res.rates).toBeDefined(); - expect(res.rates['TON']).toBeDefined(); - expect(res.rates['TOKEN_WITH_UNDERSCORE']).toBeDefined(); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.rates).toBeDefined(); + expect(data?.rates['TON']).toBeDefined(); + expect(data?.rates['TOKEN_WITH_UNDERSCORE']).toBeDefined(); }); test('getRates, explode in params should be matter', async () => { @@ -67,7 +67,7 @@ test('getRates, explode in params should be matter', async () => { }); expect(fetchSpy).toHaveBeenCalledTimes(1); - const url = fetchSpy.mock.calls[0][0] as string; + const url = fetchSpy.mock.calls[0]?.[0] as string; const searchParams = new URL(url).searchParams; expect(searchParams.get('tokens')).toBe('TON,EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..217bcbb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "bundler", + "paths": { + "@ton-api/client": ["./packages/client/src/client.ts"], + "@ton-api/ton-adapter": ["./packages/ton-adapter/src/index.ts"] + } + }, + "include": [ + "tests/**/*.ts", + "examples/**/*.ts" + ], + "exclude": [ + "node_modules/**", + "packages/**/dist/**", + "packages/**/node_modules/**", + "tests/client/__mock__/fetchMock.ts" + ] +} diff --git a/turbo.json b/turbo.json index 4867ddb..3753453 100644 --- a/turbo.json +++ b/turbo.json @@ -14,6 +14,9 @@ "dependsOn": ["build"], "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"] }, + "typecheck": { + "outputs": [] + }, "clean": { "cache": false }, From 842fc5655954237cd1d39306b8fe88496a8457d9 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Tue, 11 Nov 2025 01:54:56 +0400 Subject: [PATCH 02/27] feat: add schema patching system for OpenAPI client generation - Introduced a schema patching system that allows modifications to the OpenAPI schema before client generation. - Added functionality to deep merge patches from `src/schema-patches.json` into the downloaded schema. - Implemented a method to apply patches automatically during the build process. - Updated `generate.ts` to include schema patching logic, enhancing the flexibility of the API client generation process. --- package-lock.json | 11 + packages/client/package.json | 2 + packages/client/src/api.yml | 877 ++++++++++++------------ packages/client/src/generate.ts | 96 +++ packages/client/src/schema-patches.json | 23 + 5 files changed, 570 insertions(+), 439 deletions(-) create mode 100644 packages/client/src/schema-patches.json diff --git a/package-lock.json b/package-lock.json index bb641b6..288fe04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3710,6 +3710,13 @@ "pretty-format": "^29.0.0" } }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -9806,6 +9813,8 @@ }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { @@ -14292,7 +14301,9 @@ "core-js-pure": "^3.38.0" }, "devDependencies": { + "@types/js-yaml": "^4.0.9", "@types/node": "^20.14.2", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", "patch-package": "^8.0.0", "rimraf": "^5.0.7", diff --git a/packages/client/package.json b/packages/client/package.json index 3e9da22..8dc4346 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -38,7 +38,9 @@ "clean": "rimraf ./dist" }, "devDependencies": { + "@types/js-yaml": "^4.0.9", "@types/node": "^20.14.2", + "js-yaml": "^4.1.0", "lodash": "^4.17.21", "patch-package": "^8.0.0", "rimraf": "^5.0.7", diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index be0f01c..c155349 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -7,10 +7,9 @@ info: name: Support email: support@tonkeeper.com servers: - - url: "https://tonapi.io" - - url: "https://testnet.tonapi.io" - - url: "http://localhost:8081" - + - url: https://tonapi.io + - url: https://testnet.tonapi.io + - url: http://localhost:8081 tags: - name: Accounts externalDocs: @@ -88,7 +87,6 @@ tags: externalDocs: description: Additional documentation url: https://docs.tonconsole.com/tonapi/rest-api/extra-currency - paths: /v2/openapi.json: get: @@ -101,8 +99,8 @@ paths: description: openapi.json content: application/json: - schema: { } # Free-form JSON value - 'default': + schema: {} + default: $ref: '#/components/responses/Error' /v2/openapi.yml: get: @@ -118,7 +116,7 @@ paths: schema: type: string format: binary - 'default': + default: $ref: '#/components/responses/Error' /v2/status: get: @@ -133,7 +131,7 @@ paths: application/json: schema: $ref: '#/components/schemas/ServiceStatus' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/reduced/blocks: get: @@ -151,7 +149,7 @@ paths: application/json: schema: $ref: '#/components/schemas/ReducedBlocks' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/blocks/{block_id}: get: @@ -168,7 +166,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainBlock' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/masterchain/{masterchain_seqno}/shards: get: @@ -185,7 +183,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainBlockShards' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/masterchain/{masterchain_seqno}/blocks: get: @@ -202,7 +200,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainBlocks' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/masterchain/{masterchain_seqno}/transactions: get: @@ -219,7 +217,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Transactions' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/masterchain/{masterchain_seqno}/config: get: @@ -236,7 +234,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainConfig' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/masterchain/{masterchain_seqno}/config/raw: get: @@ -253,7 +251,7 @@ paths: application/json: schema: $ref: '#/components/schemas/RawBlockchainConfig' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/blocks/{block_id}/transactions: get: @@ -270,7 +268,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Transactions' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/transactions/{transaction_id}: get: @@ -287,7 +285,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Transaction' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/messages/{msg_id}/transaction: get: @@ -304,7 +302,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Transaction' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/validators: get: @@ -319,7 +317,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Validators' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/masterchain-head: get: @@ -334,7 +332,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainBlock' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/accounts/{account_id}: get: @@ -351,7 +349,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainRawAccount' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/accounts/{account_id}/transactions: get: @@ -363,7 +361,7 @@ paths: - $ref: '#/components/parameters/accountIDParameter' - name: after_lt in: query - description: "omit this parameter to get last transactions" + description: omit this parameter to get last transactions schema: type: integer format: int64 @@ -371,7 +369,7 @@ paths: x-js-format: bigint - name: before_lt in: query - description: "omit this parameter to get last transactions" + description: omit this parameter to get last transactions schema: type: integer format: int64 @@ -390,8 +388,8 @@ paths: in: query schema: type: string - description: "used to sort the result-set in ascending or descending order by lt." - default: "desc" + description: used to sort the result-set in ascending or descending order by lt. + default: desc enum: - desc - asc @@ -402,7 +400,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Transactions' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/accounts/{account_id}/methods/{method_name}: get: @@ -429,7 +427,8 @@ paths: single-root hex-encoded BOC for slice (Example: b5ee9c72010101010002000000) items: type: string - example: [ "0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8" ] + example: + - 0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8 - name: fix_order in: query required: false @@ -448,7 +447,7 @@ paths: application/json: schema: $ref: '#/components/schemas/MethodExecutionResult' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/message: post: @@ -457,11 +456,11 @@ paths: tags: - Blockchain requestBody: - $ref: "#/components/requestBodies/BatchBoc" + $ref: '#/components/requestBodies/BatchBoc' responses: '200': description: the message has been sent - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/config: get: @@ -476,7 +475,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainConfig' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/config/raw: get: @@ -491,7 +490,7 @@ paths: application/json: schema: $ref: '#/components/schemas/RawBlockchainConfig' - 'default': + default: $ref: '#/components/responses/Error' /v2/blockchain/accounts/{account_id}/inspect: get: @@ -508,7 +507,7 @@ paths: application/json: schema: $ref: '#/components/schemas/BlockchainAccountInspect' - 'default': + default: $ref: '#/components/responses/Error' /v2/address/{account_id}/parse: get: @@ -535,7 +534,7 @@ paths: raw_form: type: string format: address - example: "0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e" + example: 0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e bounceable: required: - b64 @@ -569,9 +568,9 @@ paths: tags: - Accounts parameters: - - $ref: "#/components/parameters/currencyQuery" + - $ref: '#/components/parameters/currencyQuery' requestBody: - $ref: "#/components/requestBodies/AccountIDs" + $ref: '#/components/requestBodies/AccountIDs' responses: '200': description: a list of accounts @@ -579,7 +578,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Accounts' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}: get: @@ -596,7 +595,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Account' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/dns/backresolve: get: @@ -613,7 +612,7 @@ paths: application/json: schema: $ref: '#/components/schemas/DomainNames' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/jettons: get: @@ -632,7 +631,7 @@ paths: application/json: schema: $ref: '#/components/schemas/JettonsBalances' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/jettons/{jetton_id}: get: @@ -652,7 +651,7 @@ paths: application/json: schema: $ref: '#/components/schemas/JettonBalance' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/jettons/history: get: @@ -665,7 +664,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -703,7 +702,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/jettons/{jetton_id}/history: get: @@ -717,7 +716,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -755,7 +754,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/nfts: get: @@ -771,7 +770,7 @@ paths: - in: query name: indirect_ownership required: false - description: "Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly." + description: Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. schema: type: boolean default: false @@ -782,7 +781,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftItems' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/nfts/history: get: @@ -796,7 +795,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -834,7 +833,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/events: get: @@ -848,14 +847,14 @@ paths: - $ref: '#/components/parameters/initiatorQuery' - name: subject_only in: query - description: "filter actions where requested account is not real subject (for example sender or receiver jettons)" + description: filter actions where requested account is not real subject (for example sender or receiver jettons) schema: type: boolean default: false required: false - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -893,7 +892,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/events/{event_id}: get: @@ -907,7 +906,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: subject_only in: query - description: "filter actions where requested account is not real subject (for example sender or receiver jettons)" + description: filter actions where requested account is not real subject (for example sender or receiver jettons) schema: type: boolean default: false @@ -919,7 +918,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvent' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/traces: get: @@ -931,7 +930,7 @@ paths: - $ref: '#/components/parameters/accountIDParameter' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -953,7 +952,7 @@ paths: application/json: schema: $ref: '#/components/schemas/TraceIDs' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/subscriptions: get: @@ -970,7 +969,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Subscriptions' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/reindex: post: @@ -983,7 +982,7 @@ paths: responses: '200': description: success - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/search: get: @@ -1006,7 +1005,7 @@ paths: application/json: schema: $ref: '#/components/schemas/FoundAccounts' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/dns/expiring: get: @@ -1024,7 +1023,7 @@ paths: application/json: schema: $ref: '#/components/schemas/DnsExpiring' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/publickey: get: @@ -1046,8 +1045,8 @@ paths: properties: public_key: type: string - example: "NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3..." - 'default': + example: NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3... + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/multisigs: get: @@ -1064,9 +1063,8 @@ paths: application/json: schema: $ref: '#/components/schemas/Multisigs' - 'default': + default: $ref: '#/components/responses/Error' - /v2/accounts/{account_id}/diff: get: description: Get account's balance change @@ -1105,9 +1103,8 @@ paths: type: integer format: int64 example: 1000000000 - 'default': + default: $ref: '#/components/responses/Error' - /v2/accounts/{account_id}/extra-currency/{id}/history: get: description: Get the transfer history of extra currencies for an account. @@ -1120,7 +1117,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -1158,9 +1155,8 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' - /v2/dns/{domain_name}: get: description: Get full information about domain name @@ -1176,7 +1172,7 @@ paths: application/json: schema: $ref: '#/components/schemas/DomainInfo' - 'default': + default: $ref: '#/components/responses/Error' /v2/dns/{domain_name}/resolve: get: @@ -1193,7 +1189,7 @@ paths: application/json: schema: $ref: '#/components/schemas/DnsRecord' - 'default': + default: $ref: '#/components/responses/Error' /v2/dns/{domain_name}/bids: get: @@ -1210,7 +1206,7 @@ paths: application/json: schema: $ref: '#/components/schemas/DomainBids' - 'default': + default: $ref: '#/components/responses/Error' /v2/dns/auctions: get: @@ -1227,9 +1223,8 @@ paths: application/json: schema: $ref: '#/components/schemas/Auctions' - 'default': + default: $ref: '#/components/responses/Error' - /v2/nfts/collections: get: description: Get NFT collections @@ -1261,7 +1256,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftCollections' - 'default': + default: $ref: '#/components/responses/Error' /v2/nfts/collections/{account_id}: get: @@ -1278,7 +1273,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftCollection' - 'default': + default: $ref: '#/components/responses/Error' /v2/nfts/collections/_bulk: post: @@ -1287,7 +1282,7 @@ paths: tags: - NFT requestBody: - $ref: "#/components/requestBodies/AccountIDs" + $ref: '#/components/requestBodies/AccountIDs' responses: '200': description: nft collections @@ -1295,7 +1290,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftCollections' - 'default': + default: $ref: '#/components/responses/Error' /v2/nfts/collections/{account_id}/items: get: @@ -1314,7 +1309,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftItems' - 'default': + default: $ref: '#/components/responses/Error' /v2/nfts/_bulk: post: @@ -1323,7 +1318,7 @@ paths: tags: - NFT requestBody: - $ref: "#/components/requestBodies/AccountIDs" + $ref: '#/components/requestBodies/AccountIDs' responses: '200': description: nft items @@ -1331,7 +1326,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftItems' - 'default': + default: $ref: '#/components/responses/Error' /v2/nfts/{account_id}: get: @@ -1348,7 +1343,7 @@ paths: application/json: schema: $ref: '#/components/schemas/NftItem' - 'default': + default: $ref: '#/components/responses/Error' /v2/nfts/{account_id}/history: get: @@ -1361,7 +1356,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -1399,7 +1394,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/traces/{trace_id}: get: @@ -1416,9 +1411,8 @@ paths: application/json: schema: $ref: '#/components/schemas/Trace' - 'default': + default: $ref: '#/components/responses/Error' - /v2/events/{event_id}: get: description: Get an event either by event ID or a hash of any transaction in a trace. An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. @@ -1435,9 +1429,8 @@ paths: application/json: schema: $ref: '#/components/schemas/Event' - 'default': + default: $ref: '#/components/responses/Error' - /v2/experimental/accounts/{account_id}/inscriptions: get: description: Get all inscriptions by owner address. It's experimental API and can be dropped in the future. @@ -1455,7 +1448,7 @@ paths: application/json: schema: $ref: '#/components/schemas/InscriptionBalances' - 'default': + default: $ref: '#/components/responses/Error' /v2/experimental/accounts/{account_id}/inscriptions/history: get: @@ -1468,7 +1461,7 @@ paths: - $ref: '#/components/parameters/i18n' - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -1491,7 +1484,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/experimental/accounts/{account_id}/inscriptions/{ticker}/history: get: @@ -1507,10 +1500,10 @@ paths: required: true schema: type: string - example: "nano" + example: nano - name: before_lt in: query - description: "omit this parameter to get last events" + description: omit this parameter to get last events required: false schema: type: integer @@ -1533,7 +1526,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvents' - 'default': + default: $ref: '#/components/responses/Error' /v2/experimental/inscriptions/op-template: get: @@ -1547,8 +1540,10 @@ paths: required: true schema: type: string - enum: [ "ton20", "gram20" ] - example: "ton20" + enum: + - ton20 + - gram20 + example: ton20 - in: query name: destination required: false @@ -1564,21 +1559,22 @@ paths: required: true schema: type: string - enum: [ "transfer" ] - example: "transfer" + enum: + - transfer + example: transfer - in: query name: amount required: true schema: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' - in: query name: ticker required: true schema: type: string - example: "nano" + example: nano - in: query name: who required: true @@ -1598,11 +1594,11 @@ paths: properties: comment: type: string - example: "comment" + example: comment destination: type: string - example: "0:0000000000000" - 'default': + example: '0:0000000000000' + default: $ref: '#/components/responses/Error' /v2/jettons: get: @@ -1635,7 +1631,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Jettons' - 'default': + default: $ref: '#/components/responses/Error' /v2/jettons/{account_id}: get: @@ -1652,7 +1648,7 @@ paths: application/json: schema: $ref: '#/components/schemas/JettonInfo' - 'default': + default: $ref: '#/components/responses/Error' /v2/jettons/_bulk: post: @@ -1661,7 +1657,7 @@ paths: tags: - Jettons requestBody: - $ref: "#/components/requestBodies/AccountIDs" + $ref: '#/components/requestBodies/AccountIDs' responses: '200': description: a list of jettons @@ -1669,7 +1665,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Jettons' - 'default': + default: $ref: '#/components/responses/Error' /v2/jettons/{account_id}/holders: get: @@ -1688,7 +1684,7 @@ paths: application/json: schema: $ref: '#/components/schemas/JettonHolders' - 'default': + default: $ref: '#/components/responses/Error' /v2/jettons/{jetton_id}/transfer/{account_id}/payload: get: @@ -1706,11 +1702,11 @@ paths: application/json: schema: $ref: '#/components/schemas/JettonTransferPayload' - 'default': + default: $ref: '#/components/responses/Error' /v2/events/{event_id}/jettons: get: - description: "Get only jetton transfers in the event" + description: Get only jetton transfers in the event operationId: getJettonsEvents tags: - Jettons @@ -1724,9 +1720,8 @@ paths: application/json: schema: $ref: '#/components/schemas/Event' - 'default': + default: $ref: '#/components/responses/Error' - /v2/extra-currency/{id}: get: description: Get extra currency info by id @@ -1742,9 +1737,8 @@ paths: application/json: schema: $ref: '#/components/schemas/EcPreview' - 'default': + default: $ref: '#/components/responses/Error' - /v2/staking/nominator/{account_id}/pools: get: description: All pools where account participates @@ -1760,7 +1754,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountStaking' - 'default': + default: $ref: '#/components/responses/Error' /v2/staking/pool/{account_id}: get: @@ -1786,7 +1780,7 @@ paths: $ref: '#/components/schemas/PoolImplementation' pool: $ref: '#/components/schemas/PoolInfo' - 'default': + default: $ref: '#/components/responses/Error' /v2/staking/pool/{account_id}/history: get: @@ -1810,7 +1804,7 @@ paths: type: array items: $ref: '#/components/schemas/ApyHistory' - 'default': + default: $ref: '#/components/responses/Error' /v2/staking/pools: get: @@ -1830,7 +1824,7 @@ paths: - in: query name: include_unverified required: false - description: "return also pools not from white list - just compatible by interfaces (maybe dangerous!)" + description: return also pools not from white list - just compatible by interfaces (maybe dangerous!) schema: type: boolean example: false @@ -1854,9 +1848,8 @@ paths: type: object additionalProperties: $ref: '#/components/schemas/PoolImplementation' - 'default': + default: $ref: '#/components/responses/Error' - /v2/storage/providers: get: description: Get TON storage providers deployed to the blockchain. @@ -1877,9 +1870,8 @@ paths: type: array items: $ref: '#/components/schemas/StorageProvider' - 'default': + default: $ref: '#/components/responses/Error' - /v2/rates: get: description: Get the token price in the chosen currency for display only. Don’t use this for financial transactions. @@ -1897,7 +1889,8 @@ paths: maxItems: 100 items: type: string - example: [ "ton" ] + example: + - ton - in: query name: currencies description: accept ton and all possible fiat currencies, separated by commas @@ -1908,7 +1901,10 @@ paths: maxItems: 50 items: type: string - example: [ "ton","usd","rub" ] + example: + - ton + - usd + - rub responses: '200': description: tokens rates @@ -1923,7 +1919,7 @@ paths: type: object additionalProperties: $ref: '#/components/schemas/TokenRates' - 'default': + default: $ref: '#/components/responses/Error' /v2/rates/chart: get: @@ -1984,7 +1980,7 @@ paths: type: array items: $ref: '#/components/schemas/ChartPoints' - 'default': + default: $ref: '#/components/responses/Error' /v2/rates/markets: get: @@ -2006,9 +2002,8 @@ paths: type: array items: $ref: '#/components/schemas/MarketTonRates' - 'default': + default: $ref: '#/components/responses/Error' - /v2/tonconnect/payload: get: description: Get a payload for further token receipt @@ -2027,8 +2022,8 @@ paths: properties: payload: type: string - example: "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" - 'default': + example: 84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa + default: $ref: '#/components/responses/Error' /v2/tonconnect/stateinit: post: @@ -2037,7 +2032,7 @@ paths: tags: - Connect requestBody: - $ref: "#/components/requestBodies/TonConnectStateInit" + $ref: '#/components/requestBodies/TonConnectStateInit' responses: '200': description: account info @@ -2045,7 +2040,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountInfoByStateInit' - 'default': + default: $ref: '#/components/responses/Error' /v2/wallet/auth/proof: post: @@ -2054,7 +2049,7 @@ paths: tags: - Wallet requestBody: - $ref: "#/components/requestBodies/TonConnectProof" + $ref: '#/components/requestBodies/TonConnectProof' responses: '200': description: auth token @@ -2067,8 +2062,8 @@ paths: properties: token: type: string - example: "NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3..." - 'default': + example: NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3... + default: $ref: '#/components/responses/Error' /v2/wallet/{account_id}/seqno: get: @@ -2085,7 +2080,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Seqno' - 'default': + default: $ref: '#/components/responses/Error' /v2/gasless/config: get: @@ -2095,12 +2090,12 @@ paths: - Gasless responses: '200': - description: "gasless config" + description: gasless config content: application/json: schema: $ref: '#/components/schemas/GaslessConfig' - 'default': + default: $ref: '#/components/responses/Error' /v2/gasless/estimate/{master_id}: post: @@ -2118,15 +2113,15 @@ paths: tags: - Gasless requestBody: - $ref: "#/components/requestBodies/InternalMessages" + $ref: '#/components/requestBodies/InternalMessages' responses: '200': - description: "payload to sign" + description: payload to sign content: application/json: schema: $ref: '#/components/schemas/SignRawParams' - 'default': + default: $ref: '#/components/responses/Error' /v2/gasless/send: post: @@ -2135,11 +2130,11 @@ paths: tags: - Gasless requestBody: - $ref: "#/components/requestBodies/GaslessSend" + $ref: '#/components/requestBodies/GaslessSend' responses: '200': description: the message has been sent - 'default': + default: $ref: '#/components/responses/Error' /v2/pubkeys/{public_key}/wallets: get: @@ -2156,9 +2151,8 @@ paths: application/json: schema: $ref: '#/components/schemas/Accounts' - 'default': + default: $ref: '#/components/responses/Error' - /v2/liteserver/get_masterchain_info: get: description: Get raw masterchain info @@ -2184,7 +2178,7 @@ paths: example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 init: $ref: '#/components/schemas/InitStateRaw' - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_masterchain_info_ext: get: @@ -2238,7 +2232,7 @@ paths: example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 init: $ref: '#/components/schemas/InitStateRaw' - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_time: get: @@ -2260,7 +2254,7 @@ paths: type: integer format: int32 example: 1687146728 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_block/{block_id}: get: @@ -2286,7 +2280,7 @@ paths: data: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_state/{block_id}: get: @@ -2320,7 +2314,7 @@ paths: data: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_block_header/{block_id}: get: @@ -2352,7 +2346,7 @@ paths: header_proof: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/send_message: post: @@ -2361,7 +2355,7 @@ paths: tags: - Lite Server requestBody: - $ref: "#/components/requestBodies/LiteServerSendMessageRequest" + $ref: '#/components/requestBodies/LiteServerSendMessageRequest' responses: '200': description: code @@ -2376,7 +2370,7 @@ paths: type: integer format: int32 example: 200 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_account_state/{account_id}: get: @@ -2414,7 +2408,7 @@ paths: state: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_shard_info/{block_id}: get: @@ -2450,7 +2444,7 @@ paths: shard_descr: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_all_shards_info/{block_id}: get: @@ -2480,7 +2474,7 @@ paths: data: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_transactions/{account_id}: get: @@ -2511,7 +2505,7 @@ paths: transactions: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/list_block_transactions/{block_id}: get: @@ -2572,7 +2566,7 @@ paths: proof: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_block_proof: get: @@ -2688,7 +2682,7 @@ paths: signature: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_config_all/{block_id}: get: @@ -2724,7 +2718,7 @@ paths: config_proof: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_shard_block_proof/{block_id}: get: @@ -2760,7 +2754,7 @@ paths: proof: type: string example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 - 'default': + default: $ref: '#/components/responses/Error' /v2/liteserver/get_out_msg_queue_sizes: get: @@ -2795,9 +2789,8 @@ paths: size: type: integer format: uint32 - 'default': + default: $ref: '#/components/responses/Error' - /v2/multisig/{account_id}: get: description: Get multisig account info @@ -2813,7 +2806,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Multisig' - 'default': + default: $ref: '#/components/responses/Error' /v2/message/decode: post: @@ -2822,7 +2815,7 @@ paths: tags: - Emulation requestBody: - $ref: "#/components/requestBodies/Boc" + $ref: '#/components/requestBodies/Boc' responses: '200': description: decoded message @@ -2830,7 +2823,7 @@ paths: application/json: schema: $ref: '#/components/schemas/DecodedMessage' - 'default': + default: $ref: '#/components/responses/Error' /v2/events/emulate: post: @@ -2847,7 +2840,7 @@ paths: schema: type: boolean requestBody: - $ref: "#/components/requestBodies/Boc" + $ref: '#/components/requestBodies/Boc' responses: '200': description: emulated event @@ -2855,7 +2848,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Event' - 'default': + default: $ref: '#/components/responses/Error' /v2/traces/emulate: post: @@ -2871,7 +2864,7 @@ paths: schema: type: boolean requestBody: - $ref: "#/components/requestBodies/Boc" + $ref: '#/components/requestBodies/Boc' responses: '200': description: emulated trace @@ -2879,7 +2872,7 @@ paths: application/json: schema: $ref: '#/components/schemas/Trace' - 'default': + default: $ref: '#/components/responses/Error' /v2/wallet/emulate: post: @@ -2891,7 +2884,7 @@ paths: parameters: - $ref: '#/components/parameters/i18n' requestBody: - $ref: "#/components/requestBodies/EmulationBoc" + $ref: '#/components/requestBodies/EmulationBoc' responses: '200': description: emulated message @@ -2899,7 +2892,7 @@ paths: application/json: schema: $ref: '#/components/schemas/MessageConsequences' - 'default': + default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/events/emulate: post: @@ -2917,7 +2910,7 @@ paths: schema: type: boolean requestBody: - $ref: "#/components/requestBodies/Boc" + $ref: '#/components/requestBodies/Boc' responses: '200': description: emulated message to account @@ -2925,7 +2918,7 @@ paths: application/json: schema: $ref: '#/components/schemas/AccountEvent' - 'default': + default: $ref: '#/components/responses/Error' components: parameters: @@ -2933,7 +2926,7 @@ components: in: path name: masterchain_seqno required: true - description: "masterchain block seqno" + description: masterchain block seqno schema: type: integer format: int32 @@ -2950,7 +2943,7 @@ components: in: path name: block_id required: true - description: "block ID: (workchain,shard,seqno,root_hash,file_hash)" + description: 'block ID: (workchain,shard,seqno,root_hash,file_hash)' schema: type: string example: (-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29) @@ -3020,7 +3013,7 @@ components: in: path name: trace_id required: true - description: "trace ID or transaction hash in hex (without 0x) or base64url format" + description: trace ID or transaction hash in hex (without 0x) or base64url format schema: type: string example: 97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621 @@ -3028,7 +3021,7 @@ components: in: path name: event_id required: true - description: "event ID or transaction hash in hex (without 0x) or base64url format" + description: event ID or transaction hash in hex (without 0x) or base64url format schema: type: string example: 97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621 @@ -3036,7 +3029,7 @@ components: in: path name: id required: true - description: "extra currency id" + description: extra currency id schema: type: integer example: 239 @@ -3054,8 +3047,8 @@ components: required: false schema: type: string - example: "ru-RU,ru;q=0.5" - default: "en" + example: ru-RU,ru;q=0.5 + default: en limitQuery: in: query name: limit @@ -3085,7 +3078,7 @@ components: in: query name: period required: false - description: "number of days before expiration" + description: number of days before expiration schema: type: integer minimum: 1 @@ -3094,16 +3087,16 @@ components: in: query name: collection required: false - description: "nft collection" + description: nft collection schema: type: string format: address - example: "0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465" + example: 0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465 modeQuery: in: query name: mode required: true - description: "mode" + description: mode schema: type: integer format: int32 @@ -3112,7 +3105,7 @@ components: in: query name: count required: true - description: "count" + description: count schema: type: integer format: int32 @@ -3121,7 +3114,7 @@ components: in: query name: known_block required: true - description: "known block: (workchain,shard,seqno,root_hash,file_hash)" + description: 'known block: (workchain,shard,seqno,root_hash,file_hash)' schema: type: string example: (-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29) @@ -3129,7 +3122,7 @@ components: in: query name: target_block required: false - description: "target block: (workchain,shard,seqno,root_hash,file_hash)" + description: 'target block: (workchain,shard,seqno,root_hash,file_hash)' schema: type: string example: (-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29) @@ -3137,7 +3130,7 @@ components: in: query name: lt required: true - description: "lt" + description: lt schema: type: integer format: int64 @@ -3145,7 +3138,7 @@ components: ltQuery: in: query name: lt - description: "lt" + description: lt schema: type: integer format: int64 @@ -3154,15 +3147,15 @@ components: in: query name: hash required: true - description: "hash" + description: hash schema: type: string - example: "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" + example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 workchainQuery: in: query name: workchain required: true - description: "workchain" + description: workchain schema: type: integer format: int32 @@ -3171,7 +3164,7 @@ components: in: query name: shard required: true - description: "shard" + description: shard schema: type: integer format: int64 @@ -3180,7 +3173,7 @@ components: in: query name: exact required: true - description: "exact" + description: exact schema: type: boolean example: false @@ -3212,25 +3205,29 @@ components: type: array items: type: string - example: [ "ton", "usd", "rub" ] + example: + - ton + - usd + - rub supportedExtensions: in: query name: supported_extensions - description: "comma separated list supported extensions" + description: comma separated list supported extensions explode: false required: false schema: type: array items: type: string - example: [ "custom_payload" ] + example: + - custom_payload currencyQuery: in: query name: currency required: false schema: type: string - example: "usd" + example: usd fromQuery: in: query name: from @@ -3245,7 +3242,6 @@ components: schema: type: integer format: int64 - requestBodies: MethodParameters: description: input parameters for contract get method @@ -3298,7 +3294,7 @@ components: address: type: string format: address - example: "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + example: 0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b balance: type: integer format: int64 @@ -3377,7 +3373,7 @@ components: format: address example: 0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621 TonConnectProof: - description: "Data that is expected from TON Connect" + description: Data that is expected from TON Connect required: true content: application/json: @@ -3390,7 +3386,7 @@ components: address: type: string format: address - example: "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + example: 0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b proof: type: object required: @@ -3402,7 +3398,7 @@ components: timestamp: type: integer format: int64 - example: "1678275313" + example: '1678275313' domain: type: object required: @@ -3417,12 +3413,12 @@ components: type: string payload: type: string - example: "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" + example: 84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa state_init: type: string format: cell-base64 TonConnectStateInit: - description: "Data that is expected" + description: Data that is expected required: true content: application/json: @@ -3435,7 +3431,7 @@ components: type: string format: cell-base64 LiteServerSendMessageRequest: - description: "Data that is expected" + description: Data that is expected required: true content: application/json: @@ -3447,7 +3443,6 @@ components: body: type: string format: cell-base64 - schemas: Error: type: object @@ -3508,7 +3503,7 @@ components: value: type: string x-js-format: bigint - example: "10000000000" + example: '10000000000' BlockValueFlow: type: object required: @@ -3576,8 +3571,7 @@ components: format: int32 shard: type: string - # x-js-format: bigint ??? - example: "8000000000000000" + example: '8000000000000000' seqno: type: integer example: 21734019 @@ -3596,12 +3590,12 @@ components: type: array items: type: string - example: "[ (0,4234235,8000000000000000) ]" + example: '[ (0,4234235,8000000000000000) ]' parent: type: array items: type: string - example: "[ (0,21734018,8000000000000000) ]" + example: '[ (0,21734018,8000000000000000) ]' BlockchainBlock: type: object required: @@ -3644,8 +3638,7 @@ components: format: int32 shard: type: string - # x-js-format: bigint ??? - example: "8000000000000000" + example: '8000000000000000' seqno: type: integer example: 21734019 @@ -3727,7 +3720,10 @@ components: type: array items: type: string - example: [ (-1,4234235,8000000000000000) ] + example: + - (-1 + - 4234235 + - 8000000000000000) in_msg_descr_length: type: integer format: int64 @@ -3871,21 +3867,21 @@ components: op_code: type: string x-js-format: bigint - example: "0xdeadbeaf" + example: '0xdeadbeaf' init: $ref: '#/components/schemas/StateInit' hash: type: string - example: "1219de582369ac80ee1afe12147930f458a54ff1eea612611a8bc6bd31581a6c" + example: 1219de582369ac80ee1afe12147930f458a54ff1eea612611a8bc6bd31581a6c raw_body: type: string format: cell description: hex-encoded BoC with raw message body - example: "B5EE9C7201010101001100001D00048656C6C6F2C20776F726C64218" + example: B5EE9C7201010101001100001D00048656C6C6F2C20776F726C64218 decoded_op_name: type: string - example: "nft_transfer" - decoded_body: { } # Free-form JSON value + example: nft_transfer + decoded_body: {} TransactionType: type: string example: TransOrd @@ -4118,8 +4114,8 @@ components: raw: type: string format: cell - description: "hex encoded boc with raw transaction" - example: "b5ee9c72410206010001380003b372cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb00002ac5795c0e41fdf79135cb7da03cc623b165d614b562a51eeccd8a5e097f405abf6b37f4e73000002ac5629732c1666887ed000144030480102030101a004008272abc8f2971aa4404ac6da1597720f348b2e1247b1ad9f55cbd3b6812f0a5f08b269bb65039fb1f6074d00f794e857f6dfd01131d299df456af10a8a4943d4d165000d0c80608840492001ab48015581f575c3b8c6ab3d6" + description: hex encoded boc with raw transaction + example: b5ee9c72410206010001380003b372cf3b5b8c891e517c9addbda1c0386a09ccacbb0e3faf630b51cfc8152325acb00002ac5795c0e41fdf79135cb7da03cc623b165d614b562a51eeccd8a5e097f405abf6b37f4e73000002ac5629732c1666887ed000144030480102030101a004008272abc8f2971aa4404ac6da1597720f348b2e1247b1ad9f55cbd3b6812f0a5f08b269bb65039fb1f6074d00f794e857f6dfd01131d299df456af10a8a4943d4d165000d0c80608840492001ab48015581f575c3b8c6ab3d6 Transactions: type: object required: @@ -4329,10 +4325,10 @@ components: example: 1000000 zerostate_root_hash: type: string - example: "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" + example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 zerostate_file_hash: type: string - example: "A6A0BD6608672B11B79538A50B2204E748305C12AA0DED9C16CF0006CE3AF8DB" + example: A6A0BD6608672B11B79538A50B2204E748305C12AA0DED9C16CF0006CE3AF8DB version: type: integer format: int64 @@ -4387,7 +4383,6 @@ components: medium_proportional_mult: type: integer example: 1000000 - SizeLimitsConfig: type: object required: @@ -4450,7 +4445,7 @@ components: total_weight: type: string x-js-format: bigint - example: "1152921504606846800" + example: '1152921504606846800' list: type: array items: @@ -4467,7 +4462,7 @@ components: x-js-format: bigint adnl_addr: type: string - example: "45061C1D4EC44A937D0318589E13C73D151D1CEF5D3C0E53AFBCF56A6C2FE2BD" + example: 45061C1D4EC44A937D0318589E13C73D151D1CEF5D3C0E53AFBCF56A6C2FE2BD Oracle: type: object required: @@ -4664,8 +4659,6 @@ components: type: object additionalProperties: type: string - # x-js-format: bigint ??? - # example ??? code: type: string format: cell @@ -4686,7 +4679,7 @@ components: type: string example: 088b436a846d92281734236967970612f87fbd64a2cd3573107948379e8e4161 status: - '$ref': '#/components/schemas/AccountStatus' + $ref: '#/components/schemas/AccountStatus' storage: $ref: '#/components/schemas/AccountStorageInfo' libraries: @@ -4727,17 +4720,17 @@ components: items: $ref: '#/components/schemas/ExtraCurrency' currencies_balance: - description: "{'USD': 1, 'IDR': 1000}" + description: '{''USD'': 1, ''IDR'': 1000}' type: object additionalProperties: true - example: { } + example: {} last_activity: type: integer description: unix timestamp format: int64 example: 1720860269 status: - '$ref': '#/components/schemas/AccountStatus' + $ref: '#/components/schemas/AccountStatus' interfaces: type: array items: @@ -4745,13 +4738,13 @@ components: example: nft_sale name: type: string - example: "Ton foundation" + example: Ton foundation is_scam: type: boolean example: true icon: type: string - example: "https://ton.org/logo.png" + example: https://ton.org/logo.png memo_required: type: boolean example: true @@ -4759,7 +4752,8 @@ components: type: array items: type: string - example: [ 'get_item_data' ] + example: + - get_item_data is_suspended: type: boolean is_wallet: @@ -4782,11 +4776,11 @@ components: relay_address: type: string format: address - description: "sending excess to this address decreases the commission of a gasless transfer" + description: sending excess to this address decreases the commission of a gasless transfer example: 0:dfbd5be8497fdc0c9fcbdfc676864840ddf8ad6423d6d5657d9b0e8270d6c8ac gas_jettons: type: array - description: "list of jettons, any of them can be used to pay for gas" + description: list of jettons, any of them can be used to pay for gas items: type: object required: @@ -4807,17 +4801,15 @@ components: example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf amount: type: string - # x-js-format: bigint - # example: "1000000" nanocoins or decimal ? - description: "Number of nanocoins to send. Decimal string." + description: Number of nanocoins to send. Decimal string. payload: type: string format: cell - description: "Raw one-cell BoC encoded in hex." + description: Raw one-cell BoC encoded in hex. stateInit: type: string format: cell - description: "Raw once-cell BoC encoded in hex." + description: Raw once-cell BoC encoded in hex. SignRawParams: type: object required: @@ -4834,8 +4826,8 @@ components: commission: type: string x-js-format: bigint - example: "1000000" - description: "Commission for the transaction. In nanocoins." + example: '1000000' + description: Commission for the transaction. In nanocoins. from: type: string format: address @@ -4865,8 +4857,8 @@ components: stack: type: array items: - $ref: "#/components/schemas/TvmStackRecord" - decoded: { } # Free-form JSON value + $ref: '#/components/schemas/TvmStackRecord' + decoded: {} TvmStackRecord: type: object format: tuple-item @@ -4875,12 +4867,12 @@ components: properties: type: type: string - example: "cell" + example: cell enum: - cell - num - nan - - "null" + - 'null' - tuple cell: type: string @@ -4890,10 +4882,10 @@ components: format: cell num: type: string - example: "" + example: '' tuple: type: array - example: [ ] + example: [] items: $ref: '#/components/schemas/TvmStackRecord' RawBlockchainConfig: @@ -4904,43 +4896,38 @@ components: config: type: object additionalProperties: true - example: { } - + example: {} BlockchainConfig: type: object required: - raw - - "0" - - "1" - - "2" - - "4" - - "44" + - '0' + - '1' + - '2' + - '4' + - '44' properties: - raw: - type: string - format: cell - description: config boc in hex format - "0": + '0': type: string format: address - description: "config address" - "1": + description: config address + '1': type: string format: address - description: "elector address" - "2": + description: elector address + '2': type: string format: address - description: "minter address" - "3": + description: minter address + '3': type: string format: address - description: "The address of the transaction fee collector." - "4": + description: The address of the transaction fee collector. + '4': type: string format: address - description: "dns root address" - "5": + description: dns root address + '5': type: object required: - fee_burn_nom @@ -4955,7 +4942,7 @@ components: fee_burn_denom: type: integer format: int64 - "6": + '6': type: object description: Minting fees of new currencies. required: @@ -4968,7 +4955,7 @@ components: mint_add_price: type: integer format: int64 - "7": + '7': type: object description: The volume of each of the additional currencies in circulation. required: @@ -4987,9 +4974,7 @@ components: format: int64 amount: type: string - # x-js-format: bigint - # example: "1000000" - "8": + '8': type: object description: The network version and additional capabilities supported by the validators. required: @@ -5002,7 +4987,7 @@ components: capabilities: type: integer format: int64 - "9": + '9': type: object description: List of mandatory parameters of the blockchain config. required: @@ -5013,7 +4998,7 @@ components: items: type: integer format: int32 - "10": + '10': type: object description: List of critical TON parameters, the change of which significantly affects the network, so more voting rounds are held. required: @@ -5024,7 +5009,7 @@ components: items: type: integer format: int32 - "11": + '11': type: object description: This parameter indicates under what conditions proposals to change the TON configuration are accepted. required: @@ -5035,7 +5020,7 @@ components: $ref: '#/components/schemas/ConfigProposalSetup' critical_params: $ref: '#/components/schemas/ConfigProposalSetup' - "12": + '12': type: object description: Workchains in the TON Blockchain required: @@ -5045,7 +5030,7 @@ components: type: array items: $ref: '#/components/schemas/WorkchainDescr' - "13": + '13': type: object description: The cost of filing complaints about incorrect operation of validators. required: @@ -5062,7 +5047,7 @@ components: cell_price: type: integer format: int64 - "14": + '14': type: object description: The reward in nanoTons for block creation in the TON blockchain. required: @@ -5075,7 +5060,7 @@ components: basechain_block_fee: type: integer format: int64 - "15": + '15': type: object description: The reward in nanoTons for block creation in the TON blockchain. required: @@ -5100,7 +5085,7 @@ components: type: integer format: int64 example: 32768 - "16": + '16': type: object description: The limits on the number of validators in the TON blockchain. required: @@ -5117,7 +5102,7 @@ components: min_validators: type: integer example: 75 - "17": + '17': type: object description: The stake parameters configuration in the TON blockchain. required: @@ -5128,20 +5113,14 @@ components: properties: min_stake: type: string - # x-js-format: bigint - # example: "1000000" max_stake: type: string - # x-js-format: bigint - # example: "1000000" min_total_stake: type: string - # x-js-format: bigint - # example: "1000000" max_stake_factor: type: integer format: int64 - "18": + '18': type: object description: The prices for data storage. required: @@ -5178,7 +5157,7 @@ components: type: integer format: int64 example: 500000 - "20": + '20': type: object description: The cost of computations in the masterchain. The complexity of any computation is estimated in gas units. required: @@ -5186,7 +5165,7 @@ components: properties: gas_limits_prices: $ref: '#/components/schemas/GasLimitPrices' - "21": + '21': type: object description: The cost of computations in the basechains. The complexity of any computation is estimated in gas units. required: @@ -5194,7 +5173,7 @@ components: properties: gas_limits_prices: $ref: '#/components/schemas/GasLimitPrices' - "22": + '22': type: object description: The limits on the block in the masterchain, upon reaching which the block is finalized and the callback of the remaining messages (if any) is carried over to the next block. required: @@ -5202,7 +5181,7 @@ components: properties: block_limits: $ref: '#/components/schemas/BlockLimits' - "23": + '23': type: object description: The limits on the block in the basechains, upon reaching which the block is finalized and the callback of the remaining messages (if any) is carried over to the next block. required: @@ -5210,7 +5189,7 @@ components: properties: block_limits: $ref: '#/components/schemas/BlockLimits' - "24": + '24': type: object description: The cost of sending messages in the masterchain of the TON blockchain. required: @@ -5218,7 +5197,7 @@ components: properties: msg_forward_prices: $ref: '#/components/schemas/MsgForwardPrices' - "25": + '25': type: object description: The cost of sending messages in the basechains of the TON blockchain. required: @@ -5226,7 +5205,7 @@ components: properties: msg_forward_prices: $ref: '#/components/schemas/MsgForwardPrices' - "28": + '28': type: object description: The configuration for the Catchain protocol. required: @@ -5257,7 +5236,7 @@ components: example: 1000000 shuffle_mc_validators: type: boolean - "29": + '29': type: object description: The configuration for the consensus protocol above catchain. required: @@ -5317,7 +5296,7 @@ components: type: integer format: int64 example: 10000 - "31": + '31': type: object description: The configuration for the consensus protocol above catchain. required: @@ -5328,20 +5307,20 @@ components: items: type: string format: address - example: -1:dd24c4a1f2b88f8b7053513b5cc6c5a31bc44b2a72dcb4d8c0338af0f0d37ec5 - "32": + example: '-1:dd24c4a1f2b88f8b7053513b5cc6c5a31bc44b2a72dcb4d8c0338af0f0d37ec5' + '32': $ref: '#/components/schemas/ValidatorsSet' - "33": + '33': $ref: '#/components/schemas/ValidatorsSet' - "34": + '34': $ref: '#/components/schemas/ValidatorsSet' - "35": + '35': $ref: '#/components/schemas/ValidatorsSet' - "36": + '36': $ref: '#/components/schemas/ValidatorsSet' - "37": + '37': $ref: '#/components/schemas/ValidatorsSet' - "40": + '40': type: object description: The configuration for punishment for improper behavior (non-validation). In the absence of the parameter, the default fine size is 101 TON required: @@ -5349,7 +5328,7 @@ components: properties: misbehaviour_punishment_config: $ref: '#/components/schemas/MisbehaviourPunishmentConfig' - "43": + '43': type: object description: The size limits and some other characteristics of accounts and messages. required: @@ -5357,7 +5336,7 @@ components: properties: size_limits_config: $ref: '#/components/schemas/SizeLimitsConfig' - "44": + '44': type: object description: suspended accounts required: @@ -5369,11 +5348,10 @@ components: items: type: string format: address - example: 0:0000000000000000000000000000000000000000000000000000000000000000 + example: '0:0000000000000000000000000000000000000000000000000000000000000000' suspended_until: type: integer - - "45": + '45': type: object description: precompiled contracts required: @@ -5393,7 +5371,7 @@ components: gas_usage: type: integer format: int64 - "71": + '71': type: object description: Bridge parameters for wrapping TON in other networks. required: @@ -5401,7 +5379,7 @@ components: properties: oracle_bridge_params: $ref: '#/components/schemas/OracleBridgeParams' - "72": + '72': type: object description: Bridge parameters for wrapping TON in other networks. required: @@ -5409,7 +5387,7 @@ components: properties: oracle_bridge_params: $ref: '#/components/schemas/OracleBridgeParams' - "73": + '73': type: object description: Bridge parameters for wrapping TON in other networks. required: @@ -5417,7 +5395,7 @@ components: properties: oracle_bridge_params: $ref: '#/components/schemas/OracleBridgeParams' - "79": + '79': type: object description: Bridge parameters for wrapping tokens from other networks into tokens on the TON network. required: @@ -5425,7 +5403,7 @@ components: properties: jetton_bridge_params: $ref: '#/components/schemas/JettonBridgeParams' - "81": + '81': type: object description: Bridge parameters for wrapping tokens from other networks into tokens on the TON network. required: @@ -5433,7 +5411,7 @@ components: properties: jetton_bridge_params: $ref: '#/components/schemas/JettonBridgeParams' - "82": + '82': type: object description: Bridge parameters for wrapping tokens from other networks into tokens on the TON network. required: @@ -5441,6 +5419,10 @@ components: properties: jetton_bridge_params: $ref: '#/components/schemas/JettonBridgeParams' + raw: + type: string + format: cell + description: config boc in hex format DomainNames: type: object required: @@ -5521,7 +5503,7 @@ components: example: https://cache.tonapi.io/images/jetton.jpg verification: $ref: '#/components/schemas/JettonVerificationType' - custom_payload_api_uri: # todo: maybe remove + custom_payload_api_uri: type: string score: type: integer @@ -5536,7 +5518,7 @@ components: balance: type: string x-js-format: bigint - example: "597968399" + example: '597968399' price: $ref: '#/components/schemas/TokenRates' wallet_address: @@ -5559,7 +5541,7 @@ components: amount: type: string x-js-format: bigint - example: "597968399" + example: '597968399' till: type: integer format: int64 @@ -5582,7 +5564,7 @@ components: value: type: string x-js-format: bigint - example: "123000000000" + example: '123000000000' token_name: type: string example: TON @@ -5594,10 +5576,10 @@ components: properties: resolution: type: string - example: "100x100" + example: 100x100 url: type: string - example: "https://site.com/pic1.jpg" + example: https://site.com/pic1.jpg NftApprovedBy: type: array items: @@ -5667,15 +5649,15 @@ components: example: TON Diamonds description: type: string - example: "Best collection in TON network" + example: Best collection in TON network verified: type: boolean - description: "Collection master contract confirmed that this item is part of collection" + description: Collection master contract confirmed that this item is part of collection example: true metadata: type: object additionalProperties: true - example: { } + example: {} sale: $ref: '#/components/schemas/Sale' previews: @@ -5687,7 +5669,7 @@ components: example: crypto.ton approved_by: deprecated: true - description: "please use trust field" + description: please use trust field $ref: '#/components/schemas/NftApprovedBy' include_cnft: type: boolean @@ -5725,7 +5707,7 @@ components: address: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf seqno: type: integer format: int64 @@ -5738,13 +5720,13 @@ components: items: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf proposers: type: array items: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf orders: type: array items: @@ -5766,7 +5748,7 @@ components: address: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf order_seqno: type: integer format: int64 @@ -5782,7 +5764,7 @@ components: items: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf approvals_num: type: integer format: int32 @@ -5799,7 +5781,7 @@ components: items: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf Refund: type: object required: @@ -5815,7 +5797,7 @@ components: - GetGems origin: type: string - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf ValueFlow: type: object required: @@ -5852,7 +5834,7 @@ components: qty: type: string x-js-format: bigint - example: "200" + example: '200' quantity: type: integer deprecated: true @@ -5869,7 +5851,7 @@ components: properties: type: type: string - example: "TonTransfer" + example: TonTransfer enum: - TonTransfer - ExtraCurrencyTransfer @@ -5895,7 +5877,7 @@ components: - Unknown status: type: string - example: "ok" + example: ok enum: - ok - failed @@ -5947,7 +5929,7 @@ components: type: array items: type: string - description: "transaction hash" + description: transaction hash example: e8b0e3fee4a26bd2317ac1f9952fcdc87dc08fdb617656b5202416323337372e TonTransferAction: type: object @@ -5968,7 +5950,9 @@ components: x-js-format: bigint comment: type: string - example: "Hi! This is your salary. \nFrom accounting with love." + example: |- + Hi! This is your salary. + From accounting with love. encrypted_comment: $ref: '#/components/schemas/EncryptedComment' refund: @@ -6018,11 +6002,13 @@ components: amount: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' description: amount in quanta of tokens comment: type: string - example: "Hi! This is your salary. \nFrom accounting with love." + example: |- + Hi! This is your salary. + From accounting with love. encrypted_comment: $ref: '#/components/schemas/EncryptedComment' currency: @@ -6047,10 +6033,9 @@ components: x-js-format: bigint operation: type: string - example: "NftTransfer or 0x35d95a12" + example: NftTransfer or 0x35d95a12 payload: type: string - # example ??, maybe cell? refund: $ref: '#/components/schemas/Refund' DomainRenewAction: @@ -6062,11 +6047,11 @@ components: properties: domain: type: string - example: "vasya.ton" + example: vasya.ton contract_address: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf renewer: $ref: '#/components/schemas/AccountAddress' InscriptionMintAction: @@ -6084,16 +6069,16 @@ components: type: string x-js-format: bigint description: amount in minimal particles - example: "123456789" + example: '123456789' type: type: string enum: - ton20 - gram20 - example: "ton20" + example: ton20 ticker: type: string - example: "nano" + example: nano decimals: type: integer example: 9 @@ -6115,19 +6100,21 @@ components: type: string x-js-format: bigint description: amount in minimal particles - example: "123456789" + example: '123456789' comment: type: string - example: "Hi! This is your salary. \nFrom accounting with love." + example: |- + Hi! This is your salary. + From accounting with love. type: type: string enum: - ton20 - gram20 - example: "ton20" + example: ton20 ticker: type: string - example: "nano" + example: nano decimals: type: integer example: 9 @@ -6142,16 +6129,18 @@ components: $ref: '#/components/schemas/AccountAddress' nft: type: string - example: "" + example: '' comment: type: string - example: "Hi! This is your salary. \nFrom accounting with love." + example: |- + Hi! This is your salary. + From accounting with love. encrypted_comment: $ref: '#/components/schemas/EncryptedComment' payload: type: string description: raw hex encoded payload - example: '0234de3e21d21b3ee21f3' + example: 0234de3e21d21b3ee21f3 refund: $ref: '#/components/schemas/Refund' JettonTransferAction: @@ -6177,11 +6166,13 @@ components: amount: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' description: amount in quanta of tokens comment: type: string - example: "Hi! This is your salary. \nFrom accounting with love." + example: |- + Hi! This is your salary. + From accounting with love. encrypted_comment: $ref: '#/components/schemas/EncryptedComment' refund: @@ -6205,7 +6196,7 @@ components: amount: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' description: amount in quanta of tokens jetton: $ref: '#/components/schemas/JettonPreview' @@ -6226,7 +6217,7 @@ components: amount: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' description: amount in quanta of tokens jetton: $ref: '#/components/schemas/JettonPreview' @@ -6239,12 +6230,14 @@ components: address: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf interfaces: type: array items: type: string - example: [ "nft_item", "nft_royalty" ] + example: + - nft_item + - nft_royalty SubscriptionAction: type: object required: @@ -6259,7 +6252,7 @@ components: subscription: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf beneficiary: $ref: '#/components/schemas/AccountAddress' amount: @@ -6282,7 +6275,7 @@ components: subscription: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf beneficiary: $ref: '#/components/schemas/AccountAddress' AuctionBidAction: @@ -6309,7 +6302,7 @@ components: auction: $ref: '#/components/schemas/AccountAddress' DepositStakeAction: - description: "validator's participation in elections" + description: validator's participation in elections type: object required: - amount @@ -6329,7 +6322,7 @@ components: implementation: $ref: '#/components/schemas/PoolImplementationType' WithdrawStakeAction: - description: "validator's participation in elections" + description: validator's participation in elections type: object required: - amount @@ -6349,7 +6342,7 @@ components: implementation: $ref: '#/components/schemas/PoolImplementationType' WithdrawStakeRequestAction: - description: "validator's participation in elections" + description: validator's participation in elections type: object required: - staker @@ -6411,11 +6404,11 @@ components: amount_in: type: string x-js-format: bigint - example: "1660050553" + example: '1660050553' amount_out: type: string x-js-format: bigint - example: "1660050553" + example: '1660050553' ton_in: type: integer example: 1000000000 @@ -6468,16 +6461,16 @@ components: properties: name: type: string - example: "Ton Transfer" + example: Ton Transfer description: type: string - example: "Transferring 5 Ton" + example: Transferring 5 Ton action_image: type: string description: a link to an image for this particular action. value: type: string - example: "5 Ton" + example: 5 Ton value_image: type: string description: a link to an image that depicts this action's asset. @@ -6700,7 +6693,7 @@ components: address: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf account: $ref: '#/components/schemas/AccountAddress' is_wallet: @@ -6716,7 +6709,7 @@ components: type: array items: type: string - example: "name" + example: name DomainInfo: type: object required: @@ -6740,16 +6733,16 @@ components: next_resolver: type: string format: address - example: "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf sites: type: array items: type: string - example: "http://12234.ton" + example: http://12234.ton storage: type: string - description: "tonstorage bag id" - example: "da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + description: tonstorage bag id + example: da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf NftCollection: type: object required: @@ -6774,7 +6767,7 @@ components: metadata: type: object additionalProperties: true - example: { } + example: {} previews: type: array items: @@ -6802,7 +6795,9 @@ components: type: array items: type: string - example: [ "wallet", "tep62_item" ] + example: + - wallet + - tep62_item children: type: array items: @@ -6859,7 +6854,7 @@ components: quantity: type: string x-js-format: bigint - example: "597968399" + example: '597968399' wallet_address: $ref: '#/components/schemas/AccountAddress' jetton: @@ -6874,7 +6869,7 @@ components: $ref: '#/components/schemas/AccountAddress' destination_wallet_version: type: string - example: "v3R2" + example: v3R2 ext_in_msg_decoded: type: object properties: @@ -6959,7 +6954,7 @@ components: example: 1 bounded_query_id: type: string - example: "34254528475294857" + example: '34254528475294857' raw_messages: type: array items: @@ -6980,12 +6975,12 @@ components: format: cell decoded_op_name: type: string - example: "nft_transfer" + example: nft_transfer op_code: type: string x-js-format: bigint - example: "0xdeadbeaf" - decoded_body: { } # Free-form JSON value + example: '0xdeadbeaf' + decoded_body: {} mode: type: integer example: 2 @@ -7048,10 +7043,10 @@ components: example: WTON decimals: type: string - example: "9" + example: '9' image: type: string - example: "https://bitcoincash-example.github.io/website/logo.png" + example: https://bitcoincash-example.github.io/website/logo.png description: this field currently returns a cached image URL (e.g., "https://cache.tonapi.io/images/jetton.jpg"). In the future, this will be replaced with the original URL from the metadata. The cached image is already available in the `preview` field of `JettonInfo` and will remain there. description: type: string @@ -7060,20 +7055,26 @@ components: type: array items: type: string - example: [ "https://t.me/durov_coin", "https://twitter.com/durov_coin" ] + example: + - https://t.me/durov_coin + - https://twitter.com/durov_coin websites: type: array items: type: string - example: [ "https://durov.coin", "ton://durov-coin.ton" ] + example: + - https://durov.coin + - ton://durov-coin.ton catalogs: type: array items: type: string - example: [ "https://coinmarketcap.com/currencies/drv/", "https://www.coingecko.com/en/coins/durov" ] + example: + - https://coinmarketcap.com/currencies/drv/ + - https://www.coingecko.com/en/coins/durov custom_payload_api_uri: type: string - example: "https://claim-api.tonapi.io/jettons/TESTMINT" + example: https://claim-api.tonapi.io/jettons/TESTMINT InscriptionBalances: type: object required: @@ -7096,14 +7097,14 @@ components: enum: - ton20 - gram20 - example: "ton20" + example: ton20 ticker: type: string - example: "nano" + example: nano balance: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' decimals: type: integer example: 9 @@ -7132,14 +7133,14 @@ components: total_supply: type: string x-js-format: bigint - example: "5887105890579978" + example: '5887105890579978' admin: $ref: '#/components/schemas/AccountAddress' metadata: $ref: '#/components/schemas/JettonMetadata' preview: type: string - example: "https://cache.tonapi.io/images/jetton.jpg" + example: https://cache.tonapi.io/images/jetton.jpg verification: $ref: '#/components/schemas/JettonVerificationType' holders_count: @@ -7170,7 +7171,7 @@ components: balance: type: string x-js-format: bigint - example: "168856200518084" + example: '168856200518084' description: balance in the smallest jetton's units total: type: integer @@ -7184,14 +7185,12 @@ components: properties: custom_payload: type: string - # format: ??? - example: "b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d" - description: "hex-encoded BoC" + example: b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d + description: hex-encoded BoC state_init: type: string - # format: ??? - example: "b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d" - description: "hex-encoded BoC" + example: b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d + description: hex-encoded BoC AccountStaking: type: object required: @@ -7212,7 +7211,7 @@ components: properties: pool: type: string - example: "EQBI-wGVp_x0VFEjd7m9cEUD3tJ_bnxMSp0Tb9qz757ATEAM" + example: EQBI-wGVp_x0VFEjd7m9cEUD3tJ_bnxMSp0Tb9qz757ATEAM amount: type: integer format: int64 @@ -7253,10 +7252,10 @@ components: address: type: string format: address - example: "0:48fb0195a7fc7454512377b9bd704503ded27f6e7c4c4a9d136fdab3ef9ec04c" + example: 0:48fb0195a7fc7454512377b9bd704503ded27f6e7c4c4a9d136fdab3ef9ec04c name: type: string - example: "Tonkeeper pool" + example: Tonkeeper pool total_amount: type: integer format: int64 @@ -7297,20 +7296,20 @@ components: liquid_jetton_master: type: string format: address - example: "0:4a91d32d0289bda9813ae00ff7640e6c38fdce76e4583dd6afc463b70c7d767c" - description: "for liquid staking master account of jetton" + example: 0:4a91d32d0289bda9813ae00ff7640e6c38fdce76e4583dd6afc463b70c7d767c + description: for liquid staking master account of jetton nominators_stake: type: integer format: int64 x-js-format: bigint example: 5000000000 - description: "total stake of all nominators" + description: total stake of all nominators validator_stake: type: integer format: int64 x-js-format: bigint example: 5000000000 - description: "stake of validator" + description: stake of validator cycle_length: type: integer format: int64 @@ -7327,15 +7326,15 @@ components: example: TON Whales description: type: string - example: "Oldest pool with minimal staking amount 50 TON" + example: Oldest pool with minimal staking amount 50 TON url: type: string - example: "https://tonvalidators.org/" + example: https://tonvalidators.org/ socials: type: array items: type: string - example: "https://t.me/tonwhales" + example: https://t.me/tonwhales StorageProvider: type: object required: @@ -7390,10 +7389,10 @@ components: format: address name: type: string - example: "blah_blah.ton" + example: blah_blah.ton preview: type: string - example: "https://cache.tonapi.io/images/media.jpg" + example: https://cache.tonapi.io/images/media.jpg trust: $ref: '#/components/schemas/TrustType' DnsExpiring: @@ -7415,7 +7414,7 @@ components: example: 1678275313 name: type: string - example: "blah_blah.ton" + example: blah_blah.ton dns_item: $ref: '#/components/schemas/NftItem' ChartPoints: @@ -7428,7 +7427,9 @@ components: description: Decimal price of the token in the requested currency items: false additionalItems: false - example: [[ 1668436763, 97.21323234 ]] + example: + - - 1668436763 + - 97.21323234 AccountInfoByStateInit: type: object required: @@ -7437,11 +7438,11 @@ components: properties: public_key: type: string - example: "NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3..." + example: NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3... address: type: string format: address - example: "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + example: 0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b Seqno: type: object required: @@ -7465,8 +7466,7 @@ components: format: int32 shard: type: string - # x-js-format: bigint ?? - example: "800000000000000" + example: '800000000000000' seqno: type: integer example: 30699640 @@ -7502,10 +7502,10 @@ components: properties: encryption_type: type: string - example: "simple" + example: simple cipher_text: type: string - example: "A6A0BD6608672B...CE3AF8DB" + example: A6A0BD6608672B...CE3AF8DB BlockchainAccountInspect: type: object required: @@ -7551,19 +7551,19 @@ components: additionalProperties: type: string example: - TON: "-1.28%" + TON: '-1.28%' diff_7d: type: object additionalProperties: type: string example: - TON: "-2.74%" + TON: '-2.74%' diff_30d: type: object additionalProperties: type: string example: - TON: "-0.56%" + TON: '-0.56%' MarketTonRates: type: object required: @@ -7573,10 +7573,10 @@ components: properties: market: type: string - example: "OKX" + example: OKX usd_price: type: number - example: 5.20 + example: 5.2 last_date_update: type: integer format: int64 @@ -7590,7 +7590,7 @@ components: amount: type: string x-js-format: bigint - example: "1000000000" + example: '1000000000' preview: $ref: '#/components/schemas/EcPreview' SourceFile: @@ -7635,8 +7635,7 @@ components: format: int64 method: type: string - example: "get_something" - + example: get_something responses: Error: description: Some error during request processing @@ -7651,4 +7650,4 @@ components: type: string error_code: type: integer - format: int64 \ No newline at end of file + format: int64 diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index 0ee4877..4bbc76e 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -10,12 +10,42 @@ import { import path from 'path'; import * as fs from 'fs'; import * as https from 'https'; +import * as yaml from 'js-yaml'; const packageVersion = process.env.npm_package_version; const openapiPath = path.resolve(process.cwd(), 'src/api.yml'); const openapiUrl = 'https://tonapi.io/v2/openapi.yml'; +/** + * Schema Patches System + * --------------------- + * This file (schema-patches.json) contains modifications that are automatically + * applied to the OpenAPI schema before client generation. + * + * Format: Standard JSON object that gets deeply merged with the original schema. + * + * Example: + * { + * "components": { + * "schemas": { + * "ChartPoints": { + * "type": "array", + * "prefixItems": [ + * { "type": "integer", "format": "int64", "description": "Unix timestamp" }, + * { "type": "number", "description": "Price" } + * ], + * "items": false + * } + * } + * } + * } + * + * The patch will be applied every time you run `npm run build`. + * To add new patches, simply edit src/schema-patches.json. + */ +const schemaPatchesPath = path.resolve(process.cwd(), 'src/schema-patches.json'); + function downloadSchema(url: string, outputPath: string): Promise { return new Promise((resolve, reject) => { const file = fs.createWriteStream(outputPath); @@ -35,6 +65,66 @@ function downloadSchema(url: string, outputPath: string): Promise { }); } +/** + * Deep merge two objects with priority to patch values + */ +function deepMerge(target: any, patch: any): any { + if (patch === null || patch === undefined) { + return target; + } + + if (typeof patch !== 'object' || Array.isArray(patch)) { + return patch; + } + + const result = { ...target }; + + for (const key in patch) { + if (patch.hasOwnProperty(key)) { + if (typeof patch[key] === 'object' && !Array.isArray(patch[key]) && patch[key] !== null) { + result[key] = deepMerge(target[key] || {}, patch[key]); + } else { + result[key] = patch[key]; + } + } + } + + return result; +} + +/** + * Apply patches from schema-patches.json to the downloaded schema + */ +function applySchemaPatches(schemaPath: string, patchesPath: string): void { + if (!fs.existsSync(patchesPath)) { + console.log('No schema patches file found, skipping patches'); + return; + } + + console.log('Applying schema patches...'); + + // Read the schema + const schemaContent = fs.readFileSync(schemaPath, 'utf8'); + const schema = yaml.load(schemaContent) as any; + + // Read the patches + const patchesContent = fs.readFileSync(patchesPath, 'utf8'); + const patches = JSON.parse(patchesContent); + + // Apply patches + const patchedSchema = deepMerge(schema, patches); + + // Write back to file + const yamlOutput = yaml.dump(patchedSchema, { + lineWidth: -1, + noRefs: true, + sortKeys: false + }); + + fs.writeFileSync(schemaPath, yamlOutput, 'utf8'); + console.log('Schema patches applied successfully'); +} + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, match => match[1]?.toUpperCase() ?? ''); } @@ -167,7 +257,13 @@ const generateApiParams: GenerateApiParams = { }; async function main() { + // Uncomment the following lines to download schema and apply patches automatically // await downloadSchema(openapiUrl, openapiPath); + // applySchemaPatches(openapiPath, schemaPatchesPath); + + // Apply patches to existing schema + applySchemaPatches(openapiPath, schemaPatchesPath); + generateApi(generateApiParams); } diff --git a/packages/client/src/schema-patches.json b/packages/client/src/schema-patches.json new file mode 100644 index 0000000..ff3addc --- /dev/null +++ b/packages/client/src/schema-patches.json @@ -0,0 +1,23 @@ +{ + "components": { + "schemas": { + "ChartPoints": { + "type": "array", + "prefixItems": [ + { + "type": "integer", + "format": "int64", + "description": "Unix timestamp of the data point" + }, + { + "type": "number", + "description": "Decimal price of the token in the requested currency" + } + ], + "items": false, + "additionalItems": false, + "example": [[1668436763, 97.21323234]] + } + } + } +} From 3358e7c6ba05b57638f4f2034dec6a94d48bc7f7 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Tue, 11 Nov 2025 02:32:34 +0400 Subject: [PATCH 03/27] feat: enhance HttpClient with API key management and custom fetch support - Added `setApiKey` method to manage API key in request headers, allowing for dynamic updates. - Introduced `setCustomFetch` method to enable custom fetch implementations. - Refactored client initialization to support singleton pattern for HttpClient, ensuring a single instance is used throughout the application. - Updated API client configuration methods to allow for dynamic updates of base URL, API key, and fetch function. - Adjusted tests to utilize the new client initialization and API key management features, ensuring robust testing of the new functionality. --- packages/client/src/client.ts | 6639 ++++++++--------- packages/client/src/generate.ts | 7 +- packages/client/src/templates/api.ejs | 56 +- packages/client/src/templates/http-client.ejs | 23 + .../client/src/templates/procedure-call.ejs | 8 +- tests/client/client.test.ts | 46 +- tests/client/errors.test.ts | 26 +- tests/client/memory-leak.test.ts | 13 +- tests/client/parse-address.test.ts | 13 +- tests/client/parse-bigint.test.ts | 13 +- tests/client/parse-cell.test.ts | 15 +- tests/client/parse-tuple.test.ts | 11 +- tests/client/services.test.ts | 15 +- tests/client/utils/client.ts | 33 +- 14 files changed, 3467 insertions(+), 3451 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 52b9493..9e58fcc 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3478,6 +3478,29 @@ class HttpClient { } }; + public setApiKey = (apiKey: string | undefined) => { + if (apiKey) { + this.baseApiParams = { + ...this.baseApiParams, + headers: { + ...(this.baseApiParams.headers || {}), + Authorization: `Bearer ${apiKey}` + } as HeadersInit + }; + } else { + const headers = { ...(this.baseApiParams.headers || {}) } as Record; + delete headers['Authorization']; + this.baseApiParams = { + ...this.baseApiParams, + headers: headers as HeadersInit + }; + } + }; + + public setCustomFetch = (fetchFn: typeof fetch | undefined) => { + this.providedFetch = fetchFn ?? null; + }; + public request = async ({ body, secure, @@ -6063,3217 +6086,3141 @@ function prepareRequestData(data: any, orSchema?: any): any { * * Provide access to indexed TON blockchain */ -export class TonApiClient { - http: HttpClient; - constructor(apiConfig: ApiConfig = {}) { - this.http = new HttpClient(apiConfig); +// Singleton HttpClient instance +let httpClient: HttpClient | null = null; + +/** + * Initialize the API client with configuration + * @param apiConfig - Configuration for the API client (baseUrl, apiKey, etc.) + */ +export function initClient(apiConfig: ApiConfig = {}): void { + httpClient = new HttpClient(apiConfig); +} + +/** + * Get the current HttpClient instance (creates one if it doesn't exist) + * @internal + */ +function getHttpClient(): HttpClient { + if (!httpClient) { + httpClient = new HttpClient(); } + return httpClient; +} - utilities = { - /** - * @description Get the openapi.json file - * - * @tags Utilities - * @name GetOpenapiJson - * @request GET:/v2/openapi.json - */ - getOpenapiJson: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/openapi.json`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, {}); - }, +/** + * Update the API client configuration + * @param apiConfig - Configuration to update + */ +export function updateClient(apiConfig: Partial): void { + const client = getHttpClient(); + if (apiConfig.baseUrl !== undefined) client.baseUrl = apiConfig.baseUrl; + if (apiConfig.apiKey !== undefined) client.setApiKey(apiConfig.apiKey); + if (apiConfig.fetch !== undefined) client.setCustomFetch(apiConfig.fetch); +} - /** - * @description Get the openapi.yml file - * - * @tags Utilities - * @name GetOpenapiYml - * @request GET:/v2/openapi.yml - */ - getOpenapiYml: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/openapi.yml`, - method: 'GET', - ...params - }); - - return prepareResponse(req); - }, +/** + * @description Get the openapi.json file + * + * @tags Utilities + * @name GetOpenapiJson + * @request GET:/v2/openapi.json + */ +export const getOpenapiJson = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/openapi.json`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Status - * - * @tags Utilities - * @name Status - * @request GET:/v2/status - */ - status: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/status`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/ServiceStatus' }); - }, + return prepareResponse(req, {}); +}; - /** - * @description parse address and display in all formats - * - * @tags Utilities - * @name AddressParse - * @request GET:/v2/address/{account_id}/parse - */ - addressParse: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/address/${accountId}/parse`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['raw_form', 'bounceable', 'non_bounceable', 'given_type', 'test_only'], - properties: { - raw_form: { type: 'string', format: 'address' }, - bounceable: { - required: ['b64', 'b64url'], - type: 'object', - properties: { b64: { type: 'string' }, b64url: { type: 'string' } } - }, - non_bounceable: { - required: ['b64', 'b64url'], - type: 'object', - properties: { b64: { type: 'string' }, b64url: { type: 'string' } } - }, - given_type: { type: 'string' }, - test_only: { type: 'boolean' } - } - }); - } - }; - blockchain = { - /** - * @description Get reduced blockchain blocks data - * - * @tags Blockchain - * @name GetReducedBlockchainBlocks - * @request GET:/v2/blockchain/reduced/blocks - */ - getReducedBlockchainBlocks: ( - query: { - /** @format int64 */ - from: number; - /** @format int64 */ - to: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/blockchain/reduced/blocks`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/ReducedBlocks' - }); - }, +/** + * @description Get the openapi.yml file + * + * @tags Utilities + * @name GetOpenapiYml + * @request GET:/v2/openapi.yml + */ +export const getOpenapiYml = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/openapi.yml`, + method: 'GET', + ...params + }); - /** - * @description Get blockchain block data - * - * @tags Blockchain - * @name GetBlockchainBlock - * @request GET:/v2/blockchain/blocks/{block_id} - */ - getBlockchainBlock: (blockId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/blocks/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlock' - }); - }, + return prepareResponse(req); +}; - /** - * @description Get blockchain block shards - * - * @tags Blockchain - * @name GetBlockchainMasterchainShards - * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards - */ - getBlockchainMasterchainShards: (masterchainSeqno: number, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/shards`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlockShards' - }); - }, +/** + * @description Status + * + * @tags Utilities + * @name Status + * @request GET:/v2/status + */ +export const status = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/status`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get all blocks in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. - * - * @tags Blockchain - * @name GetBlockchainMasterchainBlocks - * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks - */ - getBlockchainMasterchainBlocks: (masterchainSeqno: number, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/blocks`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlocks' - }); - }, + return prepareResponse(req, { $ref: '#/components/schemas/ServiceStatus' }); +}; - /** - * @description Get all transactions in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. - * - * @tags Blockchain - * @name GetBlockchainMasterchainTransactions - * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions - */ - getBlockchainMasterchainTransactions: ( - masterchainSeqno: number, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/transactions`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transactions' - }); - }, +/** + * @description parse address and display in all formats + * + * @tags Utilities + * @name AddressParse + * @request GET:/v2/address/{account_id}/parse + */ +export const addressParse = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/address/${accountId}/parse`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get blockchain config from a specific block, if present. - * - * @tags Blockchain - * @name GetBlockchainConfigFromBlock - * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config - */ - getBlockchainConfigFromBlock: (masterchainSeqno: number, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/config`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainConfig' - }); - }, + return prepareResponse(req, { + type: 'object', + required: ['raw_form', 'bounceable', 'non_bounceable', 'given_type', 'test_only'], + properties: { + raw_form: { type: 'string', format: 'address' }, + bounceable: { + required: ['b64', 'b64url'], + type: 'object', + properties: { b64: { type: 'string' }, b64url: { type: 'string' } } + }, + non_bounceable: { + required: ['b64', 'b64url'], + type: 'object', + properties: { b64: { type: 'string' }, b64url: { type: 'string' } } + }, + given_type: { type: 'string' }, + test_only: { type: 'boolean' } + } + }); +}; - /** - * @description Get raw blockchain config from a specific block, if present. - * - * @tags Blockchain - * @name GetRawBlockchainConfigFromBlock - * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw - */ - getRawBlockchainConfigFromBlock: (masterchainSeqno: number, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/config/raw`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/RawBlockchainConfig' - }); - }, +/** + * @description Get reduced blockchain blocks data + * + * @tags Blockchain + * @name GetReducedBlockchainBlocks + * @request GET:/v2/blockchain/reduced/blocks + */ +export const getReducedBlockchainBlocks = ( + query: { + /** @format int64 */ + from: number; + /** @format int64 */ + to: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/reduced/blocks`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - /** - * @description Get transactions from block - * - * @tags Blockchain - * @name GetBlockchainBlockTransactions - * @request GET:/v2/blockchain/blocks/{block_id}/transactions - */ - getBlockchainBlockTransactions: (blockId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/blocks/${blockId}/transactions`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transactions' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/ReducedBlocks' + }); +}; - /** - * @description Get transaction data - * - * @tags Blockchain - * @name GetBlockchainTransaction - * @request GET:/v2/blockchain/transactions/{transaction_id} - */ - getBlockchainTransaction: (transactionId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/transactions/${transactionId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transaction' - }); - }, +/** + * @description Get blockchain block data + * + * @tags Blockchain + * @name GetBlockchainBlock + * @request GET:/v2/blockchain/blocks/{block_id} + */ +export const getBlockchainBlock = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/blocks/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get transaction data by message hash - * - * @tags Blockchain - * @name GetBlockchainTransactionByMessageHash - * @request GET:/v2/blockchain/messages/{msg_id}/transaction - */ - getBlockchainTransactionByMessageHash: (msgId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/messages/${msgId}/transaction`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transaction' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlock' + }); +}; - /** - * @description Get blockchain validators - * - * @tags Blockchain - * @name GetBlockchainValidators - * @request GET:/v2/blockchain/validators - */ - getBlockchainValidators: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/validators`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Validators' - }); - }, +/** + * @description Get blockchain block shards + * + * @tags Blockchain + * @name GetBlockchainMasterchainShards + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards + */ +export const getBlockchainMasterchainShards = ( + masterchainSeqno: number, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/shards`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get last known masterchain block - * - * @tags Blockchain - * @name GetBlockchainMasterchainHead - * @request GET:/v2/blockchain/masterchain-head - */ - getBlockchainMasterchainHead: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/masterchain-head`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlock' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlockShards' + }); +}; - /** - * @description Get low-level information about an account taken directly from the blockchain. - * - * @tags Blockchain - * @name GetBlockchainRawAccount - * @request GET:/v2/blockchain/accounts/{account_id} - */ - getBlockchainRawAccount: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/blockchain/accounts/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainRawAccount' - }); - }, +/** + * @description Get all blocks in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. + * + * @tags Blockchain + * @name GetBlockchainMasterchainBlocks + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks + */ +export const getBlockchainMasterchainBlocks = ( + masterchainSeqno: number, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/blocks`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get account transactions - * - * @tags Blockchain - * @name GetBlockchainAccountTransactions - * @request GET:/v2/blockchain/accounts/{account_id}/transactions - */ - getBlockchainAccountTransactions: ( - accountId_Address: Address, - query?: { - /** - * omit this parameter to get last transactions - * @format bigint - * @example 39787624000003 - */ - after_lt?: bigint; - /** - * omit this parameter to get last transactions - * @format bigint - * @example 39787624000003 - */ - before_lt?: bigint; - /** - * @format int32 - * @min 1 - * @max 1000 - * @default 100 - * @example 100 - */ - limit?: number; - /** - * used to sort the result-set in ascending or descending order by lt. - * @default "desc" - */ - sort_order?: 'desc' | 'asc'; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/blockchain/accounts/${accountId}/transactions`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transactions' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlocks' + }); +}; - /** - * @description Execute get method for account - * - * @tags Blockchain - * @name ExecGetMethodForBlockchainAccount - * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} - */ - execGetMethodForBlockchainAccount: ( - accountId_Address: Address, - methodName: string, - query?: { - /** - * Supported values: - * "NaN" for NaN type, - * "Null" for Null type, - * 10-base digits for tiny int type (Example: 100500), - * 0x-prefixed hex digits for int257 (Example: 0xfa01d78381ae32), - * all forms of addresses for slice type (Example: 0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e), - * single-root base64-encoded BOC for cell (Example: "te6ccgEBAQEAAgAAAA=="), - * single-root hex-encoded BOC for slice (Example: b5ee9c72010101010002000000) - * @example ["0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8"] - */ - args?: string[]; - /** - * A temporary fix to switch to a scheme with direct ordering of arguments. - * If equal to false, then the method takes arguments in direct order, - * e.g. for get_nft_content(int index, cell individual_content) we pass a list of arguments [index, individual_content]. - * If equal to true, then the method takes arguments in reverse order, e.g. [individual_content, index]. - * @default true - */ - fix_order?: boolean; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/MethodExecutionResult' - }); - }, +/** + * @description Get all transactions in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. + * + * @tags Blockchain + * @name GetBlockchainMasterchainTransactions + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions + */ +export const getBlockchainMasterchainTransactions = ( + masterchainSeqno: number, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/transactions`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Send message to blockchain - * - * @tags Blockchain - * @name SendBlockchainMessage - * @request POST:/v2/blockchain/message - */ - sendBlockchainMessage: ( - data: { - /** @format cell */ - boc?: Cell; - /** @maxItems 5 */ - batch?: Cell[]; - meta?: Record; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/blockchain/message`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - properties: { - boc: { type: 'string', format: 'cell' }, - batch: { - type: 'array', - maxItems: 5, - items: { type: 'string', format: 'cell' } - }, - meta: { type: 'object', additionalProperties: { type: 'string' } } - } - }), - ...params - }); + return prepareResponse(req, { + $ref: '#/components/schemas/Transactions' + }); +}; - return prepareResponse(req); - }, +/** + * @description Get blockchain config from a specific block, if present. + * + * @tags Blockchain + * @name GetBlockchainConfigFromBlock + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config + */ +export const getBlockchainConfigFromBlock = ( + masterchainSeqno: number, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/config`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get blockchain config - * - * @tags Blockchain - * @name GetBlockchainConfig - * @request GET:/v2/blockchain/config - */ - getBlockchainConfig: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/config`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainConfig' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainConfig' + }); +}; - /** - * @description Get raw blockchain config - * - * @tags Blockchain - * @name GetRawBlockchainConfig - * @request GET:/v2/blockchain/config/raw - */ - getRawBlockchainConfig: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/blockchain/config/raw`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/RawBlockchainConfig' - }); - }, +/** + * @description Get raw blockchain config from a specific block, if present. + * + * @tags Blockchain + * @name GetRawBlockchainConfigFromBlock + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw + */ +export const getRawBlockchainConfigFromBlock = ( + masterchainSeqno: number, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/config/raw`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Blockchain account inspect - * - * @tags Blockchain - * @name BlockchainAccountInspect - * @request GET:/v2/blockchain/accounts/{account_id}/inspect - */ - blockchainAccountInspect: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/blockchain/accounts/${accountId}/inspect`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainAccountInspect' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/RawBlockchainConfig' + }); +}; - /** - * @description Status - * - * @tags Utilities - * @name Status - * @request GET:/v2/status - * @deprecated - */ - status: (requestParams: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/status`, - method: 'GET', - format: 'json', - ...requestParams - }); +/** + * @description Get transactions from block + * + * @tags Blockchain + * @name GetBlockchainBlockTransactions + * @request GET:/v2/blockchain/blocks/{block_id}/transactions + */ +export const getBlockchainBlockTransactions = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/blocks/${blockId}/transactions`, + method: 'GET', + format: 'json', + ...params + }); - return prepareResponse(req, { $ref: '#/components/schemas/ServiceStatus' }); - } - }; - accounts = { - /** - * @description Get human-friendly information about several accounts without low-level details. - * - * @tags Accounts - * @name GetAccounts - * @request POST:/v2/accounts/_bulk - */ - getAccounts: ( - data: { - accountIds: Address[]; - }, - query?: { - /** @example "usd" */ - currency?: string; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/accounts/_bulk`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); + return prepareResponse(req, { + $ref: '#/components/schemas/Transactions' + }); +}; - return prepareResponse(req, { $ref: '#/components/schemas/Accounts' }); - }, +/** + * @description Get transaction data + * + * @tags Blockchain + * @name GetBlockchainTransaction + * @request GET:/v2/blockchain/transactions/{transaction_id} + */ +export const getBlockchainTransaction = (transactionId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/transactions/${transactionId}`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get human-friendly information about an account without low-level details. - * - * @tags Accounts - * @name GetAccount - * @request GET:/v2/accounts/{account_id} - */ - getAccount: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Account' }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/Transaction' + }); +}; - /** - * @description Get account's domains - * - * @tags Accounts - * @name AccountDnsBackResolve - * @request GET:/v2/accounts/{account_id}/dns/backresolve - */ - accountDnsBackResolve: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/dns/backresolve`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DomainNames' - }); - }, +/** + * @description Get transaction data by message hash + * + * @tags Blockchain + * @name GetBlockchainTransactionByMessageHash + * @request GET:/v2/blockchain/messages/{msg_id}/transaction + */ +export const getBlockchainTransactionByMessageHash = ( + msgId: string, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/messages/${msgId}/transaction`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get all Jettons balances by owner address - * - * @tags Accounts - * @name GetAccountJettonsBalances - * @request GET:/v2/accounts/{account_id}/jettons - */ - getAccountJettonsBalances: ( - accountId_Address: Address, - query?: { - /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] - */ - currencies?: string[]; - /** - * comma separated list supported extensions - * @example ["custom_payload"] - */ - supported_extensions?: string[]; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/jettons`, - method: 'GET', - query: query, - queryImplode: ['currencies', 'supported_extensions'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonsBalances' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/Transaction' + }); +}; - /** - * @description Get Jetton balance by owner address - * - * @tags Accounts - * @name GetAccountJettonBalance - * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} - */ - getAccountJettonBalance: ( - accountId_Address: Address, - jettonId_Address: Address, - query?: { - /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] - */ - currencies?: string[]; - /** - * comma separated list supported extensions - * @example ["custom_payload"] - */ - supported_extensions?: string[]; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/jettons/${jettonId}`, - method: 'GET', - query: query, - queryImplode: ['currencies', 'supported_extensions'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonBalance' - }); - }, +/** + * @description Get blockchain validators + * + * @tags Blockchain + * @name GetBlockchainValidators + * @request GET:/v2/blockchain/validators + */ +export const getBlockchainValidators = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/validators`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get the transfer jettons history for account - * - * @tags Accounts - * @name GetAccountJettonsHistory - * @request GET:/v2/accounts/{account_id}/jettons/history - */ - getAccountJettonsHistory: ( - accountId_Address: Address, - query: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @example 100 - */ - limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/jettons/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/Validators' + }); +}; - /** - * @description Get the transfer jetton history for account and jetton - * - * @tags Accounts - * @name GetAccountJettonHistoryById - * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history - */ - getAccountJettonHistoryById: ( - accountId_Address: Address, - jettonId_Address: Address, - query: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @example 100 - */ - limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/jettons/${jettonId}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, +/** + * @description Get last known masterchain block + * + * @tags Blockchain + * @name GetBlockchainMasterchainHead + * @request GET:/v2/blockchain/masterchain-head + */ +export const getBlockchainMasterchainHead = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/masterchain-head`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get all NFT items by owner address - * - * @tags Accounts - * @name GetAccountNftItems - * @request GET:/v2/accounts/{account_id}/nfts - */ - getAccountNftItems: ( - accountId_Address: Address, - query?: { - /** - * nft collection - * @format address - * @example "0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465" - */ - collection?: Address; - /** - * @min 1 - * @max 1000 - * @default 1000 - */ - limit?: number; - /** - * @min 0 - * @default 0 - */ - offset?: number; - /** - * Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. - * @default false - */ - indirect_ownership?: boolean; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/nfts`, - method: 'GET', - query: query && { - ...query, - collection: query.collection?.toRawString() - }, - format: 'json', - ...params - }); + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlock' + }); +}; - return prepareResponse(req, { - $ref: '#/components/schemas/NftItems' - }); - }, +/** + * @description Get low-level information about an account taken directly from the blockchain. + * + * @tags Blockchain + * @name GetBlockchainRawAccount + * @request GET:/v2/blockchain/accounts/{account_id} + */ +export const getBlockchainRawAccount = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/blockchain/accounts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get events for an account. Each event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. - * - * @tags Accounts - * @name GetAccountEvents - * @request GET:/v2/accounts/{account_id}/events - */ - getAccountEvents: ( - accountId_Address: Address, - query: { - /** - * Show only events that are initiated by this account - * @default false - */ - initiator?: boolean; - /** - * filter actions where requested account is not real subject (for example sender or receiver jettons) - * @default false - */ - subject_only?: boolean; - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 100 - * @example 20 - */ - limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/events`, - method: 'GET', - query: query, - queryImplode: ['initiator'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainRawAccount' + }); +}; +/** + * @description Get account transactions + * + * @tags Blockchain + * @name GetBlockchainAccountTransactions + * @request GET:/v2/blockchain/accounts/{account_id}/transactions + */ +export const getBlockchainAccountTransactions = ( + accountId_Address: Address, + query?: { /** - * @description Get event for an account by event_id - * - * @tags Accounts - * @name GetAccountEvent - * @request GET:/v2/accounts/{account_id}/events/{event_id} + * omit this parameter to get last transactions + * @format bigint + * @example 39787624000003 */ - getAccountEvent: ( - accountId_Address: Address, - eventId: string, - query?: { - /** - * filter actions where requested account is not real subject (for example sender or receiver jettons) - * @default false - */ - subject_only?: boolean; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/events/${eventId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvent' - }); - }, - + after_lt?: bigint; /** - * @description Get traces for account - * - * @tags Accounts - * @name GetAccountTraces - * @request GET:/v2/accounts/{account_id}/traces + * omit this parameter to get last transactions + * @format bigint + * @example 39787624000003 */ - getAccountTraces: ( - accountId_Address: Address, - query?: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @default 100 - * @example 100 - */ - limit?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/traces`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/TraceIDs' - }); - }, - + before_lt?: bigint; /** - * @description Get all subscriptions by wallet address - * - * @tags Accounts - * @name GetAccountSubscriptions - * @request GET:/v2/accounts/{account_id}/subscriptions - */ - getAccountSubscriptions: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/subscriptions`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Subscriptions' - }); - }, + * @format int32 + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + /** + * used to sort the result-set in ascending or descending order by lt. + * @default "desc" + */ + sort_order?: 'desc' | 'asc'; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/blockchain/accounts/${accountId}/transactions`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - /** - * @description Update internal cache for a particular account - * - * @tags Accounts - * @name ReindexAccount - * @request POST:/v2/accounts/{account_id}/reindex - */ - reindexAccount: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/reindex`, - method: 'POST', - ...params - }); - - return prepareResponse(req); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/Transactions' + }); +}; - /** - * @description Search by account domain name - * - * @tags Accounts - * @name SearchAccounts - * @request GET:/v2/accounts/search - */ - searchAccounts: ( - query: { - /** - * @minLength 3 - * @maxLength 15 - */ - name: string; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/accounts/search`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/FoundAccounts' - }); - }, +/** + * @description Execute get method for account + * + * @tags Blockchain + * @name ExecGetMethodForBlockchainAccount + * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} + */ +export const execGetMethodForBlockchainAccount = ( + accountId_Address: Address, + methodName: string, + query?: { + /** + * Supported values: + * "NaN" for NaN type, + * "Null" for Null type, + * 10-base digits for tiny int type (Example: 100500), + * 0x-prefixed hex digits for int257 (Example: 0xfa01d78381ae32), + * all forms of addresses for slice type (Example: 0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e), + * single-root base64-encoded BOC for cell (Example: "te6ccgEBAQEAAgAAAA=="), + * single-root hex-encoded BOC for slice (Example: b5ee9c72010101010002000000) + * @example ["0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8"] + */ + args?: string[]; + /** + * A temporary fix to switch to a scheme with direct ordering of arguments. + * If equal to false, then the method takes arguments in direct order, + * e.g. for get_nft_content(int index, cell individual_content) we pass a list of arguments [index, individual_content]. + * If equal to true, then the method takes arguments in reverse order, e.g. [individual_content, index]. + * @default true + */ + fix_order?: boolean; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - /** - * @description Get expiring account .ton dns - * - * @tags Accounts - * @name GetAccountDnsExpiring - * @request GET:/v2/accounts/{account_id}/dns/expiring - */ - getAccountDnsExpiring: ( - accountId_Address: Address, - query?: { - /** - * number of days before expiration - * @min 1 - * @max 3660 - */ - period?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/dns/expiring`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DnsExpiring' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/MethodExecutionResult' + }); +}; - /** - * @description Get public key by account id - * - * @tags Accounts - * @name GetAccountPublicKey - * @request GET:/v2/accounts/{account_id}/publickey - */ - getAccountPublicKey: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/publickey`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['public_key'], - properties: { public_key: { type: 'string' } } - }); - }, +/** + * @description Send message to blockchain + * + * @tags Blockchain + * @name SendBlockchainMessage + * @request POST:/v2/blockchain/message + */ +export const sendBlockchainMessage = ( + data: { + /** @format cell */ + boc?: Cell; + /** @maxItems 5 */ + batch?: Cell[]; + meta?: Record; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/message`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + properties: { + boc: { type: 'string', format: 'cell' }, + batch: { type: 'array', maxItems: 5, items: { type: 'string', format: 'cell' } }, + meta: { type: 'object', additionalProperties: { type: 'string' } } + } + }), + ...params + }); - /** - * @description Get account's multisigs - * - * @tags Accounts - * @name GetAccountMultisigs - * @request GET:/v2/accounts/{account_id}/multisigs - */ - getAccountMultisigs: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/multisigs`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Multisigs' - }); - }, + return prepareResponse(req); +}; - /** - * @description Get account's balance change - * - * @tags Accounts - * @name GetAccountDiff - * @request GET:/v2/accounts/{account_id}/diff - */ - getAccountDiff: ( - accountId_Address: Address, - query: { - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/diff`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['balance_change'], - properties: { balance_change: { type: 'integer', format: 'int64' } } - }); - }, +/** + * @description Get blockchain config + * + * @tags Blockchain + * @name GetBlockchainConfig + * @request GET:/v2/blockchain/config + */ +export const getBlockchainConfig = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/config`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get the transfer history of extra currencies for an account. - * - * @tags Accounts - * @name GetAccountExtraCurrencyHistoryById - * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history - */ - getAccountExtraCurrencyHistoryById: ( - accountId_Address: Address, - id: number, - query: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @example 100 - */ - limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/extra-currency/${id}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainConfig' + }); +}; - /** - * @description parse address and display in all formats - * - * @tags Utilities - * @name AddressParse - * @request GET:/v2/address/{account_id}/parse - * @deprecated - */ - addressParse: (accountId_Address: Address, requestParams: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/address/${accountId}/parse`, - method: 'GET', - format: 'json', - ...requestParams - }); - - return prepareResponse(req, { - type: 'object', - required: ['raw_form', 'bounceable', 'non_bounceable', 'given_type', 'test_only'], - properties: { - raw_form: { type: 'string', format: 'address' }, - bounceable: { - required: ['b64', 'b64url'], - type: 'object', - properties: { b64: { type: 'string' }, b64url: { type: 'string' } } - }, - non_bounceable: { - required: ['b64', 'b64url'], - type: 'object', - properties: { b64: { type: 'string' }, b64url: { type: 'string' } } - }, - given_type: { type: 'string' }, - test_only: { type: 'boolean' } - } - }); - } - }; - nft = { - /** - * @description Get the transfer nft history - * - * @tags NFT - * @name GetAccountNftHistory - * @request GET:/v2/accounts/{account_id}/nfts/history - */ - getAccountNftHistory: ( - accountId_Address: Address, - query: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @example 100 - */ - limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/nfts/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, +/** + * @description Get raw blockchain config + * + * @tags Blockchain + * @name GetRawBlockchainConfig + * @request GET:/v2/blockchain/config/raw + */ +export const getRawBlockchainConfig = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/config/raw`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get NFT collections - * - * @tags NFT - * @name GetNftCollections - * @request GET:/v2/nfts/collections - */ - getNftCollections: ( - query?: { - /** - * @format int32 - * @min 1 - * @max 1000 - * @default 100 - * @example 15 - */ - limit?: number; - /** - * @format int32 - * @min 0 - * @default 0 - * @example 10 - */ - offset?: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/nfts/collections`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftCollections' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/RawBlockchainConfig' + }); +}; - /** - * @description Get NFT collection by collection address - * - * @tags NFT - * @name GetNftCollection - * @request GET:/v2/nfts/collections/{account_id} - */ - getNftCollection: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/nfts/collections/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftCollection' - }); - }, +/** + * @description Blockchain account inspect + * + * @tags Blockchain + * @name BlockchainAccountInspect + * @request GET:/v2/blockchain/accounts/{account_id}/inspect + */ +export const blockchainAccountInspect = ( + accountId_Address: Address, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/blockchain/accounts/${accountId}/inspect`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Get NFT collection items by their addresses - * - * @tags NFT - * @name GetNftCollectionItemsByAddresses - * @request POST:/v2/nfts/collections/_bulk - */ - getNftCollectionItemsByAddresses: ( - data: { - accountIds: Address[]; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/nfts/collections/_bulk`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftCollections' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainAccountInspect' + }); +}; - /** - * @description Get NFT items from collection by collection address - * - * @tags NFT - * @name GetItemsFromCollection - * @request GET:/v2/nfts/collections/{account_id}/items - */ - getItemsFromCollection: ( - accountId_Address: Address, - query?: { - /** - * @min 1 - * @max 1000 - * @default 1000 - */ - limit?: number; - /** - * @min 0 - * @default 0 - */ - offset?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/nfts/collections/${accountId}/items`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftItems' - }); - }, +/** + * @description Get human-friendly information about several accounts without low-level details. + * + * @tags Accounts + * @name GetAccounts + * @request POST:/v2/accounts/_bulk + */ +export const getAccounts = ( + data: { + accountIds: Address[]; + }, + query?: { + /** @example "usd" */ + currency?: string; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/accounts/_bulk`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); - /** - * @description Get NFT items by their addresses - * - * @tags NFT - * @name GetNftItemsByAddresses - * @request POST:/v2/nfts/_bulk - */ - getNftItemsByAddresses: ( - data: { - accountIds: Address[]; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/nfts/_bulk`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftItems' - }); - }, + return prepareResponse(req, { $ref: '#/components/schemas/Accounts' }); +}; - /** - * @description Get NFT item by its address - * - * @tags NFT - * @name GetNftItemByAddress - * @request GET:/v2/nfts/{account_id} - */ - getNftItemByAddress: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/nfts/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftItem' - }); - }, +/** + * @description Get human-friendly information about an account without low-level details. + * + * @tags Accounts + * @name GetAccount + * @request GET:/v2/accounts/{account_id} + */ +export const getAccount = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Account' }); +}; + +/** + * @description Get account's domains + * + * @tags Accounts + * @name AccountDnsBackResolve + * @request GET:/v2/accounts/{account_id}/dns/backresolve + */ +export const accountDnsBackResolve = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/dns/backresolve`, + method: 'GET', + format: 'json', + ...params + }); + return prepareResponse(req, { + $ref: '#/components/schemas/DomainNames' + }); +}; + +/** + * @description Get all Jettons balances by owner address + * + * @tags Accounts + * @name GetAccountJettonsBalances + * @request GET:/v2/accounts/{account_id}/jettons + */ +export const getAccountJettonsBalances = ( + accountId_Address: Address, + query?: { /** - * @description Get the transfer nfts history for account - * - * @tags NFT - * @name GetNftHistoryById - * @request GET:/v2/nfts/{account_id}/history + * accept ton and all possible fiat currencies, separated by commas + * @example ["ton","usd","rub"] */ - getNftHistoryById: ( - accountId_Address: Address, - query: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @example 100 - */ - limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/nfts/${accountId}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - } - }; - dns = { + currencies?: string[]; /** - * @description Get full information about domain name - * - * @tags DNS - * @name GetDnsInfo - * @request GET:/v2/dns/{domain_name} + * comma separated list supported extensions + * @example ["custom_payload"] */ - getDnsInfo: (domainName: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/dns/${domainName}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DomainInfo' - }); - }, + supported_extensions?: string[]; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/jettons`, + method: 'GET', + query: query, + queryImplode: ['currencies', 'supported_extensions'], + format: 'json', + ...params + }); - /** - * @description DNS resolve for domain name - * - * @tags DNS - * @name DnsResolve - * @request GET:/v2/dns/{domain_name}/resolve - */ - dnsResolve: (domainName: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/dns/${domainName}/resolve`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/DnsRecord' }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/JettonsBalances' + }); +}; - /** - * @description Get domain bids - * - * @tags DNS - * @name GetDomainBids - * @request GET:/v2/dns/{domain_name}/bids - */ - getDomainBids: (domainName: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/dns/${domainName}/bids`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DomainBids' - }); - }, +/** + * @description Get Jetton balance by owner address + * + * @tags Accounts + * @name GetAccountJettonBalance + * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} + */ +export const getAccountJettonBalance = ( + accountId_Address: Address, + jettonId_Address: Address, + query?: { + /** + * accept ton and all possible fiat currencies, separated by commas + * @example ["ton","usd","rub"] + */ + currencies?: string[]; + /** + * comma separated list supported extensions + * @example ["custom_payload"] + */ + supported_extensions?: string[]; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/jettons/${jettonId}`, + method: 'GET', + query: query, + queryImplode: ['currencies', 'supported_extensions'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonBalance' + }); +}; +/** + * @description Get the transfer jettons history for account + * + * @tags Accounts + * @name GetAccountJettonsHistory + * @request GET:/v2/accounts/{account_id}/jettons/history + */ +export const getAccountJettonsHistory = ( + accountId_Address: Address, + query: { /** - * @description Get all auctions - * - * @tags DNS - * @name GetAllAuctions - * @request GET:/v2/dns/auctions + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getAllAuctions: ( - query?: { - /** - * domain filter for current auctions "ton" or "t.me" - * @example "ton" - */ - tld?: string; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/dns/auctions`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Auctions' - }); - } - }; - traces = { + before_lt?: bigint; /** - * @description Get the trace by trace ID or hash of any transaction in trace - * - * @tags Traces - * @name GetTrace - * @request GET:/v2/traces/{trace_id} + * @min 1 + * @max 1000 + * @example 100 */ - getTrace: (traceId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/traces/${traceId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); - } - }; - events = { + limit: number; /** - * @description Get an event either by event ID or a hash of any transaction in a trace. An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. - * - * @tags Events - * @name GetEvent - * @request GET:/v2/events/{event_id} + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - getEvent: (eventId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/events/${eventId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Event' }); - } - }; - inscriptions = { + start_date?: number; /** - * @description Get all inscriptions by owner address. It's experimental API and can be dropped in the future. - * - * @tags Inscriptions - * @name GetAccountInscriptions - * @request GET:/v2/experimental/accounts/{account_id}/inscriptions - */ - getAccountInscriptions: ( - accountId_Address: Address, - query?: { - /** - * @min 1 - * @max 1000 - * @default 1000 - */ - limit?: number; - /** - * @min 0 - * @default 0 - */ - offset?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/experimental/accounts/${accountId}/inscriptions`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/InscriptionBalances' - }); - }, + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/jettons/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - /** - * @description Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. - * - * @tags Inscriptions - * @name GetAccountInscriptionsHistory - * @request GET:/v2/experimental/accounts/{account_id}/inscriptions/history - */ - getAccountInscriptionsHistory: ( - accountId_Address: Address, - query?: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @default 100 - * @example 100 - */ - limit?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/experimental/accounts/${accountId}/inscriptions/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; +/** + * @description Get the transfer jetton history for account and jetton + * + * @tags Accounts + * @name GetAccountJettonHistoryById + * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history + */ +export const getAccountJettonHistoryById = ( + accountId_Address: Address, + jettonId_Address: Address, + query: { /** - * @description Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. - * - * @tags Inscriptions - * @name GetAccountInscriptionsHistoryByTicker - * @request GET:/v2/experimental/accounts/{account_id}/inscriptions/{ticker}/history + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getAccountInscriptionsHistoryByTicker: ( - accountId_Address: Address, - ticker: string, - query?: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @default 100 - * @example 100 - */ - limit?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/experimental/accounts/${accountId}/inscriptions/${ticker}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); - }, - + before_lt?: bigint; /** - * @description return comment for making operation with inscription. please don't use it if you don't know what you are doing - * - * @tags Inscriptions - * @name GetInscriptionOpTemplate - * @request GET:/v2/experimental/inscriptions/op-template + * @min 1 + * @max 1000 + * @example 100 */ - getInscriptionOpTemplate: ( - query: { - /** @example "ton20" */ - type: 'ton20' | 'gram20'; - destination?: string; - comment?: string; - /** @example "transfer" */ - operation: 'transfer'; - /** - * @format bigint - * @example "1000000000" - */ - amount: bigint; - /** @example "nano" */ - ticker: string; - /** @example "UQAs87W4yJHlF8mt29ocA4agnMrLsOP69jC1HPyBUjJay7Mg" */ - who: string; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/experimental/inscriptions/op-template`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['comment', 'destination'], - properties: { comment: { type: 'string' }, destination: { type: 'string' } } - }); - } - }; - jettons = { + limit: number; /** - * @description Get a list of all indexed jetton masters in the blockchain. - * - * @tags Jettons - * @name GetJettons - * @request GET:/v2/jettons + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - getJettons: ( - query?: { - /** - * @format int32 - * @min 1 - * @max 1000 - * @default 100 - * @example 15 - */ - limit?: number; - /** - * @format int32 - * @min 0 - * @default 0 - * @example 10 - */ - offset?: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/jettons`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Jettons' }); - }, + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/jettons/${jettonId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; +/** + * @description Get all NFT items by owner address + * + * @tags Accounts + * @name GetAccountNftItems + * @request GET:/v2/accounts/{account_id}/nfts + */ +export const getAccountNftItems = ( + accountId_Address: Address, + query?: { /** - * @description Get jetton metadata by jetton master address - * - * @tags Jettons - * @name GetJettonInfo - * @request GET:/v2/jettons/{account_id} + * nft collection + * @format address + * @example "0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465" */ - getJettonInfo: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/jettons/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonInfo' - }); - }, - + collection?: Address; /** - * @description Get jetton metadata items by jetton master addresses - * - * @tags Jettons - * @name GetJettonInfosByAddresses - * @request POST:/v2/jettons/_bulk + * @min 1 + * @max 1000 + * @default 1000 */ - getJettonInfosByAddresses: ( - data: { - accountIds: Address[]; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/jettons/_bulk`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Jettons' - }); - }, - + limit?: number; /** - * @description Get jetton's holders - * - * @tags Jettons - * @name GetJettonHolders - * @request GET:/v2/jettons/{account_id}/holders + * @min 0 + * @default 0 */ - getJettonHolders: ( - accountId_Address: Address, - query?: { - /** - * @min 1 - * @max 1000 - * @default 1000 - */ - limit?: number; - /** - * @min 0 - * @default 0 - */ - offset?: number; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/jettons/${accountId}/holders`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonHolders' - }); - }, - + offset?: number; /** - * @description Get jetton's custom payload and state init required for transfer - * - * @tags Jettons - * @name GetJettonTransferPayload - * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload + * Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. + * @default false */ - getJettonTransferPayload: ( - accountId_Address: Address, - jettonId_Address: Address, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/jettons/${jettonId}/transfer/${accountId}/payload`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonTransferPayload' - }); + indirect_ownership?: boolean; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/nfts`, + method: 'GET', + query: query && { + ...query, + collection: query.collection?.toRawString() }, + format: 'json', + ...params + }); + return prepareResponse(req, { $ref: '#/components/schemas/NftItems' }); +}; + +/** + * @description Get events for an account. Each event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + * + * @tags Accounts + * @name GetAccountEvents + * @request GET:/v2/accounts/{account_id}/events + */ +export const getAccountEvents = ( + accountId_Address: Address, + query: { /** - * @description Get only jetton transfers in the event - * - * @tags Jettons - * @name GetJettonsEvents - * @request GET:/v2/events/{event_id}/jettons + * Show only events that are initiated by this account + * @default false */ - getJettonsEvents: (eventId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/events/${eventId}/jettons`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Event' - }); - } - }; - extraCurrency = { + initiator?: boolean; /** - * @description Get extra currency info by id - * - * @tags ExtraCurrency - * @name GetExtraCurrencyInfo - * @request GET:/v2/extra-currency/{id} + * filter actions where requested account is not real subject (for example sender or receiver jettons) + * @default false */ - getExtraCurrencyInfo: (id: number, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/extra-currency/${id}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/EcPreview' - }); - } - }; - staking = { + subject_only?: boolean; /** - * @description All pools where account participates - * - * @tags Staking - * @name GetAccountNominatorsPools - * @request GET:/v2/staking/nominator/{account_id}/pools + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getAccountNominatorsPools: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/staking/nominator/${accountId}/pools`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountStaking' - }); - }, - + before_lt?: bigint; /** - * @description Stacking pool info - * - * @tags Staking - * @name GetStakingPoolInfo - * @request GET:/v2/staking/pool/{account_id} + * @min 1 + * @max 100 + * @example 20 */ - getStakingPoolInfo: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/staking/pool/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['implementation', 'pool'], - properties: { - implementation: { $ref: '#/components/schemas/PoolImplementation' }, - pool: { $ref: '#/components/schemas/PoolInfo' } - } - }); - }, - + limit: number; /** - * @description Pool history - * - * @tags Staking - * @name GetStakingPoolHistory - * @request GET:/v2/staking/pool/{account_id}/history + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - getStakingPoolHistory: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/staking/pool/${accountId}/history`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['apy'], - properties: { - apy: { type: 'array', items: { $ref: '#/components/schemas/ApyHistory' } } - } - }); - }, + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/events`, + method: 'GET', + query: query, + queryImplode: ['initiator'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; + +/** + * @description Get event for an account by event_id + * + * @tags Accounts + * @name GetAccountEvent + * @request GET:/v2/accounts/{account_id}/events/{event_id} + */ +export const getAccountEvent = ( + accountId_Address: Address, + eventId: string, + query?: { + /** + * filter actions where requested account is not real subject (for example sender or receiver jettons) + * @default false + */ + subject_only?: boolean; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/events/${eventId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvent' }); +}; + +/** + * @description Get traces for account + * + * @tags Accounts + * @name GetAccountTraces + * @request GET:/v2/accounts/{account_id}/traces + */ +export const getAccountTraces = ( + accountId_Address: Address, + query?: { /** - * @description All pools available in network - * - * @tags Staking - * @name GetStakingPools - * @request GET:/v2/staking/pools + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getStakingPools: ( - query?: { - /** - * account ID - * @format address - * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" - */ - available_for?: Address; - /** - * return also pools not from white list - just compatible by interfaces (maybe dangerous!) - * @example false - */ - include_unverified?: boolean; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/staking/pools`, - method: 'GET', - query: query && { - ...query, - available_for: query.available_for?.toRawString() - }, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['pools', 'implementations'], - properties: { - pools: { type: 'array', items: { $ref: '#/components/schemas/PoolInfo' } }, - implementations: { - type: 'object', - additionalProperties: { $ref: '#/components/schemas/PoolImplementation' } - } - } - }); - } - }; - storage = { + before_lt?: bigint; /** - * @description Get TON storage providers deployed to the blockchain. - * - * @tags Storage - * @name GetStorageProviders - * @request GET:/v2/storage/providers + * @min 1 + * @max 1000 + * @default 100 + * @example 100 */ - getStorageProviders: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/storage/providers`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['providers'], - properties: { - providers: { - type: 'array', - items: { $ref: '#/components/schemas/StorageProvider' } - } - } - }); - } - }; - rates = { + limit?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/traces`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/TraceIDs' }); +}; + +/** + * @description Get all subscriptions by wallet address + * + * @tags Accounts + * @name GetAccountSubscriptions + * @request GET:/v2/accounts/{account_id}/subscriptions + */ +export const getAccountSubscriptions = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/subscriptions`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Subscriptions' + }); +}; + +/** + * @description Update internal cache for a particular account + * + * @tags Accounts + * @name ReindexAccount + * @request POST:/v2/accounts/{account_id}/reindex + */ +export const reindexAccount = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/reindex`, + method: 'POST', + ...params + }); + + return prepareResponse(req); +}; + +/** + * @description Search by account domain name + * + * @tags Accounts + * @name SearchAccounts + * @request GET:/v2/accounts/search + */ +export const searchAccounts = ( + query: { /** - * @description Get the token price in the chosen currency for display only. Don’t use this for financial transactions. - * - * @tags Rates - * @name GetRates - * @request GET:/v2/rates + * @minLength 3 + * @maxLength 15 */ - getRates: ( - query: { - /** - * accept ton and jetton master addresses, separated by commas - * @maxItems 100 - * @example ["ton"] - */ - tokens: string[]; - /** - * accept ton and all possible fiat currencies, separated by commas - * @maxItems 50 - * @example ["ton","usd","rub"] - */ - currencies: string[]; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/rates`, - method: 'GET', - query: query, - queryImplode: ['tokens', 'currencies'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['rates'], - properties: { - rates: { - type: 'object', - additionalProperties: { $ref: '#/components/schemas/TokenRates' } - } - } - }); - }, + name: string; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/accounts/search`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/FoundAccounts' }); +}; + +/** + * @description Get expiring account .ton dns + * + * @tags Accounts + * @name GetAccountDnsExpiring + * @request GET:/v2/accounts/{account_id}/dns/expiring + */ +export const getAccountDnsExpiring = ( + accountId_Address: Address, + query?: { + /** + * number of days before expiration + * @min 1 + * @max 3660 + */ + period?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/dns/expiring`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/DnsExpiring' + }); +}; + +/** + * @description Get public key by account id + * + * @tags Accounts + * @name GetAccountPublicKey + * @request GET:/v2/accounts/{account_id}/publickey + */ +export const getAccountPublicKey = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/publickey`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['public_key'], + properties: { public_key: { type: 'string' } } + }); +}; + +/** + * @description Get account's multisigs + * + * @tags Accounts + * @name GetAccountMultisigs + * @request GET:/v2/accounts/{account_id}/multisigs + */ +export const getAccountMultisigs = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/multisigs`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Multisigs' + }); +}; +/** + * @description Get account's balance change + * + * @tags Accounts + * @name GetAccountDiff + * @request GET:/v2/accounts/{account_id}/diff + */ +export const getAccountDiff = ( + accountId_Address: Address, + query: { /** - * @description Get chart by token - * - * @tags Rates - * @name GetChartRates - * @request GET:/v2/rates/chart + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - getChartRates: ( - query: { - /** - * accept jetton master address - * @format address - */ - token: Address; - /** @example "usd" */ - currency?: string; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; - /** - * @format int - * @min 0 - * @max 200 - * @default 200 - */ - points_count?: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/rates/chart`, - method: 'GET', - query: query && { - ...query, - token: query.token?.toRawString() - }, - format: 'json', - ...params - }); + start_date: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/diff`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - return prepareResponse(req, { - type: 'object', - required: ['points'], - properties: { - points: { type: 'array', items: { $ref: '#/components/schemas/ChartPoints' } } - } - }); - }, + return prepareResponse(req, { + type: 'object', + required: ['balance_change'], + properties: { balance_change: { type: 'integer', format: 'int64' } } + }); +}; +/** + * @description Get the transfer history of extra currencies for an account. + * + * @tags Accounts + * @name GetAccountExtraCurrencyHistoryById + * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history + */ +export const getAccountExtraCurrencyHistoryById = ( + accountId_Address: Address, + id: number, + query: { /** - * @description Get the TON price from markets - * - * @tags Rates - * @name GetMarketsRates - * @request GET:/v2/rates/markets + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getMarketsRates: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/rates/markets`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['markets'], - properties: { - markets: { - type: 'array', - items: { $ref: '#/components/schemas/MarketTonRates' } - } - } - }); - } - }; - connect = { + before_lt?: bigint; /** - * @description Get a payload for further token receipt - * - * @tags Connect - * @name GetTonConnectPayload - * @request GET:/v2/tonconnect/payload + * @min 1 + * @max 1000 + * @example 100 */ - getTonConnectPayload: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/tonconnect/payload`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['payload'], - properties: { payload: { type: 'string' } } - }); - }, - + limit: number; /** - * @description Get account info by state init - * - * @tags Connect - * @name GetAccountInfoByStateInit - * @request POST:/v2/tonconnect/stateinit + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - getAccountInfoByStateInit: ( - data: { - /** @format cell-base64 */ - stateInit: Cell; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/tonconnect/stateinit`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['stateInit'], - properties: { stateInit: { type: 'string', format: 'cell-base64' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountInfoByStateInit' - }); - } - }; - wallet = { + start_date?: number; /** - * @description Account verification and token issuance - * - * @tags Wallet - * @name TonConnectProof - * @request POST:/v2/wallet/auth/proof - */ - tonConnectProof: ( - data: { - /** - * @format address - * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" - */ - address: Address; - proof: { - /** - * @format int64 - * @example "1678275313" - */ - timestamp: number; - domain: { - /** @format int32 */ - lengthBytes?: number; - value: string; - }; - signature: string; - /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ - payload: string; - /** @format cell-base64 */ - stateInit?: Cell; - }; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/wallet/auth/proof`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['address', 'proof'], - properties: { - address: { type: 'string', format: 'address' }, - proof: { - type: 'object', - required: ['timestamp', 'domain', 'signature', 'payload'], - properties: { - timestamp: { type: 'integer', format: 'int64' }, - domain: { - type: 'object', - required: ['value'], - properties: { - lengthBytes: { type: 'integer', format: 'int32' }, - value: { type: 'string' } - } - }, - signature: { type: 'string' }, - payload: { type: 'string' }, - stateInit: { type: 'string', format: 'cell-base64' } - } - } - } - }), - format: 'json', - ...params - }); + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/extra-currency/${id}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - return prepareResponse(req, { - type: 'object', - required: ['token'], - properties: { token: { type: 'string' } } - }); - }, + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; +/** + * @description Get the transfer nft history + * + * @tags NFT + * @name GetAccountNftHistory + * @request GET:/v2/accounts/{account_id}/nfts/history + */ +export const getAccountNftHistory = ( + accountId_Address: Address, + query: { /** - * @description Get account seqno - * - * @tags Wallet - * @name GetAccountSeqno - * @request GET:/v2/wallet/{account_id}/seqno + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getAccountSeqno: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/wallet/${accountId}/seqno`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Seqno' - }); - }, - + before_lt?: bigint; /** - * @description Get wallets by public key - * - * @tags Wallet - * @name GetWalletsByPublicKey - * @request GET:/v2/pubkeys/{public_key}/wallets + * @min 1 + * @max 1000 + * @example 100 */ - getWalletsByPublicKey: (publicKey: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/pubkeys/${publicKey}/wallets`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Accounts' - }); - } - }; - gasless = { + limit: number; /** - * @description Returns configuration of gasless transfers - * - * @tags Gasless - * @name GaslessConfig - * @request GET:/v2/gasless/config + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - gaslessConfig: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/gasless/config`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/GaslessConfig' - }); - }, + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/nfts/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; +/** + * @description Get NFT collections + * + * @tags NFT + * @name GetNftCollections + * @request GET:/v2/nfts/collections + */ +export const getNftCollections = ( + query?: { /** - * @description Estimates the cost of the given messages and returns a payload to sign - * - * @tags Gasless - * @name GaslessEstimate - * @request POST:/v2/gasless/estimate/{master_id} + * @format int32 + * @min 1 + * @max 1000 + * @default 100 + * @example 15 */ - gaslessEstimate: ( - masterId_Address: Address, - data: { - /** @format address */ - walletAddress: Address; - walletPublicKey: string; - messages: { - /** @format cell */ - boc: Cell; - }[]; - }, - params: RequestParams = {} - ) => { - const masterId = masterId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/gasless/estimate/${masterId}`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['messages', 'walletAddress', 'walletPublicKey'], - properties: { - walletAddress: { type: 'string', format: 'address' }, - walletPublicKey: { type: 'string' }, - messages: { - type: 'array', - items: { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - } - } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/SignRawParams' - }); - }, - + limit?: number; /** - * @description Submits the signed gasless transaction message to the network - * - * @tags Gasless - * @name GaslessSend - * @request POST:/v2/gasless/send + * @format int32 + * @min 0 + * @default 0 + * @example 10 */ - gaslessSend: ( - data: { - /** hex encoded public key */ - walletPublicKey: string; - /** @format cell */ - boc: Cell; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/gasless/send`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['boc', 'walletPublicKey'], - properties: { - walletPublicKey: { type: 'string' }, - boc: { type: 'string', format: 'cell' } - } - }), - ...params - }); + offset?: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/nfts/collections`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - return prepareResponse(req); - } - }; - liteServer = { + return prepareResponse(req, { + $ref: '#/components/schemas/NftCollections' + }); +}; + +/** + * @description Get NFT collection by collection address + * + * @tags NFT + * @name GetNftCollection + * @request GET:/v2/nfts/collections/{account_id} + */ +export const getNftCollection = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/nfts/collections/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftCollection' + }); +}; + +/** + * @description Get NFT collection items by their addresses + * + * @tags NFT + * @name GetNftCollectionItemsByAddresses + * @request POST:/v2/nfts/collections/_bulk + */ +export const getNftCollectionItemsByAddresses = ( + data: { + accountIds: Address[]; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/nfts/collections/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftCollections' + }); +}; + +/** + * @description Get NFT items from collection by collection address + * + * @tags NFT + * @name GetItemsFromCollection + * @request GET:/v2/nfts/collections/{account_id}/items + */ +export const getItemsFromCollection = ( + accountId_Address: Address, + query?: { /** - * @description Get raw masterchain info - * - * @tags Lite Server - * @name GetRawMasterchainInfo - * @request GET:/v2/liteserver/get_masterchain_info + * @min 1 + * @max 1000 + * @default 1000 */ - getRawMasterchainInfo: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_masterchain_info`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['last', 'state_root_hash', 'init'], - properties: { - last: { $ref: '#/components/schemas/BlockRaw' }, - state_root_hash: { type: 'string' }, - init: { $ref: '#/components/schemas/InitStateRaw' } - } - }); - }, - + limit?: number; /** - * @description Get raw masterchain info ext - * - * @tags Lite Server - * @name GetRawMasterchainInfoExt - * @request GET:/v2/liteserver/get_masterchain_info_ext + * @min 0 + * @default 0 */ - getRawMasterchainInfoExt: ( - query: { - /** - * mode - * @format int32 - * @example 0 - */ - mode: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/get_masterchain_info_ext`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: [ - 'mode', - 'version', - 'capabilities', - 'last', - 'last_utime', - 'now', - 'state_root_hash', - 'init' - ], - properties: { - mode: { type: 'integer', format: 'int32' }, - version: { type: 'integer', format: 'int32' }, - capabilities: { type: 'integer', format: 'int64' }, - last: { $ref: '#/components/schemas/BlockRaw' }, - last_utime: { type: 'integer', format: 'int32' }, - now: { type: 'integer', format: 'int32' }, - state_root_hash: { type: 'string' }, - init: { $ref: '#/components/schemas/InitStateRaw' } - } - }); - }, + offset?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/nfts/collections/${accountId}/items`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftItems' + }); +}; + +/** + * @description Get NFT items by their addresses + * + * @tags NFT + * @name GetNftItemsByAddresses + * @request POST:/v2/nfts/_bulk + */ +export const getNftItemsByAddresses = ( + data: { + accountIds: Address[]; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/nfts/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftItems' + }); +}; + +/** + * @description Get NFT item by its address + * + * @tags NFT + * @name GetNftItemByAddress + * @request GET:/v2/nfts/{account_id} + */ +export const getNftItemByAddress = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/nfts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/NftItem' }); +}; +/** + * @description Get the transfer nfts history for account + * + * @tags NFT + * @name GetNftHistoryById + * @request GET:/v2/nfts/{account_id}/history + */ +export const getNftHistoryById = ( + accountId_Address: Address, + query: { /** - * @description Get raw time - * - * @tags Lite Server - * @name GetRawTime - * @request GET:/v2/liteserver/get_time + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 */ - getRawTime: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_time`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['time'], - properties: { time: { type: 'integer', format: 'int32' } } - }); - }, - + before_lt?: bigint; /** - * @description Get raw blockchain block - * - * @tags Lite Server - * @name GetRawBlockchainBlock - * @request GET:/v2/liteserver/get_block/{block_id} + * @min 1 + * @max 1000 + * @example 100 */ - getRawBlockchainBlock: (blockId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_block/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'data'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - data: { type: 'string' } - } - }); - }, - + limit: number; /** - * @description Get raw blockchain block state - * - * @tags Lite Server - * @name GetRawBlockchainBlockState - * @request GET:/v2/liteserver/get_state/{block_id} + * @format int64 + * @max 2114380800 + * @example 1668436763 */ - getRawBlockchainBlockState: (blockId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_state/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'root_hash', 'file_hash', 'data'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - root_hash: { type: 'string' }, - file_hash: { type: 'string' }, - data: { type: 'string' } - } - }); - }, + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/nfts/${accountId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; + +/** + * @description Get full information about domain name + * + * @tags DNS + * @name GetDnsInfo + * @request GET:/v2/dns/{domain_name} + */ +export const getDnsInfo = (domainName: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/dns/${domainName}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DomainInfo' }); +}; + +/** + * @description DNS resolve for domain name + * + * @tags DNS + * @name DnsResolve + * @request GET:/v2/dns/{domain_name}/resolve + */ +export const dnsResolve = (domainName: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/dns/${domainName}/resolve`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DnsRecord' }); +}; + +/** + * @description Get domain bids + * + * @tags DNS + * @name GetDomainBids + * @request GET:/v2/dns/{domain_name}/bids + */ +export const getDomainBids = (domainName: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/dns/${domainName}/bids`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DomainBids' }); +}; + +/** + * @description Get all auctions + * + * @tags DNS + * @name GetAllAuctions + * @request GET:/v2/dns/auctions + */ +export const getAllAuctions = ( + query?: { /** - * @description Get raw blockchain block header - * - * @tags Lite Server - * @name GetRawBlockchainBlockHeader - * @request GET:/v2/liteserver/get_block_header/{block_id} + * domain filter for current auctions "ton" or "t.me" + * @example "ton" */ - getRawBlockchainBlockHeader: ( - blockId: string, - query: { - /** - * mode - * @format int32 - * @example 0 - */ - mode: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/get_block_header/${blockId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'mode', 'header_proof'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - mode: { type: 'integer', format: 'int32' }, - header_proof: { type: 'string' } - } - }); - }, - + tld?: string; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/dns/auctions`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Auctions' }); +}; + +/** + * @description Get the trace by trace ID or hash of any transaction in trace + * + * @tags Traces + * @name GetTrace + * @request GET:/v2/traces/{trace_id} + */ +export const getTrace = (traceId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/traces/${traceId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); +}; + +/** + * @description Get an event either by event ID or a hash of any transaction in a trace. An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + * + * @tags Events + * @name GetEvent + * @request GET:/v2/events/{event_id} + */ +export const getEvent = (eventId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/events/${eventId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Event' }); +}; + +/** + * @description Get all inscriptions by owner address. It's experimental API and can be dropped in the future. + * + * @tags Inscriptions + * @name GetAccountInscriptions + * @request GET:/v2/experimental/accounts/{account_id}/inscriptions + */ +export const getAccountInscriptions = ( + accountId_Address: Address, + query?: { + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @default 0 + */ + offset?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/experimental/accounts/${accountId}/inscriptions`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/InscriptionBalances' + }); +}; + +/** + * @description Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. + * + * @tags Inscriptions + * @name GetAccountInscriptionsHistory + * @request GET:/v2/experimental/accounts/{account_id}/inscriptions/history + */ +export const getAccountInscriptionsHistory = ( + accountId_Address: Address, + query?: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/experimental/accounts/${accountId}/inscriptions/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; + +/** + * @description Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. + * + * @tags Inscriptions + * @name GetAccountInscriptionsHistoryByTicker + * @request GET:/v2/experimental/accounts/{account_id}/inscriptions/{ticker}/history + */ +export const getAccountInscriptionsHistoryByTicker = ( + accountId_Address: Address, + ticker: string, + query?: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/experimental/accounts/${accountId}/inscriptions/${ticker}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); +}; + +/** + * @description return comment for making operation with inscription. please don't use it if you don't know what you are doing + * + * @tags Inscriptions + * @name GetInscriptionOpTemplate + * @request GET:/v2/experimental/inscriptions/op-template + */ +export const getInscriptionOpTemplate = ( + query: { + /** @example "ton20" */ + type: 'ton20' | 'gram20'; + destination?: string; + comment?: string; + /** @example "transfer" */ + operation: 'transfer'; + /** + * @format bigint + * @example "1000000000" + */ + amount: bigint; + /** @example "nano" */ + ticker: string; + /** @example "UQAs87W4yJHlF8mt29ocA4agnMrLsOP69jC1HPyBUjJay7Mg" */ + who: string; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/experimental/inscriptions/op-template`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['comment', 'destination'], + properties: { comment: { type: 'string' }, destination: { type: 'string' } } + }); +}; + +/** + * @description Get a list of all indexed jetton masters in the blockchain. + * + * @tags Jettons + * @name GetJettons + * @request GET:/v2/jettons + */ +export const getJettons = ( + query?: { + /** + * @format int32 + * @min 1 + * @max 1000 + * @default 100 + * @example 15 + */ + limit?: number; + /** + * @format int32 + * @min 0 + * @default 0 + * @example 10 + */ + offset?: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/jettons`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Jettons' }); +}; + +/** + * @description Get jetton metadata by jetton master address + * + * @tags Jettons + * @name GetJettonInfo + * @request GET:/v2/jettons/{account_id} + */ +export const getJettonInfo = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/jettons/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/JettonInfo' }); +}; + +/** + * @description Get jetton metadata items by jetton master addresses + * + * @tags Jettons + * @name GetJettonInfosByAddresses + * @request POST:/v2/jettons/_bulk + */ +export const getJettonInfosByAddresses = ( + data: { + accountIds: Address[]; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/jettons/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Jettons' + }); +}; + +/** + * @description Get jetton's holders + * + * @tags Jettons + * @name GetJettonHolders + * @request GET:/v2/jettons/{account_id}/holders + */ +export const getJettonHolders = ( + accountId_Address: Address, + query?: { + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @default 0 + */ + offset?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/jettons/${accountId}/holders`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonHolders' + }); +}; + +/** + * @description Get jetton's custom payload and state init required for transfer + * + * @tags Jettons + * @name GetJettonTransferPayload + * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload + */ +export const getJettonTransferPayload = ( + accountId_Address: Address, + jettonId_Address: Address, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/jettons/${jettonId}/transfer/${accountId}/payload`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonTransferPayload' + }); +}; + +/** + * @description Get only jetton transfers in the event + * + * @tags Jettons + * @name GetJettonsEvents + * @request GET:/v2/events/{event_id}/jettons + */ +export const getJettonsEvents = (eventId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/events/${eventId}/jettons`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Event' }); +}; + +/** + * @description Get extra currency info by id + * + * @tags ExtraCurrency + * @name GetExtraCurrencyInfo + * @request GET:/v2/extra-currency/{id} + */ +export const getExtraCurrencyInfo = (id: number, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/extra-currency/${id}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/EcPreview' + }); +}; + +/** + * @description All pools where account participates + * + * @tags Staking + * @name GetAccountNominatorsPools + * @request GET:/v2/staking/nominator/{account_id}/pools + */ +export const getAccountNominatorsPools = ( + accountId_Address: Address, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/staking/nominator/${accountId}/pools`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountStaking' + }); +}; + +/** + * @description Stacking pool info + * + * @tags Staking + * @name GetStakingPoolInfo + * @request GET:/v2/staking/pool/{account_id} + */ +export const getStakingPoolInfo = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/staking/pool/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['implementation', 'pool'], + properties: { + implementation: { $ref: '#/components/schemas/PoolImplementation' }, + pool: { $ref: '#/components/schemas/PoolInfo' } + } + }); +}; + +/** + * @description Pool history + * + * @tags Staking + * @name GetStakingPoolHistory + * @request GET:/v2/staking/pool/{account_id}/history + */ +export const getStakingPoolHistory = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/staking/pool/${accountId}/history`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['apy'], + properties: { apy: { type: 'array', items: { $ref: '#/components/schemas/ApyHistory' } } } + }); +}; + +/** + * @description All pools available in network + * + * @tags Staking + * @name GetStakingPools + * @request GET:/v2/staking/pools + */ +export const getStakingPools = ( + query?: { + /** + * account ID + * @format address + * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" + */ + available_for?: Address; + /** + * return also pools not from white list - just compatible by interfaces (maybe dangerous!) + * @example false + */ + include_unverified?: boolean; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/staking/pools`, + method: 'GET', + query: query && { + ...query, + available_for: query.available_for?.toRawString() + }, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['pools', 'implementations'], + properties: { + pools: { type: 'array', items: { $ref: '#/components/schemas/PoolInfo' } }, + implementations: { + type: 'object', + additionalProperties: { $ref: '#/components/schemas/PoolImplementation' } + } + } + }); +}; + +/** + * @description Get TON storage providers deployed to the blockchain. + * + * @tags Storage + * @name GetStorageProviders + * @request GET:/v2/storage/providers + */ +export const getStorageProviders = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/storage/providers`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['providers'], + properties: { + providers: { type: 'array', items: { $ref: '#/components/schemas/StorageProvider' } } + } + }); +}; + +/** + * @description Get the token price in the chosen currency for display only. Don’t use this for financial transactions. + * + * @tags Rates + * @name GetRates + * @request GET:/v2/rates + */ +export const getRates = ( + query: { + /** + * accept ton and jetton master addresses, separated by commas + * @maxItems 100 + * @example ["ton"] + */ + tokens: string[]; + /** + * accept ton and all possible fiat currencies, separated by commas + * @maxItems 50 + * @example ["ton","usd","rub"] + */ + currencies: string[]; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/rates`, + method: 'GET', + query: query, + queryImplode: ['tokens', 'currencies'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['rates'], + properties: { + rates: { + type: 'object', + additionalProperties: { $ref: '#/components/schemas/TokenRates' } + } + } + }); +}; + +/** + * @description Get chart by token + * + * @tags Rates + * @name GetChartRates + * @request GET:/v2/rates/chart + */ +export const getChartRates = ( + query: { + /** + * accept jetton master address + * @format address + */ + token: Address; + /** @example "usd" */ + currency?: string; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + /** + * @format int + * @min 0 + * @max 200 + * @default 200 + */ + points_count?: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/rates/chart`, + method: 'GET', + query: query && { + ...query, + token: query.token?.toRawString() + }, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['points'], + properties: { + points: { type: 'array', items: { $ref: '#/components/schemas/ChartPoints' } } + } + }); +}; + +/** + * @description Get the TON price from markets + * + * @tags Rates + * @name GetMarketsRates + * @request GET:/v2/rates/markets + */ +export const getMarketsRates = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/rates/markets`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['markets'], + properties: { + markets: { type: 'array', items: { $ref: '#/components/schemas/MarketTonRates' } } + } + }); +}; + +/** + * @description Get a payload for further token receipt + * + * @tags Connect + * @name GetTonConnectPayload + * @request GET:/v2/tonconnect/payload + */ +export const getTonConnectPayload = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/tonconnect/payload`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['payload'], + properties: { payload: { type: 'string' } } + }); +}; + +/** + * @description Get account info by state init + * + * @tags Connect + * @name GetAccountInfoByStateInit + * @request POST:/v2/tonconnect/stateinit + */ +export const getAccountInfoByStateInit = ( + data: { + /** @format cell-base64 */ + stateInit: Cell; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/tonconnect/stateinit`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['stateInit'], + properties: { stateInit: { type: 'string', format: 'cell-base64' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountInfoByStateInit' + }); +}; + +/** + * @description Account verification and token issuance + * + * @tags Wallet + * @name TonConnectProof + * @request POST:/v2/wallet/auth/proof + */ +export const tonConnectProof = ( + data: { + /** + * @format address + * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + */ + address: Address; + proof: { + /** + * @format int64 + * @example "1678275313" + */ + timestamp: number; + domain: { + /** @format int32 */ + lengthBytes?: number; + value: string; + }; + signature: string; + /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ + payload: string; + /** @format cell-base64 */ + stateInit?: Cell; + }; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/wallet/auth/proof`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['address', 'proof'], + properties: { + address: { type: 'string', format: 'address' }, + proof: { + type: 'object', + required: ['timestamp', 'domain', 'signature', 'payload'], + properties: { + timestamp: { type: 'integer', format: 'int64' }, + domain: { + type: 'object', + required: ['value'], + properties: { + lengthBytes: { type: 'integer', format: 'int32' }, + value: { type: 'string' } + } + }, + signature: { type: 'string' }, + payload: { type: 'string' }, + stateInit: { type: 'string', format: 'cell-base64' } + } + } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['token'], + properties: { token: { type: 'string' } } + }); +}; + +/** + * @description Get account seqno + * + * @tags Wallet + * @name GetAccountSeqno + * @request GET:/v2/wallet/{account_id}/seqno + */ +export const getAccountSeqno = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/wallet/${accountId}/seqno`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Seqno' }); +}; + +/** + * @description Get wallets by public key + * + * @tags Wallet + * @name GetWalletsByPublicKey + * @request GET:/v2/pubkeys/{public_key}/wallets + */ +export const getWalletsByPublicKey = (publicKey: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/pubkeys/${publicKey}/wallets`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Accounts' + }); +}; + +/** + * @description Returns configuration of gasless transfers + * + * @tags Gasless + * @name GaslessConfig + * @request GET:/v2/gasless/config + */ +export const gaslessConfig = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/gasless/config`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/GaslessConfig' }); +}; + +/** + * @description Estimates the cost of the given messages and returns a payload to sign + * + * @tags Gasless + * @name GaslessEstimate + * @request POST:/v2/gasless/estimate/{master_id} + */ +export const gaslessEstimate = ( + masterId_Address: Address, + data: { + /** @format address */ + walletAddress: Address; + walletPublicKey: string; + messages: { + /** @format cell */ + boc: Cell; + }[]; + }, + params: RequestParams = {} +) => { + const masterId = masterId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/gasless/estimate/${masterId}`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['messages', 'walletAddress', 'walletPublicKey'], + properties: { + walletAddress: { type: 'string', format: 'address' }, + walletPublicKey: { type: 'string' }, + messages: { + type: 'array', + items: { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + } + } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/SignRawParams' + }); +}; + +/** + * @description Submits the signed gasless transaction message to the network + * + * @tags Gasless + * @name GaslessSend + * @request POST:/v2/gasless/send + */ +export const gaslessSend = ( + data: { + /** hex encoded public key */ + walletPublicKey: string; + /** @format cell */ + boc: Cell; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/gasless/send`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['boc', 'walletPublicKey'], + properties: { + walletPublicKey: { type: 'string' }, + boc: { type: 'string', format: 'cell' } + } + }), + ...params + }); + + return prepareResponse(req); +}; + +/** + * @description Get raw masterchain info + * + * @tags Lite Server + * @name GetRawMasterchainInfo + * @request GET:/v2/liteserver/get_masterchain_info + */ +export const getRawMasterchainInfo = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_masterchain_info`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['last', 'state_root_hash', 'init'], + properties: { + last: { $ref: '#/components/schemas/BlockRaw' }, + state_root_hash: { type: 'string' }, + init: { $ref: '#/components/schemas/InitStateRaw' } + } + }); +}; + +/** + * @description Get raw masterchain info ext + * + * @tags Lite Server + * @name GetRawMasterchainInfoExt + * @request GET:/v2/liteserver/get_masterchain_info_ext + */ +export const getRawMasterchainInfoExt = ( + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_masterchain_info_ext`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: [ + 'mode', + 'version', + 'capabilities', + 'last', + 'last_utime', + 'now', + 'state_root_hash', + 'init' + ], + properties: { + mode: { type: 'integer', format: 'int32' }, + version: { type: 'integer', format: 'int32' }, + capabilities: { type: 'integer', format: 'int64' }, + last: { $ref: '#/components/schemas/BlockRaw' }, + last_utime: { type: 'integer', format: 'int32' }, + now: { type: 'integer', format: 'int32' }, + state_root_hash: { type: 'string' }, + init: { $ref: '#/components/schemas/InitStateRaw' } + } + }); +}; + +/** + * @description Get raw time + * + * @tags Lite Server + * @name GetRawTime + * @request GET:/v2/liteserver/get_time + */ +export const getRawTime = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_time`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['time'], + properties: { time: { type: 'integer', format: 'int32' } } + }); +}; + +/** + * @description Get raw blockchain block + * + * @tags Lite Server + * @name GetRawBlockchainBlock + * @request GET:/v2/liteserver/get_block/{block_id} + */ +export const getRawBlockchainBlock = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_block/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'data'], + properties: { id: { $ref: '#/components/schemas/BlockRaw' }, data: { type: 'string' } } + }); +}; + +/** + * @description Get raw blockchain block state + * + * @tags Lite Server + * @name GetRawBlockchainBlockState + * @request GET:/v2/liteserver/get_state/{block_id} + */ +export const getRawBlockchainBlockState = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_state/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'root_hash', 'file_hash', 'data'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + root_hash: { type: 'string' }, + file_hash: { type: 'string' }, + data: { type: 'string' } + } + }); +}; + +/** + * @description Get raw blockchain block header + * + * @tags Lite Server + * @name GetRawBlockchainBlockHeader + * @request GET:/v2/liteserver/get_block_header/{block_id} + */ +export const getRawBlockchainBlockHeader = ( + blockId: string, + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_block_header/${blockId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'mode', 'header_proof'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + mode: { type: 'integer', format: 'int32' }, + header_proof: { type: 'string' } + } + }); +}; + +/** + * @description Send raw message to blockchain + * + * @tags Lite Server + * @name SendRawMessage + * @request POST:/v2/liteserver/send_message + */ +export const sendRawMessage = ( + data: { + /** @format cell-base64 */ + body: Cell; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/send_message`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['body'], + properties: { body: { type: 'string', format: 'cell-base64' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['code'], + properties: { code: { type: 'integer', format: 'int32' } } + }); +}; + +/** + * @description Get raw account state + * + * @tags Lite Server + * @name GetRawAccountState + * @request GET:/v2/liteserver/get_account_state/{account_id} + */ +export const getRawAccountState = ( + accountId_Address: Address, + query?: { + /** + * target block: (workchain,shard,seqno,root_hash,file_hash) + * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" + */ + target_block?: string; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/liteserver/get_account_state/${accountId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'shardblk', 'shard_proof', 'proof', 'state'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + shardblk: { $ref: '#/components/schemas/BlockRaw' }, + shard_proof: { type: 'string' }, + proof: { type: 'string' }, + state: { type: 'string' } + } + }); +}; + +/** + * @description Get raw shard info + * + * @tags Lite Server + * @name GetRawShardInfo + * @request GET:/v2/liteserver/get_shard_info/{block_id} + */ +export const getRawShardInfo = ( + blockId: string, + query: { + /** + * workchain + * @format int32 + * @example 1 + */ + workchain: number; + /** + * shard + * @format int64 + * @example 1 + */ + shard: number; + /** + * exact + * @example false + */ + exact: boolean; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_shard_info/${blockId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'shardblk', 'shard_proof', 'shard_descr'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + shardblk: { $ref: '#/components/schemas/BlockRaw' }, + shard_proof: { type: 'string' }, + shard_descr: { type: 'string' } + } + }); +}; + +/** + * @description Get all raw shards info + * + * @tags Lite Server + * @name GetAllRawShardsInfo + * @request GET:/v2/liteserver/get_all_shards_info/{block_id} + */ +export const getAllRawShardsInfo = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_all_shards_info/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'proof', 'data'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + proof: { type: 'string' }, + data: { type: 'string' } + } + }); +}; + +/** + * @description Get raw transactions + * + * @tags Lite Server + * @name GetRawTransactions + * @request GET:/v2/liteserver/get_transactions/{account_id} + */ +export const getRawTransactions = ( + accountId_Address: Address, + query: { + /** + * count + * @format int32 + * @example 100 + */ + count: number; + /** + * lt + * @format int64 + * @example 23814011000000 + */ + lt: number; + /** + * hash + * @example "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" + */ + hash: string; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/liteserver/get_transactions/${accountId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['ids', 'transactions'], + properties: { + ids: { type: 'array', items: { $ref: '#/components/schemas/BlockRaw' } }, + transactions: { type: 'string' } + } + }); +}; + +/** + * @description Get raw list block transactions + * + * @tags Lite Server + * @name GetRawListBlockTransactions + * @request GET:/v2/liteserver/list_block_transactions/{block_id} + */ +export const getRawListBlockTransactions = ( + blockId: string, + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; /** - * @description Send raw message to blockchain - * - * @tags Lite Server - * @name SendRawMessage - * @request POST:/v2/liteserver/send_message + * count + * @format int32 + * @example 100 */ - sendRawMessage: ( - data: { - /** @format cell-base64 */ - body: Cell; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/send_message`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['body'], - properties: { body: { type: 'string', format: 'cell-base64' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['code'], - properties: { code: { type: 'integer', format: 'int32' } } - }); - }, - + count: number; /** - * @description Get raw account state - * - * @tags Lite Server - * @name GetRawAccountState - * @request GET:/v2/liteserver/get_account_state/{account_id} + * account ID + * @format address + * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" */ - getRawAccountState: ( - accountId_Address: Address, - query?: { - /** - * target block: (workchain,shard,seqno,root_hash,file_hash) - * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" - */ - target_block?: string; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/liteserver/get_account_state/${accountId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'shardblk', 'shard_proof', 'proof', 'state'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - shardblk: { $ref: '#/components/schemas/BlockRaw' }, - shard_proof: { type: 'string' }, - proof: { type: 'string' }, - state: { type: 'string' } - } - }); + account_id?: Address; + /** + * lt + * @format int64 + * @example 23814011000000 + */ + lt?: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/list_block_transactions/${blockId}`, + method: 'GET', + query: query && { + ...query, + account_id: query.account_id?.toRawString() }, + queryImplode: ['account_id'], + format: 'json', + ...params + }); - /** - * @description Get raw shard info - * - * @tags Lite Server - * @name GetRawShardInfo - * @request GET:/v2/liteserver/get_shard_info/{block_id} - */ - getRawShardInfo: ( - blockId: string, - query: { - /** - * workchain - * @format int32 - * @example 1 - */ - workchain: number; - /** - * shard - * @format int64 - * @example 1 - */ - shard: number; - /** - * exact - * @example false - */ - exact: boolean; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/get_shard_info/${blockId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'shardblk', 'shard_proof', 'shard_descr'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - shardblk: { $ref: '#/components/schemas/BlockRaw' }, - shard_proof: { type: 'string' }, - shard_descr: { type: 'string' } + return prepareResponse(req, { + type: 'object', + required: ['id', 'req_count', 'incomplete', 'ids', 'proof'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + req_count: { type: 'integer', format: 'int32' }, + incomplete: { type: 'boolean' }, + ids: { + type: 'array', + items: { + type: 'object', + required: ['mode'], + properties: { + mode: { type: 'integer', format: 'int32' }, + account: { type: 'string' }, + lt: { type: 'integer', format: 'bigint', 'x-js-format': 'bigint' }, + hash: { type: 'string' } + } } - }); - }, + }, + proof: { type: 'string' } + } + }); +}; +/** + * @description Get raw block proof + * + * @tags Lite Server + * @name GetRawBlockProof + * @request GET:/v2/liteserver/get_block_proof + */ +export const getRawBlockProof = ( + query: { /** - * @description Get all raw shards info - * - * @tags Lite Server - * @name GetAllRawShardsInfo - * @request GET:/v2/liteserver/get_all_shards_info/{block_id} + * known block: (workchain,shard,seqno,root_hash,file_hash) + * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" */ - getAllRawShardsInfo: (blockId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_all_shards_info/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'proof', 'data'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - proof: { type: 'string' }, - data: { type: 'string' } - } - }); - }, - + known_block: string; /** - * @description Get raw transactions - * - * @tags Lite Server - * @name GetRawTransactions - * @request GET:/v2/liteserver/get_transactions/{account_id} + * target block: (workchain,shard,seqno,root_hash,file_hash) + * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" */ - getRawTransactions: ( - accountId_Address: Address, - query: { - /** - * count - * @format int32 - * @example 100 - */ - count: number; - /** - * lt - * @format int64 - * @example 23814011000000 - */ - lt: number; - /** - * hash - * @example "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" - */ - hash: string; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/liteserver/get_transactions/${accountId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['ids', 'transactions'], - properties: { - ids: { type: 'array', items: { $ref: '#/components/schemas/BlockRaw' } }, - transactions: { type: 'string' } - } - }); - }, - + target_block?: string; /** - * @description Get raw list block transactions - * - * @tags Lite Server - * @name GetRawListBlockTransactions - * @request GET:/v2/liteserver/list_block_transactions/{block_id} + * mode + * @format int32 + * @example 0 */ - getRawListBlockTransactions: ( - blockId: string, - query: { - /** - * mode - * @format int32 - * @example 0 - */ - mode: number; - /** - * count - * @format int32 - * @example 100 - */ - count: number; - /** - * account ID - * @format address - * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" - */ - account_id?: Address; - /** - * lt - * @format int64 - * @example 23814011000000 - */ - lt?: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/list_block_transactions/${blockId}`, - method: 'GET', - query: query && { - ...query, - account_id: query.account_id?.toRawString() - }, - queryImplode: ['account_id'], - format: 'json', - ...params - }); + mode: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_block_proof`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - return prepareResponse(req, { - type: 'object', - required: ['id', 'req_count', 'incomplete', 'ids', 'proof'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - req_count: { type: 'integer', format: 'int32' }, - incomplete: { type: 'boolean' }, - ids: { - type: 'array', - items: { + return prepareResponse(req, { + type: 'object', + required: ['complete', 'from', 'to', 'steps'], + properties: { + complete: { type: 'boolean' }, + from: { $ref: '#/components/schemas/BlockRaw' }, + to: { $ref: '#/components/schemas/BlockRaw' }, + steps: { + type: 'array', + items: { + type: 'object', + required: ['lite_server_block_link_back', 'lite_server_block_link_forward'], + properties: { + lite_server_block_link_back: { type: 'object', - required: ['mode'], + required: [ + 'to_key_block', + 'from', + 'to', + 'dest_proof', + 'proof', + 'state_proof' + ], properties: { - mode: { type: 'integer', format: 'int32' }, - account: { type: 'string' }, - lt: { type: 'integer', format: 'bigint', 'x-js-format': 'bigint' }, - hash: { type: 'string' } + to_key_block: { type: 'boolean' }, + from: { $ref: '#/components/schemas/BlockRaw' }, + to: { $ref: '#/components/schemas/BlockRaw' }, + dest_proof: { type: 'string' }, + proof: { type: 'string' }, + state_proof: { type: 'string' } } - } - }, - proof: { type: 'string' } - } - }); - }, - - /** - * @description Get raw block proof - * - * @tags Lite Server - * @name GetRawBlockProof - * @request GET:/v2/liteserver/get_block_proof - */ - getRawBlockProof: ( - query: { - /** - * known block: (workchain,shard,seqno,root_hash,file_hash) - * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" - */ - known_block: string; - /** - * target block: (workchain,shard,seqno,root_hash,file_hash) - * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" - */ - target_block?: string; - /** - * mode - * @format int32 - * @example 0 - */ - mode: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/get_block_proof`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['complete', 'from', 'to', 'steps'], - properties: { - complete: { type: 'boolean' }, - from: { $ref: '#/components/schemas/BlockRaw' }, - to: { $ref: '#/components/schemas/BlockRaw' }, - steps: { - type: 'array', - items: { + }, + lite_server_block_link_forward: { type: 'object', required: [ - 'lite_server_block_link_back', - 'lite_server_block_link_forward' + 'to_key_block', + 'from', + 'to', + 'dest_proof', + 'config_proof', + 'signatures' ], properties: { - lite_server_block_link_back: { - type: 'object', - required: [ - 'to_key_block', - 'from', - 'to', - 'dest_proof', - 'proof', - 'state_proof' - ], - properties: { - to_key_block: { type: 'boolean' }, - from: { $ref: '#/components/schemas/BlockRaw' }, - to: { $ref: '#/components/schemas/BlockRaw' }, - dest_proof: { type: 'string' }, - proof: { type: 'string' }, - state_proof: { type: 'string' } - } - }, - lite_server_block_link_forward: { + to_key_block: { type: 'boolean' }, + from: { $ref: '#/components/schemas/BlockRaw' }, + to: { $ref: '#/components/schemas/BlockRaw' }, + dest_proof: { type: 'string' }, + config_proof: { type: 'string' }, + signatures: { type: 'object', required: [ - 'to_key_block', - 'from', - 'to', - 'dest_proof', - 'config_proof', + 'validator_set_hash', + 'catchain_seqno', 'signatures' ], properties: { - to_key_block: { type: 'boolean' }, - from: { $ref: '#/components/schemas/BlockRaw' }, - to: { $ref: '#/components/schemas/BlockRaw' }, - dest_proof: { type: 'string' }, - config_proof: { type: 'string' }, + validator_set_hash: { type: 'integer', format: 'int64' }, + catchain_seqno: { type: 'integer', format: 'int32' }, signatures: { - type: 'object', - required: [ - 'validator_set_hash', - 'catchain_seqno', - 'signatures' - ], - properties: { - validator_set_hash: { - type: 'integer', - format: 'int64' - }, - catchain_seqno: { - type: 'integer', - format: 'int32' - }, - signatures: { - type: 'array', - items: { - type: 'object', - required: ['node_id_short', 'signature'], - properties: { - node_id_short: { type: 'string' }, - signature: { type: 'string' } - } - } + type: 'array', + items: { + type: 'object', + required: ['node_id_short', 'signature'], + properties: { + node_id_short: { type: 'string' }, + signature: { type: 'string' } } } } @@ -9283,338 +9230,324 @@ export class TonApiClient { } } } - }); - }, + } + } + }); +}; +/** + * @description Get raw config + * + * @tags Lite Server + * @name GetRawConfig + * @request GET:/v2/liteserver/get_config_all/{block_id} + */ +export const getRawConfig = ( + blockId: string, + query: { /** - * @description Get raw config - * - * @tags Lite Server - * @name GetRawConfig - * @request GET:/v2/liteserver/get_config_all/{block_id} + * mode + * @format int32 + * @example 0 */ - getRawConfig: ( - blockId: string, - query: { - /** - * mode - * @format int32 - * @example 0 - */ - mode: number; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/liteserver/get_config_all/${blockId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['mode', 'id', 'state_proof', 'config_proof'], - properties: { - mode: { type: 'integer', format: 'int32' }, - id: { $ref: '#/components/schemas/BlockRaw' }, - state_proof: { type: 'string' }, - config_proof: { type: 'string' } - } - }); - }, + mode: number; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_config_all/${blockId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - /** - * @description Get raw shard block proof - * - * @tags Lite Server - * @name GetRawShardBlockProof - * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} - */ - getRawShardBlockProof: (blockId: string, params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_shard_block_proof/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['masterchain_id', 'links'], - properties: { - masterchain_id: { $ref: '#/components/schemas/BlockRaw' }, - links: { - type: 'array', - items: { - type: 'object', - required: ['id', 'proof'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - proof: { type: 'string' } - } - } + return prepareResponse(req, { + type: 'object', + required: ['mode', 'id', 'state_proof', 'config_proof'], + properties: { + mode: { type: 'integer', format: 'int32' }, + id: { $ref: '#/components/schemas/BlockRaw' }, + state_proof: { type: 'string' }, + config_proof: { type: 'string' } + } + }); +}; + +/** + * @description Get raw shard block proof + * + * @tags Lite Server + * @name GetRawShardBlockProof + * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} + */ +export const getRawShardBlockProof = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_shard_block_proof/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['masterchain_id', 'links'], + properties: { + masterchain_id: { $ref: '#/components/schemas/BlockRaw' }, + links: { + type: 'array', + items: { + type: 'object', + required: ['id', 'proof'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + proof: { type: 'string' } } } - }); - }, + } + } + }); +}; - /** - * @description Get out msg queue sizes - * - * @tags Lite Server - * @name GetOutMsgQueueSizes - * @request GET:/v2/liteserver/get_out_msg_queue_sizes - */ - getOutMsgQueueSizes: (params: RequestParams = {}) => { - const req = this.http.request({ - path: `/v2/liteserver/get_out_msg_queue_sizes`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['ext_msg_queue_size_limit', 'shards'], - properties: { - ext_msg_queue_size_limit: { type: 'integer', format: 'uint32' }, - shards: { - type: 'array', - items: { - type: 'object', - required: ['id', 'size'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - size: { type: 'integer', format: 'uint32' } - } - } +/** + * @description Get out msg queue sizes + * + * @tags Lite Server + * @name GetOutMsgQueueSizes + * @request GET:/v2/liteserver/get_out_msg_queue_sizes + */ +export const getOutMsgQueueSizes = (params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/liteserver/get_out_msg_queue_sizes`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['ext_msg_queue_size_limit', 'shards'], + properties: { + ext_msg_queue_size_limit: { type: 'integer', format: 'uint32' }, + shards: { + type: 'array', + items: { + type: 'object', + required: ['id', 'size'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + size: { type: 'integer', format: 'uint32' } } } - }); - } - }; - multisig = { - /** - * @description Get multisig account info - * - * @tags Multisig - * @name GetMultisigAccount - * @request GET:/v2/multisig/{account_id} - */ - getMultisigAccount: (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/multisig/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Multisig' - }); + } } - }; - emulation = { - /** - * @description Decode a given message. Only external incoming messages can be decoded currently. - * - * @tags Emulation - * @name DecodeMessage - * @request POST:/v2/message/decode - */ - decodeMessage: ( - data: { - /** @format cell */ - boc: Cell; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/message/decode`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DecodedMessage' - }); - }, + }); +}; - /** - * @description Emulate sending message to blockchain - * - * @tags Emulation, Events - * @name EmulateMessageToEvent - * @request POST:/v2/events/emulate - */ - emulateMessageToEvent: ( - data: { - /** @format cell */ - boc: Cell; - }, - query?: { - ignore_signature_check?: boolean; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/events/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Event' - }); - }, +/** + * @description Get multisig account info + * + * @tags Multisig + * @name GetMultisigAccount + * @request GET:/v2/multisig/{account_id} + */ +export const getMultisigAccount = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/multisig/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); - /** - * @description Emulate sending message to blockchain - * - * @tags Emulation, Traces - * @name EmulateMessageToTrace - * @request POST:/v2/traces/emulate - */ - emulateMessageToTrace: ( - data: { - /** @format cell */ - boc: Cell; - }, - query?: { - ignore_signature_check?: boolean; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/traces/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Trace' - }); - }, + return prepareResponse(req, { $ref: '#/components/schemas/Multisig' }); +}; - /** - * @description Emulate sending message to blockchain - * - * @tags Emulation, Wallet - * @name EmulateMessageToWallet - * @request POST:/v2/wallet/emulate - */ - emulateMessageToWallet: ( - data: { - /** @format cell */ - boc: Cell; - /** additional per account configuration */ - params?: { - /** - * @format address - * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" - */ - address: Address; - /** - * @format bigint - * @example 10000000000 - */ - balance?: bigint; - }[]; - }, - params: RequestParams = {} - ) => { - const req = this.http.request({ - path: `/v2/wallet/emulate`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { - boc: { type: 'string', format: 'cell' }, - params: { - type: 'array', - items: { - type: 'object', - required: ['address'], - properties: { - address: { type: 'string', format: 'address' }, - balance: { - type: 'integer', - format: 'bigint', - 'x-js-format': 'bigint' - } - } - } +/** + * @description Decode a given message. Only external incoming messages can be decoded currently. + * + * @tags Emulation + * @name DecodeMessage + * @request POST:/v2/message/decode + */ +export const decodeMessage = ( + data: { + /** @format cell */ + boc: Cell; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/message/decode`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DecodedMessage' }); +}; + +/** + * @description Emulate sending message to blockchain + * + * @tags Emulation, Events + * @name EmulateMessageToEvent + * @request POST:/v2/events/emulate + */ +export const emulateMessageToEvent = ( + data: { + /** @format cell */ + boc: Cell; + }, + query?: { + ignore_signature_check?: boolean; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/events/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Event' }); +}; + +/** + * @description Emulate sending message to blockchain + * + * @tags Emulation, Traces + * @name EmulateMessageToTrace + * @request POST:/v2/traces/emulate + */ +export const emulateMessageToTrace = ( + data: { + /** @format cell */ + boc: Cell; + }, + query?: { + ignore_signature_check?: boolean; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/traces/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); +}; + +/** + * @description Emulate sending message to blockchain + * + * @tags Emulation, Wallet + * @name EmulateMessageToWallet + * @request POST:/v2/wallet/emulate + */ +export const emulateMessageToWallet = ( + data: { + /** @format cell */ + boc: Cell; + /** additional per account configuration */ + params?: { + /** + * @format address + * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + */ + address: Address; + /** + * @format bigint + * @example 10000000000 + */ + balance?: bigint; + }[]; + }, + params: RequestParams = {} +) => { + const req = getHttpClient().request({ + path: `/v2/wallet/emulate`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { + boc: { type: 'string', format: 'cell' }, + params: { + type: 'array', + items: { + type: 'object', + required: ['address'], + properties: { + address: { type: 'string', format: 'address' }, + balance: { type: 'integer', format: 'bigint', 'x-js-format': 'bigint' } } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/MessageConsequences' - }); - }, + } + } + }), + format: 'json', + ...params + }); - /** - * @description Emulate sending message to blockchain - * - * @tags Emulation, Accounts - * @name EmulateMessageToAccountEvent - * @request POST:/v2/accounts/{account_id}/events/emulate - */ - emulateMessageToAccountEvent: ( - accountId_Address: Address, - data: { - /** @format cell */ - boc: Cell; - }, - query?: { - ignore_signature_check?: boolean; - }, - params: RequestParams = {} - ) => { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ - path: `/v2/accounts/${accountId}/events/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); + return prepareResponse(req, { + $ref: '#/components/schemas/MessageConsequences' + }); +}; - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvent' - }); - } - }; -} +/** + * @description Emulate sending message to blockchain + * + * @tags Emulation, Accounts + * @name EmulateMessageToAccountEvent + * @request POST:/v2/accounts/{account_id}/events/emulate + */ +export const emulateMessageToAccountEvent = ( + accountId_Address: Address, + data: { + /** @format cell */ + boc: Cell; + }, + query?: { + ignore_signature_check?: boolean; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/accounts/${accountId}/events/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvent' + }); +}; diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index 4bbc76e..b9821e3 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -245,9 +245,10 @@ const generateApiParams: GenerateApiParams = { }; }, onPrepareConfig(config) { - // Fall back to previous version of the schema - addRouteToModuleByOperationId('addressParse', 'accounts', config); - addRouteToModuleByOperationId('status', 'blockchain', config); + // Note: These fallback routes create duplicates in flat export structure + // Commented out for flat SDK generation + // addRouteToModuleByOperationId('addressParse', 'accounts', config); + // addRouteToModuleByOperationId('status', 'blockchain', config); return config; } diff --git a/packages/client/src/templates/api.ejs b/packages/client/src/templates/api.ejs index ce97841..784f5c4 100644 --- a/packages/client/src/templates/api.ejs +++ b/packages/client/src/templates/api.ejs @@ -64,18 +64,8 @@ const schemasObject = _.keys(config.originalSchema.components.schemas).reduce((a return acc; }, {}); -// TODO: Maybe we will need this in the future -// const requestBodiesObject = _.keys(config.originalSchema.components.requestBodies).reduce((acc, key) => { -// const fullKey = "#/components/requestBodies/" + key; -// const requestBodyContent = config.originalSchema.components.requestBodies[key].content['application/json']; -// // Skip requestBodies with content type other than application/json -// acc[fullKey] = requestBodyContent && clearSchemaReferenceInformation(requestBodyContent.schema); -// return acc; -// }, {}); - const componentsJson = JSON.stringify({ ...schemasObject, - // ...requestBodiesObject }); utils.clearSchemaReferenceInformation = clearSchemaReferenceInformation; @@ -96,34 +86,54 @@ const components = <%~ componentsJson %> <% }) %> */ <% } %> -export class TonApiClient { -<% if(config.singleHttpClient) { %> - http: HttpClient; +// Singleton HttpClient instance +let httpClient: HttpClient | null = null; + +/** + * Initialize the API client with configuration + * @param apiConfig - Configuration for the API client (baseUrl, apiKey, etc.) + */ +export function initClient(apiConfig: ApiConfig = {}): void { + httpClient = new HttpClient(apiConfig); +} - constructor (apiConfig: ApiConfig = {}) { - this.http = new HttpClient(apiConfig); +/** + * Get the current HttpClient instance (creates one if it doesn't exist) + * @internal + */ +function getHttpClient(): HttpClient { + if (!httpClient) { + httpClient = new HttpClient(); } -<% } %> + return httpClient; +} +/** + * Update the API client configuration + * @param apiConfig - Configuration to update + */ +export function updateClient(apiConfig: Partial): void { + const client = getHttpClient(); + if (apiConfig.baseUrl !== undefined) client.baseUrl = apiConfig.baseUrl; + if (apiConfig.apiKey !== undefined) client.setApiKey(apiConfig.apiKey); + if (apiConfig.fetch !== undefined) client.setCustomFetch(apiConfig.fetch); +} <% if (routes.outOfModule) { %> <% for (const route of routes.outOfModule) { %> - <%~ includeFile('./procedure-call.ejs', { ...it, route }) %> +<%~ includeFile('./procedure-call.ejs', { ...it, route, isFlat: true }) %> <% } %> <% } %> <% if (routes.combined) { %> <% for (const { routes: combinedRoutes = [], moduleName } of routes.combined) { %> - <%~ moduleName %> = { - <% for (const route of combinedRoutes) { %> + <% for (const route of combinedRoutes) { %> - <%~ includeFile('./procedure-call.ejs', { ...it, route }) %> +<%~ includeFile('./procedure-call.ejs', { ...it, route, isFlat: true }) %> - <% } %> - } + <% } %> <% } %> <% } %> -} diff --git a/packages/client/src/templates/http-client.ejs b/packages/client/src/templates/http-client.ejs index e319333..0e43a5a 100644 --- a/packages/client/src/templates/http-client.ejs +++ b/packages/client/src/templates/http-client.ejs @@ -228,6 +228,29 @@ class HttpClient { } } + public setApiKey = (apiKey: string | undefined) => { + if (apiKey) { + this.baseApiParams = { + ...this.baseApiParams, + headers: { + ...(this.baseApiParams.headers || {}), + Authorization: `Bearer ${apiKey}` + } as HeadersInit + }; + } else { + const headers = { ...(this.baseApiParams.headers || {}) } as Record; + delete headers['Authorization']; + this.baseApiParams = { + ...this.baseApiParams, + headers: headers as HeadersInit + }; + } + } + + public setCustomFetch = (fetchFn: typeof fetch | undefined) => { + this.providedFetch = fetchFn ?? null; + } + public request = async ({ body, secure, diff --git a/packages/client/src/templates/procedure-call.ejs b/packages/client/src/templates/procedure-call.ejs index 7bb2ef5..18c1493 100644 --- a/packages/client/src/templates/procedure-call.ejs +++ b/packages/client/src/templates/procedure-call.ejs @@ -1,5 +1,5 @@ <% -const { utils, route, config } = it; +const { utils, route, config, isFlat } = it; const { requestBodyInfo, responseBodyInfo, responseBodySchema, specificArgNameResolver } = route; const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require, clearSchemaReferenceInformation } = utils; const { parameters, path, method, payload, query, formData, security, requestParams } = route.request; @@ -105,9 +105,9 @@ const queryImplodeTmpl = queryImplodeParams.length === 0 ? null : JSON.stringify <%~ routeDocs.lines %> */ -<%~ route.routeName.usage %><%~ route.namespace ? ': ' : ' = ' %> (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { +<% if (isFlat) { %>export const <% } %><%~ route.routeName.usage %><%~ route.namespace && !isFlat ? ': ' : ' = ' %> (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { <%~ reducedPathParams %> - const req = <%~ config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({ + const req = <%~ isFlat ? 'getHttpClient().request' : config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({ path: `<%~ path %>`, method: '<%~ _.upperCase(method) %>', <%~ queryTmpl ? `query: ${queryTmplValue},` : '' %> @@ -120,5 +120,5 @@ const queryImplodeTmpl = queryImplodeParams.length === 0 ? null : JSON.stringify }); return prepareResponse<<%~ type %>>(req<%~ schemaTmpl %>); -}<%~ route.namespace ? ',' : '' %> +}<%~ route.namespace && !isFlat ? ',' : '' %> diff --git a/tests/client/client.test.ts b/tests/client/client.test.ts index 77ce20a..26c17a5 100644 --- a/tests/client/client.test.ts +++ b/tests/client/client.test.ts @@ -1,10 +1,15 @@ -import { TonApiClient, ApiConfig } from '@ton-api/client'; -import { ta, taWithApiKey } from './utils/client'; +import { initClient, status, getAccounts as getAccountsOp, getAccountPublicKey } from '@ton-api/client'; +import { initTa, useTa, useTaWithApiKey } from './utils/client'; import { Address } from '@ton/core'; import { getAccounts } from './__mock__/services'; -import { vi, test, expect, afterEach } from 'vitest'; +import { vi, test, expect, afterEach, beforeEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; +beforeEach(() => { + // Reset to default client before each test + initTa(); +}); + afterEach(() => { vi.restoreAllMocks(); }); @@ -15,7 +20,7 @@ test('Client status test', async () => { indexing_latency: 8 }); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(error).toBeNull(); expect(data).toBeDefined(); }); @@ -26,7 +31,8 @@ test('Client apiKey test', async () => { indexing_latency: 8 }); - const { data, error } = await taWithApiKey.utilities.status(); + useTaWithApiKey(); + const { data, error } = await status(); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -46,12 +52,10 @@ test('Client apiKey missing test', async () => { indexing_latency: 8 }); - const config: ApiConfig = { + initClient({ baseUrl: 'https://tonapi.io' - }; - - const localTa = new TonApiClient(config); - const { data, error } = await localTa.utilities.status(); + }); + const { data, error } = await status(); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -71,12 +75,10 @@ test('Client fallback test', async () => { indexing_latency: 8 }); - const config: ApiConfig = { + initClient({ baseUrl: 'https://tonapi.io' - }; - - const localTa = new TonApiClient(config); - const { data, error } = await localTa.blockchain.status(); + }); + const { data, error } = await status(); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -96,7 +98,7 @@ test('Client x-tonapi-client header test', async () => { indexing_latency: 8 }); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -123,14 +125,12 @@ test('Client custom fetch is called', async () => { }) ); - const config: ApiConfig = { + initClient({ baseUrl: 'https://tonapi.io', fetch: customFetch - }; - - const ta = new TonApiClient(config); + }); - await ta.utilities.status(); + await status(); expect(customFetch).toHaveBeenCalled(); }); @@ -143,7 +143,7 @@ test('Client post method in fetch', async () => { 'UQAW2nxA69WYdMr90utDmpeZFwvG4XYcc9iibAP5sZnlojRO' ]; - const { data, error } = await ta.accounts.getAccounts({ + const { data, error } = await getAccountsOp({ accountIds: accountIds.map(id => Address.parse(id)) }); @@ -164,7 +164,7 @@ test('Client response type for schema outside component (with snake_case)', asyn }); const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9YvxsnV'); - const { data, error } = await ta.accounts.getAccountPublicKey(senderAddress); + const { data, error } = await getAccountPublicKey(senderAddress); expect(error).toBeNull(); expect(data).toBeDefined(); diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index bfeb46a..8a6fd41 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -1,8 +1,10 @@ -import { ta } from './utils/client'; +import { status } from '@ton-api/client'; +import { initTa } from './utils/client'; import { vi, test, expect, afterEach, beforeEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; beforeEach(() => { + initTa(); vi.restoreAllMocks(); }); @@ -17,7 +19,7 @@ test('should return a successful response with JSON data', async () => { const mockData = { status: 'ok', uptime: 123456 }; const fetchSpy = mockFetch(mockData); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(error).toBeNull(); expect(data).toEqual(mockData); expect(fetchSpy).toHaveBeenCalledWith( @@ -30,7 +32,7 @@ test('should handle an error response with a JSON message', async () => { const mockError = { error: 'Invalid request' }; vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Invalid request'); @@ -41,7 +43,7 @@ test('should handle an error response with a JSON message', async () => { test('should handle an error response with a string message', async () => { vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse('Simple error message', 500)); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Simple error message'); @@ -53,7 +55,7 @@ test('should include cause in the error object', async () => { const mockError = { error: 'Invalid request' }; vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Invalid request'); @@ -65,7 +67,7 @@ test('should handle an error response without JSON', async () => { const mockError = new Error('Network failure'); vi.spyOn(global, 'fetch').mockRejectedValueOnce(mockError); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Network failure'); @@ -79,7 +81,7 @@ test('should handle an error response with invalid JSON', async () => { }); vi.spyOn(global, 'fetch').mockResolvedValueOnce(response); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toContain('Failed to parse error response'); @@ -90,7 +92,7 @@ test('should handle an error response with invalid JSON', async () => { test('should handle an unknown error type (object)', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce({ message: 'Some unknown error' } as any); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Unknown error occurred'); @@ -99,7 +101,7 @@ test('should handle an unknown error type (object)', async () => { test('should handle an unknown error type (string)', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce('Some unknown error' as any); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Unknown error occurred'); @@ -108,7 +110,7 @@ test('should handle an unknown error type (string)', async () => { test('should handle null as an error', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce(null as any); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Unknown error occurred'); @@ -117,7 +119,7 @@ test('should handle null as an error', async () => { test('should handle undefined as an error', async () => { vi.spyOn(global, 'fetch').mockRejectedValueOnce(undefined as any); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Unknown error occurred'); @@ -127,7 +129,7 @@ test('should handle a JSON error response without an error field', async () => { const mockError = { message: 'Some error without error field' }; vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - const { data, error } = await ta.utilities.status(); + const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); expect(error?.message).toBe('Some error without error field'); diff --git a/tests/client/memory-leak.test.ts b/tests/client/memory-leak.test.ts index 65fd70c..8368b8e 100644 --- a/tests/client/memory-leak.test.ts +++ b/tests/client/memory-leak.test.ts @@ -1,8 +1,13 @@ import { getBlockchainBlockTransactions } from './__mock__/services'; -import { ta } from './utils/client'; -import { describe, test, expect } from 'vitest'; +import { status, getBlockchainBlockTransactions as getBlockchainBlockTransactionsOp } from '@ton-api/client'; +import { initTa } from './utils/client'; +import { describe, test, expect, beforeEach } from 'vitest'; import { JSONStringify } from './utils/jsonbig'; +beforeEach(() => { + initTa(); +}); + global.fetch = () => Promise.resolve( new Response(JSONStringify(getBlockchainBlockTransactions), { @@ -27,10 +32,10 @@ describe.skip('Memory leak test', () => { const initialMemory = process.memoryUsage().heapUsed; const memoryUsageSamples: number[] = []; - await ta.utilities.status(); + await status(); for (let i = 0; i < iterations; i++) { - await ta.blockchain.getBlockchainBlockTransactions('(-1,8000000000000000,4234234)'); + await getBlockchainBlockTransactionsOp('(-1,8000000000000000,4234234)'); // 🔍 Log memory usage every 50_000 iterations if (i % 50_000 === 0) { diff --git a/tests/client/parse-address.test.ts b/tests/client/parse-address.test.ts index 0314245..22937ee 100644 --- a/tests/client/parse-address.test.ts +++ b/tests/client/parse-address.test.ts @@ -1,9 +1,14 @@ import { Address } from '@ton/core'; -import { ta } from './utils/client'; +import { getBlockchainRawAccount as getBlockchainRawAccountOp, getAccounts as getAccountsOp } from '@ton-api/client'; +import { initTa } from './utils/client'; import { getAccounts, getBlockchainRawAccount } from './__mock__/address'; -import { vi, test, expect, afterEach } from 'vitest'; +import { vi, test, expect, afterEach, beforeEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; +beforeEach(() => { + initTa(); +}); + afterEach(() => { vi.restoreAllMocks(); }); @@ -14,7 +19,7 @@ test('Address simple in params & response', async () => { const addressString = 'UQC62nZpm36EFzADVfXDVd_4OpbFyc1D3w3ZvCPHLni8Dst4'; const addressObject = Address.parse(addressString); const addressRawString = addressObject.toRawString(); - const { data, error } = await ta.blockchain.getBlockchainRawAccount(addressObject); + const { data, error } = await getBlockchainRawAccountOp(addressObject); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -34,7 +39,7 @@ test('Address in request body test', async () => { ]; const accountIds = addressStrings.map(str => Address.parse(str)); - const { data, error } = await ta.accounts.getAccounts({ accountIds }); + const { data, error } = await getAccountsOp({ accountIds }); expect(error).toBeNull(); expect(data).toBeDefined(); diff --git a/tests/client/parse-bigint.test.ts b/tests/client/parse-bigint.test.ts index 775861f..7eef8f7 100644 --- a/tests/client/parse-bigint.test.ts +++ b/tests/client/parse-bigint.test.ts @@ -1,8 +1,13 @@ import { Address } from '@ton/core'; -import { ta } from './utils/client'; +import { getAccounts as getAccountsOp, getJettonInfo as getJettonInfoOp } from '@ton-api/client'; +import { initTa } from './utils/client'; import { getAccount, getJettonInfo } from './__mock__/bigint'; import { mockFetch } from './utils/mockFetch'; -import { vi, afterEach, test, expect } from 'vitest'; +import { vi, afterEach, beforeEach, test, expect } from 'vitest'; + +beforeEach(() => { + initTa(); +}); afterEach(() => { vi.restoreAllMocks(); @@ -16,7 +21,7 @@ test('BigInt parse data in number test', async () => { '0:7c9fc62291740a143086c807fe322accfd12737b3c2243676228176707c7ce40' ]; const accountIds = addressStrings.map(addr => Address.parse(addr)); - const { data, error } = await ta.accounts.getAccounts({ accountIds }); + const { data, error } = await getAccountsOp({ accountIds }); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -31,7 +36,7 @@ test('BigInt parse data in string test', async () => { mockFetch(getJettonInfo); const usdtJettonAddress = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); - const { data, error } = await ta.jettons.getJettonInfo(usdtJettonAddress); + const { data, error } = await getJettonInfoOp(usdtJettonAddress); expect(error).toBeNull(); expect(data).toBeDefined(); diff --git a/tests/client/parse-cell.test.ts b/tests/client/parse-cell.test.ts index 90ba9ea..c99fc64 100644 --- a/tests/client/parse-cell.test.ts +++ b/tests/client/parse-cell.test.ts @@ -1,8 +1,13 @@ import { Address, Cell, TupleItem, TupleItemCell } from '@ton/core'; -import { ta } from './utils/client'; +import { getBlockchainRawAccount as getBlockchainRawAccountOp, sendBlockchainMessage, execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountOp } from '@ton-api/client'; +import { initTa } from './utils/client'; import { execGetMethodForBlockchainAccount, getBlockchainRawAccount } from './__mock__/cell'; import { mockFetch } from './utils/mockFetch'; -import { test, expect, afterEach, vi } from 'vitest'; +import { test, expect, afterEach, beforeEach, vi } from 'vitest'; + +beforeEach(() => { + initTa(); +}); afterEach(() => { vi.restoreAllMocks(); @@ -13,7 +18,7 @@ test('Cell hex in response test', async () => { const addressString = '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'; const addressObject = Address.parse(addressString); - const { data, error } = await ta.blockchain.getBlockchainRawAccount(addressObject); + const { data, error } = await getBlockchainRawAccountOp(addressObject); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -33,7 +38,7 @@ test('Cell hex in request body test', async () => { const cell = Cell.fromBase64(cellBase64); - await ta.blockchain.sendBlockchainMessage({ + await sendBlockchainMessage({ boc: cell }); @@ -57,7 +62,7 @@ test('Cell base64 in response test', async () => { const addressString = 'EQDW6q4sRqQwNCmW4qwUpeFSU1Xhd6l3xwJ6jjknBPzxKNtT'; const addressObject = Address.parse(addressString); - const { data, error } = await ta.blockchain.execGetMethodForBlockchainAccount( + const { data, error } = await execGetMethodForBlockchainAccountOp( addressObject, 'royalty_params' ); diff --git a/tests/client/parse-tuple.test.ts b/tests/client/parse-tuple.test.ts index 4b5a685..f6658b8 100644 --- a/tests/client/parse-tuple.test.ts +++ b/tests/client/parse-tuple.test.ts @@ -1,8 +1,13 @@ import { Address, Tuple, TupleItem } from '@ton/core'; +import { execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountOp } from '@ton-api/client'; +import { initTa } from './utils/client'; import { execGetMethodForBlockchainAccount } from './__mock__/tuple'; -import { ta } from './utils/client'; import { mockFetch } from './utils/mockFetch'; -import { test, expect, afterEach, vi } from 'vitest'; +import { test, expect, afterEach, beforeEach, vi } from 'vitest'; + +beforeEach(() => { + initTa(); +}); afterEach(() => { vi.restoreAllMocks(); @@ -17,7 +22,7 @@ test('Tuple test', async () => { const addressString = 'Ef_X4pRKtgXOXYMOXNgXNRdlhkNKJ9bTKMfqvj6HDIiQG98F'; const addressObject = Address.parse(addressString); - const { data, error } = await ta.blockchain.execGetMethodForBlockchainAccount( + const { data, error } = await execGetMethodForBlockchainAccountOp( addressObject, 'list_nominators' ); diff --git a/tests/client/services.test.ts b/tests/client/services.test.ts index 26e1654..0f9752f 100644 --- a/tests/client/services.test.ts +++ b/tests/client/services.test.ts @@ -1,8 +1,13 @@ import { Address } from '@ton/core'; -import { ta } from './utils/client'; +import { getChartRates as getChartRatesOp, getRates as getRatesOp } from '@ton-api/client'; +import { initTa } from './utils/client'; import { getChartRates, getRates } from './__mock__/services'; import { mockFetch } from './utils/mockFetch'; -import { test, expect, afterEach, vi } from 'vitest'; +import { test, expect, afterEach, beforeEach, vi } from 'vitest'; + +beforeEach(() => { + initTa(); +}); afterEach(() => { vi.restoreAllMocks(); @@ -13,7 +18,7 @@ test('getChartRates, should correct parse array in pair', async () => { const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; const addressObject = Address.parse(addressString); - const { data, error } = await ta.rates.getChartRates({ + const { data, error } = await getChartRatesOp({ token: addressObject, currency: 'rub' }); @@ -40,7 +45,7 @@ test('getChartRates, should correct parse array in pair', async () => { test('getRates, additionalProperties should be not convert to camelCase', async () => { mockFetch(getRates); - const { data, error } = await ta.rates.getRates({ + const { data, error } = await getRatesOp({ tokens: ['TON,TOKEN_WITH_UNDERSCORE'], currencies: ['USD', 'EUR'] }); @@ -61,7 +66,7 @@ test('getRates, explode in params should be matter', async () => { // }) // ); - await ta.rates.getRates({ + await getRatesOp({ tokens: ['TON', 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'], currencies: ['USD', 'EUR'] }); diff --git a/tests/client/utils/client.ts b/tests/client/utils/client.ts index d9c6c6f..552edec 100644 --- a/tests/client/utils/client.ts +++ b/tests/client/utils/client.ts @@ -1,12 +1,29 @@ -import { TonApiClient } from '@ton-api/client'; +import { initClient, updateClient } from '@ton-api/client'; const baseUrl = 'https://tonapi.io'; -export const taWithApiKey = new TonApiClient({ - baseUrl, - apiKey: 'TEST_API_KEY' -}); +// Initialize default client (without API key) +export function initTa() { + initClient({ baseUrl }); +} -export const ta = new TonApiClient({ - baseUrl -}); +// Initialize client with API key +export function initTaWithApiKey() { + initClient({ + baseUrl, + apiKey: 'TEST_API_KEY' + }); +} + +// Switch to client without API key +export function useTa() { + updateClient({ apiKey: undefined }); +} + +// Switch to client with API key +export function useTaWithApiKey() { + updateClient({ apiKey: 'TEST_API_KEY' }); +} + +// Initialize default client on module load +initTa(); From c7c718e2be62bb13db21fefdc78064e00e29c2e2 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Tue, 11 Nov 2025 19:13:16 +0400 Subject: [PATCH 04/27] feat: implement centralized error handling for parsing errors in TonAPI SDK - Introduced `TonApiParsingError` class for consistent error management across parsing operations. - Updated parsing functions to throw `TonApiParsingError` for Address, Cell, BigInt, and TupleItem errors, enhancing error clarity. - Refactored error handling in response preparation to utilize centralized formatting for parsing errors. - Removed deprecated methods from `HttpClient` and streamlined client initialization. - Updated tests to validate new error handling structure and ensure robust coverage for parsing scenarios. --- packages/client/src/client.ts | 146 +++++--- packages/client/src/generate.ts | 53 +-- packages/client/src/templates/api.ejs | 28 +- packages/client/src/templates/errors.ejs | 39 +++ packages/client/src/templates/http-client.ejs | 23 -- packages/client/src/templates/utils.ejs | 55 ++- tests/client/client.test.ts | 329 ++++++++++++++++- tests/client/errors.test.ts | 330 +++++++++++++++++- tests/client/utils/client.ts | 9 +- 9 files changed, 872 insertions(+), 140 deletions(-) create mode 100644 packages/client/src/templates/errors.ejs diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 9e58fcc..8b91fcb 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3478,29 +3478,6 @@ class HttpClient { } }; - public setApiKey = (apiKey: string | undefined) => { - if (apiKey) { - this.baseApiParams = { - ...this.baseApiParams, - headers: { - ...(this.baseApiParams.headers || {}), - Authorization: `Bearer ${apiKey}` - } as HeadersInit - }; - } else { - const headers = { ...(this.baseApiParams.headers || {}) } as Record; - delete headers['Authorization']; - this.baseApiParams = { - ...this.baseApiParams, - headers: headers as HeadersInit - }; - } - }; - - public setCustomFetch = (fetchFn: typeof fetch | undefined) => { - this.providedFetch = fetchFn ?? null; - }; - public request = async ({ body, secure, @@ -5805,6 +5782,46 @@ const components = { properties: { id: { type: 'integer', format: 'int64' }, method: { type: 'string' } } } }; +/** + * Single error class for all parsing errors in the TonAPI SDK + * + * Provides type-safe error handling with centralized message formatting. + * Use parsingType property to distinguish between Address, Cell, BigInt, and TupleItem errors. + * + * @example + * ```typescript + * if (error.cause instanceof TonApiParsingError) { + * console.log('Parsing type:', error.cause.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' + * console.log('Error message:', error.cause.formatMessage()); + * } + * ``` + */ +export class TonApiParsingError extends Error { + readonly type = 'parsing_error' as const; + readonly parsingType: string; + readonly originalCause: unknown; + + constructor(parsingType: string, message: string, cause: unknown) { + super(message); + this.name = 'TonApiParsingError'; + this.parsingType = parsingType; + this.originalCause = cause; + + // Maintain proper stack trace in V8 + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } + + /** + * Format error message for end users + * Centralized formatting - change here to change everywhere + */ + formatMessage(): string { + return `SDK parsing error [${this.parsingType}]: ${this.message}`; + } +} + type ComponentRef = keyof typeof components; export interface TonApiError { @@ -5838,7 +5855,12 @@ function camelToSnake(camel: string): string { } function cellParse(src: string): Cell { - return Cell.fromHex(src); + try { + return Cell.fromHex(src); + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('Cell', msg, e); + } } function parseHexToBigInt(str: string) { @@ -5853,7 +5875,19 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis const data = prepareResponseData(obj, orSchema); return { data, error: null } as Result; } catch (parseError: unknown) { - // SDK parsing error (Address.parse, Cell.fromHex, BigInt conversion, etc.) + // Handle our custom parsing errors with centralized formatting + if (parseError instanceof TonApiParsingError) { + return { + data: null, + error: { + message: parseError.formatMessage(), // ✨ Centralized formatting! + type: 'parsing_error', + cause: parseError + } + } as Result; + } + + // Handle other errors (should not happen, but defensive) const message = parseError instanceof Error ? `SDK parsing error: ${parseError.message}` @@ -5939,7 +5973,12 @@ function prepareResponseData(obj: any, orSchema?: any): U { } else if (schema) { if (schema.type === 'string') { if (schema.format === 'address') { - return Address.parse(obj as string) as U; + try { + return Address.parse(obj as string) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('Address', msg, e); + } } if (schema.format === 'cell') { @@ -5947,18 +5986,33 @@ function prepareResponseData(obj: any, orSchema?: any): U { } if (schema['x-js-format'] === 'bigint') { - return BigInt(obj as string) as U; + try { + return BigInt(obj as string) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('BigInt', msg, e); + } } // maybe not used if (schema.format === 'cell-base64') { - return obj && (Cell.fromBase64(obj as string) as U); + try { + return obj && (Cell.fromBase64(obj as string) as U); + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('Cell', msg, e); + } } } if (schema.type === 'integer') { if (schema['x-js-format'] === 'bigint') { - return BigInt(obj as number) as U; + try { + return BigInt(obj as number) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('BigInt', msg, e); + } } return Number(obj as number) as U; @@ -5999,7 +6053,11 @@ function prepareResponseData(obj: any, orSchema?: any): U { type: 'nan' } as U; default: - throw new Error(`Unknown tuple item type: ${obj.type}`); + throw new TonApiParsingError( + 'TupleItem', + `Unknown tuple item type: ${obj.type}`, + obj + ); } } } @@ -6091,8 +6149,21 @@ function prepareRequestData(data: any, orSchema?: any): any { let httpClient: HttpClient | null = null; /** - * Initialize the API client with configuration - * @param apiConfig - Configuration for the API client (baseUrl, apiKey, etc.) + * Initialize the API client with configuration. + * Should be called once at application startup. + * + * @param apiConfig - Configuration for the API client + * @param apiConfig.baseUrl - API base URL + * @param apiConfig.apiKey - API authentication key + * @param apiConfig.baseApiParams - Additional request parameters + * + * @example + * ```typescript + * initClient({ + * baseUrl: 'https://tonapi.io', + * apiKey: process.env.TON_API_KEY + * }); + * ``` */ export function initClient(apiConfig: ApiConfig = {}): void { httpClient = new HttpClient(apiConfig); @@ -6109,17 +6180,6 @@ function getHttpClient(): HttpClient { return httpClient; } -/** - * Update the API client configuration - * @param apiConfig - Configuration to update - */ -export function updateClient(apiConfig: Partial): void { - const client = getHttpClient(); - if (apiConfig.baseUrl !== undefined) client.baseUrl = apiConfig.baseUrl; - if (apiConfig.apiKey !== undefined) client.setApiKey(apiConfig.apiKey); - if (apiConfig.fetch !== undefined) client.setCustomFetch(apiConfig.fetch); -} - /** * @description Get the openapi.json file * diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index b9821e3..b77388d 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -1,10 +1,8 @@ import { - GenerateApiConfiguration, GenerateApiParams, PrimitiveTypeStruct, SchemaComponent, generateApi - // generateTemplates, } from 'swagger-typescript-api'; import path from 'path'; @@ -81,7 +79,11 @@ function deepMerge(target: any, patch: any): any { for (const key in patch) { if (patch.hasOwnProperty(key)) { - if (typeof patch[key] === 'object' && !Array.isArray(patch[key]) && patch[key] !== null) { + if ( + typeof patch[key] === 'object' && + !Array.isArray(patch[key]) && + patch[key] !== null + ) { result[key] = deepMerge(target[key] || {}, patch[key]); } else { result[key] = patch[key]; @@ -175,29 +177,6 @@ function onCreateComponent(component: SchemaComponent) { return component; } -function addRouteToModuleByOperationId( - operationId: string, - moduleName: string, - config: GenerateApiConfiguration -) { - const route = config.routes.combined - ?.find(route => route.routes.find(route => route.routeName.usage === operationId)) - ?.routes.find(route => route.routeName.usage === operationId); - - if (route) { - const newRoute = { - ...route, - raw: { - ...route.raw, - deprecated: true - } - }; - config.routes.combined - ?.find(route => route.moduleName === moduleName) - ?.routes.push(newRoute); - } -} - const generateApiParams: GenerateApiParams = { name: 'src/client.ts', output: path.resolve(process.cwd(), './'), @@ -243,14 +222,6 @@ const generateApiParams: GenerateApiParams = { ...originalSchema, format: originalSchema['x-js-format'] ?? originalSchema.format }; - }, - onPrepareConfig(config) { - // Note: These fallback routes create duplicates in flat export structure - // Commented out for flat SDK generation - // addRouteToModuleByOperationId('addressParse', 'accounts', config); - // addRouteToModuleByOperationId('status', 'blockchain', config); - - return config; } }, // @ts-ignore @@ -258,23 +229,11 @@ const generateApiParams: GenerateApiParams = { }; async function main() { - // Uncomment the following lines to download schema and apply patches automatically + // Download schema and apply patches automatically // await downloadSchema(openapiUrl, openapiPath); - // applySchemaPatches(openapiPath, schemaPatchesPath); - - // Apply patches to existing schema applySchemaPatches(openapiPath, schemaPatchesPath); generateApi(generateApiParams); } main(); - -// generateTemplates({ -// cleanOutput: false, -// output: path.resolve(process.cwd(), "./src/templates"), -// httpClientType: "fetch", -// modular: false, -// silent: false, -// // rewrite: false, -// }); diff --git a/packages/client/src/templates/api.ejs b/packages/client/src/templates/api.ejs index 784f5c4..05f613d 100644 --- a/packages/client/src/templates/api.ejs +++ b/packages/client/src/templates/api.ejs @@ -91,8 +91,21 @@ const components = <%~ componentsJson %> let httpClient: HttpClient | null = null; /** - * Initialize the API client with configuration - * @param apiConfig - Configuration for the API client (baseUrl, apiKey, etc.) + * Initialize the API client with configuration. + * Should be called once at application startup. + * + * @param apiConfig - Configuration for the API client + * @param apiConfig.baseUrl - API base URL + * @param apiConfig.apiKey - API authentication key + * @param apiConfig.baseApiParams - Additional request parameters + * + * @example + * ```typescript + * initClient({ + * baseUrl: 'https://tonapi.io', + * apiKey: process.env.TON_API_KEY + * }); + * ``` */ export function initClient(apiConfig: ApiConfig = {}): void { httpClient = new HttpClient(apiConfig); @@ -109,17 +122,6 @@ function getHttpClient(): HttpClient { return httpClient; } -/** - * Update the API client configuration - * @param apiConfig - Configuration to update - */ -export function updateClient(apiConfig: Partial): void { - const client = getHttpClient(); - if (apiConfig.baseUrl !== undefined) client.baseUrl = apiConfig.baseUrl; - if (apiConfig.apiKey !== undefined) client.setApiKey(apiConfig.apiKey); - if (apiConfig.fetch !== undefined) client.setCustomFetch(apiConfig.fetch); -} - <% if (routes.outOfModule) { %> <% for (const route of routes.outOfModule) { %> diff --git a/packages/client/src/templates/errors.ejs b/packages/client/src/templates/errors.ejs new file mode 100644 index 0000000..fff5d94 --- /dev/null +++ b/packages/client/src/templates/errors.ejs @@ -0,0 +1,39 @@ +/** + * Single error class for all parsing errors in the TonAPI SDK + * + * Provides type-safe error handling with centralized message formatting. + * Use parsingType property to distinguish between Address, Cell, BigInt, and TupleItem errors. + * + * @example + * ```typescript + * if (error.cause instanceof TonApiParsingError) { + * console.log('Parsing type:', error.cause.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' + * console.log('Error message:', error.cause.formatMessage()); + * } + * ``` + */ +export class TonApiParsingError extends Error { + readonly type = 'parsing_error' as const; + readonly parsingType: string; + readonly originalCause: unknown; + + constructor(parsingType: string, message: string, cause: unknown) { + super(message); + this.name = 'TonApiParsingError'; + this.parsingType = parsingType; + this.originalCause = cause; + + // Maintain proper stack trace in V8 + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } + + /** + * Format error message for end users + * Centralized formatting - change here to change everywhere + */ + formatMessage(): string { + return `SDK parsing error [${this.parsingType}]: ${this.message}`; + } +} diff --git a/packages/client/src/templates/http-client.ejs b/packages/client/src/templates/http-client.ejs index 0e43a5a..e319333 100644 --- a/packages/client/src/templates/http-client.ejs +++ b/packages/client/src/templates/http-client.ejs @@ -228,29 +228,6 @@ class HttpClient { } } - public setApiKey = (apiKey: string | undefined) => { - if (apiKey) { - this.baseApiParams = { - ...this.baseApiParams, - headers: { - ...(this.baseApiParams.headers || {}), - Authorization: `Bearer ${apiKey}` - } as HeadersInit - }; - } else { - const headers = { ...(this.baseApiParams.headers || {}) } as Record; - delete headers['Authorization']; - this.baseApiParams = { - ...this.baseApiParams, - headers: headers as HeadersInit - }; - } - } - - public setCustomFetch = (fetchFn: typeof fetch | undefined) => { - this.providedFetch = fetchFn ?? null; - } - public request = async ({ body, secure, diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index 50d8a54..e5f7902 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -1,3 +1,5 @@ +<%~ includeFile('./errors.ejs') %> + type ComponentRef = keyof typeof components; export interface TonApiError { @@ -33,7 +35,12 @@ function camelToSnake(camel: string): string { } function cellParse(src: string): Cell { - return Cell.fromHex(src); + try { + return Cell.fromHex(src); + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('Cell', msg, e); + } } function parseHexToBigInt(str: string) { @@ -48,7 +55,19 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis const data = prepareResponseData(obj, orSchema); return { data, error: null } as Result; } catch (parseError: unknown) { - // SDK parsing error (Address.parse, Cell.fromHex, BigInt conversion, etc.) + // Handle our custom parsing errors with centralized formatting + if (parseError instanceof TonApiParsingError) { + return { + data: null, + error: { + message: parseError.formatMessage(), // ✨ Centralized formatting! + type: 'parsing_error', + cause: parseError + } + } as Result; + } + + // Handle other errors (should not happen, but defensive) const message = parseError instanceof Error ? `SDK parsing error: ${parseError.message}` : 'SDK parsing error: Unknown error'; @@ -147,7 +166,12 @@ function prepareResponseData(obj: any, orSchema?: any): U { } else if (schema) { if (schema.type === "string") { if (schema.format === "address") { - return Address.parse(obj as string) as U; + try { + return Address.parse(obj as string) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('Address', msg, e); + } } if (schema.format === "cell") { @@ -155,18 +179,33 @@ function prepareResponseData(obj: any, orSchema?: any): U { } if (schema['x-js-format'] === 'bigint') { + try { return BigInt(obj as string) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('BigInt', msg, e); + } } // maybe not used if (schema.format === "cell-base64") { - return obj && (Cell.fromBase64(obj as string) as U); + try { + return obj && (Cell.fromBase64(obj as string) as U); + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('Cell', msg, e); + } } } if (schema.type === "integer") { if (schema['x-js-format'] === "bigint") { - return BigInt(obj as number) as U; + try { + return BigInt(obj as number) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('BigInt', msg, e); + } } return Number(obj as number) as U; @@ -206,7 +245,11 @@ function prepareResponseData(obj: any, orSchema?: any): U { type: "nan" } as U; default: - throw new Error(`Unknown tuple item type: ${obj.type}`); + throw new TonApiParsingError( + 'TupleItem', + `Unknown tuple item type: ${obj.type}`, + obj + ); } } } diff --git a/tests/client/client.test.ts b/tests/client/client.test.ts index 26c17a5..890fb91 100644 --- a/tests/client/client.test.ts +++ b/tests/client/client.test.ts @@ -1,13 +1,13 @@ -import { initClient, status, getAccounts as getAccountsOp, getAccountPublicKey } from '@ton-api/client'; +import { initClient, status, getAccounts as getAccountsOp, getAccountPublicKey, getAccount } from '@ton-api/client'; import { initTa, useTa, useTaWithApiKey } from './utils/client'; import { Address } from '@ton/core'; import { getAccounts } from './__mock__/services'; -import { vi, test, expect, afterEach, beforeEach } from 'vitest'; +import { vi, test, expect, afterEach, beforeEach, describe } from 'vitest'; import { mockFetch } from './utils/mockFetch'; beforeEach(() => { - // Reset to default client before each test initTa(); + vi.restoreAllMocks(); }); afterEach(() => { @@ -170,3 +170,326 @@ test('Client response type for schema outside component (with snake_case)', asyn expect(data).toBeDefined(); expect(data?.publicKey).toBe('9544d2cccdd17e06e27f14fd531f803378d27f64710fd6aadc418c53d0660ec6'); }); + +describe('Client initialization and configuration', () => { + beforeEach(() => { + vi.restoreAllMocks(); + }); + + test('initClient() should initialize the singleton client', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'test-key-123' + }); + + await status(); + + expect(fetchSpy).toHaveBeenCalledWith( + expect.stringContaining('https://tonapi.io'), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer test-key-123' + }) + }) + ); +}); + +test('initClient() should reinitialize the singleton client', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + // First initialization + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'first-key' + }); + + // Second initialization should replace the client + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'second-key' + }); + + await status(); + + expect(fetchSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer second-key' + }) + }) + ); +}); + +test('reinitializing client should update apiKey', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'initial-key' + }); + + // Reinitialize with new apiKey + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'updated-key' + }); + + await status(); + + expect(fetchSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer updated-key' + }) + }) + ); +}); + +test('reinitializing client should update baseUrl', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + initClient({ + baseUrl: 'https://tonapi.io' + }); + + // Reinitialize with new baseUrl + initClient({ + baseUrl: 'https://testnet.tonapi.io' + }); + + await status(); + + expect(fetchSpy).toHaveBeenCalledWith( + expect.stringContaining('https://testnet.tonapi.io'), + expect.anything() + ); +}); + +test('reinitializing client should update custom fetch', async () => { + const mockResponse = { + rest_online: true, + indexing_latency: 8 + }; + + const firstFetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify(mockResponse), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }) + ); + + const secondFetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify(mockResponse), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }) + ); + + initClient({ + baseUrl: 'https://tonapi.io', + fetch: firstFetch + }); + + // Reinitialize with secondFetch + initClient({ + baseUrl: 'https://tonapi.io', + fetch: secondFetch + }); + + await status(); + + expect(firstFetch).not.toHaveBeenCalled(); + expect(secondFetch).toHaveBeenCalled(); +}); + +test('operations should share the same singleton client', async () => { + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'shared-key' + }); + + // First operation + const statusSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + await status(); + + expect(statusSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer shared-key' + }) + }) + ); + + // Second operation should use the same client with same apiKey + const accountSpy = mockFetch({ balance: '1000000000' }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + await getAccount(address); + + expect(accountSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer shared-key' + }) + }) + ); +}); + +test('lazy initialization: operations should work without explicit initClient()', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + // Don't call initClient(), just use the operation directly + // This should create a default client + const { data, error } = await status(); + + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(fetchSpy).toHaveBeenCalled(); +}); + +test('reinitializing without apiKey should remove Authorization header', async () => { + const fetchSpy = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ rest_online: true, indexing_latency: 8 }), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }) + ); + + vi.spyOn(global, 'fetch').mockImplementation(fetchSpy); + + // First, init with apiKey + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'will-be-removed' + }); + + await status(); + + let callArgs = fetchSpy.mock.calls[0]; + let headers = callArgs?.[1]?.headers as Record; + expect(headers?.Authorization).toBe('Bearer will-be-removed'); + + fetchSpy.mockClear(); + + // Reinitialize without apiKey + initClient({ + baseUrl: 'https://tonapi.io' + }); + + await status(); + + callArgs = fetchSpy.mock.calls[0]; + headers = callArgs?.[1]?.headers as Record; + + // Check that Authorization header is not present after reinitialization + expect(headers).toBeDefined(); + expect(headers?.Authorization).toBeUndefined(); + expect(headers?.['x-tonapi-client']).toBeDefined(); // Should still have other headers +}); + +test('configuration changes should persist across multiple requests', async () => { + initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'persistent-key' + }); + + // Make first request + const firstSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + await status(); + + expect(firstSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer persistent-key' + }) + }) + ); + + // Make second request - should still use the same configuration + const secondSpy = mockFetch({ rest_online: true, indexing_latency: 8 }); + + await status(); + + expect(secondSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + Authorization: 'Bearer persistent-key' + }) + }) + ); +}); + +test('initClient() with baseApiParams should set custom headers', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + initClient({ + baseUrl: 'https://tonapi.io', + baseApiParams: { + headers: { + 'Custom-Header': 'custom-value', + 'Another-Header': 'another-value' + } + } + }); + + await status(); + + expect(fetchSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + 'Custom-Header': 'custom-value', + 'Another-Header': 'another-value' + }) + }) + ); +}); + + test('initClient() should work with minimal configuration', async () => { + const fetchSpy = mockFetch({ + rest_online: true, + indexing_latency: 8 + }); + + initClient(); + const { data, error } = await status(); + + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(fetchSpy).toHaveBeenCalled(); + }); +}); diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index 8a6fd41..e45c253 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -1,6 +1,7 @@ -import { status } from '@ton-api/client'; +import { status, getAccount, execGetMethodForBlockchainAccount, TonApiParsingError } from '@ton-api/client'; +import { Address } from '@ton/core'; import { initTa } from './utils/client'; -import { vi, test, expect, afterEach, beforeEach } from 'vitest'; +import { vi, test, expect, beforeEach, describe } from 'vitest'; import { mockFetch } from './utils/mockFetch'; beforeEach(() => { @@ -136,3 +137,328 @@ test('should handle a JSON error response without an error field', async () => { expect(error?.status).toBe(400); expect(error?.type).toBe('http_error'); }); + +describe('Parsing validation errors', () => { + describe('Invalid Address parsing', () => { + test('should return parsing_error for invalid address string', async () => { + // Mock API response with invalid address + mockFetch({ + address: 'invalid-address-string', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(data).toBeNull(); + expect(error).toBeDefined(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Address]'); + expect(error?.cause).toBeDefined(); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Address'); + } + }); + + test('should return parsing_error for empty address string', async () => { + mockFetch({ + address: '', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(data).toBeNull(); + expect(error).toBeDefined(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Address]'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Address'); + } + }); + + test('should return parsing_error for malformed address format', async () => { + mockFetch({ + address: 'EQ_this_is_not_valid_base64', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(data).toBeNull(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Address]'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Address'); + } + }); + }); + + describe('Invalid Cell parsing', () => { + test('should return parsing_error for invalid cell hex string', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'invalid-hex-string' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeNull(); + expect(error).toBeDefined(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Cell]'); + expect(error?.cause).toBeDefined(); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Cell'); + } + }); + + test('should return parsing_error for invalid cell BoC format', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'b5ee9c72410101010007' // Valid hex but invalid BoC format + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeNull(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Cell]'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Cell'); + } + }); + + test('should return parsing_error for odd length hex string', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'abc' // 3 characters - odd length + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeNull(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Cell]'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Cell'); + } + }); + + test('should return parsing_error for non-hex characters in cell', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'zzxxyyaabbcc' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeNull(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Cell]'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Cell'); + } + }); + }); + + describe('Invalid BigInt parsing', () => { + test('should return parsing_error for non-numeric BigInt string', async () => { + mockFetch({ + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: 'not-a-number', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(data).toBeNull(); + expect(error).toBeDefined(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [BigInt]'); + expect(error?.cause).toBeDefined(); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('BigInt'); + } + }); + + test('should return parsing_error for invalid BigInt format', async () => { + mockFetch({ + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '123.456', // Decimal number, BigInt doesn't support decimals + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(data).toBeNull(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [BigInt]'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('BigInt'); + } + }); + + test('should handle empty string in BigInt field (converts to 0n)', async () => { + // Note: BigInt('') actually returns 0n, not an error + mockFetch({ + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + // Empty string converts to 0n without error + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.balance).toBe(0n); + }); + }); + + describe('Invalid TupleItem type', () => { + test('should return parsing_error for unknown tuple item type', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'unknown_type', + value: 'some-value' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeNull(); + expect(error).toBeDefined(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [TupleItem]'); + expect(error?.message).toContain('Unknown tuple item type'); + expect(error?.cause).toBeDefined(); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('TupleItem'); + } + }); + + test('should return parsing_error for invalid type in nested tuple', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'tuple', + tuple: [ + { + type: 'invalid_nested_type', + value: 'test' + } + ] + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeNull(); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [TupleItem]'); + expect(error?.message).toContain('Unknown tuple item type'); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('TupleItem'); + } + }); + }); + + describe('Error structure validation', () => { + test('parsing_error should have correct structure', async () => { + mockFetch({ + address: 'invalid', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(data).toBeNull(); + expect(error).toBeDefined(); + + // Verify error structure + expect(error).toHaveProperty('message'); + expect(error).toHaveProperty('type'); + expect(error).toHaveProperty('cause'); + + expect(typeof error?.message).toBe('string'); + expect(error?.type).toBe('parsing_error'); + expect(error?.message).toContain('SDK parsing error [Address]'); + }); + + test('cause should contain the original error', async () => { + mockFetch({ + address: 'invalid-address', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(error?.cause).toBeDefined(); + expect(error?.cause).toBeInstanceOf(TonApiParsingError); + if (error?.cause instanceof TonApiParsingError) { + expect(error.cause.parsingType).toBe('Address'); + } + }); + }); +}); diff --git a/tests/client/utils/client.ts b/tests/client/utils/client.ts index 552edec..d40aa9d 100644 --- a/tests/client/utils/client.ts +++ b/tests/client/utils/client.ts @@ -1,4 +1,4 @@ -import { initClient, updateClient } from '@ton-api/client'; +import { initClient } from '@ton-api/client'; const baseUrl = 'https://tonapi.io'; @@ -17,12 +17,15 @@ export function initTaWithApiKey() { // Switch to client without API key export function useTa() { - updateClient({ apiKey: undefined }); + initClient({ baseUrl }); } // Switch to client with API key export function useTaWithApiKey() { - updateClient({ apiKey: 'TEST_API_KEY' }); + initClient({ + baseUrl, + apiKey: 'TEST_API_KEY' + }); } // Initialize default client on module load From df0c0d987d32e1a8ede5e609c969c9a88d5b9fcb Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Wed, 12 Nov 2025 01:06:05 +0400 Subject: [PATCH 05/27] refactor: enhance error handling in TonAPI SDK - Introduced a base abstract error class `TonApiErrorAbstract` for consistent error management across the SDK. - Refactored existing error classes (`TonApiHttpError`, `TonApiNetworkError`, `TonApiParsingError`, `TonApiUnknownError`) to extend from the new base class, improving code organization and maintainability. - Updated error constructors to include detailed messages and original causes for better debugging. - Enhanced the `prepareResponse` function to handle errors more effectively, returning instances of the new error classes directly. - Updated tests to validate the new error handling structure and ensure comprehensive coverage for various error scenarios. --- packages/client/src/client.ts | 276 +++++++++++------ packages/client/src/templates/errors.ejs | 179 +++++++++-- packages/client/src/templates/utils.ejs | 93 ++---- tests/client/errors.test.ts | 365 +++++++++++++++++------ tests/client/parse-cell.test.ts | 30 +- tests/client/parse-tuple.test.ts | 42 ++- tests/client/services.test.ts | 50 +++- 7 files changed, 737 insertions(+), 298 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 8b91fcb..fcc71ec 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -5783,28 +5783,17 @@ const components = { } }; /** - * Single error class for all parsing errors in the TonAPI SDK - * - * Provides type-safe error handling with centralized message formatting. - * Use parsingType property to distinguish between Address, Cell, BigInt, and TupleItem errors. - * - * @example - * ```typescript - * if (error.cause instanceof TonApiParsingError) { - * console.log('Parsing type:', error.cause.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' - * console.log('Error message:', error.cause.formatMessage()); - * } - * ``` + * Base abstract error class for all TonAPI SDK errors + * Not exported - only used for internal inheritance */ -export class TonApiParsingError extends Error { - readonly type = 'parsing_error' as const; - readonly parsingType: string; - readonly originalCause: unknown; +abstract class TonApiErrorAbstract extends Error { + abstract readonly type: string; + readonly message: string; + readonly originalCause?: unknown; - constructor(parsingType: string, message: string, cause: unknown) { + constructor(message: string, cause?: unknown) { super(message); - this.name = 'TonApiParsingError'; - this.parsingType = parsingType; + this.message = message; this.originalCause = cause; // Maintain proper stack trace in V8 @@ -5812,38 +5801,173 @@ export class TonApiParsingError extends Error { Error.captureStackTrace(this, this.constructor); } } +} - /** - * Format error message for end users - * Centralized formatting - change here to change everywhere - */ - formatMessage(): string { - return `SDK parsing error [${this.parsingType}]: ${this.message}`; +/** + * HTTP error returned by TonAPI + * Represents 4xx and 5xx responses from the API + * + * @example + * ```typescript + * if (error instanceof TonApiHttpError) { + * console.log('HTTP Status:', error.status); + * console.log('Error code:', error.code); + * console.log('Request URL:', error.url); + * } + * ``` + */ +export class TonApiHttpError extends TonApiErrorAbstract { + readonly type = 'http_error' as const; + readonly status: number; + readonly code?: string; + readonly url: string; + + constructor(status: number, message: string, url: string, code?: string, cause?: unknown) { + const formattedMessage = code + ? `HTTP ${status} [${code}]: ${message}` + : `HTTP ${status}: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiHttpError'; + this.status = status; + this.url = url; + this.code = code; } } -type ComponentRef = keyof typeof components; - -export interface TonApiError { - /** Human-readable error message */ - message: string; +/** + * Network error (connection failed, timeout, etc.) + * Thrown when the HTTP request itself fails, not when it returns an error response + * + * @example + * ```typescript + * if (error instanceof TonApiNetworkError) { + * console.log('Network error:', error.message); + * console.log('Cause:', error.originalCause); + * } + * ``` + */ +export class TonApiNetworkError extends TonApiErrorAbstract { + readonly type = 'network_error' as const; - /** Error type for programmatic handling */ - type?: 'http_error' | 'network_error' | 'parsing_error'; + constructor(message: string, cause: unknown) { + const formattedMessage = `Network error: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiNetworkError'; + } +} - /** Error code from API response (for http_error) */ - code?: string; +/** + * Parsing error for Address, Cell, BigInt, or TupleItem + * Thrown when SDK fails to parse data returned from TonAPI + * + * @example + * ```typescript + * if (error instanceof TonApiParsingError) { + * console.log('Parsing type:', error.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' + * console.log('Error message:', error.message); + * console.log('Original response:', error.response); + * } + * ``` + */ +export class TonApiParsingError extends TonApiErrorAbstract { + readonly type = 'parsing_error' as const; + readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem'; + readonly response: unknown; + + constructor( + parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem', + message: string, + cause: unknown, + response: unknown + ) { + const formattedMessage = `SDK parsing error [${parsingType}]: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiParsingError'; + this.parsingType = parsingType; + this.response = response; - /** HTTP status code (for http_error) */ - status?: number; + // Log to console with request to report issue + console.error( + `[TonAPI SDK] Parsing error occurred. This might be a bug in the SDK.\n` + + `Please report this issue at: https://github.com/tonkeeper/tonapi-js/issues\n` + + `Error details:`, + { + type: parsingType, + message: message, + response: response + } + ); + } +} - /** Request URL for debugging */ - url?: string; +/** + * Unknown error type + * Thrown when an error occurs that doesn't fit other categories + * + * @example + * ```typescript + * if (error instanceof TonApiUnknownError) { + * console.log('Unknown error:', error.message); + * console.log('Cause:', error.originalCause); + * } + * ``` + */ +export class TonApiUnknownError extends TonApiErrorAbstract { + readonly type = 'unknown_error' as const; - /** Original error/response for advanced debugging */ - cause?: unknown; + constructor(message: string, cause: unknown) { + const formattedMessage = `Unknown error: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiUnknownError'; + } } +/** + * Union type of all possible TonAPI errors + * Use this type in Result and for error handling + * + * @example + * ```typescript + * const { data, error } = await getAccount(address); + * + * if (error) { + * // Type-safe instanceof checks + * if (error instanceof TonApiHttpError) { + * console.log(`HTTP ${error.status}: ${error.message}`); + * } else if (error instanceof TonApiNetworkError) { + * console.log(`Network error: ${error.message}`); + * } else if (error instanceof TonApiParsingError) { + * console.log(`Parsing ${error.parsingType} failed: ${error.message}`); + * } else if (error instanceof TonApiUnknownError) { + * console.log(`Unknown error: ${error.message}`); + * } + * + * // Or use discriminated union + * switch (error.type) { + * case 'http_error': + * console.log(error.status, error.code, error.url); + * break; + * case 'network_error': + * console.log(error.originalCause); + * break; + * case 'parsing_error': + * console.log(error.parsingType); + * break; + * case 'unknown_error': + * console.log(error.originalCause); + * break; + * } + * } + * ``` + */ +export type TonApiError = + | TonApiHttpError + | TonApiNetworkError + | TonApiParsingError + | TonApiUnknownError; + +type ComponentRef = keyof typeof components; + export type Result = { data: T; error: null } | { data: null; error: TonApiError }; function snakeToCamel(snakeCaseString: string): string { @@ -5854,12 +5978,12 @@ function camelToSnake(camel: string): string { return camel.replace(/([A-Z])/g, match => `_${match.toLowerCase()}`); } -function cellParse(src: string): Cell { +function cellParse(src: string, response: unknown): Cell { try { return Cell.fromHex(src); } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('Cell', msg, e); + throw new TonApiParsingError('Cell', msg, e, response); } } @@ -5872,18 +5996,14 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis .then(obj => { try { // Parse and transform response data - const data = prepareResponseData(obj, orSchema); + const data = prepareResponseData(obj, orSchema, obj); return { data, error: null } as Result; } catch (parseError: unknown) { - // Handle our custom parsing errors with centralized formatting + // Handle our custom parsing errors - return the error instance directly if (parseError instanceof TonApiParsingError) { return { data: null, - error: { - message: parseError.formatMessage(), // ✨ Centralized formatting! - type: 'parsing_error', - cause: parseError - } + error: parseError } as Result; } @@ -5893,13 +6013,10 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis ? `SDK parsing error: ${parseError.message}` : 'SDK parsing error: Unknown error'; + // Create a generic parsing error for unexpected cases return { data: null, - error: { - message, - type: 'parsing_error', - cause: parseError - } + error: new TonApiParsingError('Cell', message, parseError, obj) } as Result; } }) @@ -5908,18 +6025,14 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis if (response instanceof Error) { return { data: null, - error: { - message: response.message || 'Network error', - type: 'network_error', - cause: response - } + error: new TonApiNetworkError(response.message || 'Network error', response) } as Result; } // HTTP error with response if (response && typeof response === 'object' && response.status !== undefined) { const status = response.status; - const url = response.url; + const url = response.url || ''; let message: string = 'Request failed'; let code: string | undefined = undefined; @@ -5940,36 +6053,28 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis return { data: null, - error: { - message, - type: 'http_error', - code, - status, - url, - cause: response - } + error: new TonApiHttpError(status, message, url, code, response) } as Result; } // Unknown error return { data: null, - error: { - message: 'Unknown error occurred', - cause: response - } + error: new TonApiUnknownError('Unknown error occurred', response) } as Result; }); } -function prepareResponseData(obj: any, orSchema?: any): U { +function prepareResponseData(obj: any, orSchema?: any, originalResponse: unknown = obj): U { const ref = (orSchema && orSchema.$ref) as ComponentRef | undefined; const schema = ref ? components[ref] : orSchema; if (Array.isArray(obj)) { const itemSchema = schema && schema.items; - return obj.map(item => prepareResponseData(item, itemSchema)) as unknown as U; + return obj.map(item => + prepareResponseData(item, itemSchema, originalResponse) + ) as unknown as U; } else if (schema) { if (schema.type === 'string') { if (schema.format === 'address') { @@ -5977,12 +6082,12 @@ function prepareResponseData(obj: any, orSchema?: any): U { return Address.parse(obj as string) as U; } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('Address', msg, e); + throw new TonApiParsingError('Address', msg, e, originalResponse); } } if (schema.format === 'cell') { - return obj && (cellParse(obj as string) as U); + return obj && (cellParse(obj as string, originalResponse) as U); } if (schema['x-js-format'] === 'bigint') { @@ -5990,7 +6095,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return BigInt(obj as string) as U; } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('BigInt', msg, e); + throw new TonApiParsingError('BigInt', msg, e, originalResponse); } } @@ -6000,7 +6105,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return obj && (Cell.fromBase64(obj as string) as U); } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('Cell', msg, e); + throw new TonApiParsingError('Cell', msg, e, originalResponse); } } } @@ -6011,7 +6116,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return BigInt(obj as number) as U; } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('BigInt', msg, e); + throw new TonApiParsingError('BigInt', msg, e, originalResponse); } } @@ -6026,7 +6131,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return { type: 'tuple', items: obj.tuple.map((item: any) => - prepareResponseData(item, itemSchema) + prepareResponseData(item, itemSchema, originalResponse) ) } as U; case 'num': @@ -6037,12 +6142,12 @@ function prepareResponseData(obj: any, orSchema?: any): U { case 'cell': return { type: 'cell', - cell: cellParse(obj.cell as string) + cell: cellParse(obj.cell as string, originalResponse) } as U; case 'slice': return { type: 'slice', - slice: cellParse(obj.slice as string) + slice: cellParse(obj.slice as string, originalResponse) } as U; case 'null': return { @@ -6056,7 +6161,8 @@ function prepareResponseData(obj: any, orSchema?: any): U { throw new TonApiParsingError( 'TupleItem', `Unknown tuple item type: ${obj.type}`, - obj + obj, + originalResponse ); } } @@ -6069,7 +6175,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { (acc, key) => { if (!schema) { // If schema is undefined, do not convert keys - acc[key] = prepareResponseData(obj[key], undefined); + acc[key] = prepareResponseData(obj[key], undefined, originalResponse); return acc; } @@ -6082,7 +6188,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { // Use the specific property schema or the additionalProperties schema const propertySchema = isDefinedProperty ? objSchema : schema.additionalProperties; - acc[camelCaseKey] = prepareResponseData(obj[key], propertySchema); + acc[camelCaseKey] = prepareResponseData(obj[key], propertySchema, originalResponse); return acc; }, {} as Record diff --git a/packages/client/src/templates/errors.ejs b/packages/client/src/templates/errors.ejs index fff5d94..22b3787 100644 --- a/packages/client/src/templates/errors.ejs +++ b/packages/client/src/templates/errors.ejs @@ -1,39 +1,174 @@ /** - * Single error class for all parsing errors in the TonAPI SDK + * Base abstract error class for all TonAPI SDK errors + * Not exported - only used for internal inheritance + */ +abstract class TonApiErrorAbstract extends Error { + abstract readonly type: string; + readonly message: string; + readonly originalCause?: unknown; + + constructor(message: string, cause?: unknown) { + super(message); + this.message = message; + this.originalCause = cause; + + // Maintain proper stack trace in V8 + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } +} + +/** + * HTTP error returned by TonAPI + * Represents 4xx and 5xx responses from the API * - * Provides type-safe error handling with centralized message formatting. - * Use parsingType property to distinguish between Address, Cell, BigInt, and TupleItem errors. + * @example + * ```typescript + * if (error instanceof TonApiHttpError) { + * console.log('HTTP Status:', error.status); + * console.log('Error code:', error.code); + * console.log('Request URL:', error.url); + * } + * ``` + */ +export class TonApiHttpError extends TonApiErrorAbstract { + readonly type = 'http_error' as const; + readonly status: number; + readonly code?: string; + readonly url: string; + + constructor(status: number, message: string, url: string, code?: string, cause?: unknown) { + const formattedMessage = code + ? `HTTP ${status} [${code}]: ${message}` + : `HTTP ${status}: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiHttpError'; + this.status = status; + this.url = url; + this.code = code; + } +} + +/** + * Network error (connection failed, timeout, etc.) + * Thrown when the HTTP request itself fails, not when it returns an error response * * @example * ```typescript - * if (error.cause instanceof TonApiParsingError) { - * console.log('Parsing type:', error.cause.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' - * console.log('Error message:', error.cause.formatMessage()); + * if (error instanceof TonApiNetworkError) { + * console.log('Network error:', error.message); + * console.log('Cause:', error.originalCause); * } * ``` */ -export class TonApiParsingError extends Error { +export class TonApiNetworkError extends TonApiErrorAbstract { + readonly type = 'network_error' as const; + + constructor(message: string, cause: unknown) { + const formattedMessage = `Network error: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiNetworkError'; + } +} + +/** + * Parsing error for Address, Cell, BigInt, or TupleItem + * Thrown when SDK fails to parse data returned from TonAPI + * + * @example + * ```typescript + * if (error instanceof TonApiParsingError) { + * console.log('Parsing type:', error.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' + * console.log('Error message:', error.message); + * console.log('Original response:', error.response); + * } + * ``` + */ +export class TonApiParsingError extends TonApiErrorAbstract { readonly type = 'parsing_error' as const; - readonly parsingType: string; - readonly originalCause: unknown; + readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem'; + readonly response: unknown; - constructor(parsingType: string, message: string, cause: unknown) { - super(message); + constructor(parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem', message: string, cause: unknown, response: unknown) { + const formattedMessage = `SDK parsing error [${parsingType}]: ${message}`; + super(formattedMessage, cause); this.name = 'TonApiParsingError'; this.parsingType = parsingType; - this.originalCause = cause; + this.response = response; - // Maintain proper stack trace in V8 - if (Error.captureStackTrace) { - Error.captureStackTrace(this, this.constructor); - } + // Log to console with request to report issue + console.error( + `[TonAPI SDK] Parsing error occurred. This might be a bug in the SDK.\n` + + `Please report this issue at: https://github.com/tonkeeper/tonapi-js/issues\n` + + `Error details:`, + { + type: parsingType, + message: message, + response: response + } + ); } +} - /** - * Format error message for end users - * Centralized formatting - change here to change everywhere - */ - formatMessage(): string { - return `SDK parsing error [${this.parsingType}]: ${this.message}`; +/** + * Unknown error type + * Thrown when an error occurs that doesn't fit other categories + * + * @example + * ```typescript + * if (error instanceof TonApiUnknownError) { + * console.log('Unknown error:', error.message); + * console.log('Cause:', error.originalCause); + * } + * ``` + */ +export class TonApiUnknownError extends TonApiErrorAbstract { + readonly type = 'unknown_error' as const; + + constructor(message: string, cause: unknown) { + const formattedMessage = `Unknown error: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiUnknownError'; } } + +/** + * Union type of all possible TonAPI errors + * Use this type in Result and for error handling + * + * @example + * ```typescript + * const { data, error } = await getAccount(address); + * + * if (error) { + * // Type-safe instanceof checks + * if (error instanceof TonApiHttpError) { + * console.log(`HTTP ${error.status}: ${error.message}`); + * } else if (error instanceof TonApiNetworkError) { + * console.log(`Network error: ${error.message}`); + * } else if (error instanceof TonApiParsingError) { + * console.log(`Parsing ${error.parsingType} failed: ${error.message}`); + * } else if (error instanceof TonApiUnknownError) { + * console.log(`Unknown error: ${error.message}`); + * } + * + * // Or use discriminated union + * switch (error.type) { + * case 'http_error': + * console.log(error.status, error.code, error.url); + * break; + * case 'network_error': + * console.log(error.originalCause); + * break; + * case 'parsing_error': + * console.log(error.parsingType); + * break; + * case 'unknown_error': + * console.log(error.originalCause); + * break; + * } + * } + * ``` + */ +export type TonApiError = TonApiHttpError | TonApiNetworkError | TonApiParsingError | TonApiUnknownError; diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index e5f7902..180e71a 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -2,26 +2,6 @@ type ComponentRef = keyof typeof components; -export interface TonApiError { - /** Human-readable error message */ - message: string; - - /** Error type for programmatic handling */ - type?: 'http_error' | 'network_error' | 'parsing_error'; - - /** Error code from API response (for http_error) */ - code?: string; - - /** HTTP status code (for http_error) */ - status?: number; - - /** Request URL for debugging */ - url?: string; - - /** Original error/response for advanced debugging */ - cause?: unknown; -} - export type Result = | { data: T; error: null } | { data: null; error: TonApiError }; @@ -34,12 +14,12 @@ function camelToSnake(camel: string): string { return camel.replace(/([A-Z])/g, (match) => `_${match.toLowerCase()}`); } -function cellParse(src: string): Cell { +function cellParse(src: string, response: unknown): Cell { try { return Cell.fromHex(src); } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('Cell', msg, e); + throw new TonApiParsingError('Cell', msg, e, response); } } @@ -52,18 +32,14 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis .then(obj => { try { // Parse and transform response data - const data = prepareResponseData(obj, orSchema); + const data = prepareResponseData(obj, orSchema, obj); return { data, error: null } as Result; } catch (parseError: unknown) { - // Handle our custom parsing errors with centralized formatting + // Handle our custom parsing errors - return the error instance directly if (parseError instanceof TonApiParsingError) { return { data: null, - error: { - message: parseError.formatMessage(), // ✨ Centralized formatting! - type: 'parsing_error', - cause: parseError - } + error: parseError } as Result; } @@ -72,13 +48,10 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis ? `SDK parsing error: ${parseError.message}` : 'SDK parsing error: Unknown error'; + // Create a generic parsing error for unexpected cases return { data: null, - error: { - message, - type: 'parsing_error', - cause: parseError - } + error: new TonApiParsingError('Cell', message, parseError, obj) } as Result; } }) @@ -87,18 +60,17 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis if (response instanceof Error) { return { data: null, - error: { - message: response.message || 'Network error', - type: 'network_error', - cause: response - } + error: new TonApiNetworkError( + response.message || 'Network error', + response + ) } as Result; } // HTTP error with response if (response && typeof response === 'object' && response.status !== undefined) { const status = response.status; - const url = response.url; + const url = response.url || ''; let message: string = 'Request failed'; let code: string | undefined = undefined; @@ -119,29 +91,19 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis return { data: null, - error: { - message, - type: 'http_error', - code, - status, - url, - cause: response - } + error: new TonApiHttpError(status, message, url, code, response) } as Result; } // Unknown error return { data: null, - error: { - message: 'Unknown error occurred', - cause: response - } + error: new TonApiUnknownError('Unknown error occurred', response) } as Result; }); } -function prepareResponseData(obj: any, orSchema?: any): U { +function prepareResponseData(obj: any, orSchema?: any, originalResponse: unknown = obj): U { const ref = (orSchema && orSchema.$ref) as ComponentRef | undefined; const schema = ref ? components[ref] : orSchema; @@ -162,7 +124,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { if (Array.isArray(obj)) { const itemSchema = schema && schema.items; - return obj.map((item) => prepareResponseData(item, itemSchema)) as unknown as U; + return obj.map((item) => prepareResponseData(item, itemSchema, originalResponse)) as unknown as U; } else if (schema) { if (schema.type === "string") { if (schema.format === "address") { @@ -170,12 +132,12 @@ function prepareResponseData(obj: any, orSchema?: any): U { return Address.parse(obj as string) as U; } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('Address', msg, e); + throw new TonApiParsingError('Address', msg, e, originalResponse); } } if (schema.format === "cell") { - return obj && (cellParse(obj as string) as U); + return obj && (cellParse(obj as string, originalResponse) as U); } if (schema['x-js-format'] === 'bigint') { @@ -183,7 +145,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return BigInt(obj as string) as U; } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('BigInt', msg, e); + throw new TonApiParsingError('BigInt', msg, e, originalResponse); } } @@ -193,7 +155,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return obj && (Cell.fromBase64(obj as string) as U); } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('Cell', msg, e); + throw new TonApiParsingError('Cell', msg, e, originalResponse); } } } @@ -204,7 +166,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { return BigInt(obj as number) as U; } catch (e) { const msg = e instanceof Error ? e.message : String(e); - throw new TonApiParsingError('BigInt', msg, e); + throw new TonApiParsingError('BigInt', msg, e, originalResponse); } } @@ -219,7 +181,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { const itemSchema = schema.properties.tuple.items; return { type: "tuple", - items: obj.tuple.map((item: any) => prepareResponseData(item, itemSchema)) + items: obj.tuple.map((item: any) => prepareResponseData(item, itemSchema, originalResponse)) } as U; case "num": return { @@ -229,12 +191,12 @@ function prepareResponseData(obj: any, orSchema?: any): U { case "cell": return { type: "cell", - cell: cellParse(obj.cell as string) + cell: cellParse(obj.cell as string, originalResponse) } as U; case "slice": return { type: "slice", - slice: cellParse(obj.slice as string) + slice: cellParse(obj.slice as string, originalResponse) } as U; case "null": return { @@ -248,7 +210,8 @@ function prepareResponseData(obj: any, orSchema?: any): U { throw new TonApiParsingError( 'TupleItem', `Unknown tuple item type: ${obj.type}`, - obj + obj, + originalResponse ); } } @@ -261,7 +224,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { (acc, key) => { if (!schema) { // If schema is undefined, do not convert keys - acc[key] = prepareResponseData(obj[key], undefined); + acc[key] = prepareResponseData(obj[key], undefined, originalResponse); return acc; } @@ -274,7 +237,7 @@ function prepareResponseData(obj: any, orSchema?: any): U { // Use the specific property schema or the additionalProperties schema const propertySchema = isDefinedProperty ? objSchema : schema.additionalProperties; - acc[camelCaseKey] = prepareResponseData(obj[key], propertySchema); + acc[camelCaseKey] = prepareResponseData(obj[key], propertySchema, originalResponse); return acc; }, {} as Record diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index e45c253..5ed0d7c 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -1,4 +1,4 @@ -import { status, getAccount, execGetMethodForBlockchainAccount, TonApiParsingError } from '@ton-api/client'; +import { status, getAccount, execGetMethodForBlockchainAccount, TonApiParsingError, TonApiHttpError, TonApiNetworkError, TonApiUnknownError } from '@ton-api/client'; import { Address } from '@ton/core'; import { initTa } from './utils/client'; import { vi, test, expect, beforeEach, describe } from 'vitest'; @@ -16,6 +16,23 @@ const createJsonResponse = (data: any, status = 200) => { }); }; +// Type assertion helpers for safe error testing +function assertIsHttpError(error: unknown): asserts error is TonApiHttpError { + expect(error).toBeInstanceOf(TonApiHttpError); +} + +function assertIsNetworkError(error: unknown): asserts error is TonApiNetworkError { + expect(error).toBeInstanceOf(TonApiNetworkError); +} + +function assertIsParsingError(error: unknown): asserts error is TonApiParsingError { + expect(error).toBeInstanceOf(TonApiParsingError); +} + +function assertIsUnknownError(error: unknown): asserts error is TonApiUnknownError { + expect(error).toBeInstanceOf(TonApiUnknownError); +} + test('should return a successful response with JSON data', async () => { const mockData = { status: 'ok', uptime: 123456 }; const fetchSpy = mockFetch(mockData); @@ -36,9 +53,10 @@ test('should handle an error response with a JSON message', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Invalid request'); - expect(error?.status).toBe(400); - expect(error?.type).toBe('http_error'); + assertIsHttpError(error); + expect(error.message).toBe('HTTP 400: Invalid request'); + expect(error.status).toBe(400); + expect(error.type).toBe('http_error'); }); test('should handle an error response with a string message', async () => { @@ -47,9 +65,10 @@ test('should handle an error response with a string message', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Simple error message'); - expect(error?.status).toBe(500); - expect(error?.type).toBe('http_error'); + assertIsHttpError(error); + expect(error.message).toBe('HTTP 500: Simple error message'); + expect(error.status).toBe(500); + expect(error.type).toBe('http_error'); }); test('should include cause in the error object', async () => { @@ -59,8 +78,8 @@ test('should include cause in the error object', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Invalid request'); - expect(error?.cause).toBeDefined(); + expect(error?.message).toBe('HTTP 400: Invalid request'); + expect(error).toBeDefined(); expect(error?.type).toBe('http_error'); }); @@ -71,7 +90,7 @@ test('should handle an error response without JSON', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Network failure'); + expect(error?.message).toBe('Network error: Network failure'); expect(error?.type).toBe('network_error'); }); @@ -85,9 +104,10 @@ test('should handle an error response with invalid JSON', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toContain('Failed to parse error response'); - expect(error?.status).toBe(400); - expect(error?.type).toBe('http_error'); + assertIsHttpError(error); + expect(error.message).toContain('Failed to parse error response'); + expect(error.status).toBe(400); + expect(error.type).toBe('http_error'); }); test('should handle an unknown error type (object)', async () => { @@ -96,7 +116,9 @@ test('should handle an unknown error type (object)', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Unknown error occurred'); + expect(error).toBeInstanceOf(TonApiUnknownError); + expect(error?.message).toBe('Unknown error: Unknown error occurred'); + expect(error?.type).toBe('unknown_error'); }); test('should handle an unknown error type (string)', async () => { @@ -105,7 +127,9 @@ test('should handle an unknown error type (string)', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Unknown error occurred'); + expect(error).toBeInstanceOf(TonApiUnknownError); + expect(error?.message).toBe('Unknown error: Unknown error occurred'); + expect(error?.type).toBe('unknown_error'); }); test('should handle null as an error', async () => { @@ -114,7 +138,9 @@ test('should handle null as an error', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Unknown error occurred'); + expect(error).toBeInstanceOf(TonApiUnknownError); + expect(error?.message).toBe('Unknown error: Unknown error occurred'); + expect(error?.type).toBe('unknown_error'); }); test('should handle undefined as an error', async () => { @@ -123,7 +149,9 @@ test('should handle undefined as an error', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Unknown error occurred'); + expect(error).toBeInstanceOf(TonApiUnknownError); + expect(error?.message).toBe('Unknown error: Unknown error occurred'); + expect(error?.type).toBe('unknown_error'); }); test('should handle a JSON error response without an error field', async () => { @@ -133,9 +161,10 @@ test('should handle a JSON error response without an error field', async () => { const { data, error } = await status(); expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error?.message).toBe('Some error without error field'); - expect(error?.status).toBe(400); - expect(error?.type).toBe('http_error'); + assertIsHttpError(error); + expect(error.message).toBe('HTTP 400: Some error without error field'); + expect(error.status).toBe(400); + expect(error.type).toBe('http_error'); }); describe('Parsing validation errors', () => { @@ -153,13 +182,8 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error).toBeDefined(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Address]'); - expect(error?.cause).toBeDefined(); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Address'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); }); test('should return parsing_error for empty address string', async () => { @@ -174,12 +198,8 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error).toBeDefined(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Address]'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Address'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); }); test('should return parsing_error for malformed address format', async () => { @@ -193,12 +213,8 @@ describe('Parsing validation errors', () => { const { data, error } = await getAccount(validAddress); expect(data).toBeNull(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Address]'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Address'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); }); }); @@ -220,13 +236,8 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error).toBeDefined(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Cell]'); - expect(error?.cause).toBeDefined(); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Cell'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); }); test('should return parsing_error for invalid cell BoC format', async () => { @@ -245,12 +256,8 @@ describe('Parsing validation errors', () => { const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); expect(data).toBeNull(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Cell]'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Cell'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); }); test('should return parsing_error for odd length hex string', async () => { @@ -269,12 +276,8 @@ describe('Parsing validation errors', () => { const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); expect(data).toBeNull(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Cell]'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Cell'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); }); test('should return parsing_error for non-hex characters in cell', async () => { @@ -293,12 +296,8 @@ describe('Parsing validation errors', () => { const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); expect(data).toBeNull(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Cell]'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Cell'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); }); }); @@ -315,13 +314,9 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error).toBeDefined(); - expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [BigInt]'); - expect(error?.cause).toBeDefined(); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('BigInt'); - } + expect(error).toBeDefined(); + assertIsParsingError(error); + expect(error.parsingType).toBe('BigInt'); }); test('should return parsing_error for invalid BigInt format', async () => { @@ -336,10 +331,10 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [BigInt]'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('BigInt'); + + assertIsParsingError(error); + if (error instanceof TonApiParsingError) { + expect(error.parsingType).toBe('BigInt'); } }); @@ -380,13 +375,10 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error).toBeDefined(); expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [TupleItem]'); + expect(error?.message).toContain('Unknown tuple item type'); - expect(error?.cause).toBeDefined(); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('TupleItem'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('TupleItem'); }); test('should return parsing_error for invalid type in nested tuple', async () => { @@ -411,12 +403,10 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [TupleItem]'); + expect(error?.message).toContain('Unknown tuple item type'); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('TupleItem'); - } + assertIsParsingError(error); + expect(error.parsingType).toBe('TupleItem'); }); }); @@ -433,18 +423,18 @@ describe('Parsing validation errors', () => { expect(data).toBeNull(); expect(error).toBeDefined(); + assertIsParsingError(error); // Verify error structure expect(error).toHaveProperty('message'); expect(error).toHaveProperty('type'); - expect(error).toHaveProperty('cause'); + expect(error).toHaveProperty('originalCause'); expect(typeof error?.message).toBe('string'); expect(error?.type).toBe('parsing_error'); - expect(error?.message).toContain('SDK parsing error [Address]'); }); - test('cause should contain the original error', async () => { + test('originalCause should contain the original error', async () => { mockFetch({ address: 'invalid-address', balance: '1000000000', @@ -454,11 +444,198 @@ describe('Parsing validation errors', () => { const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); const { data, error } = await getAccount(validAddress); - expect(error?.cause).toBeDefined(); - expect(error?.cause).toBeInstanceOf(TonApiParsingError); - if (error?.cause instanceof TonApiParsingError) { - expect(error.cause.parsingType).toBe('Address'); - } + assertIsParsingError(error); + expect(error.originalCause).toBeDefined(); + expect(error.parsingType).toBe('Address'); }); }); }); + +describe('instanceof error checks', () => { + test('TonApiHttpError instanceof check', async () => { + const mockError = { error: 'Not found' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 404)); + + const { data, error } = await status(); + + expect(error).not.toBeNull(); + expect(error).toBeInstanceOf(TonApiHttpError); + + // TypeScript should narrow the type + if (error instanceof TonApiHttpError) { + expect(error.status).toBe(404); + expect(error.message).toBe('HTTP 404: Not found'); + expect(error.type).toBe('http_error'); + expect(error.url).toBeDefined(); + } + }); + + test('TonApiNetworkError instanceof check', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Network connection failed')); + + const { data, error } = await status(); + + expect(error).not.toBeNull(); + assertIsNetworkError(error); + expect(error.message).toBe('Network error: Network connection failed'); + expect(error.type).toBe('network_error'); + expect(error.originalCause).toBeInstanceOf(Error); + }); + + test('TonApiParsingError instanceof check', async () => { + mockFetch({ + address: 'INVALID_ADDRESS_FORMAT', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount(validAddress); + + expect(error).not.toBeNull(); + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); + expect(error.type).toBe('parsing_error'); + expect(error.message).toBeDefined(); + expect(error.originalCause).toBeDefined(); + }); + + test('TonApiUnknownError instanceof check', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce({ something: 'unexpected' } as any); + + const { data, error } = await status(); + + expect(error).not.toBeNull(); + assertIsUnknownError(error); + expect(error.message).toBe('Unknown error: Unknown error occurred'); + expect(error.type).toBe('unknown_error'); + expect(error.originalCause).toBeDefined(); + }); +}); + +describe('discriminated union error handling', () => { + test('should handle errors using switch/case on type', async () => { + const mockError = { error: 'Bad request', code: 'INVALID_PARAMS' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); + + const { data, error } = await status(); + + expect(error).not.toBeNull(); + expect(error).toBeDefined(); + + if (!error) { + expect.fail('Expected error to be defined'); + return; + } + + switch (error.type) { + case 'http_error': + expect(error.status).toBe(400); + expect(error.code).toBe('INVALID_PARAMS'); + expect(error.url).toBeDefined(); + break; + case 'network_error': + expect(error.originalCause).toBeDefined(); + break; + case 'parsing_error': + expect(error.parsingType).toBeDefined(); + break; + case 'unknown_error': + expect(error.originalCause).toBeDefined(); + break; + default: + expect.fail(`Unexpected error type: ${(error as any).type}`); + } + }); + + test('should handle network error using switch/case', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Timeout')); + + const { data, error } = await status(); + + expect(error).not.toBeNull(); + expect(error).toBeDefined(); + + if (!error) { + expect.fail('Expected error to be defined'); + return; + } + + switch (error.type) { + case 'http_error': + expect.fail('Expected network error, got HTTP error'); + break; + case 'network_error': + expect(error.message).toBe('Network error: Timeout'); + break; + case 'parsing_error': + expect.fail('Expected network error, got parsing error'); + break; + case 'unknown_error': + expect.fail('Expected network error, got unknown error'); + break; + default: + expect.fail(`Unexpected error type: ${(error as any).type}`); + } + }); + + test('all error types have message property', async () => { + // Test HTTP error + const mockError = { error: 'Server error' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 500)); + + const { error: httpError } = await status(); + assertIsHttpError(httpError); + expect(httpError.message).toBe('HTTP 500: Server error'); + + // Test Network error + vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Connection failed')); + const { error: networkError } = await status(); + assertIsNetworkError(networkError); + expect(networkError.message).toBe('Network error: Connection failed'); + + // Test Parsing error + mockFetch({ address: 'INVALID', balance: '0', status: 'active' }); + const { error: parsingError } = await getAccount(Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y')); + assertIsParsingError(parsingError); + expect(parsingError.message).toBeDefined(); + + // Test Unknown error + vi.spyOn(global, 'fetch').mockRejectedValueOnce('something weird' as any); + const { error: unknownError } = await status(); + assertIsUnknownError(unknownError); + expect(unknownError.message).toBe('Unknown error: Unknown error occurred'); + }); + + test('should handle unknown error using switch/case', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce({ weird: 'object' } as any); + + const { data, error } = await status(); + + expect(error).not.toBeNull(); + expect(error).toBeDefined(); + + if (!error) { + expect.fail('Expected error to be defined'); + return; + } + + switch (error.type) { + case 'http_error': + expect.fail('Expected unknown error, got HTTP error'); + break; + case 'network_error': + expect.fail('Expected unknown error, got network error'); + break; + case 'parsing_error': + expect.fail('Expected unknown error, got parsing error'); + break; + case 'unknown_error': + expect(error.message).toBe('Unknown error: Unknown error occurred'); + expect(error.originalCause).toBeDefined(); + break; + default: + expect.fail(`Unexpected error type: ${(error as any).type}`); + } + }); +}); diff --git a/tests/client/parse-cell.test.ts b/tests/client/parse-cell.test.ts index c99fc64..970e810 100644 --- a/tests/client/parse-cell.test.ts +++ b/tests/client/parse-cell.test.ts @@ -1,7 +1,14 @@ import { Address, Cell, TupleItem, TupleItemCell } from '@ton/core'; -import { getBlockchainRawAccount as getBlockchainRawAccountOp, sendBlockchainMessage, execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountOp } from '@ton-api/client'; +import { + getBlockchainRawAccount, + sendBlockchainMessage, + execGetMethodForBlockchainAccount +} from '@ton-api/client'; import { initTa } from './utils/client'; -import { execGetMethodForBlockchainAccount, getBlockchainRawAccount } from './__mock__/cell'; +import { + execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountMock, + getBlockchainRawAccount as getBlockchainRawAccountMock +} from './__mock__/cell'; import { mockFetch } from './utils/mockFetch'; import { test, expect, afterEach, beforeEach, vi } from 'vitest'; @@ -14,11 +21,11 @@ afterEach(() => { }); test('Cell hex in response test', async () => { - mockFetch(getBlockchainRawAccount); + mockFetch(getBlockchainRawAccountMock); const addressString = '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'; const addressObject = Address.parse(addressString); - const { data, error } = await getBlockchainRawAccountOp(addressObject); + const { data, error } = await getBlockchainRawAccount(addressObject); expect(error).toBeNull(); expect(data).toBeDefined(); @@ -58,11 +65,11 @@ const guardCell = (item: TupleItem): item is TupleItemCell => { }; test('Cell base64 in response test', async () => { - mockFetch(execGetMethodForBlockchainAccount); + mockFetch(execGetMethodForBlockchainAccountMock); const addressString = 'EQDW6q4sRqQwNCmW4qwUpeFSU1Xhd6l3xwJ6jjknBPzxKNtT'; const addressObject = Address.parse(addressString); - const { data, error } = await execGetMethodForBlockchainAccountOp( + const { data, error } = await execGetMethodForBlockchainAccount( addressObject, 'royalty_params' ); @@ -75,10 +82,11 @@ test('Cell base64 in response test', async () => { expect(cellTupleItem).toBeDefined(); expect(cellTupleItem?.type).toBe('cell'); - if (cellTupleItem && guardCell(cellTupleItem)) { - expect(cellTupleItem.cell).toBeDefined(); - expect(cellTupleItem.cell).toBeInstanceOf(Cell); - } else { - throw new Error('Cell guard failed'); + if (!cellTupleItem || !guardCell(cellTupleItem)) { + expect.fail('Expected cellTupleItem to be a cell type'); + return; } + + expect(cellTupleItem.cell).toBeDefined(); + expect(cellTupleItem.cell).toBeInstanceOf(Cell); }); diff --git a/tests/client/parse-tuple.test.ts b/tests/client/parse-tuple.test.ts index f6658b8..0386d74 100644 --- a/tests/client/parse-tuple.test.ts +++ b/tests/client/parse-tuple.test.ts @@ -36,20 +36,32 @@ test('Tuple test', async () => { expect(highLevelTuple?.type).toBeDefined(); expect(highLevelTuple?.type).toBe('tuple'); - if (highLevelTuple && guardTuple(highLevelTuple)) { - expect(highLevelTuple.items).toBeDefined(); - - const secondLevelTupleFirst = highLevelTuple.items[0]; - expect(secondLevelTupleFirst).toBeDefined(); - expect(secondLevelTupleFirst?.type).toBeDefined(); - expect(secondLevelTupleFirst?.type).toBe('tuple'); - - if (secondLevelTupleFirst && guardTuple(secondLevelTupleFirst)) { - expect(secondLevelTupleFirst.items).toBeDefined(); - } else { - throw new Error('Second Tuple guard failed'); - } - } else { - throw new Error('First Tuple guard failed'); + if (!highLevelTuple) { + expect.fail('Expected highLevelTuple to be defined'); + return; } + + if (!guardTuple(highLevelTuple)) { + expect.fail('Expected highLevelTuple to be a tuple type'); + return; + } + + expect(highLevelTuple.items).toBeDefined(); + + const secondLevelTupleFirst = highLevelTuple.items[0]; + expect(secondLevelTupleFirst).toBeDefined(); + expect(secondLevelTupleFirst?.type).toBeDefined(); + expect(secondLevelTupleFirst?.type).toBe('tuple'); + + if (!secondLevelTupleFirst) { + expect.fail('Expected secondLevelTupleFirst to be defined'); + return; + } + + if (!guardTuple(secondLevelTupleFirst)) { + expect.fail('Expected secondLevelTupleFirst to be a tuple type'); + return; + } + + expect(secondLevelTupleFirst.items).toBeDefined(); }); diff --git a/tests/client/services.test.ts b/tests/client/services.test.ts index 0f9752f..84d07c0 100644 --- a/tests/client/services.test.ts +++ b/tests/client/services.test.ts @@ -1,7 +1,7 @@ import { Address } from '@ton/core'; -import { getChartRates as getChartRatesOp, getRates as getRatesOp } from '@ton-api/client'; +import { getChartRates, getRates as getRatesOp } from '@ton-api/client'; import { initTa } from './utils/client'; -import { getChartRates, getRates } from './__mock__/services'; +import { getChartRates as getChartRatesMock, getRates as getRatesMock } from './__mock__/services'; import { mockFetch } from './utils/mockFetch'; import { test, expect, afterEach, beforeEach, vi } from 'vitest'; @@ -14,11 +14,11 @@ afterEach(() => { }); test('getChartRates, should correct parse array in pair', async () => { - mockFetch(getChartRates); + mockFetch(getChartRatesMock); const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; const addressObject = Address.parse(addressString); - const { data, error } = await getChartRatesOp({ + const { data, error } = await getChartRates({ token: addressObject, currency: 'rub' }); @@ -43,7 +43,7 @@ test('getChartRates, should correct parse array in pair', async () => { }); test('getRates, additionalProperties should be not convert to camelCase', async () => { - mockFetch(getRates); + mockFetch(getRatesMock); const { data, error } = await getRatesOp({ tokens: ['TON,TOKEN_WITH_UNDERSCORE'], @@ -58,7 +58,7 @@ test('getRates, additionalProperties should be not convert to camelCase', async }); test('getRates, explode in params should be matter', async () => { - const fetchSpy = mockFetch(getRates); + const fetchSpy = mockFetch(getRatesMock); // const fetchSpy = vi.spyOn(global, 'fetch').mockResolvedValueOnce( // new Response(JSON.stringify(getRates), { // status: 200, @@ -78,3 +78,41 @@ test('getRates, explode in params should be matter', async () => { expect(searchParams.get('tokens')).toBe('TON,EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); expect(searchParams.get('currencies')).toBe('USD,EUR'); }); + +test('getChartRates, should serialize Address object to string', async () => { + const fetchSpy = mockFetch(getChartRatesMock); + + const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; + const addressObject = Address.parse(addressString); + + await getChartRates({ + token: addressObject, + currency: 'usd' + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const url = fetchSpy.mock.calls[0]?.[0] as string; + const searchParams = new URL(url).searchParams; + + // Address object should be serialized to its string representation + expect(searchParams.get('token')).toBe(addressString); + expect(searchParams.get('currency')).toBe('usd'); +}); + +test('getChartRates, should accept string token directly', async () => { + const fetchSpy = mockFetch(getChartRatesMock); + + const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; + + await getChartRates({ + token: addressString, + currency: 'usd' + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const url = fetchSpy.mock.calls[0]?.[0] as string; + const searchParams = new URL(url).searchParams; + + expect(searchParams.get('token')).toBe(addressString); + expect(searchParams.get('currency')).toBe('usd'); +}); From bdc7c8ec83e756b21759e5179eda49c83a75531d Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Wed, 12 Nov 2025 01:41:20 +0400 Subject: [PATCH 06/27] refactor: update TonApi client initialization and method usage - Replaced instances of `TonApiClient` with `initClient` for improved client initialization across multiple example files. - Updated method calls to use the new flat API structure, enhancing code clarity and maintainability. - Adjusted error handling in examples to align with the new response pattern, ensuring consistent error management. - Refactored tests to remove dependencies on `TonApiClient`, streamlining the testing process. --- examples/emulate.ts | 10 +- examples/gasless.ts | 20 ++-- examples/send-jetton.ts | 8 +- examples/send-ton.ts | 6 +- examples/track-transaction.ts | 10 +- packages/ton-adapter/src/tonapi-adapter.ts | 102 +++++++++++---------- tests/adapters/migratebeta.test.ts | 45 +++------ tests/adapters/readme.test.ts | 10 +- tests/adapters/utils/clients.ts | 7 +- tests/adapters/utils/contract.ts | 7 +- 10 files changed, 110 insertions(+), 115 deletions(-) diff --git a/examples/emulate.ts b/examples/emulate.ts index 5db4161..357c50c 100644 --- a/examples/emulate.ts +++ b/examples/emulate.ts @@ -9,10 +9,10 @@ import { storeMessage } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto'; -import { TonApiClient } from '@ton-api/client'; +import { initClient, getAccountSeqno, getAccountPublicKey, emulateMessageToTrace } from '@ton-api/client'; // if you need to send lots of requests in parallel, make sure you use a tonapi token. -const ta = new TonApiClient({ +initClient({ baseUrl: 'https://tonapi.io', apiKey: 'YOUR_API_KEY' }); @@ -22,13 +22,13 @@ const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9Y const recipientAddress = Address.parse('UQDNzlh0XSZdb5_Qrlx5QjyZHVAO74v5oMeVVrtF_5Vt1rIt'); // Get wallet's seqno and public key -const { data: seqnoData, error: seqnoError } = await ta.wallet.getAccountSeqno(senderAddress); +const { data: seqnoData, error: seqnoError } = await getAccountSeqno(senderAddress); if (seqnoError) { console.error('Error getting seqno:', seqnoError.message); process.exit(1); } -const { data: publicKeyData, error: publicKeyError } = await ta.accounts.getAccountPublicKey(senderAddress); +const { data: publicKeyData, error: publicKeyError } = await getAccountPublicKey(senderAddress); if (publicKeyError) { console.error('Error getting public key:', publicKeyError.message); process.exit(1); @@ -85,7 +85,7 @@ const bocExternalMessage = beginCell() .endCell(); // Emulate transaction -const { data: emulateTrace, error: emulateError } = await ta.emulation.emulateMessageToTrace( +const { data: emulateTrace, error: emulateError } = await emulateMessageToTrace( { boc: bocExternalMessage }, { ignore_signature_check: true } // Ignore signature for execute message from other account ); diff --git a/examples/gasless.ts b/examples/gasless.ts index e0f9113..c789bc4 100644 --- a/examples/gasless.ts +++ b/examples/gasless.ts @@ -11,16 +11,16 @@ import { storeMessageRelaxed } from '@ton/ton'; -import { TonApiClient } from '@ton-api/client'; +import { initClient, execGetMethodForBlockchainAccount, gaslessConfig, gaslessEstimate, gaslessSend, TonApiHttpError } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; // if you need to send lots of requests in parallel, make sure you use a tonapi token. -const ta = new TonApiClient({ +initClient({ baseUrl: 'https://tonapi.io', apiKey: 'YOUR_API_KEY' }); -const provider = new ContractAdapter(ta); +const provider = new ContractAdapter(); const OP_CODES = { TK_RELAYER_FEE: 0x878da6e3, @@ -48,7 +48,7 @@ const contract = provider.open(wallet); console.log('Wallet address:', wallet.address.toString()); const { data: jettonWalletAddressResult, error: getWalletError } = - await ta.blockchain.execGetMethodForBlockchainAccount(usdtMaster, 'get_wallet_address', { + await execGetMethodForBlockchainAccount(usdtMaster, 'get_wallet_address', { args: [wallet.address.toRawString()] }); @@ -92,7 +92,7 @@ const messageToEstimate = beginCell() // we send a single message containing a transfer from our wallet to a desired destination. // as a result of estimation, TonAPI returns a list of messages that we need to sign. // the first message is a fee transfer to the relay address, the second message is our original transfer. -const { data: params, error: estimateError } = await ta.gasless.gaslessEstimate(usdtMaster, { +const { data: params, error: estimateError } = await gaslessEstimate(usdtMaster, { walletAddress: wallet.address, walletPublicKey: keyPair.publicKey.toString('hex'), messages: [{ boc: messageToEstimate }] @@ -136,19 +136,23 @@ const extMessage = beginCell() .endCell(); // Send a gasless transfer -const { data: sendResult, error: sendError } = await ta.gasless.gaslessSend({ +const { data: sendResult, error: sendError } = await gaslessSend({ walletPublicKey: keyPair.publicKey.toString('hex'), boc: extMessage }); if (sendError) { - console.error('Error sending gasless transfer:', sendError.message, sendError.status); + if (sendError instanceof TonApiHttpError) { + console.error('Error sending gasless transfer:', sendError.message, 'Status:', sendError.status); + } else { + console.error('Error sending gasless transfer:', sendError.message); + } } else { console.log('A gasless transfer sent!'); } async function printConfigAndReturnRelayAddress(): Promise
{ - const { data: cfg, error } = await ta.gasless.gaslessConfig(); + const { data: cfg, error } = await gaslessConfig(); if (error) { console.error('Error getting gasless config:', error.message); diff --git a/examples/send-jetton.ts b/examples/send-jetton.ts index 1e126f5..c7527a3 100644 --- a/examples/send-jetton.ts +++ b/examples/send-jetton.ts @@ -1,17 +1,17 @@ import { WalletContractV5R1, Address, beginCell, internal, toNano, SendMode } from '@ton/ton'; import { mnemonicToPrivateKey } from '@ton/crypto'; -import { TonApiClient } from '@ton-api/client'; +import { initClient, execGetMethodForBlockchainAccount } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; // Initialize TonApi client -const ta = new TonApiClient({ +initClient({ baseUrl: 'https://tonapi.io', apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access }); // Create an adapter for interacting with contracts -const adapter = new ContractAdapter(ta); +const adapter = new ContractAdapter(); // Base gas fee required for the jetton transfer const BASE_JETTON_SEND_AMOUNT = toNano(0.05); @@ -32,7 +32,7 @@ const wallet = WalletContractV5R1.create({ workchain: 0, publicKey: keyPair.publ const contract = adapter.open(wallet); // Open the wallet contract using the adapter // Get the sender's jetton wallet address from the jetton master contract -const { data: jettonWalletAddressResult, error } = await ta.blockchain.execGetMethodForBlockchainAccount( +const { data: jettonWalletAddressResult, error } = await execGetMethodForBlockchainAccount( jettonMaster, 'get_wallet_address', { args: [wallet.address.toRawString()] } diff --git a/examples/send-ton.ts b/examples/send-ton.ts index 8602fa9..06d8e9f 100644 --- a/examples/send-ton.ts +++ b/examples/send-ton.ts @@ -1,16 +1,16 @@ import { WalletContractV5R1, internal, SendMode } from '@ton/ton'; import { mnemonicToPrivateKey } from '@ton/crypto'; -import { TonApiClient } from '@ton-api/client'; +import { initClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; // Initialize TonApi client -const ta = new TonApiClient({ +initClient({ baseUrl: 'https://tonapi.io', apiKey: 'YOUR_API_KEY', // Optional, improves limits and access }); // Create an adapter for interacting with contracts -const adapter = new ContractAdapter(ta); +const adapter = new ContractAdapter(); // Convert mnemonic phrase to a private key const mnemonics = 'word1 word2 ...'.split(' '); // Replace with your mnemonic phrase diff --git a/examples/track-transaction.ts b/examples/track-transaction.ts index 085bf74..1d79f74 100644 --- a/examples/track-transaction.ts +++ b/examples/track-transaction.ts @@ -1,7 +1,7 @@ import { WalletContractV5R1 } from '@ton/ton'; import { Address, beginCell, internal, external, SendMode, Message } from '@ton/core'; import { mnemonicToPrivateKey } from '@ton/crypto'; -import { TonApiClient } from '@ton-api/client'; +import { initClient, getBlockchainTransactionByMessageHash } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; import { Cell, loadMessage } from '@ton/core'; @@ -36,11 +36,11 @@ function normalizeHash(message: Message, normalizeExternal: boolean): Buffer { // ---------------------------------------------------------- // Step 1: Initialize the TonAPI client -const ta = new TonApiClient({ +initClient({ baseUrl: 'https://tonapi.io' // apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access }); -const adapter = new ContractAdapter(ta); +const adapter = new ContractAdapter(); // Step 2: Define the wallet and recipient addresses const destination = Address.parse('EQCKWpx7cNMpvmcN5ObM5lLUZHZRFKqYA4xmw9jOry0ZsF9M'); @@ -83,7 +83,7 @@ console.log('Manual Message Hash:', manualExtMessageHash.toString('hex')); await delay(10000); // Step 8: Retrieve the resulting transaction using the normalized external hash -const manualTransaction = await ta.blockchain.getBlockchainTransactionByMessageHash( +const manualTransaction = await getBlockchainTransactionByMessageHash( manualExtMessageHash.toString('hex') ); console.log('Manual Transaction Details:', manualTransaction); @@ -106,7 +106,7 @@ const bocExtMessageHash = normalizeHash(bocMessage, true); console.log('BOC Message Hash:', bocExtMessageHash.toString('hex')); // Step 3: Retrieve the transaction using that hash -const bocTransaction = await ta.blockchain.getBlockchainTransactionByMessageHash( +const bocTransaction = await getBlockchainTransactionByMessageHash( bocExtMessageHash.toString('hex') ); console.log('BOC Transaction Details:', bocTransaction); diff --git a/packages/ton-adapter/src/tonapi-adapter.ts b/packages/ton-adapter/src/tonapi-adapter.ts index ddfa5b8..7d619be 100644 --- a/packages/ton-adapter/src/tonapi-adapter.ts +++ b/packages/ton-adapter/src/tonapi-adapter.ts @@ -19,24 +19,25 @@ import { } from '@ton/core'; import { AccountStatus as TonApiAccountStatus, - TonApiClient, + getBlockchainRawAccount, + execGetMethodForBlockchainAccount, + getAccount, + sendBlockchainMessage, + getBlockchainAccountTransactions, BlockchainRawAccount, - AccountStatus + AccountStatus, + TonApiHttpError } from '@ton-api/client'; import { Buffer } from 'buffer'; export class ContractAdapter { - constructor(private readonly tonapi: TonApiClient) {} - /** * Open smart contract * @param contract contract * @returns opened contract */ open(contract: T) { - return openContract(contract, args => - createProvider(this.tonapi, args.address, args.init) - ); + return openContract(contract, args => createProvider(args.address, args.init)); } /** @@ -46,14 +47,13 @@ export class ContractAdapter { * @returns provider */ provider(address: Address, init?: { code?: Cell; data?: Cell } | null) { - return createProvider(this.tonapi, address, init ? init : null); + return createProvider(address, init ? init : null); } } -type LoclaBlockchainRawAccount = Partial> & +type LocalBlockchainRawAccount = Partial> & Omit; function createProvider( - tonapi: TonApiClient, address: Address, init: { code?: Cell | null; data?: Cell | null } | null ): ContractProvider { @@ -61,15 +61,21 @@ function createProvider( async getState(): Promise { // Load state const { data: accountData, error: accountError } = - await tonapi.blockchain.getBlockchainRawAccount(address); + await getBlockchainRawAccount(address); - let account: LoclaBlockchainRawAccount; + let account: LocalBlockchainRawAccount; if (accountError) { - if (accountError.message !== 'entity not found') { - throw new Error(`Account request failed: ${accountError.message}`, accountError); + // Check if it's a 404 error (account not found) + const accountNotExists = + accountError instanceof TonApiHttpError && accountError.status === 404; + + if (!accountNotExists) { + throw new Error(`Account request failed`, { + cause: accountError + }); } - const mockResult: LoclaBlockchainRawAccount = { + const mockResult: LocalBlockchainRawAccount = { address: address, balance: 0n, lastTransactionLt: undefined, @@ -99,7 +105,7 @@ function createProvider( const stateGetters: Record< TonApiAccountStatus, - (account: LoclaBlockchainRawAccount) => ContractState['state'] + (account: LocalBlockchainRawAccount) => ContractState['state'] > = { active: account => ({ type: 'active', @@ -139,14 +145,14 @@ function createProvider( throw new Error('Tuples as get parameters are not supported by tonapi'); } - const { data: result, error } = await tonapi.blockchain.execGetMethodForBlockchainAccount( - address, - name, - { args: args.map(TupleItemToTonapiString) } - ); + const { data: result, error } = await execGetMethodForBlockchainAccount(address, name, { + args: args.map(TupleItemToTonapiString) + }); if (error) { - throw new Error(`Get method execution failed: ${error.message}`, error); + throw new Error(`Get method execution failed`, { + cause: error + }); } return { @@ -157,12 +163,13 @@ function createProvider( // Resolve init let neededInit: { code?: Cell | null; data?: Cell | null } | null = null; if (init) { - const { data: accountInfo, error: accountError } = - await tonapi.accounts.getAccount(address); - if (accountError) { - throw new Error(`Failed to get account info: ${accountError.message}`, accountError); + const { data, error } = await getAccount(address); + if (error) { + throw new Error(`Failed to get account info`, { + cause: error + }); } - if (accountInfo.status !== 'active') { + if (data.status !== 'active') { neededInit = init; } } @@ -175,21 +182,25 @@ function createProvider( }); const boc = beginCell().store(storeMessage(ext)).endCell(); - const { error: sendError } = await tonapi.blockchain.sendBlockchainMessage({ boc }); - if (sendError) { - throw new Error(`Failed to send blockchain message: ${sendError.message}`, sendError); + const { error } = await sendBlockchainMessage({ boc }); + + if (error) { + throw new Error(`Failed to send blockchain message`, { + cause: error + }); } }, async internal(via, message) { // Resolve init let neededInit: { code?: Cell | null; data?: Cell | null } | null = null; if (init) { - const { data: accountInfo, error: accountError } = - await tonapi.accounts.getAccount(address); - if (accountError) { - throw new Error(`Failed to get account info: ${accountError.message}`, accountError); + const { data, error } = await getAccount(address); + if (error) { + throw new Error(`Failed to get account info`, { + cause: error + }); } - if (accountInfo.status !== 'active') { + if (data.status !== 'active') { neededInit = init; } } @@ -227,9 +238,7 @@ function createProvider( }); }, open(contract: T): OpenedContract { - return openContract(contract, params => - createProvider(tonapi, params.address, params.init) - ); + return openContract(contract, params => createProvider(params.address, params.init)); }, async getTransactions( address: Address, @@ -238,19 +247,18 @@ function createProvider( limit?: number ): Promise { console.info( - 'hash param in getTransactions action ignored, beacause not supported', + 'hash param in getTransactions action ignored, because not supported', hash.toString('hex') ); - const { data: result, error } = await tonapi.blockchain.getBlockchainAccountTransactions( - address, - { - before_lt: lt + 1n, - limit - } - ); + const { data: result, error } = await getBlockchainAccountTransactions(address, { + before_lt: lt + 1n, + limit + }); if (error) { - throw new Error(`Failed to get account transactions: ${error.message}`, error); + throw new Error(`Failed to get account transactions`, { + cause: error + }); } return result.transactions.map(transaction => diff --git a/tests/adapters/migratebeta.test.ts b/tests/adapters/migratebeta.test.ts index 8392486..67c0ade 100644 --- a/tests/adapters/migratebeta.test.ts +++ b/tests/adapters/migratebeta.test.ts @@ -1,8 +1,8 @@ import { Address, Contract, ContractProvider, OpenedContract } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey, KeyPair } from '@ton/crypto'; import { ContractAdapter } from '@ton-api/ton-adapter'; -import { TonApiClient } from '@ton-api/client'; -import { test, beforeAll } from 'vitest'; +import { initClient } from '@ton-api/client'; +import { test, beforeAll, expect } from 'vitest'; class NftItem implements Contract { constructor(public readonly address: Address) {} @@ -23,15 +23,15 @@ class NftItem implements Contract { } } -// Initialize the ton API client -const ta = new TonApiClient({ +// Initialize the ton API client using flat API +initClient({ baseUrl: 'https://tonapi.io' // apiKey: 'your-api-key', }); // Create an adapter -const contractAdapter = new ContractAdapter(ta); -let keyPair: KeyPair; // eslint-disable-line +const contractAdapter = new ContractAdapter(); +let keyPair: KeyPair; let contract: OpenedContract; beforeAll(async () => { @@ -39,37 +39,18 @@ beforeAll(async () => { const mnemonics = await mnemonicNew(); keyPair = await mnemonicToPrivateKey(mnemonics); - // const customPublickKey = 'bada76699b7e8417300355f5c355dff83a96c5c9cd43df0dd9bc23c72e78bc0e'; - // const buffer = Buffer.from(customPublickKey, 'hex'); const wallet = NftItem.createFromAddress( Address.parse('UQAs87W4yJHlF8mt29ocA4agnMrLsOP69jC1HPyBUjJay7Mg') ); contract = contractAdapter.open(wallet); }); -// Use tonapi adapter to work with any @ton/ton smart-contracts wrappers - -test('Wallet contract', async () => { - // Get balance - // const balance: bigint = await contract.getBalance(); - // expect(balance).toBe(0n); - // expect(typeof balance === 'bigint').toBe(true); - - // get transactions - const data = await contract.getData(); // eslint-disable-line - // console.log(data); - - // Create a transfer - // const seqno: number = await contract.getSeqno(); - // await contract.sendTransfer({ - // seqno, - // secretKey: keyPair.secretKey, - // messages: [internal({ - // value: '0.001', - // to: 'EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N', - // body: 'Hello world', - // })] - // }); +test.skip('NftItem contract getData', async () => { + const data = await contract.getData(); + expect(data).toBeDefined(); }); -test('Wallet contract', async () => {}); +test.skip('NftItem contract getTransactions', async () => { + const transactions = await contract.getTransactions(); + expect(Array.isArray(transactions)).toBe(true); +}); diff --git a/tests/adapters/readme.test.ts b/tests/adapters/readme.test.ts index 8b88588..fd74343 100644 --- a/tests/adapters/readme.test.ts +++ b/tests/adapters/readme.test.ts @@ -1,17 +1,17 @@ import { SendMode, WalletContractV5R1, internal } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto'; -import { TonApiClient } from '@ton-api/client'; +import { initClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; import { test, vi, expect } from 'vitest'; // Initialize TonApi client -const ta = new TonApiClient({ +initClient({ baseUrl: 'https://tonapi.io' // apiKey: 'YOUR_API_KEY' // Uncomment this line and set your API key }); // Create an adapter -const adapter = new ContractAdapter(ta); +const adapter = new ContractAdapter(); // Create and use a wallet contract async function main() { @@ -49,8 +49,8 @@ test('Readme example', async () => { await main(); - // Check if console.log was called twice - expect(consoleLogMock).toHaveBeenCalledTimes(1); + // Check if console.log was called (Balance + error from sendTransfer) + expect(consoleLogMock.mock.calls.length).toBeGreaterThanOrEqual(1); // Check the first console.log call (Balance) expect(consoleLogMock.mock.calls[0]).toEqual(['Balance:', '0']); diff --git a/tests/adapters/utils/clients.ts b/tests/adapters/utils/clients.ts index a590e0f..0676bb4 100644 --- a/tests/adapters/utils/clients.ts +++ b/tests/adapters/utils/clients.ts @@ -1,15 +1,16 @@ import { TonClient } from '@ton/ton'; import { ContractAdapter } from '@ton-api/ton-adapter'; -import { TonApiClient } from '@ton-api/client'; +import { initClient } from '@ton-api/client'; require('dotenv').config(); -const ta = new TonApiClient({ +// Initialize client for TonApi +initClient({ baseUrl: 'https://tonapi.io', apiKey: process.env.TONAPI_API_KEY }); -export const clientTonApi = new ContractAdapter(ta); // Create an adapter +export const clientTonApi = new ContractAdapter(); // Create an adapter export const getTonCenterClient = () => { if (!process.env.TONCENTER_API_KEY) { diff --git a/tests/adapters/utils/contract.ts b/tests/adapters/utils/contract.ts index 97cf6f9..434853c 100644 --- a/tests/adapters/utils/contract.ts +++ b/tests/adapters/utils/contract.ts @@ -1,8 +1,9 @@ import { Address, Contract, ContractProvider, TupleItem } from '@ton/core'; import { WalletContractV4 } from '@ton/ton'; -import { TonApiClient } from '@ton-api/client'; +import { initClient, execGetMethodForBlockchainAccount } from '@ton-api/client'; -const ta = new TonApiClient({ +// Initialize client once at module load time +initClient({ baseUrl: 'https://tonapi.io' }); @@ -37,7 +38,7 @@ export class WalletItem implements Contract { } static async createFromAddress(address: Address) { - const { data: accountData, error } = await ta.blockchain.execGetMethodForBlockchainAccount( + const { data: accountData, error } = await execGetMethodForBlockchainAccount( address, 'get_public_key' ); From b54376d69b821798faf72aba183036353127e394 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Wed, 12 Nov 2025 02:54:11 +0400 Subject: [PATCH 07/27] feat: update API schema and enhance client functionality - Downgraded OpenAPI version from 3.1.0 to 3.0.0 for compatibility. - Updated external documentation URLs for Lite Server and added new endpoints for blockchain block BOC download and library retrieval. - Introduced new Purchase and AccountPurchases schemas to manage purchase history. - Refactored existing schemas and interfaces to improve clarity and maintainability, including updates to Jetton and NFT operations. - Removed deprecated endpoints related to inscriptions and adjusted related documentation. - Enhanced client interfaces to support new wallet and purchase functionalities. - Improved query parameters for various endpoints to ensure better usability and flexibility. --- packages/client/src/api.yml | 1290 +++++++++++++------- packages/client/src/client.ts | 1479 ++++++++++++++++------- packages/client/src/generate.ts | 2 +- packages/client/src/schema-patches.json | 138 ++- 4 files changed, 2066 insertions(+), 843 deletions(-) diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index c155349..027f9bd 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -1,4 +1,4 @@ -openapi: 3.1.0 +openapi: 3.0.0 info: title: REST api to TON blockchain explorer version: 2.0.0 @@ -70,15 +70,11 @@ tags: - name: Lite Server externalDocs: description: Additional documentation - url: https://docs.tonconsole.com/tonapi/rest-api/liteserver + url: https://docs.tonconsole.com/tonapi/rest-api/lite-server - name: Emulation externalDocs: description: Additional documentation url: https://docs.tonconsole.com/tonapi/rest-api/emulation - - name: Inscriptions - externalDocs: - description: Additional documentation - url: https://docs.tonconsole.com/tonapi/rest-api/inscriptions - name: Utilities externalDocs: description: Additional documentation @@ -87,6 +83,7 @@ tags: externalDocs: description: Additional documentation url: https://docs.tonconsole.com/tonapi/rest-api/extra-currency + - name: Purchases paths: /v2/openapi.json: get: @@ -168,6 +165,29 @@ paths: $ref: '#/components/schemas/BlockchainBlock' default: $ref: '#/components/responses/Error' + /v2/blockchain/blocks/{block_id}/boc: + get: + description: Download blockchain block BOC + operationId: downloadBlockchainBlockBoc + tags: + - Blockchain + parameters: + - $ref: '#/components/parameters/blockchainBlockIDParameter' + responses: + '200': + description: Block BOC file + content: + application/octet-stream: + schema: + type: string + format: binary + headers: + Content-Disposition: + schema: + type: string + example: attachment; filename="block.boc" + default: + $ref: '#/components/responses/Error' /v2/blockchain/masterchain/{masterchain_seqno}/shards: get: description: Get blockchain block shards @@ -417,29 +437,37 @@ paths: schema: type: array description: |- - Supported values: - "NaN" for NaN type, - "Null" for Null type, - 10-base digits for tiny int type (Example: 100500), - 0x-prefixed hex digits for int257 (Example: 0xfa01d78381ae32), - all forms of addresses for slice type (Example: 0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e), - single-root base64-encoded BOC for cell (Example: "te6ccgEBAQEAAgAAAA=="), - single-root hex-encoded BOC for slice (Example: b5ee9c72010101010002000000) + Array of method arguments in string format. Supported value formats: + - "NaN" for Not-a-Number type + - "Null" for Null type + - Decimal integers for tinyint type (e.g., "100500") + - 0x-prefixed hex strings for int257 type (e.g., "0xfa01d78381ae32") + - TON blockchain addresses for slice type (e.g., "0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e") + - Base64-encoded BOC for cell type (e.g., "te6ccgEBAQEAAgAAAA==") + - Hex-encoded BOC for slice type (e.g., "b5ee9c72010101010002000000") items: type: string example: - 0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8 - - name: fix_order - in: query - required: false - schema: - type: boolean - description: |- - A temporary fix to switch to a scheme with direct ordering of arguments. - If equal to false, then the method takes arguments in direct order, - e.g. for get_nft_content(int index, cell individual_content) we pass a list of arguments [index, individual_content]. - If equal to true, then the method takes arguments in reverse order, e.g. [individual_content, index]. - default: true + responses: + '200': + description: method execution result + content: + application/json: + schema: + $ref: '#/components/schemas/MethodExecutionResult' + default: + $ref: '#/components/responses/Error' + post: + description: Execute get method for account + operationId: execGetMethodWithBodyForBlockchainAccount + tags: + - Blockchain + parameters: + - $ref: '#/components/parameters/accountIDParameter' + - $ref: '#/components/parameters/methodNameParameter' + requestBody: + $ref: '#/components/requestBodies/ExecGetMethodArgs' responses: '200': description: method execution result @@ -509,6 +537,23 @@ paths: $ref: '#/components/schemas/BlockchainAccountInspect' default: $ref: '#/components/responses/Error' + /v2/blockchain/libraries/{hash}: + get: + description: Get library cell + operationId: getLibraryByHash + tags: + - Blockchain + parameters: + - $ref: '#/components/parameters/hashParameter' + responses: + '200': + description: library cell + content: + application/json: + schema: + $ref: '#/components/schemas/BlockchainLibrary' + default: + $ref: '#/components/responses/Error' /v2/address/{account_id}/parse: get: description: parse address and display in all formats @@ -661,7 +706,6 @@ paths: - Accounts parameters: - $ref: '#/components/parameters/accountIDParameter' - - $ref: '#/components/parameters/i18n' - name: before_lt in: query description: omit this parameter to get last events @@ -679,34 +723,19 @@ paths: example: 100 maximum: 1000 minimum: 1 - - name: start_date - in: query - required: false - schema: - type: integer - format: int64 - maximum: 2114380800 - example: 1668436763 - - name: end_date - in: query - required: false - schema: - type: integer - format: int64 - maximum: 2114380800 - example: 1668436763 responses: '200': description: account jettons history content: application/json: schema: - $ref: '#/components/schemas/AccountEvents' + $ref: '#/components/schemas/JettonOperations' default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/jettons/{jetton_id}/history: get: - description: Get the transfer jetton history for account and jetton + deprecated: true + description: Please use `getJettonAccountHistoryByID`` instead operationId: getAccountJettonHistoryByID tags: - Accounts @@ -785,7 +814,6 @@ paths: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/nfts/history: get: - x-question: duplicate of getNftHistoryByID ? description: Get the transfer nft history operationId: getAccountNftHistory tags: @@ -810,29 +838,13 @@ paths: example: 100 maximum: 1000 minimum: 1 - - name: start_date - in: query - required: false - schema: - type: integer - format: int64 - maximum: 2114380800 - example: 1668436763 - - name: end_date - in: query - required: false - schema: - type: integer - format: int64 - maximum: 2114380800 - example: 1668436763 responses: '200': description: nft history content: application/json: schema: - $ref: '#/components/schemas/AccountEvents' + $ref: '#/components/schemas/NftOperations' default: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/events: @@ -1182,6 +1194,12 @@ paths: - DNS parameters: - $ref: '#/components/parameters/domainNameParameter' + - name: filter + in: query + schema: + type: boolean + default: false + required: false responses: '200': description: dns record @@ -1347,7 +1365,8 @@ paths: $ref: '#/components/responses/Error' /v2/nfts/{account_id}/history: get: - description: Get the transfer nfts history for account + deprecated: true + description: Please use `getAccountNftHistory`` instead operationId: getNftHistoryByID tags: - NFT @@ -1431,175 +1450,6 @@ paths: $ref: '#/components/schemas/Event' default: $ref: '#/components/responses/Error' - /v2/experimental/accounts/{account_id}/inscriptions: - get: - description: Get all inscriptions by owner address. It's experimental API and can be dropped in the future. - operationId: getAccountInscriptions - tags: - - Inscriptions - parameters: - - $ref: '#/components/parameters/accountIDParameter' - - $ref: '#/components/parameters/limitQuery' - - $ref: '#/components/parameters/offsetQuery' - responses: - '200': - description: account inscriptions - content: - application/json: - schema: - $ref: '#/components/schemas/InscriptionBalances' - default: - $ref: '#/components/responses/Error' - /v2/experimental/accounts/{account_id}/inscriptions/history: - get: - description: Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. - operationId: getAccountInscriptionsHistory - tags: - - Inscriptions - parameters: - - $ref: '#/components/parameters/accountIDParameter' - - $ref: '#/components/parameters/i18n' - - name: before_lt - in: query - description: omit this parameter to get last events - required: false - schema: - type: integer - format: int64 - example: 25758317000002 - x-js-format: bigint - - name: limit - in: query - required: false - schema: - type: integer - example: 100 - default: 100 - maximum: 1000 - minimum: 1 - responses: - '200': - description: account inscriptions history - content: - application/json: - schema: - $ref: '#/components/schemas/AccountEvents' - default: - $ref: '#/components/responses/Error' - /v2/experimental/accounts/{account_id}/inscriptions/{ticker}/history: - get: - description: Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. - operationId: getAccountInscriptionsHistoryByTicker - tags: - - Inscriptions - parameters: - - $ref: '#/components/parameters/accountIDParameter' - - $ref: '#/components/parameters/i18n' - - name: ticker - in: path - required: true - schema: - type: string - example: nano - - name: before_lt - in: query - description: omit this parameter to get last events - required: false - schema: - type: integer - format: int64 - example: 25758317000002 - x-js-format: bigint - - name: limit - in: query - required: false - schema: - type: integer - example: 100 - default: 100 - maximum: 1000 - minimum: 1 - responses: - '200': - description: account inscriptions history - content: - application/json: - schema: - $ref: '#/components/schemas/AccountEvents' - default: - $ref: '#/components/responses/Error' - /v2/experimental/inscriptions/op-template: - get: - description: return comment for making operation with inscription. please don't use it if you don't know what you are doing - operationId: getInscriptionOpTemplate - tags: - - Inscriptions - parameters: - - in: query - name: type - required: true - schema: - type: string - enum: - - ton20 - - gram20 - example: ton20 - - in: query - name: destination - required: false - schema: - type: string - - in: query - name: comment - required: false - schema: - type: string - - in: query - name: operation - required: true - schema: - type: string - enum: - - transfer - example: transfer - - in: query - name: amount - required: true - schema: - type: string - x-js-format: bigint - example: '1000000000' - - in: query - name: ticker - required: true - schema: - type: string - example: nano - - in: query - name: who - required: true - schema: - type: string - example: UQAs87W4yJHlF8mt29ocA4agnMrLsOP69jC1HPyBUjJay7Mg - responses: - '200': - description: inscription op template - content: - application/json: - schema: - type: object - required: - - comment - - destination - properties: - comment: - type: string - example: comment - destination: - type: string - example: '0:0000000000000' - default: - $ref: '#/components/responses/Error' /v2/jettons: get: description: Get a list of all indexed jetton masters in the blockchain. @@ -1676,7 +1526,14 @@ paths: parameters: - $ref: '#/components/parameters/accountIDParameter' - $ref: '#/components/parameters/limitQuery' - - $ref: '#/components/parameters/offsetQuery' + - in: query + name: offset + required: false + schema: + type: integer + default: 0 + minimum: 0 + maximum: 9000 responses: '200': description: jetton's holders @@ -1722,6 +1579,57 @@ paths: $ref: '#/components/schemas/Event' default: $ref: '#/components/responses/Error' + /v2/jettons/{jetton_id}/accounts/{account_id}/history: + get: + description: Get the transfer jetton history for account and jetton + operationId: getJettonAccountHistoryByID + tags: + - Accounts + parameters: + - $ref: '#/components/parameters/accountIDParameter' + - $ref: '#/components/parameters/jettonIDParameter' + - name: before_lt + in: query + description: omit this parameter to get last events + required: false + schema: + type: integer + format: int64 + example: 25758317000002 + x-js-format: bigint + - name: limit + in: query + required: true + schema: + type: integer + example: 100 + maximum: 1000 + minimum: 1 + - name: start_date + in: query + required: false + schema: + type: integer + format: int64 + maximum: 2114380800 + example: 1668436763 + - name: end_date + in: query + required: false + schema: + type: integer + format: int64 + maximum: 2114380800 + example: 1668436763 + responses: + '200': + description: account jetton history + content: + application/json: + schema: + $ref: '#/components/schemas/JettonOperations' + default: + $ref: '#/components/responses/Error' /v2/extra-currency/{id}: get: description: Get extra currency info by id @@ -1881,19 +1789,22 @@ paths: parameters: - in: query name: tokens - description: accept ton and jetton master addresses, separated by commas + description: accept cryptocurrencies or jetton master addresses, separated by commas required: true explode: false schema: type: array maxItems: 100 items: - type: string + oneOf: + - type: string + format: address + - type: string example: - ton - in: query name: currencies - description: accept ton and all possible fiat currencies, separated by commas + description: accept cryptocurrencies and all possible fiat currencies, separated by commas required: true explode: false schema: @@ -1930,11 +1841,13 @@ paths: parameters: - in: query name: token - description: accept jetton master address + description: accept cryptocurrencies or jetton master addresses required: true schema: - type: string - format: address + oneOf: + - type: string + format: address + - type: string - in: query name: currency required: false @@ -2082,6 +1995,23 @@ paths: $ref: '#/components/schemas/Seqno' default: $ref: '#/components/responses/Error' + /v2/wallet/{account_id}: + get: + description: Get human-friendly information about a wallet without low-level details. + operationId: getWalletInfo + tags: + - Wallet + parameters: + - $ref: '#/components/parameters/accountIDParameter' + responses: + '200': + description: wallet + content: + application/json: + schema: + $ref: '#/components/schemas/Wallet' + default: + $ref: '#/components/responses/Error' /v2/gasless/config: get: description: Returns configuration of gasless transfers @@ -2102,6 +2032,7 @@ paths: description: Estimates the cost of the given messages and returns a payload to sign operationId: gaslessEstimate parameters: + - $ref: '#/components/parameters/i18n' - name: master_id in: path required: true @@ -2134,6 +2065,10 @@ paths: responses: '200': description: the message has been sent + content: + application/json: + schema: + $ref: '#/components/schemas/GaslessTx' default: $ref: '#/components/responses/Error' /v2/pubkeys/{public_key}/wallets: @@ -2150,7 +2085,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Accounts' + $ref: '#/components/schemas/Wallets' default: $ref: '#/components/responses/Error' /v2/liteserver/get_masterchain_info: @@ -2808,6 +2743,23 @@ paths: $ref: '#/components/schemas/Multisig' default: $ref: '#/components/responses/Error' + /v2/multisig/order/{account_id}: + get: + description: Get multisig order + operationId: getMultisigOrder + tags: + - Multisig + parameters: + - $ref: '#/components/parameters/accountIDParameter' + responses: + '200': + description: multisig order + content: + application/json: + schema: + $ref: '#/components/schemas/MultisigOrder' + default: + $ref: '#/components/responses/Error' /v2/message/decode: post: description: Decode a given message. Only external incoming messages can be decoded currently. @@ -2827,7 +2779,7 @@ paths: $ref: '#/components/responses/Error' /v2/events/emulate: post: - description: Emulate sending message to blockchain + description: Emulate sending message to retrieve general blockchain events operationId: emulateMessageToEvent tags: - Emulation @@ -2852,7 +2804,7 @@ paths: $ref: '#/components/responses/Error' /v2/traces/emulate: post: - description: Emulate sending message to blockchain + description: Emulate sending message to retrieve with a detailed execution trace operationId: emulateMessageToTrace tags: - Emulation @@ -2876,13 +2828,14 @@ paths: $ref: '#/components/responses/Error' /v2/wallet/emulate: post: - description: Emulate sending message to blockchain + description: Emulate sending message to retrieve the resulting wallet state operationId: emulateMessageToWallet tags: - Emulation - Wallet parameters: - $ref: '#/components/parameters/i18n' + - $ref: '#/components/parameters/currencyQuery' requestBody: $ref: '#/components/requestBodies/EmulationBoc' responses: @@ -2896,7 +2849,7 @@ paths: $ref: '#/components/responses/Error' /v2/accounts/{account_id}/events/emulate: post: - description: Emulate sending message to blockchain + description: Emulate sending message to retrieve account-specific events operationId: emulateMessageToAccountEvent tags: - Emulation @@ -2908,16 +2861,51 @@ paths: in: query required: false schema: - type: boolean - requestBody: - $ref: '#/components/requestBodies/Boc' + type: boolean + requestBody: + $ref: '#/components/requestBodies/Boc' + responses: + '200': + description: emulated message to account + content: + application/json: + schema: + $ref: '#/components/schemas/AccountEvent' + default: + $ref: '#/components/responses/Error' + /v2/purchases/{account_id}/history: + get: + description: Get history of purchases + operationId: getPurchaseHistory + tags: + - Purchases + parameters: + - $ref: '#/components/parameters/accountIDParameter' + - name: before_lt + in: query + description: omit this parameter to get last invoices + required: false + schema: + type: integer + format: int64 + example: 25758317000002 + x-js-format: bigint + - name: limit + in: query + required: false + schema: + type: integer + default: 100 + example: 100 + maximum: 1000 + minimum: 1 responses: '200': - description: emulated message to account + description: account purchase history content: application/json: schema: - $ref: '#/components/schemas/AccountEvent' + $ref: '#/components/schemas/AccountPurchases' default: $ref: '#/components/responses/Error' components: @@ -3041,6 +3029,14 @@ components: schema: type: string example: NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2ODQ3... + hashParameter: + in: path + name: hash + required: true + description: hash in hex (without 0x) format + schema: + type: string + example: 131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85 i18n: in: header name: Accept-Language @@ -3312,6 +3308,13 @@ components: - wallet_address - wallet_public_key properties: + throw_error_if_not_enough_jettons: + type: boolean + default: false + description: TONAPI verifies that the account has enough jettons to pay the commission and make a transfer. + return_emulation: + type: boolean + default: false wallet_address: type: string format: address @@ -3443,6 +3446,20 @@ components: body: type: string format: cell-base64 + ExecGetMethodArgs: + description: | + Request body for executing a GET method on a blockchain account via POST. This format allows passing arguments in the request body instead of query parameters, which is especially useful for large or complex input data. + content: + application/json: + schema: + type: object + required: + - args + properties: + args: + type: array + items: + $ref: '#/components/schemas/ExecGetMethodArg' schemas: Error: type: object @@ -3907,6 +3924,7 @@ components: - cskip_no_state - cskip_bad_state - cskip_no_gas + - cskip_suspended BouncePhaseType: type: string example: cskip_no_state @@ -4656,9 +4674,9 @@ components: x-js-format: bigint example: 123456789 extra_balance: - type: object - additionalProperties: - type: string + type: array + items: + $ref: '#/components/schemas/ExtraCurrency' code: type: string format: cell @@ -4696,6 +4714,127 @@ components: root: type: string format: cell + BlockchainLibrary: + type: object + required: + - boc + properties: + boc: + type: string + format: cell + example: b5ee9c7201010101005f0000baff0020dd2082014c97ba218201339cbab19c71b0ed44d0d31fd70bffe304e0a4f260810200d71820d70b1fed44d0d31fd3ffd15112baf2a122f901541044f910f2a2f80001d31f3120d74a96d307d402fb00ded1a4c8cb1fcbffc9ed54 + WalletStats: + type: object + required: + - nfts_count + - jettons_count + - multisig_count + - staking_count + properties: + nfts_count: + type: integer + format: int32 + example: 123456789 + jettons_count: + type: integer + format: int32 + example: 123456789 + multisig_count: + type: integer + format: int32 + example: 123456789 + staking_count: + type: integer + format: int32 + example: 123456789 + WalletPlugin: + type: object + required: + - address + - type + - status + properties: + address: + type: string + format: address + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + type: + type: string + example: subscription_v1 + status: + $ref: '#/components/schemas/AccountStatus' + Wallets: + type: object + required: + - accounts + properties: + accounts: + type: array + items: + $ref: '#/components/schemas/Wallet' + Wallet: + type: object + required: + - address + - balance + - stats + - plugins + - status + - last_activity + - get_methods + - is_wallet + - last_lt + properties: + address: + type: string + format: address + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + is_wallet: + type: boolean + balance: + type: integer + format: int64 + example: 123456789 + x-js-format: bigint + stats: + $ref: '#/components/schemas/WalletStats' + plugins: + type: array + items: + $ref: '#/components/schemas/WalletPlugin' + status: + $ref: '#/components/schemas/AccountStatus' + last_activity: + type: integer + description: unix timestamp + format: int64 + example: 1720860269 + name: + type: string + example: Ton foundation + icon: + type: string + example: https://ton.org/logo.png + get_methods: + type: array + deprecated: true + items: + type: string + example: + - get_item_data + is_suspended: + type: boolean + signature_disabled: + type: boolean + interfaces: + type: array + items: + type: string + last_lt: + type: integer + format: int64 + example: 25713146000001 + x-js-format: bigint Account: type: object required: @@ -4810,6 +4949,13 @@ components: type: string format: cell description: Raw once-cell BoC encoded in hex. + GaslessTx: + type: object + required: + - protocol_name + properties: + protocol_name: + type: string SignRawParams: type: object required: @@ -4818,7 +4964,10 @@ components: - commission - from - valid_until + - protocol_name properties: + protocol_name: + type: string relay_address: type: string format: address @@ -4840,6 +4989,8 @@ components: type: array items: $ref: '#/components/schemas/SignRawMessage' + emulation: + $ref: '#/components/schemas/MessageConsequences' MethodExecutionResult: type: object required: @@ -5472,6 +5623,7 @@ components: type: string enum: - whitelist + - graylist - blacklist - none JettonPreview: @@ -5519,6 +5671,10 @@ components: type: string x-js-format: bigint example: '597968399' + scaled_ui_balance: + type: string + x-js-format: bigint + example: '597968399' price: $ref: '#/components/schemas/TokenRates' wallet_address: @@ -5555,19 +5711,57 @@ components: type: array items: $ref: '#/components/schemas/JettonBalance' + CurrencyType: + type: string + example: jetton + enum: + - native + - extra_currency + - jetton + - fiat + VaultDepositInfo: + type: object + required: + - price + - vault + properties: + price: + $ref: '#/components/schemas/Price' + vault: + type: string + format: address + example: 0:0BB5A9F69043EEBDDA5AD2E946EB953242BD8F603FE795D90698CEEC6BFC60A0 Price: type: object required: + - currency_type - value + - decimals - token_name + - verification + - image properties: + currency_type: + $ref: '#/components/schemas/CurrencyType' value: type: string x-js-format: bigint example: '123000000000' + decimals: + type: integer + example: 9 token_name: type: string example: TON + verification: + $ref: '#/components/schemas/TrustType' + image: + type: string + example: https://cache.tonapi.io/images/jetton.jpg + jetton: + type: string + format: address + example: 0:0BB5A9F69043EEBDDA5AD2E946EB953242BD8F603FE795D90698CEEC6BFC60A0 ImagePreview: type: object required: @@ -5668,9 +5862,10 @@ components: type: string example: crypto.ton approved_by: + allOf: + - $ref: '#/components/schemas/NftApprovedBy' deprecated: true - description: please use trust field - $ref: '#/components/schemas/NftApprovedBy' + description: Please use trust field include_cnft: type: boolean example: false @@ -5709,9 +5904,7 @@ components: format: address example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf seqno: - type: integer - format: int64 - example: 1 + type: string threshold: type: integer format: int32 @@ -5744,15 +5937,14 @@ components: - risk - creation_date - signed_by + - multisig_address properties: address: type: string format: address example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf order_seqno: - type: integer - format: int64 - example: 1 + type: string threshold: type: integer format: int32 @@ -5782,6 +5974,31 @@ components: type: string format: address example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + multisig_address: + type: string + format: address + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + changing_parameters: + type: object + required: + - threshold + - signers + - proposers + properties: + threshold: + type: integer + format: int32 + signers: + type: array + items: + type: string + format: address + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + proposers: + type: array + items: + type: string + format: address Refund: type: object required: @@ -5855,11 +6072,11 @@ components: enum: - TonTransfer - ExtraCurrencyTransfer + - ContractDeploy - JettonTransfer - JettonBurn - JettonMint - NftItemTransfer - - ContractDeploy - Subscribe - UnSubscribe - AuctionBid @@ -5867,13 +6084,19 @@ components: - DepositStake - WithdrawStake - WithdrawStakeRequest + - ElectionsDepositStake + - ElectionsRecoverStake - JettonSwap - SmartContractExec - - ElectionsRecoverStake - - ElectionsDepositStake - DomainRenew - - InscriptionTransfer - - InscriptionMint + - Purchase + - AddExtension + - RemoveExtension + - SetSignatureAllowedAction + - GasRelay + - DepositTokenStake + - WithdrawTokenStakeRequest + - LiquidityDeposit - Unknown status: type: string @@ -5919,10 +6142,22 @@ components: $ref: '#/components/schemas/SmartContractAction' DomainRenew: $ref: '#/components/schemas/DomainRenewAction' - InscriptionTransfer: - $ref: '#/components/schemas/InscriptionTransferAction' - InscriptionMint: - $ref: '#/components/schemas/InscriptionMintAction' + Purchase: + $ref: '#/components/schemas/PurchaseAction' + AddExtension: + $ref: '#/components/schemas/AddExtensionAction' + RemoveExtension: + $ref: '#/components/schemas/RemoveExtensionAction' + SetSignatureAllowedAction: + $ref: '#/components/schemas/SetSignatureAllowedAction' + GasRelay: + $ref: '#/components/schemas/GasRelayAction' + DepositTokenStake: + $ref: '#/components/schemas/DepositTokenStakeAction' + WithdrawTokenStakeRequest: + $ref: '#/components/schemas/WithdrawTokenStakeRequestAction' + LiquidityDeposit: + $ref: '#/components/schemas/LiquidityDepositAction' simple_preview: $ref: '#/components/schemas/ActionSimplePreview' base_transactions: @@ -6054,70 +6289,76 @@ components: example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf renewer: $ref: '#/components/schemas/AccountAddress' - InscriptionMintAction: + GasRelayAction: type: object required: - - type - - ticker - - recipient - amount - - decimals + - relayer + - target properties: - recipient: - $ref: '#/components/schemas/AccountAddress' amount: - type: string - x-js-format: bigint - description: amount in minimal particles - example: '123456789' - type: - type: string - enum: - - ton20 - - gram20 - example: ton20 - ticker: - type: string - example: nano - decimals: type: integer - example: 9 - InscriptionTransferAction: + format: int64 + x-js-format: bigint + example: 1000000000 + relayer: + $ref: '#/components/schemas/AccountAddress' + target: + $ref: '#/components/schemas/AccountAddress' + PurchaseAction: type: object required: - - sender - - recipient + - source + - destination + - invoice_id - amount - - type - - ticker - - decimals + - metadata properties: - sender: + source: $ref: '#/components/schemas/AccountAddress' - recipient: + destination: $ref: '#/components/schemas/AccountAddress' - amount: + invoice_id: type: string - x-js-format: bigint - description: amount in minimal particles - example: '123456789' - comment: - type: string - example: |- - Hi! This is your salary. - From accounting with love. - type: + example: 03cfc582-b1c3-410a-a9a7-1f3afe326b3b + amount: + $ref: '#/components/schemas/Price' + metadata: + $ref: '#/components/schemas/Metadata' + AddExtensionAction: + type: object + required: + - wallet + - extension + properties: + wallet: + $ref: '#/components/schemas/AccountAddress' + extension: type: string - enum: - - ton20 - - gram20 - example: ton20 - ticker: + format: address + example: 0:10C1073837B93FDAAD594284CE8B8EFF7B9CF25427440EB2FC682762E1471365 + RemoveExtensionAction: + type: object + required: + - wallet + - extension + properties: + wallet: + $ref: '#/components/schemas/AccountAddress' + extension: type: string - example: nano - decimals: - type: integer - example: 9 + format: address + example: 0:10C1073837B93FDAAD594284CE8B8EFF7B9CF25427440EB2FC682762E1471365 + SetSignatureAllowedAction: + type: object + required: + - wallet + - allowed + properties: + wallet: + $ref: '#/components/schemas/AccountAddress' + allowed: + type: boolean NftItemTransferAction: type: object required: @@ -6168,6 +6409,10 @@ components: x-js-format: bigint example: '1000000000' description: amount in quanta of tokens + scaled_ui_amount: + type: string + x-js-format: bigint + example: '1100000000' comment: type: string example: |- @@ -6244,7 +6489,8 @@ components: - subscriber - subscription - beneficiary - - amount + - admin + - price - initial properties: subscriber: @@ -6255,11 +6501,16 @@ components: example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf beneficiary: $ref: '#/components/schemas/AccountAddress' + admin: + $ref: '#/components/schemas/AccountAddress' amount: + deprecated: true type: integer format: int64 example: 1000000000 x-js-format: bigint + price: + $ref: '#/components/schemas/Price' initial: type: boolean example: false @@ -6269,6 +6520,7 @@ components: - subscriber - subscription - beneficiary + - admin properties: subscriber: $ref: '#/components/schemas/AccountAddress' @@ -6278,6 +6530,8 @@ components: example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf beneficiary: $ref: '#/components/schemas/AccountAddress' + admin: + $ref: '#/components/schemas/AccountAddress' AuctionBidAction: type: object required: @@ -6397,10 +6651,7 @@ components: properties: dex: type: string - enum: - - stonfi - - dedust - - megatonfi + example: stonfi amount_in: type: string x-js-format: bigint @@ -6451,6 +6702,45 @@ components: $ref: '#/components/schemas/AccountAddress' buyer: $ref: '#/components/schemas/AccountAddress' + DepositTokenStakeAction: + type: object + required: + - staker + - protocol + properties: + staker: + $ref: '#/components/schemas/AccountAddress' + protocol: + $ref: '#/components/schemas/Protocol' + stake_meta: + $ref: '#/components/schemas/Price' + WithdrawTokenStakeRequestAction: + type: object + required: + - staker + - protocol + properties: + staker: + $ref: '#/components/schemas/AccountAddress' + protocol: + $ref: '#/components/schemas/Protocol' + stake_meta: + $ref: '#/components/schemas/Price' + LiquidityDepositAction: + type: object + required: + - protocol + - from + - tokens + properties: + protocol: + $ref: '#/components/schemas/Protocol' + from: + $ref: '#/components/schemas/AccountAddress' + tokens: + type: array + items: + $ref: '#/components/schemas/VaultDepositInfo' ActionSimplePreview: type: object description: shortly describes what this action is about. @@ -6490,6 +6780,7 @@ components: - lt - in_progress - extra + - progress properties: event_id: type: string @@ -6522,6 +6813,12 @@ components: type: integer format: int64 example: 3 + progress: + type: number + format: float + minimum: 0 + maximum: 1 + example: 0.5 AccountEvents: type: object required: @@ -6536,6 +6833,67 @@ components: type: integer format: int64 example: 25713146000001 + Purchase: + type: object + required: + - event_id + - invoice_id + - source + - destination + - lt + - utime + - amount + - metadata + properties: + event_id: + type: string + example: e8b0e3fee4a26bd2317ac1f9952fcdc87dc08fdb617656b5202416323337372e + invoice_id: + type: string + example: 03cfc582-b1c3-410a-a9a7-1f3afe326b3b + source: + $ref: '#/components/schemas/AccountAddress' + destination: + $ref: '#/components/schemas/AccountAddress' + lt: + type: integer + format: int64 + example: 25713146000001 + x-js-format: bigint + utime: + type: integer + format: int64 + example: 1645544908 + amount: + $ref: '#/components/schemas/Price' + metadata: + $ref: '#/components/schemas/Metadata' + AccountPurchases: + type: object + required: + - purchases + - next_from + properties: + purchases: + type: array + items: + $ref: '#/components/schemas/Purchase' + next_from: + type: integer + format: int64 + example: 25713146000001 + Metadata: + type: object + required: + - encrypted_binary + properties: + encrypted_binary: + type: string + description: hex encoded bytes + decryption_key: + type: string + description: hex encoded bytes + example: dead.....beef TraceID: type: object required: @@ -6571,62 +6929,52 @@ components: Subscription: type: object required: - - address - - wallet_address - - beneficiary_address - - amount + - type + - status - period - - start_time - - timeout - - last_payment_time - - last_request_time - subscription_id - - failed_attempts + - payment_per_period + - wallet + - next_charge_at + - metadata properties: - address: - type: string - format: address - example: 0:dea8f638b789172ce36d10a20318125e52c649aa84893cd77858224fe2b9b0ee - wallet_address: + type: type: string - format: address - example: 0:567DE86AF2B6A557D7085807CF7C26338124987A5179344F0D0FA2657EB710F1 - beneficiary_address: + description: type of subscription + example: v2 + status: type: string - format: address - example: 0:c704dadfabac88eab58e340de03080df81ff76636431f48624ad6e26fb2da0a4 - amount: - type: integer - format: int64 - example: 1000000000 + enum: + - not_ready + - active + - suspended + - cancelled period: type: integer + description: payment period in seconds format: int64 example: 2592000 - start_time: - type: integer - format: int64 - example: 1653996832 - timeout: - type: integer - format: int64 - example: 10800 - last_payment_time: - type: integer - format: int64 - example: 1653996834 - last_request_time: - type: integer - format: int64 - example: 0 subscription_id: + type: string + description: common identifier + payment_per_period: + $ref: '#/components/schemas/Price' + wallet: + $ref: '#/components/schemas/AccountAddress' + next_charge_at: type: integer format: int64 - example: 217477 - failed_attempts: - type: integer - format: int32 - example: 0 + example: 1653996834 + metadata: + $ref: '#/components/schemas/Metadata' + address: + type: string + format: address + example: 0:dea8f638b789172ce36d10a20318125e52c649aa84893cd77858224fe2b9b0ee + beneficiary: + $ref: '#/components/schemas/AccountAddress' + admin: + $ref: '#/components/schemas/AccountAddress' Subscriptions: type: object required: @@ -6844,6 +7192,10 @@ components: type: array items: $ref: '#/components/schemas/NftItem' + total_equivalent: + type: number + format: float + description: Estimated equivalent value of all assets at risk in selected currency (for example USD) JettonQuantity: type: object required: @@ -6994,6 +7346,7 @@ components: - is_scam - lt - in_progress + - progress properties: event_id: type: string @@ -7023,6 +7376,12 @@ components: type: boolean example: false description: Event is not finished yet. Transactions still happening + progress: + type: number + format: float + minimum: 0 + maximum: 1 + example: 0.5 JettonMetadata: type: object required: @@ -7075,39 +7434,6 @@ components: custom_payload_api_uri: type: string example: https://claim-api.tonapi.io/jettons/TESTMINT - InscriptionBalances: - type: object - required: - - inscriptions - properties: - inscriptions: - type: array - items: - $ref: '#/components/schemas/InscriptionBalance' - InscriptionBalance: - type: object - required: - - type - - ticker - - balance - - decimals - properties: - type: - type: string - enum: - - ton20 - - gram20 - example: ton20 - ticker: - type: string - example: nano - balance: - type: string - x-js-format: bigint - example: '1000000000' - decimals: - type: integer - example: 9 Jettons: type: object required: @@ -7419,17 +7745,21 @@ components: $ref: '#/components/schemas/NftItem' ChartPoints: type: array + items: false + description: | + Each inner array is a pair [timestamp, price]: + • index 0 — Unix timestamp (int64) + • index 1 — token price (decimal) in the requested currency. + example: + - 1668436763 + - 97.21323234 prefixItems: - type: integer format: int64 description: Unix timestamp of the data point - type: number description: Decimal price of the token in the requested currency - items: false additionalItems: false - example: - - - 1668436763 - - 97.21323234 AccountInfoByStateInit: type: object required: @@ -7517,6 +7847,8 @@ components: code: type: string format: cell + disassembled_code: + type: string code_hash: type: string methods: @@ -7636,6 +7968,156 @@ components: method: type: string example: get_something + NftOperations: + type: object + required: + - operations + properties: + operations: + type: array + items: + $ref: '#/components/schemas/NftOperation' + next_from: + type: integer + format: int64 + example: 25713146000001 + x-js-format: bigint + NftOperation: + type: object + required: + - operation + - utime + - lt + - transaction_hash + - item + properties: + operation: + type: string + example: transfer + utime: + type: integer + format: int64 + example: 1234567890 + lt: + type: integer + format: int64 + example: 25713146000001 + x-js-format: bigint + transaction_hash: + type: string + example: '0xdeadbeaf' + source: + $ref: '#/components/schemas/AccountAddress' + destination: + $ref: '#/components/schemas/AccountAddress' + item: + $ref: '#/components/schemas/NftItem' + JettonOperations: + type: object + required: + - operations + properties: + operations: + type: array + items: + $ref: '#/components/schemas/JettonOperation' + next_from: + type: integer + format: int64 + example: 25713146000001 + x-js-format: bigint + JettonOperation: + type: object + required: + - operation + - utime + - lt + - jetton + - transaction_hash + - amount + - trace_id + - query_id + properties: + operation: + type: string + example: transfer + enum: + - transfer + - mint + - burn + utime: + type: integer + format: int64 + example: 1234567890 + lt: + type: integer + format: int64 + example: 25713146000001 + x-js-format: bigint + transaction_hash: + type: string + example: cbf3e3d70ecf6f69643dd430761cd6004de2cacbdbc3029b0abd30ca3cc1c67e + source: + $ref: '#/components/schemas/AccountAddress' + destination: + $ref: '#/components/schemas/AccountAddress' + amount: + type: string + x-js-format: bigint + example: '1000000000' + jetton: + $ref: '#/components/schemas/JettonPreview' + trace_id: + type: string + example: 8fa19eec7bd6d00d0d76048cebe31e34082a859410c9fcf7d55ef4ff8f7fcb47 + query_id: + type: string + example: '17286061481122318000' + x-js-format: bigint + payload: {} + ExecGetMethodArgType: + type: string + description: | + Data type of the argument value: + - `nan`: Not-a-Number value + - `null`: Null value + - `tinyint`: Decimal integer (e.g., `100500`) + - `int257`: 257-bit integer in hex format with 0x prefix (e.g., `0xfa01d78381ae32`) + - `slice`: TON blockchain address (e.g., `0:6e731f2e...`) + - `cell_boc_base64`: Base64-encoded cell BOC (Binary Object Code) (e.g., `te6ccgEBAQEAAgAAAA==`) + - `slice_boc_hex`: Hex-encoded slice BOC (e.g., `b5ee9c72...`) + enum: + - nan + - 'null' + - tinyint + - int257 + - slice + - cell_boc_base64 + - slice_boc_hex + example: int257 + ExecGetMethodArg: + type: object + required: + - type + - value + properties: + type: + $ref: '#/components/schemas/ExecGetMethodArgType' + value: + type: string + description: String representation of the value according to the specified type + example: '0xfa01d78381ae32' + Protocol: + type: object + required: + - name + properties: + name: + type: string + example: Ethena + image: + type: string + example: https://cache.tonapi.io/images/jetton.jpg responses: Error: description: Some error during request processing diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index fcc71ec..49dd78f 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -329,7 +329,8 @@ export enum AccStatusChange { export enum ComputeSkipReason { CskipNoState = 'cskip_no_state', CskipBadState = 'cskip_bad_state', - CskipNoGas = 'cskip_no_gas' + CskipNoGas = 'cskip_no_gas', + CskipSuspended = 'cskip_suspended' } /** @example "cskip_no_state" */ @@ -890,7 +891,7 @@ export interface BlockchainRawAccount { * @example 123456789 */ balance: bigint; - extraBalance?: Record; + extraBalance?: ExtraCurrency[]; /** * @format cell * @example "b5ee9c72410104010087000114ff00f4a413f4a0f2c80b0102012002030002d200dfa5ffff76a268698fe9ffe8e42c5267858f90e785ffe4f6aa6467c444ffb365ffc10802faf0807d014035e7a064b87d804077e7857fc10803dfd2407d014035e7a064b86467cd8903a32b9ba4410803ade68afd014035e7a045ea432b6363796103bb7b9363210c678b64b87d807d8040c249b3e4" @@ -920,6 +921,92 @@ export interface BlockchainRawAccount { }[]; } +export interface BlockchainLibrary { + /** + * @format cell + * @example "b5ee9c7201010101005f0000baff0020dd2082014c97ba218201339cbab19c71b0ed44d0d31fd70bffe304e0a4f260810200d71820d70b1fed44d0d31fd3ffd15112baf2a122f901541044f910f2a2f80001d31f3120d74a96d307d402fb00ded1a4c8cb1fcbffc9ed54" + */ + boc: Cell; +} + +export interface WalletStats { + /** + * @format int32 + * @example 123456789 + */ + nftsCount: number; + /** + * @format int32 + * @example 123456789 + */ + jettonsCount: number; + /** + * @format int32 + * @example 123456789 + */ + multisigCount: number; + /** + * @format int32 + * @example 123456789 + */ + stakingCount: number; +} + +export interface WalletPlugin { + /** + * @format address + * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + */ + address: Address; + /** @example "subscription_v1" */ + type: string; + status: AccountStatus; +} + +export interface Wallets { + accounts: Wallet[]; +} + +export interface Wallet { + /** + * @format address + * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + */ + address: Address; + isWallet: boolean; + /** + * @format bigint + * @example 123456789 + */ + balance: bigint; + stats: WalletStats; + plugins: WalletPlugin[]; + status: AccountStatus; + /** + * unix timestamp + * @format int64 + * @example 1720860269 + */ + lastActivity: number; + /** @example "Ton foundation" */ + name?: string; + /** @example "https://ton.org/logo.png" */ + icon?: string; + /** + * @deprecated + * @example ["get_item_data"] + */ + getMethods: string[]; + isSuspended?: boolean; + signatureDisabled?: boolean; + interfaces?: string[]; + /** + * @format bigint + * @example 25713146000001 + */ + lastLt: bigint; +} + export interface Account { /** * @format address @@ -997,7 +1084,12 @@ export interface SignRawMessage { stateInit?: Cell; } +export interface GaslessTx { + protocolName: string; +} + export interface SignRawParams { + protocolName: string; /** * @format address * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" @@ -1020,6 +1112,7 @@ export interface SignRawParams { */ validUntil: number; messages: SignRawMessage[]; + emulation?: MessageConsequences; } export interface MethodExecutionResult { @@ -1405,6 +1498,7 @@ export interface DomainBids { export enum JettonVerificationType { Whitelist = 'whitelist', + Graylist = 'graylist', Blacklist = 'blacklist', None = 'none' } @@ -1435,6 +1529,11 @@ export interface JettonBalance { * @example "597968399" */ balance: bigint; + /** + * @format bigint + * @example "597968399" + */ + scaledUiBalance?: bigint; price?: TokenRates; walletAddress: AccountAddress; jetton: JettonPreview; @@ -1458,14 +1557,42 @@ export interface JettonsBalances { balances: JettonBalance[]; } +/** @example "jetton" */ +export enum CurrencyType { + Native = 'native', + ExtraCurrency = 'extra_currency', + Jetton = 'jetton', + Fiat = 'fiat' +} + +export interface VaultDepositInfo { + price: Price; + /** + * @format address + * @example "0:0BB5A9F69043EEBDDA5AD2E946EB953242BD8F603FE795D90698CEEC6BFC60A0" + */ + vault: Address; +} + export interface Price { + currencyType: CurrencyType; /** * @format bigint * @example "123000000000" */ value: bigint; + /** @example 9 */ + decimals: number; /** @example "TON" */ tokenName: string; + verification: TrustType; + /** @example "https://cache.tonapi.io/images/jetton.jpg" */ + image: string; + /** + * @format address + * @example "0:0BB5A9F69043EEBDDA5AD2E946EB953242BD8F603FE795D90698CEEC6BFC60A0" + */ + jetton?: Address; } export interface ImagePreview { @@ -1531,7 +1658,7 @@ export interface NftItem { /** @example "crypto.ton" */ dns?: string; /** - * please use trust field + * Please use trust field * @deprecated */ approvedBy: NftApprovedBy; @@ -1554,11 +1681,7 @@ export interface Multisig { * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" */ address: Address; - /** - * @format int64 - * @example 1 - */ - seqno: number; + seqno: string; /** @format int32 */ threshold: number; signers: Address[]; @@ -1572,11 +1695,7 @@ export interface MultisigOrder { * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" */ address: Address; - /** - * @format int64 - * @example 1 - */ - orderSeqno: number; + orderSeqno: string; /** @format int32 */ threshold: number; /** @example false */ @@ -1591,6 +1710,17 @@ export interface MultisigOrder { /** @format int64 */ creationDate: number; signedBy: Address[]; + /** + * @format address + * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" + */ + multisigAddress: Address; + changingParameters?: { + /** @format int32 */ + threshold: number; + signers: Address[]; + proposers: Address[]; + }; } export interface Refund { @@ -1634,11 +1764,11 @@ export interface Action { type: | 'TonTransfer' | 'ExtraCurrencyTransfer' + | 'ContractDeploy' | 'JettonTransfer' | 'JettonBurn' | 'JettonMint' | 'NftItemTransfer' - | 'ContractDeploy' | 'Subscribe' | 'UnSubscribe' | 'AuctionBid' @@ -1646,13 +1776,19 @@ export interface Action { | 'DepositStake' | 'WithdrawStake' | 'WithdrawStakeRequest' + | 'ElectionsDepositStake' + | 'ElectionsRecoverStake' | 'JettonSwap' | 'SmartContractExec' - | 'ElectionsRecoverStake' - | 'ElectionsDepositStake' | 'DomainRenew' - | 'InscriptionTransfer' - | 'InscriptionMint' + | 'Purchase' + | 'AddExtension' + | 'RemoveExtension' + | 'SetSignatureAllowedAction' + | 'GasRelay' + | 'DepositTokenStake' + | 'WithdrawTokenStakeRequest' + | 'LiquidityDeposit' | 'Unknown'; /** @example "ok" */ status: 'ok' | 'failed'; @@ -1678,8 +1814,14 @@ export interface Action { JettonSwap?: JettonSwapAction; SmartContractExec?: SmartContractAction; DomainRenew?: DomainRenewAction; - InscriptionTransfer?: InscriptionTransferAction; - InscriptionMint?: InscriptionMintAction; + Purchase?: PurchaseAction; + AddExtension?: AddExtensionAction; + RemoveExtension?: RemoveExtensionAction; + SetSignatureAllowedAction?: SetSignatureAllowedAction; + GasRelay?: GasRelayAction; + DepositTokenStake?: DepositTokenStakeAction; + WithdrawTokenStakeRequest?: WithdrawTokenStakeRequestAction; + LiquidityDeposit?: LiquidityDepositAction; /** shortly describes what this action is about. */ simplePreview: ActionSimplePreview; baseTransactions: string[]; @@ -1765,42 +1907,46 @@ export interface DomainRenewAction { renewer: AccountAddress; } -export interface InscriptionMintAction { - recipient: AccountAddress; +export interface GasRelayAction { /** - * amount in minimal particles * @format bigint - * @example "123456789" + * @example 1000000000 */ amount: bigint; - /** @example "ton20" */ - type: 'ton20' | 'gram20'; - /** @example "nano" */ - ticker: string; - /** @example 9 */ - decimals: number; + relayer: AccountAddress; + target: AccountAddress; } -export interface InscriptionTransferAction { - sender: AccountAddress; - recipient: AccountAddress; +export interface PurchaseAction { + source: AccountAddress; + destination: AccountAddress; + /** @example "03cfc582-b1c3-410a-a9a7-1f3afe326b3b" */ + invoiceId: string; + amount: Price; + metadata: Metadata; +} + +export interface AddExtensionAction { + wallet: AccountAddress; /** - * amount in minimal particles - * @format bigint - * @example "123456789" + * @format address + * @example "0:10C1073837B93FDAAD594284CE8B8EFF7B9CF25427440EB2FC682762E1471365" */ - amount: bigint; + extension: Address; +} + +export interface RemoveExtensionAction { + wallet: AccountAddress; /** - * @example "Hi! This is your salary. - * From accounting with love." + * @format address + * @example "0:10C1073837B93FDAAD594284CE8B8EFF7B9CF25427440EB2FC682762E1471365" */ - comment?: string; - /** @example "ton20" */ - type: 'ton20' | 'gram20'; - /** @example "nano" */ - ticker: string; - /** @example 9 */ - decimals: number; + extension: Address; +} + +export interface SetSignatureAllowedAction { + wallet: AccountAddress; + allowed: boolean; } export interface NftItemTransferAction { @@ -1841,6 +1987,11 @@ export interface JettonTransferAction { * @example "1000000000" */ amount: bigint; + /** + * @format bigint + * @example "1100000000" + */ + scaledUiAmount?: bigint; /** * @example "Hi! This is your salary. * From accounting with love." @@ -1901,11 +2052,14 @@ export interface SubscriptionAction { */ subscription: Address; beneficiary: AccountAddress; + admin: AccountAddress; /** + * @deprecated * @format bigint * @example 1000000000 */ - amount: bigint; + amount?: bigint; + price: Price; /** @example false */ initial: boolean; } @@ -1918,6 +2072,7 @@ export interface UnSubscriptionAction { */ subscription: Address; beneficiary: AccountAddress; + admin: AccountAddress; } export interface AuctionBidAction { @@ -1983,7 +2138,8 @@ export interface ElectionsDepositStakeAction { } export interface JettonSwapAction { - dex: 'stonfi' | 'dedust' | 'megatonfi'; + /** @example "stonfi" */ + dex: string; /** * @format bigint * @example "1660050553" @@ -2018,6 +2174,24 @@ export interface NftPurchaseAction { buyer: AccountAddress; } +export interface DepositTokenStakeAction { + staker: AccountAddress; + protocol: Protocol; + stakeMeta?: Price; +} + +export interface WithdrawTokenStakeRequestAction { + staker: AccountAddress; + protocol: Protocol; + stakeMeta?: Price; +} + +export interface LiquidityDepositAction { + protocol: Protocol; + from: AccountAddress; + tokens: VaultDepositInfo[]; +} + /** shortly describes what this action is about. */ export interface ActionSimplePreview { /** @example "Ton Transfer" */ @@ -2065,6 +2239,13 @@ export interface AccountEvent { * @example 3 */ extra: number; + /** + * @format float + * @min 0 + * @max 1 + * @example 0.5 + */ + progress: number; } export interface AccountEvents { @@ -2076,6 +2257,46 @@ export interface AccountEvents { nextFrom: number; } +export interface Purchase { + /** @example "e8b0e3fee4a26bd2317ac1f9952fcdc87dc08fdb617656b5202416323337372e" */ + eventId: string; + /** @example "03cfc582-b1c3-410a-a9a7-1f3afe326b3b" */ + invoiceId: string; + source: AccountAddress; + destination: AccountAddress; + /** + * @format bigint + * @example 25713146000001 + */ + lt: bigint; + /** + * @format int64 + * @example 1645544908 + */ + utime: number; + amount: Price; + metadata: Metadata; +} + +export interface AccountPurchases { + purchases: Purchase[]; + /** + * @format int64 + * @example 25713146000001 + */ + nextFrom: number; +} + +export interface Metadata { + /** hex encoded bytes */ + encryptedBinary: string; + /** + * hex encoded bytes + * @example "dead.....beef" + */ + decryptionKey?: string; +} + export interface TraceID { /** @example "55e8809519cd3c49098c9ee45afdafcea7a894a74d0f628d94a115a50e045122" */ id: string; @@ -2097,60 +2318,34 @@ export interface ApyHistory { export interface Subscription { /** - * @format address - * @example "0:dea8f638b789172ce36d10a20318125e52c649aa84893cd77858224fe2b9b0ee" - */ - address: Address; - /** - * @format address - * @example "0:567DE86AF2B6A557D7085807CF7C26338124987A5179344F0D0FA2657EB710F1" - */ - walletAddress: Address; - /** - * @format address - * @example "0:c704dadfabac88eab58e340de03080df81ff76636431f48624ad6e26fb2da0a4" + * type of subscription + * @example "v2" */ - beneficiaryAddress: Address; - /** - * @format int64 - * @example 1000000000 - */ - amount: number; + type: string; + status: 'not_ready' | 'active' | 'suspended' | 'cancelled'; /** + * payment period in seconds * @format int64 * @example 2592000 */ period: number; - /** - * @format int64 - * @example 1653996832 - */ - startTime: number; - /** - * @format int64 - * @example 10800 - */ - timeout: number; + /** common identifier */ + subscriptionId: string; + paymentPerPeriod: Price; + wallet: AccountAddress; /** * @format int64 * @example 1653996834 */ - lastPaymentTime: number; + nextChargeAt: number; + metadata: Metadata; /** - * @format int64 - * @example 0 - */ - lastRequestTime: number; - /** - * @format int64 - * @example 217477 - */ - subscriptionId: number; - /** - * @format int32 - * @example 0 + * @format address + * @example "0:dea8f638b789172ce36d10a20318125e52c649aa84893cd77858224fe2b9b0ee" */ - failedAttempts: number; + address?: Address; + beneficiary?: AccountAddress; + admin?: AccountAddress; } export interface Subscriptions { @@ -2287,6 +2482,11 @@ export interface Risk { ton: bigint; jettons: JettonQuantity[]; nfts: NftItem[]; + /** + * Estimated equivalent value of all assets at risk in selected currency (for example USD) + * @format float + */ + totalEquivalent?: number; } export interface JettonQuantity { @@ -2408,6 +2608,13 @@ export interface Event { * @example false */ inProgress: boolean; + /** + * @format float + * @min 0 + * @max 1 + * @example 0.5 + */ + progress: number; } export interface JettonMetadata { @@ -2436,24 +2643,6 @@ export interface JettonMetadata { customPayloadApiUri?: string; } -export interface InscriptionBalances { - inscriptions: InscriptionBalance[]; -} - -export interface InscriptionBalance { - /** @example "ton20" */ - type: 'ton20' | 'gram20'; - /** @example "nano" */ - ticker: string; - /** - * @format bigint - * @example "1000000000" - */ - balance: bigint; - /** @example 9 */ - decimals: number; -} - export interface Jettons { jettons: JettonInfo[]; } @@ -2678,7 +2867,12 @@ export interface DnsExpiring { }[]; } -/** @example [[1668436763,97.21323234]] */ +/** + * Each inner array is a pair [timestamp, price]: + * • index 0 — Unix timestamp (int64) + * • index 1 — token price (decimal) in the requested currency. + * @example [1668436763,97.21323234] + */ export type ChartPoints = [number, number]; export interface AccountInfoByStateInit { @@ -2737,6 +2931,7 @@ export interface EncryptedComment { export interface BlockchainAccountInspect { /** @format cell */ code: Cell; + disassembledCode?: string; codeHash: string; methods: Method[]; compiler: 'func' | 'fift' | 'tact'; @@ -2792,15 +2987,133 @@ export interface SourceFile { includeInCommand: boolean; } -export interface Source { - files: SourceFile[]; +export interface Source { + files: SourceFile[]; +} + +export interface Method { + /** @format int64 */ + id: number; + /** @example "get_something" */ + method: string; +} + +export interface NftOperations { + operations: NftOperation[]; + /** + * @format bigint + * @example 25713146000001 + */ + nextFrom?: bigint; +} + +export interface NftOperation { + /** @example "transfer" */ + operation: string; + /** + * @format int64 + * @example 1234567890 + */ + utime: number; + /** + * @format bigint + * @example 25713146000001 + */ + lt: bigint; + /** @example "0xdeadbeaf" */ + transactionHash: string; + source?: AccountAddress; + destination?: AccountAddress; + item: NftItem; +} + +export interface JettonOperations { + operations: JettonOperation[]; + /** + * @format bigint + * @example 25713146000001 + */ + nextFrom?: bigint; +} + +export interface JettonOperation { + /** @example "transfer" */ + operation: 'transfer' | 'mint' | 'burn'; + /** + * @format int64 + * @example 1234567890 + */ + utime: number; + /** + * @format bigint + * @example 25713146000001 + */ + lt: bigint; + /** @example "cbf3e3d70ecf6f69643dd430761cd6004de2cacbdbc3029b0abd30ca3cc1c67e" */ + transactionHash: string; + source?: AccountAddress; + destination?: AccountAddress; + /** + * @format bigint + * @example "1000000000" + */ + amount: bigint; + jetton: JettonPreview; + /** @example "8fa19eec7bd6d00d0d76048cebe31e34082a859410c9fcf7d55ef4ff8f7fcb47" */ + traceId: string; + /** + * @format bigint + * @example "17286061481122318000" + */ + queryId: bigint; + payload?: any; +} + +/** + * Data type of the argument value: + * - `nan`: Not-a-Number value + * - `null`: Null value + * - `tinyint`: Decimal integer (e.g., `100500`) + * - `int257`: 257-bit integer in hex format with 0x prefix (e.g., `0xfa01d78381ae32`) + * - `slice`: TON blockchain address (e.g., `0:6e731f2e...`) + * - `cell_boc_base64`: Base64-encoded cell BOC (Binary Object Code) (e.g., `te6ccgEBAQEAAgAAAA==`) + * - `slice_boc_hex`: Hex-encoded slice BOC (e.g., `b5ee9c72...`) + * @example "int257" + */ +export enum ExecGetMethodArgType { + Nan = 'nan', + Null = 'null', + Tinyint = 'tinyint', + Int257 = 'int257', + Slice = 'slice', + CellBocBase64 = 'cell_boc_base64', + SliceBocHex = 'slice_boc_hex' +} + +export interface ExecGetMethodArg { + /** + * Data type of the argument value: + * - `nan`: Not-a-Number value + * - `null`: Null value + * - `tinyint`: Decimal integer (e.g., `100500`) + * - `int257`: 257-bit integer in hex format with 0x prefix (e.g., `0xfa01d78381ae32`) + * - `slice`: TON blockchain address (e.g., `0:6e731f2e...`) + * - `cell_boc_base64`: Base64-encoded cell BOC (Binary Object Code) (e.g., `te6ccgEBAQEAAgAAAA==`) + * - `slice_boc_hex`: Hex-encoded slice BOC (e.g., `b5ee9c72...`) + */ + type: ExecGetMethodArgType; + /** + * String representation of the value according to the specified type + * @example "0xfa01d78381ae32" + */ + value: string; } -export interface Method { - /** @format int64 */ - id: number; - /** @example "get_something" */ - method: string; +export interface Protocol { + /** @example "Ethena" */ + name: string; + /** @example "https://cache.tonapi.io/images/jetton.jpg" */ + image?: string; } export type GetOpenapiJsonData = any; @@ -2814,6 +3127,9 @@ export type GetReducedBlockchainBlocksData = ReducedBlocks; export type GetBlockchainBlockData = BlockchainBlock; +/** @format binary */ +export type DownloadBlockchainBlockBocData = File; + export type GetBlockchainMasterchainShardsData = BlockchainBlockShards; export type GetBlockchainMasterchainBlocksData = BlockchainBlocks; @@ -2840,6 +3156,8 @@ export type GetBlockchainAccountTransactionsData = Transactions; export type ExecGetMethodForBlockchainAccountData = MethodExecutionResult; +export type ExecGetMethodWithBodyForBlockchainAccountData = MethodExecutionResult; + export type SendBlockchainMessageData = any; export type GetBlockchainConfigData = BlockchainConfig; @@ -2848,6 +3166,8 @@ export type GetRawBlockchainConfigData = RawBlockchainConfig; export type BlockchainAccountInspectData = BlockchainAccountInspect; +export type GetLibraryByHashData = BlockchainLibrary; + export interface AddressParseData { /** * @format address @@ -2876,13 +3196,13 @@ export type GetAccountJettonsBalancesData = JettonsBalances; export type GetAccountJettonBalanceData = JettonBalance; -export type GetAccountJettonsHistoryData = AccountEvents; +export type GetAccountJettonsHistoryData = JettonOperations; export type GetAccountJettonHistoryByIdData = AccountEvents; export type GetAccountNftItemsData = NftItems; -export type GetAccountNftHistoryData = AccountEvents; +export type GetAccountNftHistoryData = NftOperations; export type GetAccountEventsData = AccountEvents; @@ -2941,19 +3261,6 @@ export type GetTraceData = Trace; export type GetEventData = Event; -export type GetAccountInscriptionsData = InscriptionBalances; - -export type GetAccountInscriptionsHistoryData = AccountEvents; - -export type GetAccountInscriptionsHistoryByTickerData = AccountEvents; - -export interface GetInscriptionOpTemplateData { - /** @example "comment" */ - comment: string; - /** @example "0:0000000000000" */ - destination: string; -} - export type GetJettonsData = Jettons; export type GetJettonInfoData = JettonInfo; @@ -2966,6 +3273,8 @@ export type GetJettonTransferPayloadData = JettonTransferPayload; export type GetJettonsEventsData = Event; +export type GetJettonAccountHistoryByIdData = JettonOperations; + export type GetExtraCurrencyInfoData = EcPreview; export type GetAccountNominatorsPoolsData = AccountStaking; @@ -3014,13 +3323,15 @@ export interface TonConnectProofData { export type GetAccountSeqnoData = Seqno; +export type GetWalletInfoData = Wallet; + export type GaslessConfigData = GaslessConfig; export type GaslessEstimateData = SignRawParams; -export type GaslessSendData = any; +export type GaslessSendData = GaslessTx; -export type GetWalletsByPublicKeyData = Accounts; +export type GetWalletsByPublicKeyData = Wallets; export interface GetRawMasterchainInfoData { last: BlockRaw; @@ -3241,6 +3552,8 @@ export interface GetOutMsgQueueSizesData { export type GetMultisigAccountData = Multisig; +export type GetMultisigOrderData = MultisigOrder; + export type DecodeMessageData = DecodedMessage; export type EmulateMessageToEventData = Event; @@ -3251,6 +3564,8 @@ export type EmulateMessageToWalletData = MessageConsequences; export type EmulateMessageToAccountEventData = AccountEvent; +export type GetPurchaseHistoryData = AccountPurchases; + export type QueryParamsType = Record; export type ResponseFormat = keyof Omit; @@ -3801,7 +4116,7 @@ const components = { }, '#/components/schemas/ComputeSkipReason': { type: 'string', - enum: ['cskip_no_state', 'cskip_bad_state', 'cskip_no_gas'] + enum: ['cskip_no_state', 'cskip_bad_state', 'cskip_no_gas', 'cskip_suspended'] }, '#/components/schemas/BouncePhaseType': { type: 'string', @@ -4188,7 +4503,7 @@ const components = { properties: { address: { type: 'string', format: 'address' }, balance: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, - extra_balance: { type: 'object', additionalProperties: { type: 'string' } }, + extra_balance: { type: 'array', items: { $ref: '#/components/schemas/ExtraCurrency' } }, code: { type: 'string', format: 'cell' }, data: { type: 'string', format: 'cell' }, last_transaction_lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, @@ -4209,6 +4524,65 @@ const components = { } } }, + '#/components/schemas/BlockchainLibrary': { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }, + '#/components/schemas/WalletStats': { + type: 'object', + required: ['nfts_count', 'jettons_count', 'multisig_count', 'staking_count'], + properties: { + nfts_count: { type: 'integer', format: 'int32' }, + jettons_count: { type: 'integer', format: 'int32' }, + multisig_count: { type: 'integer', format: 'int32' }, + staking_count: { type: 'integer', format: 'int32' } + } + }, + '#/components/schemas/WalletPlugin': { + type: 'object', + required: ['address', 'type', 'status'], + properties: { + address: { type: 'string', format: 'address' }, + type: { type: 'string' }, + status: { $ref: '#/components/schemas/AccountStatus' } + } + }, + '#/components/schemas/Wallets': { + type: 'object', + required: ['accounts'], + properties: { accounts: { type: 'array', items: { $ref: '#/components/schemas/Wallet' } } } + }, + '#/components/schemas/Wallet': { + type: 'object', + required: [ + 'address', + 'balance', + 'stats', + 'plugins', + 'status', + 'last_activity', + 'get_methods', + 'is_wallet', + 'last_lt' + ], + properties: { + address: { type: 'string', format: 'address' }, + is_wallet: { type: 'boolean' }, + balance: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + stats: { $ref: '#/components/schemas/WalletStats' }, + plugins: { type: 'array', items: { $ref: '#/components/schemas/WalletPlugin' } }, + status: { $ref: '#/components/schemas/AccountStatus' }, + last_activity: { type: 'integer', format: 'int64' }, + name: { type: 'string' }, + icon: { type: 'string' }, + get_methods: { type: 'array', deprecated: true, items: { type: 'string' } }, + is_suspended: { type: 'boolean' }, + signature_disabled: { type: 'boolean' }, + interfaces: { type: 'array', items: { type: 'string' } }, + last_lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' } + } + }, '#/components/schemas/Account': { type: 'object', required: ['address', 'balance', 'status', 'last_activity', 'get_methods', 'is_wallet'], @@ -4259,15 +4633,29 @@ const components = { stateInit: { type: 'string', format: 'cell' } } }, + '#/components/schemas/GaslessTx': { + type: 'object', + required: ['protocol_name'], + properties: { protocol_name: { type: 'string' } } + }, '#/components/schemas/SignRawParams': { type: 'object', - required: ['messages', 'relay_address', 'commission', 'from', 'valid_until'], + required: [ + 'messages', + 'relay_address', + 'commission', + 'from', + 'valid_until', + 'protocol_name' + ], properties: { + protocol_name: { type: 'string' }, relay_address: { type: 'string', format: 'address' }, commission: { type: 'string', 'x-js-format': 'bigint' }, from: { type: 'string', format: 'address' }, valid_until: { type: 'integer', format: 'int64' }, - messages: { type: 'array', items: { $ref: '#/components/schemas/SignRawMessage' } } + messages: { type: 'array', items: { $ref: '#/components/schemas/SignRawMessage' } }, + emulation: { $ref: '#/components/schemas/MessageConsequences' } } }, '#/components/schemas/MethodExecutionResult': { @@ -4660,7 +5048,7 @@ const components = { }, '#/components/schemas/JettonVerificationType': { type: 'string', - enum: ['whitelist', 'blacklist', 'none'] + enum: ['whitelist', 'graylist', 'blacklist', 'none'] }, '#/components/schemas/JettonPreview': { type: 'object', @@ -4681,6 +5069,7 @@ const components = { required: ['balance', 'wallet_address', 'jetton'], properties: { balance: { type: 'string', 'x-js-format': 'bigint' }, + scaled_ui_balance: { type: 'string', 'x-js-format': 'bigint' }, price: { $ref: '#/components/schemas/TokenRates' }, wallet_address: { $ref: '#/components/schemas/AccountAddress' }, jetton: { $ref: '#/components/schemas/JettonPreview' }, @@ -4702,12 +5091,29 @@ const components = { balances: { type: 'array', items: { $ref: '#/components/schemas/JettonBalance' } } } }, + '#/components/schemas/CurrencyType': { + type: 'string', + enum: ['native', 'extra_currency', 'jetton', 'fiat'] + }, + '#/components/schemas/VaultDepositInfo': { + type: 'object', + required: ['price', 'vault'], + properties: { + price: { $ref: '#/components/schemas/Price' }, + vault: { type: 'string', format: 'address' } + } + }, '#/components/schemas/Price': { type: 'object', - required: ['value', 'token_name'], + required: ['currency_type', 'value', 'decimals', 'token_name', 'verification', 'image'], properties: { + currency_type: { $ref: '#/components/schemas/CurrencyType' }, value: { type: 'string', 'x-js-format': 'bigint' }, - token_name: { type: 'string' } + decimals: { type: 'integer' }, + token_name: { type: 'string' }, + verification: { $ref: '#/components/schemas/TrustType' }, + image: { type: 'string' }, + jetton: { type: 'string', format: 'address' } } }, '#/components/schemas/ImagePreview': { @@ -4755,9 +5161,9 @@ const components = { previews: { type: 'array', items: { $ref: '#/components/schemas/ImagePreview' } }, dns: { type: 'string' }, approved_by: { + allOf: { '0': { $ref: '#/components/schemas/NftApprovedBy' } }, deprecated: true, - description: 'please use trust field', - $ref: '#/components/schemas/NftApprovedBy' + description: 'Please use trust field' }, include_cnft: { type: 'boolean' }, trust: { $ref: '#/components/schemas/TrustType' } @@ -4782,7 +5188,7 @@ const components = { required: ['address', 'seqno', 'threshold', 'signers', 'proposers', 'orders'], properties: { address: { type: 'string', format: 'address' }, - seqno: { type: 'integer', format: 'int64' }, + seqno: { type: 'string' }, threshold: { type: 'integer', format: 'int32' }, signers: { type: 'array', items: { type: 'string', format: 'address' } }, proposers: { type: 'array', items: { type: 'string', format: 'address' } }, @@ -4801,11 +5207,12 @@ const components = { 'expiration_date', 'risk', 'creation_date', - 'signed_by' + 'signed_by', + 'multisig_address' ], properties: { address: { type: 'string', format: 'address' }, - order_seqno: { type: 'integer', format: 'int64' }, + order_seqno: { type: 'string' }, threshold: { type: 'integer', format: 'int32' }, sent_for_execution: { type: 'boolean' }, signers: { type: 'array', items: { type: 'string', format: 'address' } }, @@ -4813,7 +5220,17 @@ const components = { expiration_date: { type: 'integer', format: 'int64' }, risk: { $ref: '#/components/schemas/Risk' }, creation_date: { type: 'integer', format: 'int64' }, - signed_by: { type: 'array', items: { type: 'string', format: 'address' } } + signed_by: { type: 'array', items: { type: 'string', format: 'address' } }, + multisig_address: { type: 'string', format: 'address' }, + changing_parameters: { + type: 'object', + required: ['threshold', 'signers', 'proposers'], + properties: { + threshold: { type: 'integer', format: 'int32' }, + signers: { type: 'array', items: { type: 'string', format: 'address' } }, + proposers: { type: 'array', items: { type: 'string', format: 'address' } } + } + } } }, '#/components/schemas/Refund': { @@ -4860,11 +5277,11 @@ const components = { enum: [ 'TonTransfer', 'ExtraCurrencyTransfer', + 'ContractDeploy', 'JettonTransfer', 'JettonBurn', 'JettonMint', 'NftItemTransfer', - 'ContractDeploy', 'Subscribe', 'UnSubscribe', 'AuctionBid', @@ -4872,13 +5289,19 @@ const components = { 'DepositStake', 'WithdrawStake', 'WithdrawStakeRequest', + 'ElectionsDepositStake', + 'ElectionsRecoverStake', 'JettonSwap', 'SmartContractExec', - 'ElectionsRecoverStake', - 'ElectionsDepositStake', 'DomainRenew', - 'InscriptionTransfer', - 'InscriptionMint', + 'Purchase', + 'AddExtension', + 'RemoveExtension', + 'SetSignatureAllowedAction', + 'GasRelay', + 'DepositTokenStake', + 'WithdrawTokenStakeRequest', + 'LiquidityDeposit', 'Unknown' ] }, @@ -4902,8 +5325,16 @@ const components = { JettonSwap: { $ref: '#/components/schemas/JettonSwapAction' }, SmartContractExec: { $ref: '#/components/schemas/SmartContractAction' }, DomainRenew: { $ref: '#/components/schemas/DomainRenewAction' }, - InscriptionTransfer: { $ref: '#/components/schemas/InscriptionTransferAction' }, - InscriptionMint: { $ref: '#/components/schemas/InscriptionMintAction' }, + Purchase: { $ref: '#/components/schemas/PurchaseAction' }, + AddExtension: { $ref: '#/components/schemas/AddExtensionAction' }, + RemoveExtension: { $ref: '#/components/schemas/RemoveExtensionAction' }, + SetSignatureAllowedAction: { $ref: '#/components/schemas/SetSignatureAllowedAction' }, + GasRelay: { $ref: '#/components/schemas/GasRelayAction' }, + DepositTokenStake: { $ref: '#/components/schemas/DepositTokenStakeAction' }, + WithdrawTokenStakeRequest: { + $ref: '#/components/schemas/WithdrawTokenStakeRequestAction' + }, + LiquidityDeposit: { $ref: '#/components/schemas/LiquidityDepositAction' }, simple_preview: { $ref: '#/components/schemas/ActionSimplePreview' }, base_transactions: { type: 'array', items: { type: 'string' } } } @@ -4970,28 +5401,48 @@ const components = { renewer: { $ref: '#/components/schemas/AccountAddress' } } }, - '#/components/schemas/InscriptionMintAction': { + '#/components/schemas/GasRelayAction': { type: 'object', - required: ['type', 'ticker', 'recipient', 'amount', 'decimals'], + required: ['amount', 'relayer', 'target'], properties: { - recipient: { $ref: '#/components/schemas/AccountAddress' }, - amount: { type: 'string', 'x-js-format': 'bigint' }, - type: { type: 'string', enum: ['ton20', 'gram20'] }, - ticker: { type: 'string' }, - decimals: { type: 'integer' } + amount: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + relayer: { $ref: '#/components/schemas/AccountAddress' }, + target: { $ref: '#/components/schemas/AccountAddress' } } }, - '#/components/schemas/InscriptionTransferAction': { + '#/components/schemas/PurchaseAction': { type: 'object', - required: ['sender', 'recipient', 'amount', 'type', 'ticker', 'decimals'], + required: ['source', 'destination', 'invoice_id', 'amount', 'metadata'], properties: { - sender: { $ref: '#/components/schemas/AccountAddress' }, - recipient: { $ref: '#/components/schemas/AccountAddress' }, - amount: { type: 'string', 'x-js-format': 'bigint' }, - comment: { type: 'string' }, - type: { type: 'string', enum: ['ton20', 'gram20'] }, - ticker: { type: 'string' }, - decimals: { type: 'integer' } + source: { $ref: '#/components/schemas/AccountAddress' }, + destination: { $ref: '#/components/schemas/AccountAddress' }, + invoice_id: { type: 'string' }, + amount: { $ref: '#/components/schemas/Price' }, + metadata: { $ref: '#/components/schemas/Metadata' } + } + }, + '#/components/schemas/AddExtensionAction': { + type: 'object', + required: ['wallet', 'extension'], + properties: { + wallet: { $ref: '#/components/schemas/AccountAddress' }, + extension: { type: 'string', format: 'address' } + } + }, + '#/components/schemas/RemoveExtensionAction': { + type: 'object', + required: ['wallet', 'extension'], + properties: { + wallet: { $ref: '#/components/schemas/AccountAddress' }, + extension: { type: 'string', format: 'address' } + } + }, + '#/components/schemas/SetSignatureAllowedAction': { + type: 'object', + required: ['wallet', 'allowed'], + properties: { + wallet: { $ref: '#/components/schemas/AccountAddress' }, + allowed: { type: 'boolean' } } }, '#/components/schemas/NftItemTransferAction': { @@ -5016,6 +5467,7 @@ const components = { senders_wallet: { type: 'string', format: 'address' }, recipients_wallet: { type: 'string', format: 'address' }, amount: { type: 'string', 'x-js-format': 'bigint' }, + scaled_ui_amount: { type: 'string', 'x-js-format': 'bigint' }, comment: { type: 'string' }, encrypted_comment: { $ref: '#/components/schemas/EncryptedComment' }, refund: { $ref: '#/components/schemas/Refund' }, @@ -5052,22 +5504,25 @@ const components = { }, '#/components/schemas/SubscriptionAction': { type: 'object', - required: ['subscriber', 'subscription', 'beneficiary', 'amount', 'initial'], + required: ['subscriber', 'subscription', 'beneficiary', 'admin', 'price', 'initial'], properties: { subscriber: { $ref: '#/components/schemas/AccountAddress' }, subscription: { type: 'string', format: 'address' }, beneficiary: { $ref: '#/components/schemas/AccountAddress' }, - amount: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + admin: { $ref: '#/components/schemas/AccountAddress' }, + amount: { deprecated: true, type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + price: { $ref: '#/components/schemas/Price' }, initial: { type: 'boolean' } } }, '#/components/schemas/UnSubscriptionAction': { type: 'object', - required: ['subscriber', 'subscription', 'beneficiary'], + required: ['subscriber', 'subscription', 'beneficiary', 'admin'], properties: { subscriber: { $ref: '#/components/schemas/AccountAddress' }, subscription: { type: 'string', format: 'address' }, - beneficiary: { $ref: '#/components/schemas/AccountAddress' } + beneficiary: { $ref: '#/components/schemas/AccountAddress' }, + admin: { $ref: '#/components/schemas/AccountAddress' } } }, '#/components/schemas/AuctionBidAction': { @@ -5131,7 +5586,7 @@ const components = { type: 'object', required: ['dex', 'amount_in', 'amount_out', 'user_wallet', 'router'], properties: { - dex: { type: 'string', enum: ['stonfi', 'dedust', 'megatonfi'] }, + dex: { type: 'string' }, amount_in: { type: 'string', 'x-js-format': 'bigint' }, amount_out: { type: 'string', 'x-js-format': 'bigint' }, ton_in: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, @@ -5153,6 +5608,33 @@ const components = { buyer: { $ref: '#/components/schemas/AccountAddress' } } }, + '#/components/schemas/DepositTokenStakeAction': { + type: 'object', + required: ['staker', 'protocol'], + properties: { + staker: { $ref: '#/components/schemas/AccountAddress' }, + protocol: { $ref: '#/components/schemas/Protocol' }, + stake_meta: { $ref: '#/components/schemas/Price' } + } + }, + '#/components/schemas/WithdrawTokenStakeRequestAction': { + type: 'object', + required: ['staker', 'protocol'], + properties: { + staker: { $ref: '#/components/schemas/AccountAddress' }, + protocol: { $ref: '#/components/schemas/Protocol' }, + stake_meta: { $ref: '#/components/schemas/Price' } + } + }, + '#/components/schemas/LiquidityDepositAction': { + type: 'object', + required: ['protocol', 'from', 'tokens'], + properties: { + protocol: { $ref: '#/components/schemas/Protocol' }, + from: { $ref: '#/components/schemas/AccountAddress' }, + tokens: { type: 'array', items: { $ref: '#/components/schemas/VaultDepositInfo' } } + } + }, '#/components/schemas/ActionSimplePreview': { type: 'object', required: ['name', 'description', 'accounts'], @@ -5175,7 +5657,8 @@ const components = { 'is_scam', 'lt', 'in_progress', - 'extra' + 'extra', + 'progress' ], properties: { event_id: { type: 'string' }, @@ -5185,7 +5668,8 @@ const components = { is_scam: { type: 'boolean' }, lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, in_progress: { type: 'boolean' }, - extra: { type: 'integer', format: 'int64' } + extra: { type: 'integer', format: 'int64' }, + progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 } } }, '#/components/schemas/AccountEvents': { @@ -5196,6 +5680,42 @@ const components = { next_from: { type: 'integer', format: 'int64' } } }, + '#/components/schemas/Purchase': { + type: 'object', + required: [ + 'event_id', + 'invoice_id', + 'source', + 'destination', + 'lt', + 'utime', + 'amount', + 'metadata' + ], + properties: { + event_id: { type: 'string' }, + invoice_id: { type: 'string' }, + source: { $ref: '#/components/schemas/AccountAddress' }, + destination: { $ref: '#/components/schemas/AccountAddress' }, + lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + utime: { type: 'integer', format: 'int64' }, + amount: { $ref: '#/components/schemas/Price' }, + metadata: { $ref: '#/components/schemas/Metadata' } + } + }, + '#/components/schemas/AccountPurchases': { + type: 'object', + required: ['purchases', 'next_from'], + properties: { + purchases: { type: 'array', items: { $ref: '#/components/schemas/Purchase' } }, + next_from: { type: 'integer', format: 'int64' } + } + }, + '#/components/schemas/Metadata': { + type: 'object', + required: ['encrypted_binary'], + properties: { encrypted_binary: { type: 'string' }, decryption_key: { type: 'string' } } + }, '#/components/schemas/TraceID': { type: 'object', required: ['id', 'utime'], @@ -5214,30 +5734,27 @@ const components = { '#/components/schemas/Subscription': { type: 'object', required: [ - 'address', - 'wallet_address', - 'beneficiary_address', - 'amount', + 'type', + 'status', 'period', - 'start_time', - 'timeout', - 'last_payment_time', - 'last_request_time', 'subscription_id', - 'failed_attempts' + 'payment_per_period', + 'wallet', + 'next_charge_at', + 'metadata' ], properties: { - address: { type: 'string', format: 'address' }, - wallet_address: { type: 'string', format: 'address' }, - beneficiary_address: { type: 'string', format: 'address' }, - amount: { type: 'integer', format: 'int64' }, + type: { type: 'string' }, + status: { type: 'string', enum: ['not_ready', 'active', 'suspended', 'cancelled'] }, period: { type: 'integer', format: 'int64' }, - start_time: { type: 'integer', format: 'int64' }, - timeout: { type: 'integer', format: 'int64' }, - last_payment_time: { type: 'integer', format: 'int64' }, - last_request_time: { type: 'integer', format: 'int64' }, - subscription_id: { type: 'integer', format: 'int64' }, - failed_attempts: { type: 'integer', format: 'int32' } + subscription_id: { type: 'string' }, + payment_per_period: { $ref: '#/components/schemas/Price' }, + wallet: { $ref: '#/components/schemas/AccountAddress' }, + next_charge_at: { type: 'integer', format: 'int64' }, + metadata: { $ref: '#/components/schemas/Metadata' }, + address: { type: 'string', format: 'address' }, + beneficiary: { $ref: '#/components/schemas/AccountAddress' }, + admin: { $ref: '#/components/schemas/AccountAddress' } } }, '#/components/schemas/Subscriptions': { @@ -5353,7 +5870,8 @@ const components = { transfer_all_remaining_balance: { type: 'boolean' }, ton: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, jettons: { type: 'array', items: { $ref: '#/components/schemas/JettonQuantity' } }, - nfts: { type: 'array', items: { $ref: '#/components/schemas/NftItem' } } + nfts: { type: 'array', items: { $ref: '#/components/schemas/NftItem' } }, + total_equivalent: { type: 'number', format: 'float' } } }, '#/components/schemas/JettonQuantity': { @@ -5454,7 +5972,8 @@ const components = { 'value_flow', 'is_scam', 'lt', - 'in_progress' + 'in_progress', + 'progress' ], properties: { event_id: { type: 'string' }, @@ -5463,7 +5982,8 @@ const components = { value_flow: { type: 'array', items: { $ref: '#/components/schemas/ValueFlow' } }, is_scam: { type: 'boolean' }, lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, - in_progress: { type: 'boolean' } + in_progress: { type: 'boolean' }, + progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 } } }, '#/components/schemas/JettonMetadata': { @@ -5482,26 +6002,6 @@ const components = { custom_payload_api_uri: { type: 'string' } } }, - '#/components/schemas/InscriptionBalances': { - type: 'object', - required: ['inscriptions'], - properties: { - inscriptions: { - type: 'array', - items: { $ref: '#/components/schemas/InscriptionBalance' } - } - } - }, - '#/components/schemas/InscriptionBalance': { - type: 'object', - required: ['type', 'ticker', 'balance', 'decimals'], - properties: { - type: { type: 'string', enum: ['ton20', 'gram20'] }, - ticker: { type: 'string' }, - balance: { type: 'string', 'x-js-format': 'bigint' }, - decimals: { type: 'integer' } - } - }, '#/components/schemas/Jettons': { type: 'object', required: ['jettons'], @@ -5724,6 +6224,7 @@ const components = { required: ['code', 'code_hash', 'methods', 'compiler'], properties: { code: { type: 'string', format: 'cell' }, + disassembled_code: { type: 'string' }, code_hash: { type: 'string' }, methods: { type: 'array', items: { $ref: '#/components/schemas/Method' } }, compiler: { type: 'string', enum: ['func', 'fift', 'tact'] }, @@ -5780,6 +6281,78 @@ const components = { type: 'object', required: ['id', 'method'], properties: { id: { type: 'integer', format: 'int64' }, method: { type: 'string' } } + }, + '#/components/schemas/NftOperations': { + type: 'object', + required: ['operations'], + properties: { + operations: { type: 'array', items: { $ref: '#/components/schemas/NftOperation' } }, + next_from: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' } + } + }, + '#/components/schemas/NftOperation': { + type: 'object', + required: ['operation', 'utime', 'lt', 'transaction_hash', 'item'], + properties: { + operation: { type: 'string' }, + utime: { type: 'integer', format: 'int64' }, + lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + transaction_hash: { type: 'string' }, + source: { $ref: '#/components/schemas/AccountAddress' }, + destination: { $ref: '#/components/schemas/AccountAddress' }, + item: { $ref: '#/components/schemas/NftItem' } + } + }, + '#/components/schemas/JettonOperations': { + type: 'object', + required: ['operations'], + properties: { + operations: { type: 'array', items: { $ref: '#/components/schemas/JettonOperation' } }, + next_from: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' } + } + }, + '#/components/schemas/JettonOperation': { + type: 'object', + required: [ + 'operation', + 'utime', + 'lt', + 'jetton', + 'transaction_hash', + 'amount', + 'trace_id', + 'query_id' + ], + properties: { + operation: { type: 'string', enum: ['transfer', 'mint', 'burn'] }, + utime: { type: 'integer', format: 'int64' }, + lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + transaction_hash: { type: 'string' }, + source: { $ref: '#/components/schemas/AccountAddress' }, + destination: { $ref: '#/components/schemas/AccountAddress' }, + amount: { type: 'string', 'x-js-format': 'bigint' }, + jetton: { $ref: '#/components/schemas/JettonPreview' }, + trace_id: { type: 'string' }, + query_id: { type: 'string', 'x-js-format': 'bigint' }, + payload: {} + } + }, + '#/components/schemas/ExecGetMethodArgType': { + type: 'string', + enum: ['nan', 'null', 'tinyint', 'int257', 'slice', 'cell_boc_base64', 'slice_boc_hex'] + }, + '#/components/schemas/ExecGetMethodArg': { + type: 'object', + required: ['type', 'value'], + properties: { + type: { $ref: '#/components/schemas/ExecGetMethodArgType' }, + value: { type: 'string' } + } + }, + '#/components/schemas/Protocol': { + type: 'object', + required: ['name'], + properties: { name: { type: 'string' }, image: { type: 'string' } } } }; /** @@ -6425,6 +6998,23 @@ export const getBlockchainBlock = (blockId: string, params: RequestParams = {}) }); }; +/** + * @description Download blockchain block BOC + * + * @tags Blockchain + * @name DownloadBlockchainBlockBoc + * @request GET:/v2/blockchain/blocks/{block_id}/boc + */ +export const downloadBlockchainBlockBoc = (blockId: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/blocks/${blockId}/boc`, + method: 'GET', + ...params + }); + + return prepareResponse(req); +}; + /** * @description Get blockchain block shards * @@ -6728,25 +7318,17 @@ export const execGetMethodForBlockchainAccount = ( methodName: string, query?: { /** - * Supported values: - * "NaN" for NaN type, - * "Null" for Null type, - * 10-base digits for tiny int type (Example: 100500), - * 0x-prefixed hex digits for int257 (Example: 0xfa01d78381ae32), - * all forms of addresses for slice type (Example: 0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e), - * single-root base64-encoded BOC for cell (Example: "te6ccgEBAQEAAgAAAA=="), - * single-root hex-encoded BOC for slice (Example: b5ee9c72010101010002000000) + * Array of method arguments in string format. Supported value formats: + * - "NaN" for Not-a-Number type + * - "Null" for Null type + * - Decimal integers for tinyint type (e.g., "100500") + * - 0x-prefixed hex strings for int257 type (e.g., "0xfa01d78381ae32") + * - TON blockchain addresses for slice type (e.g., "0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e") + * - Base64-encoded BOC for cell type (e.g., "te6ccgEBAQEAAgAAAA==") + * - Hex-encoded BOC for slice type (e.g., "b5ee9c72010101010002000000") * @example ["0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8"] */ args?: string[]; - /** - * A temporary fix to switch to a scheme with direct ordering of arguments. - * If equal to false, then the method takes arguments in direct order, - * e.g. for get_nft_content(int index, cell individual_content) we pass a list of arguments [index, individual_content]. - * If equal to true, then the method takes arguments in reverse order, e.g. [individual_content, index]. - * @default true - */ - fix_order?: boolean; }, params: RequestParams = {} ) => { @@ -6764,6 +7346,41 @@ export const execGetMethodForBlockchainAccount = ( }); }; +/** + * @description Execute get method for account + * + * @tags Blockchain + * @name ExecGetMethodWithBodyForBlockchainAccount + * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} + */ +export const execGetMethodWithBodyForBlockchainAccount = ( + accountId_Address: Address, + methodName: string, + data: { + args: ExecGetMethodArg[]; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['args'], + properties: { + args: { type: 'array', items: { $ref: '#/components/schemas/ExecGetMethodArg' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/MethodExecutionResult' + }); +}; + /** * @description Send message to blockchain * @@ -6857,8 +7474,28 @@ export const blockchainAccountInspect = ( ...params }); - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainAccountInspect' + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainAccountInspect' + }); +}; + +/** + * @description Get library cell + * + * @tags Blockchain + * @name GetLibraryByHash + * @request GET:/v2/blockchain/libraries/{hash} + */ +export const getLibraryByHash = (hash: string, params: RequestParams = {}) => { + const req = getHttpClient().request({ + path: `/v2/blockchain/libraries/${hash}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainLibrary' }); }; @@ -7037,18 +7674,6 @@ export const getAccountJettonsHistory = ( * @example 100 */ limit: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - start_date?: number; - /** - * @format int64 - * @max 2114380800 - * @example 1668436763 - */ - end_date?: number; }, params: RequestParams = {} ) => { @@ -7062,16 +7687,17 @@ export const getAccountJettonsHistory = ( }); return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' + $ref: '#/components/schemas/JettonOperations' }); }; /** - * @description Get the transfer jetton history for account and jetton + * @description Please use `getJettonAccountHistoryByID`` instead * * @tags Accounts * @name GetAccountJettonHistoryById * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history + * @deprecated */ export const getAccountJettonHistoryById = ( accountId_Address: Address, @@ -7538,14 +8164,15 @@ export const getAccountExtraCurrencyHistoryById = ( }; /** - * @description Get the transfer nft history + * @description Get the transfer jetton history for account and jetton * - * @tags NFT - * @name GetAccountNftHistory - * @request GET:/v2/accounts/{account_id}/nfts/history + * @tags Accounts + * @name GetJettonAccountHistoryById + * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history */ -export const getAccountNftHistory = ( +export const getJettonAccountHistoryById = ( accountId_Address: Address, + jettonId_Address: Address, query: { /** * omit this parameter to get last events @@ -7573,6 +8200,46 @@ export const getAccountNftHistory = ( end_date?: number; }, params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/jettons/${jettonId}/accounts/${accountId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonOperations' + }); +}; + +/** + * @description Get the transfer nft history + * + * @tags NFT + * @name GetAccountNftHistory + * @request GET:/v2/accounts/{account_id}/nfts/history + */ +export const getAccountNftHistory = ( + accountId_Address: Address, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + }, + params: RequestParams = {} ) => { const accountId = accountId_Address.toRawString(); const req = getHttpClient().request({ @@ -7584,7 +8251,7 @@ export const getAccountNftHistory = ( }); return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' + $ref: '#/components/schemas/NftOperations' }); }; @@ -7771,11 +8438,12 @@ export const getNftItemByAddress = (accountId_Address: Address, params: RequestP }; /** - * @description Get the transfer nfts history for account + * @description Please use `getAccountNftHistory`` instead * * @tags NFT * @name GetNftHistoryById * @request GET:/v2/nfts/{account_id}/history + * @deprecated */ export const getNftHistoryById = ( accountId_Address: Address, @@ -7846,10 +8514,18 @@ export const getDnsInfo = (domainName: string, params: RequestParams = {}) => { * @name DnsResolve * @request GET:/v2/dns/{domain_name}/resolve */ -export const dnsResolve = (domainName: string, params: RequestParams = {}) => { +export const dnsResolve = ( + domainName: string, + query?: { + /** @default false */ + filter?: boolean; + }, + params: RequestParams = {} +) => { const req = getHttpClient().request({ path: `/v2/dns/${domainName}/resolve`, method: 'GET', + query: query, format: 'json', ...params }); @@ -7939,167 +8615,6 @@ export const getEvent = (eventId: string, params: RequestParams = {}) => { return prepareResponse(req, { $ref: '#/components/schemas/Event' }); }; -/** - * @description Get all inscriptions by owner address. It's experimental API and can be dropped in the future. - * - * @tags Inscriptions - * @name GetAccountInscriptions - * @request GET:/v2/experimental/accounts/{account_id}/inscriptions - */ -export const getAccountInscriptions = ( - accountId_Address: Address, - query?: { - /** - * @min 1 - * @max 1000 - * @default 1000 - */ - limit?: number; - /** - * @min 0 - * @default 0 - */ - offset?: number; - }, - params: RequestParams = {} -) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/experimental/accounts/${accountId}/inscriptions`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/InscriptionBalances' - }); -}; - -/** - * @description Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. - * - * @tags Inscriptions - * @name GetAccountInscriptionsHistory - * @request GET:/v2/experimental/accounts/{account_id}/inscriptions/history - */ -export const getAccountInscriptionsHistory = ( - accountId_Address: Address, - query?: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @default 100 - * @example 100 - */ - limit?: number; - }, - params: RequestParams = {} -) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/experimental/accounts/${accountId}/inscriptions/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); -}; - -/** - * @description Get the transfer inscriptions history for account. It's experimental API and can be dropped in the future. - * - * @tags Inscriptions - * @name GetAccountInscriptionsHistoryByTicker - * @request GET:/v2/experimental/accounts/{account_id}/inscriptions/{ticker}/history - */ -export const getAccountInscriptionsHistoryByTicker = ( - accountId_Address: Address, - ticker: string, - query?: { - /** - * omit this parameter to get last events - * @format bigint - * @example 25758317000002 - */ - before_lt?: bigint; - /** - * @min 1 - * @max 1000 - * @default 100 - * @example 100 - */ - limit?: number; - }, - params: RequestParams = {} -) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/experimental/accounts/${accountId}/inscriptions/${ticker}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); -}; - -/** - * @description return comment for making operation with inscription. please don't use it if you don't know what you are doing - * - * @tags Inscriptions - * @name GetInscriptionOpTemplate - * @request GET:/v2/experimental/inscriptions/op-template - */ -export const getInscriptionOpTemplate = ( - query: { - /** @example "ton20" */ - type: 'ton20' | 'gram20'; - destination?: string; - comment?: string; - /** @example "transfer" */ - operation: 'transfer'; - /** - * @format bigint - * @example "1000000000" - */ - amount: bigint; - /** @example "nano" */ - ticker: string; - /** @example "UQAs87W4yJHlF8mt29ocA4agnMrLsOP69jC1HPyBUjJay7Mg" */ - who: string; - }, - params: RequestParams = {} -) => { - const req = getHttpClient().request({ - path: `/v2/experimental/inscriptions/op-template`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['comment', 'destination'], - properties: { comment: { type: 'string' }, destination: { type: 'string' } } - }); -}; - /** * @description Get a list of all indexed jetton masters in the blockchain. * @@ -8207,6 +8722,7 @@ export const getJettonHolders = ( limit?: number; /** * @min 0 + * @max 9000 * @default 0 */ offset?: number; @@ -8445,13 +8961,13 @@ export const getStorageProviders = (params: RequestParams = {}) => { export const getRates = ( query: { /** - * accept ton and jetton master addresses, separated by commas + * accept cryptocurrencies or jetton master addresses, separated by commas * @maxItems 100 * @example ["ton"] */ - tokens: string[]; + tokens: (Address | string)[]; /** - * accept ton and all possible fiat currencies, separated by commas + * accept cryptocurrencies and all possible fiat currencies, separated by commas * @maxItems 50 * @example ["ton","usd","rub"] */ @@ -8489,11 +9005,8 @@ export const getRates = ( */ export const getChartRates = ( query: { - /** - * accept jetton master address - * @format address - */ - token: Address; + /** accept cryptocurrencies or jetton master addresses */ + token: Address | string; /** @example "usd" */ currency?: string; /** @@ -8521,10 +9034,7 @@ export const getChartRates = ( const req = getHttpClient().request({ path: `/v2/rates/chart`, method: 'GET', - query: query && { - ...query, - token: query.token?.toRawString() - }, + query: query, format: 'json', ...params }); @@ -8707,6 +9217,25 @@ export const getAccountSeqno = (accountId_Address: Address, params: RequestParam return prepareResponse(req, { $ref: '#/components/schemas/Seqno' }); }; +/** + * @description Get human-friendly information about a wallet without low-level details. + * + * @tags Wallet + * @name GetWalletInfo + * @request GET:/v2/wallet/{account_id} + */ +export const getWalletInfo = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/wallet/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Wallet' }); +}; + /** * @description Get wallets by public key * @@ -8723,7 +9252,7 @@ export const getWalletsByPublicKey = (publicKey: string, params: RequestParams = }); return prepareResponse(req, { - $ref: '#/components/schemas/Accounts' + $ref: '#/components/schemas/Wallets' }); }; @@ -8755,6 +9284,13 @@ export const gaslessConfig = (params: RequestParams = {}) => { export const gaslessEstimate = ( masterId_Address: Address, data: { + /** + * TONAPI verifies that the account has enough jettons to pay the commission and make a transfer. + * @default false + */ + throwErrorIfNotEnoughJettons?: boolean; + /** @default false */ + returnEmulation?: boolean; /** @format address */ walletAddress: Address; walletPublicKey: string; @@ -8773,6 +9309,8 @@ export const gaslessEstimate = ( type: 'object', required: ['messages', 'walletAddress', 'walletPublicKey'], properties: { + throwErrorIfNotEnoughJettons: { type: 'boolean', default: false }, + returnEmulation: { type: 'boolean', default: false }, walletAddress: { type: 'string', format: 'address' }, walletPublicKey: { type: 'string' }, messages: { @@ -8821,10 +9359,11 @@ export const gaslessSend = ( boc: { type: 'string', format: 'cell' } } }), + format: 'json', ...params }); - return prepareResponse(req); + return prepareResponse(req, { $ref: '#/components/schemas/GaslessTx' }); }; /** @@ -9529,6 +10068,27 @@ export const getMultisigAccount = (accountId_Address: Address, params: RequestPa return prepareResponse(req, { $ref: '#/components/schemas/Multisig' }); }; +/** + * @description Get multisig order + * + * @tags Multisig + * @name GetMultisigOrder + * @request GET:/v2/multisig/order/{account_id} + */ +export const getMultisigOrder = (accountId_Address: Address, params: RequestParams = {}) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/multisig/order/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/MultisigOrder' + }); +}; + /** * @description Decode a given message. Only external incoming messages can be decoded currently. * @@ -9559,7 +10119,7 @@ export const decodeMessage = ( }; /** - * @description Emulate sending message to blockchain + * @description Emulate sending message to retrieve general blockchain events * * @tags Emulation, Events * @name EmulateMessageToEvent @@ -9592,7 +10152,7 @@ export const emulateMessageToEvent = ( }; /** - * @description Emulate sending message to blockchain + * @description Emulate sending message to retrieve with a detailed execution trace * * @tags Emulation, Traces * @name EmulateMessageToTrace @@ -9625,7 +10185,7 @@ export const emulateMessageToTrace = ( }; /** - * @description Emulate sending message to blockchain + * @description Emulate sending message to retrieve the resulting wallet state * * @tags Emulation, Wallet * @name EmulateMessageToWallet @@ -9649,11 +10209,16 @@ export const emulateMessageToWallet = ( balance?: bigint; }[]; }, + query?: { + /** @example "usd" */ + currency?: string; + }, params: RequestParams = {} ) => { const req = getHttpClient().request({ path: `/v2/wallet/emulate`, method: 'POST', + query: query, body: prepareRequestData(data, { type: 'object', required: ['boc'], @@ -9682,7 +10247,7 @@ export const emulateMessageToWallet = ( }; /** - * @description Emulate sending message to blockchain + * @description Emulate sending message to retrieve account-specific events * * @tags Emulation, Accounts * @name EmulateMessageToAccountEvent @@ -9717,3 +10282,43 @@ export const emulateMessageToAccountEvent = ( $ref: '#/components/schemas/AccountEvent' }); }; + +/** + * @description Get history of purchases + * + * @tags Purchases + * @name GetPurchaseHistory + * @request GET:/v2/purchases/{account_id}/history + */ +export const getPurchaseHistory = ( + accountId_Address: Address, + query?: { + /** + * omit this parameter to get last invoices + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + }, + params: RequestParams = {} +) => { + const accountId = accountId_Address.toRawString(); + const req = getHttpClient().request({ + path: `/v2/purchases/${accountId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountPurchases' + }); +}; diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index b77388d..0a14ce5 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -230,7 +230,7 @@ const generateApiParams: GenerateApiParams = { async function main() { // Download schema and apply patches automatically - // await downloadSchema(openapiUrl, openapiPath); + await downloadSchema(openapiUrl, openapiPath); applySchemaPatches(openapiPath, schemaPatchesPath); generateApi(generateApiParams); diff --git a/packages/client/src/schema-patches.json b/packages/client/src/schema-patches.json index ff3addc..1d55aa2 100644 --- a/packages/client/src/schema-patches.json +++ b/packages/client/src/schema-patches.json @@ -16,7 +16,143 @@ ], "items": false, "additionalItems": false, - "example": [[1668436763, 97.21323234]] + "example": [1668436763, 97.21323234] + } + } + }, + "paths": { + "/v2/rates": { + "get": { + "parameters": [ + { + "in": "query", + "name": "tokens", + "description": "accept cryptocurrencies or jetton master addresses, separated by commas", + "required": true, + "explode": false, + "schema": { + "type": "array", + "maxItems": 100, + "items": { + "oneOf": [ + { + "type": "string", + "format": "address" + }, + { + "type": "string" + } + ] + }, + "example": ["ton"] + } + }, + { + "in": "query", + "name": "currencies", + "description": "accept cryptocurrencies and all possible fiat currencies, separated by commas", + "required": true, + "explode": false, + "schema": { + "type": "array", + "maxItems": 50, + "items": { + "type": "string" + }, + "example": ["ton","usd","rub"] + } + } + ] + } + }, + "/v2/rates/chart": { + "get": { + "parameters": [ + { + "in": "query", + "name": "token", + "description": "accept cryptocurrencies or jetton master addresses", + "required": true, + "schema": { + "oneOf": [ + { + "type": "string", + "format": "address" + }, + { + "type": "string" + } + ] + } + }, + { + "in": "query", + "name": "currency", + "required": false, + "schema": { + "type": "string", + "example": "usd" + } + }, + { + "name": "start_date", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int64", + "maximum": 2114380800, + "example": 1668436763 + } + }, + { + "name": "end_date", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int64", + "maximum": 2114380800, + "example": 1668436763 + } + }, + { + "name": "points_count", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int", + "maximum": 200, + "minimum": 0, + "default": 200 + } + } + ], + "responses": { + "200": { + "description": "token chart", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["points"], + "properties": { + "points": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChartPoints" + } + } + } + } + } + } + }, + "default": { + "$ref": "#/components/responses/Error" + } + } } } } From dc86a6075bcd84906c3122eeeeb596ced317ceb8 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Wed, 12 Nov 2025 02:56:10 +0400 Subject: [PATCH 08/27] chore: bump version to 0.5.0-alpha.0 in package.json and update client header --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- packages/client/src/generate.ts | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2d6e021..160672e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.4.0", + "version": "0.5.0-alpha.0", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 8dc4346..72547b9 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.4.0", + "version": "0.5.0-alpha.0", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 49dd78f..42b6d0f 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3678,7 +3678,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.4.0` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.0` }; const preparedApiConfig = { diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index 0a14ce5..afc2a18 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -230,8 +230,8 @@ const generateApiParams: GenerateApiParams = { async function main() { // Download schema and apply patches automatically - await downloadSchema(openapiUrl, openapiPath); - applySchemaPatches(openapiPath, schemaPatchesPath); + // await downloadSchema(openapiUrl, openapiPath); + // applySchemaPatches(openapiPath, schemaPatchesPath); generateApi(generateApiParams); } From 58044f894562052096e9f4654ce63ba79a676e87 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Thu, 13 Nov 2025 13:09:49 +0400 Subject: [PATCH 09/27] refactor: enhance TonApi client structure and error handling - Introduced a new instance-based approach for the TonApiClient, allowing for better encapsulation and configuration. - Updated error handling to throw specific errors directly, improving clarity and consistency in error management. - Refactored response preparation to streamline error handling and ensure proper error propagation. - Enhanced documentation and examples to reflect the new client structure and usage patterns. - Updated tests to validate the new instance-based client and error handling mechanisms, ensuring comprehensive coverage. --- packages/client/src/client.ts | 6201 ++++++++++++----- packages/client/src/templates/api.ejs | 70 +- packages/client/src/templates/errors.ejs | 8 +- .../client/src/templates/procedure-call.ejs | 27 +- packages/client/src/templates/utils.ejs | 55 +- tests/client/client.test.ts | 386 +- tests/client/errors.test.ts | 945 ++- tests/client/memory-leak.test.ts | 62 +- tests/client/parse-address.test.ts | 15 +- tests/client/parse-bigint.test.ts | 19 +- tests/client/parse-cell.test.ts | 16 +- tests/client/parse-tuple.test.ts | 16 +- tests/client/services.test.ts | 43 +- tests/client/utils/client.ts | 27 +- 14 files changed, 5138 insertions(+), 2752 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 42b6d0f..728adaa 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -6430,13 +6430,13 @@ export class TonApiNetworkError extends TonApiErrorAbstract { } /** - * Parsing error for Address, Cell, BigInt, or TupleItem + * Parsing error for Address, Cell, BigInt, TupleItem, or Unknown * Thrown when SDK fails to parse data returned from TonAPI * * @example * ```typescript * if (error instanceof TonApiParsingError) { - * console.log('Parsing type:', error.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' + * console.log('Parsing type:', error.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem', 'Unknown' * console.log('Error message:', error.message); * console.log('Original response:', error.response); * } @@ -6444,11 +6444,11 @@ export class TonApiNetworkError extends TonApiErrorAbstract { */ export class TonApiParsingError extends TonApiErrorAbstract { readonly type = 'parsing_error' as const; - readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem'; + readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown'; readonly response: unknown; constructor( - parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem', + parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown', message: string, cause: unknown, response: unknown @@ -6564,45 +6564,39 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } -async function prepareResponse(promise: Promise, orSchema?: any): Promise> { - return await promise +async function prepareResponse(promise: Promise, orSchema?: any): Promise { + return promise .then(obj => { try { - // Parse and transform response data - const data = prepareResponseData(obj, orSchema, obj); - return { data, error: null } as Result; + return prepareResponseData(obj, orSchema, obj); } catch (parseError: unknown) { - // Handle our custom parsing errors - return the error instance directly if (parseError instanceof TonApiParsingError) { - return { - data: null, - error: parseError - } as Result; + throw parseError; } - // Handle other errors (should not happen, but defensive) const message = parseError instanceof Error ? `SDK parsing error: ${parseError.message}` : 'SDK parsing error: Unknown error'; - // Create a generic parsing error for unexpected cases - return { - data: null, - error: new TonApiParsingError('Cell', message, parseError, obj) - } as Result; + throw new TonApiParsingError('Unknown', message, parseError, obj); } }) - .catch(async response => { - // Network error (fetch failed) + .catch((response: any) => { + // Re-throw our custom errors without wrapping + if ( + response instanceof TonApiParsingError || + response instanceof TonApiNetworkError || + response instanceof TonApiHttpError || + response instanceof TonApiUnknownError + ) { + throw response; + } + if (response instanceof Error) { - return { - data: null, - error: new TonApiNetworkError(response.message || 'Network error', response) - } as Result; + throw new TonApiNetworkError(response.message || 'Network error', response); } - // HTTP error with response if (response && typeof response === 'object' && response.status !== undefined) { const status = response.status; const url = response.url || ''; @@ -6624,17 +6618,10 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis } } - return { - data: null, - error: new TonApiHttpError(status, message, url, code, response) - } as Result; + throw new TonApiHttpError(status, message, url, code, response); } - // Unknown error - return { - data: null, - error: new TonApiUnknownError('Unknown error occurred', response) - } as Result; + throw new TonApiUnknownError('Unknown error occurred', response); }); } @@ -6785,51 +6772,3559 @@ function prepareRequestData(data: any, orSchema?: any): any { return (data as Address).toRawString(); } - if (schema.format === 'cell') { - return (data as Cell).toBoc().toString('hex'); - } + if (schema.format === 'cell') { + return (data as Cell).toBoc().toString('hex'); + } + + if (schema.format === 'cell-base64') { + return (data as Cell).toBoc().toString('base64'); + } + + if (schema['x-js-format'] === 'bigint') { + return (data as bigint).toString(); + } + } + } + + if (data !== null && typeof data === 'object') { + return Object.keys(data).reduce( + (acc, key) => { + const objSchema = schema?.properties && schema.properties[key]; + + const snakeCaseKey = camelToSnake(key); + + acc[snakeCaseKey] = prepareRequestData(data[key], objSchema); + return acc; + }, + {} as Record + ); + } + return data; +} + +/** + * @title REST api to TON blockchain explorer + * @version 2.0.0 + * @baseUrl https://tonapi.io + * @contact Support + * + * Provide access to indexed TON blockchain + */ + +/** + * TonAPI Client - instance-based approach (recommended) + * + * @example + * ```typescript + * const client = new TonApiClient({ + * baseUrl: 'https://tonapi.io', + * apiKey: process.env.TON_API_KEY + * }); + * + * try { + * const account = await client.getAccount(address); + * console.log(account); + * } catch (error) { + * console.error('Error:', error.message); + * } + * ``` + */ +export class TonApiClient { + private http: HttpClient; + + constructor(apiConfig: ApiConfig = {}) { + this.http = new HttpClient(apiConfig); + } + + /** + * @description Get the openapi.json file + * + * @tags Utilities + * @name GetOpenapiJson + * @request GET:/v2/openapi.json + */ + async getOpenapiJson(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/openapi.json`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, {}); + } + + /** + * @description Get the openapi.yml file + * + * @tags Utilities + * @name GetOpenapiYml + * @request GET:/v2/openapi.yml + */ + async getOpenapiYml(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/openapi.yml`, + method: 'GET', + ...params + }); + + return prepareResponse(req); + } + + /** + * @description Status + * + * @tags Utilities + * @name Status + * @request GET:/v2/status + */ + async status(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/status`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/ServiceStatus' }); + } + + /** + * @description parse address and display in all formats + * + * @tags Utilities + * @name AddressParse + * @request GET:/v2/address/{account_id}/parse + */ + async addressParse(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/address/${accountId}/parse`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['raw_form', 'bounceable', 'non_bounceable', 'given_type', 'test_only'], + properties: { + raw_form: { type: 'string', format: 'address' }, + bounceable: { + required: ['b64', 'b64url'], + type: 'object', + properties: { b64: { type: 'string' }, b64url: { type: 'string' } } + }, + non_bounceable: { + required: ['b64', 'b64url'], + type: 'object', + properties: { b64: { type: 'string' }, b64url: { type: 'string' } } + }, + given_type: { type: 'string' }, + test_only: { type: 'boolean' } + } + }); + } + + /** + * @description Get reduced blockchain blocks data + * + * @tags Blockchain + * @name GetReducedBlockchainBlocks + * @request GET:/v2/blockchain/reduced/blocks + */ + async getReducedBlockchainBlocks( + query: { + /** @format int64 */ + from: number; + /** @format int64 */ + to: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/blockchain/reduced/blocks`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/ReducedBlocks' + }); + } + + /** + * @description Get blockchain block data + * + * @tags Blockchain + * @name GetBlockchainBlock + * @request GET:/v2/blockchain/blocks/{block_id} + */ + async getBlockchainBlock(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/blocks/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlock' + }); + } + + /** + * @description Download blockchain block BOC + * + * @tags Blockchain + * @name DownloadBlockchainBlockBoc + * @request GET:/v2/blockchain/blocks/{block_id}/boc + */ + async downloadBlockchainBlockBoc(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/blocks/${blockId}/boc`, + method: 'GET', + ...params + }); + + return prepareResponse(req); + } + + /** + * @description Get blockchain block shards + * + * @tags Blockchain + * @name GetBlockchainMasterchainShards + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards + */ + async getBlockchainMasterchainShards(masterchainSeqno: number, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/shards`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlockShards' + }); + } + + /** + * @description Get all blocks in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. + * + * @tags Blockchain + * @name GetBlockchainMasterchainBlocks + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks + */ + async getBlockchainMasterchainBlocks(masterchainSeqno: number, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/blocks`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlocks' + }); + } + + /** + * @description Get all transactions in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. + * + * @tags Blockchain + * @name GetBlockchainMasterchainTransactions + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions + */ + async getBlockchainMasterchainTransactions( + masterchainSeqno: number, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/transactions`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Transactions' + }); + } + + /** + * @description Get blockchain config from a specific block, if present. + * + * @tags Blockchain + * @name GetBlockchainConfigFromBlock + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config + */ + async getBlockchainConfigFromBlock(masterchainSeqno: number, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/config`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainConfig' + }); + } + + /** + * @description Get raw blockchain config from a specific block, if present. + * + * @tags Blockchain + * @name GetRawBlockchainConfigFromBlock + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw + */ + async getRawBlockchainConfigFromBlock(masterchainSeqno: number, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/masterchain/${masterchainSeqno}/config/raw`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/RawBlockchainConfig' + }); + } + + /** + * @description Get transactions from block + * + * @tags Blockchain + * @name GetBlockchainBlockTransactions + * @request GET:/v2/blockchain/blocks/{block_id}/transactions + */ + async getBlockchainBlockTransactions(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/blocks/${blockId}/transactions`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Transactions' + }); + } + + /** + * @description Get transaction data + * + * @tags Blockchain + * @name GetBlockchainTransaction + * @request GET:/v2/blockchain/transactions/{transaction_id} + */ + async getBlockchainTransaction(transactionId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/transactions/${transactionId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Transaction' + }); + } + + /** + * @description Get transaction data by message hash + * + * @tags Blockchain + * @name GetBlockchainTransactionByMessageHash + * @request GET:/v2/blockchain/messages/{msg_id}/transaction + */ + async getBlockchainTransactionByMessageHash(msgId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/messages/${msgId}/transaction`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Transaction' + }); + } + + /** + * @description Get blockchain validators + * + * @tags Blockchain + * @name GetBlockchainValidators + * @request GET:/v2/blockchain/validators + */ + async getBlockchainValidators(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/validators`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Validators' + }); + } + + /** + * @description Get last known masterchain block + * + * @tags Blockchain + * @name GetBlockchainMasterchainHead + * @request GET:/v2/blockchain/masterchain-head + */ + async getBlockchainMasterchainHead(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/masterchain-head`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainBlock' + }); + } + + /** + * @description Get low-level information about an account taken directly from the blockchain. + * + * @tags Blockchain + * @name GetBlockchainRawAccount + * @request GET:/v2/blockchain/accounts/{account_id} + */ + async getBlockchainRawAccount(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/blockchain/accounts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainRawAccount' + }); + } + + /** + * @description Get account transactions + * + * @tags Blockchain + * @name GetBlockchainAccountTransactions + * @request GET:/v2/blockchain/accounts/{account_id}/transactions + */ + async getBlockchainAccountTransactions( + accountId_Address: Address, + query?: { + /** + * omit this parameter to get last transactions + * @format bigint + * @example 39787624000003 + */ + after_lt?: bigint; + /** + * omit this parameter to get last transactions + * @format bigint + * @example 39787624000003 + */ + before_lt?: bigint; + /** + * @format int32 + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + /** + * used to sort the result-set in ascending or descending order by lt. + * @default "desc" + */ + sort_order?: 'desc' | 'asc'; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/blockchain/accounts/${accountId}/transactions`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Transactions' + }); + } + + /** + * @description Execute get method for account + * + * @tags Blockchain + * @name ExecGetMethodForBlockchainAccount + * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} + */ + async execGetMethodForBlockchainAccount( + accountId_Address: Address, + methodName: string, + query?: { + /** + * Array of method arguments in string format. Supported value formats: + * - "NaN" for Not-a-Number type + * - "Null" for Null type + * - Decimal integers for tinyint type (e.g., "100500") + * - 0x-prefixed hex strings for int257 type (e.g., "0xfa01d78381ae32") + * - TON blockchain addresses for slice type (e.g., "0:6e731f2e28b73539a7f85ac47ca104d5840b229351189977bb6151d36b5e3f5e") + * - Base64-encoded BOC for cell type (e.g., "te6ccgEBAQEAAgAAAA==") + * - Hex-encoded BOC for slice type (e.g., "b5ee9c72010101010002000000") + * @example ["0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8"] + */ + args?: string[]; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/MethodExecutionResult' + }); + } + + /** + * @description Execute get method for account + * + * @tags Blockchain + * @name ExecGetMethodWithBodyForBlockchainAccount + * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} + */ + async execGetMethodWithBodyForBlockchainAccount( + accountId_Address: Address, + methodName: string, + data: { + args: ExecGetMethodArg[]; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['args'], + properties: { + args: { + type: 'array', + items: { $ref: '#/components/schemas/ExecGetMethodArg' } + } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/MethodExecutionResult' + }); + } + + /** + * @description Send message to blockchain + * + * @tags Blockchain + * @name SendBlockchainMessage + * @request POST:/v2/blockchain/message + */ + async sendBlockchainMessage( + data: { + /** @format cell */ + boc?: Cell; + /** @maxItems 5 */ + batch?: Cell[]; + meta?: Record; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/blockchain/message`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + properties: { + boc: { type: 'string', format: 'cell' }, + batch: { + type: 'array', + maxItems: 5, + items: { type: 'string', format: 'cell' } + }, + meta: { type: 'object', additionalProperties: { type: 'string' } } + } + }), + ...params + }); + + return prepareResponse(req); + } + + /** + * @description Get blockchain config + * + * @tags Blockchain + * @name GetBlockchainConfig + * @request GET:/v2/blockchain/config + */ + async getBlockchainConfig(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/config`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainConfig' + }); + } + + /** + * @description Get raw blockchain config + * + * @tags Blockchain + * @name GetRawBlockchainConfig + * @request GET:/v2/blockchain/config/raw + */ + async getRawBlockchainConfig(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/config/raw`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/RawBlockchainConfig' + }); + } + + /** + * @description Blockchain account inspect + * + * @tags Blockchain + * @name BlockchainAccountInspect + * @request GET:/v2/blockchain/accounts/{account_id}/inspect + */ + async blockchainAccountInspect(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/blockchain/accounts/${accountId}/inspect`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainAccountInspect' + }); + } + + /** + * @description Get library cell + * + * @tags Blockchain + * @name GetLibraryByHash + * @request GET:/v2/blockchain/libraries/{hash} + */ + async getLibraryByHash(hash: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/blockchain/libraries/${hash}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainLibrary' + }); + } + + /** + * @description Get human-friendly information about several accounts without low-level details. + * + * @tags Accounts + * @name GetAccounts + * @request POST:/v2/accounts/_bulk + */ + async getAccounts( + data: { + accountIds: Address[]; + }, + query?: { + /** @example "usd" */ + currency?: string; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/accounts/_bulk`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Accounts' }); + } + + /** + * @description Get human-friendly information about an account without low-level details. + * + * @tags Accounts + * @name GetAccount + * @request GET:/v2/accounts/{account_id} + */ + async getAccount(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Account' }); + } + + /** + * @description Get account's domains + * + * @tags Accounts + * @name AccountDnsBackResolve + * @request GET:/v2/accounts/{account_id}/dns/backresolve + */ + async accountDnsBackResolve(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/dns/backresolve`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/DomainNames' + }); + } + + /** + * @description Get all Jettons balances by owner address + * + * @tags Accounts + * @name GetAccountJettonsBalances + * @request GET:/v2/accounts/{account_id}/jettons + */ + async getAccountJettonsBalances( + accountId_Address: Address, + query?: { + /** + * accept ton and all possible fiat currencies, separated by commas + * @example ["ton","usd","rub"] + */ + currencies?: string[]; + /** + * comma separated list supported extensions + * @example ["custom_payload"] + */ + supported_extensions?: string[]; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/jettons`, + method: 'GET', + query: query, + queryImplode: ['currencies', 'supported_extensions'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonsBalances' + }); + } + + /** + * @description Get Jetton balance by owner address + * + * @tags Accounts + * @name GetAccountJettonBalance + * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} + */ + async getAccountJettonBalance( + accountId_Address: Address, + jettonId_Address: Address, + query?: { + /** + * accept ton and all possible fiat currencies, separated by commas + * @example ["ton","usd","rub"] + */ + currencies?: string[]; + /** + * comma separated list supported extensions + * @example ["custom_payload"] + */ + supported_extensions?: string[]; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/jettons/${jettonId}`, + method: 'GET', + query: query, + queryImplode: ['currencies', 'supported_extensions'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonBalance' + }); + } + + /** + * @description Get the transfer jettons history for account + * + * @tags Accounts + * @name GetAccountJettonsHistory + * @request GET:/v2/accounts/{account_id}/jettons/history + */ + async getAccountJettonsHistory( + accountId_Address: Address, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/jettons/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonOperations' + }); + } + + /** + * @description Please use `getJettonAccountHistoryByID`` instead + * + * @tags Accounts + * @name GetAccountJettonHistoryById + * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history + * @deprecated + */ + async getAccountJettonHistoryById( + accountId_Address: Address, + jettonId_Address: Address, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/jettons/${jettonId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); + } + + /** + * @description Get all NFT items by owner address + * + * @tags Accounts + * @name GetAccountNftItems + * @request GET:/v2/accounts/{account_id}/nfts + */ + async getAccountNftItems( + accountId_Address: Address, + query?: { + /** + * nft collection + * @format address + * @example "0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465" + */ + collection?: Address; + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @default 0 + */ + offset?: number; + /** + * Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. + * @default false + */ + indirect_ownership?: boolean; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/nfts`, + method: 'GET', + query: query && { + ...query, + collection: query.collection?.toRawString() + }, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftItems' + }); + } + + /** + * @description Get events for an account. Each event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + * + * @tags Accounts + * @name GetAccountEvents + * @request GET:/v2/accounts/{account_id}/events + */ + async getAccountEvents( + accountId_Address: Address, + query: { + /** + * Show only events that are initiated by this account + * @default false + */ + initiator?: boolean; + /** + * filter actions where requested account is not real subject (for example sender or receiver jettons) + * @default false + */ + subject_only?: boolean; + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 100 + * @example 20 + */ + limit: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/events`, + method: 'GET', + query: query, + queryImplode: ['initiator'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); + } + + /** + * @description Get event for an account by event_id + * + * @tags Accounts + * @name GetAccountEvent + * @request GET:/v2/accounts/{account_id}/events/{event_id} + */ + async getAccountEvent( + accountId_Address: Address, + eventId: string, + query?: { + /** + * filter actions where requested account is not real subject (for example sender or receiver jettons) + * @default false + */ + subject_only?: boolean; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/events/${eventId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvent' + }); + } + + /** + * @description Get traces for account + * + * @tags Accounts + * @name GetAccountTraces + * @request GET:/v2/accounts/{account_id}/traces + */ + async getAccountTraces( + accountId_Address: Address, + query?: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/traces`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/TraceIDs' + }); + } + + /** + * @description Get all subscriptions by wallet address + * + * @tags Accounts + * @name GetAccountSubscriptions + * @request GET:/v2/accounts/{account_id}/subscriptions + */ + async getAccountSubscriptions(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/subscriptions`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Subscriptions' + }); + } + + /** + * @description Update internal cache for a particular account + * + * @tags Accounts + * @name ReindexAccount + * @request POST:/v2/accounts/{account_id}/reindex + */ + async reindexAccount(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/reindex`, + method: 'POST', + ...params + }); + + return prepareResponse(req); + } + + /** + * @description Search by account domain name + * + * @tags Accounts + * @name SearchAccounts + * @request GET:/v2/accounts/search + */ + async searchAccounts( + query: { + /** + * @minLength 3 + * @maxLength 15 + */ + name: string; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/accounts/search`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/FoundAccounts' + }); + } + + /** + * @description Get expiring account .ton dns + * + * @tags Accounts + * @name GetAccountDnsExpiring + * @request GET:/v2/accounts/{account_id}/dns/expiring + */ + async getAccountDnsExpiring( + accountId_Address: Address, + query?: { + /** + * number of days before expiration + * @min 1 + * @max 3660 + */ + period?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/dns/expiring`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/DnsExpiring' + }); + } + + /** + * @description Get public key by account id + * + * @tags Accounts + * @name GetAccountPublicKey + * @request GET:/v2/accounts/{account_id}/publickey + */ + async getAccountPublicKey(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/publickey`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['public_key'], + properties: { public_key: { type: 'string' } } + }); + } + + /** + * @description Get account's multisigs + * + * @tags Accounts + * @name GetAccountMultisigs + * @request GET:/v2/accounts/{account_id}/multisigs + */ + async getAccountMultisigs(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/multisigs`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Multisigs' + }); + } + + /** + * @description Get account's balance change + * + * @tags Accounts + * @name GetAccountDiff + * @request GET:/v2/accounts/{account_id}/diff + */ + async getAccountDiff( + accountId_Address: Address, + query: { + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/diff`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['balance_change'], + properties: { balance_change: { type: 'integer', format: 'int64' } } + }); + } + + /** + * @description Get the transfer history of extra currencies for an account. + * + * @tags Accounts + * @name GetAccountExtraCurrencyHistoryById + * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history + */ + async getAccountExtraCurrencyHistoryById( + accountId_Address: Address, + id: number, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/extra-currency/${id}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); + } + + /** + * @description Get the transfer jetton history for account and jetton + * + * @tags Accounts + * @name GetJettonAccountHistoryById + * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history + */ + async getJettonAccountHistoryById( + accountId_Address: Address, + jettonId_Address: Address, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/jettons/${jettonId}/accounts/${accountId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonOperations' + }); + } + + /** + * @description Get the transfer nft history + * + * @tags NFT + * @name GetAccountNftHistory + * @request GET:/v2/accounts/{account_id}/nfts/history + */ + async getAccountNftHistory( + accountId_Address: Address, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/nfts/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftOperations' + }); + } + + /** + * @description Get NFT collections + * + * @tags NFT + * @name GetNftCollections + * @request GET:/v2/nfts/collections + */ + async getNftCollections( + query?: { + /** + * @format int32 + * @min 1 + * @max 1000 + * @default 100 + * @example 15 + */ + limit?: number; + /** + * @format int32 + * @min 0 + * @default 0 + * @example 10 + */ + offset?: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/nfts/collections`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftCollections' + }); + } + + /** + * @description Get NFT collection by collection address + * + * @tags NFT + * @name GetNftCollection + * @request GET:/v2/nfts/collections/{account_id} + */ + async getNftCollection(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/nfts/collections/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftCollection' + }); + } + + /** + * @description Get NFT collection items by their addresses + * + * @tags NFT + * @name GetNftCollectionItemsByAddresses + * @request POST:/v2/nfts/collections/_bulk + */ + async getNftCollectionItemsByAddresses( + data: { + accountIds: Address[]; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/nfts/collections/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftCollections' + }); + } + + /** + * @description Get NFT items from collection by collection address + * + * @tags NFT + * @name GetItemsFromCollection + * @request GET:/v2/nfts/collections/{account_id}/items + */ + async getItemsFromCollection( + accountId_Address: Address, + query?: { + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @default 0 + */ + offset?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/nfts/collections/${accountId}/items`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftItems' + }); + } + + /** + * @description Get NFT items by their addresses + * + * @tags NFT + * @name GetNftItemsByAddresses + * @request POST:/v2/nfts/_bulk + */ + async getNftItemsByAddresses( + data: { + accountIds: Address[]; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/nfts/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftItems' + }); + } + + /** + * @description Get NFT item by its address + * + * @tags NFT + * @name GetNftItemByAddress + * @request GET:/v2/nfts/{account_id} + */ + async getNftItemByAddress(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/nfts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/NftItem' + }); + } + + /** + * @description Please use `getAccountNftHistory`` instead + * + * @tags NFT + * @name GetNftHistoryById + * @request GET:/v2/nfts/{account_id}/history + * @deprecated + */ + async getNftHistoryById( + accountId_Address: Address, + query: { + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @example 100 + */ + limit: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/nfts/${accountId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvents' + }); + } + + /** + * @description Get full information about domain name + * + * @tags DNS + * @name GetDnsInfo + * @request GET:/v2/dns/{domain_name} + */ + async getDnsInfo(domainName: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/dns/${domainName}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DomainInfo' }); + } + + /** + * @description DNS resolve for domain name + * + * @tags DNS + * @name DnsResolve + * @request GET:/v2/dns/{domain_name}/resolve + */ + async dnsResolve( + domainName: string, + query?: { + /** @default false */ + filter?: boolean; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/dns/${domainName}/resolve`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DnsRecord' }); + } + + /** + * @description Get domain bids + * + * @tags DNS + * @name GetDomainBids + * @request GET:/v2/dns/{domain_name}/bids + */ + async getDomainBids(domainName: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/dns/${domainName}/bids`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/DomainBids' }); + } + + /** + * @description Get all auctions + * + * @tags DNS + * @name GetAllAuctions + * @request GET:/v2/dns/auctions + */ + async getAllAuctions( + query?: { + /** + * domain filter for current auctions "ton" or "t.me" + * @example "ton" + */ + tld?: string; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/dns/auctions`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Auctions' }); + } + + /** + * @description Get the trace by trace ID or hash of any transaction in trace + * + * @tags Traces + * @name GetTrace + * @request GET:/v2/traces/{trace_id} + */ + async getTrace(traceId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/traces/${traceId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); + } + + /** + * @description Get an event either by event ID or a hash of any transaction in a trace. An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + * + * @tags Events + * @name GetEvent + * @request GET:/v2/events/{event_id} + */ + async getEvent(eventId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/events/${eventId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Event' }); + } + + /** + * @description Get a list of all indexed jetton masters in the blockchain. + * + * @tags Jettons + * @name GetJettons + * @request GET:/v2/jettons + */ + async getJettons( + query?: { + /** + * @format int32 + * @min 1 + * @max 1000 + * @default 100 + * @example 15 + */ + limit?: number; + /** + * @format int32 + * @min 0 + * @default 0 + * @example 10 + */ + offset?: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/jettons`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Jettons' }); + } + + /** + * @description Get jetton metadata by jetton master address + * + * @tags Jettons + * @name GetJettonInfo + * @request GET:/v2/jettons/{account_id} + */ + async getJettonInfo(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/jettons/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/JettonInfo' }); + } + + /** + * @description Get jetton metadata items by jetton master addresses + * + * @tags Jettons + * @name GetJettonInfosByAddresses + * @request POST:/v2/jettons/_bulk + */ + async getJettonInfosByAddresses( + data: { + accountIds: Address[]; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/jettons/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Jettons' + }); + } + + /** + * @description Get jetton's holders + * + * @tags Jettons + * @name GetJettonHolders + * @request GET:/v2/jettons/{account_id}/holders + */ + async getJettonHolders( + accountId_Address: Address, + query?: { + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @max 9000 + * @default 0 + */ + offset?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/jettons/${accountId}/holders`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonHolders' + }); + } + + /** + * @description Get jetton's custom payload and state init required for transfer + * + * @tags Jettons + * @name GetJettonTransferPayload + * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload + */ + async getJettonTransferPayload( + accountId_Address: Address, + jettonId_Address: Address, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const jettonId = jettonId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/jettons/${jettonId}/transfer/${accountId}/payload`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/JettonTransferPayload' + }); + } + + /** + * @description Get only jetton transfers in the event + * + * @tags Jettons + * @name GetJettonsEvents + * @request GET:/v2/events/{event_id}/jettons + */ + async getJettonsEvents(eventId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/events/${eventId}/jettons`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Event' }); + } + + /** + * @description Get extra currency info by id + * + * @tags ExtraCurrency + * @name GetExtraCurrencyInfo + * @request GET:/v2/extra-currency/{id} + */ + async getExtraCurrencyInfo(id: number, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/extra-currency/${id}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/EcPreview' + }); + } + + /** + * @description All pools where account participates + * + * @tags Staking + * @name GetAccountNominatorsPools + * @request GET:/v2/staking/nominator/{account_id}/pools + */ + async getAccountNominatorsPools(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/staking/nominator/${accountId}/pools`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountStaking' + }); + } + + /** + * @description Stacking pool info + * + * @tags Staking + * @name GetStakingPoolInfo + * @request GET:/v2/staking/pool/{account_id} + */ + async getStakingPoolInfo(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/staking/pool/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['implementation', 'pool'], + properties: { + implementation: { $ref: '#/components/schemas/PoolImplementation' }, + pool: { $ref: '#/components/schemas/PoolInfo' } + } + }); + } + + /** + * @description Pool history + * + * @tags Staking + * @name GetStakingPoolHistory + * @request GET:/v2/staking/pool/{account_id}/history + */ + async getStakingPoolHistory(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/staking/pool/${accountId}/history`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['apy'], + properties: { + apy: { type: 'array', items: { $ref: '#/components/schemas/ApyHistory' } } + } + }); + } + + /** + * @description All pools available in network + * + * @tags Staking + * @name GetStakingPools + * @request GET:/v2/staking/pools + */ + async getStakingPools( + query?: { + /** + * account ID + * @format address + * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" + */ + available_for?: Address; + /** + * return also pools not from white list - just compatible by interfaces (maybe dangerous!) + * @example false + */ + include_unverified?: boolean; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/staking/pools`, + method: 'GET', + query: query && { + ...query, + available_for: query.available_for?.toRawString() + }, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['pools', 'implementations'], + properties: { + pools: { type: 'array', items: { $ref: '#/components/schemas/PoolInfo' } }, + implementations: { + type: 'object', + additionalProperties: { $ref: '#/components/schemas/PoolImplementation' } + } + } + }); + } + + /** + * @description Get TON storage providers deployed to the blockchain. + * + * @tags Storage + * @name GetStorageProviders + * @request GET:/v2/storage/providers + */ + async getStorageProviders(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/storage/providers`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['providers'], + properties: { + providers: { + type: 'array', + items: { $ref: '#/components/schemas/StorageProvider' } + } + } + }); + } + + /** + * @description Get the token price in the chosen currency for display only. Don’t use this for financial transactions. + * + * @tags Rates + * @name GetRates + * @request GET:/v2/rates + */ + async getRates( + query: { + /** + * accept cryptocurrencies or jetton master addresses, separated by commas + * @maxItems 100 + * @example ["ton"] + */ + tokens: (Address | string)[]; + /** + * accept cryptocurrencies and all possible fiat currencies, separated by commas + * @maxItems 50 + * @example ["ton","usd","rub"] + */ + currencies: string[]; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/rates`, + method: 'GET', + query: query, + queryImplode: ['tokens', 'currencies'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['rates'], + properties: { + rates: { + type: 'object', + additionalProperties: { $ref: '#/components/schemas/TokenRates' } + } + } + }); + } + + /** + * @description Get chart by token + * + * @tags Rates + * @name GetChartRates + * @request GET:/v2/rates/chart + */ + async getChartRates( + query: { + /** accept cryptocurrencies or jetton master addresses */ + token: Address | string; + /** @example "usd" */ + currency?: string; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + start_date?: number; + /** + * @format int64 + * @max 2114380800 + * @example 1668436763 + */ + end_date?: number; + /** + * @format int + * @min 0 + * @max 200 + * @default 200 + */ + points_count?: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/rates/chart`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['points'], + properties: { + points: { type: 'array', items: { $ref: '#/components/schemas/ChartPoints' } } + } + }); + } + + /** + * @description Get the TON price from markets + * + * @tags Rates + * @name GetMarketsRates + * @request GET:/v2/rates/markets + */ + async getMarketsRates(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/rates/markets`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['markets'], + properties: { + markets: { type: 'array', items: { $ref: '#/components/schemas/MarketTonRates' } } + } + }); + } + + /** + * @description Get a payload for further token receipt + * + * @tags Connect + * @name GetTonConnectPayload + * @request GET:/v2/tonconnect/payload + */ + async getTonConnectPayload(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/tonconnect/payload`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['payload'], + properties: { payload: { type: 'string' } } + }); + } + + /** + * @description Get account info by state init + * + * @tags Connect + * @name GetAccountInfoByStateInit + * @request POST:/v2/tonconnect/stateinit + */ + async getAccountInfoByStateInit( + data: { + /** @format cell-base64 */ + stateInit: Cell; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/tonconnect/stateinit`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['stateInit'], + properties: { stateInit: { type: 'string', format: 'cell-base64' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/AccountInfoByStateInit' + }); + } + + /** + * @description Account verification and token issuance + * + * @tags Wallet + * @name TonConnectProof + * @request POST:/v2/wallet/auth/proof + */ + async tonConnectProof( + data: { + /** + * @format address + * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + */ + address: Address; + proof: { + /** + * @format int64 + * @example "1678275313" + */ + timestamp: number; + domain: { + /** @format int32 */ + lengthBytes?: number; + value: string; + }; + signature: string; + /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ + payload: string; + /** @format cell-base64 */ + stateInit?: Cell; + }; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/wallet/auth/proof`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['address', 'proof'], + properties: { + address: { type: 'string', format: 'address' }, + proof: { + type: 'object', + required: ['timestamp', 'domain', 'signature', 'payload'], + properties: { + timestamp: { type: 'integer', format: 'int64' }, + domain: { + type: 'object', + required: ['value'], + properties: { + lengthBytes: { type: 'integer', format: 'int32' }, + value: { type: 'string' } + } + }, + signature: { type: 'string' }, + payload: { type: 'string' }, + stateInit: { type: 'string', format: 'cell-base64' } + } + } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['token'], + properties: { token: { type: 'string' } } + }); + } + + /** + * @description Get account seqno + * + * @tags Wallet + * @name GetAccountSeqno + * @request GET:/v2/wallet/{account_id}/seqno + */ + async getAccountSeqno(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/wallet/${accountId}/seqno`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Seqno' }); + } + + /** + * @description Get human-friendly information about a wallet without low-level details. + * + * @tags Wallet + * @name GetWalletInfo + * @request GET:/v2/wallet/{account_id} + */ + async getWalletInfo(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/wallet/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/Wallet' }); + } + + /** + * @description Get wallets by public key + * + * @tags Wallet + * @name GetWalletsByPublicKey + * @request GET:/v2/pubkeys/{public_key}/wallets + */ + async getWalletsByPublicKey(publicKey: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/pubkeys/${publicKey}/wallets`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Wallets' + }); + } + + /** + * @description Returns configuration of gasless transfers + * + * @tags Gasless + * @name GaslessConfig + * @request GET:/v2/gasless/config + */ + async gaslessConfig(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/gasless/config`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/GaslessConfig' + }); + } + + /** + * @description Estimates the cost of the given messages and returns a payload to sign + * + * @tags Gasless + * @name GaslessEstimate + * @request POST:/v2/gasless/estimate/{master_id} + */ + async gaslessEstimate( + masterId_Address: Address, + data: { + /** + * TONAPI verifies that the account has enough jettons to pay the commission and make a transfer. + * @default false + */ + throwErrorIfNotEnoughJettons?: boolean; + /** @default false */ + returnEmulation?: boolean; + /** @format address */ + walletAddress: Address; + walletPublicKey: string; + messages: { + /** @format cell */ + boc: Cell; + }[]; + }, + params: RequestParams = {} + ) { + const masterId = masterId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/gasless/estimate/${masterId}`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['messages', 'walletAddress', 'walletPublicKey'], + properties: { + throwErrorIfNotEnoughJettons: { type: 'boolean', default: false }, + returnEmulation: { type: 'boolean', default: false }, + walletAddress: { type: 'string', format: 'address' }, + walletPublicKey: { type: 'string' }, + messages: { + type: 'array', + items: { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + } + } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/SignRawParams' + }); + } + + /** + * @description Submits the signed gasless transaction message to the network + * + * @tags Gasless + * @name GaslessSend + * @request POST:/v2/gasless/send + */ + async gaslessSend( + data: { + /** hex encoded public key */ + walletPublicKey: string; + /** @format cell */ + boc: Cell; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/gasless/send`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['boc', 'walletPublicKey'], + properties: { + walletPublicKey: { type: 'string' }, + boc: { type: 'string', format: 'cell' } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { $ref: '#/components/schemas/GaslessTx' }); + } + + /** + * @description Get raw masterchain info + * + * @tags Lite Server + * @name GetRawMasterchainInfo + * @request GET:/v2/liteserver/get_masterchain_info + */ + async getRawMasterchainInfo(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_masterchain_info`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['last', 'state_root_hash', 'init'], + properties: { + last: { $ref: '#/components/schemas/BlockRaw' }, + state_root_hash: { type: 'string' }, + init: { $ref: '#/components/schemas/InitStateRaw' } + } + }); + } + + /** + * @description Get raw masterchain info ext + * + * @tags Lite Server + * @name GetRawMasterchainInfoExt + * @request GET:/v2/liteserver/get_masterchain_info_ext + */ + async getRawMasterchainInfoExt( + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/get_masterchain_info_ext`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: [ + 'mode', + 'version', + 'capabilities', + 'last', + 'last_utime', + 'now', + 'state_root_hash', + 'init' + ], + properties: { + mode: { type: 'integer', format: 'int32' }, + version: { type: 'integer', format: 'int32' }, + capabilities: { type: 'integer', format: 'int64' }, + last: { $ref: '#/components/schemas/BlockRaw' }, + last_utime: { type: 'integer', format: 'int32' }, + now: { type: 'integer', format: 'int32' }, + state_root_hash: { type: 'string' }, + init: { $ref: '#/components/schemas/InitStateRaw' } + } + }); + } + + /** + * @description Get raw time + * + * @tags Lite Server + * @name GetRawTime + * @request GET:/v2/liteserver/get_time + */ + async getRawTime(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_time`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['time'], + properties: { time: { type: 'integer', format: 'int32' } } + }); + } + + /** + * @description Get raw blockchain block + * + * @tags Lite Server + * @name GetRawBlockchainBlock + * @request GET:/v2/liteserver/get_block/{block_id} + */ + async getRawBlockchainBlock(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_block/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'data'], + properties: { id: { $ref: '#/components/schemas/BlockRaw' }, data: { type: 'string' } } + }); + } + + /** + * @description Get raw blockchain block state + * + * @tags Lite Server + * @name GetRawBlockchainBlockState + * @request GET:/v2/liteserver/get_state/{block_id} + */ + async getRawBlockchainBlockState(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_state/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'root_hash', 'file_hash', 'data'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + root_hash: { type: 'string' }, + file_hash: { type: 'string' }, + data: { type: 'string' } + } + }); + } + + /** + * @description Get raw blockchain block header + * + * @tags Lite Server + * @name GetRawBlockchainBlockHeader + * @request GET:/v2/liteserver/get_block_header/{block_id} + */ + async getRawBlockchainBlockHeader( + blockId: string, + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/get_block_header/${blockId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'mode', 'header_proof'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + mode: { type: 'integer', format: 'int32' }, + header_proof: { type: 'string' } + } + }); + } + + /** + * @description Send raw message to blockchain + * + * @tags Lite Server + * @name SendRawMessage + * @request POST:/v2/liteserver/send_message + */ + async sendRawMessage( + data: { + /** @format cell-base64 */ + body: Cell; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/send_message`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['body'], + properties: { body: { type: 'string', format: 'cell-base64' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['code'], + properties: { code: { type: 'integer', format: 'int32' } } + }); + } + + /** + * @description Get raw account state + * + * @tags Lite Server + * @name GetRawAccountState + * @request GET:/v2/liteserver/get_account_state/{account_id} + */ + async getRawAccountState( + accountId_Address: Address, + query?: { + /** + * target block: (workchain,shard,seqno,root_hash,file_hash) + * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" + */ + target_block?: string; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/liteserver/get_account_state/${accountId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'shardblk', 'shard_proof', 'proof', 'state'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + shardblk: { $ref: '#/components/schemas/BlockRaw' }, + shard_proof: { type: 'string' }, + proof: { type: 'string' }, + state: { type: 'string' } + } + }); + } + + /** + * @description Get raw shard info + * + * @tags Lite Server + * @name GetRawShardInfo + * @request GET:/v2/liteserver/get_shard_info/{block_id} + */ + async getRawShardInfo( + blockId: string, + query: { + /** + * workchain + * @format int32 + * @example 1 + */ + workchain: number; + /** + * shard + * @format int64 + * @example 1 + */ + shard: number; + /** + * exact + * @example false + */ + exact: boolean; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/get_shard_info/${blockId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'shardblk', 'shard_proof', 'shard_descr'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + shardblk: { $ref: '#/components/schemas/BlockRaw' }, + shard_proof: { type: 'string' }, + shard_descr: { type: 'string' } + } + }); + } + + /** + * @description Get all raw shards info + * + * @tags Lite Server + * @name GetAllRawShardsInfo + * @request GET:/v2/liteserver/get_all_shards_info/{block_id} + */ + async getAllRawShardsInfo(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_all_shards_info/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'proof', 'data'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + proof: { type: 'string' }, + data: { type: 'string' } + } + }); + } + + /** + * @description Get raw transactions + * + * @tags Lite Server + * @name GetRawTransactions + * @request GET:/v2/liteserver/get_transactions/{account_id} + */ + async getRawTransactions( + accountId_Address: Address, + query: { + /** + * count + * @format int32 + * @example 100 + */ + count: number; + /** + * lt + * @format int64 + * @example 23814011000000 + */ + lt: number; + /** + * hash + * @example "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" + */ + hash: string; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/liteserver/get_transactions/${accountId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['ids', 'transactions'], + properties: { + ids: { type: 'array', items: { $ref: '#/components/schemas/BlockRaw' } }, + transactions: { type: 'string' } + } + }); + } + + /** + * @description Get raw list block transactions + * + * @tags Lite Server + * @name GetRawListBlockTransactions + * @request GET:/v2/liteserver/list_block_transactions/{block_id} + */ + async getRawListBlockTransactions( + blockId: string, + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + /** + * count + * @format int32 + * @example 100 + */ + count: number; + /** + * account ID + * @format address + * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" + */ + account_id?: Address; + /** + * lt + * @format int64 + * @example 23814011000000 + */ + lt?: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/list_block_transactions/${blockId}`, + method: 'GET', + query: query && { + ...query, + account_id: query.account_id?.toRawString() + }, + queryImplode: ['account_id'], + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['id', 'req_count', 'incomplete', 'ids', 'proof'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + req_count: { type: 'integer', format: 'int32' }, + incomplete: { type: 'boolean' }, + ids: { + type: 'array', + items: { + type: 'object', + required: ['mode'], + properties: { + mode: { type: 'integer', format: 'int32' }, + account: { type: 'string' }, + lt: { type: 'integer', format: 'bigint', 'x-js-format': 'bigint' }, + hash: { type: 'string' } + } + } + }, + proof: { type: 'string' } + } + }); + } + + /** + * @description Get raw block proof + * + * @tags Lite Server + * @name GetRawBlockProof + * @request GET:/v2/liteserver/get_block_proof + */ + async getRawBlockProof( + query: { + /** + * known block: (workchain,shard,seqno,root_hash,file_hash) + * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" + */ + known_block: string; + /** + * target block: (workchain,shard,seqno,root_hash,file_hash) + * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" + */ + target_block?: string; + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/get_block_proof`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['complete', 'from', 'to', 'steps'], + properties: { + complete: { type: 'boolean' }, + from: { $ref: '#/components/schemas/BlockRaw' }, + to: { $ref: '#/components/schemas/BlockRaw' }, + steps: { + type: 'array', + items: { + type: 'object', + required: ['lite_server_block_link_back', 'lite_server_block_link_forward'], + properties: { + lite_server_block_link_back: { + type: 'object', + required: [ + 'to_key_block', + 'from', + 'to', + 'dest_proof', + 'proof', + 'state_proof' + ], + properties: { + to_key_block: { type: 'boolean' }, + from: { $ref: '#/components/schemas/BlockRaw' }, + to: { $ref: '#/components/schemas/BlockRaw' }, + dest_proof: { type: 'string' }, + proof: { type: 'string' }, + state_proof: { type: 'string' } + } + }, + lite_server_block_link_forward: { + type: 'object', + required: [ + 'to_key_block', + 'from', + 'to', + 'dest_proof', + 'config_proof', + 'signatures' + ], + properties: { + to_key_block: { type: 'boolean' }, + from: { $ref: '#/components/schemas/BlockRaw' }, + to: { $ref: '#/components/schemas/BlockRaw' }, + dest_proof: { type: 'string' }, + config_proof: { type: 'string' }, + signatures: { + type: 'object', + required: [ + 'validator_set_hash', + 'catchain_seqno', + 'signatures' + ], + properties: { + validator_set_hash: { + type: 'integer', + format: 'int64' + }, + catchain_seqno: { type: 'integer', format: 'int32' }, + signatures: { + type: 'array', + items: { + type: 'object', + required: ['node_id_short', 'signature'], + properties: { + node_id_short: { type: 'string' }, + signature: { type: 'string' } + } + } + } + } + } + } + } + } + } + } + } + }); + } + + /** + * @description Get raw config + * + * @tags Lite Server + * @name GetRawConfig + * @request GET:/v2/liteserver/get_config_all/{block_id} + */ + async getRawConfig( + blockId: string, + query: { + /** + * mode + * @format int32 + * @example 0 + */ + mode: number; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/liteserver/get_config_all/${blockId}`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['mode', 'id', 'state_proof', 'config_proof'], + properties: { + mode: { type: 'integer', format: 'int32' }, + id: { $ref: '#/components/schemas/BlockRaw' }, + state_proof: { type: 'string' }, + config_proof: { type: 'string' } + } + }); + } + + /** + * @description Get raw shard block proof + * + * @tags Lite Server + * @name GetRawShardBlockProof + * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} + */ + async getRawShardBlockProof(blockId: string, params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_shard_block_proof/${blockId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['masterchain_id', 'links'], + properties: { + masterchain_id: { $ref: '#/components/schemas/BlockRaw' }, + links: { + type: 'array', + items: { + type: 'object', + required: ['id', 'proof'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + proof: { type: 'string' } + } + } + } + } + }); + } + + /** + * @description Get out msg queue sizes + * + * @tags Lite Server + * @name GetOutMsgQueueSizes + * @request GET:/v2/liteserver/get_out_msg_queue_sizes + */ + async getOutMsgQueueSizes(params: RequestParams = {}) { + const req = this.http.request({ + path: `/v2/liteserver/get_out_msg_queue_sizes`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'object', + required: ['ext_msg_queue_size_limit', 'shards'], + properties: { + ext_msg_queue_size_limit: { type: 'integer', format: 'uint32' }, + shards: { + type: 'array', + items: { + type: 'object', + required: ['id', 'size'], + properties: { + id: { $ref: '#/components/schemas/BlockRaw' }, + size: { type: 'integer', format: 'uint32' } + } + } + } + } + }); + } + + /** + * @description Get multisig account info + * + * @tags Multisig + * @name GetMultisigAccount + * @request GET:/v2/multisig/{account_id} + */ + async getMultisigAccount(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/multisig/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Multisig' + }); + } + + /** + * @description Get multisig order + * + * @tags Multisig + * @name GetMultisigOrder + * @request GET:/v2/multisig/order/{account_id} + */ + async getMultisigOrder(accountId_Address: Address, params: RequestParams = {}) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/multisig/order/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/MultisigOrder' + }); + } + + /** + * @description Decode a given message. Only external incoming messages can be decoded currently. + * + * @tags Emulation + * @name DecodeMessage + * @request POST:/v2/message/decode + */ + async decodeMessage( + data: { + /** @format cell */ + boc: Cell; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/message/decode`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/DecodedMessage' + }); + } + + /** + * @description Emulate sending message to retrieve general blockchain events + * + * @tags Emulation, Events + * @name EmulateMessageToEvent + * @request POST:/v2/events/emulate + */ + async emulateMessageToEvent( + data: { + /** @format cell */ + boc: Cell; + }, + query?: { + ignore_signature_check?: boolean; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/events/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Event' + }); + } + + /** + * @description Emulate sending message to retrieve with a detailed execution trace + * + * @tags Emulation, Traces + * @name EmulateMessageToTrace + * @request POST:/v2/traces/emulate + */ + async emulateMessageToTrace( + data: { + /** @format cell */ + boc: Cell; + }, + query?: { + ignore_signature_check?: boolean; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/traces/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/Trace' + }); + } + + /** + * @description Emulate sending message to retrieve the resulting wallet state + * + * @tags Emulation, Wallet + * @name EmulateMessageToWallet + * @request POST:/v2/wallet/emulate + */ + async emulateMessageToWallet( + data: { + /** @format cell */ + boc: Cell; + /** additional per account configuration */ + params?: { + /** + * @format address + * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" + */ + address: Address; + /** + * @format bigint + * @example 10000000000 + */ + balance?: bigint; + }[]; + }, + query?: { + /** @example "usd" */ + currency?: string; + }, + params: RequestParams = {} + ) { + const req = this.http.request({ + path: `/v2/wallet/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { + boc: { type: 'string', format: 'cell' }, + params: { + type: 'array', + items: { + type: 'object', + required: ['address'], + properties: { + address: { type: 'string', format: 'address' }, + balance: { + type: 'integer', + format: 'bigint', + 'x-js-format': 'bigint' + } + } + } + } + } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/MessageConsequences' + }); + } - if (schema.format === 'cell-base64') { - return (data as Cell).toBoc().toString('base64'); - } + /** + * @description Emulate sending message to retrieve account-specific events + * + * @tags Emulation, Accounts + * @name EmulateMessageToAccountEvent + * @request POST:/v2/accounts/{account_id}/events/emulate + */ + async emulateMessageToAccountEvent( + accountId_Address: Address, + data: { + /** @format cell */ + boc: Cell; + }, + query?: { + ignore_signature_check?: boolean; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/events/emulate`, + method: 'POST', + query: query, + body: prepareRequestData(data, { + type: 'object', + required: ['boc'], + properties: { boc: { type: 'string', format: 'cell' } } + }), + format: 'json', + ...params + }); - if (schema['x-js-format'] === 'bigint') { - return (data as bigint).toString(); - } - } + return prepareResponse(req, { + $ref: '#/components/schemas/AccountEvent' + }); } - if (data !== null && typeof data === 'object') { - return Object.keys(data).reduce( - (acc, key) => { - const objSchema = schema?.properties && schema.properties[key]; - - const snakeCaseKey = camelToSnake(key); + /** + * @description Get history of purchases + * + * @tags Purchases + * @name GetPurchaseHistory + * @request GET:/v2/purchases/{account_id}/history + */ + async getPurchaseHistory( + accountId_Address: Address, + query?: { + /** + * omit this parameter to get last invoices + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @min 1 + * @max 1000 + * @default 100 + * @example 100 + */ + limit?: number; + }, + params: RequestParams = {} + ) { + const accountId = accountId_Address.toRawString(); + const req = this.http.request({ + path: `/v2/purchases/${accountId}/history`, + method: 'GET', + query: query, + format: 'json', + ...params + }); - acc[snakeCaseKey] = prepareRequestData(data[key], objSchema); - return acc; - }, - {} as Record - ); + return prepareResponse(req, { + $ref: '#/components/schemas/AccountPurchases' + }); } - return data; } -/** - * @title REST api to TON blockchain explorer - * @version 2.0.0 - * @baseUrl https://tonapi.io - * @contact Support - * - * Provide access to indexed TON blockchain - */ - -// Singleton HttpClient instance -let httpClient: HttpClient | null = null; +// Default client instance for global methods +let defaultClient: TonApiClient | null = null; /** - * Initialize the API client with configuration. - * Should be called once at application startup. + * Initialize the global API client with configuration. + * For advanced use cases with global methods. * * @param apiConfig - Configuration for the API client * @param apiConfig.baseUrl - API base URL @@ -6842,21 +10337,31 @@ let httpClient: HttpClient | null = null; * baseUrl: 'https://tonapi.io', * apiKey: process.env.TON_API_KEY * }); + * + * const { data, error } = await getAccount(address); + * if (error) { + * console.error('Error:', error.message); + * } else { + * console.log(data); + * } * ``` */ export function initClient(apiConfig: ApiConfig = {}): void { - httpClient = new HttpClient(apiConfig); + defaultClient = new TonApiClient(apiConfig); } /** - * Get the current HttpClient instance (creates one if it doesn't exist) + * Get the current default client instance * @internal */ -function getHttpClient(): HttpClient { - if (!httpClient) { - httpClient = new HttpClient(); +function getDefaultClient(): TonApiClient { + if (!defaultClient) { + throw new Error( + 'TonApiClient is not initialized. Call initClient() before using global methods, ' + + 'or use new TonApiClient() for instance-based approach.' + ); } - return httpClient; + return defaultClient; } /** @@ -6866,15 +10371,13 @@ function getHttpClient(): HttpClient { * @name GetOpenapiJson * @request GET:/v2/openapi.json */ -export const getOpenapiJson = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/openapi.json`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, {}); +export const getOpenapiJson = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getOpenapiJson(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -6884,14 +10387,13 @@ export const getOpenapiJson = (params: RequestParams = {}) => { * @name GetOpenapiYml * @request GET:/v2/openapi.yml */ -export const getOpenapiYml = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/openapi.yml`, - method: 'GET', - ...params - }); - - return prepareResponse(req); +export const getOpenapiYml = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getOpenapiYml(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -6901,15 +10403,13 @@ export const getOpenapiYml = (params: RequestParams = {}) => { * @name Status * @request GET:/v2/status */ -export const status = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/status`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/ServiceStatus' }); +export const status = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().status(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -6919,34 +10419,13 @@ export const status = (params: RequestParams = {}) => { * @name AddressParse * @request GET:/v2/address/{account_id}/parse */ -export const addressParse = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/address/${accountId}/parse`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['raw_form', 'bounceable', 'non_bounceable', 'given_type', 'test_only'], - properties: { - raw_form: { type: 'string', format: 'address' }, - bounceable: { - required: ['b64', 'b64url'], - type: 'object', - properties: { b64: { type: 'string' }, b64url: { type: 'string' } } - }, - non_bounceable: { - required: ['b64', 'b64url'], - type: 'object', - properties: { b64: { type: 'string' }, b64url: { type: 'string' } } - }, - given_type: { type: 'string' }, - test_only: { type: 'boolean' } - } - }); +export const addressParse = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().addressParse(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -6956,7 +10435,7 @@ export const addressParse = (accountId_Address: Address, params: RequestParams = * @name GetReducedBlockchainBlocks * @request GET:/v2/blockchain/reduced/blocks */ -export const getReducedBlockchainBlocks = ( +export const getReducedBlockchainBlocks = async ( query: { /** @format int64 */ from: number; @@ -6965,17 +10444,12 @@ export const getReducedBlockchainBlocks = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/reduced/blocks`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/ReducedBlocks' - }); + try { + const result = await getDefaultClient().getReducedBlockchainBlocks(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -6985,17 +10459,13 @@ export const getReducedBlockchainBlocks = ( * @name GetBlockchainBlock * @request GET:/v2/blockchain/blocks/{block_id} */ -export const getBlockchainBlock = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/blocks/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlock' - }); +export const getBlockchainBlock = async (blockId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getBlockchainBlock(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7005,14 +10475,13 @@ export const getBlockchainBlock = (blockId: string, params: RequestParams = {}) * @name DownloadBlockchainBlockBoc * @request GET:/v2/blockchain/blocks/{block_id}/boc */ -export const downloadBlockchainBlockBoc = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/blocks/${blockId}/boc`, - method: 'GET', - ...params - }); - - return prepareResponse(req); +export const downloadBlockchainBlockBoc = async (blockId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().downloadBlockchainBlockBoc(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7022,20 +10491,19 @@ export const downloadBlockchainBlockBoc = (blockId: string, params: RequestParam * @name GetBlockchainMasterchainShards * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards */ -export const getBlockchainMasterchainShards = ( +export const getBlockchainMasterchainShards = async ( masterchainSeqno: number, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/shards`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlockShards' - }); + try { + const result = await getDefaultClient().getBlockchainMasterchainShards( + masterchainSeqno, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7045,20 +10513,19 @@ export const getBlockchainMasterchainShards = ( * @name GetBlockchainMasterchainBlocks * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks */ -export const getBlockchainMasterchainBlocks = ( +export const getBlockchainMasterchainBlocks = async ( masterchainSeqno: number, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/blocks`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlocks' - }); + try { + const result = await getDefaultClient().getBlockchainMasterchainBlocks( + masterchainSeqno, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7068,20 +10535,19 @@ export const getBlockchainMasterchainBlocks = ( * @name GetBlockchainMasterchainTransactions * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions */ -export const getBlockchainMasterchainTransactions = ( +export const getBlockchainMasterchainTransactions = async ( masterchainSeqno: number, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/transactions`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transactions' - }); + try { + const result = await getDefaultClient().getBlockchainMasterchainTransactions( + masterchainSeqno, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7091,20 +10557,19 @@ export const getBlockchainMasterchainTransactions = ( * @name GetBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config */ -export const getBlockchainConfigFromBlock = ( +export const getBlockchainConfigFromBlock = async ( masterchainSeqno: number, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/config`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainConfig' - }); + try { + const result = await getDefaultClient().getBlockchainConfigFromBlock( + masterchainSeqno, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7114,20 +10579,19 @@ export const getBlockchainConfigFromBlock = ( * @name GetRawBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw */ -export const getRawBlockchainConfigFromBlock = ( +export const getRawBlockchainConfigFromBlock = async ( masterchainSeqno: number, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/masterchain/${masterchainSeqno}/config/raw`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/RawBlockchainConfig' - }); + try { + const result = await getDefaultClient().getRawBlockchainConfigFromBlock( + masterchainSeqno, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7137,17 +10601,16 @@ export const getRawBlockchainConfigFromBlock = ( * @name GetBlockchainBlockTransactions * @request GET:/v2/blockchain/blocks/{block_id}/transactions */ -export const getBlockchainBlockTransactions = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/blocks/${blockId}/transactions`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transactions' - }); +export const getBlockchainBlockTransactions = async ( + blockId: string, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getBlockchainBlockTransactions(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7157,17 +10620,16 @@ export const getBlockchainBlockTransactions = (blockId: string, params: RequestP * @name GetBlockchainTransaction * @request GET:/v2/blockchain/transactions/{transaction_id} */ -export const getBlockchainTransaction = (transactionId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/transactions/${transactionId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transaction' - }); +export const getBlockchainTransaction = async ( + transactionId: string, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getBlockchainTransaction(transactionId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7177,20 +10639,19 @@ export const getBlockchainTransaction = (transactionId: string, params: RequestP * @name GetBlockchainTransactionByMessageHash * @request GET:/v2/blockchain/messages/{msg_id}/transaction */ -export const getBlockchainTransactionByMessageHash = ( +export const getBlockchainTransactionByMessageHash = async ( msgId: string, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/messages/${msgId}/transaction`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transaction' - }); + try { + const result = await getDefaultClient().getBlockchainTransactionByMessageHash( + msgId, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7200,17 +10661,13 @@ export const getBlockchainTransactionByMessageHash = ( * @name GetBlockchainValidators * @request GET:/v2/blockchain/validators */ -export const getBlockchainValidators = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/validators`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Validators' - }); +export const getBlockchainValidators = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getBlockchainValidators(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7220,17 +10677,13 @@ export const getBlockchainValidators = (params: RequestParams = {}) => { * @name GetBlockchainMasterchainHead * @request GET:/v2/blockchain/masterchain-head */ -export const getBlockchainMasterchainHead = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/masterchain-head`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainBlock' - }); +export const getBlockchainMasterchainHead = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getBlockchainMasterchainHead(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7240,18 +10693,16 @@ export const getBlockchainMasterchainHead = (params: RequestParams = {}) => { * @name GetBlockchainRawAccount * @request GET:/v2/blockchain/accounts/{account_id} */ -export const getBlockchainRawAccount = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/blockchain/accounts/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainRawAccount' - }); +export const getBlockchainRawAccount = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getBlockchainRawAccount(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7261,7 +10712,7 @@ export const getBlockchainRawAccount = (accountId_Address: Address, params: Requ * @name GetBlockchainAccountTransactions * @request GET:/v2/blockchain/accounts/{account_id}/transactions */ -export const getBlockchainAccountTransactions = ( +export const getBlockchainAccountTransactions = async ( accountId_Address: Address, query?: { /** @@ -7292,18 +10743,16 @@ export const getBlockchainAccountTransactions = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/blockchain/accounts/${accountId}/transactions`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Transactions' - }); + try { + const result = await getDefaultClient().getBlockchainAccountTransactions( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7313,7 +10762,7 @@ export const getBlockchainAccountTransactions = ( * @name ExecGetMethodForBlockchainAccount * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ -export const execGetMethodForBlockchainAccount = ( +export const execGetMethodForBlockchainAccount = async ( accountId_Address: Address, methodName: string, query?: { @@ -7332,18 +10781,17 @@ export const execGetMethodForBlockchainAccount = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/MethodExecutionResult' - }); + try { + const result = await getDefaultClient().execGetMethodForBlockchainAccount( + accountId_Address, + methodName, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7353,7 +10801,7 @@ export const execGetMethodForBlockchainAccount = ( * @name ExecGetMethodWithBodyForBlockchainAccount * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ -export const execGetMethodWithBodyForBlockchainAccount = ( +export const execGetMethodWithBodyForBlockchainAccount = async ( accountId_Address: Address, methodName: string, data: { @@ -7361,24 +10809,17 @@ export const execGetMethodWithBodyForBlockchainAccount = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['args'], - properties: { - args: { type: 'array', items: { $ref: '#/components/schemas/ExecGetMethodArg' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/MethodExecutionResult' - }); + try { + const result = await getDefaultClient().execGetMethodWithBodyForBlockchainAccount( + accountId_Address, + methodName, + data, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7388,7 +10829,7 @@ export const execGetMethodWithBodyForBlockchainAccount = ( * @name SendBlockchainMessage * @request POST:/v2/blockchain/message */ -export const sendBlockchainMessage = ( +export const sendBlockchainMessage = async ( data: { /** @format cell */ boc?: Cell; @@ -7398,21 +10839,12 @@ export const sendBlockchainMessage = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/message`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - properties: { - boc: { type: 'string', format: 'cell' }, - batch: { type: 'array', maxItems: 5, items: { type: 'string', format: 'cell' } }, - meta: { type: 'object', additionalProperties: { type: 'string' } } - } - }), - ...params - }); - - return prepareResponse(req); + try { + const result = await getDefaultClient().sendBlockchainMessage(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7422,17 +10854,13 @@ export const sendBlockchainMessage = ( * @name GetBlockchainConfig * @request GET:/v2/blockchain/config */ -export const getBlockchainConfig = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/config`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainConfig' - }); +export const getBlockchainConfig = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getBlockchainConfig(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7442,17 +10870,13 @@ export const getBlockchainConfig = (params: RequestParams = {}) => { * @name GetRawBlockchainConfig * @request GET:/v2/blockchain/config/raw */ -export const getRawBlockchainConfig = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/config/raw`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/RawBlockchainConfig' - }); +export const getRawBlockchainConfig = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getRawBlockchainConfig(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7462,21 +10886,16 @@ export const getRawBlockchainConfig = (params: RequestParams = {}) => { * @name BlockchainAccountInspect * @request GET:/v2/blockchain/accounts/{account_id}/inspect */ -export const blockchainAccountInspect = ( +export const blockchainAccountInspect = async ( accountId_Address: Address, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/blockchain/accounts/${accountId}/inspect`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainAccountInspect' - }); + try { + const result = await getDefaultClient().blockchainAccountInspect(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7486,17 +10905,13 @@ export const blockchainAccountInspect = ( * @name GetLibraryByHash * @request GET:/v2/blockchain/libraries/{hash} */ -export const getLibraryByHash = (hash: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/blockchain/libraries/${hash}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainLibrary' - }); +export const getLibraryByHash = async (hash: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getLibraryByHash(hash, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7506,7 +10921,7 @@ export const getLibraryByHash = (hash: string, params: RequestParams = {}) => { * @name GetAccounts * @request POST:/v2/accounts/_bulk */ -export const getAccounts = ( +export const getAccounts = async ( data: { accountIds: Address[]; }, @@ -7516,22 +10931,12 @@ export const getAccounts = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/accounts/_bulk`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Accounts' }); + try { + const result = await getDefaultClient().getAccounts(data, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7541,16 +10946,13 @@ export const getAccounts = ( * @name GetAccount * @request GET:/v2/accounts/{account_id} */ -export const getAccount = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Account' }); +export const getAccount = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getAccount(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7560,18 +10962,16 @@ export const getAccount = (accountId_Address: Address, params: RequestParams = { * @name AccountDnsBackResolve * @request GET:/v2/accounts/{account_id}/dns/backresolve */ -export const accountDnsBackResolve = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/dns/backresolve`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DomainNames' - }); +export const accountDnsBackResolve = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().accountDnsBackResolve(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7581,7 +10981,7 @@ export const accountDnsBackResolve = (accountId_Address: Address, params: Reques * @name GetAccountJettonsBalances * @request GET:/v2/accounts/{account_id}/jettons */ -export const getAccountJettonsBalances = ( +export const getAccountJettonsBalances = async ( accountId_Address: Address, query?: { /** @@ -7597,19 +10997,16 @@ export const getAccountJettonsBalances = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/jettons`, - method: 'GET', - query: query, - queryImplode: ['currencies', 'supported_extensions'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonsBalances' - }); + try { + const result = await getDefaultClient().getAccountJettonsBalances( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7619,7 +11016,7 @@ export const getAccountJettonsBalances = ( * @name GetAccountJettonBalance * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} */ -export const getAccountJettonBalance = ( +export const getAccountJettonBalance = async ( accountId_Address: Address, jettonId_Address: Address, query?: { @@ -7636,20 +11033,17 @@ export const getAccountJettonBalance = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/jettons/${jettonId}`, - method: 'GET', - query: query, - queryImplode: ['currencies', 'supported_extensions'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonBalance' - }); + try { + const result = await getDefaultClient().getAccountJettonBalance( + accountId_Address, + jettonId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7659,7 +11053,7 @@ export const getAccountJettonBalance = ( * @name GetAccountJettonsHistory * @request GET:/v2/accounts/{account_id}/jettons/history */ -export const getAccountJettonsHistory = ( +export const getAccountJettonsHistory = async ( accountId_Address: Address, query: { /** @@ -7677,18 +11071,16 @@ export const getAccountJettonsHistory = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/jettons/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonOperations' - }); + try { + const result = await getDefaultClient().getAccountJettonsHistory( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7699,7 +11091,7 @@ export const getAccountJettonsHistory = ( * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history * @deprecated */ -export const getAccountJettonHistoryById = ( +export const getAccountJettonHistoryById = async ( accountId_Address: Address, jettonId_Address: Address, query: { @@ -7730,19 +11122,17 @@ export const getAccountJettonHistoryById = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/jettons/${jettonId}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); + try { + const result = await getDefaultClient().getAccountJettonHistoryById( + accountId_Address, + jettonId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7752,7 +11142,7 @@ export const getAccountJettonHistoryById = ( * @name GetAccountNftItems * @request GET:/v2/accounts/{account_id}/nfts */ -export const getAccountNftItems = ( +export const getAccountNftItems = async ( accountId_Address: Address, query?: { /** @@ -7780,19 +11170,16 @@ export const getAccountNftItems = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/nfts`, - method: 'GET', - query: query && { - ...query, - collection: query.collection?.toRawString() - }, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/NftItems' }); + try { + const result = await getDefaultClient().getAccountNftItems( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7802,7 +11189,7 @@ export const getAccountNftItems = ( * @name GetAccountEvents * @request GET:/v2/accounts/{account_id}/events */ -export const getAccountEvents = ( +export const getAccountEvents = async ( accountId_Address: Address, query: { /** @@ -7841,20 +11228,13 @@ export const getAccountEvents = ( end_date?: number; }, params: RequestParams = {} -) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/events`, - method: 'GET', - query: query, - queryImplode: ['initiator'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); +) => { + try { + const result = await getDefaultClient().getAccountEvents(accountId_Address, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7864,7 +11244,7 @@ export const getAccountEvents = ( * @name GetAccountEvent * @request GET:/v2/accounts/{account_id}/events/{event_id} */ -export const getAccountEvent = ( +export const getAccountEvent = async ( accountId_Address: Address, eventId: string, query?: { @@ -7876,16 +11256,17 @@ export const getAccountEvent = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/events/${eventId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/AccountEvent' }); + try { + const result = await getDefaultClient().getAccountEvent( + accountId_Address, + eventId, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7895,7 +11276,7 @@ export const getAccountEvent = ( * @name GetAccountTraces * @request GET:/v2/accounts/{account_id}/traces */ -export const getAccountTraces = ( +export const getAccountTraces = async ( accountId_Address: Address, query?: { /** @@ -7914,16 +11295,12 @@ export const getAccountTraces = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/traces`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/TraceIDs' }); + try { + const result = await getDefaultClient().getAccountTraces(accountId_Address, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7933,18 +11310,16 @@ export const getAccountTraces = ( * @name GetAccountSubscriptions * @request GET:/v2/accounts/{account_id}/subscriptions */ -export const getAccountSubscriptions = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/subscriptions`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Subscriptions' - }); +export const getAccountSubscriptions = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getAccountSubscriptions(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7954,15 +11329,13 @@ export const getAccountSubscriptions = (accountId_Address: Address, params: Requ * @name ReindexAccount * @request POST:/v2/accounts/{account_id}/reindex */ -export const reindexAccount = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/reindex`, - method: 'POST', - ...params - }); - - return prepareResponse(req); +export const reindexAccount = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().reindexAccount(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -7972,7 +11345,7 @@ export const reindexAccount = (accountId_Address: Address, params: RequestParams * @name SearchAccounts * @request GET:/v2/accounts/search */ -export const searchAccounts = ( +export const searchAccounts = async ( query: { /** * @minLength 3 @@ -7982,15 +11355,12 @@ export const searchAccounts = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/accounts/search`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/FoundAccounts' }); + try { + const result = await getDefaultClient().searchAccounts(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8000,7 +11370,7 @@ export const searchAccounts = ( * @name GetAccountDnsExpiring * @request GET:/v2/accounts/{account_id}/dns/expiring */ -export const getAccountDnsExpiring = ( +export const getAccountDnsExpiring = async ( accountId_Address: Address, query?: { /** @@ -8012,18 +11382,16 @@ export const getAccountDnsExpiring = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/dns/expiring`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/DnsExpiring' - }); + try { + const result = await getDefaultClient().getAccountDnsExpiring( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8033,20 +11401,16 @@ export const getAccountDnsExpiring = ( * @name GetAccountPublicKey * @request GET:/v2/accounts/{account_id}/publickey */ -export const getAccountPublicKey = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/publickey`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['public_key'], - properties: { public_key: { type: 'string' } } - }); +export const getAccountPublicKey = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getAccountPublicKey(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8056,18 +11420,16 @@ export const getAccountPublicKey = (accountId_Address: Address, params: RequestP * @name GetAccountMultisigs * @request GET:/v2/accounts/{account_id}/multisigs */ -export const getAccountMultisigs = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/multisigs`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Multisigs' - }); +export const getAccountMultisigs = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getAccountMultisigs(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8077,7 +11439,7 @@ export const getAccountMultisigs = (accountId_Address: Address, params: RequestP * @name GetAccountDiff * @request GET:/v2/accounts/{account_id}/diff */ -export const getAccountDiff = ( +export const getAccountDiff = async ( accountId_Address: Address, query: { /** @@ -8095,20 +11457,12 @@ export const getAccountDiff = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/diff`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['balance_change'], - properties: { balance_change: { type: 'integer', format: 'int64' } } - }); + try { + const result = await getDefaultClient().getAccountDiff(accountId_Address, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8118,7 +11472,7 @@ export const getAccountDiff = ( * @name GetAccountExtraCurrencyHistoryById * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history */ -export const getAccountExtraCurrencyHistoryById = ( +export const getAccountExtraCurrencyHistoryById = async ( accountId_Address: Address, id: number, query: { @@ -8149,18 +11503,17 @@ export const getAccountExtraCurrencyHistoryById = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/extra-currency/${id}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); + try { + const result = await getDefaultClient().getAccountExtraCurrencyHistoryById( + accountId_Address, + id, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8170,7 +11523,7 @@ export const getAccountExtraCurrencyHistoryById = ( * @name GetJettonAccountHistoryById * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history */ -export const getJettonAccountHistoryById = ( +export const getJettonAccountHistoryById = async ( accountId_Address: Address, jettonId_Address: Address, query: { @@ -8201,19 +11554,17 @@ export const getJettonAccountHistoryById = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/jettons/${jettonId}/accounts/${accountId}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonOperations' - }); + try { + const result = await getDefaultClient().getJettonAccountHistoryById( + accountId_Address, + jettonId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8223,7 +11574,7 @@ export const getJettonAccountHistoryById = ( * @name GetAccountNftHistory * @request GET:/v2/accounts/{account_id}/nfts/history */ -export const getAccountNftHistory = ( +export const getAccountNftHistory = async ( accountId_Address: Address, query: { /** @@ -8241,18 +11592,16 @@ export const getAccountNftHistory = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/nfts/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftOperations' - }); + try { + const result = await getDefaultClient().getAccountNftHistory( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8262,7 +11611,7 @@ export const getAccountNftHistory = ( * @name GetNftCollections * @request GET:/v2/nfts/collections */ -export const getNftCollections = ( +export const getNftCollections = async ( query?: { /** * @format int32 @@ -8282,17 +11631,12 @@ export const getNftCollections = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/nfts/collections`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftCollections' - }); + try { + const result = await getDefaultClient().getNftCollections(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8302,18 +11646,13 @@ export const getNftCollections = ( * @name GetNftCollection * @request GET:/v2/nfts/collections/{account_id} */ -export const getNftCollection = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/nfts/collections/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftCollection' - }); +export const getNftCollection = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getNftCollection(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8323,29 +11662,18 @@ export const getNftCollection = (accountId_Address: Address, params: RequestPara * @name GetNftCollectionItemsByAddresses * @request POST:/v2/nfts/collections/_bulk */ -export const getNftCollectionItemsByAddresses = ( +export const getNftCollectionItemsByAddresses = async ( data: { accountIds: Address[]; }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/nfts/collections/_bulk`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftCollections' - }); + try { + const result = await getDefaultClient().getNftCollectionItemsByAddresses(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8355,7 +11683,7 @@ export const getNftCollectionItemsByAddresses = ( * @name GetItemsFromCollection * @request GET:/v2/nfts/collections/{account_id}/items */ -export const getItemsFromCollection = ( +export const getItemsFromCollection = async ( accountId_Address: Address, query?: { /** @@ -8372,18 +11700,16 @@ export const getItemsFromCollection = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/nfts/collections/${accountId}/items`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftItems' - }); + try { + const result = await getDefaultClient().getItemsFromCollection( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8393,29 +11719,18 @@ export const getItemsFromCollection = ( * @name GetNftItemsByAddresses * @request POST:/v2/nfts/_bulk */ -export const getNftItemsByAddresses = ( +export const getNftItemsByAddresses = async ( data: { accountIds: Address[]; }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/nfts/_bulk`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/NftItems' - }); + try { + const result = await getDefaultClient().getNftItemsByAddresses(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8425,16 +11740,16 @@ export const getNftItemsByAddresses = ( * @name GetNftItemByAddress * @request GET:/v2/nfts/{account_id} */ -export const getNftItemByAddress = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/nfts/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/NftItem' }); +export const getNftItemByAddress = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getNftItemByAddress(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8445,7 +11760,7 @@ export const getNftItemByAddress = (accountId_Address: Address, params: RequestP * @request GET:/v2/nfts/{account_id}/history * @deprecated */ -export const getNftHistoryById = ( +export const getNftHistoryById = async ( accountId_Address: Address, query: { /** @@ -8475,18 +11790,12 @@ export const getNftHistoryById = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/nfts/${accountId}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvents' - }); + try { + const result = await getDefaultClient().getNftHistoryById(accountId_Address, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8496,15 +11805,13 @@ export const getNftHistoryById = ( * @name GetDnsInfo * @request GET:/v2/dns/{domain_name} */ -export const getDnsInfo = (domainName: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/dns/${domainName}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/DomainInfo' }); +export const getDnsInfo = async (domainName: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getDnsInfo(domainName, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8514,7 +11821,7 @@ export const getDnsInfo = (domainName: string, params: RequestParams = {}) => { * @name DnsResolve * @request GET:/v2/dns/{domain_name}/resolve */ -export const dnsResolve = ( +export const dnsResolve = async ( domainName: string, query?: { /** @default false */ @@ -8522,15 +11829,12 @@ export const dnsResolve = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/dns/${domainName}/resolve`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/DnsRecord' }); + try { + const result = await getDefaultClient().dnsResolve(domainName, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8540,15 +11844,13 @@ export const dnsResolve = ( * @name GetDomainBids * @request GET:/v2/dns/{domain_name}/bids */ -export const getDomainBids = (domainName: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/dns/${domainName}/bids`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/DomainBids' }); +export const getDomainBids = async (domainName: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getDomainBids(domainName, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8558,7 +11860,7 @@ export const getDomainBids = (domainName: string, params: RequestParams = {}) => * @name GetAllAuctions * @request GET:/v2/dns/auctions */ -export const getAllAuctions = ( +export const getAllAuctions = async ( query?: { /** * domain filter for current auctions "ton" or "t.me" @@ -8568,15 +11870,12 @@ export const getAllAuctions = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/dns/auctions`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Auctions' }); + try { + const result = await getDefaultClient().getAllAuctions(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8586,15 +11885,13 @@ export const getAllAuctions = ( * @name GetTrace * @request GET:/v2/traces/{trace_id} */ -export const getTrace = (traceId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/traces/${traceId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); +export const getTrace = async (traceId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getTrace(traceId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8604,15 +11901,13 @@ export const getTrace = (traceId: string, params: RequestParams = {}) => { * @name GetEvent * @request GET:/v2/events/{event_id} */ -export const getEvent = (eventId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/events/${eventId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Event' }); +export const getEvent = async (eventId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getEvent(eventId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8622,7 +11917,7 @@ export const getEvent = (eventId: string, params: RequestParams = {}) => { * @name GetJettons * @request GET:/v2/jettons */ -export const getJettons = ( +export const getJettons = async ( query?: { /** * @format int32 @@ -8642,15 +11937,12 @@ export const getJettons = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/jettons`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Jettons' }); + try { + const result = await getDefaultClient().getJettons(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8660,16 +11952,13 @@ export const getJettons = ( * @name GetJettonInfo * @request GET:/v2/jettons/{account_id} */ -export const getJettonInfo = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/jettons/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/JettonInfo' }); +export const getJettonInfo = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getJettonInfo(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8679,29 +11968,18 @@ export const getJettonInfo = (accountId_Address: Address, params: RequestParams * @name GetJettonInfosByAddresses * @request POST:/v2/jettons/_bulk */ -export const getJettonInfosByAddresses = ( +export const getJettonInfosByAddresses = async ( data: { accountIds: Address[]; }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/jettons/_bulk`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['accountIds'], - properties: { - accountIds: { type: 'array', items: { type: 'string', format: 'address' } } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Jettons' - }); + try { + const result = await getDefaultClient().getJettonInfosByAddresses(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8711,7 +11989,7 @@ export const getJettonInfosByAddresses = ( * @name GetJettonHolders * @request GET:/v2/jettons/{account_id}/holders */ -export const getJettonHolders = ( +export const getJettonHolders = async ( accountId_Address: Address, query?: { /** @@ -8729,18 +12007,12 @@ export const getJettonHolders = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/jettons/${accountId}/holders`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonHolders' - }); + try { + const result = await getDefaultClient().getJettonHolders(accountId_Address, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8750,23 +12022,21 @@ export const getJettonHolders = ( * @name GetJettonTransferPayload * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload */ -export const getJettonTransferPayload = ( +export const getJettonTransferPayload = async ( accountId_Address: Address, jettonId_Address: Address, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/jettons/${jettonId}/transfer/${accountId}/payload`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/JettonTransferPayload' - }); + try { + const result = await getDefaultClient().getJettonTransferPayload( + accountId_Address, + jettonId_Address, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8776,15 +12046,13 @@ export const getJettonTransferPayload = ( * @name GetJettonsEvents * @request GET:/v2/events/{event_id}/jettons */ -export const getJettonsEvents = (eventId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/events/${eventId}/jettons`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Event' }); +export const getJettonsEvents = async (eventId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getJettonsEvents(eventId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8794,17 +12062,13 @@ export const getJettonsEvents = (eventId: string, params: RequestParams = {}) => * @name GetExtraCurrencyInfo * @request GET:/v2/extra-currency/{id} */ -export const getExtraCurrencyInfo = (id: number, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/extra-currency/${id}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/EcPreview' - }); +export const getExtraCurrencyInfo = async (id: number, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getExtraCurrencyInfo(id, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8814,21 +12078,19 @@ export const getExtraCurrencyInfo = (id: number, params: RequestParams = {}) => * @name GetAccountNominatorsPools * @request GET:/v2/staking/nominator/{account_id}/pools */ -export const getAccountNominatorsPools = ( +export const getAccountNominatorsPools = async ( accountId_Address: Address, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/staking/nominator/${accountId}/pools`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountStaking' - }); + try { + const result = await getDefaultClient().getAccountNominatorsPools( + accountId_Address, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8838,23 +12100,16 @@ export const getAccountNominatorsPools = ( * @name GetStakingPoolInfo * @request GET:/v2/staking/pool/{account_id} */ -export const getStakingPoolInfo = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/staking/pool/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['implementation', 'pool'], - properties: { - implementation: { $ref: '#/components/schemas/PoolImplementation' }, - pool: { $ref: '#/components/schemas/PoolInfo' } - } - }); +export const getStakingPoolInfo = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getStakingPoolInfo(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8864,20 +12119,16 @@ export const getStakingPoolInfo = (accountId_Address: Address, params: RequestPa * @name GetStakingPoolHistory * @request GET:/v2/staking/pool/{account_id}/history */ -export const getStakingPoolHistory = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/staking/pool/${accountId}/history`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['apy'], - properties: { apy: { type: 'array', items: { $ref: '#/components/schemas/ApyHistory' } } } - }); +export const getStakingPoolHistory = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getStakingPoolHistory(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8887,7 +12138,7 @@ export const getStakingPoolHistory = (accountId_Address: Address, params: Reques * @name GetStakingPools * @request GET:/v2/staking/pools */ -export const getStakingPools = ( +export const getStakingPools = async ( query?: { /** * account ID @@ -8903,28 +12154,12 @@ export const getStakingPools = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/staking/pools`, - method: 'GET', - query: query && { - ...query, - available_for: query.available_for?.toRawString() - }, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['pools', 'implementations'], - properties: { - pools: { type: 'array', items: { $ref: '#/components/schemas/PoolInfo' } }, - implementations: { - type: 'object', - additionalProperties: { $ref: '#/components/schemas/PoolImplementation' } - } - } - }); + try { + const result = await getDefaultClient().getStakingPools(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8934,21 +12169,13 @@ export const getStakingPools = ( * @name GetStorageProviders * @request GET:/v2/storage/providers */ -export const getStorageProviders = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/storage/providers`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['providers'], - properties: { - providers: { type: 'array', items: { $ref: '#/components/schemas/StorageProvider' } } - } - }); +export const getStorageProviders = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getStorageProviders(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -8958,7 +12185,7 @@ export const getStorageProviders = (params: RequestParams = {}) => { * @name GetRates * @request GET:/v2/rates */ -export const getRates = ( +export const getRates = async ( query: { /** * accept cryptocurrencies or jetton master addresses, separated by commas @@ -8975,25 +12202,12 @@ export const getRates = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/rates`, - method: 'GET', - query: query, - queryImplode: ['tokens', 'currencies'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['rates'], - properties: { - rates: { - type: 'object', - additionalProperties: { $ref: '#/components/schemas/TokenRates' } - } - } - }); + try { + const result = await getDefaultClient().getRates(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9003,7 +12217,7 @@ export const getRates = ( * @name GetChartRates * @request GET:/v2/rates/chart */ -export const getChartRates = ( +export const getChartRates = async ( query: { /** accept cryptocurrencies or jetton master addresses */ token: Address | string; @@ -9031,21 +12245,12 @@ export const getChartRates = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/rates/chart`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['points'], - properties: { - points: { type: 'array', items: { $ref: '#/components/schemas/ChartPoints' } } - } - }); + try { + const result = await getDefaultClient().getChartRates(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9055,21 +12260,13 @@ export const getChartRates = ( * @name GetMarketsRates * @request GET:/v2/rates/markets */ -export const getMarketsRates = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/rates/markets`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['markets'], - properties: { - markets: { type: 'array', items: { $ref: '#/components/schemas/MarketTonRates' } } - } - }); +export const getMarketsRates = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getMarketsRates(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9079,19 +12276,13 @@ export const getMarketsRates = (params: RequestParams = {}) => { * @name GetTonConnectPayload * @request GET:/v2/tonconnect/payload */ -export const getTonConnectPayload = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/tonconnect/payload`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['payload'], - properties: { payload: { type: 'string' } } - }); +export const getTonConnectPayload = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getTonConnectPayload(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9101,28 +12292,19 @@ export const getTonConnectPayload = (params: RequestParams = {}) => { * @name GetAccountInfoByStateInit * @request POST:/v2/tonconnect/stateinit */ -export const getAccountInfoByStateInit = ( +export const getAccountInfoByStateInit = async ( data: { /** @format cell-base64 */ stateInit: Cell; }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/tonconnect/stateinit`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['stateInit'], - properties: { stateInit: { type: 'string', format: 'cell-base64' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountInfoByStateInit' - }); + try { + const result = await getDefaultClient().getAccountInfoByStateInit(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9132,7 +12314,7 @@ export const getAccountInfoByStateInit = ( * @name TonConnectProof * @request POST:/v2/wallet/auth/proof */ -export const tonConnectProof = ( +export const tonConnectProof = async ( data: { /** * @format address @@ -9151,51 +12333,20 @@ export const tonConnectProof = ( value: string; }; signature: string; - /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ - payload: string; - /** @format cell-base64 */ - stateInit?: Cell; - }; - }, - params: RequestParams = {} -) => { - const req = getHttpClient().request({ - path: `/v2/wallet/auth/proof`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['address', 'proof'], - properties: { - address: { type: 'string', format: 'address' }, - proof: { - type: 'object', - required: ['timestamp', 'domain', 'signature', 'payload'], - properties: { - timestamp: { type: 'integer', format: 'int64' }, - domain: { - type: 'object', - required: ['value'], - properties: { - lengthBytes: { type: 'integer', format: 'int32' }, - value: { type: 'string' } - } - }, - signature: { type: 'string' }, - payload: { type: 'string' }, - stateInit: { type: 'string', format: 'cell-base64' } - } - } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['token'], - properties: { token: { type: 'string' } } - }); + /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ + payload: string; + /** @format cell-base64 */ + stateInit?: Cell; + }; + }, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().tonConnectProof(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9205,16 +12356,13 @@ export const tonConnectProof = ( * @name GetAccountSeqno * @request GET:/v2/wallet/{account_id}/seqno */ -export const getAccountSeqno = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/wallet/${accountId}/seqno`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Seqno' }); +export const getAccountSeqno = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getAccountSeqno(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9224,16 +12372,13 @@ export const getAccountSeqno = (accountId_Address: Address, params: RequestParam * @name GetWalletInfo * @request GET:/v2/wallet/{account_id} */ -export const getWalletInfo = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/wallet/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Wallet' }); +export const getWalletInfo = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getWalletInfo(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9243,17 +12388,13 @@ export const getWalletInfo = (accountId_Address: Address, params: RequestParams * @name GetWalletsByPublicKey * @request GET:/v2/pubkeys/{public_key}/wallets */ -export const getWalletsByPublicKey = (publicKey: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/pubkeys/${publicKey}/wallets`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/Wallets' - }); +export const getWalletsByPublicKey = async (publicKey: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getWalletsByPublicKey(publicKey, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9263,15 +12404,13 @@ export const getWalletsByPublicKey = (publicKey: string, params: RequestParams = * @name GaslessConfig * @request GET:/v2/gasless/config */ -export const gaslessConfig = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/gasless/config`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/GaslessConfig' }); +export const gaslessConfig = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().gaslessConfig(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9281,7 +12420,7 @@ export const gaslessConfig = (params: RequestParams = {}) => { * @name GaslessEstimate * @request POST:/v2/gasless/estimate/{master_id} */ -export const gaslessEstimate = ( +export const gaslessEstimate = async ( masterId_Address: Address, data: { /** @@ -9301,35 +12440,12 @@ export const gaslessEstimate = ( }, params: RequestParams = {} ) => { - const masterId = masterId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/gasless/estimate/${masterId}`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['messages', 'walletAddress', 'walletPublicKey'], - properties: { - throwErrorIfNotEnoughJettons: { type: 'boolean', default: false }, - returnEmulation: { type: 'boolean', default: false }, - walletAddress: { type: 'string', format: 'address' }, - walletPublicKey: { type: 'string' }, - messages: { - type: 'array', - items: { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - } - } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/SignRawParams' - }); + try { + const result = await getDefaultClient().gaslessEstimate(masterId_Address, data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9339,7 +12455,7 @@ export const gaslessEstimate = ( * @name GaslessSend * @request POST:/v2/gasless/send */ -export const gaslessSend = ( +export const gaslessSend = async ( data: { /** hex encoded public key */ walletPublicKey: string; @@ -9348,22 +12464,12 @@ export const gaslessSend = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/gasless/send`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['boc', 'walletPublicKey'], - properties: { - walletPublicKey: { type: 'string' }, - boc: { type: 'string', format: 'cell' } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/GaslessTx' }); + try { + const result = await getDefaultClient().gaslessSend(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9373,23 +12479,13 @@ export const gaslessSend = ( * @name GetRawMasterchainInfo * @request GET:/v2/liteserver/get_masterchain_info */ -export const getRawMasterchainInfo = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_masterchain_info`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['last', 'state_root_hash', 'init'], - properties: { - last: { $ref: '#/components/schemas/BlockRaw' }, - state_root_hash: { type: 'string' }, - init: { $ref: '#/components/schemas/InitStateRaw' } - } - }); +export const getRawMasterchainInfo = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getRawMasterchainInfo(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9399,7 +12495,7 @@ export const getRawMasterchainInfo = (params: RequestParams = {}) => { * @name GetRawMasterchainInfoExt * @request GET:/v2/liteserver/get_masterchain_info_ext */ -export const getRawMasterchainInfoExt = ( +export const getRawMasterchainInfoExt = async ( query: { /** * mode @@ -9410,37 +12506,12 @@ export const getRawMasterchainInfoExt = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_masterchain_info_ext`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: [ - 'mode', - 'version', - 'capabilities', - 'last', - 'last_utime', - 'now', - 'state_root_hash', - 'init' - ], - properties: { - mode: { type: 'integer', format: 'int32' }, - version: { type: 'integer', format: 'int32' }, - capabilities: { type: 'integer', format: 'int64' }, - last: { $ref: '#/components/schemas/BlockRaw' }, - last_utime: { type: 'integer', format: 'int32' }, - now: { type: 'integer', format: 'int32' }, - state_root_hash: { type: 'string' }, - init: { $ref: '#/components/schemas/InitStateRaw' } - } - }); + try { + const result = await getDefaultClient().getRawMasterchainInfoExt(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9450,19 +12521,13 @@ export const getRawMasterchainInfoExt = ( * @name GetRawTime * @request GET:/v2/liteserver/get_time */ -export const getRawTime = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_time`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['time'], - properties: { time: { type: 'integer', format: 'int32' } } - }); +export const getRawTime = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getRawTime(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9472,19 +12537,13 @@ export const getRawTime = (params: RequestParams = {}) => { * @name GetRawBlockchainBlock * @request GET:/v2/liteserver/get_block/{block_id} */ -export const getRawBlockchainBlock = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_block/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'data'], - properties: { id: { $ref: '#/components/schemas/BlockRaw' }, data: { type: 'string' } } - }); +export const getRawBlockchainBlock = async (blockId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getRawBlockchainBlock(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9494,24 +12553,13 @@ export const getRawBlockchainBlock = (blockId: string, params: RequestParams = { * @name GetRawBlockchainBlockState * @request GET:/v2/liteserver/get_state/{block_id} */ -export const getRawBlockchainBlockState = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_state/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'root_hash', 'file_hash', 'data'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - root_hash: { type: 'string' }, - file_hash: { type: 'string' }, - data: { type: 'string' } - } - }); +export const getRawBlockchainBlockState = async (blockId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getRawBlockchainBlockState(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9521,7 +12569,7 @@ export const getRawBlockchainBlockState = (blockId: string, params: RequestParam * @name GetRawBlockchainBlockHeader * @request GET:/v2/liteserver/get_block_header/{block_id} */ -export const getRawBlockchainBlockHeader = ( +export const getRawBlockchainBlockHeader = async ( blockId: string, query: { /** @@ -9533,23 +12581,12 @@ export const getRawBlockchainBlockHeader = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_block_header/${blockId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'mode', 'header_proof'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - mode: { type: 'integer', format: 'int32' }, - header_proof: { type: 'string' } - } - }); + try { + const result = await getDefaultClient().getRawBlockchainBlockHeader(blockId, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9559,30 +12596,19 @@ export const getRawBlockchainBlockHeader = ( * @name SendRawMessage * @request POST:/v2/liteserver/send_message */ -export const sendRawMessage = ( +export const sendRawMessage = async ( data: { /** @format cell-base64 */ body: Cell; }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/send_message`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['body'], - properties: { body: { type: 'string', format: 'cell-base64' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['code'], - properties: { code: { type: 'integer', format: 'int32' } } - }); + try { + const result = await getDefaultClient().sendRawMessage(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9592,7 +12618,7 @@ export const sendRawMessage = ( * @name GetRawAccountState * @request GET:/v2/liteserver/get_account_state/{account_id} */ -export const getRawAccountState = ( +export const getRawAccountState = async ( accountId_Address: Address, query?: { /** @@ -9603,26 +12629,16 @@ export const getRawAccountState = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/liteserver/get_account_state/${accountId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'shardblk', 'shard_proof', 'proof', 'state'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - shardblk: { $ref: '#/components/schemas/BlockRaw' }, - shard_proof: { type: 'string' }, - proof: { type: 'string' }, - state: { type: 'string' } - } - }); + try { + const result = await getDefaultClient().getRawAccountState( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9632,7 +12648,7 @@ export const getRawAccountState = ( * @name GetRawShardInfo * @request GET:/v2/liteserver/get_shard_info/{block_id} */ -export const getRawShardInfo = ( +export const getRawShardInfo = async ( blockId: string, query: { /** @@ -9655,24 +12671,12 @@ export const getRawShardInfo = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_shard_info/${blockId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'shardblk', 'shard_proof', 'shard_descr'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - shardblk: { $ref: '#/components/schemas/BlockRaw' }, - shard_proof: { type: 'string' }, - shard_descr: { type: 'string' } - } - }); + try { + const result = await getDefaultClient().getRawShardInfo(blockId, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9682,23 +12686,13 @@ export const getRawShardInfo = ( * @name GetAllRawShardsInfo * @request GET:/v2/liteserver/get_all_shards_info/{block_id} */ -export const getAllRawShardsInfo = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_all_shards_info/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'proof', 'data'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - proof: { type: 'string' }, - data: { type: 'string' } - } - }); +export const getAllRawShardsInfo = async (blockId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getAllRawShardsInfo(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9708,7 +12702,7 @@ export const getAllRawShardsInfo = (blockId: string, params: RequestParams = {}) * @name GetRawTransactions * @request GET:/v2/liteserver/get_transactions/{account_id} */ -export const getRawTransactions = ( +export const getRawTransactions = async ( accountId_Address: Address, query: { /** @@ -9731,23 +12725,16 @@ export const getRawTransactions = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/liteserver/get_transactions/${accountId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['ids', 'transactions'], - properties: { - ids: { type: 'array', items: { $ref: '#/components/schemas/BlockRaw' } }, - transactions: { type: 'string' } - } - }); + try { + const result = await getDefaultClient().getRawTransactions( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9757,7 +12744,7 @@ export const getRawTransactions = ( * @name GetRawListBlockTransactions * @request GET:/v2/liteserver/list_block_transactions/{block_id} */ -export const getRawListBlockTransactions = ( +export const getRawListBlockTransactions = async ( blockId: string, query: { /** @@ -9787,41 +12774,12 @@ export const getRawListBlockTransactions = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/list_block_transactions/${blockId}`, - method: 'GET', - query: query && { - ...query, - account_id: query.account_id?.toRawString() - }, - queryImplode: ['account_id'], - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['id', 'req_count', 'incomplete', 'ids', 'proof'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - req_count: { type: 'integer', format: 'int32' }, - incomplete: { type: 'boolean' }, - ids: { - type: 'array', - items: { - type: 'object', - required: ['mode'], - properties: { - mode: { type: 'integer', format: 'int32' }, - account: { type: 'string' }, - lt: { type: 'integer', format: 'bigint', 'x-js-format': 'bigint' }, - hash: { type: 'string' } - } - } - }, - proof: { type: 'string' } - } - }); + try { + const result = await getDefaultClient().getRawListBlockTransactions(blockId, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9831,7 +12789,7 @@ export const getRawListBlockTransactions = ( * @name GetRawBlockProof * @request GET:/v2/liteserver/get_block_proof */ -export const getRawBlockProof = ( +export const getRawBlockProof = async ( query: { /** * known block: (workchain,shard,seqno,root_hash,file_hash) @@ -9852,92 +12810,12 @@ export const getRawBlockProof = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_block_proof`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['complete', 'from', 'to', 'steps'], - properties: { - complete: { type: 'boolean' }, - from: { $ref: '#/components/schemas/BlockRaw' }, - to: { $ref: '#/components/schemas/BlockRaw' }, - steps: { - type: 'array', - items: { - type: 'object', - required: ['lite_server_block_link_back', 'lite_server_block_link_forward'], - properties: { - lite_server_block_link_back: { - type: 'object', - required: [ - 'to_key_block', - 'from', - 'to', - 'dest_proof', - 'proof', - 'state_proof' - ], - properties: { - to_key_block: { type: 'boolean' }, - from: { $ref: '#/components/schemas/BlockRaw' }, - to: { $ref: '#/components/schemas/BlockRaw' }, - dest_proof: { type: 'string' }, - proof: { type: 'string' }, - state_proof: { type: 'string' } - } - }, - lite_server_block_link_forward: { - type: 'object', - required: [ - 'to_key_block', - 'from', - 'to', - 'dest_proof', - 'config_proof', - 'signatures' - ], - properties: { - to_key_block: { type: 'boolean' }, - from: { $ref: '#/components/schemas/BlockRaw' }, - to: { $ref: '#/components/schemas/BlockRaw' }, - dest_proof: { type: 'string' }, - config_proof: { type: 'string' }, - signatures: { - type: 'object', - required: [ - 'validator_set_hash', - 'catchain_seqno', - 'signatures' - ], - properties: { - validator_set_hash: { type: 'integer', format: 'int64' }, - catchain_seqno: { type: 'integer', format: 'int32' }, - signatures: { - type: 'array', - items: { - type: 'object', - required: ['node_id_short', 'signature'], - properties: { - node_id_short: { type: 'string' }, - signature: { type: 'string' } - } - } - } - } - } - } - } - } - } - } - } - }); + try { + const result = await getDefaultClient().getRawBlockProof(query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9947,7 +12825,7 @@ export const getRawBlockProof = ( * @name GetRawConfig * @request GET:/v2/liteserver/get_config_all/{block_id} */ -export const getRawConfig = ( +export const getRawConfig = async ( blockId: string, query: { /** @@ -9959,24 +12837,12 @@ export const getRawConfig = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_config_all/${blockId}`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['mode', 'id', 'state_proof', 'config_proof'], - properties: { - mode: { type: 'integer', format: 'int32' }, - id: { $ref: '#/components/schemas/BlockRaw' }, - state_proof: { type: 'string' }, - config_proof: { type: 'string' } - } - }); + try { + const result = await getDefaultClient().getRawConfig(blockId, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -9986,32 +12852,13 @@ export const getRawConfig = ( * @name GetRawShardBlockProof * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} */ -export const getRawShardBlockProof = (blockId: string, params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_shard_block_proof/${blockId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['masterchain_id', 'links'], - properties: { - masterchain_id: { $ref: '#/components/schemas/BlockRaw' }, - links: { - type: 'array', - items: { - type: 'object', - required: ['id', 'proof'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - proof: { type: 'string' } - } - } - } - } - }); +export const getRawShardBlockProof = async (blockId: string, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getRawShardBlockProof(blockId, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10021,32 +12868,13 @@ export const getRawShardBlockProof = (blockId: string, params: RequestParams = { * @name GetOutMsgQueueSizes * @request GET:/v2/liteserver/get_out_msg_queue_sizes */ -export const getOutMsgQueueSizes = (params: RequestParams = {}) => { - const req = getHttpClient().request({ - path: `/v2/liteserver/get_out_msg_queue_sizes`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - type: 'object', - required: ['ext_msg_queue_size_limit', 'shards'], - properties: { - ext_msg_queue_size_limit: { type: 'integer', format: 'uint32' }, - shards: { - type: 'array', - items: { - type: 'object', - required: ['id', 'size'], - properties: { - id: { $ref: '#/components/schemas/BlockRaw' }, - size: { type: 'integer', format: 'uint32' } - } - } - } - } - }); +export const getOutMsgQueueSizes = async (params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getOutMsgQueueSizes(params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10056,16 +12884,16 @@ export const getOutMsgQueueSizes = (params: RequestParams = {}) => { * @name GetMultisigAccount * @request GET:/v2/multisig/{account_id} */ -export const getMultisigAccount = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/multisig/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Multisig' }); +export const getMultisigAccount = async ( + accountId_Address: Address, + params: RequestParams = {} +) => { + try { + const result = await getDefaultClient().getMultisigAccount(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10075,18 +12903,13 @@ export const getMultisigAccount = (accountId_Address: Address, params: RequestPa * @name GetMultisigOrder * @request GET:/v2/multisig/order/{account_id} */ -export const getMultisigOrder = (accountId_Address: Address, params: RequestParams = {}) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/multisig/order/${accountId}`, - method: 'GET', - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/MultisigOrder' - }); +export const getMultisigOrder = async (accountId_Address: Address, params: RequestParams = {}) => { + try { + const result = await getDefaultClient().getMultisigOrder(accountId_Address, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10096,26 +12919,19 @@ export const getMultisigOrder = (accountId_Address: Address, params: RequestPara * @name DecodeMessage * @request POST:/v2/message/decode */ -export const decodeMessage = ( +export const decodeMessage = async ( data: { /** @format cell */ boc: Cell; }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/message/decode`, - method: 'POST', - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/DecodedMessage' }); + try { + const result = await getDefaultClient().decodeMessage(data, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10125,7 +12941,7 @@ export const decodeMessage = ( * @name EmulateMessageToEvent * @request POST:/v2/events/emulate */ -export const emulateMessageToEvent = ( +export const emulateMessageToEvent = async ( data: { /** @format cell */ boc: Cell; @@ -10135,20 +12951,12 @@ export const emulateMessageToEvent = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/events/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Event' }); + try { + const result = await getDefaultClient().emulateMessageToEvent(data, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10158,7 +12966,7 @@ export const emulateMessageToEvent = ( * @name EmulateMessageToTrace * @request POST:/v2/traces/emulate */ -export const emulateMessageToTrace = ( +export const emulateMessageToTrace = async ( data: { /** @format cell */ boc: Cell; @@ -10168,20 +12976,12 @@ export const emulateMessageToTrace = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/traces/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); + try { + const result = await getDefaultClient().emulateMessageToTrace(data, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10191,7 +12991,7 @@ export const emulateMessageToTrace = ( * @name EmulateMessageToWallet * @request POST:/v2/wallet/emulate */ -export const emulateMessageToWallet = ( +export const emulateMessageToWallet = async ( data: { /** @format cell */ boc: Cell; @@ -10215,35 +13015,12 @@ export const emulateMessageToWallet = ( }, params: RequestParams = {} ) => { - const req = getHttpClient().request({ - path: `/v2/wallet/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { - boc: { type: 'string', format: 'cell' }, - params: { - type: 'array', - items: { - type: 'object', - required: ['address'], - properties: { - address: { type: 'string', format: 'address' }, - balance: { type: 'integer', format: 'bigint', 'x-js-format': 'bigint' } - } - } - } - } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/MessageConsequences' - }); + try { + const result = await getDefaultClient().emulateMessageToWallet(data, query, params); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10253,7 +13030,7 @@ export const emulateMessageToWallet = ( * @name EmulateMessageToAccountEvent * @request POST:/v2/accounts/{account_id}/events/emulate */ -export const emulateMessageToAccountEvent = ( +export const emulateMessageToAccountEvent = async ( accountId_Address: Address, data: { /** @format cell */ @@ -10264,23 +13041,17 @@ export const emulateMessageToAccountEvent = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/accounts/${accountId}/events/emulate`, - method: 'POST', - query: query, - body: prepareRequestData(data, { - type: 'object', - required: ['boc'], - properties: { boc: { type: 'string', format: 'cell' } } - }), - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountEvent' - }); + try { + const result = await getDefaultClient().emulateMessageToAccountEvent( + accountId_Address, + data, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; /** @@ -10290,7 +13061,7 @@ export const emulateMessageToAccountEvent = ( * @name GetPurchaseHistory * @request GET:/v2/purchases/{account_id}/history */ -export const getPurchaseHistory = ( +export const getPurchaseHistory = async ( accountId_Address: Address, query?: { /** @@ -10309,16 +13080,14 @@ export const getPurchaseHistory = ( }, params: RequestParams = {} ) => { - const accountId = accountId_Address.toRawString(); - const req = getHttpClient().request({ - path: `/v2/purchases/${accountId}/history`, - method: 'GET', - query: query, - format: 'json', - ...params - }); - - return prepareResponse(req, { - $ref: '#/components/schemas/AccountPurchases' - }); + try { + const result = await getDefaultClient().getPurchaseHistory( + accountId_Address, + query, + params + ); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } }; diff --git a/packages/client/src/templates/api.ejs b/packages/client/src/templates/api.ejs index 05f613d..3f6942e 100644 --- a/packages/client/src/templates/api.ejs +++ b/packages/client/src/templates/api.ejs @@ -87,12 +87,52 @@ const components = <%~ componentsJson %> */ <% } %> -// Singleton HttpClient instance -let httpClient: HttpClient | null = null; +/** + * TonAPI Client - instance-based approach (recommended) + * + * @example + * ```typescript + * const client = new TonApiClient({ + * baseUrl: 'https://tonapi.io', + * apiKey: process.env.TON_API_KEY + * }); + * + * try { + * const account = await client.getAccount(address); + * console.log(account); + * } catch (error) { + * console.error('Error:', error.message); + * } + * ``` + */ +export class TonApiClient { + private http: HttpClient; + + constructor(apiConfig: ApiConfig = {}) { + this.http = new HttpClient(apiConfig); + } + +<% if (routes.outOfModule) { %> + <% for (const route of routes.outOfModule) { %> +<%~ includeFile('./procedure-call.ejs', { ...it, route, isFlat: false }) %> + <% } %> +<% } %> + +<% if (routes.combined) { %> + <% for (const { routes: combinedRoutes = [], moduleName } of routes.combined) { %> + <% for (const route of combinedRoutes) { %> +<%~ includeFile('./procedure-call.ejs', { ...it, route, isFlat: false }) %> + <% } %> + <% } %> +<% } %> +} + +// Default client instance for global methods +let defaultClient: TonApiClient | null = null; /** - * Initialize the API client with configuration. - * Should be called once at application startup. + * Initialize the global API client with configuration. + * For advanced use cases with global methods. * * @param apiConfig - Configuration for the API client * @param apiConfig.baseUrl - API base URL @@ -105,21 +145,31 @@ let httpClient: HttpClient | null = null; * baseUrl: 'https://tonapi.io', * apiKey: process.env.TON_API_KEY * }); + * + * const { data, error } = await getAccount(address); + * if (error) { + * console.error('Error:', error.message); + * } else { + * console.log(data); + * } * ``` */ export function initClient(apiConfig: ApiConfig = {}): void { - httpClient = new HttpClient(apiConfig); + defaultClient = new TonApiClient(apiConfig); } /** - * Get the current HttpClient instance (creates one if it doesn't exist) + * Get the current default client instance * @internal */ -function getHttpClient(): HttpClient { - if (!httpClient) { - httpClient = new HttpClient(); +function getDefaultClient(): TonApiClient { + if (!defaultClient) { + throw new Error( + 'TonApiClient is not initialized. Call initClient() before using global methods, ' + + 'or use new TonApiClient() for instance-based approach.' + ); } - return httpClient; + return defaultClient; } <% if (routes.outOfModule) { %> diff --git a/packages/client/src/templates/errors.ejs b/packages/client/src/templates/errors.ejs index 22b3787..2a54dea 100644 --- a/packages/client/src/templates/errors.ejs +++ b/packages/client/src/templates/errors.ejs @@ -73,13 +73,13 @@ export class TonApiNetworkError extends TonApiErrorAbstract { } /** - * Parsing error for Address, Cell, BigInt, or TupleItem + * Parsing error for Address, Cell, BigInt, TupleItem, or Unknown * Thrown when SDK fails to parse data returned from TonAPI * * @example * ```typescript * if (error instanceof TonApiParsingError) { - * console.log('Parsing type:', error.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem' + * console.log('Parsing type:', error.parsingType); // 'Address', 'Cell', 'BigInt', 'TupleItem', 'Unknown' * console.log('Error message:', error.message); * console.log('Original response:', error.response); * } @@ -87,10 +87,10 @@ export class TonApiNetworkError extends TonApiErrorAbstract { */ export class TonApiParsingError extends TonApiErrorAbstract { readonly type = 'parsing_error' as const; - readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem'; + readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown'; readonly response: unknown; - constructor(parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem', message: string, cause: unknown, response: unknown) { + constructor(parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown', message: string, cause: unknown, response: unknown) { const formattedMessage = `SDK parsing error [${parsingType}]: ${message}`; super(formattedMessage, cause); this.name = 'TonApiParsingError'; diff --git a/packages/client/src/templates/procedure-call.ejs b/packages/client/src/templates/procedure-call.ejs index 18c1493..19b4c76 100644 --- a/packages/client/src/templates/procedure-call.ejs +++ b/packages/client/src/templates/procedure-call.ejs @@ -25,8 +25,9 @@ const pathParams = originPathParams.map( const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH; +// Use consistent parameter name for both class methods and global functions const requestConfigParam = { - name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES), + name: 'params', optional: true, type: "RequestParams", defaultValue: "{}", @@ -42,11 +43,14 @@ const rawWrapperArgs = _.compact([ ]); // Sort by optionality -const wrapperArgs = _ - .sortBy(rawWrapperArgs, [o => o.optional]) +const sortedWrapperArgs = _.sortBy(rawWrapperArgs, [o => o.optional]); +const wrapperArgs = sortedWrapperArgs .map(argToTmpl) .join(', '); +// For passing arguments to class method in correct order (use sorted order) +const passedArgs = sortedWrapperArgs.map(arg => arg.name).join(', '); + // RequestParams["type"] const requestContentKind = { "JSON": "ContentType.Json", @@ -105,9 +109,19 @@ const queryImplodeTmpl = queryImplodeParams.length === 0 ? null : JSON.stringify <%~ routeDocs.lines %> */ -<% if (isFlat) { %>export const <% } %><%~ route.routeName.usage %><%~ route.namespace && !isFlat ? ': ' : ' = ' %> (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { +<% if (isFlat) { %> +export const <%~ route.routeName.usage %> = async (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { + try { + const result = await getDefaultClient().<%~ route.routeName.usage %>(<%~ passedArgs %>); + return { data: result, error: null }; + } catch (error) { + return { data: null, error: error as TonApiError }; + } +}; +<% } else { %> +async <%~ route.routeName.usage %>(<%~ wrapperArgs %>)<%~ config.toJS ? `: Promise<${type}>` : "" %> { <%~ reducedPathParams %> - const req = <%~ isFlat ? 'getHttpClient().request' : config.singleHttpClient ? 'this.http.request' : 'this.request' %><<%~ type %>, <%~ errorType %>>({ + const req = this.http.request<<%~ type %>, <%~ errorType %>>({ path: `<%~ path %>`, method: '<%~ _.upperCase(method) %>', <%~ queryTmpl ? `query: ${queryTmplValue},` : '' %> @@ -120,5 +134,6 @@ const queryImplodeTmpl = queryImplodeParams.length === 0 ? null : JSON.stringify }); return prepareResponse<<%~ type %>>(req<%~ schemaTmpl %>); -}<%~ route.namespace && !isFlat ? ',' : '' %> +} +<% } %> diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index 180e71a..a5b94a3 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -27,47 +27,39 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } -async function prepareResponse(promise: Promise, orSchema?: any): Promise> { - return await promise +async function prepareResponse(promise: Promise, orSchema?: any): Promise { + return promise .then(obj => { try { - // Parse and transform response data - const data = prepareResponseData(obj, orSchema, obj); - return { data, error: null } as Result; + return prepareResponseData(obj, orSchema, obj); } catch (parseError: unknown) { - // Handle our custom parsing errors - return the error instance directly if (parseError instanceof TonApiParsingError) { - return { - data: null, - error: parseError - } as Result; + throw parseError; } - // Handle other errors (should not happen, but defensive) const message = parseError instanceof Error ? `SDK parsing error: ${parseError.message}` : 'SDK parsing error: Unknown error'; - // Create a generic parsing error for unexpected cases - return { - data: null, - error: new TonApiParsingError('Cell', message, parseError, obj) - } as Result; + throw new TonApiParsingError('Unknown', message, parseError, obj); } }) - .catch(async response => { - // Network error (fetch failed) + .catch((response: any) => { + // Re-throw our custom errors without wrapping + if (response instanceof TonApiParsingError || + response instanceof TonApiNetworkError || + response instanceof TonApiHttpError || + response instanceof TonApiUnknownError) { + throw response; + } + if (response instanceof Error) { - return { - data: null, - error: new TonApiNetworkError( - response.message || 'Network error', - response - ) - } as Result; + throw new TonApiNetworkError( + response.message || 'Network error', + response + ); } - // HTTP error with response if (response && typeof response === 'object' && response.status !== undefined) { const status = response.status; const url = response.url || ''; @@ -89,17 +81,10 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis } } - return { - data: null, - error: new TonApiHttpError(status, message, url, code, response) - } as Result; + throw new TonApiHttpError(status, message, url, code, response); } - // Unknown error - return { - data: null, - error: new TonApiUnknownError('Unknown error occurred', response) - } as Result; + throw new TonApiUnknownError('Unknown error occurred', response); }); } diff --git a/tests/client/client.test.ts b/tests/client/client.test.ts index 890fb91..1c823a1 100644 --- a/tests/client/client.test.ts +++ b/tests/client/client.test.ts @@ -1,15 +1,10 @@ -import { initClient, status, getAccounts as getAccountsOp, getAccountPublicKey, getAccount } from '@ton-api/client'; -import { initTa, useTa, useTaWithApiKey } from './utils/client'; +import { TonApiClient, ApiConfig } from '@ton-api/client'; +import { ta, taWithApiKey } from './utils/client'; import { Address } from '@ton/core'; import { getAccounts } from './__mock__/services'; -import { vi, test, expect, afterEach, beforeEach, describe } from 'vitest'; +import { vi, test, expect, afterEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; -beforeEach(() => { - initTa(); - vi.restoreAllMocks(); -}); - afterEach(() => { vi.restoreAllMocks(); }); @@ -20,9 +15,8 @@ test('Client status test', async () => { indexing_latency: 8 }); - const { data, error } = await status(); - expect(error).toBeNull(); - expect(data).toBeDefined(); + const res = await ta.status(); + expect(res).toBeDefined(); }); test('Client apiKey test', async () => { @@ -31,10 +25,8 @@ test('Client apiKey test', async () => { indexing_latency: 8 }); - useTaWithApiKey(); - const { data, error } = await status(); - expect(error).toBeNull(); - expect(data).toBeDefined(); + const res = await taWithApiKey.status(); + expect(res).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -52,12 +44,8 @@ test('Client apiKey missing test', async () => { indexing_latency: 8 }); - initClient({ - baseUrl: 'https://tonapi.io' - }); - const { data, error } = await status(); - expect(error).toBeNull(); - expect(data).toBeDefined(); + const res = await ta.status(); + expect(res).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -75,12 +63,8 @@ test('Client fallback test', async () => { indexing_latency: 8 }); - initClient({ - baseUrl: 'https://tonapi.io' - }); - const { data, error } = await status(); - expect(error).toBeNull(); - expect(data).toBeDefined(); + const res = await ta.status(); + expect(res).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -98,9 +82,8 @@ test('Client x-tonapi-client header test', async () => { indexing_latency: 8 }); - const { data, error } = await status(); - expect(error).toBeNull(); - expect(data).toBeDefined(); + const res = await ta.status(); + expect(res).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -125,12 +108,14 @@ test('Client custom fetch is called', async () => { }) ); - initClient({ + const config: ApiConfig = { baseUrl: 'https://tonapi.io', fetch: customFetch - }); + }; - await status(); + const ta = new TonApiClient(config); + + await ta.status(); expect(customFetch).toHaveBeenCalled(); }); @@ -143,12 +128,11 @@ test('Client post method in fetch', async () => { 'UQAW2nxA69WYdMr90utDmpeZFwvG4XYcc9iibAP5sZnlojRO' ]; - const { data, error } = await getAccountsOp({ + const res = await ta.getAccounts({ accountIds: accountIds.map(id => Address.parse(id)) }); - expect(error).toBeNull(); - expect(data).toBeDefined(); + expect(res).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.anything(), @@ -164,332 +148,8 @@ test('Client response type for schema outside component (with snake_case)', asyn }); const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9YvxsnV'); - const { data, error } = await getAccountPublicKey(senderAddress); - - expect(error).toBeNull(); - expect(data).toBeDefined(); - expect(data?.publicKey).toBe('9544d2cccdd17e06e27f14fd531f803378d27f64710fd6aadc418c53d0660ec6'); -}); - -describe('Client initialization and configuration', () => { - beforeEach(() => { - vi.restoreAllMocks(); - }); - - test('initClient() should initialize the singleton client', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'test-key-123' - }); - - await status(); - - expect(fetchSpy).toHaveBeenCalledWith( - expect.stringContaining('https://tonapi.io'), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer test-key-123' - }) - }) - ); -}); - -test('initClient() should reinitialize the singleton client', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - // First initialization - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'first-key' - }); - - // Second initialization should replace the client - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'second-key' - }); - - await status(); - - expect(fetchSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer second-key' - }) - }) - ); -}); - -test('reinitializing client should update apiKey', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'initial-key' - }); - - // Reinitialize with new apiKey - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'updated-key' - }); - - await status(); - - expect(fetchSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer updated-key' - }) - }) - ); -}); - -test('reinitializing client should update baseUrl', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - initClient({ - baseUrl: 'https://tonapi.io' - }); - - // Reinitialize with new baseUrl - initClient({ - baseUrl: 'https://testnet.tonapi.io' - }); - - await status(); - - expect(fetchSpy).toHaveBeenCalledWith( - expect.stringContaining('https://testnet.tonapi.io'), - expect.anything() - ); -}); - -test('reinitializing client should update custom fetch', async () => { - const mockResponse = { - rest_online: true, - indexing_latency: 8 - }; - - const firstFetch = vi.fn().mockResolvedValue( - new Response(JSON.stringify(mockResponse), { - status: 200, - headers: { 'Content-Type': 'application/json' } - }) - ); - - const secondFetch = vi.fn().mockResolvedValue( - new Response(JSON.stringify(mockResponse), { - status: 200, - headers: { 'Content-Type': 'application/json' } - }) - ); - - initClient({ - baseUrl: 'https://tonapi.io', - fetch: firstFetch - }); - - // Reinitialize with secondFetch - initClient({ - baseUrl: 'https://tonapi.io', - fetch: secondFetch - }); - - await status(); - - expect(firstFetch).not.toHaveBeenCalled(); - expect(secondFetch).toHaveBeenCalled(); -}); - -test('operations should share the same singleton client', async () => { - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'shared-key' - }); - - // First operation - const statusSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - await status(); - - expect(statusSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer shared-key' - }) - }) - ); - - // Second operation should use the same client with same apiKey - const accountSpy = mockFetch({ balance: '1000000000' }); - - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - await getAccount(address); - - expect(accountSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer shared-key' - }) - }) - ); -}); - -test('lazy initialization: operations should work without explicit initClient()', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - // Don't call initClient(), just use the operation directly - // This should create a default client - const { data, error } = await status(); - - expect(error).toBeNull(); - expect(data).toBeDefined(); - expect(fetchSpy).toHaveBeenCalled(); -}); - -test('reinitializing without apiKey should remove Authorization header', async () => { - const fetchSpy = vi.fn().mockResolvedValue( - new Response(JSON.stringify({ rest_online: true, indexing_latency: 8 }), { - status: 200, - headers: { 'Content-Type': 'application/json' } - }) - ); - - vi.spyOn(global, 'fetch').mockImplementation(fetchSpy); - - // First, init with apiKey - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'will-be-removed' - }); - - await status(); - - let callArgs = fetchSpy.mock.calls[0]; - let headers = callArgs?.[1]?.headers as Record; - expect(headers?.Authorization).toBe('Bearer will-be-removed'); - - fetchSpy.mockClear(); + const res = await ta.getAccountPublicKey(senderAddress); - // Reinitialize without apiKey - initClient({ - baseUrl: 'https://tonapi.io' - }); - - await status(); - - callArgs = fetchSpy.mock.calls[0]; - headers = callArgs?.[1]?.headers as Record; - - // Check that Authorization header is not present after reinitialization - expect(headers).toBeDefined(); - expect(headers?.Authorization).toBeUndefined(); - expect(headers?.['x-tonapi-client']).toBeDefined(); // Should still have other headers -}); - -test('configuration changes should persist across multiple requests', async () => { - initClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'persistent-key' - }); - - // Make first request - const firstSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - await status(); - - expect(firstSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer persistent-key' - }) - }) - ); - - // Make second request - should still use the same configuration - const secondSpy = mockFetch({ rest_online: true, indexing_latency: 8 }); - - await status(); - - expect(secondSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - Authorization: 'Bearer persistent-key' - }) - }) - ); -}); - -test('initClient() with baseApiParams should set custom headers', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - initClient({ - baseUrl: 'https://tonapi.io', - baseApiParams: { - headers: { - 'Custom-Header': 'custom-value', - 'Another-Header': 'another-value' - } - } - }); - - await status(); - - expect(fetchSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.objectContaining({ - 'Custom-Header': 'custom-value', - 'Another-Header': 'another-value' - }) - }) - ); -}); - - test('initClient() should work with minimal configuration', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - initClient(); - const { data, error } = await status(); - - expect(error).toBeNull(); - expect(data).toBeDefined(); - expect(fetchSpy).toHaveBeenCalled(); - }); + expect(res).toBeDefined(); + expect(res.publicKey).toBe('9544d2cccdd17e06e27f14fd531f803378d27f64710fd6aadc418c53d0660ec6'); }); diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index 5ed0d7c..25566cf 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -1,21 +1,31 @@ +import { initTa, ta } from './utils/client'; import { status, getAccount, execGetMethodForBlockchainAccount, TonApiParsingError, TonApiHttpError, TonApiNetworkError, TonApiUnknownError } from '@ton-api/client'; import { Address } from '@ton/core'; -import { initTa } from './utils/client'; -import { vi, test, expect, beforeEach, describe } from 'vitest'; +import { vi, test, expect, beforeEach, describe, afterEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; beforeEach(() => { - initTa(); vi.restoreAllMocks(); + // Suppress console.error logs from parsing errors + vi.spyOn(console, 'error').mockImplementation(() => {}); }); -const createJsonResponse = (data: any, status = 200) => { +afterEach(() => { + vi.restoreAllMocks(); +}); + +const createJsonResponse = (data: any, statusCode = 200) => { return new Response(JSON.stringify(data), { - status, + status: statusCode, headers: { 'Content-Type': 'application/json' } }); }; +// Helper to catch thrown errors for clean assertion +async function expectThrowingError(fn: () => Promise) { + return await fn().catch(err => err); +} + // Type assertion helpers for safe error testing function assertIsHttpError(error: unknown): asserts error is TonApiHttpError { expect(error).toBeInstanceOf(TonApiHttpError); @@ -33,609 +43,514 @@ function assertIsUnknownError(error: unknown): asserts error is TonApiUnknownErr expect(error).toBeInstanceOf(TonApiUnknownError); } -test('should return a successful response with JSON data', async () => { - const mockData = { status: 'ok', uptime: 123456 }; - const fetchSpy = mockFetch(mockData); - - const { data, error } = await status(); - expect(error).toBeNull(); - expect(data).toEqual(mockData); - expect(fetchSpy).toHaveBeenCalledWith( - expect.stringContaining('/v2/status'), - expect.any(Object) - ); -}); +// ============================================================================ +// PRIMARY APPROACH: Instance-based methods with throw on error (ta.*) +// ============================================================================ + +describe('Instance API - Primary approach (throws errors)', () => { + test('should return a successful response with JSON data', async () => { + const mockData = { rest_online: true, indexing_latency: 8 }; + const fetchSpy = mockFetch(mockData); + + const result = await ta.status(); + expect(result).toBeDefined(); + // Response is converted to camelCase + expect(result?.restOnline).toBe(true); + expect(result?.indexingLatency).toBe(8); + expect(fetchSpy).toHaveBeenCalledWith( + expect.stringContaining('/v2/status'), + expect.any(Object) + ); + }); -test('should handle an error response with a JSON message', async () => { - const mockError = { error: 'Invalid request' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - assertIsHttpError(error); - expect(error.message).toBe('HTTP 400: Invalid request'); - expect(error.status).toBe(400); - expect(error.type).toBe('http_error'); -}); + // ======================================================================== + // TonApiHttpError + // ======================================================================== -test('should handle an error response with a string message', async () => { - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse('Simple error message', 500)); + describe('TonApiHttpError', () => { + test('should have all required properties', async () => { + const mockError = { error: 'Test error', code: 'TEST_CODE' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - assertIsHttpError(error); - expect(error.message).toBe('HTTP 500: Simple error message'); - expect(error.status).toBe(500); - expect(error.type).toBe('http_error'); -}); + const error = await expectThrowingError(() => ta.status()); + assertIsHttpError(error); -test('should include cause in the error object', async () => { - const mockError = { error: 'Invalid request' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); + // Verify all required properties + expect(error).toHaveProperty('message'); + expect(error).toHaveProperty('status'); + expect(error).toHaveProperty('type'); + expect(error).toHaveProperty('url'); + expect(error).toHaveProperty('code'); + expect(error).toHaveProperty('originalCause'); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - expect(error?.message).toBe('HTTP 400: Invalid request'); - expect(error).toBeDefined(); - expect(error?.type).toBe('http_error'); -}); + expect(typeof error.message).toBe('string'); + expect(typeof error.status).toBe('number'); + expect(error.type).toBe('http_error'); + expect(typeof error.url).toBe('string'); + expect(error.status).toBe(400); + }); -test('should handle an error response without JSON', async () => { - const mockError = new Error('Network failure'); - vi.spyOn(global, 'fetch').mockRejectedValueOnce(mockError); + test('should throw with JSON message', async () => { + const mockError = { error: 'Invalid request' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - expect(error?.message).toBe('Network error: Network failure'); - expect(error?.type).toBe('network_error'); -}); + const error = await expectThrowingError(() => ta.status()); + assertIsHttpError(error); + expect(error.message).toContain('Invalid request'); + expect(error.status).toBe(400); + expect(error.type).toBe('http_error'); + }); -test('should handle an error response with invalid JSON', async () => { - const response = new Response('Invalid JSON', { - status: 400, - headers: { 'Content-Type': 'application/json' } - }); - vi.spyOn(global, 'fetch').mockResolvedValueOnce(response); - - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - assertIsHttpError(error); - expect(error.message).toContain('Failed to parse error response'); - expect(error.status).toBe(400); - expect(error.type).toBe('http_error'); -}); + test('should throw with string message', async () => { + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse('Simple error message', 500)); -test('should handle an unknown error type (object)', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce({ message: 'Some unknown error' } as any); + const error = await expectThrowingError(() => ta.status()); + assertIsHttpError(error); + expect(error.message).toContain('Simple error message'); + expect(error.status).toBe(500); + expect(error.type).toBe('http_error'); + }); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - expect(error).toBeInstanceOf(TonApiUnknownError); - expect(error?.message).toBe('Unknown error: Unknown error occurred'); - expect(error?.type).toBe('unknown_error'); -}); + test('should throw with proper structure', async () => { + const mockError = { error: 'Invalid request' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); -test('should handle an unknown error type (string)', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce('Some unknown error' as any); + const error = await expectThrowingError(() => ta.status()); + expect(error).toBeDefined(); + expect(error.message).toBeDefined(); + assertIsHttpError(error); + }); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - expect(error).toBeInstanceOf(TonApiUnknownError); - expect(error?.message).toBe('Unknown error: Unknown error occurred'); - expect(error?.type).toBe('unknown_error'); -}); + test('should throw without error field', async () => { + const mockError = { message: 'Some error without error field' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); -test('should handle null as an error', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce(null as any); + const error = await expectThrowingError(() => ta.status()); + assertIsHttpError(error); + expect(error.message).toContain('Some error without error field'); + expect(error.status).toBe(400); + expect(error.type).toBe('http_error'); + }); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - expect(error).toBeInstanceOf(TonApiUnknownError); - expect(error?.message).toBe('Unknown error: Unknown error occurred'); - expect(error?.type).toBe('unknown_error'); -}); + test('should throw when response has invalid JSON', async () => { + const response = new Response('Invalid JSON', { + status: 400, + headers: { 'Content-Type': 'application/json' } + }); + vi.spyOn(global, 'fetch').mockResolvedValueOnce(response); -test('should handle undefined as an error', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce(undefined as any); + const error = await expectThrowingError(() => ta.status()); + assertIsHttpError(error); + expect(error.type).toBe('http_error'); + }); + }); - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - expect(error).toBeInstanceOf(TonApiUnknownError); - expect(error?.message).toBe('Unknown error: Unknown error occurred'); - expect(error?.type).toBe('unknown_error'); -}); + // ======================================================================== + // TonApiNetworkError + // ======================================================================== -test('should handle a JSON error response without an error field', async () => { - const mockError = { message: 'Some error without error field' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - - const { data, error } = await status(); - expect(data).toBeNull(); - expect(error).not.toBeNull(); - assertIsHttpError(error); - expect(error.message).toBe('HTTP 400: Some error without error field'); - expect(error.status).toBe(400); - expect(error.type).toBe('http_error'); -}); + describe('TonApiNetworkError', () => { + test('should have all required properties', async () => { + const mockError = new Error('Network failure'); + vi.spyOn(global, 'fetch').mockRejectedValueOnce(mockError); -describe('Parsing validation errors', () => { - describe('Invalid Address parsing', () => { - test('should return parsing_error for invalid address string', async () => { - // Mock API response with invalid address - mockFetch({ - address: 'invalid-address-string', - balance: '1000000000', - status: 'active' - }); + const error = await expectThrowingError(() => ta.status()); + assertIsNetworkError(error); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + // Verify all required properties + expect(error).toHaveProperty('message'); + expect(error).toHaveProperty('type'); + expect(error).toHaveProperty('originalCause'); - expect(data).toBeNull(); - expect(error).toBeDefined(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Address'); + expect(typeof error.message).toBe('string'); + expect(error.type).toBe('network_error'); + expect(error.originalCause).toBeInstanceOf(Error); }); - test('should return parsing_error for empty address string', async () => { - mockFetch({ - address: '', - balance: '1000000000', - status: 'active' - }); - - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + test('should throw when network fails', async () => { + const mockError = new Error('Network failure'); + vi.spyOn(global, 'fetch').mockRejectedValueOnce(mockError); - expect(data).toBeNull(); - expect(error).toBeDefined(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Address'); + const error = await expectThrowingError(() => ta.status()); + assertIsNetworkError(error); + expect(error.message).toContain('Network failure'); + expect(error.type).toBe('network_error'); }); + }); - test('should return parsing_error for malformed address format', async () => { - mockFetch({ - address: 'EQ_this_is_not_valid_base64', - balance: '1000000000', - status: 'active' - }); - - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + // ======================================================================== + // TonApiUnknownError + // ======================================================================== - expect(data).toBeNull(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Address'); - }); - }); + describe('TonApiUnknownError', () => { + test('should have all required properties', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce({ message: 'Some unknown error' }); - describe('Invalid Cell parsing', () => { - test('should return parsing_error for invalid cell hex string', async () => { - mockFetch({ - success: true, - exit_code: 0, - stack: [ - { - type: 'cell', - cell: 'invalid-hex-string' - } - ] - }); + const error = await expectThrowingError(() => ta.status()); + assertIsUnknownError(error); - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + // Verify all required properties + expect(error).toHaveProperty('message'); + expect(error).toHaveProperty('type'); + expect(error).toHaveProperty('originalCause'); - expect(data).toBeNull(); - expect(error).toBeDefined(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Cell'); + expect(typeof error.message).toBe('string'); + expect(error.type).toBe('unknown_error'); + expect(error.originalCause).toBeDefined(); }); - test('should return parsing_error for invalid cell BoC format', async () => { - mockFetch({ - success: true, - exit_code: 0, - stack: [ - { - type: 'cell', - cell: 'b5ee9c72410101010007' // Valid hex but invalid BoC format - } - ] - }); - - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + test('should throw on unknown error type (object)', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce({ message: 'Some unknown error' }); - expect(data).toBeNull(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Cell'); + const error = await expectThrowingError(() => ta.status()); + assertIsUnknownError(error); + expect(error.type).toBe('unknown_error'); }); - test('should return parsing_error for odd length hex string', async () => { - mockFetch({ - success: true, - exit_code: 0, - stack: [ - { - type: 'cell', - cell: 'abc' // 3 characters - odd length - } - ] - }); - - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + test('should throw on unknown error type (string)', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce('Some unknown error'); - expect(data).toBeNull(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Cell'); + const error = await expectThrowingError(() => ta.status()); + assertIsUnknownError(error); + expect(error.type).toBe('unknown_error'); }); - test('should return parsing_error for non-hex characters in cell', async () => { - mockFetch({ - success: true, - exit_code: 0, - stack: [ - { - type: 'cell', - cell: 'zzxxyyaabbcc' - } - ] - }); + test('should throw when error is null', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce(null); - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + const error = await expectThrowingError(() => ta.status()); + assertIsUnknownError(error); + expect(error.type).toBe('unknown_error'); + }); + + test('should throw when error is undefined', async () => { + vi.spyOn(global, 'fetch').mockRejectedValueOnce(undefined); - expect(data).toBeNull(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Cell'); + const error = await expectThrowingError(() => ta.status()); + assertIsUnknownError(error); + expect(error.type).toBe('unknown_error'); }); }); - describe('Invalid BigInt parsing', () => { - test('should return parsing_error for non-numeric BigInt string', async () => { - mockFetch({ - address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', - balance: 'not-a-number', - status: 'active' + // ======================================================================== + // TonApiParsingError + // ======================================================================== + + describe('TonApiParsingError', () => { + describe('Invalid Address parsing', () => { + test('should throw parsing_error for invalid address string', async () => { + mockFetch({ + address: 'invalid-address-string', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); + + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); + expect(error.type).toBe('parsing_error'); }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + test('should throw parsing_error for empty address string', async () => { + mockFetch({ + address: '', + balance: '1000000000', + status: 'active' + }); - expect(data).toBeNull(); - expect(error).toBeDefined(); - expect(error).toBeDefined(); - assertIsParsingError(error); - expect(error.parsingType).toBe('BigInt'); - }); + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); - test('should return parsing_error for invalid BigInt format', async () => { - mockFetch({ - address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', - balance: '123.456', // Decimal number, BigInt doesn't support decimals - status: 'active' + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + test('should throw parsing_error for malformed address format', async () => { + mockFetch({ + address: 'EQ_this_is_not_valid_base64', + balance: '1000000000', + status: 'active' + }); - expect(data).toBeNull(); - expect(error?.type).toBe('parsing_error'); - - assertIsParsingError(error); - if (error instanceof TonApiParsingError) { - expect(error.parsingType).toBe('BigInt'); - } + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); + + assertIsParsingError(error); + expect(error.parsingType).toBe('Address'); + }); }); - test('should handle empty string in BigInt field (converts to 0n)', async () => { - // Note: BigInt('') actually returns 0n, not an error - mockFetch({ - address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', - balance: '', - status: 'active' + describe('Invalid Cell parsing', () => { + test('should throw parsing_error for invalid cell hex string', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'invalid-hex-string' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + test('should throw parsing_error for invalid cell BoC format', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'b5ee9c72410101010007' // Valid hex but invalid BoC format + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); + }); - // Empty string converts to 0n without error - expect(error).toBeNull(); - expect(data).toBeDefined(); - expect(data?.balance).toBe(0n); - }); - }); + test('should throw parsing_error for odd length hex string', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'abc' // 3 characters - odd length + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); + }); - describe('Invalid TupleItem type', () => { - test('should return parsing_error for unknown tuple item type', async () => { - mockFetch({ - success: true, - exit_code: 0, - stack: [ - { - type: 'unknown_type', - value: 'some-value' - } - ] + test('should throw parsing_error for non-hex characters in cell', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'cell', + cell: 'zzxxyyaabbcc' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + + assertIsParsingError(error); + expect(error.parsingType).toBe('Cell'); }); + }); - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + describe('Invalid BigInt parsing', () => { + test('should throw parsing_error for non-numeric BigInt string', async () => { + mockFetch({ + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: 'not-a-number', + status: 'active' + }); - expect(data).toBeNull(); - expect(error).toBeDefined(); - expect(error?.type).toBe('parsing_error'); - - expect(error?.message).toContain('Unknown tuple item type'); - assertIsParsingError(error); - expect(error.parsingType).toBe('TupleItem'); - }); + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); - test('should return parsing_error for invalid type in nested tuple', async () => { - mockFetch({ - success: true, - exit_code: 0, - stack: [ - { - type: 'tuple', - tuple: [ - { - type: 'invalid_nested_type', - value: 'test' - } - ] - } - ] + assertIsParsingError(error); + expect(error.parsingType).toBe('BigInt'); }); - const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await execGetMethodForBlockchainAccount(address, 'get_data'); + test('should throw parsing_error for invalid BigInt format', async () => { + mockFetch({ + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '123.456', // Decimal number, BigInt doesn't support decimals + status: 'active' + }); - expect(data).toBeNull(); - expect(error?.type).toBe('parsing_error'); - - expect(error?.message).toContain('Unknown tuple item type'); - assertIsParsingError(error); - expect(error.parsingType).toBe('TupleItem'); - }); - }); + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); - describe('Error structure validation', () => { - test('parsing_error should have correct structure', async () => { - mockFetch({ - address: 'invalid', - balance: '1000000000', - status: 'active' + assertIsParsingError(error); + expect(error.parsingType).toBe('BigInt'); }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); - - expect(data).toBeNull(); - expect(error).toBeDefined(); - assertIsParsingError(error); + test('should handle empty string in BigInt field (converts to 0n)', async () => { + // Note: BigInt('') actually returns 0n, not an error + mockFetch({ + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '', + status: 'active' + }); - // Verify error structure - expect(error).toHaveProperty('message'); - expect(error).toHaveProperty('type'); - expect(error).toHaveProperty('originalCause'); + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const result = await ta.getAccount(validAddress); - expect(typeof error?.message).toBe('string'); - expect(error?.type).toBe('parsing_error'); + // Empty string converts to 0n without error + expect(result).toBeDefined(); + expect(result?.balance).toBe(0n); + }); }); - test('originalCause should contain the original error', async () => { - mockFetch({ - address: 'invalid-address', - balance: '1000000000', - status: 'active' + describe('Invalid TupleItem type', () => { + test('should throw parsing_error for unknown tuple item type', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'unknown_type', + value: 'some-value' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + + assertIsParsingError(error); + expect(error.parsingType).toBe('TupleItem'); }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); - - assertIsParsingError(error); - expect(error.originalCause).toBeDefined(); - expect(error.parsingType).toBe('Address'); + test('should throw parsing_error for invalid type in nested tuple', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'tuple', + tuple: [ + { + type: 'invalid_nested_type', + value: 'test' + } + ] + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + + assertIsParsingError(error); + expect(error.parsingType).toBe('TupleItem'); + }); }); - }); -}); - -describe('instanceof error checks', () => { - test('TonApiHttpError instanceof check', async () => { - const mockError = { error: 'Not found' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 404)); - - const { data, error } = await status(); - - expect(error).not.toBeNull(); - expect(error).toBeInstanceOf(TonApiHttpError); - - // TypeScript should narrow the type - if (error instanceof TonApiHttpError) { - expect(error.status).toBe(404); - expect(error.message).toBe('HTTP 404: Not found'); - expect(error.type).toBe('http_error'); - expect(error.url).toBeDefined(); - } - }); - test('TonApiNetworkError instanceof check', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Network connection failed')); + describe('Error structure validation', () => { + test('should have all required properties', async () => { + mockFetch({ + address: 'invalid', + balance: '1000000000', + status: 'active' + }); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); + + assertIsParsingError(error); + + // Verify all required properties + expect(error).toHaveProperty('message'); + expect(error).toHaveProperty('type'); + expect(error).toHaveProperty('parsingType'); + expect(error).toHaveProperty('originalCause'); + expect(error).toHaveProperty('response'); + + expect(typeof error.message).toBe('string'); + expect(error.type).toBe('parsing_error'); + expect(['Address', 'Cell', 'BigInt', 'TupleItem', 'Unknown']).toContain(error.parsingType); + }); - const { data, error } = await status(); + test('parsing_error should have correct structure', async () => { + mockFetch({ + address: 'invalid', + balance: '1000000000', + status: 'active' + }); - expect(error).not.toBeNull(); - assertIsNetworkError(error); - expect(error.message).toBe('Network error: Network connection failed'); - expect(error.type).toBe('network_error'); - expect(error.originalCause).toBeInstanceOf(Error); - }); + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); - test('TonApiParsingError instanceof check', async () => { - mockFetch({ - address: 'INVALID_ADDRESS_FORMAT', - balance: '1000000000', - status: 'active' - }); + assertIsParsingError(error); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const { data, error } = await getAccount(validAddress); + // Verify error structure + expect(error).toHaveProperty('message'); + expect(error).toHaveProperty('type'); + expect(error).toHaveProperty('parsingType'); + expect(error).toHaveProperty('originalCause'); - expect(error).not.toBeNull(); - assertIsParsingError(error); - expect(error.parsingType).toBe('Address'); - expect(error.type).toBe('parsing_error'); - expect(error.message).toBeDefined(); - expect(error.originalCause).toBeDefined(); - }); + expect(typeof error?.message).toBe('string'); + expect(error?.type).toBe('parsing_error'); + }); - test('TonApiUnknownError instanceof check', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce({ something: 'unexpected' } as any); + test('originalCause should contain the original error', async () => { + mockFetch({ + address: 'invalid-address', + balance: '1000000000', + status: 'active' + }); - const { data, error } = await status(); + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const error = await expectThrowingError(() => ta.getAccount(validAddress)); - expect(error).not.toBeNull(); - assertIsUnknownError(error); - expect(error.message).toBe('Unknown error: Unknown error occurred'); - expect(error.type).toBe('unknown_error'); - expect(error.originalCause).toBeDefined(); + assertIsParsingError(error); + expect(error.originalCause).toBeDefined(); + expect(error.parsingType).toBe('Address'); + }); + }); }); }); -describe('discriminated union error handling', () => { - test('should handle errors using switch/case on type', async () => { - const mockError = { error: 'Bad request', code: 'INVALID_PARAMS' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); - - const { data, error } = await status(); +// ============================================================================ +// ADVANCED APPROACH: Global methods with {data, error} return pattern +// ============================================================================ - expect(error).not.toBeNull(); - expect(error).toBeDefined(); - - if (!error) { - expect.fail('Expected error to be defined'); - return; - } - - switch (error.type) { - case 'http_error': - expect(error.status).toBe(400); - expect(error.code).toBe('INVALID_PARAMS'); - expect(error.url).toBeDefined(); - break; - case 'network_error': - expect(error.originalCause).toBeDefined(); - break; - case 'parsing_error': - expect(error.parsingType).toBeDefined(); - break; - case 'unknown_error': - expect(error.originalCause).toBeDefined(); - break; - default: - expect.fail(`Unexpected error type: ${(error as any).type}`); - } +describe('Advanced API - Global methods (returns {data, error})', () => { + beforeEach(() => { + initTa(); }); - test('should handle network error using switch/case', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Timeout')); + test('should return a successful response with JSON data', async () => { + const mockData = { rest_online: true, indexing_latency: 8 }; + const fetchSpy = mockFetch(mockData); const { data, error } = await status(); - - expect(error).not.toBeNull(); - expect(error).toBeDefined(); - - if (!error) { - expect.fail('Expected error to be defined'); - return; - } - - switch (error.type) { - case 'http_error': - expect.fail('Expected network error, got HTTP error'); - break; - case 'network_error': - expect(error.message).toBe('Network error: Timeout'); - break; - case 'parsing_error': - expect.fail('Expected network error, got parsing error'); - break; - case 'unknown_error': - expect.fail('Expected network error, got unknown error'); - break; - default: - expect.fail(`Unexpected error type: ${(error as any).type}`); - } - }); - - test('all error types have message property', async () => { - // Test HTTP error - const mockError = { error: 'Server error' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 500)); - - const { error: httpError } = await status(); - assertIsHttpError(httpError); - expect(httpError.message).toBe('HTTP 500: Server error'); - - // Test Network error - vi.spyOn(global, 'fetch').mockRejectedValueOnce(new Error('Connection failed')); - const { error: networkError } = await status(); - assertIsNetworkError(networkError); - expect(networkError.message).toBe('Network error: Connection failed'); - - // Test Parsing error - mockFetch({ address: 'INVALID', balance: '0', status: 'active' }); - const { error: parsingError } = await getAccount(Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y')); - assertIsParsingError(parsingError); - expect(parsingError.message).toBeDefined(); - - // Test Unknown error - vi.spyOn(global, 'fetch').mockRejectedValueOnce('something weird' as any); - const { error: unknownError } = await status(); - assertIsUnknownError(unknownError); - expect(unknownError.message).toBe('Unknown error: Unknown error occurred'); + expect(error).toBeNull(); + expect(data).toBeDefined(); + // Response is converted to camelCase + expect(data?.restOnline).toBe(true); + expect(data?.indexingLatency).toBe(8); + expect(fetchSpy).toHaveBeenCalledWith( + expect.stringContaining('/v2/status'), + expect.any(Object) + ); }); - test('should handle unknown error using switch/case', async () => { - vi.spyOn(global, 'fetch').mockRejectedValueOnce({ weird: 'object' } as any); + test('should handle an error response with a JSON message', async () => { + const mockError = { error: 'Invalid request' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 400)); const { data, error } = await status(); - + expect(data).toBeNull(); expect(error).not.toBeNull(); - expect(error).toBeDefined(); - - if (!error) { - expect.fail('Expected error to be defined'); - return; - } - - switch (error.type) { - case 'http_error': - expect.fail('Expected unknown error, got HTTP error'); - break; - case 'network_error': - expect.fail('Expected unknown error, got network error'); - break; - case 'parsing_error': - expect.fail('Expected unknown error, got parsing error'); - break; - case 'unknown_error': - expect(error.message).toBe('Unknown error: Unknown error occurred'); - expect(error.originalCause).toBeDefined(); - break; - default: - expect.fail(`Unexpected error type: ${(error as any).type}`); - } + assertIsHttpError(error); + expect(error.message).toContain('Invalid request'); + expect(error.status).toBe(400); + expect(error.type).toBe('http_error'); }); }); diff --git a/tests/client/memory-leak.test.ts b/tests/client/memory-leak.test.ts index 8368b8e..004f180 100644 --- a/tests/client/memory-leak.test.ts +++ b/tests/client/memory-leak.test.ts @@ -1,13 +1,9 @@ import { getBlockchainBlockTransactions } from './__mock__/services'; -import { status, getBlockchainBlockTransactions as getBlockchainBlockTransactionsOp } from '@ton-api/client'; -import { initTa } from './utils/client'; -import { describe, test, expect, beforeEach } from 'vitest'; +import { ta } from './utils/client'; +import { getBlockchainBlockTransactions as getBlockchainBlockTransactionsGlobal } from '@ton-api/client'; +import { describe, test, expect } from 'vitest'; import { JSONStringify } from './utils/jsonbig'; -beforeEach(() => { - initTa(); -}); - global.fetch = () => Promise.resolve( new Response(JSONStringify(getBlockchainBlockTransactions), { @@ -22,22 +18,64 @@ global.fetch = () => describe.skip('Memory leak test', () => { const iterations = 500000; - test('Memory leak test for raw fetch', async () => { + test('Memory leak test for instance API', async () => { if (!global.gc) { console.warn('Run with --expose-gc'); } else { global.gc(); } - + const initialMemory = process.memoryUsage().heapUsed; const memoryUsageSamples: number[] = []; - await status(); + await ta.status(); + + for (let i = 0; i < iterations; i++) { + await ta.getBlockchainBlockTransactions('(-1,8000000000000000,4234234)'); + + // Log memory usage every 50_000 iterations + if (i % 50_000 === 0) { + const currentMemory = process.memoryUsage().heapUsed; + console.log( + `Iteration ${i}, memory: ${(currentMemory / 1024 / 1024).toFixed(2)} MB` + ); + memoryUsageSamples.push(currentMemory); + } + } + + if (global.gc) global.gc(); + + await new Promise(resolve => setTimeout(resolve, 5000)); // Wait for GC to work + + const finalMemory = process.memoryUsage().heapUsed; + + console.log( + `Memory before: ${(initialMemory / 1024 / 1024).toFixed(2)} MB, ` + + `Memory after: ${(finalMemory / 1024 / 1024).toFixed(2)} MB` + ); + + console.log( + 'Memory samples:', + memoryUsageSamples.map(m => (m / 1024 / 1024).toFixed(2)) + ); + + expect((finalMemory - initialMemory) / 1024 / 1024).toBeLessThan(15); + }, 1_000_000); + + test('Memory leak test for global API', async () => { + if (!global.gc) { + console.warn('Run with --expose-gc'); + } else { + global.gc(); + } + + const initialMemory = process.memoryUsage().heapUsed; + const memoryUsageSamples: number[] = []; for (let i = 0; i < iterations; i++) { - await getBlockchainBlockTransactionsOp('(-1,8000000000000000,4234234)'); + await getBlockchainBlockTransactionsGlobal('(-1,8000000000000000,4234234)'); - // 🔍 Log memory usage every 50_000 iterations + // Log memory usage every 50_000 iterations if (i % 50_000 === 0) { const currentMemory = process.memoryUsage().heapUsed; console.log( diff --git a/tests/client/parse-address.test.ts b/tests/client/parse-address.test.ts index 22937ee..6443db3 100644 --- a/tests/client/parse-address.test.ts +++ b/tests/client/parse-address.test.ts @@ -1,14 +1,9 @@ import { Address } from '@ton/core'; -import { getBlockchainRawAccount as getBlockchainRawAccountOp, getAccounts as getAccountsOp } from '@ton-api/client'; -import { initTa } from './utils/client'; +import { ta } from './utils/client'; import { getAccounts, getBlockchainRawAccount } from './__mock__/address'; -import { vi, test, expect, afterEach, beforeEach } from 'vitest'; +import { vi, test, expect, afterEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; -beforeEach(() => { - initTa(); -}); - afterEach(() => { vi.restoreAllMocks(); }); @@ -19,9 +14,8 @@ test('Address simple in params & response', async () => { const addressString = 'UQC62nZpm36EFzADVfXDVd_4OpbFyc1D3w3ZvCPHLni8Dst4'; const addressObject = Address.parse(addressString); const addressRawString = addressObject.toRawString(); - const { data, error } = await getBlockchainRawAccountOp(addressObject); + const data = await ta.getBlockchainRawAccount(addressObject); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(Address.isAddress(data?.address)).toBe(true); expect(fetchSpy).toHaveBeenCalledWith( @@ -39,9 +33,8 @@ test('Address in request body test', async () => { ]; const accountIds = addressStrings.map(str => Address.parse(str)); - const { data, error } = await getAccountsOp({ accountIds }); + const data = await ta.getAccounts({ accountIds }); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(fetchSpy).toHaveBeenCalledWith( expect.any(String), diff --git a/tests/client/parse-bigint.test.ts b/tests/client/parse-bigint.test.ts index 7eef8f7..3aab9b2 100644 --- a/tests/client/parse-bigint.test.ts +++ b/tests/client/parse-bigint.test.ts @@ -1,13 +1,8 @@ import { Address } from '@ton/core'; -import { getAccounts as getAccountsOp, getJettonInfo as getJettonInfoOp } from '@ton-api/client'; -import { initTa } from './utils/client'; -import { getAccount, getJettonInfo } from './__mock__/bigint'; +import { ta } from './utils/client'; +import { getAccount, getJettonInfo as getJettonInfoMock } from './__mock__/bigint'; import { mockFetch } from './utils/mockFetch'; -import { vi, afterEach, beforeEach, test, expect } from 'vitest'; - -beforeEach(() => { - initTa(); -}); +import { vi, afterEach, test, expect } from 'vitest'; afterEach(() => { vi.restoreAllMocks(); @@ -21,9 +16,8 @@ test('BigInt parse data in number test', async () => { '0:7c9fc62291740a143086c807fe322accfd12737b3c2243676228176707c7ce40' ]; const accountIds = addressStrings.map(addr => Address.parse(addr)); - const { data, error } = await getAccountsOp({ accountIds }); + const data = await ta.getAccounts({ accountIds }); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(data?.accounts).toHaveLength(2); expect(data?.accounts[0]?.balance).toBe(471698230471698230471698230471698230n); @@ -33,12 +27,11 @@ test('BigInt parse data in number test', async () => { }); test('BigInt parse data in string test', async () => { - mockFetch(getJettonInfo); + mockFetch(getJettonInfoMock); const usdtJettonAddress = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); - const { data, error } = await getJettonInfoOp(usdtJettonAddress); + const data = await ta.getJettonInfo(usdtJettonAddress); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(typeof data?.totalSupply).toBe('bigint'); }); diff --git a/tests/client/parse-cell.test.ts b/tests/client/parse-cell.test.ts index 970e810..667a700 100644 --- a/tests/client/parse-cell.test.ts +++ b/tests/client/parse-cell.test.ts @@ -1,10 +1,6 @@ import { Address, Cell, TupleItem, TupleItemCell } from '@ton/core'; -import { - getBlockchainRawAccount, - sendBlockchainMessage, - execGetMethodForBlockchainAccount -} from '@ton-api/client'; -import { initTa } from './utils/client'; +import { ta } from './utils/client'; +import { sendBlockchainMessage, initClient } from '@ton-api/client'; import { execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountMock, getBlockchainRawAccount as getBlockchainRawAccountMock @@ -13,7 +9,7 @@ import { mockFetch } from './utils/mockFetch'; import { test, expect, afterEach, beforeEach, vi } from 'vitest'; beforeEach(() => { - initTa(); + initClient({ baseUrl: 'https://tonapi.io' }); }); afterEach(() => { @@ -25,9 +21,8 @@ test('Cell hex in response test', async () => { const addressString = '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'; const addressObject = Address.parse(addressString); - const { data, error } = await getBlockchainRawAccount(addressObject); + const data = await ta.getBlockchainRawAccount(addressObject); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(data?.code).toBeDefined(); expect(data?.code).toBeInstanceOf(Cell); @@ -69,12 +64,11 @@ test('Cell base64 in response test', async () => { const addressString = 'EQDW6q4sRqQwNCmW4qwUpeFSU1Xhd6l3xwJ6jjknBPzxKNtT'; const addressObject = Address.parse(addressString); - const { data, error } = await execGetMethodForBlockchainAccount( + const data = await ta.execGetMethodForBlockchainAccount( addressObject, 'royalty_params' ); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(data?.success).toBeDefined(); diff --git a/tests/client/parse-tuple.test.ts b/tests/client/parse-tuple.test.ts index 0386d74..17a241d 100644 --- a/tests/client/parse-tuple.test.ts +++ b/tests/client/parse-tuple.test.ts @@ -1,13 +1,8 @@ import { Address, Tuple, TupleItem } from '@ton/core'; -import { execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountOp } from '@ton-api/client'; -import { initTa } from './utils/client'; -import { execGetMethodForBlockchainAccount } from './__mock__/tuple'; +import { ta } from './utils/client'; +import { execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountMock } from './__mock__/tuple'; import { mockFetch } from './utils/mockFetch'; -import { test, expect, afterEach, beforeEach, vi } from 'vitest'; - -beforeEach(() => { - initTa(); -}); +import { test, expect, afterEach, vi } from 'vitest'; afterEach(() => { vi.restoreAllMocks(); @@ -18,16 +13,15 @@ function guardTuple(item: TupleItem): item is Tuple { } test('Tuple test', async () => { - mockFetch(execGetMethodForBlockchainAccount); + mockFetch(execGetMethodForBlockchainAccountMock); const addressString = 'Ef_X4pRKtgXOXYMOXNgXNRdlhkNKJ9bTKMfqvj6HDIiQG98F'; const addressObject = Address.parse(addressString); - const { data, error } = await execGetMethodForBlockchainAccountOp( + const data = await ta.execGetMethodForBlockchainAccount( addressObject, 'list_nominators' ); - expect(error).toBeNull(); expect(data).toBeDefined(); expect(data?.success).toBeDefined(); diff --git a/tests/client/services.test.ts b/tests/client/services.test.ts index 84d07c0..5f22733 100644 --- a/tests/client/services.test.ts +++ b/tests/client/services.test.ts @@ -1,13 +1,8 @@ import { Address } from '@ton/core'; -import { getChartRates, getRates as getRatesOp } from '@ton-api/client'; -import { initTa } from './utils/client'; +import { ta } from './utils/client'; import { getChartRates as getChartRatesMock, getRates as getRatesMock } from './__mock__/services'; import { mockFetch } from './utils/mockFetch'; -import { test, expect, afterEach, beforeEach, vi } from 'vitest'; - -beforeEach(() => { - initTa(); -}); +import { test, expect, afterEach, vi } from 'vitest'; afterEach(() => { vi.restoreAllMocks(); @@ -18,18 +13,17 @@ test('getChartRates, should correct parse array in pair', async () => { const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; const addressObject = Address.parse(addressString); - const { data, error } = await getChartRates({ + const data = await ta.getChartRates({ token: addressObject, currency: 'rub' }); - expect(error).toBeNull(); expect(data).toBeDefined(); - expect(data?.points).toBeDefined(); - expect(Array.isArray(data?.points)).toBe(true); - expect(data?.points?.length).toBeGreaterThan(0); + expect(data.points).toBeDefined(); + expect(Array.isArray(data.points)).toBe(true); + expect(data.points.length).toBeGreaterThan(0); - data?.points?.forEach(point => { + data.points.forEach(point => { expect(Array.isArray(point)).toBe(true); expect(point.length).toBe(2); @@ -45,28 +39,21 @@ test('getChartRates, should correct parse array in pair', async () => { test('getRates, additionalProperties should be not convert to camelCase', async () => { mockFetch(getRatesMock); - const { data, error } = await getRatesOp({ + const data = await ta.getRates({ tokens: ['TON,TOKEN_WITH_UNDERSCORE'], currencies: ['USD', 'EUR'] }); - expect(error).toBeNull(); expect(data).toBeDefined(); - expect(data?.rates).toBeDefined(); - expect(data?.rates['TON']).toBeDefined(); - expect(data?.rates['TOKEN_WITH_UNDERSCORE']).toBeDefined(); + expect(data.rates).toBeDefined(); + expect(data.rates['TON']).toBeDefined(); + expect(data.rates['TOKEN_WITH_UNDERSCORE']).toBeDefined(); }); test('getRates, explode in params should be matter', async () => { const fetchSpy = mockFetch(getRatesMock); - // const fetchSpy = vi.spyOn(global, 'fetch').mockResolvedValueOnce( - // new Response(JSON.stringify(getRates), { - // status: 200, - // headers: { 'Content-Type': 'application/json' } - // }) - // ); - - await getRatesOp({ + + await ta.getRates({ tokens: ['TON', 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'], currencies: ['USD', 'EUR'] }); @@ -85,7 +72,7 @@ test('getChartRates, should serialize Address object to string', async () => { const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; const addressObject = Address.parse(addressString); - await getChartRates({ + await ta.getChartRates({ token: addressObject, currency: 'usd' }); @@ -104,7 +91,7 @@ test('getChartRates, should accept string token directly', async () => { const addressString = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; - await getChartRates({ + await ta.getChartRates({ token: addressString, currency: 'usd' }); diff --git a/tests/client/utils/client.ts b/tests/client/utils/client.ts index d40aa9d..635810f 100644 --- a/tests/client/utils/client.ts +++ b/tests/client/utils/client.ts @@ -1,7 +1,16 @@ -import { initClient } from '@ton-api/client'; +import { initClient, TonApiClient } from '@ton-api/client'; const baseUrl = 'https://tonapi.io'; +export const taWithApiKey = new TonApiClient({ + baseUrl, + apiKey: 'TEST_API_KEY' +}); + +export const ta = new TonApiClient({ + baseUrl +}); + // Initialize default client (without API key) export function initTa() { initClient({ baseUrl }); @@ -14,19 +23,3 @@ export function initTaWithApiKey() { apiKey: 'TEST_API_KEY' }); } - -// Switch to client without API key -export function useTa() { - initClient({ baseUrl }); -} - -// Switch to client with API key -export function useTaWithApiKey() { - initClient({ - baseUrl, - apiKey: 'TEST_API_KEY' - }); -} - -// Initialize default client on module load -initTa(); From abecfca1d47dffed4461f9a762855285b073ffef Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Thu, 13 Nov 2025 13:11:20 +0400 Subject: [PATCH 10/27] chore: bump version to 0.5.0-alpha.1 --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 160672e..c9e8c47 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.0", + "version": "0.5.0-alpha.1", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 72547b9..23292c4 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.0", + "version": "0.5.0-alpha.1", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 728adaa..42a98a7 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3678,7 +3678,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.0` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.1` }; const preparedApiConfig = { From 0a0a6b5d61562fdde5a19eb4d31a3d84b8e34bbc Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Thu, 13 Nov 2025 19:08:26 +0400 Subject: [PATCH 11/27] refactor: update examples to use TonApiClient instance - Replaced `initClient` with direct instantiation of `TonApiClient` in multiple example files for improved clarity and consistency. - Updated method calls to utilize the new client instance, enhancing error handling and response management. - Refactored error handling in examples to align with the new client structure, ensuring consistent error reporting. - Adjusted tests to validate the new client usage and error handling mechanisms, ensuring comprehensive coverage. --- examples/emulate.ts | 48 +- examples/gasless.ts | 80 +- examples/send-jetton.ts | 18 +- examples/send-ton.ts | 10 +- examples/track-transaction.ts | 27 +- packages/client/src/client.ts | 3321 +++++++++++++---- .../client/src/templates/procedure-call.ejs | 110 +- packages/client/src/templates/utils.ejs | 11 + packages/ton-adapter/src/tonapi-adapter.ts | 193 +- tests/adapters/migratebeta.test.ts | 10 +- tests/adapters/readme.test.ts | 12 +- tests/adapters/utils/clients.ts | 8 +- tests/adapters/utils/contract.ts | 29 +- tests/client/errors.test.ts | 186 +- tests/client/memory-leak.test.ts | 10 +- tests/client/parse-cell.test.ts | 4 +- 16 files changed, 3064 insertions(+), 1013 deletions(-) diff --git a/examples/emulate.ts b/examples/emulate.ts index 357c50c..93528b6 100644 --- a/examples/emulate.ts +++ b/examples/emulate.ts @@ -9,33 +9,40 @@ import { storeMessage } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto'; -import { initClient, getAccountSeqno, getAccountPublicKey, emulateMessageToTrace } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; +// Create TonApiClient instance // if you need to send lots of requests in parallel, make sure you use a tonapi token. -initClient({ +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io', - apiKey: 'YOUR_API_KEY' + // apiKey: 'YOUR_API_KEY' }); // Sender's wallet address const senderAddress = Address.parse('UQAQxxpzxmEVU0Lu8U0zNTxBzXIWPvo263TIN1OQM9YvxsnV'); const recipientAddress = Address.parse('UQDNzlh0XSZdb5_Qrlx5QjyZHVAO74v5oMeVVrtF_5Vt1rIt'); -// Get wallet's seqno and public key -const { data: seqnoData, error: seqnoError } = await getAccountSeqno(senderAddress); -if (seqnoError) { - console.error('Error getting seqno:', seqnoError.message); - process.exit(1); -} +const seqno = await tonApiClient + .getAccountSeqno(senderAddress) + .then(seqnoData => seqnoData.seqno) + .catch((error: unknown) => { + console.error( + 'Error getting account seqno:', + error instanceof Error ? error.message : String(error) + ); + process.exit(1); + }); -const { data: publicKeyData, error: publicKeyError } = await getAccountPublicKey(senderAddress); -if (publicKeyError) { - console.error('Error getting public key:', publicKeyError.message); - process.exit(1); -} - -const seqno = seqnoData.seqno; -const publicKeyHex = publicKeyData.publicKey; +const publicKeyHex = await tonApiClient + .getAccountPublicKey(senderAddress) + .then(publicKeyData => publicKeyData.publicKey) + .catch((error: unknown) => { + console.error( + 'Error getting account public key:', + error instanceof Error ? error.message : String(error) + ); + process.exit(1); + }); // Emulate transaction from wallet_v4 address const wallet = WalletContractV4.create({ @@ -85,14 +92,9 @@ const bocExternalMessage = beginCell() .endCell(); // Emulate transaction -const { data: emulateTrace, error: emulateError } = await emulateMessageToTrace( +const emulateTrace = await tonApiClient.emulateMessageToTrace( { boc: bocExternalMessage }, { ignore_signature_check: true } // Ignore signature for execute message from other account ); -if (emulateError) { - console.error('Error emulating message:', emulateError.message); - process.exit(1); -} - console.log(emulateTrace); diff --git a/examples/gasless.ts b/examples/gasless.ts index c789bc4..b74fc9b 100644 --- a/examples/gasless.ts +++ b/examples/gasless.ts @@ -11,16 +11,17 @@ import { storeMessageRelaxed } from '@ton/ton'; -import { initClient, execGetMethodForBlockchainAccount, gaslessConfig, gaslessEstimate, gaslessSend, TonApiHttpError } from '@ton-api/client'; +import { TonApiClient, TonApiHttpError } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; +// Create TonApiClient instance // if you need to send lots of requests in parallel, make sure you use a tonapi token. -initClient({ +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io', - apiKey: 'YOUR_API_KEY' + // apiKey: 'YOUR_API_KEY' }); -const provider = new ContractAdapter(); +const provider = new ContractAdapter(tonApiClient); const OP_CODES = { TK_RELAYER_FEE: 0x878da6e3, @@ -47,16 +48,16 @@ const contract = provider.open(wallet); console.log('Wallet address:', wallet.address.toString()); -const { data: jettonWalletAddressResult, error: getWalletError } = - await execGetMethodForBlockchainAccount(usdtMaster, 'get_wallet_address', { +const jettonWalletAddressResult = await tonApiClient + .execGetMethodForBlockchainAccount(usdtMaster, 'get_wallet_address', { args: [wallet.address.toRawString()] + }) + .catch((getWalletError: unknown) => { + console.error('Error getting jetton wallet:', + getWalletError instanceof Error ? getWalletError.message : String(getWalletError)); + process.exit(1); }); -if (getWalletError) { - console.error('Error getting jetton wallet:', getWalletError.message); - process.exit(1); -} - const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address); // we use USDt in this example, @@ -92,16 +93,17 @@ const messageToEstimate = beginCell() // we send a single message containing a transfer from our wallet to a desired destination. // as a result of estimation, TonAPI returns a list of messages that we need to sign. // the first message is a fee transfer to the relay address, the second message is our original transfer. -const { data: params, error: estimateError } = await gaslessEstimate(usdtMaster, { - walletAddress: wallet.address, - walletPublicKey: keyPair.publicKey.toString('hex'), - messages: [{ boc: messageToEstimate }] -}); - -if (estimateError) { - console.error('Error estimating gasless transfer:', estimateError.message); - process.exit(1); -} +const params = await tonApiClient + .gaslessEstimate(usdtMaster, { + walletAddress: wallet.address, + walletPublicKey: keyPair.publicKey.toString('hex'), + messages: [{ boc: messageToEstimate }] + }) + .catch((estimateError: unknown) => { + console.error('Error estimating gasless transfer:', + estimateError instanceof Error ? estimateError.message : String(estimateError)); + process.exit(1); + }); console.log('Estimated transfer:', params); @@ -136,31 +138,33 @@ const extMessage = beginCell() .endCell(); // Send a gasless transfer -const { data: sendResult, error: sendError } = await gaslessSend({ - walletPublicKey: keyPair.publicKey.toString('hex'), - boc: extMessage -}); +const sendResult = await tonApiClient + .gaslessSend({ + walletPublicKey: keyPair.publicKey.toString('hex'), + boc: extMessage + }) + .catch((sendError: unknown) => { + if (sendError instanceof TonApiHttpError) { + console.error('Error sending gasless transfer:', sendError.message, 'Status:', sendError.status); + } else { + console.error('Error sending gasless transfer:', sendError instanceof Error ? sendError.message : String(sendError)); + } + return null; + }); -if (sendError) { - if (sendError instanceof TonApiHttpError) { - console.error('Error sending gasless transfer:', sendError.message, 'Status:', sendError.status); - } else { - console.error('Error sending gasless transfer:', sendError.message); - } -} else { +if (sendResult) { console.log('A gasless transfer sent!'); } async function printConfigAndReturnRelayAddress(): Promise
{ - const { data: cfg, error } = await gaslessConfig(); - - if (error) { - console.error('Error getting gasless config:', error.message); + const cfg = await tonApiClient.gaslessConfig().catch((error: unknown) => { + console.error('Error getting gasless config:', + error instanceof Error ? error.message : String(error)); process.exit(1); - } + }); console.log('Available jettons for gasless transfer'); - console.log(cfg.gasJettons.map(gasJetton => gasJetton.masterId)); + console.log(cfg.gasJettons.map((gasJetton: any) => gasJetton.masterId)); console.log(`Relay address to send fees to: ${cfg.relayAddress}`); return cfg.relayAddress; diff --git a/examples/send-jetton.ts b/examples/send-jetton.ts index c7527a3..8265fb6 100644 --- a/examples/send-jetton.ts +++ b/examples/send-jetton.ts @@ -1,17 +1,17 @@ import { WalletContractV5R1, Address, beginCell, internal, toNano, SendMode } from '@ton/ton'; import { mnemonicToPrivateKey } from '@ton/crypto'; -import { initClient, execGetMethodForBlockchainAccount } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; -// Initialize TonApi client -initClient({ +// Create TonApiClient instance +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io', - apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access + // apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access }); // Create an adapter for interacting with contracts -const adapter = new ContractAdapter(); +const adapter = new ContractAdapter(tonApiClient); // Base gas fee required for the jetton transfer const BASE_JETTON_SEND_AMOUNT = toNano(0.05); @@ -32,16 +32,14 @@ const wallet = WalletContractV5R1.create({ workchain: 0, publicKey: keyPair.publ const contract = adapter.open(wallet); // Open the wallet contract using the adapter // Get the sender's jetton wallet address from the jetton master contract -const { data: jettonWalletAddressResult, error } = await execGetMethodForBlockchainAccount( +const jettonWalletAddressResult = await tonApiClient.execGetMethodForBlockchainAccount( jettonMaster, 'get_wallet_address', { args: [wallet.address.toRawString()] } -); - -if (error) { +).catch((error) => { console.error('Error getting jetton wallet address:', error.message); process.exit(1); -} +}); const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address); // Extract the jetton wallet address diff --git a/examples/send-ton.ts b/examples/send-ton.ts index 06d8e9f..295f749 100644 --- a/examples/send-ton.ts +++ b/examples/send-ton.ts @@ -1,16 +1,16 @@ import { WalletContractV5R1, internal, SendMode } from '@ton/ton'; import { mnemonicToPrivateKey } from '@ton/crypto'; -import { initClient } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; -// Initialize TonApi client -initClient({ +// Create TonApiClient instance +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io', - apiKey: 'YOUR_API_KEY', // Optional, improves limits and access + // apiKey: 'YOUR_API_KEY', // Optional, improves limits and access }); // Create an adapter for interacting with contracts -const adapter = new ContractAdapter(); +const adapter = new ContractAdapter(tonApiClient); // Convert mnemonic phrase to a private key const mnemonics = 'word1 word2 ...'.split(' '); // Replace with your mnemonic phrase diff --git a/examples/track-transaction.ts b/examples/track-transaction.ts index 1d79f74..e5b8ea8 100644 --- a/examples/track-transaction.ts +++ b/examples/track-transaction.ts @@ -1,7 +1,7 @@ import { WalletContractV5R1 } from '@ton/ton'; import { Address, beginCell, internal, external, SendMode, Message } from '@ton/core'; import { mnemonicToPrivateKey } from '@ton/crypto'; -import { initClient, getBlockchainTransactionByMessageHash } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; import { Cell, loadMessage } from '@ton/core'; @@ -35,12 +35,12 @@ function normalizeHash(message: Message, normalizeExternal: boolean): Buffer { // 1) Using normalizeHash with a manually-created external message // ---------------------------------------------------------- -// Step 1: Initialize the TonAPI client -initClient({ +// Step 1: Create TonApiClient instance +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io' // apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access }); -const adapter = new ContractAdapter(); +const adapter = new ContractAdapter(tonApiClient); // Step 2: Define the wallet and recipient addresses const destination = Address.parse('EQCKWpx7cNMpvmcN5ObM5lLUZHZRFKqYA4xmw9jOry0ZsF9M'); @@ -83,9 +83,13 @@ console.log('Manual Message Hash:', manualExtMessageHash.toString('hex')); await delay(10000); // Step 8: Retrieve the resulting transaction using the normalized external hash -const manualTransaction = await getBlockchainTransactionByMessageHash( - manualExtMessageHash.toString('hex') -); +// You can retry this step if the transaction is not found, until +const manualTransaction = await tonApiClient + .getBlockchainTransactionByMessageHash(manualExtMessageHash.toString('hex')) + .catch((error) => { + console.error('Error fetching transaction:', error.message); + return null; + }); console.log('Manual Transaction Details:', manualTransaction); // ---------------------------------------------------------- @@ -106,7 +110,10 @@ const bocExtMessageHash = normalizeHash(bocMessage, true); console.log('BOC Message Hash:', bocExtMessageHash.toString('hex')); // Step 3: Retrieve the transaction using that hash -const bocTransaction = await getBlockchainTransactionByMessageHash( - bocExtMessageHash.toString('hex') -); +const bocTransaction = await tonApiClient + .getBlockchainTransactionByMessageHash(bocExtMessageHash.toString('hex')) + .catch((error) => { + console.error('Error fetching transaction:', error.message); + return null; + }); console.log('BOC Transaction Details:', bocTransaction); diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 42a98a7..6410c56 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -6543,6 +6543,18 @@ type ComponentRef = keyof typeof components; export type Result = { data: T; error: null } | { data: null; error: TonApiError }; +/** + * Conditional return type for Advanced API methods with throwOnError support + * @template T - The data type returned on success + * @template ThrowOnError - Boolean flag determining if errors should be thrown + * + * When ThrowOnError is true: returns Promise (throws on error) + * When ThrowOnError is false: returns Promise> (returns {data, error}) + */ +export type MethodResult = ThrowOnError extends true + ? Promise + : Promise>; + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, match => match[1]?.toUpperCase() ?? ''); } @@ -10371,12 +10383,27 @@ function getDefaultClient(): TonApiClient { * @name GetOpenapiJson * @request GET:/v2/openapi.json */ -export const getOpenapiJson = async (params: RequestParams = {}) => { +export const getOpenapiJson = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getOpenapiJson(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getOpenapiJson(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10387,12 +10414,27 @@ export const getOpenapiJson = async (params: RequestParams = {}) => { * @name GetOpenapiYml * @request GET:/v2/openapi.yml */ -export const getOpenapiYml = async (params: RequestParams = {}) => { +export const getOpenapiYml = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getOpenapiYml(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getOpenapiYml(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10403,12 +10445,27 @@ export const getOpenapiYml = async (params: RequestParams = {}) => { * @name Status * @request GET:/v2/status */ -export const status = async (params: RequestParams = {}) => { +export const status = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().status(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.status(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10419,12 +10476,30 @@ export const status = async (params: RequestParams = {}) => { * @name AddressParse * @request GET:/v2/address/{account_id}/parse */ -export const addressParse = async (accountId_Address: Address, params: RequestParams = {}) => { +export const addressParse = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().addressParse(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.addressParse(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10435,20 +10510,33 @@ export const addressParse = async (accountId_Address: Address, params: RequestPa * @name GetReducedBlockchainBlocks * @request GET:/v2/blockchain/reduced/blocks */ -export const getReducedBlockchainBlocks = async ( +export const getReducedBlockchainBlocks = async (options: { + client?: TonApiClient; query: { /** @format int64 */ from: number; /** @format int64 */ to: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getReducedBlockchainBlocks(query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getReducedBlockchainBlocks(options.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10459,12 +10547,30 @@ export const getReducedBlockchainBlocks = async ( * @name GetBlockchainBlock * @request GET:/v2/blockchain/blocks/{block_id} */ -export const getBlockchainBlock = async (blockId: string, params: RequestParams = {}) => { +export const getBlockchainBlock = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainBlock(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainBlock(options.path.blockId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10475,12 +10581,33 @@ export const getBlockchainBlock = async (blockId: string, params: RequestParams * @name DownloadBlockchainBlockBoc * @request GET:/v2/blockchain/blocks/{block_id}/boc */ -export const downloadBlockchainBlockBoc = async (blockId: string, params: RequestParams = {}) => { +export const downloadBlockchainBlockBoc = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().downloadBlockchainBlockBoc(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.downloadBlockchainBlockBoc( + options.path.blockId, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10491,18 +10618,35 @@ export const downloadBlockchainBlockBoc = async (blockId: string, params: Reques * @name GetBlockchainMasterchainShards * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards */ -export const getBlockchainMasterchainShards = async ( - masterchainSeqno: number, - params: RequestParams = {} -) => { +export const getBlockchainMasterchainShards = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + masterchainSeqno: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainMasterchainShards( - masterchainSeqno, - params + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainMasterchainShards( + options.path.masterchainSeqno, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10513,18 +10657,35 @@ export const getBlockchainMasterchainShards = async ( * @name GetBlockchainMasterchainBlocks * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks */ -export const getBlockchainMasterchainBlocks = async ( - masterchainSeqno: number, - params: RequestParams = {} -) => { +export const getBlockchainMasterchainBlocks = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + masterchainSeqno: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainMasterchainBlocks( - masterchainSeqno, - params + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainMasterchainBlocks( + options.path.masterchainSeqno, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10535,18 +10696,35 @@ export const getBlockchainMasterchainBlocks = async ( * @name GetBlockchainMasterchainTransactions * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions */ -export const getBlockchainMasterchainTransactions = async ( - masterchainSeqno: number, - params: RequestParams = {} -) => { +export const getBlockchainMasterchainTransactions = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + masterchainSeqno: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainMasterchainTransactions( - masterchainSeqno, - params + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainMasterchainTransactions( + options.path.masterchainSeqno, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10557,18 +10735,33 @@ export const getBlockchainMasterchainTransactions = async ( * @name GetBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config */ -export const getBlockchainConfigFromBlock = async ( - masterchainSeqno: number, - params: RequestParams = {} -) => { +export const getBlockchainConfigFromBlock = async (options: { + client?: TonApiClient; + path: { + masterchainSeqno: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainConfigFromBlock( - masterchainSeqno, - params + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainConfigFromBlock( + options.path.masterchainSeqno, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10579,18 +10772,35 @@ export const getBlockchainConfigFromBlock = async ( * @name GetRawBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw */ -export const getRawBlockchainConfigFromBlock = async ( - masterchainSeqno: number, - params: RequestParams = {} -) => { +export const getRawBlockchainConfigFromBlock = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + masterchainSeqno: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawBlockchainConfigFromBlock( - masterchainSeqno, - params + const client = options.client || getDefaultClient(); + const result = await client.getRawBlockchainConfigFromBlock( + options.path.masterchainSeqno, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10601,15 +10811,35 @@ export const getRawBlockchainConfigFromBlock = async ( * @name GetBlockchainBlockTransactions * @request GET:/v2/blockchain/blocks/{block_id}/transactions */ -export const getBlockchainBlockTransactions = async ( - blockId: string, - params: RequestParams = {} -) => { +export const getBlockchainBlockTransactions = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainBlockTransactions(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainBlockTransactions( + options.path.blockId, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10620,15 +10850,33 @@ export const getBlockchainBlockTransactions = async ( * @name GetBlockchainTransaction * @request GET:/v2/blockchain/transactions/{transaction_id} */ -export const getBlockchainTransaction = async ( - transactionId: string, - params: RequestParams = {} -) => { +export const getBlockchainTransaction = async (options: { + client?: TonApiClient; + path: { + transactionId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainTransaction(transactionId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainTransaction( + options.path.transactionId, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10639,18 +10887,35 @@ export const getBlockchainTransaction = async ( * @name GetBlockchainTransactionByMessageHash * @request GET:/v2/blockchain/messages/{msg_id}/transaction */ -export const getBlockchainTransactionByMessageHash = async ( - msgId: string, - params: RequestParams = {} -) => { +export const getBlockchainTransactionByMessageHash = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + msgId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainTransactionByMessageHash( - msgId, - params + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainTransactionByMessageHash( + options.path.msgId, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10661,12 +10926,27 @@ export const getBlockchainTransactionByMessageHash = async ( * @name GetBlockchainValidators * @request GET:/v2/blockchain/validators */ -export const getBlockchainValidators = async (params: RequestParams = {}) => { +export const getBlockchainValidators = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainValidators(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getBlockchainValidators(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10677,12 +10957,27 @@ export const getBlockchainValidators = async (params: RequestParams = {}) => { * @name GetBlockchainMasterchainHead * @request GET:/v2/blockchain/masterchain-head */ -export const getBlockchainMasterchainHead = async (params: RequestParams = {}) => { +export const getBlockchainMasterchainHead = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainMasterchainHead(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getBlockchainMasterchainHead(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10693,15 +10988,30 @@ export const getBlockchainMasterchainHead = async (params: RequestParams = {}) = * @name GetBlockchainRawAccount * @request GET:/v2/blockchain/accounts/{account_id} */ -export const getBlockchainRawAccount = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getBlockchainRawAccount = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainRawAccount(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainRawAccount(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10712,8 +11022,13 @@ export const getBlockchainRawAccount = async ( * @name GetBlockchainAccountTransactions * @request GET:/v2/blockchain/accounts/{account_id}/transactions */ -export const getBlockchainAccountTransactions = async ( - accountId_Address: Address, +export const getBlockchainAccountTransactions = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * omit this parameter to get last transactions @@ -10740,18 +11055,30 @@ export const getBlockchainAccountTransactions = async ( * @default "desc" */ sort_order?: 'desc' | 'asc'; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainAccountTransactions( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainAccountTransactions( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10762,9 +11089,14 @@ export const getBlockchainAccountTransactions = async ( * @name ExecGetMethodForBlockchainAccount * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ -export const execGetMethodForBlockchainAccount = async ( - accountId_Address: Address, - methodName: string, +export const execGetMethodForBlockchainAccount = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + accountId: Address; + methodName: string; + }; query?: { /** * Array of method arguments in string format. Supported value formats: @@ -10778,19 +11110,31 @@ export const execGetMethodForBlockchainAccount = async ( * @example ["0:9a33970f617bcd71acf2cd28357c067aa31859c02820d8f01d74c88063a8f4d8"] */ args?: string[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().execGetMethodForBlockchainAccount( - accountId_Address, - methodName, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.execGetMethodForBlockchainAccount( + options.path.accountId, + options.path.methodName, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10801,24 +11145,41 @@ export const execGetMethodForBlockchainAccount = async ( * @name ExecGetMethodWithBodyForBlockchainAccount * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ -export const execGetMethodWithBodyForBlockchainAccount = async ( - accountId_Address: Address, - methodName: string, - data: { +export const execGetMethodWithBodyForBlockchainAccount = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + accountId: Address; + methodName: string; + }; + body: { args: ExecGetMethodArg[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().execGetMethodWithBodyForBlockchainAccount( - accountId_Address, - methodName, - data, - params + const client = options.client || getDefaultClient(); + const result = await client.execGetMethodWithBodyForBlockchainAccount( + options.path.accountId, + options.path.methodName, + options.body, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10829,21 +11190,34 @@ export const execGetMethodWithBodyForBlockchainAccount = async ( * @name SendBlockchainMessage * @request POST:/v2/blockchain/message */ -export const sendBlockchainMessage = async ( - data: { +export const sendBlockchainMessage = async (options: { + client?: TonApiClient; + body: { /** @format cell */ boc?: Cell; /** @maxItems 5 */ batch?: Cell[]; meta?: Record; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().sendBlockchainMessage(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.sendBlockchainMessage(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10854,12 +11228,27 @@ export const sendBlockchainMessage = async ( * @name GetBlockchainConfig * @request GET:/v2/blockchain/config */ -export const getBlockchainConfig = async (params: RequestParams = {}) => { +export const getBlockchainConfig = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getBlockchainConfig(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getBlockchainConfig(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10870,12 +11259,27 @@ export const getBlockchainConfig = async (params: RequestParams = {}) => { * @name GetRawBlockchainConfig * @request GET:/v2/blockchain/config/raw */ -export const getRawBlockchainConfig = async (params: RequestParams = {}) => { +export const getRawBlockchainConfig = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawBlockchainConfig(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getRawBlockchainConfig(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10886,15 +11290,33 @@ export const getRawBlockchainConfig = async (params: RequestParams = {}) => { * @name BlockchainAccountInspect * @request GET:/v2/blockchain/accounts/{account_id}/inspect */ -export const blockchainAccountInspect = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const blockchainAccountInspect = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().blockchainAccountInspect(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.blockchainAccountInspect( + options.path.accountId, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10905,12 +11327,30 @@ export const blockchainAccountInspect = async ( * @name GetLibraryByHash * @request GET:/v2/blockchain/libraries/{hash} */ -export const getLibraryByHash = async (hash: string, params: RequestParams = {}) => { +export const getLibraryByHash = async (options: { + client?: TonApiClient; + path: { + hash: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getLibraryByHash(hash, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getLibraryByHash(options.path.hash, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10921,21 +11361,34 @@ export const getLibraryByHash = async (hash: string, params: RequestParams = {}) * @name GetAccounts * @request POST:/v2/accounts/_bulk */ -export const getAccounts = async ( - data: { +export const getAccounts = async (options: { + client?: TonApiClient; + body: { accountIds: Address[]; - }, + }; query?: { /** @example "usd" */ currency?: string; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccounts(data, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccounts(options.body, options?.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10946,12 +11399,30 @@ export const getAccounts = async ( * @name GetAccount * @request GET:/v2/accounts/{account_id} */ -export const getAccount = async (accountId_Address: Address, params: RequestParams = {}) => { +export const getAccount = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccount(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccount(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10962,15 +11433,30 @@ export const getAccount = async (accountId_Address: Address, params: RequestPara * @name AccountDnsBackResolve * @request GET:/v2/accounts/{account_id}/dns/backresolve */ -export const accountDnsBackResolve = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const accountDnsBackResolve = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().accountDnsBackResolve(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.accountDnsBackResolve(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -10981,8 +11467,11 @@ export const accountDnsBackResolve = async ( * @name GetAccountJettonsBalances * @request GET:/v2/accounts/{account_id}/jettons */ -export const getAccountJettonsBalances = async ( - accountId_Address: Address, +export const getAccountJettonsBalances = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * accept ton and all possible fiat currencies, separated by commas @@ -10994,18 +11483,30 @@ export const getAccountJettonsBalances = async ( * @example ["custom_payload"] */ supported_extensions?: string[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountJettonsBalances( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountJettonsBalances( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11016,9 +11517,12 @@ export const getAccountJettonsBalances = async ( * @name GetAccountJettonBalance * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} */ -export const getAccountJettonBalance = async ( - accountId_Address: Address, - jettonId_Address: Address, +export const getAccountJettonBalance = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + jettonId: Address; + }; query?: { /** * accept ton and all possible fiat currencies, separated by commas @@ -11030,19 +11534,31 @@ export const getAccountJettonBalance = async ( * @example ["custom_payload"] */ supported_extensions?: string[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountJettonBalance( - accountId_Address, - jettonId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountJettonBalance( + options.path.accountId, + options.path.jettonId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11053,8 +11569,11 @@ export const getAccountJettonBalance = async ( * @name GetAccountJettonsHistory * @request GET:/v2/accounts/{account_id}/jettons/history */ -export const getAccountJettonsHistory = async ( - accountId_Address: Address, +export const getAccountJettonsHistory = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query: { /** * omit this parameter to get last events @@ -11068,18 +11587,30 @@ export const getAccountJettonsHistory = async ( * @example 100 */ limit: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountJettonsHistory( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountJettonsHistory( + options.path.accountId, + options.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11091,9 +11622,12 @@ export const getAccountJettonsHistory = async ( * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history * @deprecated */ -export const getAccountJettonHistoryById = async ( - accountId_Address: Address, - jettonId_Address: Address, +export const getAccountJettonHistoryById = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + jettonId: Address; + }; query: { /** * omit this parameter to get last events @@ -11119,19 +11653,31 @@ export const getAccountJettonHistoryById = async ( * @example 1668436763 */ end_date?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountJettonHistoryById( - accountId_Address, - jettonId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountJettonHistoryById( + options.path.accountId, + options.path.jettonId, + options.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11142,8 +11688,11 @@ export const getAccountJettonHistoryById = async ( * @name GetAccountNftItems * @request GET:/v2/accounts/{account_id}/nfts */ -export const getAccountNftItems = async ( - accountId_Address: Address, +export const getAccountNftItems = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * nft collection @@ -11167,18 +11716,30 @@ export const getAccountNftItems = async ( * @default false */ indirect_ownership?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountNftItems( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountNftItems( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11189,8 +11750,11 @@ export const getAccountNftItems = async ( * @name GetAccountEvents * @request GET:/v2/accounts/{account_id}/events */ -export const getAccountEvents = async ( - accountId_Address: Address, +export const getAccountEvents = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query: { /** * Show only events that are initiated by this account @@ -11226,14 +11790,30 @@ export const getAccountEvents = async ( * @example 1668436763 */ end_date?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountEvents(accountId_Address, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountEvents( + options.path.accountId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11244,28 +11824,43 @@ export const getAccountEvents = async ( * @name GetAccountEvent * @request GET:/v2/accounts/{account_id}/events/{event_id} */ -export const getAccountEvent = async ( - accountId_Address: Address, - eventId: string, +export const getAccountEvent = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + eventId: string; + }; query?: { /** * filter actions where requested account is not real subject (for example sender or receiver jettons) * @default false */ subject_only?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountEvent( - accountId_Address, - eventId, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountEvent( + options.path.accountId, + options.path.eventId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11276,8 +11871,11 @@ export const getAccountEvent = async ( * @name GetAccountTraces * @request GET:/v2/accounts/{account_id}/traces */ -export const getAccountTraces = async ( - accountId_Address: Address, +export const getAccountTraces = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * omit this parameter to get last events @@ -11292,14 +11890,30 @@ export const getAccountTraces = async ( * @example 100 */ limit?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountTraces(accountId_Address, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountTraces( + options.path.accountId, + options?.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11310,15 +11924,30 @@ export const getAccountTraces = async ( * @name GetAccountSubscriptions * @request GET:/v2/accounts/{account_id}/subscriptions */ -export const getAccountSubscriptions = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getAccountSubscriptions = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountSubscriptions(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountSubscriptions(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11329,12 +11958,30 @@ export const getAccountSubscriptions = async ( * @name ReindexAccount * @request POST:/v2/accounts/{account_id}/reindex */ -export const reindexAccount = async (accountId_Address: Address, params: RequestParams = {}) => { +export const reindexAccount = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().reindexAccount(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.reindexAccount(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11345,21 +11992,34 @@ export const reindexAccount = async (accountId_Address: Address, params: Request * @name SearchAccounts * @request GET:/v2/accounts/search */ -export const searchAccounts = async ( +export const searchAccounts = async (options: { + client?: TonApiClient; query: { /** * @minLength 3 * @maxLength 15 */ name: string; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().searchAccounts(query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.searchAccounts(options.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11370,8 +12030,11 @@ export const searchAccounts = async ( * @name GetAccountDnsExpiring * @request GET:/v2/accounts/{account_id}/dns/expiring */ -export const getAccountDnsExpiring = async ( - accountId_Address: Address, +export const getAccountDnsExpiring = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * number of days before expiration @@ -11379,18 +12042,30 @@ export const getAccountDnsExpiring = async ( * @max 3660 */ period?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountDnsExpiring( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountDnsExpiring( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11401,15 +12076,30 @@ export const getAccountDnsExpiring = async ( * @name GetAccountPublicKey * @request GET:/v2/accounts/{account_id}/publickey */ -export const getAccountPublicKey = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getAccountPublicKey = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountPublicKey(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountPublicKey(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11420,15 +12110,30 @@ export const getAccountPublicKey = async ( * @name GetAccountMultisigs * @request GET:/v2/accounts/{account_id}/multisigs */ -export const getAccountMultisigs = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getAccountMultisigs = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountMultisigs(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountMultisigs(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11439,8 +12144,11 @@ export const getAccountMultisigs = async ( * @name GetAccountDiff * @request GET:/v2/accounts/{account_id}/diff */ -export const getAccountDiff = async ( - accountId_Address: Address, +export const getAccountDiff = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query: { /** * @format int64 @@ -11454,16 +12162,32 @@ export const getAccountDiff = async ( * @example 1668436763 */ end_date: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountDiff(accountId_Address, query, params); - return { data: result, error: null }; - } catch (error) { - return { data: null, error: error as TonApiError }; - } -}; + const client = options.client || getDefaultClient(); + const result = await client.getAccountDiff( + options.path.accountId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; + } +}; /** * @description Get the transfer history of extra currencies for an account. @@ -11472,9 +12196,14 @@ export const getAccountDiff = async ( * @name GetAccountExtraCurrencyHistoryById * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history */ -export const getAccountExtraCurrencyHistoryById = async ( - accountId_Address: Address, - id: number, +export const getAccountExtraCurrencyHistoryById = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + path: { + accountId: Address; + id: number; + }; query: { /** * omit this parameter to get last events @@ -11500,19 +12229,31 @@ export const getAccountExtraCurrencyHistoryById = async ( * @example 1668436763 */ end_date?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountExtraCurrencyHistoryById( - accountId_Address, - id, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountExtraCurrencyHistoryById( + options.path.accountId, + options.path.id, + options.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11523,9 +12264,12 @@ export const getAccountExtraCurrencyHistoryById = async ( * @name GetJettonAccountHistoryById * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history */ -export const getJettonAccountHistoryById = async ( - accountId_Address: Address, - jettonId_Address: Address, +export const getJettonAccountHistoryById = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + jettonId: Address; + }; query: { /** * omit this parameter to get last events @@ -11551,19 +12295,31 @@ export const getJettonAccountHistoryById = async ( * @example 1668436763 */ end_date?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettonAccountHistoryById( - accountId_Address, - jettonId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getJettonAccountHistoryById( + options.path.accountId, + options.path.jettonId, + options.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11574,8 +12330,11 @@ export const getJettonAccountHistoryById = async ( * @name GetAccountNftHistory * @request GET:/v2/accounts/{account_id}/nfts/history */ -export const getAccountNftHistory = async ( - accountId_Address: Address, +export const getAccountNftHistory = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query: { /** * omit this parameter to get last events @@ -11589,18 +12348,30 @@ export const getAccountNftHistory = async ( * @example 100 */ limit: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountNftHistory( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountNftHistory( + options.path.accountId, + options.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11611,7 +12382,8 @@ export const getAccountNftHistory = async ( * @name GetNftCollections * @request GET:/v2/nfts/collections */ -export const getNftCollections = async ( +export const getNftCollections = async (options?: { + client?: TonApiClient; query?: { /** * @format int32 @@ -11628,14 +12400,26 @@ export const getNftCollections = async ( * @example 10 */ offset?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getNftCollections(query, params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getNftCollections(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11646,12 +12430,30 @@ export const getNftCollections = async ( * @name GetNftCollection * @request GET:/v2/nfts/collections/{account_id} */ -export const getNftCollection = async (accountId_Address: Address, params: RequestParams = {}) => { +export const getNftCollection = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getNftCollection(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getNftCollection(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11662,17 +12464,32 @@ export const getNftCollection = async (accountId_Address: Address, params: Reque * @name GetNftCollectionItemsByAddresses * @request POST:/v2/nfts/collections/_bulk */ -export const getNftCollectionItemsByAddresses = async ( - data: { +export const getNftCollectionItemsByAddresses = async < + ThrowOnError extends boolean = false +>(options: { + client?: TonApiClient; + body: { accountIds: Address[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getNftCollectionItemsByAddresses(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getNftCollectionItemsByAddresses(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11683,8 +12500,11 @@ export const getNftCollectionItemsByAddresses = async ( * @name GetItemsFromCollection * @request GET:/v2/nfts/collections/{account_id}/items */ -export const getItemsFromCollection = async ( - accountId_Address: Address, +export const getItemsFromCollection = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * @min 1 @@ -11697,18 +12517,30 @@ export const getItemsFromCollection = async ( * @default 0 */ offset?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getItemsFromCollection( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getItemsFromCollection( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11719,17 +12551,30 @@ export const getItemsFromCollection = async ( * @name GetNftItemsByAddresses * @request POST:/v2/nfts/_bulk */ -export const getNftItemsByAddresses = async ( - data: { +export const getNftItemsByAddresses = async (options: { + client?: TonApiClient; + body: { accountIds: Address[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getNftItemsByAddresses(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getNftItemsByAddresses(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11740,15 +12585,30 @@ export const getNftItemsByAddresses = async ( * @name GetNftItemByAddress * @request GET:/v2/nfts/{account_id} */ -export const getNftItemByAddress = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getNftItemByAddress = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getNftItemByAddress(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getNftItemByAddress(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11760,8 +12620,11 @@ export const getNftItemByAddress = async ( * @request GET:/v2/nfts/{account_id}/history * @deprecated */ -export const getNftHistoryById = async ( - accountId_Address: Address, +export const getNftHistoryById = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query: { /** * omit this parameter to get last events @@ -11787,14 +12650,30 @@ export const getNftHistoryById = async ( * @example 1668436763 */ end_date?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getNftHistoryById(accountId_Address, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getNftHistoryById( + options.path.accountId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11805,12 +12684,30 @@ export const getNftHistoryById = async ( * @name GetDnsInfo * @request GET:/v2/dns/{domain_name} */ -export const getDnsInfo = async (domainName: string, params: RequestParams = {}) => { +export const getDnsInfo = async (options: { + client?: TonApiClient; + path: { + domainName: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getDnsInfo(domainName, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getDnsInfo(options.path.domainName, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11821,19 +12718,38 @@ export const getDnsInfo = async (domainName: string, params: RequestParams = {}) * @name DnsResolve * @request GET:/v2/dns/{domain_name}/resolve */ -export const dnsResolve = async ( - domainName: string, +export const dnsResolve = async (options: { + client?: TonApiClient; + path: { + domainName: string; + }; query?: { /** @default false */ filter?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().dnsResolve(domainName, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.dnsResolve( + options.path.domainName, + options?.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11844,12 +12760,30 @@ export const dnsResolve = async ( * @name GetDomainBids * @request GET:/v2/dns/{domain_name}/bids */ -export const getDomainBids = async (domainName: string, params: RequestParams = {}) => { +export const getDomainBids = async (options: { + client?: TonApiClient; + path: { + domainName: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getDomainBids(domainName, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getDomainBids(options.path.domainName, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11860,21 +12794,34 @@ export const getDomainBids = async (domainName: string, params: RequestParams = * @name GetAllAuctions * @request GET:/v2/dns/auctions */ -export const getAllAuctions = async ( +export const getAllAuctions = async (options?: { + client?: TonApiClient; query?: { /** * domain filter for current auctions "ton" or "t.me" * @example "ton" */ tld?: string; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAllAuctions(query, params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getAllAuctions(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11885,12 +12832,30 @@ export const getAllAuctions = async ( * @name GetTrace * @request GET:/v2/traces/{trace_id} */ -export const getTrace = async (traceId: string, params: RequestParams = {}) => { +export const getTrace = async (options: { + client?: TonApiClient; + path: { + traceId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getTrace(traceId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getTrace(options.path.traceId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11901,12 +12866,30 @@ export const getTrace = async (traceId: string, params: RequestParams = {}) => { * @name GetEvent * @request GET:/v2/events/{event_id} */ -export const getEvent = async (eventId: string, params: RequestParams = {}) => { +export const getEvent = async (options: { + client?: TonApiClient; + path: { + eventId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getEvent(eventId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getEvent(options.path.eventId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11917,7 +12900,8 @@ export const getEvent = async (eventId: string, params: RequestParams = {}) => { * @name GetJettons * @request GET:/v2/jettons */ -export const getJettons = async ( +export const getJettons = async (options?: { + client?: TonApiClient; query?: { /** * @format int32 @@ -11934,14 +12918,26 @@ export const getJettons = async ( * @example 10 */ offset?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettons(query, params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getJettons(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11952,12 +12948,30 @@ export const getJettons = async ( * @name GetJettonInfo * @request GET:/v2/jettons/{account_id} */ -export const getJettonInfo = async (accountId_Address: Address, params: RequestParams = {}) => { +export const getJettonInfo = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettonInfo(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getJettonInfo(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11968,17 +12982,30 @@ export const getJettonInfo = async (accountId_Address: Address, params: RequestP * @name GetJettonInfosByAddresses * @request POST:/v2/jettons/_bulk */ -export const getJettonInfosByAddresses = async ( - data: { +export const getJettonInfosByAddresses = async (options: { + client?: TonApiClient; + body: { accountIds: Address[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettonInfosByAddresses(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getJettonInfosByAddresses(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -11989,8 +13016,11 @@ export const getJettonInfosByAddresses = async ( * @name GetJettonHolders * @request GET:/v2/jettons/{account_id}/holders */ -export const getJettonHolders = async ( - accountId_Address: Address, +export const getJettonHolders = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * @min 1 @@ -12004,14 +13034,30 @@ export const getJettonHolders = async ( * @default 0 */ offset?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettonHolders(accountId_Address, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getJettonHolders( + options.path.accountId, + options?.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12022,20 +13068,35 @@ export const getJettonHolders = async ( * @name GetJettonTransferPayload * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload */ -export const getJettonTransferPayload = async ( - accountId_Address: Address, - jettonId_Address: Address, - params: RequestParams = {} -) => { +export const getJettonTransferPayload = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + jettonId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettonTransferPayload( - accountId_Address, - jettonId_Address, - params + const client = options.client || getDefaultClient(); + const result = await client.getJettonTransferPayload( + options.path.accountId, + options.path.jettonId, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12046,12 +13107,30 @@ export const getJettonTransferPayload = async ( * @name GetJettonsEvents * @request GET:/v2/events/{event_id}/jettons */ -export const getJettonsEvents = async (eventId: string, params: RequestParams = {}) => { +export const getJettonsEvents = async (options: { + client?: TonApiClient; + path: { + eventId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getJettonsEvents(eventId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getJettonsEvents(options.path.eventId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12062,12 +13141,30 @@ export const getJettonsEvents = async (eventId: string, params: RequestParams = * @name GetExtraCurrencyInfo * @request GET:/v2/extra-currency/{id} */ -export const getExtraCurrencyInfo = async (id: number, params: RequestParams = {}) => { +export const getExtraCurrencyInfo = async (options: { + client?: TonApiClient; + path: { + id: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getExtraCurrencyInfo(id, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getExtraCurrencyInfo(options.path.id, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12078,18 +13175,33 @@ export const getExtraCurrencyInfo = async (id: number, params: RequestParams = { * @name GetAccountNominatorsPools * @request GET:/v2/staking/nominator/{account_id}/pools */ -export const getAccountNominatorsPools = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getAccountNominatorsPools = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountNominatorsPools( - accountId_Address, - params + const client = options.client || getDefaultClient(); + const result = await client.getAccountNominatorsPools( + options.path.accountId, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12100,15 +13212,30 @@ export const getAccountNominatorsPools = async ( * @name GetStakingPoolInfo * @request GET:/v2/staking/pool/{account_id} */ -export const getStakingPoolInfo = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getStakingPoolInfo = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getStakingPoolInfo(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getStakingPoolInfo(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12119,15 +13246,30 @@ export const getStakingPoolInfo = async ( * @name GetStakingPoolHistory * @request GET:/v2/staking/pool/{account_id}/history */ -export const getStakingPoolHistory = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getStakingPoolHistory = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getStakingPoolHistory(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getStakingPoolHistory(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12138,7 +13280,8 @@ export const getStakingPoolHistory = async ( * @name GetStakingPools * @request GET:/v2/staking/pools */ -export const getStakingPools = async ( +export const getStakingPools = async (options?: { + client?: TonApiClient; query?: { /** * account ID @@ -12151,14 +13294,26 @@ export const getStakingPools = async ( * @example false */ include_unverified?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getStakingPools(query, params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getStakingPools(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12169,12 +13324,27 @@ export const getStakingPools = async ( * @name GetStorageProviders * @request GET:/v2/storage/providers */ -export const getStorageProviders = async (params: RequestParams = {}) => { +export const getStorageProviders = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getStorageProviders(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getStorageProviders(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12185,7 +13355,8 @@ export const getStorageProviders = async (params: RequestParams = {}) => { * @name GetRates * @request GET:/v2/rates */ -export const getRates = async ( +export const getRates = async (options: { + client?: TonApiClient; query: { /** * accept cryptocurrencies or jetton master addresses, separated by commas @@ -12199,14 +13370,26 @@ export const getRates = async ( * @example ["ton","usd","rub"] */ currencies: string[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRates(query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRates(options.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12217,7 +13400,8 @@ export const getRates = async ( * @name GetChartRates * @request GET:/v2/rates/chart */ -export const getChartRates = async ( +export const getChartRates = async (options: { + client?: TonApiClient; query: { /** accept cryptocurrencies or jetton master addresses */ token: Address | string; @@ -12242,14 +13426,26 @@ export const getChartRates = async ( * @default 200 */ points_count?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getChartRates(query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getChartRates(options.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12260,12 +13456,27 @@ export const getChartRates = async ( * @name GetMarketsRates * @request GET:/v2/rates/markets */ -export const getMarketsRates = async (params: RequestParams = {}) => { +export const getMarketsRates = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getMarketsRates(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getMarketsRates(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12276,12 +13487,27 @@ export const getMarketsRates = async (params: RequestParams = {}) => { * @name GetTonConnectPayload * @request GET:/v2/tonconnect/payload */ -export const getTonConnectPayload = async (params: RequestParams = {}) => { +export const getTonConnectPayload = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getTonConnectPayload(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getTonConnectPayload(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12292,18 +13518,31 @@ export const getTonConnectPayload = async (params: RequestParams = {}) => { * @name GetAccountInfoByStateInit * @request POST:/v2/tonconnect/stateinit */ -export const getAccountInfoByStateInit = async ( - data: { +export const getAccountInfoByStateInit = async (options: { + client?: TonApiClient; + body: { /** @format cell-base64 */ stateInit: Cell; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountInfoByStateInit(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountInfoByStateInit(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12314,8 +13553,9 @@ export const getAccountInfoByStateInit = async ( * @name TonConnectProof * @request POST:/v2/wallet/auth/proof */ -export const tonConnectProof = async ( - data: { +export const tonConnectProof = async (options: { + client?: TonApiClient; + body: { /** * @format address * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" @@ -12338,14 +13578,26 @@ export const tonConnectProof = async ( /** @format cell-base64 */ stateInit?: Cell; }; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().tonConnectProof(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.tonConnectProof(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12356,12 +13608,30 @@ export const tonConnectProof = async ( * @name GetAccountSeqno * @request GET:/v2/wallet/{account_id}/seqno */ -export const getAccountSeqno = async (accountId_Address: Address, params: RequestParams = {}) => { +export const getAccountSeqno = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAccountSeqno(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAccountSeqno(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12372,12 +13642,30 @@ export const getAccountSeqno = async (accountId_Address: Address, params: Reques * @name GetWalletInfo * @request GET:/v2/wallet/{account_id} */ -export const getWalletInfo = async (accountId_Address: Address, params: RequestParams = {}) => { +export const getWalletInfo = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getWalletInfo(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getWalletInfo(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12388,12 +13676,30 @@ export const getWalletInfo = async (accountId_Address: Address, params: RequestP * @name GetWalletsByPublicKey * @request GET:/v2/pubkeys/{public_key}/wallets */ -export const getWalletsByPublicKey = async (publicKey: string, params: RequestParams = {}) => { +export const getWalletsByPublicKey = async (options: { + client?: TonApiClient; + path: { + publicKey: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getWalletsByPublicKey(publicKey, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getWalletsByPublicKey(options.path.publicKey, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12404,12 +13710,27 @@ export const getWalletsByPublicKey = async (publicKey: string, params: RequestPa * @name GaslessConfig * @request GET:/v2/gasless/config */ -export const gaslessConfig = async (params: RequestParams = {}) => { +export const gaslessConfig = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().gaslessConfig(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.gaslessConfig(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12420,9 +13741,12 @@ export const gaslessConfig = async (params: RequestParams = {}) => { * @name GaslessEstimate * @request POST:/v2/gasless/estimate/{master_id} */ -export const gaslessEstimate = async ( - masterId_Address: Address, - data: { +export const gaslessEstimate = async (options: { + client?: TonApiClient; + path: { + masterId: Address; + }; + body: { /** * TONAPI verifies that the account has enough jettons to pay the commission and make a transfer. * @default false @@ -12437,14 +13761,30 @@ export const gaslessEstimate = async ( /** @format cell */ boc: Cell; }[]; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().gaslessEstimate(masterId_Address, data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.gaslessEstimate( + options.path.masterId, + options.body, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12455,20 +13795,33 @@ export const gaslessEstimate = async ( * @name GaslessSend * @request POST:/v2/gasless/send */ -export const gaslessSend = async ( - data: { +export const gaslessSend = async (options: { + client?: TonApiClient; + body: { /** hex encoded public key */ walletPublicKey: string; /** @format cell */ boc: Cell; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().gaslessSend(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.gaslessSend(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12479,12 +13832,27 @@ export const gaslessSend = async ( * @name GetRawMasterchainInfo * @request GET:/v2/liteserver/get_masterchain_info */ -export const getRawMasterchainInfo = async (params: RequestParams = {}) => { +export const getRawMasterchainInfo = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawMasterchainInfo(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getRawMasterchainInfo(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12495,7 +13863,8 @@ export const getRawMasterchainInfo = async (params: RequestParams = {}) => { * @name GetRawMasterchainInfoExt * @request GET:/v2/liteserver/get_masterchain_info_ext */ -export const getRawMasterchainInfoExt = async ( +export const getRawMasterchainInfoExt = async (options: { + client?: TonApiClient; query: { /** * mode @@ -12503,14 +13872,26 @@ export const getRawMasterchainInfoExt = async ( * @example 0 */ mode: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawMasterchainInfoExt(query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawMasterchainInfoExt(options.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12521,12 +13902,27 @@ export const getRawMasterchainInfoExt = async ( * @name GetRawTime * @request GET:/v2/liteserver/get_time */ -export const getRawTime = async (params: RequestParams = {}) => { +export const getRawTime = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawTime(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getRawTime(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12537,12 +13933,30 @@ export const getRawTime = async (params: RequestParams = {}) => { * @name GetRawBlockchainBlock * @request GET:/v2/liteserver/get_block/{block_id} */ -export const getRawBlockchainBlock = async (blockId: string, params: RequestParams = {}) => { +export const getRawBlockchainBlock = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawBlockchainBlock(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawBlockchainBlock(options.path.blockId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12553,12 +13967,33 @@ export const getRawBlockchainBlock = async (blockId: string, params: RequestPara * @name GetRawBlockchainBlockState * @request GET:/v2/liteserver/get_state/{block_id} */ -export const getRawBlockchainBlockState = async (blockId: string, params: RequestParams = {}) => { +export const getRawBlockchainBlockState = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawBlockchainBlockState(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawBlockchainBlockState( + options.path.blockId, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12569,8 +14004,11 @@ export const getRawBlockchainBlockState = async (blockId: string, params: Reques * @name GetRawBlockchainBlockHeader * @request GET:/v2/liteserver/get_block_header/{block_id} */ -export const getRawBlockchainBlockHeader = async ( - blockId: string, +export const getRawBlockchainBlockHeader = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; query: { /** * mode @@ -12578,14 +14016,30 @@ export const getRawBlockchainBlockHeader = async ( * @example 0 */ mode: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawBlockchainBlockHeader(blockId, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawBlockchainBlockHeader( + options.path.blockId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12596,18 +14050,31 @@ export const getRawBlockchainBlockHeader = async ( * @name SendRawMessage * @request POST:/v2/liteserver/send_message */ -export const sendRawMessage = async ( - data: { +export const sendRawMessage = async (options: { + client?: TonApiClient; + body: { /** @format cell-base64 */ body: Cell; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().sendRawMessage(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.sendRawMessage(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12618,26 +14085,41 @@ export const sendRawMessage = async ( * @name GetRawAccountState * @request GET:/v2/liteserver/get_account_state/{account_id} */ -export const getRawAccountState = async ( - accountId_Address: Address, +export const getRawAccountState = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * target block: (workchain,shard,seqno,root_hash,file_hash) * @example "(-1,8000000000000000,4234234,3E575DAB1D25...90D8,47192E5C46C...BB29)" */ target_block?: string; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawAccountState( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getRawAccountState( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12648,8 +14130,11 @@ export const getRawAccountState = async ( * @name GetRawShardInfo * @request GET:/v2/liteserver/get_shard_info/{block_id} */ -export const getRawShardInfo = async ( - blockId: string, +export const getRawShardInfo = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; query: { /** * workchain @@ -12668,14 +14153,30 @@ export const getRawShardInfo = async ( * @example false */ exact: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawShardInfo(blockId, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawShardInfo( + options.path.blockId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12686,12 +14187,30 @@ export const getRawShardInfo = async ( * @name GetAllRawShardsInfo * @request GET:/v2/liteserver/get_all_shards_info/{block_id} */ -export const getAllRawShardsInfo = async (blockId: string, params: RequestParams = {}) => { +export const getAllRawShardsInfo = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getAllRawShardsInfo(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getAllRawShardsInfo(options.path.blockId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12702,8 +14221,11 @@ export const getAllRawShardsInfo = async (blockId: string, params: RequestParams * @name GetRawTransactions * @request GET:/v2/liteserver/get_transactions/{account_id} */ -export const getRawTransactions = async ( - accountId_Address: Address, +export const getRawTransactions = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query: { /** * count @@ -12722,18 +14244,30 @@ export const getRawTransactions = async ( * @example "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" */ hash: string; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawTransactions( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getRawTransactions( + options.path.accountId, + options.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12744,8 +14278,11 @@ export const getRawTransactions = async ( * @name GetRawListBlockTransactions * @request GET:/v2/liteserver/list_block_transactions/{block_id} */ -export const getRawListBlockTransactions = async ( - blockId: string, +export const getRawListBlockTransactions = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; query: { /** * mode @@ -12771,14 +14308,30 @@ export const getRawListBlockTransactions = async ( * @example 23814011000000 */ lt?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawListBlockTransactions(blockId, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawListBlockTransactions( + options.path.blockId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12789,7 +14342,8 @@ export const getRawListBlockTransactions = async ( * @name GetRawBlockProof * @request GET:/v2/liteserver/get_block_proof */ -export const getRawBlockProof = async ( +export const getRawBlockProof = async (options: { + client?: TonApiClient; query: { /** * known block: (workchain,shard,seqno,root_hash,file_hash) @@ -12807,14 +14361,26 @@ export const getRawBlockProof = async ( * @example 0 */ mode: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawBlockProof(query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawBlockProof(options.query, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12825,8 +14391,11 @@ export const getRawBlockProof = async ( * @name GetRawConfig * @request GET:/v2/liteserver/get_config_all/{block_id} */ -export const getRawConfig = async ( - blockId: string, +export const getRawConfig = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; query: { /** * mode @@ -12834,14 +14403,30 @@ export const getRawConfig = async ( * @example 0 */ mode: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawConfig(blockId, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawConfig( + options.path.blockId, + options.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12852,12 +14437,30 @@ export const getRawConfig = async ( * @name GetRawShardBlockProof * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} */ -export const getRawShardBlockProof = async (blockId: string, params: RequestParams = {}) => { +export const getRawShardBlockProof = async (options: { + client?: TonApiClient; + path: { + blockId: string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getRawShardBlockProof(blockId, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getRawShardBlockProof(options.path.blockId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12868,12 +14471,27 @@ export const getRawShardBlockProof = async (blockId: string, params: RequestPara * @name GetOutMsgQueueSizes * @request GET:/v2/liteserver/get_out_msg_queue_sizes */ -export const getOutMsgQueueSizes = async (params: RequestParams = {}) => { +export const getOutMsgQueueSizes = async (options?: { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getOutMsgQueueSizes(params); - return { data: result, error: null }; + const client = options?.client || getDefaultClient(); + const result = await client.getOutMsgQueueSizes(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12884,15 +14502,30 @@ export const getOutMsgQueueSizes = async (params: RequestParams = {}) => { * @name GetMultisigAccount * @request GET:/v2/multisig/{account_id} */ -export const getMultisigAccount = async ( - accountId_Address: Address, - params: RequestParams = {} -) => { +export const getMultisigAccount = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getMultisigAccount(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getMultisigAccount(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12903,12 +14536,30 @@ export const getMultisigAccount = async ( * @name GetMultisigOrder * @request GET:/v2/multisig/order/{account_id} */ -export const getMultisigOrder = async (accountId_Address: Address, params: RequestParams = {}) => { +export const getMultisigOrder = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getMultisigOrder(accountId_Address, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.getMultisigOrder(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12919,18 +14570,31 @@ export const getMultisigOrder = async (accountId_Address: Address, params: Reque * @name DecodeMessage * @request POST:/v2/message/decode */ -export const decodeMessage = async ( - data: { +export const decodeMessage = async (options: { + client?: TonApiClient; + body: { /** @format cell */ boc: Cell; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().decodeMessage(data, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.decodeMessage(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12941,21 +14605,38 @@ export const decodeMessage = async ( * @name EmulateMessageToEvent * @request POST:/v2/events/emulate */ -export const emulateMessageToEvent = async ( - data: { +export const emulateMessageToEvent = async (options: { + client?: TonApiClient; + body: { /** @format cell */ boc: Cell; - }, + }; query?: { ignore_signature_check?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().emulateMessageToEvent(data, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.emulateMessageToEvent( + options.body, + options?.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12966,21 +14647,38 @@ export const emulateMessageToEvent = async ( * @name EmulateMessageToTrace * @request POST:/v2/traces/emulate */ -export const emulateMessageToTrace = async ( - data: { +export const emulateMessageToTrace = async (options: { + client?: TonApiClient; + body: { /** @format cell */ boc: Cell; - }, + }; query?: { ignore_signature_check?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().emulateMessageToTrace(data, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.emulateMessageToTrace( + options.body, + options?.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -12991,8 +14689,9 @@ export const emulateMessageToTrace = async ( * @name EmulateMessageToWallet * @request POST:/v2/wallet/emulate */ -export const emulateMessageToWallet = async ( - data: { +export const emulateMessageToWallet = async (options: { + client?: TonApiClient; + body: { /** @format cell */ boc: Cell; /** additional per account configuration */ @@ -13008,18 +14707,34 @@ export const emulateMessageToWallet = async ( */ balance?: bigint; }[]; - }, + }; query?: { /** @example "usd" */ currency?: string; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().emulateMessageToWallet(data, query, params); - return { data: result, error: null }; + const client = options.client || getDefaultClient(); + const result = await client.emulateMessageToWallet( + options.body, + options?.query, + options.params + ); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -13030,27 +14745,42 @@ export const emulateMessageToWallet = async ( * @name EmulateMessageToAccountEvent * @request POST:/v2/accounts/{account_id}/events/emulate */ -export const emulateMessageToAccountEvent = async ( - accountId_Address: Address, - data: { +export const emulateMessageToAccountEvent = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; + body: { /** @format cell */ boc: Cell; - }, + }; query?: { ignore_signature_check?: boolean; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().emulateMessageToAccountEvent( - accountId_Address, - data, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.emulateMessageToAccountEvent( + options.path.accountId, + options.body, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; @@ -13061,8 +14791,11 @@ export const emulateMessageToAccountEvent = async ( * @name GetPurchaseHistory * @request GET:/v2/purchases/{account_id}/history */ -export const getPurchaseHistory = async ( - accountId_Address: Address, +export const getPurchaseHistory = async (options: { + client?: TonApiClient; + path: { + accountId: Address; + }; query?: { /** * omit this parameter to get last invoices @@ -13077,17 +14810,29 @@ export const getPurchaseHistory = async ( * @example 100 */ limit?: number; - }, - params: RequestParams = {} -) => { + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}) => { try { - const result = await getDefaultClient().getPurchaseHistory( - accountId_Address, - query, - params + const client = options.client || getDefaultClient(); + const result = await client.getPurchaseHistory( + options.path.accountId, + options?.query, + options.params ); - return { data: result, error: null }; + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; diff --git a/packages/client/src/templates/procedure-call.ejs b/packages/client/src/templates/procedure-call.ejs index 19b4c76..372e756 100644 --- a/packages/client/src/templates/procedure-call.ejs +++ b/packages/client/src/templates/procedure-call.ejs @@ -23,6 +23,19 @@ const pathParams = originPathParams.map( ); // #endregion +// #region Helper functions for Advanced API (global functions) +const hasPathParams = () => pathParams.length > 0; +const hasQueryParams = () => query != null; +const hasBodyParams = () => payload != null; +const isOptionsRequired = () => { + // Options required if there are non-optional path, body, or query params + const hasRequiredPath = pathParams.some(param => !param.optional); + const hasRequiredBody = payload && !payload.optional; + const hasRequiredQuery = query && !query.optional; + return hasRequiredPath || hasRequiredBody || hasRequiredQuery; +}; +// #endregion + const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH; // Use consistent parameter name for both class methods and global functions @@ -75,7 +88,7 @@ const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || n const responseFormatTmpl = responseContentKind[successResponse.contentKind] || null; const securityTmpl = security ? 'true' : null; -const describeReturnType = () => !config.toJS ? '' : `Promise>`; +const describeReturnType = () => !config.toJS ? '' : `MethodResult<${type}, ThrowOnError>`; const reducedPathParams = addressType.map((name) => `const ${name} = ${getNameAddressFromId(name)}.toRawString();`).join('\n'); @@ -100,6 +113,82 @@ const queryImplodeParams = route.routeParams.query. filter(param => param.explode === false) .map(param => param.name) const queryImplodeTmpl = queryImplodeParams.length === 0 ? null : JSON.stringify(queryImplodeParams) + +// #region Advanced API options type generation (for isFlat=true) +const generatePathFieldName = (param) => { + // Remove _Address suffix to get original parameter name + return param.name.endsWith('_Address') ? param.name.slice(0, -8) : param.name; +}; + +const generateOptionsInterface = () => { + const fields = []; + + // Always add client + fields.push('client?: TonApiClient;'); + + // Add path field if there are path parameters + if (hasPathParams()) { + const pathFields = pathParams.map(param => { + const fieldName = generatePathFieldName(param); + const optional = param.optional ? '?' : ''; + return `${fieldName}${optional}: ${param.type}`; + }).join(';\n '); + fields.push(`path: {\n ${pathFields};\n };`); + } + + // Add body field if there is a payload + if (hasBodyParams()) { + const bodyOptional = payload.optional ? '?' : ''; + fields.push(`body${bodyOptional}: ${payload.type};`); + } + + // Add query field if there are query parameters + if (hasQueryParams()) { + const queryOptional = query.optional ? '?' : ''; + fields.push(`query${queryOptional}: ${query.type};`); + } + + // Always add params + fields.push('params?: RequestParams;'); + + // Add throwOnError for conditional return type + fields.push('throwOnError?: ThrowOnError;'); + + return `{\n ${fields.join('\n ')}\n}`; +}; + +const optionsType = generateOptionsInterface(); +const optionsArgument = `options${isOptionsRequired() ? '' : '?'}`; + +// Generate all arguments for calling the instance method +// Must match the order of sortedWrapperArgs (which sorts by optionality) +const generateAllArguments = () => { + const args = []; + + // Build args using sortedWrapperArgs order (path, query, body, params sorted by optionality) + sortedWrapperArgs.forEach(arg => { + if (arg === requestConfigParam) { + // params argument - use optional chaining only if options itself is optional + args.push(isOptionsRequired() ? 'options.params' : 'options?.params'); + } else if (arg === payload) { + // body argument + const isRequired = !payload.optional; + args.push(isRequired ? 'options.body' : 'options?.body'); + } else if (arg === query) { + // query argument + const isRequired = !query.optional; + args.push(isRequired ? 'options.query' : 'options?.query'); + } else if (pathParams.includes(arg)) { + // path parameter + const fieldName = generatePathFieldName(arg); + const isRequired = !arg.optional; + args.push(isRequired ? `options.path.${fieldName}` : `options?.path?.${fieldName}`); + } + }); + + return args.join(', '); +}; +// #endregion %> /** <%~ routeDocs.description %> @@ -110,12 +199,23 @@ const queryImplodeTmpl = queryImplodeParams.length === 0 ? null : JSON.stringify */ <% if (isFlat) { %> -export const <%~ route.routeName.usage %> = async (<%~ wrapperArgs %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { +export const <%~ route.routeName.usage %> = async (<%~ optionsArgument %>: <%~ optionsType %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { try { - const result = await getDefaultClient().<%~ route.routeName.usage %>(<%~ passedArgs %>); - return { data: result, error: null }; + const client = <%= isOptionsRequired() ? 'options.client' : 'options?.client' %> || getDefaultClient(); + const result = await client.<%~ route.routeName.usage %>(<%~ generateAllArguments() %>); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as any; + } + + return { data: result, error: null } as any; } catch (error) { - return { data: null, error: error as TonApiError }; + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as any; } }; <% } else { %> diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index a5b94a3..bc1d546 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -6,6 +6,17 @@ export type Result = | { data: T; error: null } | { data: null; error: TonApiError }; +/** + * Conditional return type for Advanced API methods with throwOnError support + * @template T - The data type returned on success + * @template ThrowOnError - Boolean flag determining if errors should be thrown + * + * When ThrowOnError is true: returns Promise (throws on error) + * When ThrowOnError is false: returns Promise> (returns {data, error}) + */ +export type MethodResult = + ThrowOnError extends true ? Promise : Promise>; + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, (match) => match[1]?.toUpperCase() ?? ''); } diff --git a/packages/ton-adapter/src/tonapi-adapter.ts b/packages/ton-adapter/src/tonapi-adapter.ts index 7d619be..c1dda47 100644 --- a/packages/ton-adapter/src/tonapi-adapter.ts +++ b/packages/ton-adapter/src/tonapi-adapter.ts @@ -19,25 +19,27 @@ import { } from '@ton/core'; import { AccountStatus as TonApiAccountStatus, - getBlockchainRawAccount, - execGetMethodForBlockchainAccount, - getAccount, - sendBlockchainMessage, - getBlockchainAccountTransactions, BlockchainRawAccount, AccountStatus, - TonApiHttpError + TonApiHttpError, + TonApiClient } from '@ton-api/client'; import { Buffer } from 'buffer'; export class ContractAdapter { + private client: TonApiClient; + + constructor(client: TonApiClient) { + this.client = client; + } + /** * Open smart contract * @param contract contract * @returns opened contract */ open(contract: T) { - return openContract(contract, args => createProvider(args.address, args.init)); + return openContract(contract, args => createProvider(this.client, args.address, args.init)); } /** @@ -47,52 +49,47 @@ export class ContractAdapter { * @returns provider */ provider(address: Address, init?: { code?: Cell; data?: Cell } | null) { - return createProvider(address, init ? init : null); + return createProvider(this.client, address, init ? init : null); } } type LocalBlockchainRawAccount = Partial> & Omit; function createProvider( + client: TonApiClient, address: Address, init: { code?: Cell | null; data?: Cell | null } | null ): ContractProvider { return { async getState(): Promise { // Load state - const { data: accountData, error: accountError } = - await getBlockchainRawAccount(address); + const account: LocalBlockchainRawAccount = await client + .getBlockchainRawAccount(address) + .catch((accountError: unknown) => { + // Check if it's a 404 error (account not found) + const accountNotExists = + accountError instanceof TonApiHttpError && accountError.status === 404; - let account: LocalBlockchainRawAccount; - if (accountError) { - // Check if it's a 404 error (account not found) - const accountNotExists = - accountError instanceof TonApiHttpError && accountError.status === 404; - - if (!accountNotExists) { - throw new Error(`Account request failed`, { - cause: accountError - }); - } - - const mockResult: LocalBlockchainRawAccount = { - address: address, - balance: 0n, - lastTransactionLt: undefined, - status: AccountStatus.Uninit, - storage: { - usedCells: 1, - usedBits: 95, - usedPublicCells: 0, - lastPaid: Math.floor(new Date().getTime() / 1000), - duePayment: 0n + if (!accountNotExists) { + throw new Error(`Account request failed`, { + cause: accountError + }); } - }; - account = mockResult; - } else { - account = accountData; - } + return { + address: address, + balance: 0n, + lastTransactionLt: undefined, + status: AccountStatus.Uninit, + storage: { + usedCells: 1, + usedBits: 95, + usedPublicCells: 0, + lastPaid: Math.floor(new Date().getTime() / 1000), + duePayment: 0n + } + } as LocalBlockchainRawAccount; + }); // Convert state const last = @@ -123,11 +120,14 @@ function createProvider( } }; - const extraCurrency: ExtraCurrency | null = account.extraBalance - ? Object.fromEntries( - Object.entries(account.extraBalance).map(([k, v]) => [Number(k), BigInt(v)]) - ) - : null; + let extraCurrency: ExtraCurrency | null = null; + if (account.extraBalance) { + const ec: Record = {}; + for (const [k, v] of Object.entries(account.extraBalance)) { + ec[Number(k)] = BigInt(v as unknown as string | number | bigint); + } + extraCurrency = ec as unknown as ExtraCurrency; + } return { balance: account.balance, @@ -145,34 +145,31 @@ function createProvider( throw new Error('Tuples as get parameters are not supported by tonapi'); } - const { data: result, error } = await execGetMethodForBlockchainAccount(address, name, { - args: args.map(TupleItemToTonapiString) - }); - - if (error) { - throw new Error(`Get method execution failed`, { - cause: error + return client + .execGetMethodForBlockchainAccount(address, name, { + args: args.map(TupleItemToTonapiString) + }) + .then((result) => ({ + stack: new TupleReader(result.stack) + })) + .catch((error: unknown) => { + throw new Error(`Get method execution failed`, { + cause: error + }); }); - } - - return { - stack: new TupleReader(result.stack) - }; }, async external(message) { // Resolve init - let neededInit: { code?: Cell | null; data?: Cell | null } | null = null; - if (init) { - const { data, error } = await getAccount(address); - if (error) { - throw new Error(`Failed to get account info`, { - cause: error - }); - } - if (data.status !== 'active') { - neededInit = init; - } - } + const neededInit: { code?: Cell | null; data?: Cell | null } | null = init + ? await client + .getAccount(address) + .then((data) => (data.status !== 'active' ? init : null)) + .catch((error: unknown) => { + throw new Error(`Failed to get account info`, { + cause: error + }); + }) + : null; // Send with state init const ext = external({ @@ -182,28 +179,26 @@ function createProvider( }); const boc = beginCell().store(storeMessage(ext)).endCell(); - const { error } = await sendBlockchainMessage({ boc }); - - if (error) { - throw new Error(`Failed to send blockchain message`, { - cause: error + return client + .sendBlockchainMessage({ boc }) + .catch((error: unknown) => { + throw new Error(`Failed to send blockchain message`, { + cause: error + }); }); - } }, async internal(via, message) { // Resolve init - let neededInit: { code?: Cell | null; data?: Cell | null } | null = null; - if (init) { - const { data, error } = await getAccount(address); - if (error) { - throw new Error(`Failed to get account info`, { - cause: error - }); - } - if (data.status !== 'active') { - neededInit = init; - } - } + const neededInit: { code?: Cell | null; data?: Cell | null } | null = init + ? await client + .getAccount(address) + .then((data) => (data.status !== 'active' ? init : null)) + .catch((error: unknown) => { + throw new Error(`Failed to get account info`, { + cause: error + }); + }) + : null; // Resolve bounce let bounce = true; @@ -238,7 +233,7 @@ function createProvider( }); }, open(contract: T): OpenedContract { - return openContract(contract, params => createProvider(params.address, params.init)); + return openContract(contract, params => createProvider(client, params.address, params.init)); }, async getTransactions( address: Address, @@ -250,20 +245,22 @@ function createProvider( 'hash param in getTransactions action ignored, because not supported', hash.toString('hex') ); - const { data: result, error } = await getBlockchainAccountTransactions(address, { - before_lt: lt + 1n, - limit - }); - if (error) { - throw new Error(`Failed to get account transactions`, { - cause: error + return client + .getBlockchainAccountTransactions(address, { + before_lt: lt + 1n, + limit + }) + .then((result) => + result.transactions.map(transaction => + loadTransaction(transaction.raw.asSlice()) + ) + ) + .catch((error: unknown) => { + throw new Error(`Failed to get account transactions`, { + cause: error + }); }); - } - - return result.transactions.map(transaction => - loadTransaction(transaction.raw.asSlice()) - ); } }; } diff --git a/tests/adapters/migratebeta.test.ts b/tests/adapters/migratebeta.test.ts index 67c0ade..54600e1 100644 --- a/tests/adapters/migratebeta.test.ts +++ b/tests/adapters/migratebeta.test.ts @@ -1,7 +1,7 @@ import { Address, Contract, ContractProvider, OpenedContract } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey, KeyPair } from '@ton/crypto'; import { ContractAdapter } from '@ton-api/ton-adapter'; -import { initClient } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; import { test, beforeAll, expect } from 'vitest'; class NftItem implements Contract { @@ -23,14 +23,14 @@ class NftItem implements Contract { } } -// Initialize the ton API client using flat API -initClient({ +// Create TonApiClient instance +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io' // apiKey: 'your-api-key', }); -// Create an adapter -const contractAdapter = new ContractAdapter(); +// Create an adapter with explicit client +const contractAdapter = new ContractAdapter(tonApiClient); let keyPair: KeyPair; let contract: OpenedContract; diff --git a/tests/adapters/readme.test.ts b/tests/adapters/readme.test.ts index fd74343..1c99e19 100644 --- a/tests/adapters/readme.test.ts +++ b/tests/adapters/readme.test.ts @@ -1,17 +1,17 @@ import { SendMode, WalletContractV5R1, internal } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto'; -import { initClient } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; import { test, vi, expect } from 'vitest'; -// Initialize TonApi client -initClient({ +// Create TonApiClient instance +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io' - // apiKey: 'YOUR_API_KEY' // Uncomment this line and set your API key + // apiKey: 'YOUR_API_KEY' // Uncomment and set your API key }); -// Create an adapter -const adapter = new ContractAdapter(); +// Create an adapter with explicit client +const adapter = new ContractAdapter(tonApiClient); // Create and use a wallet contract async function main() { diff --git a/tests/adapters/utils/clients.ts b/tests/adapters/utils/clients.ts index 0676bb4..2eb93ce 100644 --- a/tests/adapters/utils/clients.ts +++ b/tests/adapters/utils/clients.ts @@ -1,16 +1,16 @@ import { TonClient } from '@ton/ton'; import { ContractAdapter } from '@ton-api/ton-adapter'; -import { initClient } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; require('dotenv').config(); -// Initialize client for TonApi -initClient({ +// Create TonApiClient instance +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io', apiKey: process.env.TONAPI_API_KEY }); -export const clientTonApi = new ContractAdapter(); // Create an adapter +export const clientTonApi = new ContractAdapter(tonApiClient); // Create an adapter with explicit client export const getTonCenterClient = () => { if (!process.env.TONCENTER_API_KEY) { diff --git a/tests/adapters/utils/contract.ts b/tests/adapters/utils/contract.ts index 434853c..fffc9b0 100644 --- a/tests/adapters/utils/contract.ts +++ b/tests/adapters/utils/contract.ts @@ -1,10 +1,11 @@ import { Address, Contract, ContractProvider, TupleItem } from '@ton/core'; import { WalletContractV4 } from '@ton/ton'; -import { initClient, execGetMethodForBlockchainAccount } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; -// Initialize client once at module load time -initClient({ - baseUrl: 'https://tonapi.io' +// Create TonApiClient instance +const tonApiClient = new TonApiClient({ + baseUrl: 'https://tonapi.io', + apiKey: process.env.TONAPI_API_KEY }); export class NftItem implements Contract { @@ -38,18 +39,16 @@ export class WalletItem implements Contract { } static async createFromAddress(address: Address) { - const { data: accountData, error } = await execGetMethodForBlockchainAccount( - address, - 'get_public_key' - ); - if (error) { - throw new Error(`Failed to get public key: ${error.message}`); - } - const workchain = address.workChain; - const publicKey = BigInt(accountData.decoded.public_key); - const bufferPublicKey = Buffer.from(publicKey.toString(16), 'hex'); + try { + const accountData = await tonApiClient.execGetMethodForBlockchainAccount(address, 'get_public_key'); + const workchain = address.workChain; + const publicKey = BigInt(accountData.decoded.public_key); + const bufferPublicKey = Buffer.from(publicKey.toString(16), 'hex'); - return new WalletItem(address, workchain, bufferPublicKey).walletContract; + return new WalletItem(address, workchain, bufferPublicKey).walletContract; + } catch (error) { + throw new Error(`Failed to get public key: ${error instanceof Error ? error.message : String(error)}`); + } } public getBalance(provider: ContractProvider) { diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index 25566cf..7fd64b6 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -1,5 +1,5 @@ import { initTa, ta } from './utils/client'; -import { status, getAccount, execGetMethodForBlockchainAccount, TonApiParsingError, TonApiHttpError, TonApiNetworkError, TonApiUnknownError } from '@ton-api/client'; +import { status, getAccount, getAccounts, execGetMethodForBlockchainAccount, TonApiParsingError, TonApiHttpError, TonApiNetworkError, TonApiUnknownError, TonApiClient } from '@ton-api/client'; import { Address } from '@ton/core'; import { vi, test, expect, beforeEach, describe, afterEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; @@ -553,4 +553,188 @@ describe('Advanced API - Global methods (returns {data, error})', () => { expect(error.status).toBe(400); expect(error.type).toBe('http_error'); }); + + test('should use custom client when provided', async () => { + const mockData = { rest_online: true, indexing_latency: 8 }; + const customFetch = vi.fn().mockResolvedValueOnce(createJsonResponse(mockData, 200)); + const customClient = new TonApiClient({ + baseUrl: 'https://custom.tonapi.io', + fetch: customFetch + }); + + const { data, error } = await status({ client: customClient }); + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.restOnline).toBe(true); + expect(customFetch).toHaveBeenCalledWith( + expect.stringContaining('https://custom.tonapi.io/v2/status'), + expect.any(Object) + ); + }); + + test('should work with path parameters', async () => { + const mockData = { + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '1000000000', + status: 'active' + }; + mockFetch(mockData); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount({ + path: { accountId: validAddress } + }); + + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.balance).toBeDefined(); + }); + + test('should work with path parameters and custom params', async () => { + const mockData = { + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '1000000000', + status: 'active' + }; + const fetchSpy = mockFetch(mockData); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccount({ + path: { accountId: validAddress }, + params: { headers: { 'X-Custom': 'test' } } + }); + + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(fetchSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + headers: expect.objectContaining({ + 'X-Custom': 'test' + }) + }) + ); + }); + + test('should work with body and query parameters', async () => { + const mockData = { + accounts: [ + { + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '1000000000', + status: 'active' + } + ] + }; + mockFetch(mockData); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccounts({ + body: { accountIds: [address] }, + query: { currency: 'usd' } + }); + + expect(error).toBeNull(); + expect(data).toBeDefined(); + expect(data?.accounts).toBeDefined(); + }); + + test('should work with body only (optional query)', async () => { + const mockData = { + accounts: [ + { + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '1000000000', + status: 'active' + } + ] + }; + mockFetch(mockData); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const { data, error } = await getAccounts({ + body: { accountIds: [address] } + }); + + expect(error).toBeNull(); + expect(data).toBeDefined(); + }); + + describe('throwOnError mode', () => { + test('should return data directly when throwOnError is true', async () => { + const mockData = { rest_online: true, indexing_latency: 8 }; + mockFetch(mockData); + + const data = await status({ throwOnError: true }); + + // Should return data directly, not Result type + expect(data).toBeDefined(); + expect(data.restOnline).toBe(true); + expect(data.indexingLatency).toBe(8); + + // Should NOT have error property (not a Result type) + expect(data).not.toHaveProperty('error'); + expect(data).not.toHaveProperty('data'); + }); + + test('should throw error when throwOnError is true and API returns error', async () => { + const mockError = { error: 'Server error' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 500)); + + await expect(status({ throwOnError: true })).rejects.toThrow(); + }); + + test('should work with path parameters and throwOnError', async () => { + const mockData = { + address: 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y', + balance: '1000000000', + status: 'active' + }; + mockFetch(mockData); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const data = await getAccount({ + path: { accountId: validAddress }, + throwOnError: true + }); + + expect(data).toBeDefined(); + expect(data.balance).toBeDefined(); + // Should NOT have Result properties + expect(data).not.toHaveProperty('error'); + }); + + test('should throw specific error type when throwOnError is true', async () => { + const mockError = { error: 'Not found' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 404)); + + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + + try { + await getAccount({ + path: { accountId: validAddress }, + throwOnError: true + }); + // Should not reach here + expect(true).toBe(false); + } catch (error) { + assertIsHttpError(error); + expect(error.status).toBe(404); + expect(error.message).toContain('Not found'); + } + }); + + test('throwOnError false should still return Result type', async () => { + const mockData = { rest_online: true, indexing_latency: 8 }; + mockFetch(mockData); + + const result = await status({ throwOnError: false }); + + // Should return Result type + expect(result).toHaveProperty('data'); + expect(result).toHaveProperty('error'); + expect(result.error).toBeNull(); + expect(result.data).toBeDefined(); + }); + }); }); diff --git a/tests/client/memory-leak.test.ts b/tests/client/memory-leak.test.ts index 004f180..0ef408d 100644 --- a/tests/client/memory-leak.test.ts +++ b/tests/client/memory-leak.test.ts @@ -1,17 +1,19 @@ -import { getBlockchainBlockTransactions } from './__mock__/services'; +import { getBlockchainBlockTransactions as getBlockchainBlockTransactionsMock } from './__mock__/services'; import { ta } from './utils/client'; -import { getBlockchainBlockTransactions as getBlockchainBlockTransactionsGlobal } from '@ton-api/client'; +import { TonApiClient } from '@ton-api/client'; import { describe, test, expect } from 'vitest'; import { JSONStringify } from './utils/jsonbig'; global.fetch = () => Promise.resolve( - new Response(JSONStringify(getBlockchainBlockTransactions), { + new Response(JSONStringify(getBlockchainBlockTransactionsMock), { status: 200, headers: { 'Content-Type': 'application/json' } }) ); +const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + // To run this test: // NODE_OPTIONS="--expose-gc" npm run test tests/client/memory-leak.test.ts @@ -73,7 +75,7 @@ describe.skip('Memory leak test', () => { const memoryUsageSamples: number[] = []; for (let i = 0; i < iterations; i++) { - await getBlockchainBlockTransactionsGlobal('(-1,8000000000000000,4234234)'); + await tonApiClient.getBlockchainBlockTransactions('(-1,8000000000000000,4234234)'); // Log memory usage every 50_000 iterations if (i % 50_000 === 0) { diff --git a/tests/client/parse-cell.test.ts b/tests/client/parse-cell.test.ts index 667a700..7318416 100644 --- a/tests/client/parse-cell.test.ts +++ b/tests/client/parse-cell.test.ts @@ -41,7 +41,9 @@ test('Cell hex in request body test', async () => { const cell = Cell.fromBase64(cellBase64); await sendBlockchainMessage({ - boc: cell + body: { + boc: cell + } }); expect(fetchSpy).toHaveBeenCalledWith( From 5abc4c6680e33c5bdd0c7f8cba7d3506e6b4afc9 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Thu, 13 Nov 2025 19:22:52 +0400 Subject: [PATCH 12/27] chore: bump version to 0.5.0-alpha.2 in package.json and client package.json --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c9e8c47..d816cba 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.1", + "version": "0.5.0-alpha.2", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 23292c4..854bed2 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.1", + "version": "0.5.0-alpha.2", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 6410c56..7972adc 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3678,7 +3678,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.1` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.2` }; const preparedApiConfig = { From 7f3fe05645c4d4619572781fdf641925d8f5ce42 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Fri, 14 Nov 2025 00:36:56 +0400 Subject: [PATCH 13/27] refactor: update address format to maybe-address in API schema and client interfaces - Changed the format of address fields to 'maybe-address' across various components in the API schema and client interfaces, allowing for null values. - Updated related parsing logic to handle 'maybe-address' format, ensuring compatibility with empty strings. - Enhanced tests to validate the new 'maybe-address' handling, including scenarios for valid addresses and empty strings. --- packages/client/src/api.yml | 7 +-- packages/client/src/client.ts | 43 ++++++++++------ packages/client/src/generate.ts | 3 +- packages/client/src/templates/errors.ejs | 4 +- packages/client/src/templates/utils.ejs | 12 +++++ tests/client/__mock__/address.ts | 64 ++++++++++++++++++++++++ tests/client/parse-address.test.ts | 38 +++++++++++++- 7 files changed, 150 insertions(+), 21 deletions(-) diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index 027f9bd..93aa773 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -3478,7 +3478,7 @@ components: properties: address: type: string - format: address + format: maybe-address example: 0:10C1073837B93FDAAD594284CE8B8EFF7B9CF25427440EB2FC682762E1471365 name: type: string @@ -6370,6 +6370,7 @@ components: $ref: '#/components/schemas/AccountAddress' nft: type: string + format: maybe-address example: '' comment: type: string @@ -6969,7 +6970,7 @@ components: $ref: '#/components/schemas/Metadata' address: type: string - format: address + format: maybe-address example: 0:dea8f638b789172ce36d10a20318125e52c649aa84893cd77858224fe2b9b0ee beneficiary: $ref: '#/components/schemas/AccountAddress' @@ -7080,7 +7081,7 @@ components: $ref: '#/components/schemas/WalletDNS' next_resolver: type: string - format: address + format: maybe-address example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf sites: type: array diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 7972adc..a175597 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -16,10 +16,10 @@ export interface Error { export interface AccountAddress { /** - * @format address + * @format maybe-address * @example "0:10C1073837B93FDAAD594284CE8B8EFF7B9CF25427440EB2FC682762E1471365" */ - address: Address; + address: Address | null; /** * Display name. Data collected from different sources like moderation lists, dns, collections names and over. * @example "Ton foundation" @@ -1952,8 +1952,11 @@ export interface SetSignatureAllowedAction { export interface NftItemTransferAction { sender?: AccountAddress; recipient?: AccountAddress; - /** @example "" */ - nft: string; + /** + * @format maybe-address + * @example "" + */ + nft: Address | null; /** * @example "Hi! This is your salary. * From accounting with love." @@ -2340,10 +2343,10 @@ export interface Subscription { nextChargeAt: number; metadata: Metadata; /** - * @format address + * @format maybe-address * @example "0:dea8f638b789172ce36d10a20318125e52c649aa84893cd77858224fe2b9b0ee" */ - address?: Address; + address?: Address | null; beneficiary?: AccountAddress; admin?: AccountAddress; } @@ -2415,10 +2418,10 @@ export interface DomainInfo { export interface DnsRecord { wallet?: WalletDNS; /** - * @format address + * @format maybe-address * @example "0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" */ - nextResolver?: Address; + nextResolver?: Address | null; sites: string[]; /** * tonstorage bag id @@ -3872,7 +3875,7 @@ const components = { type: 'object', required: ['address', 'is_scam', 'is_wallet'], properties: { - address: { type: 'string', format: 'address' }, + address: { type: 'string', format: 'maybe-address' }, name: { type: 'string' }, is_scam: { type: 'boolean' }, icon: { type: 'string' }, @@ -5451,7 +5454,7 @@ const components = { properties: { sender: { $ref: '#/components/schemas/AccountAddress' }, recipient: { $ref: '#/components/schemas/AccountAddress' }, - nft: { type: 'string' }, + nft: { type: 'string', format: 'maybe-address' }, comment: { type: 'string' }, encrypted_comment: { $ref: '#/components/schemas/EncryptedComment' }, payload: { type: 'string' }, @@ -5752,7 +5755,7 @@ const components = { wallet: { $ref: '#/components/schemas/AccountAddress' }, next_charge_at: { type: 'integer', format: 'int64' }, metadata: { $ref: '#/components/schemas/Metadata' }, - address: { type: 'string', format: 'address' }, + address: { type: 'string', format: 'maybe-address' }, beneficiary: { $ref: '#/components/schemas/AccountAddress' }, admin: { $ref: '#/components/schemas/AccountAddress' } } @@ -5816,7 +5819,7 @@ const components = { required: ['sites'], properties: { wallet: { $ref: '#/components/schemas/WalletDNS' }, - next_resolver: { type: 'string', format: 'address' }, + next_resolver: { type: 'string', format: 'maybe-address' }, sites: { type: 'array', items: { type: 'string' } }, storage: { type: 'string' } } @@ -6444,11 +6447,11 @@ export class TonApiNetworkError extends TonApiErrorAbstract { */ export class TonApiParsingError extends TonApiErrorAbstract { readonly type = 'parsing_error' as const; - readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown'; + readonly parsingType: 'Address' | 'MaybeAddress' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown'; readonly response: unknown; constructor( - parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown', + parsingType: 'Address' | 'MaybeAddress' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown', message: string, cause: unknown, response: unknown @@ -6658,6 +6661,18 @@ function prepareResponseData(obj: any, orSchema?: any, originalResponse: unkn } } + if (schema.format === 'maybe-address') { + if (!obj || obj === '') { + return null as U; + } + try { + return Address.parse(obj as string) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('MaybeAddress', msg, e, originalResponse); + } + } + if (schema.format === 'cell') { return obj && (cellParse(obj as string, originalResponse) as U); } diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index afc2a18..dd65db7 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -201,7 +201,8 @@ const generateApiParams: GenerateApiParams = { cell: 'Cell', bigint: 'bigint', 'cell-base64': 'Cell', - 'tuple-item': 'TupleItem' + 'tuple-item': 'TupleItem', + 'maybe-address': 'Address | null' } }), hooks: { diff --git a/packages/client/src/templates/errors.ejs b/packages/client/src/templates/errors.ejs index 2a54dea..b431297 100644 --- a/packages/client/src/templates/errors.ejs +++ b/packages/client/src/templates/errors.ejs @@ -87,10 +87,10 @@ export class TonApiNetworkError extends TonApiErrorAbstract { */ export class TonApiParsingError extends TonApiErrorAbstract { readonly type = 'parsing_error' as const; - readonly parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown'; + readonly parsingType: 'Address' | 'MaybeAddress' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown'; readonly response: unknown; - constructor(parsingType: 'Address' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown', message: string, cause: unknown, response: unknown) { + constructor(parsingType: 'Address' | 'MaybeAddress' | 'Cell' | 'BigInt' | 'TupleItem' | 'Unknown', message: string, cause: unknown, response: unknown) { const formattedMessage = `SDK parsing error [${parsingType}]: ${message}`; super(formattedMessage, cause); this.name = 'TonApiParsingError'; diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index bc1d546..4a00285 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -132,6 +132,18 @@ function prepareResponseData(obj: any, orSchema?: any, originalResponse: unkn } } + if (schema.format === "maybe-address") { + if (!obj || obj === '') { + return null as U; + } + try { + return Address.parse(obj as string) as U; + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiParsingError('MaybeAddress', msg, e, originalResponse); + } + } + if (schema.format === "cell") { return obj && (cellParse(obj as string, originalResponse) as U); } diff --git a/tests/client/__mock__/address.ts b/tests/client/__mock__/address.ts index d30a59e..c8c6e50 100644 --- a/tests/client/__mock__/address.ts +++ b/tests/client/__mock__/address.ts @@ -120,3 +120,67 @@ export const getAccounts = { } ] }; + +export const getAccountEvent = { + event_id: 'test-event-id', + account: { + address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168', + is_scam: false, + is_wallet: true + }, + timestamp: 1717957542, + actions: [ + { + type: 'NftItemTransfer', + status: 'ok', + NftItemTransfer: { + nft: '0:7c9fc62291740a143086c807fe322accfd12737b3c2243676228176707c7ce40', + sender: { + address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168', + is_scam: false, + is_wallet: true + }, + recipient: { + address: '0:bada76699b7e8417300355f5c355dff83a96c5c9cd43df0dd9bc23c72e78bc0e', + is_scam: false, + is_wallet: true + } + } + } + ], + is_scam: false, + lt: 42259259000008, + in_progress: false +}; + +export const getAccountEventWithEmptyNft = { + event_id: 'test-event-id-empty', + account: { + address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168', + is_scam: false, + is_wallet: true + }, + timestamp: 1717957542, + actions: [ + { + type: 'NftItemTransfer', + status: 'ok', + NftItemTransfer: { + nft: '', + sender: { + address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168', + is_scam: false, + is_wallet: true + }, + recipient: { + address: '0:bada76699b7e8417300355f5c355dff83a96c5c9cd43df0dd9bc23c72e78bc0e', + is_scam: false, + is_wallet: true + } + } + } + ], + is_scam: false, + lt: 42259259000009, + in_progress: false +}; diff --git a/tests/client/parse-address.test.ts b/tests/client/parse-address.test.ts index 6443db3..949889c 100644 --- a/tests/client/parse-address.test.ts +++ b/tests/client/parse-address.test.ts @@ -1,6 +1,11 @@ import { Address } from '@ton/core'; import { ta } from './utils/client'; -import { getAccounts, getBlockchainRawAccount } from './__mock__/address'; +import { + getAccounts, + getBlockchainRawAccount, + getAccountEvent, + getAccountEventWithEmptyNft +} from './__mock__/address'; import { vi, test, expect, afterEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; @@ -45,3 +50,34 @@ test('Address in request body test', async () => { }) ); }); + +test('MaybeAddress with valid address', async () => { + mockFetch(getAccountEvent); + + const data = await ta.getAccountEvent( + Address.parse('0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'), + 'test-event-id' + ); + + expect(data).toBeDefined(); + expect(data.actions[0]).toBeDefined(); + const nftTransfer = data.actions[0]?.NftItemTransfer; + expect(nftTransfer).toBeDefined(); + expect(nftTransfer?.nft).toBeInstanceOf(Address); + expect(Address.isAddress(nftTransfer?.nft)).toBe(true); +}); + +test('MaybeAddress with empty string', async () => { + mockFetch(getAccountEventWithEmptyNft); + + const data = await ta.getAccountEvent( + Address.parse('0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'), + 'test-event-id-empty' + ); + + expect(data).toBeDefined(); + expect(data.actions[0]).toBeDefined(); + const nftTransfer = data.actions[0]?.NftItemTransfer; + expect(nftTransfer).toBeDefined(); + expect(nftTransfer?.nft).toBeNull(); +}); From bb6cccc40a1362951c5ad62c27ad04029d566b8a Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Fri, 14 Nov 2025 00:37:46 +0400 Subject: [PATCH 14/27] chore: bump version to 0.5.0-alpha.3 in package.json and client package.json --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d816cba..2bac94c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.2", + "version": "0.5.0-alpha.3", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 854bed2..4e23836 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.2", + "version": "0.5.0-alpha.3", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index a175597..f15ee4d 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3681,7 +3681,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.2` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.3` }; const preparedApiConfig = { From d7f704c2cc81f180c94d4e5c25c1cd35fba21792 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Fri, 14 Nov 2025 13:33:52 +0400 Subject: [PATCH 15/27] feat: add typed error handling and address string support --- package.json | 2 +- packages/client/README.md | 490 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 3979 ++++++++++++----- .../client/src/templates/procedure-call.ejs | 54 +- packages/client/src/templates/utils.ejs | 39 +- tests/client/errors.test.ts | 170 +- tests/client/type-tests.test.ts | 270 ++ tsconfig.base.json | 13 +- tsconfig.json | 2 + 10 files changed, 3835 insertions(+), 1186 deletions(-) create mode 100644 tests/client/type-tests.test.ts diff --git a/package.json b/package.json index 2bac94c..644471b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.3", + "version": "0.5.0-alpha.4", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/README.md b/packages/client/README.md index 9d23e92..c00cd1b 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -6,17 +6,19 @@ ## Documentation -For a detailed view of all methods and endpoints in a Swagger format, refer to the [Swagger documentation](https://tonapi.io/api-v2) -For detailed API information and endpoint descriptions, please refer to the [official documentation](https://docs.tonconsole.com/tonapi/rest-api) or check the [Swagger UI](https://tonapi.io/api-v2) for an interactive method list. - -For usage examples, check the [TonAPI Cookbook](https://docs.tonconsole.com/tonapi/cookbook). +For detailed API information and endpoint descriptions, please refer to: +- [Official TonAPI Documentation](https://docs.tonconsole.com/tonapi/rest-api) +- [Swagger UI](https://tonapi.io/api-v2) - Interactive API explorer +- [TonAPI Cookbook](https://docs.tonconsole.com/tonapi/cookbook) - Usage examples and recipes ## Features - Full coverage of tonapi.io endpoints - Type-safe interactions with the API - Seamless integration with `@ton/core` - +- Tree-shakeable imports for optimal bundle size +- Structured error handling with `{ data, error }` pattern +- Support for multiple client instances Additionally, [`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/ton-adapter) enables users to work with contracts written for `@ton/ton` through `@ton-api/client`, ensuring seamless integration while maintaining their existing code structure. @@ -25,98 +27,494 @@ Additionally, [`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/to To use this SDK, you need to: 1. Set up an account at [tonconsole.com](https://tonconsole.com/) -2. Obtain an API key for authentication +2. Obtain an API key for authentication (optional for public endpoints, required for higher rate limits) ## Installation Install the package and its peer dependencies using npm, yarn, or pnpm: ```sh -npm install @ton-api/client @ton/core -# or -yarn add @ton-api/client @ton/core -# or -pnpm add @ton-api/client @ton/core +npm install @ton-api/client @ton/core buffer +``` +> Note: `@ton/core` is a peer dependency and needs to be installed separately. + +**Browser polyfill** +```js +// Add before using library +require("buffer"); ``` +> **Buffer** polyfill is also required for work `@ton/core` on frontend projects. + ## Quick Start -Here's a basic example to get you started: +Initialize the client and start making requests: -```javascript -import { TonApiClient } from '@ton-api/client'; +```typescript +import { initClient, getAccount } from '@ton-api/client'; import { Address } from '@ton/core'; -// Initialize the TonApi -const ta = new TonApiClient({ +// Initialize the default client +initClient({ baseUrl: 'https://tonapi.io', - apiKey: 'YOUR_API_KEY' + apiKey: 'YOUR_API_KEY' // Optional, but recommended for production +}); + +// Make requests using { data, error } pattern +const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); +const { data, error } = await getAccount({ + path: { accountId: address } }); -// Use the API -async function fetchAccountEvents() { - const address = Address.parse('YOUR_ADDRESS_HERE'); - const events = await ta.accounts.getAccountEvents(address, { limit: 50 }) - - console.log('Account events:', events) +if (error) { + console.error('Error:', error.message); + return; } -fetchAccountEvents(); +console.log('Account balance:', data.balance); ``` -## Documentation +## Usage Examples -For detailed API information and endpoint descriptions, please refer to the [official documentation](https://docs.tonconsole.com/tonapi). +### Fetching Account Information -## Usage Examples +```typescript +import { initClient, getAccount } from '@ton-api/client'; +import { Address } from '@ton/core'; + +initClient({ baseUrl: 'https://tonapi.io' }); + +const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); +const { data, error } = await getAccount({ + path: { accountId: address } +}); + +if (error) { + console.error('Failed to fetch account:', error.message); + return; +} + +console.log('Address:', data.address); +console.log('Balance:', data.balance); +console.log('Is active:', data.status === 'active'); +``` + +### Working with Multiple Accounts + +```typescript +import { getAccounts } from '@ton-api/client'; +import { Address } from '@ton/core'; + +const addresses = [ + Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'), + Address.parse('EQCA14o1-VWhS2efqoh_9M1b_A9DtKTuoqfmkn83AbJzwnPi') +]; + +// Pass addresses in body +const { data, error } = await getAccounts({ + body: { accountIds: addresses } +}); + +if (error) { + console.error('Error:', error.message); + return; +} + +console.log('Accounts:', data.accounts); +``` + +### Using Query Parameters + +```typescript +import { getAccounts } from '@ton-api/client'; + +const addresses = [ + Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin') +]; + +// Pass both body and query parameters +const { data, error } = await getAccounts({ + body: { accountIds: addresses }, + query: { currency: 'usd' } +}); + +if (error) { + console.error('Error:', error.message); + return; +} + +console.log('Accounts with USD prices:', data.accounts); +``` ### Fetching NFT Collection -```javascript -const collectionAddress = Address.parse('COLLECTION_ADDRESS_HERE'); +```typescript +import { getNftCollection } from '@ton-api/client'; +import { Address } from '@ton/core'; + +const collectionAddress = Address.parse('EQCA14o1-VWhS2efqoh_9M1b_A9DtKTuoqfmkn83AbJzwnPi'); +const { data, error } = await getNftCollection({ + path: { accountId: collectionAddress } +}); + +if (error) { + console.error('Error:', error.message); + return; +} -ta.nft.getNftCollection(collectionAddress) - .then(collection => console.log('NFT Collection:', collection)) - .catch(error => console.error('Error fetching NFT collection:', error)); +console.log('Collection name:', data.metadata?.name); +console.log('Total items:', data.nextItemIndex); ``` ### Getting Jetton Information -```javascript -const jettonAddress = Address.parse('JETTON_ADDRESS_HERE'); +```typescript +import { getJettonInfo } from '@ton-api/client'; +import { Address } from '@ton/core'; + +const jettonAddress = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); +const { data, error } = await getJettonInfo({ + path: { accountId: jettonAddress } +}); + +if (error) { + console.error('Error:', error.message); + return; +} + +console.log('Jetton name:', data.metadata?.name); +console.log('Symbol:', data.metadata?.symbol); +console.log('Total supply:', data.totalSupply); +``` + +### Using Address as String + +You can pass addresses either as `Address` objects or as strings: + +```typescript +import { getAccount } from '@ton-api/client'; +import { Address } from '@ton/core'; + +// Using Address object +const addressObject = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); +const { data: data1 } = await getAccount({ + path: { accountId: addressObject } +}); + +// Using string directly +const { data: data2 } = await getAccount({ + path: { accountId: 'EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin' } +}); +``` + +## Error Handling + +By default, all methods return `{ data, error }` structure. This is the recommended way to handle errors: + +```typescript +import { getAccount } from '@ton-api/client'; +import { Address } from '@ton/core'; + +const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); +const { data, error } = await getAccount({ + path: { accountId: address } +}); + +if (error) { + // Handle error + console.error('Error:', error.message); + return; +} + +// TypeScript knows data is defined here +console.log('Balance:', data.balance); +``` + +### Error Types + +The SDK provides specific error types for different scenarios: + +```typescript +import { getAccount, TonApiHttpError } from '@ton-api/client'; + +const { data, error } = await getAccount({ + path: { accountId: address } +}); + +if (error instanceof TonApiHttpError) { + console.error('HTTP Error:', error.status); + console.error('Error code:', error.code); + console.error('Error message:', error.message); + console.error('Request URL:', error.url); +} + +if (error instanceof TonApiNetworkError) { + console.error('Network error:', error.message); + console.error('Original cause:', error.originalCause); +} +``` + +### Using `throwOnError` Option + +If you prefer exceptions instead of `{ data, error }`, use `throwOnError: true`: -ta.jettons.getJettonInfo(jettonAddress) - .then(jetton => console.log('Jetton Info:', jetton)) - .catch(error => console.error('Error fetching jetton info:', error)); +```typescript +import { getAccount } from '@ton-api/client'; + +// This will throw an exception on error instead of returning { data, error } +const data = await getAccount({ + path: { accountId: address }, + throwOnError: true +}).catch(error => { + console.error('Error:', error.message); + return null; +}); + +console.log('Balance:', data?.balance); ``` -### Send message to blockchain +## Sending Transactions -```javascript +```typescript +import { sendBlockchainMessage } from '@ton-api/client'; import { beginCell, external, storeMessage, Address } from '@ton/core'; -const accountAddress = Address.parse('JETTON_ADDRESS_HERE'); -const exampleMessage = beginCell() +const accountAddress = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + +// Create your message (example) +const messageBody = beginCell() .storeUint(0, 64) .endCell(); - const messageBoc = beginCell() .store( storeMessage( external({ - to: address, - body: exampleMessage + to: accountAddress, + body: messageBody }) ) ) .endCell(); -ta.blockchain.sendBlockchainMessage({ - boc: messageBoc +// Send the message +const { data, error } = await sendBlockchainMessage({ + body: { boc: messageBoc } +}); + +if (error) { + console.error('Failed to send message:', error.message); + return; +} + +console.log('Message sent successfully'); +``` + +## Using Multiple Clients + +You can use methods with different client instances by passing the `client` option: + +```typescript +import { initClient, getAccount, TonApiClient } from '@ton-api/client'; +import { Address } from '@ton/core'; + +// Initialize default client for mainnet +initClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'YOUR_API_KEY' +}); + +// Create a separate client for testnet +const testnetClient = new TonApiClient({ + baseUrl: 'https://testnet.tonapi.io', + apiKey: 'YOUR_API_KEY' +}); + +const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + +// Use default client (mainnet) +const { data: mainnetData } = await getAccount({ + path: { accountId: address } +}); + +// Use testnet client for specific call +const { data: testnetData } = await getAccount({ + client: testnetClient, + path: { accountId: address } +}); +``` + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +## Alternative: Instance API + +If you prefer object-oriented approach or need complete isolation between client instances, you can use the Instance API. Instance API uses positional parameters instead of options objects. + +```typescript +import { TonApiClient } from '@ton-api/client'; +import { Address } from '@ton/core'; + +// Create a client instance +const tonapi = new TonApiClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'YOUR_API_KEY' +}); + +// Use instance methods with positional parameters +const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); +const account = await tonapi.getAccount(address); + +console.log('Account balance:', account.balance); +``` + +### When to Use Instance API + +Use the Instance API when you need: + +- **Multiple clients with different configurations** + ```typescript + const mainnet = new TonApiClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'KEY1' + }); + const testnet = new TonApiClient({ + baseUrl: 'https://testnet.tonapi.io', + apiKey: 'KEY2' + }); + + const mainnetAccount = await mainnet.getAccount(address); + const testnetAccount = await testnet.getAccount(address); + ``` + +- **Dependency injection in large applications** + ```typescript + class AccountService { + constructor(private tonapi: TonApiClient) {} + + async getBalance(address: Address) { + const account = await this.tonapi.getAccount(address); + return account.balance; + } + } + + const service = new AccountService(tonapi); + ``` + +- **Complete state isolation** + ```typescript + // Each instance is completely independent + const client1 = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const client2 = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + ``` + +### Instance API Examples + +#### Fetching Accounts with Query Parameters + +```typescript +const tonapi = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + +const addresses = [ + Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'), + Address.parse('EQCA14o1-VWhS2efqoh_9M1b_A9DtKTuoqfmkn83AbJzwnPi') +]; + +// Parameters: data, query, params +const accounts = await tonapi.getAccounts( + { accountIds: addresses }, // data (body) + { currency: 'usd' } // query parameters +); + +console.log('Accounts:', accounts.accounts); +``` + +#### Executing Contract Methods + +```typescript +import { execGetMethodForBlockchainAccount } from '@ton-api/client'; + +const tonapi = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + +const jettonMaster = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); +const walletAddress = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + +const result = await tonapi.execGetMethodForBlockchainAccount( + jettonMaster, + 'get_wallet_address', + { args: [walletAddress.toRawString()] } +); + +console.log('Jetton wallet:', result.decoded.jetton_wallet_address); +``` + +### Error Handling with Instance API + +Instance API throws exceptions on errors, so use `.catch()` for error handling. + +**Advantage**: The Instance API provides **typed `.catch()`** - TypeScript knows the error type is `TonApiError`, not `unknown`! + +```typescript +const tonapi = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + +const account = await tonapi.getAccount(address) + .catch(error => { + // ✨ TypeScript knows error is TonApiError (not unknown)! + // You get autocomplete for error.message, error.type, etc. + + if (error instanceof TonApiHttpError) { + console.error('HTTP Error:', error.status, error.code); + } else if (error instanceof TonApiNetworkError) { + console.error('Network Error:', error.message); + } + return null; + }); + +if (account) { + console.log('Balance:', account.balance); +} +``` + +> **Note**: With the Advanced API using `throwOnError: true`, the `.catch()` error is `unknown` (standard Promise behavior). For typed error handling in `.catch()`, use the Instance API instead. + +## Advanced Features + +For more advanced use cases, check out the examples in our repository: + +- **[Transaction Emulation](https://github.com/tonkeeper/tonapi-js/blob/main/examples/emulate.ts)** - Emulate transactions before sending +- **[Gasless Transfers](https://github.com/tonkeeper/tonapi-js/blob/main/examples/gasless.ts)** - Send jettons without TON for gas +- **[Transaction Tracking](https://github.com/tonkeeper/tonapi-js/blob/main/examples/track-transaction.ts)** - Track transaction status by hash +- **[Sending TON](https://github.com/tonkeeper/tonapi-js/blob/main/examples/send-ton.ts)** - Complete example with wallet integration +- **[Sending Jettons](https://github.com/tonkeeper/tonapi-js/blob/main/examples/send-jetton.ts)** - Transfer jetton tokens + +## Working with Contracts + +For advanced contract interactions, use [`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/ton-adapter): + +```typescript +import { TonApiClient } from '@ton-api/client'; +import { ContractAdapter } from '@ton-api/ton-adapter'; +import { WalletContractV5R1 } from '@ton/ton'; + +const tonapi = new TonApiClient({ baseUrl: 'https://tonapi.io' }); +const adapter = new ContractAdapter(tonapi); + +const wallet = WalletContractV5R1.create({ + workchain: 0, + publicKey: keyPair.publicKey }); +const contract = adapter.open(wallet); + +const seqno = await contract.getSeqno(); ``` +## API Reference + +For a complete list of available methods and their parameters, refer to: + +- [Swagger UI](https://tonapi.io/api-v2) - Interactive API documentation +- [TonAPI Documentation](https://docs.tonconsole.com/tonapi) - Detailed guides and examples +- [GitHub Repository](https://github.com/tonkeeper/tonapi-js) - Source code and examples + ## License MIT diff --git a/packages/client/package.json b/packages/client/package.json index 4e23836..1bf06e4 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.3", + "version": "0.5.0-alpha.4", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index f15ee4d..ca54331 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3681,7 +3681,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.3` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.4` }; const preparedApiConfig = { @@ -6544,6 +6544,16 @@ export type TonApiError = type ComponentRef = keyof typeof components; +/** + * Custom Promise interface with typed catch method + * This allows TypeScript to infer the correct error type in .catch() handlers + */ +export interface TonApiPromise extends Promise { + catch( + onrejected?: ((reason: E) => TResult | PromiseLike) | null | undefined + ): Promise; +} + export type Result = { data: T; error: null } | { data: null; error: TonApiError }; /** @@ -6558,6 +6568,16 @@ export type MethodResult = ThrowOnError ? Promise : Promise>; +/** + * Sync version of MethodResult for use with async functions + * (async functions automatically wrap return type in Promise) + * When ThrowOnError is true, returns T but the Promise will reject with TonApiError + * When ThrowOnError is false, returns Result + */ +type MethodResultSync = ThrowOnError extends true + ? T + : Result; + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, match => match[1]?.toUpperCase() ?? ''); } @@ -6579,7 +6599,24 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } -async function prepareResponse(promise: Promise, orSchema?: any): Promise { +function addressToString(value: Address | string | undefined): string | undefined { + if (value === undefined) { + return undefined; + } + const addr = typeof value === 'string' ? Address.parse(value) : value; + return addr.toRawString(); +} + +/** + * Prepares and validates API response data + * @template U - The success response type + * @template E - The error type (defaults to TonApiError) + * @throws {E} Always throws error of type E on failure + */ +function prepareResponse( + promise: Promise, + orSchema?: any +): TonApiPromise { return promise .then(obj => { try { @@ -6637,7 +6674,7 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis } throw new TonApiUnknownError('Unknown error occurred', response); - }); + }) as TonApiPromise; } function prepareResponseData(obj: any, orSchema?: any, originalResponse: unknown = obj): U { @@ -6796,7 +6833,7 @@ function prepareRequestData(data: any, orSchema?: any): any { } else if (schema) { if (schema.type === 'string') { if (schema.format === 'address') { - return (data as Address).toRawString(); + return addressToString(data as Address | string); } if (schema.format === 'cell') { @@ -6870,15 +6907,22 @@ export class TonApiClient { * @name GetOpenapiJson * @request GET:/v2/openapi.json */ - async getOpenapiJson(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get the openapi.json file + * + * @tags Utilities + * @name GetOpenapiJson + * @request GET:/v2/openapi.json + */ + getOpenapiJson(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ path: `/v2/openapi.json`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, {}); + return prepareResponse(req, {}); } /** @@ -6888,14 +6932,21 @@ export class TonApiClient { * @name GetOpenapiYml * @request GET:/v2/openapi.yml */ - async getOpenapiYml(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get the openapi.yml file + * + * @tags Utilities + * @name GetOpenapiYml + * @request GET:/v2/openapi.yml + */ + getOpenapiYml(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ path: `/v2/openapi.yml`, method: 'GET', ...params }); - return prepareResponse(req); + return prepareResponse(req); } /** @@ -6905,15 +6956,24 @@ export class TonApiClient { * @name Status * @request GET:/v2/status */ - async status(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Status + * + * @tags Utilities + * @name Status + * @request GET:/v2/status + */ + status(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ path: `/v2/status`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/ServiceStatus' }); + return prepareResponse(req, { + $ref: '#/components/schemas/ServiceStatus' + }); } /** @@ -6923,16 +6983,26 @@ export class TonApiClient { * @name AddressParse * @request GET:/v2/address/{account_id}/parse */ - async addressParse(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description parse address and display in all formats + * + * @tags Utilities + * @name AddressParse + * @request GET:/v2/address/{account_id}/parse + */ + addressParse( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/address/${accountId}/parse`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['raw_form', 'bounceable', 'non_bounceable', 'given_type', 'test_only'], properties: { @@ -6960,7 +7030,14 @@ export class TonApiClient { * @name GetReducedBlockchainBlocks * @request GET:/v2/blockchain/reduced/blocks */ - async getReducedBlockchainBlocks( + /** + * @description Get reduced blockchain blocks data + * + * @tags Blockchain + * @name GetReducedBlockchainBlocks + * @request GET:/v2/blockchain/reduced/blocks + */ + getReducedBlockchainBlocks( query: { /** @format int64 */ from: number; @@ -6968,8 +7045,8 @@ export class TonApiClient { to: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/reduced/blocks`, method: 'GET', query: query, @@ -6977,7 +7054,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/ReducedBlocks' }); } @@ -6989,15 +7066,25 @@ export class TonApiClient { * @name GetBlockchainBlock * @request GET:/v2/blockchain/blocks/{block_id} */ - async getBlockchainBlock(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get blockchain block data + * + * @tags Blockchain + * @name GetBlockchainBlock + * @request GET:/v2/blockchain/blocks/{block_id} + */ + getBlockchainBlock( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/blocks/${blockId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainBlock' }); } @@ -7009,14 +7096,24 @@ export class TonApiClient { * @name DownloadBlockchainBlockBoc * @request GET:/v2/blockchain/blocks/{block_id}/boc */ - async downloadBlockchainBlockBoc(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Download blockchain block BOC + * + * @tags Blockchain + * @name DownloadBlockchainBlockBoc + * @request GET:/v2/blockchain/blocks/{block_id}/boc + */ + downloadBlockchainBlockBoc( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/blocks/${blockId}/boc`, method: 'GET', ...params }); - return prepareResponse(req); + return prepareResponse(req); } /** @@ -7026,15 +7123,25 @@ export class TonApiClient { * @name GetBlockchainMasterchainShards * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards */ - async getBlockchainMasterchainShards(masterchainSeqno: number, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get blockchain block shards + * + * @tags Blockchain + * @name GetBlockchainMasterchainShards + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/shards + */ + getBlockchainMasterchainShards( + masterchainSeqno: number, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/masterchain/${masterchainSeqno}/shards`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainBlockShards' }); } @@ -7046,15 +7153,25 @@ export class TonApiClient { * @name GetBlockchainMasterchainBlocks * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks */ - async getBlockchainMasterchainBlocks(masterchainSeqno: number, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get all blocks in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. + * + * @tags Blockchain + * @name GetBlockchainMasterchainBlocks + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks + */ + getBlockchainMasterchainBlocks( + masterchainSeqno: number, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/masterchain/${masterchainSeqno}/blocks`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainBlocks' }); } @@ -7066,18 +7183,25 @@ export class TonApiClient { * @name GetBlockchainMasterchainTransactions * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions */ - async getBlockchainMasterchainTransactions( + /** + * @description Get all transactions in all shards and workchains between target and previous masterchain block according to shards last blocks snapshot in masterchain. We don't recommend to build your app around this method because it has problem with scalability and will work very slow in the future. + * + * @tags Blockchain + * @name GetBlockchainMasterchainTransactions + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions + */ + getBlockchainMasterchainTransactions( masterchainSeqno: number, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/masterchain/${masterchainSeqno}/transactions`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Transactions' }); } @@ -7089,15 +7213,25 @@ export class TonApiClient { * @name GetBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config */ - async getBlockchainConfigFromBlock(masterchainSeqno: number, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get blockchain config from a specific block, if present. + * + * @tags Blockchain + * @name GetBlockchainConfigFromBlock + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config + */ + getBlockchainConfigFromBlock( + masterchainSeqno: number, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/masterchain/${masterchainSeqno}/config`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainConfig' }); } @@ -7109,15 +7243,25 @@ export class TonApiClient { * @name GetRawBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw */ - async getRawBlockchainConfigFromBlock(masterchainSeqno: number, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw blockchain config from a specific block, if present. + * + * @tags Blockchain + * @name GetRawBlockchainConfigFromBlock + * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config/raw + */ + getRawBlockchainConfigFromBlock( + masterchainSeqno: number, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/masterchain/${masterchainSeqno}/config/raw`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/RawBlockchainConfig' }); } @@ -7129,15 +7273,25 @@ export class TonApiClient { * @name GetBlockchainBlockTransactions * @request GET:/v2/blockchain/blocks/{block_id}/transactions */ - async getBlockchainBlockTransactions(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get transactions from block + * + * @tags Blockchain + * @name GetBlockchainBlockTransactions + * @request GET:/v2/blockchain/blocks/{block_id}/transactions + */ + getBlockchainBlockTransactions( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/blocks/${blockId}/transactions`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Transactions' }); } @@ -7149,15 +7303,25 @@ export class TonApiClient { * @name GetBlockchainTransaction * @request GET:/v2/blockchain/transactions/{transaction_id} */ - async getBlockchainTransaction(transactionId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get transaction data + * + * @tags Blockchain + * @name GetBlockchainTransaction + * @request GET:/v2/blockchain/transactions/{transaction_id} + */ + getBlockchainTransaction( + transactionId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/transactions/${transactionId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Transaction' }); } @@ -7169,15 +7333,25 @@ export class TonApiClient { * @name GetBlockchainTransactionByMessageHash * @request GET:/v2/blockchain/messages/{msg_id}/transaction */ - async getBlockchainTransactionByMessageHash(msgId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get transaction data by message hash + * + * @tags Blockchain + * @name GetBlockchainTransactionByMessageHash + * @request GET:/v2/blockchain/messages/{msg_id}/transaction + */ + getBlockchainTransactionByMessageHash( + msgId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/messages/${msgId}/transaction`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Transaction' }); } @@ -7189,15 +7363,24 @@ export class TonApiClient { * @name GetBlockchainValidators * @request GET:/v2/blockchain/validators */ - async getBlockchainValidators(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get blockchain validators + * + * @tags Blockchain + * @name GetBlockchainValidators + * @request GET:/v2/blockchain/validators + */ + getBlockchainValidators( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/validators`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Validators' }); } @@ -7209,15 +7392,24 @@ export class TonApiClient { * @name GetBlockchainMasterchainHead * @request GET:/v2/blockchain/masterchain-head */ - async getBlockchainMasterchainHead(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get last known masterchain block + * + * @tags Blockchain + * @name GetBlockchainMasterchainHead + * @request GET:/v2/blockchain/masterchain-head + */ + getBlockchainMasterchainHead( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/masterchain-head`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainBlock' }); } @@ -7229,16 +7421,26 @@ export class TonApiClient { * @name GetBlockchainRawAccount * @request GET:/v2/blockchain/accounts/{account_id} */ - async getBlockchainRawAccount(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get low-level information about an account taken directly from the blockchain. + * + * @tags Blockchain + * @name GetBlockchainRawAccount + * @request GET:/v2/blockchain/accounts/{account_id} + */ + getBlockchainRawAccount( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/blockchain/accounts/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainRawAccount' }); } @@ -7250,8 +7452,15 @@ export class TonApiClient { * @name GetBlockchainAccountTransactions * @request GET:/v2/blockchain/accounts/{account_id}/transactions */ - async getBlockchainAccountTransactions( - accountId_Address: Address, + /** + * @description Get account transactions + * + * @tags Blockchain + * @name GetBlockchainAccountTransactions + * @request GET:/v2/blockchain/accounts/{account_id}/transactions + */ + getBlockchainAccountTransactions( + accountId_Address: Address | string, query?: { /** * omit this parameter to get last transactions @@ -7280,9 +7489,9 @@ export class TonApiClient { sort_order?: 'desc' | 'asc'; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/blockchain/accounts/${accountId}/transactions`, method: 'GET', query: query, @@ -7290,7 +7499,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Transactions' }); } @@ -7302,8 +7511,15 @@ export class TonApiClient { * @name ExecGetMethodForBlockchainAccount * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ - async execGetMethodForBlockchainAccount( - accountId_Address: Address, + /** + * @description Execute get method for account + * + * @tags Blockchain + * @name ExecGetMethodForBlockchainAccount + * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} + */ + execGetMethodForBlockchainAccount( + accountId_Address: Address | string, methodName: string, query?: { /** @@ -7320,9 +7536,9 @@ export class TonApiClient { args?: string[]; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, method: 'GET', query: query, @@ -7330,7 +7546,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/MethodExecutionResult' }); } @@ -7342,16 +7558,23 @@ export class TonApiClient { * @name ExecGetMethodWithBodyForBlockchainAccount * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ - async execGetMethodWithBodyForBlockchainAccount( - accountId_Address: Address, + /** + * @description Execute get method for account + * + * @tags Blockchain + * @name ExecGetMethodWithBodyForBlockchainAccount + * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} + */ + execGetMethodWithBodyForBlockchainAccount( + accountId_Address: Address | string, methodName: string, data: { args: ExecGetMethodArg[]; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/blockchain/accounts/${accountId}/methods/${methodName}`, method: 'POST', body: prepareRequestData(data, { @@ -7368,7 +7591,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/MethodExecutionResult' }); } @@ -7380,7 +7603,14 @@ export class TonApiClient { * @name SendBlockchainMessage * @request POST:/v2/blockchain/message */ - async sendBlockchainMessage( + /** + * @description Send message to blockchain + * + * @tags Blockchain + * @name SendBlockchainMessage + * @request POST:/v2/blockchain/message + */ + sendBlockchainMessage( data: { /** @format cell */ boc?: Cell; @@ -7389,8 +7619,8 @@ export class TonApiClient { meta?: Record; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/message`, method: 'POST', body: prepareRequestData(data, { @@ -7408,7 +7638,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req); + return prepareResponse(req); } /** @@ -7418,15 +7648,24 @@ export class TonApiClient { * @name GetBlockchainConfig * @request GET:/v2/blockchain/config */ - async getBlockchainConfig(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get blockchain config + * + * @tags Blockchain + * @name GetBlockchainConfig + * @request GET:/v2/blockchain/config + */ + getBlockchainConfig( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/config`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainConfig' }); } @@ -7438,15 +7677,24 @@ export class TonApiClient { * @name GetRawBlockchainConfig * @request GET:/v2/blockchain/config/raw */ - async getRawBlockchainConfig(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw blockchain config + * + * @tags Blockchain + * @name GetRawBlockchainConfig + * @request GET:/v2/blockchain/config/raw + */ + getRawBlockchainConfig( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/config/raw`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/RawBlockchainConfig' }); } @@ -7458,16 +7706,26 @@ export class TonApiClient { * @name BlockchainAccountInspect * @request GET:/v2/blockchain/accounts/{account_id}/inspect */ - async blockchainAccountInspect(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Blockchain account inspect + * + * @tags Blockchain + * @name BlockchainAccountInspect + * @request GET:/v2/blockchain/accounts/{account_id}/inspect + */ + blockchainAccountInspect( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/blockchain/accounts/${accountId}/inspect`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainAccountInspect' }); } @@ -7479,15 +7737,25 @@ export class TonApiClient { * @name GetLibraryByHash * @request GET:/v2/blockchain/libraries/{hash} */ - async getLibraryByHash(hash: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get library cell + * + * @tags Blockchain + * @name GetLibraryByHash + * @request GET:/v2/blockchain/libraries/{hash} + */ + getLibraryByHash( + hash: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/blockchain/libraries/${hash}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/BlockchainLibrary' }); } @@ -7499,7 +7767,14 @@ export class TonApiClient { * @name GetAccounts * @request POST:/v2/accounts/_bulk */ - async getAccounts( + /** + * @description Get human-friendly information about several accounts without low-level details. + * + * @tags Accounts + * @name GetAccounts + * @request POST:/v2/accounts/_bulk + */ + getAccounts( data: { accountIds: Address[]; }, @@ -7508,8 +7783,8 @@ export class TonApiClient { currency?: string; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/accounts/_bulk`, method: 'POST', query: query, @@ -7524,7 +7799,9 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Accounts' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Accounts' + }); } /** @@ -7534,16 +7811,28 @@ export class TonApiClient { * @name GetAccount * @request GET:/v2/accounts/{account_id} */ - async getAccount(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get human-friendly information about an account without low-level details. + * + * @tags Accounts + * @name GetAccount + * @request GET:/v2/accounts/{account_id} + */ + getAccount( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Account' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Account' + }); } /** @@ -7553,16 +7842,26 @@ export class TonApiClient { * @name AccountDnsBackResolve * @request GET:/v2/accounts/{account_id}/dns/backresolve */ - async accountDnsBackResolve(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get account's domains + * + * @tags Accounts + * @name AccountDnsBackResolve + * @request GET:/v2/accounts/{account_id}/dns/backresolve + */ + accountDnsBackResolve( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/dns/backresolve`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/DomainNames' }); } @@ -7574,12 +7873,19 @@ export class TonApiClient { * @name GetAccountJettonsBalances * @request GET:/v2/accounts/{account_id}/jettons */ - async getAccountJettonsBalances( - accountId_Address: Address, - query?: { - /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] + /** + * @description Get all Jettons balances by owner address + * + * @tags Accounts + * @name GetAccountJettonsBalances + * @request GET:/v2/accounts/{account_id}/jettons + */ + getAccountJettonsBalances( + accountId_Address: Address | string, + query?: { + /** + * accept ton and all possible fiat currencies, separated by commas + * @example ["ton","usd","rub"] */ currencies?: string[]; /** @@ -7589,9 +7895,9 @@ export class TonApiClient { supported_extensions?: string[]; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/jettons`, method: 'GET', query: query, @@ -7600,7 +7906,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/JettonsBalances' }); } @@ -7612,9 +7918,16 @@ export class TonApiClient { * @name GetAccountJettonBalance * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} */ - async getAccountJettonBalance( - accountId_Address: Address, - jettonId_Address: Address, + /** + * @description Get Jetton balance by owner address + * + * @tags Accounts + * @name GetAccountJettonBalance + * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id} + */ + getAccountJettonBalance( + accountId_Address: Address | string, + jettonId_Address: Address | string, query?: { /** * accept ton and all possible fiat currencies, separated by commas @@ -7628,10 +7941,10 @@ export class TonApiClient { supported_extensions?: string[]; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const jettonId = addressToString(jettonId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/jettons/${jettonId}`, method: 'GET', query: query, @@ -7640,7 +7953,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/JettonBalance' }); } @@ -7652,8 +7965,15 @@ export class TonApiClient { * @name GetAccountJettonsHistory * @request GET:/v2/accounts/{account_id}/jettons/history */ - async getAccountJettonsHistory( - accountId_Address: Address, + /** + * @description Get the transfer jettons history for account + * + * @tags Accounts + * @name GetAccountJettonsHistory + * @request GET:/v2/accounts/{account_id}/jettons/history + */ + getAccountJettonsHistory( + accountId_Address: Address | string, query: { /** * omit this parameter to get last events @@ -7669,9 +7989,9 @@ export class TonApiClient { limit: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/jettons/history`, method: 'GET', query: query, @@ -7679,7 +7999,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/JettonOperations' }); } @@ -7692,9 +8012,17 @@ export class TonApiClient { * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history * @deprecated */ - async getAccountJettonHistoryById( - accountId_Address: Address, - jettonId_Address: Address, + /** + * @description Please use `getJettonAccountHistoryByID`` instead + * + * @tags Accounts + * @name GetAccountJettonHistoryById + * @request GET:/v2/accounts/{account_id}/jettons/{jetton_id}/history + * @deprecated + */ + getAccountJettonHistoryById( + accountId_Address: Address | string, + jettonId_Address: Address | string, query: { /** * omit this parameter to get last events @@ -7722,10 +8050,10 @@ export class TonApiClient { end_date?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const jettonId = addressToString(jettonId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/jettons/${jettonId}/history`, method: 'GET', query: query, @@ -7733,7 +8061,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvents' }); } @@ -7745,8 +8073,15 @@ export class TonApiClient { * @name GetAccountNftItems * @request GET:/v2/accounts/{account_id}/nfts */ - async getAccountNftItems( - accountId_Address: Address, + /** + * @description Get all NFT items by owner address + * + * @tags Accounts + * @name GetAccountNftItems + * @request GET:/v2/accounts/{account_id}/nfts + */ + getAccountNftItems( + accountId_Address: Address | string, query?: { /** * nft collection @@ -7772,20 +8107,20 @@ export class TonApiClient { indirect_ownership?: boolean; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/nfts`, method: 'GET', query: query && { ...query, - collection: query.collection?.toRawString() + collection: addressToString(query.collection) }, format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftItems' }); } @@ -7797,8 +8132,15 @@ export class TonApiClient { * @name GetAccountEvents * @request GET:/v2/accounts/{account_id}/events */ - async getAccountEvents( - accountId_Address: Address, + /** + * @description Get events for an account. Each event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + * + * @tags Accounts + * @name GetAccountEvents + * @request GET:/v2/accounts/{account_id}/events + */ + getAccountEvents( + accountId_Address: Address | string, query: { /** * Show only events that are initiated by this account @@ -7836,9 +8178,9 @@ export class TonApiClient { end_date?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/events`, method: 'GET', query: query, @@ -7847,7 +8189,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvents' }); } @@ -7859,8 +8201,15 @@ export class TonApiClient { * @name GetAccountEvent * @request GET:/v2/accounts/{account_id}/events/{event_id} */ - async getAccountEvent( - accountId_Address: Address, + /** + * @description Get event for an account by event_id + * + * @tags Accounts + * @name GetAccountEvent + * @request GET:/v2/accounts/{account_id}/events/{event_id} + */ + getAccountEvent( + accountId_Address: Address | string, eventId: string, query?: { /** @@ -7870,9 +8219,9 @@ export class TonApiClient { subject_only?: boolean; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/events/${eventId}`, method: 'GET', query: query, @@ -7880,7 +8229,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvent' }); } @@ -7892,8 +8241,15 @@ export class TonApiClient { * @name GetAccountTraces * @request GET:/v2/accounts/{account_id}/traces */ - async getAccountTraces( - accountId_Address: Address, + /** + * @description Get traces for account + * + * @tags Accounts + * @name GetAccountTraces + * @request GET:/v2/accounts/{account_id}/traces + */ + getAccountTraces( + accountId_Address: Address | string, query?: { /** * omit this parameter to get last events @@ -7910,9 +8266,9 @@ export class TonApiClient { limit?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/traces`, method: 'GET', query: query, @@ -7920,7 +8276,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/TraceIDs' }); } @@ -7932,16 +8288,26 @@ export class TonApiClient { * @name GetAccountSubscriptions * @request GET:/v2/accounts/{account_id}/subscriptions */ - async getAccountSubscriptions(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get all subscriptions by wallet address + * + * @tags Accounts + * @name GetAccountSubscriptions + * @request GET:/v2/accounts/{account_id}/subscriptions + */ + getAccountSubscriptions( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/subscriptions`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Subscriptions' }); } @@ -7953,15 +8319,25 @@ export class TonApiClient { * @name ReindexAccount * @request POST:/v2/accounts/{account_id}/reindex */ - async reindexAccount(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Update internal cache for a particular account + * + * @tags Accounts + * @name ReindexAccount + * @request POST:/v2/accounts/{account_id}/reindex + */ + reindexAccount( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/reindex`, method: 'POST', ...params }); - return prepareResponse(req); + return prepareResponse(req); } /** @@ -7971,7 +8347,14 @@ export class TonApiClient { * @name SearchAccounts * @request GET:/v2/accounts/search */ - async searchAccounts( + /** + * @description Search by account domain name + * + * @tags Accounts + * @name SearchAccounts + * @request GET:/v2/accounts/search + */ + searchAccounts( query: { /** * @minLength 3 @@ -7980,8 +8363,8 @@ export class TonApiClient { name: string; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/accounts/search`, method: 'GET', query: query, @@ -7989,7 +8372,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/FoundAccounts' }); } @@ -8001,8 +8384,15 @@ export class TonApiClient { * @name GetAccountDnsExpiring * @request GET:/v2/accounts/{account_id}/dns/expiring */ - async getAccountDnsExpiring( - accountId_Address: Address, + /** + * @description Get expiring account .ton dns + * + * @tags Accounts + * @name GetAccountDnsExpiring + * @request GET:/v2/accounts/{account_id}/dns/expiring + */ + getAccountDnsExpiring( + accountId_Address: Address | string, query?: { /** * number of days before expiration @@ -8012,9 +8402,9 @@ export class TonApiClient { period?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/dns/expiring`, method: 'GET', query: query, @@ -8022,7 +8412,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/DnsExpiring' }); } @@ -8034,16 +8424,26 @@ export class TonApiClient { * @name GetAccountPublicKey * @request GET:/v2/accounts/{account_id}/publickey */ - async getAccountPublicKey(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get public key by account id + * + * @tags Accounts + * @name GetAccountPublicKey + * @request GET:/v2/accounts/{account_id}/publickey + */ + getAccountPublicKey( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/publickey`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['public_key'], properties: { public_key: { type: 'string' } } @@ -8057,16 +8457,26 @@ export class TonApiClient { * @name GetAccountMultisigs * @request GET:/v2/accounts/{account_id}/multisigs */ - async getAccountMultisigs(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get account's multisigs + * + * @tags Accounts + * @name GetAccountMultisigs + * @request GET:/v2/accounts/{account_id}/multisigs + */ + getAccountMultisigs( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/multisigs`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Multisigs' }); } @@ -8078,8 +8488,15 @@ export class TonApiClient { * @name GetAccountDiff * @request GET:/v2/accounts/{account_id}/diff */ - async getAccountDiff( - accountId_Address: Address, + /** + * @description Get account's balance change + * + * @tags Accounts + * @name GetAccountDiff + * @request GET:/v2/accounts/{account_id}/diff + */ + getAccountDiff( + accountId_Address: Address | string, query: { /** * @format int64 @@ -8095,9 +8512,9 @@ export class TonApiClient { end_date: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/diff`, method: 'GET', query: query, @@ -8105,7 +8522,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['balance_change'], properties: { balance_change: { type: 'integer', format: 'int64' } } @@ -8119,8 +8536,15 @@ export class TonApiClient { * @name GetAccountExtraCurrencyHistoryById * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history */ - async getAccountExtraCurrencyHistoryById( - accountId_Address: Address, + /** + * @description Get the transfer history of extra currencies for an account. + * + * @tags Accounts + * @name GetAccountExtraCurrencyHistoryById + * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history + */ + getAccountExtraCurrencyHistoryById( + accountId_Address: Address | string, id: number, query: { /** @@ -8149,9 +8573,9 @@ export class TonApiClient { end_date?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/extra-currency/${id}/history`, method: 'GET', query: query, @@ -8159,7 +8583,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvents' }); } @@ -8171,9 +8595,16 @@ export class TonApiClient { * @name GetJettonAccountHistoryById * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history */ - async getJettonAccountHistoryById( - accountId_Address: Address, - jettonId_Address: Address, + /** + * @description Get the transfer jetton history for account and jetton + * + * @tags Accounts + * @name GetJettonAccountHistoryById + * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history + */ + getJettonAccountHistoryById( + accountId_Address: Address | string, + jettonId_Address: Address | string, query: { /** * omit this parameter to get last events @@ -8201,10 +8632,10 @@ export class TonApiClient { end_date?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const jettonId = addressToString(jettonId_Address); + const req = this.http.request({ path: `/v2/jettons/${jettonId}/accounts/${accountId}/history`, method: 'GET', query: query, @@ -8212,7 +8643,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/JettonOperations' }); } @@ -8224,8 +8655,15 @@ export class TonApiClient { * @name GetAccountNftHistory * @request GET:/v2/accounts/{account_id}/nfts/history */ - async getAccountNftHistory( - accountId_Address: Address, + /** + * @description Get the transfer nft history + * + * @tags NFT + * @name GetAccountNftHistory + * @request GET:/v2/accounts/{account_id}/nfts/history + */ + getAccountNftHistory( + accountId_Address: Address | string, query: { /** * omit this parameter to get last events @@ -8241,9 +8679,9 @@ export class TonApiClient { limit: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/nfts/history`, method: 'GET', query: query, @@ -8251,7 +8689,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftOperations' }); } @@ -8263,7 +8701,14 @@ export class TonApiClient { * @name GetNftCollections * @request GET:/v2/nfts/collections */ - async getNftCollections( + /** + * @description Get NFT collections + * + * @tags NFT + * @name GetNftCollections + * @request GET:/v2/nfts/collections + */ + getNftCollections( query?: { /** * @format int32 @@ -8282,8 +8727,8 @@ export class TonApiClient { offset?: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/nfts/collections`, method: 'GET', query: query, @@ -8291,7 +8736,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftCollections' }); } @@ -8303,16 +8748,26 @@ export class TonApiClient { * @name GetNftCollection * @request GET:/v2/nfts/collections/{account_id} */ - async getNftCollection(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get NFT collection by collection address + * + * @tags NFT + * @name GetNftCollection + * @request GET:/v2/nfts/collections/{account_id} + */ + getNftCollection( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/nfts/collections/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftCollection' }); } @@ -8324,13 +8779,20 @@ export class TonApiClient { * @name GetNftCollectionItemsByAddresses * @request POST:/v2/nfts/collections/_bulk */ - async getNftCollectionItemsByAddresses( + /** + * @description Get NFT collection items by their addresses + * + * @tags NFT + * @name GetNftCollectionItemsByAddresses + * @request POST:/v2/nfts/collections/_bulk + */ + getNftCollectionItemsByAddresses( data: { accountIds: Address[]; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/nfts/collections/_bulk`, method: 'POST', body: prepareRequestData(data, { @@ -8344,7 +8806,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftCollections' }); } @@ -8356,8 +8818,15 @@ export class TonApiClient { * @name GetItemsFromCollection * @request GET:/v2/nfts/collections/{account_id}/items */ - async getItemsFromCollection( - accountId_Address: Address, + /** + * @description Get NFT items from collection by collection address + * + * @tags NFT + * @name GetItemsFromCollection + * @request GET:/v2/nfts/collections/{account_id}/items + */ + getItemsFromCollection( + accountId_Address: Address | string, query?: { /** * @min 1 @@ -8372,9 +8841,9 @@ export class TonApiClient { offset?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/nfts/collections/${accountId}/items`, method: 'GET', query: query, @@ -8382,7 +8851,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftItems' }); } @@ -8394,13 +8863,20 @@ export class TonApiClient { * @name GetNftItemsByAddresses * @request POST:/v2/nfts/_bulk */ - async getNftItemsByAddresses( + /** + * @description Get NFT items by their addresses + * + * @tags NFT + * @name GetNftItemsByAddresses + * @request POST:/v2/nfts/_bulk + */ + getNftItemsByAddresses( data: { accountIds: Address[]; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/nfts/_bulk`, method: 'POST', body: prepareRequestData(data, { @@ -8414,7 +8890,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftItems' }); } @@ -8426,16 +8902,26 @@ export class TonApiClient { * @name GetNftItemByAddress * @request GET:/v2/nfts/{account_id} */ - async getNftItemByAddress(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get NFT item by its address + * + * @tags NFT + * @name GetNftItemByAddress + * @request GET:/v2/nfts/{account_id} + */ + getNftItemByAddress( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/nfts/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/NftItem' }); } @@ -8448,8 +8934,16 @@ export class TonApiClient { * @request GET:/v2/nfts/{account_id}/history * @deprecated */ - async getNftHistoryById( - accountId_Address: Address, + /** + * @description Please use `getAccountNftHistory`` instead + * + * @tags NFT + * @name GetNftHistoryById + * @request GET:/v2/nfts/{account_id}/history + * @deprecated + */ + getNftHistoryById( + accountId_Address: Address | string, query: { /** * omit this parameter to get last events @@ -8477,9 +8971,9 @@ export class TonApiClient { end_date?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/nfts/${accountId}/history`, method: 'GET', query: query, @@ -8487,7 +8981,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvents' }); } @@ -8499,15 +8993,27 @@ export class TonApiClient { * @name GetDnsInfo * @request GET:/v2/dns/{domain_name} */ - async getDnsInfo(domainName: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get full information about domain name + * + * @tags DNS + * @name GetDnsInfo + * @request GET:/v2/dns/{domain_name} + */ + getDnsInfo( + domainName: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/dns/${domainName}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/DomainInfo' }); + return prepareResponse(req, { + $ref: '#/components/schemas/DomainInfo' + }); } /** @@ -8517,15 +9023,22 @@ export class TonApiClient { * @name DnsResolve * @request GET:/v2/dns/{domain_name}/resolve */ - async dnsResolve( + /** + * @description DNS resolve for domain name + * + * @tags DNS + * @name DnsResolve + * @request GET:/v2/dns/{domain_name}/resolve + */ + dnsResolve( domainName: string, query?: { /** @default false */ filter?: boolean; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/dns/${domainName}/resolve`, method: 'GET', query: query, @@ -8533,7 +9046,9 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/DnsRecord' }); + return prepareResponse(req, { + $ref: '#/components/schemas/DnsRecord' + }); } /** @@ -8543,15 +9058,27 @@ export class TonApiClient { * @name GetDomainBids * @request GET:/v2/dns/{domain_name}/bids */ - async getDomainBids(domainName: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get domain bids + * + * @tags DNS + * @name GetDomainBids + * @request GET:/v2/dns/{domain_name}/bids + */ + getDomainBids( + domainName: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/dns/${domainName}/bids`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/DomainBids' }); + return prepareResponse(req, { + $ref: '#/components/schemas/DomainBids' + }); } /** @@ -8561,7 +9088,14 @@ export class TonApiClient { * @name GetAllAuctions * @request GET:/v2/dns/auctions */ - async getAllAuctions( + /** + * @description Get all auctions + * + * @tags DNS + * @name GetAllAuctions + * @request GET:/v2/dns/auctions + */ + getAllAuctions( query?: { /** * domain filter for current auctions "ton" or "t.me" @@ -8570,8 +9104,8 @@ export class TonApiClient { tld?: string; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/dns/auctions`, method: 'GET', query: query, @@ -8579,7 +9113,9 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Auctions' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Auctions' + }); } /** @@ -8589,15 +9125,27 @@ export class TonApiClient { * @name GetTrace * @request GET:/v2/traces/{trace_id} */ - async getTrace(traceId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get the trace by trace ID or hash of any transaction in trace + * + * @tags Traces + * @name GetTrace + * @request GET:/v2/traces/{trace_id} + */ + getTrace( + traceId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/traces/${traceId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Trace' + }); } /** @@ -8607,15 +9155,27 @@ export class TonApiClient { * @name GetEvent * @request GET:/v2/events/{event_id} */ - async getEvent(eventId: string, params: RequestParams = {}) { - const req = this.http.request({ - path: `/v2/events/${eventId}`, - method: 'GET', + /** + * @description Get an event either by event ID or a hash of any transaction in a trace. An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + * + * @tags Events + * @name GetEvent + * @request GET:/v2/events/{event_id} + */ + getEvent( + eventId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ + path: `/v2/events/${eventId}`, + method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Event' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Event' + }); } /** @@ -8625,7 +9185,14 @@ export class TonApiClient { * @name GetJettons * @request GET:/v2/jettons */ - async getJettons( + /** + * @description Get a list of all indexed jetton masters in the blockchain. + * + * @tags Jettons + * @name GetJettons + * @request GET:/v2/jettons + */ + getJettons( query?: { /** * @format int32 @@ -8644,8 +9211,8 @@ export class TonApiClient { offset?: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/jettons`, method: 'GET', query: query, @@ -8653,7 +9220,9 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Jettons' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Jettons' + }); } /** @@ -8663,16 +9232,28 @@ export class TonApiClient { * @name GetJettonInfo * @request GET:/v2/jettons/{account_id} */ - async getJettonInfo(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get jetton metadata by jetton master address + * + * @tags Jettons + * @name GetJettonInfo + * @request GET:/v2/jettons/{account_id} + */ + getJettonInfo( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/jettons/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/JettonInfo' }); + return prepareResponse(req, { + $ref: '#/components/schemas/JettonInfo' + }); } /** @@ -8682,13 +9263,20 @@ export class TonApiClient { * @name GetJettonInfosByAddresses * @request POST:/v2/jettons/_bulk */ - async getJettonInfosByAddresses( + /** + * @description Get jetton metadata items by jetton master addresses + * + * @tags Jettons + * @name GetJettonInfosByAddresses + * @request POST:/v2/jettons/_bulk + */ + getJettonInfosByAddresses( data: { accountIds: Address[]; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/jettons/_bulk`, method: 'POST', body: prepareRequestData(data, { @@ -8702,7 +9290,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Jettons' }); } @@ -8714,8 +9302,15 @@ export class TonApiClient { * @name GetJettonHolders * @request GET:/v2/jettons/{account_id}/holders */ - async getJettonHolders( - accountId_Address: Address, + /** + * @description Get jetton's holders + * + * @tags Jettons + * @name GetJettonHolders + * @request GET:/v2/jettons/{account_id}/holders + */ + getJettonHolders( + accountId_Address: Address | string, query?: { /** * @min 1 @@ -8731,9 +9326,9 @@ export class TonApiClient { offset?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/jettons/${accountId}/holders`, method: 'GET', query: query, @@ -8741,7 +9336,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/JettonHolders' }); } @@ -8753,21 +9348,28 @@ export class TonApiClient { * @name GetJettonTransferPayload * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload */ - async getJettonTransferPayload( - accountId_Address: Address, - jettonId_Address: Address, + /** + * @description Get jetton's custom payload and state init required for transfer + * + * @tags Jettons + * @name GetJettonTransferPayload + * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload + */ + getJettonTransferPayload( + accountId_Address: Address | string, + jettonId_Address: Address | string, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const jettonId = jettonId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const jettonId = addressToString(jettonId_Address); + const req = this.http.request({ path: `/v2/jettons/${jettonId}/transfer/${accountId}/payload`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/JettonTransferPayload' }); } @@ -8779,15 +9381,27 @@ export class TonApiClient { * @name GetJettonsEvents * @request GET:/v2/events/{event_id}/jettons */ - async getJettonsEvents(eventId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get only jetton transfers in the event + * + * @tags Jettons + * @name GetJettonsEvents + * @request GET:/v2/events/{event_id}/jettons + */ + getJettonsEvents( + eventId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/events/${eventId}/jettons`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Event' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Event' + }); } /** @@ -8797,15 +9411,25 @@ export class TonApiClient { * @name GetExtraCurrencyInfo * @request GET:/v2/extra-currency/{id} */ - async getExtraCurrencyInfo(id: number, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get extra currency info by id + * + * @tags ExtraCurrency + * @name GetExtraCurrencyInfo + * @request GET:/v2/extra-currency/{id} + */ + getExtraCurrencyInfo( + id: number, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/extra-currency/${id}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/EcPreview' }); } @@ -8817,16 +9441,26 @@ export class TonApiClient { * @name GetAccountNominatorsPools * @request GET:/v2/staking/nominator/{account_id}/pools */ - async getAccountNominatorsPools(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description All pools where account participates + * + * @tags Staking + * @name GetAccountNominatorsPools + * @request GET:/v2/staking/nominator/{account_id}/pools + */ + getAccountNominatorsPools( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/staking/nominator/${accountId}/pools`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountStaking' }); } @@ -8838,16 +9472,26 @@ export class TonApiClient { * @name GetStakingPoolInfo * @request GET:/v2/staking/pool/{account_id} */ - async getStakingPoolInfo(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Stacking pool info + * + * @tags Staking + * @name GetStakingPoolInfo + * @request GET:/v2/staking/pool/{account_id} + */ + getStakingPoolInfo( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/staking/pool/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['implementation', 'pool'], properties: { @@ -8864,16 +9508,26 @@ export class TonApiClient { * @name GetStakingPoolHistory * @request GET:/v2/staking/pool/{account_id}/history */ - async getStakingPoolHistory(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Pool history + * + * @tags Staking + * @name GetStakingPoolHistory + * @request GET:/v2/staking/pool/{account_id}/history + */ + getStakingPoolHistory( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/staking/pool/${accountId}/history`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['apy'], properties: { @@ -8889,7 +9543,14 @@ export class TonApiClient { * @name GetStakingPools * @request GET:/v2/staking/pools */ - async getStakingPools( + /** + * @description All pools available in network + * + * @tags Staking + * @name GetStakingPools + * @request GET:/v2/staking/pools + */ + getStakingPools( query?: { /** * account ID @@ -8904,19 +9565,19 @@ export class TonApiClient { include_unverified?: boolean; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/staking/pools`, method: 'GET', query: query && { ...query, - available_for: query.available_for?.toRawString() + available_for: addressToString(query.available_for) }, format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['pools', 'implementations'], properties: { @@ -8936,15 +9597,24 @@ export class TonApiClient { * @name GetStorageProviders * @request GET:/v2/storage/providers */ - async getStorageProviders(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get TON storage providers deployed to the blockchain. + * + * @tags Storage + * @name GetStorageProviders + * @request GET:/v2/storage/providers + */ + getStorageProviders( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/storage/providers`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['providers'], properties: { @@ -8963,7 +9633,14 @@ export class TonApiClient { * @name GetRates * @request GET:/v2/rates */ - async getRates( + /** + * @description Get the token price in the chosen currency for display only. Don’t use this for financial transactions. + * + * @tags Rates + * @name GetRates + * @request GET:/v2/rates + */ + getRates( query: { /** * accept cryptocurrencies or jetton master addresses, separated by commas @@ -8979,8 +9656,8 @@ export class TonApiClient { currencies: string[]; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/rates`, method: 'GET', query: query, @@ -8989,7 +9666,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['rates'], properties: { @@ -9008,7 +9685,14 @@ export class TonApiClient { * @name GetChartRates * @request GET:/v2/rates/chart */ - async getChartRates( + /** + * @description Get chart by token + * + * @tags Rates + * @name GetChartRates + * @request GET:/v2/rates/chart + */ + getChartRates( query: { /** accept cryptocurrencies or jetton master addresses */ token: Address | string; @@ -9035,8 +9719,8 @@ export class TonApiClient { points_count?: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/rates/chart`, method: 'GET', query: query, @@ -9044,7 +9728,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['points'], properties: { @@ -9060,15 +9744,22 @@ export class TonApiClient { * @name GetMarketsRates * @request GET:/v2/rates/markets */ - async getMarketsRates(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get the TON price from markets + * + * @tags Rates + * @name GetMarketsRates + * @request GET:/v2/rates/markets + */ + getMarketsRates(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ path: `/v2/rates/markets`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['markets'], properties: { @@ -9084,15 +9775,24 @@ export class TonApiClient { * @name GetTonConnectPayload * @request GET:/v2/tonconnect/payload */ - async getTonConnectPayload(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get a payload for further token receipt + * + * @tags Connect + * @name GetTonConnectPayload + * @request GET:/v2/tonconnect/payload + */ + getTonConnectPayload( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/tonconnect/payload`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['payload'], properties: { payload: { type: 'string' } } @@ -9106,14 +9806,21 @@ export class TonApiClient { * @name GetAccountInfoByStateInit * @request POST:/v2/tonconnect/stateinit */ - async getAccountInfoByStateInit( + /** + * @description Get account info by state init + * + * @tags Connect + * @name GetAccountInfoByStateInit + * @request POST:/v2/tonconnect/stateinit + */ + getAccountInfoByStateInit( data: { /** @format cell-base64 */ stateInit: Cell; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/tonconnect/stateinit`, method: 'POST', body: prepareRequestData(data, { @@ -9125,7 +9832,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountInfoByStateInit' }); } @@ -9137,7 +9844,14 @@ export class TonApiClient { * @name TonConnectProof * @request POST:/v2/wallet/auth/proof */ - async tonConnectProof( + /** + * @description Account verification and token issuance + * + * @tags Wallet + * @name TonConnectProof + * @request POST:/v2/wallet/auth/proof + */ + tonConnectProof( data: { /** * @format address @@ -9163,8 +9877,8 @@ export class TonApiClient { }; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/wallet/auth/proof`, method: 'POST', body: prepareRequestData(data, { @@ -9196,7 +9910,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['token'], properties: { token: { type: 'string' } } @@ -9210,16 +9924,28 @@ export class TonApiClient { * @name GetAccountSeqno * @request GET:/v2/wallet/{account_id}/seqno */ - async getAccountSeqno(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get account seqno + * + * @tags Wallet + * @name GetAccountSeqno + * @request GET:/v2/wallet/{account_id}/seqno + */ + getAccountSeqno( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/wallet/${accountId}/seqno`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Seqno' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Seqno' + }); } /** @@ -9229,16 +9955,28 @@ export class TonApiClient { * @name GetWalletInfo * @request GET:/v2/wallet/{account_id} */ - async getWalletInfo(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get human-friendly information about a wallet without low-level details. + * + * @tags Wallet + * @name GetWalletInfo + * @request GET:/v2/wallet/{account_id} + */ + getWalletInfo( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/wallet/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/Wallet' }); + return prepareResponse(req, { + $ref: '#/components/schemas/Wallet' + }); } /** @@ -9248,15 +9986,25 @@ export class TonApiClient { * @name GetWalletsByPublicKey * @request GET:/v2/pubkeys/{public_key}/wallets */ - async getWalletsByPublicKey(publicKey: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get wallets by public key + * + * @tags Wallet + * @name GetWalletsByPublicKey + * @request GET:/v2/pubkeys/{public_key}/wallets + */ + getWalletsByPublicKey( + publicKey: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/pubkeys/${publicKey}/wallets`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Wallets' }); } @@ -9268,15 +10016,22 @@ export class TonApiClient { * @name GaslessConfig * @request GET:/v2/gasless/config */ - async gaslessConfig(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Returns configuration of gasless transfers + * + * @tags Gasless + * @name GaslessConfig + * @request GET:/v2/gasless/config + */ + gaslessConfig(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ path: `/v2/gasless/config`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/GaslessConfig' }); } @@ -9288,8 +10043,15 @@ export class TonApiClient { * @name GaslessEstimate * @request POST:/v2/gasless/estimate/{master_id} */ - async gaslessEstimate( - masterId_Address: Address, + /** + * @description Estimates the cost of the given messages and returns a payload to sign + * + * @tags Gasless + * @name GaslessEstimate + * @request POST:/v2/gasless/estimate/{master_id} + */ + gaslessEstimate( + masterId_Address: Address | string, data: { /** * TONAPI verifies that the account has enough jettons to pay the commission and make a transfer. @@ -9307,9 +10069,9 @@ export class TonApiClient { }[]; }, params: RequestParams = {} - ) { - const masterId = masterId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const masterId = addressToString(masterId_Address); + const req = this.http.request({ path: `/v2/gasless/estimate/${masterId}`, method: 'POST', body: prepareRequestData(data, { @@ -9334,7 +10096,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/SignRawParams' }); } @@ -9346,7 +10108,14 @@ export class TonApiClient { * @name GaslessSend * @request POST:/v2/gasless/send */ - async gaslessSend( + /** + * @description Submits the signed gasless transaction message to the network + * + * @tags Gasless + * @name GaslessSend + * @request POST:/v2/gasless/send + */ + gaslessSend( data: { /** hex encoded public key */ walletPublicKey: string; @@ -9354,8 +10123,8 @@ export class TonApiClient { boc: Cell; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/gasless/send`, method: 'POST', body: prepareRequestData(data, { @@ -9370,7 +10139,9 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { $ref: '#/components/schemas/GaslessTx' }); + return prepareResponse(req, { + $ref: '#/components/schemas/GaslessTx' + }); } /** @@ -9380,15 +10151,24 @@ export class TonApiClient { * @name GetRawMasterchainInfo * @request GET:/v2/liteserver/get_masterchain_info */ - async getRawMasterchainInfo(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw masterchain info + * + * @tags Lite Server + * @name GetRawMasterchainInfo + * @request GET:/v2/liteserver/get_masterchain_info + */ + getRawMasterchainInfo( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_masterchain_info`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['last', 'state_root_hash', 'init'], properties: { @@ -9406,7 +10186,14 @@ export class TonApiClient { * @name GetRawMasterchainInfoExt * @request GET:/v2/liteserver/get_masterchain_info_ext */ - async getRawMasterchainInfoExt( + /** + * @description Get raw masterchain info ext + * + * @tags Lite Server + * @name GetRawMasterchainInfoExt + * @request GET:/v2/liteserver/get_masterchain_info_ext + */ + getRawMasterchainInfoExt( query: { /** * mode @@ -9416,8 +10203,8 @@ export class TonApiClient { mode: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_masterchain_info_ext`, method: 'GET', query: query, @@ -9425,7 +10212,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: [ 'mode', @@ -9457,15 +10244,22 @@ export class TonApiClient { * @name GetRawTime * @request GET:/v2/liteserver/get_time */ - async getRawTime(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw time + * + * @tags Lite Server + * @name GetRawTime + * @request GET:/v2/liteserver/get_time + */ + getRawTime(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_time`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['time'], properties: { time: { type: 'integer', format: 'int32' } } @@ -9479,15 +10273,25 @@ export class TonApiClient { * @name GetRawBlockchainBlock * @request GET:/v2/liteserver/get_block/{block_id} */ - async getRawBlockchainBlock(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw blockchain block + * + * @tags Lite Server + * @name GetRawBlockchainBlock + * @request GET:/v2/liteserver/get_block/{block_id} + */ + getRawBlockchainBlock( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_block/${blockId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'data'], properties: { id: { $ref: '#/components/schemas/BlockRaw' }, data: { type: 'string' } } @@ -9501,15 +10305,25 @@ export class TonApiClient { * @name GetRawBlockchainBlockState * @request GET:/v2/liteserver/get_state/{block_id} */ - async getRawBlockchainBlockState(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw blockchain block state + * + * @tags Lite Server + * @name GetRawBlockchainBlockState + * @request GET:/v2/liteserver/get_state/{block_id} + */ + getRawBlockchainBlockState( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_state/${blockId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'root_hash', 'file_hash', 'data'], properties: { @@ -9528,7 +10342,14 @@ export class TonApiClient { * @name GetRawBlockchainBlockHeader * @request GET:/v2/liteserver/get_block_header/{block_id} */ - async getRawBlockchainBlockHeader( + /** + * @description Get raw blockchain block header + * + * @tags Lite Server + * @name GetRawBlockchainBlockHeader + * @request GET:/v2/liteserver/get_block_header/{block_id} + */ + getRawBlockchainBlockHeader( blockId: string, query: { /** @@ -9539,8 +10360,8 @@ export class TonApiClient { mode: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_block_header/${blockId}`, method: 'GET', query: query, @@ -9548,7 +10369,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'mode', 'header_proof'], properties: { @@ -9566,14 +10387,21 @@ export class TonApiClient { * @name SendRawMessage * @request POST:/v2/liteserver/send_message */ - async sendRawMessage( + /** + * @description Send raw message to blockchain + * + * @tags Lite Server + * @name SendRawMessage + * @request POST:/v2/liteserver/send_message + */ + sendRawMessage( data: { /** @format cell-base64 */ body: Cell; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/send_message`, method: 'POST', body: prepareRequestData(data, { @@ -9585,7 +10413,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['code'], properties: { code: { type: 'integer', format: 'int32' } } @@ -9599,8 +10427,15 @@ export class TonApiClient { * @name GetRawAccountState * @request GET:/v2/liteserver/get_account_state/{account_id} */ - async getRawAccountState( - accountId_Address: Address, + /** + * @description Get raw account state + * + * @tags Lite Server + * @name GetRawAccountState + * @request GET:/v2/liteserver/get_account_state/{account_id} + */ + getRawAccountState( + accountId_Address: Address | string, query?: { /** * target block: (workchain,shard,seqno,root_hash,file_hash) @@ -9609,9 +10444,9 @@ export class TonApiClient { target_block?: string; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/liteserver/get_account_state/${accountId}`, method: 'GET', query: query, @@ -9619,7 +10454,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'shardblk', 'shard_proof', 'proof', 'state'], properties: { @@ -9639,7 +10474,14 @@ export class TonApiClient { * @name GetRawShardInfo * @request GET:/v2/liteserver/get_shard_info/{block_id} */ - async getRawShardInfo( + /** + * @description Get raw shard info + * + * @tags Lite Server + * @name GetRawShardInfo + * @request GET:/v2/liteserver/get_shard_info/{block_id} + */ + getRawShardInfo( blockId: string, query: { /** @@ -9661,8 +10503,8 @@ export class TonApiClient { exact: boolean; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_shard_info/${blockId}`, method: 'GET', query: query, @@ -9670,7 +10512,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'shardblk', 'shard_proof', 'shard_descr'], properties: { @@ -9689,15 +10531,25 @@ export class TonApiClient { * @name GetAllRawShardsInfo * @request GET:/v2/liteserver/get_all_shards_info/{block_id} */ - async getAllRawShardsInfo(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get all raw shards info + * + * @tags Lite Server + * @name GetAllRawShardsInfo + * @request GET:/v2/liteserver/get_all_shards_info/{block_id} + */ + getAllRawShardsInfo( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_all_shards_info/${blockId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'proof', 'data'], properties: { @@ -9715,8 +10567,15 @@ export class TonApiClient { * @name GetRawTransactions * @request GET:/v2/liteserver/get_transactions/{account_id} */ - async getRawTransactions( - accountId_Address: Address, + /** + * @description Get raw transactions + * + * @tags Lite Server + * @name GetRawTransactions + * @request GET:/v2/liteserver/get_transactions/{account_id} + */ + getRawTransactions( + accountId_Address: Address | string, query: { /** * count @@ -9737,9 +10596,9 @@ export class TonApiClient { hash: string; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/liteserver/get_transactions/${accountId}`, method: 'GET', query: query, @@ -9747,7 +10606,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['ids', 'transactions'], properties: { @@ -9764,7 +10623,14 @@ export class TonApiClient { * @name GetRawListBlockTransactions * @request GET:/v2/liteserver/list_block_transactions/{block_id} */ - async getRawListBlockTransactions( + /** + * @description Get raw list block transactions + * + * @tags Lite Server + * @name GetRawListBlockTransactions + * @request GET:/v2/liteserver/list_block_transactions/{block_id} + */ + getRawListBlockTransactions( blockId: string, query: { /** @@ -9793,20 +10659,20 @@ export class TonApiClient { lt?: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/list_block_transactions/${blockId}`, method: 'GET', query: query && { ...query, - account_id: query.account_id?.toRawString() + account_id: addressToString(query.account_id) }, queryImplode: ['account_id'], format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['id', 'req_count', 'incomplete', 'ids', 'proof'], properties: { @@ -9838,7 +10704,14 @@ export class TonApiClient { * @name GetRawBlockProof * @request GET:/v2/liteserver/get_block_proof */ - async getRawBlockProof( + /** + * @description Get raw block proof + * + * @tags Lite Server + * @name GetRawBlockProof + * @request GET:/v2/liteserver/get_block_proof + */ + getRawBlockProof( query: { /** * known block: (workchain,shard,seqno,root_hash,file_hash) @@ -9858,8 +10731,8 @@ export class TonApiClient { mode: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_block_proof`, method: 'GET', query: query, @@ -9867,7 +10740,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['complete', 'from', 'to', 'steps'], properties: { @@ -9957,7 +10830,14 @@ export class TonApiClient { * @name GetRawConfig * @request GET:/v2/liteserver/get_config_all/{block_id} */ - async getRawConfig( + /** + * @description Get raw config + * + * @tags Lite Server + * @name GetRawConfig + * @request GET:/v2/liteserver/get_config_all/{block_id} + */ + getRawConfig( blockId: string, query: { /** @@ -9968,8 +10848,8 @@ export class TonApiClient { mode: number; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_config_all/${blockId}`, method: 'GET', query: query, @@ -9977,7 +10857,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['mode', 'id', 'state_proof', 'config_proof'], properties: { @@ -9996,15 +10876,25 @@ export class TonApiClient { * @name GetRawShardBlockProof * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} */ - async getRawShardBlockProof(blockId: string, params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get raw shard block proof + * + * @tags Lite Server + * @name GetRawShardBlockProof + * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} + */ + getRawShardBlockProof( + blockId: string, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_shard_block_proof/${blockId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['masterchain_id', 'links'], properties: { @@ -10031,15 +10921,24 @@ export class TonApiClient { * @name GetOutMsgQueueSizes * @request GET:/v2/liteserver/get_out_msg_queue_sizes */ - async getOutMsgQueueSizes(params: RequestParams = {}) { - const req = this.http.request({ + /** + * @description Get out msg queue sizes + * + * @tags Lite Server + * @name GetOutMsgQueueSizes + * @request GET:/v2/liteserver/get_out_msg_queue_sizes + */ + getOutMsgQueueSizes( + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ path: `/v2/liteserver/get_out_msg_queue_sizes`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { type: 'object', required: ['ext_msg_queue_size_limit', 'shards'], properties: { @@ -10066,16 +10965,26 @@ export class TonApiClient { * @name GetMultisigAccount * @request GET:/v2/multisig/{account_id} */ - async getMultisigAccount(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get multisig account info + * + * @tags Multisig + * @name GetMultisigAccount + * @request GET:/v2/multisig/{account_id} + */ + getMultisigAccount( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/multisig/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Multisig' }); } @@ -10087,16 +10996,26 @@ export class TonApiClient { * @name GetMultisigOrder * @request GET:/v2/multisig/order/{account_id} */ - async getMultisigOrder(accountId_Address: Address, params: RequestParams = {}) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + /** + * @description Get multisig order + * + * @tags Multisig + * @name GetMultisigOrder + * @request GET:/v2/multisig/order/{account_id} + */ + getMultisigOrder( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/multisig/order/${accountId}`, method: 'GET', format: 'json', ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/MultisigOrder' }); } @@ -10108,14 +11027,21 @@ export class TonApiClient { * @name DecodeMessage * @request POST:/v2/message/decode */ - async decodeMessage( + /** + * @description Decode a given message. Only external incoming messages can be decoded currently. + * + * @tags Emulation + * @name DecodeMessage + * @request POST:/v2/message/decode + */ + decodeMessage( data: { /** @format cell */ boc: Cell; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/message/decode`, method: 'POST', body: prepareRequestData(data, { @@ -10127,7 +11053,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/DecodedMessage' }); } @@ -10139,7 +11065,14 @@ export class TonApiClient { * @name EmulateMessageToEvent * @request POST:/v2/events/emulate */ - async emulateMessageToEvent( + /** + * @description Emulate sending message to retrieve general blockchain events + * + * @tags Emulation, Events + * @name EmulateMessageToEvent + * @request POST:/v2/events/emulate + */ + emulateMessageToEvent( data: { /** @format cell */ boc: Cell; @@ -10148,8 +11081,8 @@ export class TonApiClient { ignore_signature_check?: boolean; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/events/emulate`, method: 'POST', query: query, @@ -10162,7 +11095,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Event' }); } @@ -10174,7 +11107,14 @@ export class TonApiClient { * @name EmulateMessageToTrace * @request POST:/v2/traces/emulate */ - async emulateMessageToTrace( + /** + * @description Emulate sending message to retrieve with a detailed execution trace + * + * @tags Emulation, Traces + * @name EmulateMessageToTrace + * @request POST:/v2/traces/emulate + */ + emulateMessageToTrace( data: { /** @format cell */ boc: Cell; @@ -10183,8 +11123,8 @@ export class TonApiClient { ignore_signature_check?: boolean; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/traces/emulate`, method: 'POST', query: query, @@ -10197,7 +11137,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/Trace' }); } @@ -10209,7 +11149,14 @@ export class TonApiClient { * @name EmulateMessageToWallet * @request POST:/v2/wallet/emulate */ - async emulateMessageToWallet( + /** + * @description Emulate sending message to retrieve the resulting wallet state + * + * @tags Emulation, Wallet + * @name EmulateMessageToWallet + * @request POST:/v2/wallet/emulate + */ + emulateMessageToWallet( data: { /** @format cell */ boc: Cell; @@ -10232,8 +11179,8 @@ export class TonApiClient { currency?: string; }, params: RequestParams = {} - ) { - const req = this.http.request({ + ): TonApiPromise { + const req = this.http.request({ path: `/v2/wallet/emulate`, method: 'POST', query: query, @@ -10263,7 +11210,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/MessageConsequences' }); } @@ -10275,8 +11222,15 @@ export class TonApiClient { * @name EmulateMessageToAccountEvent * @request POST:/v2/accounts/{account_id}/events/emulate */ - async emulateMessageToAccountEvent( - accountId_Address: Address, + /** + * @description Emulate sending message to retrieve account-specific events + * + * @tags Emulation, Accounts + * @name EmulateMessageToAccountEvent + * @request POST:/v2/accounts/{account_id}/events/emulate + */ + emulateMessageToAccountEvent( + accountId_Address: Address | string, data: { /** @format cell */ boc: Cell; @@ -10285,9 +11239,9 @@ export class TonApiClient { ignore_signature_check?: boolean; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/accounts/${accountId}/events/emulate`, method: 'POST', query: query, @@ -10300,7 +11254,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountEvent' }); } @@ -10312,8 +11266,15 @@ export class TonApiClient { * @name GetPurchaseHistory * @request GET:/v2/purchases/{account_id}/history */ - async getPurchaseHistory( - accountId_Address: Address, + /** + * @description Get history of purchases + * + * @tags Purchases + * @name GetPurchaseHistory + * @request GET:/v2/purchases/{account_id}/history + */ + getPurchaseHistory( + accountId_Address: Address | string, query?: { /** * omit this parameter to get last invoices @@ -10330,9 +11291,9 @@ export class TonApiClient { limit?: number; }, params: RequestParams = {} - ) { - const accountId = accountId_Address.toRawString(); - const req = this.http.request({ + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ path: `/v2/purchases/${accountId}/history`, method: 'GET', query: query, @@ -10340,7 +11301,7 @@ export class TonApiClient { ...params }); - return prepareResponse(req, { + return prepareResponse(req, { $ref: '#/components/schemas/AccountPurchases' }); } @@ -10398,27 +11359,33 @@ function getDefaultClient(): TonApiClient { * @name GetOpenapiJson * @request GET:/v2/openapi.json */ -export const getOpenapiJson = async (options?: { +type GetOpenapiJsonOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getOpenapiJson = async ( + options?: GetOpenapiJsonOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getOpenapiJson(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetOpenapiJsonData, + ThrowOnError + >; } }; @@ -10429,27 +11396,33 @@ export const getOpenapiJson = async (optio * @name GetOpenapiYml * @request GET:/v2/openapi.yml */ -export const getOpenapiYml = async (options?: { +type GetOpenapiYmlOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getOpenapiYml = async ( + options?: GetOpenapiYmlOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getOpenapiYml(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetOpenapiYmlData, + ThrowOnError + >; } }; @@ -10460,27 +11433,33 @@ export const getOpenapiYml = async (option * @name Status * @request GET:/v2/status */ -export const status = async (options?: { +type StatusOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const status = async ( + options?: StatusOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.status(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + StatusData, + ThrowOnError + >; } }; @@ -10491,30 +11470,36 @@ export const status = async (options?: { * @name AddressParse * @request GET:/v2/address/{account_id}/parse */ -export const addressParse = async (options: { +type AddressParseOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const addressParse = async ( + options: AddressParseOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.addressParse(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + AddressParseData, + ThrowOnError + >; } }; @@ -10525,7 +11510,7 @@ export const addressParse = async (options * @name GetReducedBlockchainBlocks * @request GET:/v2/blockchain/reduced/blocks */ -export const getReducedBlockchainBlocks = async (options: { +type GetReducedBlockchainBlocksOptions = { client?: TonApiClient; query: { /** @format int64 */ @@ -10535,23 +11520,32 @@ export const getReducedBlockchainBlocks = async { +}; +export const getReducedBlockchainBlocks = async ( + options: GetReducedBlockchainBlocksOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getReducedBlockchainBlocks(options.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetReducedBlockchainBlocksData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetReducedBlockchainBlocksData, + ThrowOnError + >; } }; @@ -10562,30 +11556,39 @@ export const getReducedBlockchainBlocks = async (options: { +type GetBlockchainBlockOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainBlock = async ( + options: GetBlockchainBlockOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainBlock(options.path.blockId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainBlockData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainBlockData, + ThrowOnError + >; } }; @@ -10596,14 +11599,17 @@ export const getBlockchainBlock = async (o * @name DownloadBlockchainBlockBoc * @request GET:/v2/blockchain/blocks/{block_id}/boc */ -export const downloadBlockchainBlockBoc = async (options: { +type DownloadBlockchainBlockBocOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const downloadBlockchainBlockBoc = async ( + options: DownloadBlockchainBlockBocOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.downloadBlockchainBlockBoc( @@ -10613,16 +11619,22 @@ export const downloadBlockchainBlockBoc = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + DownloadBlockchainBlockBocData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + DownloadBlockchainBlockBocData, + ThrowOnError + >; } }; @@ -10633,16 +11645,17 @@ export const downloadBlockchainBlockBoc = async (options: { +type GetBlockchainMasterchainShardsOptions = { client?: TonApiClient; path: { masterchainSeqno: number; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainMasterchainShards = async ( + options: GetBlockchainMasterchainShardsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainMasterchainShards( @@ -10652,16 +11665,22 @@ export const getBlockchainMasterchainShards = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainMasterchainShardsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainMasterchainShardsData, + ThrowOnError + >; } }; @@ -10672,16 +11691,17 @@ export const getBlockchainMasterchainShards = async < * @name GetBlockchainMasterchainBlocks * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/blocks */ -export const getBlockchainMasterchainBlocks = async < - ThrowOnError extends boolean = false ->(options: { +type GetBlockchainMasterchainBlocksOptions = { client?: TonApiClient; path: { masterchainSeqno: number; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainMasterchainBlocks = async ( + options: GetBlockchainMasterchainBlocksOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainMasterchainBlocks( @@ -10691,16 +11711,22 @@ export const getBlockchainMasterchainBlocks = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainMasterchainBlocksData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainMasterchainBlocksData, + ThrowOnError + >; } }; @@ -10711,16 +11737,17 @@ export const getBlockchainMasterchainBlocks = async < * @name GetBlockchainMasterchainTransactions * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/transactions */ -export const getBlockchainMasterchainTransactions = async < - ThrowOnError extends boolean = false ->(options: { +type GetBlockchainMasterchainTransactionsOptions = { client?: TonApiClient; path: { masterchainSeqno: number; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainMasterchainTransactions = async ( + options: GetBlockchainMasterchainTransactionsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainMasterchainTransactions( @@ -10730,16 +11757,25 @@ export const getBlockchainMasterchainTransactions = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync< + GetBlockchainMasterchainTransactionsData, + ThrowOnError + >; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainMasterchainTransactionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainMasterchainTransactionsData, + ThrowOnError + >; } }; @@ -10750,14 +11786,17 @@ export const getBlockchainMasterchainTransactions = async < * @name GetBlockchainConfigFromBlock * @request GET:/v2/blockchain/masterchain/{masterchain_seqno}/config */ -export const getBlockchainConfigFromBlock = async (options: { +type GetBlockchainConfigFromBlockOptions = { client?: TonApiClient; path: { masterchainSeqno: number; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainConfigFromBlock = async ( + options: GetBlockchainConfigFromBlockOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainConfigFromBlock( @@ -10767,16 +11806,22 @@ export const getBlockchainConfigFromBlock = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainConfigFromBlockData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainConfigFromBlockData, + ThrowOnError + >; } }; @@ -10787,16 +11832,17 @@ export const getBlockchainConfigFromBlock = async (options: { +type GetRawBlockchainConfigFromBlockOptions = { client?: TonApiClient; path: { masterchainSeqno: number; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawBlockchainConfigFromBlock = async ( + options: GetRawBlockchainConfigFromBlockOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawBlockchainConfigFromBlock( @@ -10806,16 +11852,22 @@ export const getRawBlockchainConfigFromBlock = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawBlockchainConfigFromBlockData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawBlockchainConfigFromBlockData, + ThrowOnError + >; } }; @@ -10826,16 +11878,17 @@ export const getRawBlockchainConfigFromBlock = async < * @name GetBlockchainBlockTransactions * @request GET:/v2/blockchain/blocks/{block_id}/transactions */ -export const getBlockchainBlockTransactions = async < - ThrowOnError extends boolean = false ->(options: { +type GetBlockchainBlockTransactionsOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainBlockTransactions = async ( + options: GetBlockchainBlockTransactionsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainBlockTransactions( @@ -10845,16 +11898,22 @@ export const getBlockchainBlockTransactions = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainBlockTransactionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainBlockTransactionsData, + ThrowOnError + >; } }; @@ -10865,14 +11924,17 @@ export const getBlockchainBlockTransactions = async < * @name GetBlockchainTransaction * @request GET:/v2/blockchain/transactions/{transaction_id} */ -export const getBlockchainTransaction = async (options: { +type GetBlockchainTransactionOptions = { client?: TonApiClient; path: { transactionId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainTransaction = async ( + options: GetBlockchainTransactionOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainTransaction( @@ -10882,16 +11944,22 @@ export const getBlockchainTransaction = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainTransactionData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainTransactionData, + ThrowOnError + >; } }; @@ -10902,16 +11970,17 @@ export const getBlockchainTransaction = async (options: { +type GetBlockchainTransactionByMessageHashOptions = { client?: TonApiClient; path: { msgId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainTransactionByMessageHash = async ( + options: GetBlockchainTransactionByMessageHashOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainTransactionByMessageHash( @@ -10921,16 +11990,25 @@ export const getBlockchainTransactionByMessageHash = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync< + GetBlockchainTransactionByMessageHashData, + ThrowOnError + >; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainTransactionByMessageHashData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainTransactionByMessageHashData, + ThrowOnError + >; } }; @@ -10941,27 +12019,36 @@ export const getBlockchainTransactionByMessageHash = async < * @name GetBlockchainValidators * @request GET:/v2/blockchain/validators */ -export const getBlockchainValidators = async (options?: { +type GetBlockchainValidatorsOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainValidators = async ( + options?: GetBlockchainValidatorsOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getBlockchainValidators(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainValidatorsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainValidatorsData, + ThrowOnError + >; } }; @@ -10972,27 +12059,36 @@ export const getBlockchainValidators = async (options?: { +type GetBlockchainMasterchainHeadOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainMasterchainHead = async ( + options?: GetBlockchainMasterchainHeadOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getBlockchainMasterchainHead(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainMasterchainHeadData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainMasterchainHeadData, + ThrowOnError + >; } }; @@ -11003,30 +12099,39 @@ export const getBlockchainMasterchainHead = async (options: { +type GetBlockchainRawAccountOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainRawAccount = async ( + options: GetBlockchainRawAccountOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainRawAccount(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainRawAccountData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainRawAccountData, + ThrowOnError + >; } }; @@ -11037,12 +12142,10 @@ export const getBlockchainRawAccount = async (options: { +type GetBlockchainAccountTransactionsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -11073,7 +12176,10 @@ export const getBlockchainAccountTransactions = async < }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainAccountTransactions = async ( + options: GetBlockchainAccountTransactionsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getBlockchainAccountTransactions( @@ -11084,16 +12190,22 @@ export const getBlockchainAccountTransactions = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainAccountTransactionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainAccountTransactionsData, + ThrowOnError + >; } }; @@ -11104,12 +12216,10 @@ export const getBlockchainAccountTransactions = async < * @name ExecGetMethodForBlockchainAccount * @request GET:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ -export const execGetMethodForBlockchainAccount = async < - ThrowOnError extends boolean = false ->(options: { +type ExecGetMethodForBlockchainAccountOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; methodName: string; }; query?: { @@ -11128,7 +12238,10 @@ export const execGetMethodForBlockchainAccount = async < }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const execGetMethodForBlockchainAccount = async ( + options: ExecGetMethodForBlockchainAccountOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.execGetMethodForBlockchainAccount( @@ -11140,16 +12253,22 @@ export const execGetMethodForBlockchainAccount = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + ExecGetMethodForBlockchainAccountData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + ExecGetMethodForBlockchainAccountData, + ThrowOnError + >; } }; @@ -11160,12 +12279,10 @@ export const execGetMethodForBlockchainAccount = async < * @name ExecGetMethodWithBodyForBlockchainAccount * @request POST:/v2/blockchain/accounts/{account_id}/methods/{method_name} */ -export const execGetMethodWithBodyForBlockchainAccount = async < - ThrowOnError extends boolean = false ->(options: { +type ExecGetMethodWithBodyForBlockchainAccountOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; methodName: string; }; body: { @@ -11173,7 +12290,12 @@ export const execGetMethodWithBodyForBlockchainAccount = async < }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const execGetMethodWithBodyForBlockchainAccount = async < + ThrowOnError extends boolean = false +>( + options: ExecGetMethodWithBodyForBlockchainAccountOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.execGetMethodWithBodyForBlockchainAccount( @@ -11185,16 +12307,25 @@ export const execGetMethodWithBodyForBlockchainAccount = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync< + ExecGetMethodWithBodyForBlockchainAccountData, + ThrowOnError + >; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + ExecGetMethodWithBodyForBlockchainAccountData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + ExecGetMethodWithBodyForBlockchainAccountData, + ThrowOnError + >; } }; @@ -11205,7 +12336,7 @@ export const execGetMethodWithBodyForBlockchainAccount = async < * @name SendBlockchainMessage * @request POST:/v2/blockchain/message */ -export const sendBlockchainMessage = async (options: { +type SendBlockchainMessageOptions = { client?: TonApiClient; body: { /** @format cell */ @@ -11216,23 +12347,32 @@ export const sendBlockchainMessage = async { +}; +export const sendBlockchainMessage = async ( + options: SendBlockchainMessageOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.sendBlockchainMessage(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + SendBlockchainMessageData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + SendBlockchainMessageData, + ThrowOnError + >; } }; @@ -11243,27 +12383,36 @@ export const sendBlockchainMessage = async (options?: { +type GetBlockchainConfigOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getBlockchainConfig = async ( + options?: GetBlockchainConfigOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getBlockchainConfig(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetBlockchainConfigData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainConfigData, + ThrowOnError + >; } }; @@ -11274,27 +12423,36 @@ export const getBlockchainConfig = async ( * @name GetRawBlockchainConfig * @request GET:/v2/blockchain/config/raw */ -export const getRawBlockchainConfig = async (options?: { +type GetRawBlockchainConfigOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawBlockchainConfig = async ( + options?: GetRawBlockchainConfigOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getRawBlockchainConfig(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawBlockchainConfigData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawBlockchainConfigData, + ThrowOnError + >; } }; @@ -11305,14 +12463,17 @@ export const getRawBlockchainConfig = async (options: { +type BlockchainAccountInspectOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const blockchainAccountInspect = async ( + options: BlockchainAccountInspectOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.blockchainAccountInspect( @@ -11322,16 +12483,22 @@ export const blockchainAccountInspect = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + BlockchainAccountInspectData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + BlockchainAccountInspectData, + ThrowOnError + >; } }; @@ -11342,30 +12509,39 @@ export const blockchainAccountInspect = async (options: { +type GetLibraryByHashOptions = { client?: TonApiClient; path: { hash: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getLibraryByHash = async ( + options: GetLibraryByHashOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getLibraryByHash(options.path.hash, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetLibraryByHashData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetLibraryByHashData, + ThrowOnError + >; } }; @@ -11376,7 +12552,7 @@ export const getLibraryByHash = async (opt * @name GetAccounts * @request POST:/v2/accounts/_bulk */ -export const getAccounts = async (options: { +type GetAccountsOptions = { client?: TonApiClient; body: { accountIds: Address[]; @@ -11387,23 +12563,29 @@ export const getAccounts = async (options: }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccounts = async ( + options: GetAccountsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccounts(options.body, options?.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountsData, + ThrowOnError + >; } }; @@ -11414,30 +12596,36 @@ export const getAccounts = async (options: * @name GetAccount * @request GET:/v2/accounts/{account_id} */ -export const getAccount = async (options: { +type GetAccountOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccount = async ( + options: GetAccountOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccount(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountData, + ThrowOnError + >; } }; @@ -11448,30 +12636,39 @@ export const getAccount = async (options: * @name AccountDnsBackResolve * @request GET:/v2/accounts/{account_id}/dns/backresolve */ -export const accountDnsBackResolve = async (options: { +type AccountDnsBackResolveOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const accountDnsBackResolve = async ( + options: AccountDnsBackResolveOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.accountDnsBackResolve(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + AccountDnsBackResolveData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + AccountDnsBackResolveData, + ThrowOnError + >; } }; @@ -11482,10 +12679,10 @@ export const accountDnsBackResolve = async (options: { +type GetAccountJettonsBalancesOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -11501,7 +12698,10 @@ export const getAccountJettonsBalances = async { +}; +export const getAccountJettonsBalances = async ( + options: GetAccountJettonsBalancesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountJettonsBalances( @@ -11512,16 +12712,22 @@ export const getAccountJettonsBalances = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountJettonsBalancesData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountJettonsBalancesData, + ThrowOnError + >; } }; @@ -11532,11 +12738,11 @@ export const getAccountJettonsBalances = async (options: { +type GetAccountJettonBalanceOptions = { client?: TonApiClient; path: { - accountId: Address; - jettonId: Address; + accountId: Address | string; + jettonId: Address | string; }; query?: { /** @@ -11552,7 +12758,10 @@ export const getAccountJettonBalance = async { +}; +export const getAccountJettonBalance = async ( + options: GetAccountJettonBalanceOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountJettonBalance( @@ -11564,16 +12773,22 @@ export const getAccountJettonBalance = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountJettonBalanceData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountJettonBalanceData, + ThrowOnError + >; } }; @@ -11584,10 +12799,10 @@ export const getAccountJettonBalance = async (options: { +type GetAccountJettonsHistoryOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query: { /** @@ -11605,7 +12820,10 @@ export const getAccountJettonsHistory = async { +}; +export const getAccountJettonsHistory = async ( + options: GetAccountJettonsHistoryOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountJettonsHistory( @@ -11616,16 +12834,22 @@ export const getAccountJettonsHistory = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountJettonsHistoryData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountJettonsHistoryData, + ThrowOnError + >; } }; @@ -11637,11 +12861,11 @@ export const getAccountJettonsHistory = async (options: { +type GetAccountJettonHistoryByIdOptions = { client?: TonApiClient; path: { - accountId: Address; - jettonId: Address; + accountId: Address | string; + jettonId: Address | string; }; query: { /** @@ -11671,7 +12895,10 @@ export const getAccountJettonHistoryById = async { +}; +export const getAccountJettonHistoryById = async ( + options: GetAccountJettonHistoryByIdOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountJettonHistoryById( @@ -11683,16 +12910,22 @@ export const getAccountJettonHistoryById = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountJettonHistoryByIdData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountJettonHistoryByIdData, + ThrowOnError + >; } }; @@ -11703,10 +12936,10 @@ export const getAccountJettonHistoryById = async (options: { +type GetAccountNftItemsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -11734,7 +12967,10 @@ export const getAccountNftItems = async (o }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountNftItems = async ( + options: GetAccountNftItemsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountNftItems( @@ -11745,16 +12981,22 @@ export const getAccountNftItems = async (o // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountNftItemsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountNftItemsData, + ThrowOnError + >; } }; @@ -11765,10 +13007,10 @@ export const getAccountNftItems = async (o * @name GetAccountEvents * @request GET:/v2/accounts/{account_id}/events */ -export const getAccountEvents = async (options: { +type GetAccountEventsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query: { /** @@ -11808,7 +13050,10 @@ export const getAccountEvents = async (opt }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountEvents = async ( + options: GetAccountEventsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountEvents( @@ -11819,16 +13064,22 @@ export const getAccountEvents = async (opt // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountEventsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountEventsData, + ThrowOnError + >; } }; @@ -11839,10 +13090,10 @@ export const getAccountEvents = async (opt * @name GetAccountEvent * @request GET:/v2/accounts/{account_id}/events/{event_id} */ -export const getAccountEvent = async (options: { +type GetAccountEventOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; eventId: string; }; query?: { @@ -11854,7 +13105,10 @@ export const getAccountEvent = async (opti }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountEvent = async ( + options: GetAccountEventOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountEvent( @@ -11866,16 +13120,19 @@ export const getAccountEvent = async (opti // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountEventData, + ThrowOnError + >; } }; @@ -11886,10 +13143,10 @@ export const getAccountEvent = async (opti * @name GetAccountTraces * @request GET:/v2/accounts/{account_id}/traces */ -export const getAccountTraces = async (options: { +type GetAccountTracesOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -11908,7 +13165,10 @@ export const getAccountTraces = async (opt }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountTraces = async ( + options: GetAccountTracesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountTraces( @@ -11919,16 +13179,22 @@ export const getAccountTraces = async (opt // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountTracesData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountTracesData, + ThrowOnError + >; } }; @@ -11939,30 +13205,39 @@ export const getAccountTraces = async (opt * @name GetAccountSubscriptions * @request GET:/v2/accounts/{account_id}/subscriptions */ -export const getAccountSubscriptions = async (options: { +type GetAccountSubscriptionsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountSubscriptions = async ( + options: GetAccountSubscriptionsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountSubscriptions(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountSubscriptionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountSubscriptionsData, + ThrowOnError + >; } }; @@ -11973,30 +13248,36 @@ export const getAccountSubscriptions = async (options: { +type ReindexAccountOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const reindexAccount = async ( + options: ReindexAccountOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.reindexAccount(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + ReindexAccountData, + ThrowOnError + >; } }; @@ -12007,7 +13288,7 @@ export const reindexAccount = async (optio * @name SearchAccounts * @request GET:/v2/accounts/search */ -export const searchAccounts = async (options: { +type SearchAccountsOptions = { client?: TonApiClient; query: { /** @@ -12018,23 +13299,29 @@ export const searchAccounts = async (optio }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const searchAccounts = async ( + options: SearchAccountsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.searchAccounts(options.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + SearchAccountsData, + ThrowOnError + >; } }; @@ -12045,10 +13332,10 @@ export const searchAccounts = async (optio * @name GetAccountDnsExpiring * @request GET:/v2/accounts/{account_id}/dns/expiring */ -export const getAccountDnsExpiring = async (options: { +type GetAccountDnsExpiringOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -12060,7 +13347,10 @@ export const getAccountDnsExpiring = async { +}; +export const getAccountDnsExpiring = async ( + options: GetAccountDnsExpiringOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountDnsExpiring( @@ -12071,16 +13361,22 @@ export const getAccountDnsExpiring = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountDnsExpiringData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountDnsExpiringData, + ThrowOnError + >; } }; @@ -12091,30 +13387,39 @@ export const getAccountDnsExpiring = async (options: { +type GetAccountPublicKeyOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountPublicKey = async ( + options: GetAccountPublicKeyOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountPublicKey(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountPublicKeyData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountPublicKeyData, + ThrowOnError + >; } }; @@ -12125,30 +13430,39 @@ export const getAccountPublicKey = async ( * @name GetAccountMultisigs * @request GET:/v2/accounts/{account_id}/multisigs */ -export const getAccountMultisigs = async (options: { +type GetAccountMultisigsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountMultisigs = async ( + options: GetAccountMultisigsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountMultisigs(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountMultisigsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountMultisigsData, + ThrowOnError + >; } }; @@ -12159,10 +13473,10 @@ export const getAccountMultisigs = async ( * @name GetAccountDiff * @request GET:/v2/accounts/{account_id}/diff */ -export const getAccountDiff = async (options: { +type GetAccountDiffOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query: { /** @@ -12180,7 +13494,10 @@ export const getAccountDiff = async (optio }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountDiff = async ( + options: GetAccountDiffOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountDiff( @@ -12191,16 +13508,19 @@ export const getAccountDiff = async (optio // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountDiffData, + ThrowOnError + >; } }; @@ -12211,12 +13531,10 @@ export const getAccountDiff = async (optio * @name GetAccountExtraCurrencyHistoryById * @request GET:/v2/accounts/{account_id}/extra-currency/{id}/history */ -export const getAccountExtraCurrencyHistoryById = async < - ThrowOnError extends boolean = false ->(options: { +type GetAccountExtraCurrencyHistoryByIdOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; id: number; }; query: { @@ -12247,7 +13565,10 @@ export const getAccountExtraCurrencyHistoryById = async < }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountExtraCurrencyHistoryById = async ( + options: GetAccountExtraCurrencyHistoryByIdOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountExtraCurrencyHistoryById( @@ -12259,16 +13580,22 @@ export const getAccountExtraCurrencyHistoryById = async < // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountExtraCurrencyHistoryByIdData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountExtraCurrencyHistoryByIdData, + ThrowOnError + >; } }; @@ -12279,11 +13606,11 @@ export const getAccountExtraCurrencyHistoryById = async < * @name GetJettonAccountHistoryById * @request GET:/v2/jettons/{jetton_id}/accounts/{account_id}/history */ -export const getJettonAccountHistoryById = async (options: { +type GetJettonAccountHistoryByIdOptions = { client?: TonApiClient; path: { - accountId: Address; - jettonId: Address; + accountId: Address | string; + jettonId: Address | string; }; query: { /** @@ -12313,7 +13640,10 @@ export const getJettonAccountHistoryById = async { +}; +export const getJettonAccountHistoryById = async ( + options: GetJettonAccountHistoryByIdOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getJettonAccountHistoryById( @@ -12325,16 +13655,22 @@ export const getJettonAccountHistoryById = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetJettonAccountHistoryByIdData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonAccountHistoryByIdData, + ThrowOnError + >; } }; @@ -12345,10 +13681,10 @@ export const getJettonAccountHistoryById = async (options: { +type GetAccountNftHistoryOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query: { /** @@ -12366,7 +13702,10 @@ export const getAccountNftHistory = async }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountNftHistory = async ( + options: GetAccountNftHistoryOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountNftHistory( @@ -12377,16 +13716,22 @@ export const getAccountNftHistory = async // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountNftHistoryData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountNftHistoryData, + ThrowOnError + >; } }; @@ -12397,7 +13742,7 @@ export const getAccountNftHistory = async * @name GetNftCollections * @request GET:/v2/nfts/collections */ -export const getNftCollections = async (options?: { +type GetNftCollectionsOptions = { client?: TonApiClient; query?: { /** @@ -12418,23 +13763,32 @@ export const getNftCollections = async (op }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getNftCollections = async ( + options?: GetNftCollectionsOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getNftCollections(options?.query, options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetNftCollectionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetNftCollectionsData, + ThrowOnError + >; } }; @@ -12445,30 +13799,39 @@ export const getNftCollections = async (op * @name GetNftCollection * @request GET:/v2/nfts/collections/{account_id} */ -export const getNftCollection = async (options: { +type GetNftCollectionOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getNftCollection = async ( + options: GetNftCollectionOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getNftCollection(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetNftCollectionData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetNftCollectionData, + ThrowOnError + >; } }; @@ -12479,32 +13842,39 @@ export const getNftCollection = async (opt * @name GetNftCollectionItemsByAddresses * @request POST:/v2/nfts/collections/_bulk */ -export const getNftCollectionItemsByAddresses = async < - ThrowOnError extends boolean = false ->(options: { +type GetNftCollectionItemsByAddressesOptions = { client?: TonApiClient; body: { accountIds: Address[]; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getNftCollectionItemsByAddresses = async ( + options: GetNftCollectionItemsByAddressesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getNftCollectionItemsByAddresses(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetNftCollectionItemsByAddressesData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetNftCollectionItemsByAddressesData, + ThrowOnError + >; } }; @@ -12515,10 +13885,10 @@ export const getNftCollectionItemsByAddresses = async < * @name GetItemsFromCollection * @request GET:/v2/nfts/collections/{account_id}/items */ -export const getItemsFromCollection = async (options: { +type GetItemsFromCollectionOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -12535,7 +13905,10 @@ export const getItemsFromCollection = async { +}; +export const getItemsFromCollection = async ( + options: GetItemsFromCollectionOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getItemsFromCollection( @@ -12546,16 +13919,22 @@ export const getItemsFromCollection = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetItemsFromCollectionData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetItemsFromCollectionData, + ThrowOnError + >; } }; @@ -12566,30 +13945,39 @@ export const getItemsFromCollection = async (options: { +type GetNftItemsByAddressesOptions = { client?: TonApiClient; body: { accountIds: Address[]; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getNftItemsByAddresses = async ( + options: GetNftItemsByAddressesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getNftItemsByAddresses(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetNftItemsByAddressesData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetNftItemsByAddressesData, + ThrowOnError + >; } }; @@ -12600,30 +13988,39 @@ export const getNftItemsByAddresses = async (options: { +type GetNftItemByAddressOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getNftItemByAddress = async ( + options: GetNftItemByAddressOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getNftItemByAddress(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetNftItemByAddressData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetNftItemByAddressData, + ThrowOnError + >; } }; @@ -12635,10 +14032,10 @@ export const getNftItemByAddress = async ( * @request GET:/v2/nfts/{account_id}/history * @deprecated */ -export const getNftHistoryById = async (options: { +type GetNftHistoryByIdOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query: { /** @@ -12668,7 +14065,10 @@ export const getNftHistoryById = async (op }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getNftHistoryById = async ( + options: GetNftHistoryByIdOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getNftHistoryById( @@ -12679,16 +14079,22 @@ export const getNftHistoryById = async (op // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetNftHistoryByIdData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetNftHistoryByIdData, + ThrowOnError + >; } }; @@ -12699,30 +14105,36 @@ export const getNftHistoryById = async (op * @name GetDnsInfo * @request GET:/v2/dns/{domain_name} */ -export const getDnsInfo = async (options: { +type GetDnsInfoOptions = { client?: TonApiClient; path: { domainName: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getDnsInfo = async ( + options: GetDnsInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getDnsInfo(options.path.domainName, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetDnsInfoData, + ThrowOnError + >; } }; @@ -12733,7 +14145,7 @@ export const getDnsInfo = async (options: * @name DnsResolve * @request GET:/v2/dns/{domain_name}/resolve */ -export const dnsResolve = async (options: { +type DnsResolveOptions = { client?: TonApiClient; path: { domainName: string; @@ -12744,7 +14156,10 @@ export const dnsResolve = async (options: }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const dnsResolve = async ( + options: DnsResolveOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.dnsResolve( @@ -12755,16 +14170,19 @@ export const dnsResolve = async (options: // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + DnsResolveData, + ThrowOnError + >; } }; @@ -12775,30 +14193,36 @@ export const dnsResolve = async (options: * @name GetDomainBids * @request GET:/v2/dns/{domain_name}/bids */ -export const getDomainBids = async (options: { +type GetDomainBidsOptions = { client?: TonApiClient; path: { domainName: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getDomainBids = async ( + options: GetDomainBidsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getDomainBids(options.path.domainName, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetDomainBidsData, + ThrowOnError + >; } }; @@ -12809,7 +14233,7 @@ export const getDomainBids = async (option * @name GetAllAuctions * @request GET:/v2/dns/auctions */ -export const getAllAuctions = async (options?: { +type GetAllAuctionsOptions = { client?: TonApiClient; query?: { /** @@ -12820,23 +14244,29 @@ export const getAllAuctions = async (optio }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAllAuctions = async ( + options?: GetAllAuctionsOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getAllAuctions(options?.query, options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAllAuctionsData, + ThrowOnError + >; } }; @@ -12847,30 +14277,36 @@ export const getAllAuctions = async (optio * @name GetTrace * @request GET:/v2/traces/{trace_id} */ -export const getTrace = async (options: { +type GetTraceOptions = { client?: TonApiClient; path: { traceId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getTrace = async ( + options: GetTraceOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getTrace(options.path.traceId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetTraceData, + ThrowOnError + >; } }; @@ -12881,30 +14317,36 @@ export const getTrace = async (options: { * @name GetEvent * @request GET:/v2/events/{event_id} */ -export const getEvent = async (options: { +type GetEventOptions = { client?: TonApiClient; path: { eventId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getEvent = async ( + options: GetEventOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getEvent(options.path.eventId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetEventData, + ThrowOnError + >; } }; @@ -12915,7 +14357,7 @@ export const getEvent = async (options: { * @name GetJettons * @request GET:/v2/jettons */ -export const getJettons = async (options?: { +type GetJettonsOptions = { client?: TonApiClient; query?: { /** @@ -12936,23 +14378,29 @@ export const getJettons = async (options?: }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getJettons = async ( + options?: GetJettonsOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getJettons(options?.query, options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonsData, + ThrowOnError + >; } }; @@ -12963,30 +14411,36 @@ export const getJettons = async (options?: * @name GetJettonInfo * @request GET:/v2/jettons/{account_id} */ -export const getJettonInfo = async (options: { +type GetJettonInfoOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getJettonInfo = async ( + options: GetJettonInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getJettonInfo(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonInfoData, + ThrowOnError + >; } }; @@ -12997,30 +14451,39 @@ export const getJettonInfo = async (option * @name GetJettonInfosByAddresses * @request POST:/v2/jettons/_bulk */ -export const getJettonInfosByAddresses = async (options: { +type GetJettonInfosByAddressesOptions = { client?: TonApiClient; body: { accountIds: Address[]; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getJettonInfosByAddresses = async ( + options: GetJettonInfosByAddressesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getJettonInfosByAddresses(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetJettonInfosByAddressesData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonInfosByAddressesData, + ThrowOnError + >; } }; @@ -13031,10 +14494,10 @@ export const getJettonInfosByAddresses = async (options: { +type GetJettonHoldersOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -13052,7 +14515,10 @@ export const getJettonHolders = async (opt }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getJettonHolders = async ( + options: GetJettonHoldersOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getJettonHolders( @@ -13063,16 +14529,22 @@ export const getJettonHolders = async (opt // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetJettonHoldersData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonHoldersData, + ThrowOnError + >; } }; @@ -13083,15 +14555,18 @@ export const getJettonHolders = async (opt * @name GetJettonTransferPayload * @request GET:/v2/jettons/{jetton_id}/transfer/{account_id}/payload */ -export const getJettonTransferPayload = async (options: { +type GetJettonTransferPayloadOptions = { client?: TonApiClient; path: { - accountId: Address; - jettonId: Address; + accountId: Address | string; + jettonId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getJettonTransferPayload = async ( + options: GetJettonTransferPayloadOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getJettonTransferPayload( @@ -13102,16 +14577,22 @@ export const getJettonTransferPayload = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetJettonTransferPayloadData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonTransferPayloadData, + ThrowOnError + >; } }; @@ -13122,30 +14603,39 @@ export const getJettonTransferPayload = async (options: { +type GetJettonsEventsOptions = { client?: TonApiClient; path: { eventId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getJettonsEvents = async ( + options: GetJettonsEventsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getJettonsEvents(options.path.eventId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetJettonsEventsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetJettonsEventsData, + ThrowOnError + >; } }; @@ -13156,30 +14646,39 @@ export const getJettonsEvents = async (opt * @name GetExtraCurrencyInfo * @request GET:/v2/extra-currency/{id} */ -export const getExtraCurrencyInfo = async (options: { +type GetExtraCurrencyInfoOptions = { client?: TonApiClient; path: { id: number; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getExtraCurrencyInfo = async ( + options: GetExtraCurrencyInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getExtraCurrencyInfo(options.path.id, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetExtraCurrencyInfoData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetExtraCurrencyInfoData, + ThrowOnError + >; } }; @@ -13190,14 +14689,17 @@ export const getExtraCurrencyInfo = async * @name GetAccountNominatorsPools * @request GET:/v2/staking/nominator/{account_id}/pools */ -export const getAccountNominatorsPools = async (options: { +type GetAccountNominatorsPoolsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountNominatorsPools = async ( + options: GetAccountNominatorsPoolsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountNominatorsPools( @@ -13207,16 +14709,22 @@ export const getAccountNominatorsPools = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountNominatorsPoolsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountNominatorsPoolsData, + ThrowOnError + >; } }; @@ -13227,30 +14735,39 @@ export const getAccountNominatorsPools = async (options: { +type GetStakingPoolInfoOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getStakingPoolInfo = async ( + options: GetStakingPoolInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getStakingPoolInfo(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetStakingPoolInfoData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetStakingPoolInfoData, + ThrowOnError + >; } }; @@ -13261,30 +14778,39 @@ export const getStakingPoolInfo = async (o * @name GetStakingPoolHistory * @request GET:/v2/staking/pool/{account_id}/history */ -export const getStakingPoolHistory = async (options: { +type GetStakingPoolHistoryOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getStakingPoolHistory = async ( + options: GetStakingPoolHistoryOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getStakingPoolHistory(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetStakingPoolHistoryData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetStakingPoolHistoryData, + ThrowOnError + >; } }; @@ -13295,7 +14821,7 @@ export const getStakingPoolHistory = async (options?: { +type GetStakingPoolsOptions = { client?: TonApiClient; query?: { /** @@ -13312,23 +14838,29 @@ export const getStakingPools = async (opti }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getStakingPools = async ( + options?: GetStakingPoolsOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getStakingPools(options?.query, options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetStakingPoolsData, + ThrowOnError + >; } }; @@ -13339,27 +14871,36 @@ export const getStakingPools = async (opti * @name GetStorageProviders * @request GET:/v2/storage/providers */ -export const getStorageProviders = async (options?: { +type GetStorageProvidersOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getStorageProviders = async ( + options?: GetStorageProvidersOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getStorageProviders(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetStorageProvidersData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetStorageProvidersData, + ThrowOnError + >; } }; @@ -13370,7 +14911,7 @@ export const getStorageProviders = async ( * @name GetRates * @request GET:/v2/rates */ -export const getRates = async (options: { +type GetRatesOptions = { client?: TonApiClient; query: { /** @@ -13388,23 +14929,29 @@ export const getRates = async (options: { }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRates = async ( + options: GetRatesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRates(options.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRatesData, + ThrowOnError + >; } }; @@ -13415,7 +14962,7 @@ export const getRates = async (options: { * @name GetChartRates * @request GET:/v2/rates/chart */ -export const getChartRates = async (options: { +type GetChartRatesOptions = { client?: TonApiClient; query: { /** accept cryptocurrencies or jetton master addresses */ @@ -13444,23 +14991,29 @@ export const getChartRates = async (option }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getChartRates = async ( + options: GetChartRatesOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getChartRates(options.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetChartRatesData, + ThrowOnError + >; } }; @@ -13471,27 +15024,33 @@ export const getChartRates = async (option * @name GetMarketsRates * @request GET:/v2/rates/markets */ -export const getMarketsRates = async (options?: { +type GetMarketsRatesOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getMarketsRates = async ( + options?: GetMarketsRatesOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getMarketsRates(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetMarketsRatesData, + ThrowOnError + >; } }; @@ -13502,27 +15061,36 @@ export const getMarketsRates = async (opti * @name GetTonConnectPayload * @request GET:/v2/tonconnect/payload */ -export const getTonConnectPayload = async (options?: { +type GetTonConnectPayloadOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getTonConnectPayload = async ( + options?: GetTonConnectPayloadOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getTonConnectPayload(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetTonConnectPayloadData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetTonConnectPayloadData, + ThrowOnError + >; } }; @@ -13533,7 +15101,7 @@ export const getTonConnectPayload = async * @name GetAccountInfoByStateInit * @request POST:/v2/tonconnect/stateinit */ -export const getAccountInfoByStateInit = async (options: { +type GetAccountInfoByStateInitOptions = { client?: TonApiClient; body: { /** @format cell-base64 */ @@ -13541,23 +15109,32 @@ export const getAccountInfoByStateInit = async { +}; +export const getAccountInfoByStateInit = async ( + options: GetAccountInfoByStateInitOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountInfoByStateInit(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAccountInfoByStateInitData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountInfoByStateInitData, + ThrowOnError + >; } }; @@ -13568,7 +15145,7 @@ export const getAccountInfoByStateInit = async (options: { +type TonConnectProofOptions = { client?: TonApiClient; body: { /** @@ -13596,23 +15173,29 @@ export const tonConnectProof = async (opti }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const tonConnectProof = async ( + options: TonConnectProofOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.tonConnectProof(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + TonConnectProofData, + ThrowOnError + >; } }; @@ -13623,30 +15206,36 @@ export const tonConnectProof = async (opti * @name GetAccountSeqno * @request GET:/v2/wallet/{account_id}/seqno */ -export const getAccountSeqno = async (options: { +type GetAccountSeqnoOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAccountSeqno = async ( + options: GetAccountSeqnoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAccountSeqno(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountSeqnoData, + ThrowOnError + >; } }; @@ -13657,30 +15246,36 @@ export const getAccountSeqno = async (opti * @name GetWalletInfo * @request GET:/v2/wallet/{account_id} */ -export const getWalletInfo = async (options: { +type GetWalletInfoOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getWalletInfo = async ( + options: GetWalletInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getWalletInfo(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetWalletInfoData, + ThrowOnError + >; } }; @@ -13691,30 +15286,39 @@ export const getWalletInfo = async (option * @name GetWalletsByPublicKey * @request GET:/v2/pubkeys/{public_key}/wallets */ -export const getWalletsByPublicKey = async (options: { +type GetWalletsByPublicKeyOptions = { client?: TonApiClient; path: { publicKey: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getWalletsByPublicKey = async ( + options: GetWalletsByPublicKeyOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getWalletsByPublicKey(options.path.publicKey, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetWalletsByPublicKeyData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetWalletsByPublicKeyData, + ThrowOnError + >; } }; @@ -13725,27 +15329,33 @@ export const getWalletsByPublicKey = async (options?: { +type GaslessConfigOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const gaslessConfig = async ( + options?: GaslessConfigOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.gaslessConfig(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GaslessConfigData, + ThrowOnError + >; } }; @@ -13756,10 +15366,10 @@ export const gaslessConfig = async (option * @name GaslessEstimate * @request POST:/v2/gasless/estimate/{master_id} */ -export const gaslessEstimate = async (options: { +type GaslessEstimateOptions = { client?: TonApiClient; path: { - masterId: Address; + masterId: Address | string; }; body: { /** @@ -13779,7 +15389,10 @@ export const gaslessEstimate = async (opti }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const gaslessEstimate = async ( + options: GaslessEstimateOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.gaslessEstimate( @@ -13790,16 +15403,19 @@ export const gaslessEstimate = async (opti // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GaslessEstimateData, + ThrowOnError + >; } }; @@ -13810,7 +15426,7 @@ export const gaslessEstimate = async (opti * @name GaslessSend * @request POST:/v2/gasless/send */ -export const gaslessSend = async (options: { +type GaslessSendOptions = { client?: TonApiClient; body: { /** hex encoded public key */ @@ -13820,23 +15436,29 @@ export const gaslessSend = async (options: }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const gaslessSend = async ( + options: GaslessSendOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.gaslessSend(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GaslessSendData, + ThrowOnError + >; } }; @@ -13847,27 +15469,36 @@ export const gaslessSend = async (options: * @name GetRawMasterchainInfo * @request GET:/v2/liteserver/get_masterchain_info */ -export const getRawMasterchainInfo = async (options?: { +type GetRawMasterchainInfoOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawMasterchainInfo = async ( + options?: GetRawMasterchainInfoOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getRawMasterchainInfo(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawMasterchainInfoData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawMasterchainInfoData, + ThrowOnError + >; } }; @@ -13878,7 +15509,7 @@ export const getRawMasterchainInfo = async (options: { +type GetRawMasterchainInfoExtOptions = { client?: TonApiClient; query: { /** @@ -13890,23 +15521,32 @@ export const getRawMasterchainInfoExt = async { +}; +export const getRawMasterchainInfoExt = async ( + options: GetRawMasterchainInfoExtOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawMasterchainInfoExt(options.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawMasterchainInfoExtData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawMasterchainInfoExtData, + ThrowOnError + >; } }; @@ -13917,27 +15557,33 @@ export const getRawMasterchainInfoExt = async (options?: { +type GetRawTimeOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawTime = async ( + options?: GetRawTimeOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getRawTime(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawTimeData, + ThrowOnError + >; } }; @@ -13948,30 +15594,39 @@ export const getRawTime = async (options?: * @name GetRawBlockchainBlock * @request GET:/v2/liteserver/get_block/{block_id} */ -export const getRawBlockchainBlock = async (options: { +type GetRawBlockchainBlockOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawBlockchainBlock = async ( + options: GetRawBlockchainBlockOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawBlockchainBlock(options.path.blockId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawBlockchainBlockData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawBlockchainBlockData, + ThrowOnError + >; } }; @@ -13982,14 +15637,17 @@ export const getRawBlockchainBlock = async (options: { +type GetRawBlockchainBlockStateOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawBlockchainBlockState = async ( + options: GetRawBlockchainBlockStateOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawBlockchainBlockState( @@ -13999,16 +15657,22 @@ export const getRawBlockchainBlockState = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawBlockchainBlockStateData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawBlockchainBlockStateData, + ThrowOnError + >; } }; @@ -14019,7 +15683,7 @@ export const getRawBlockchainBlockState = async (options: { +type GetRawBlockchainBlockHeaderOptions = { client?: TonApiClient; path: { blockId: string; @@ -14034,7 +15698,10 @@ export const getRawBlockchainBlockHeader = async { +}; +export const getRawBlockchainBlockHeader = async ( + options: GetRawBlockchainBlockHeaderOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawBlockchainBlockHeader( @@ -14045,16 +15712,22 @@ export const getRawBlockchainBlockHeader = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawBlockchainBlockHeaderData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawBlockchainBlockHeaderData, + ThrowOnError + >; } }; @@ -14065,7 +15738,7 @@ export const getRawBlockchainBlockHeader = async (options: { +type SendRawMessageOptions = { client?: TonApiClient; body: { /** @format cell-base64 */ @@ -14073,23 +15746,29 @@ export const sendRawMessage = async (optio }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const sendRawMessage = async ( + options: SendRawMessageOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.sendRawMessage(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + SendRawMessageData, + ThrowOnError + >; } }; @@ -14100,10 +15779,10 @@ export const sendRawMessage = async (optio * @name GetRawAccountState * @request GET:/v2/liteserver/get_account_state/{account_id} */ -export const getRawAccountState = async (options: { +type GetRawAccountStateOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -14114,7 +15793,10 @@ export const getRawAccountState = async (o }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawAccountState = async ( + options: GetRawAccountStateOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawAccountState( @@ -14125,16 +15807,22 @@ export const getRawAccountState = async (o // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawAccountStateData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawAccountStateData, + ThrowOnError + >; } }; @@ -14145,7 +15833,7 @@ export const getRawAccountState = async (o * @name GetRawShardInfo * @request GET:/v2/liteserver/get_shard_info/{block_id} */ -export const getRawShardInfo = async (options: { +type GetRawShardInfoOptions = { client?: TonApiClient; path: { blockId: string; @@ -14171,7 +15859,10 @@ export const getRawShardInfo = async (opti }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawShardInfo = async ( + options: GetRawShardInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawShardInfo( @@ -14182,16 +15873,19 @@ export const getRawShardInfo = async (opti // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawShardInfoData, + ThrowOnError + >; } }; @@ -14202,30 +15896,39 @@ export const getRawShardInfo = async (opti * @name GetAllRawShardsInfo * @request GET:/v2/liteserver/get_all_shards_info/{block_id} */ -export const getAllRawShardsInfo = async (options: { +type GetAllRawShardsInfoOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getAllRawShardsInfo = async ( + options: GetAllRawShardsInfoOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getAllRawShardsInfo(options.path.blockId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetAllRawShardsInfoData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAllRawShardsInfoData, + ThrowOnError + >; } }; @@ -14236,10 +15939,10 @@ export const getAllRawShardsInfo = async ( * @name GetRawTransactions * @request GET:/v2/liteserver/get_transactions/{account_id} */ -export const getRawTransactions = async (options: { +type GetRawTransactionsOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query: { /** @@ -14262,7 +15965,10 @@ export const getRawTransactions = async (o }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawTransactions = async ( + options: GetRawTransactionsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawTransactions( @@ -14273,16 +15979,22 @@ export const getRawTransactions = async (o // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawTransactionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawTransactionsData, + ThrowOnError + >; } }; @@ -14293,7 +16005,7 @@ export const getRawTransactions = async (o * @name GetRawListBlockTransactions * @request GET:/v2/liteserver/list_block_transactions/{block_id} */ -export const getRawListBlockTransactions = async (options: { +type GetRawListBlockTransactionsOptions = { client?: TonApiClient; path: { blockId: string; @@ -14326,7 +16038,10 @@ export const getRawListBlockTransactions = async { +}; +export const getRawListBlockTransactions = async ( + options: GetRawListBlockTransactionsOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawListBlockTransactions( @@ -14337,16 +16052,22 @@ export const getRawListBlockTransactions = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawListBlockTransactionsData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawListBlockTransactionsData, + ThrowOnError + >; } }; @@ -14357,7 +16078,7 @@ export const getRawListBlockTransactions = async (options: { +type GetRawBlockProofOptions = { client?: TonApiClient; query: { /** @@ -14379,23 +16100,32 @@ export const getRawBlockProof = async (opt }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawBlockProof = async ( + options: GetRawBlockProofOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawBlockProof(options.query, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawBlockProofData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawBlockProofData, + ThrowOnError + >; } }; @@ -14406,7 +16136,7 @@ export const getRawBlockProof = async (opt * @name GetRawConfig * @request GET:/v2/liteserver/get_config_all/{block_id} */ -export const getRawConfig = async (options: { +type GetRawConfigOptions = { client?: TonApiClient; path: { blockId: string; @@ -14421,7 +16151,10 @@ export const getRawConfig = async (options }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawConfig = async ( + options: GetRawConfigOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawConfig( @@ -14432,16 +16165,19 @@ export const getRawConfig = async (options // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawConfigData, + ThrowOnError + >; } }; @@ -14452,30 +16188,39 @@ export const getRawConfig = async (options * @name GetRawShardBlockProof * @request GET:/v2/liteserver/get_shard_block_proof/{block_id} */ -export const getRawShardBlockProof = async (options: { +type GetRawShardBlockProofOptions = { client?: TonApiClient; path: { blockId: string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getRawShardBlockProof = async ( + options: GetRawShardBlockProofOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getRawShardBlockProof(options.path.blockId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetRawShardBlockProofData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRawShardBlockProofData, + ThrowOnError + >; } }; @@ -14486,27 +16231,36 @@ export const getRawShardBlockProof = async (options?: { +type GetOutMsgQueueSizesOptions = { client?: TonApiClient; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getOutMsgQueueSizes = async ( + options?: GetOutMsgQueueSizesOptions +): Promise> => { try { const client = options?.client || getDefaultClient(); const result = await client.getOutMsgQueueSizes(options?.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetOutMsgQueueSizesData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetOutMsgQueueSizesData, + ThrowOnError + >; } }; @@ -14517,30 +16271,39 @@ export const getOutMsgQueueSizes = async ( * @name GetMultisigAccount * @request GET:/v2/multisig/{account_id} */ -export const getMultisigAccount = async (options: { +type GetMultisigAccountOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getMultisigAccount = async ( + options: GetMultisigAccountOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getMultisigAccount(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetMultisigAccountData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetMultisigAccountData, + ThrowOnError + >; } }; @@ -14551,30 +16314,39 @@ export const getMultisigAccount = async (o * @name GetMultisigOrder * @request GET:/v2/multisig/order/{account_id} */ -export const getMultisigOrder = async (options: { +type GetMultisigOrderOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getMultisigOrder = async ( + options: GetMultisigOrderOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getMultisigOrder(options.path.accountId, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetMultisigOrderData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetMultisigOrderData, + ThrowOnError + >; } }; @@ -14585,7 +16357,7 @@ export const getMultisigOrder = async (opt * @name DecodeMessage * @request POST:/v2/message/decode */ -export const decodeMessage = async (options: { +type DecodeMessageOptions = { client?: TonApiClient; body: { /** @format cell */ @@ -14593,23 +16365,29 @@ export const decodeMessage = async (option }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const decodeMessage = async ( + options: DecodeMessageOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.decodeMessage(options.body, options.params); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + DecodeMessageData, + ThrowOnError + >; } }; @@ -14620,7 +16398,7 @@ export const decodeMessage = async (option * @name EmulateMessageToEvent * @request POST:/v2/events/emulate */ -export const emulateMessageToEvent = async (options: { +type EmulateMessageToEventOptions = { client?: TonApiClient; body: { /** @format cell */ @@ -14631,7 +16409,10 @@ export const emulateMessageToEvent = async { +}; +export const emulateMessageToEvent = async ( + options: EmulateMessageToEventOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.emulateMessageToEvent( @@ -14642,16 +16423,22 @@ export const emulateMessageToEvent = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + EmulateMessageToEventData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + EmulateMessageToEventData, + ThrowOnError + >; } }; @@ -14662,7 +16449,7 @@ export const emulateMessageToEvent = async (options: { +type EmulateMessageToTraceOptions = { client?: TonApiClient; body: { /** @format cell */ @@ -14673,7 +16460,10 @@ export const emulateMessageToTrace = async { +}; +export const emulateMessageToTrace = async ( + options: EmulateMessageToTraceOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.emulateMessageToTrace( @@ -14684,16 +16474,22 @@ export const emulateMessageToTrace = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + EmulateMessageToTraceData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + EmulateMessageToTraceData, + ThrowOnError + >; } }; @@ -14704,7 +16500,7 @@ export const emulateMessageToTrace = async (options: { +type EmulateMessageToWalletOptions = { client?: TonApiClient; body: { /** @format cell */ @@ -14729,7 +16525,10 @@ export const emulateMessageToWallet = async { +}; +export const emulateMessageToWallet = async ( + options: EmulateMessageToWalletOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.emulateMessageToWallet( @@ -14740,16 +16539,22 @@ export const emulateMessageToWallet = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + EmulateMessageToWalletData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + EmulateMessageToWalletData, + ThrowOnError + >; } }; @@ -14760,10 +16565,10 @@ export const emulateMessageToWallet = async (options: { +type EmulateMessageToAccountEventOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; body: { /** @format cell */ @@ -14774,7 +16579,10 @@ export const emulateMessageToAccountEvent = async { +}; +export const emulateMessageToAccountEvent = async ( + options: EmulateMessageToAccountEventOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.emulateMessageToAccountEvent( @@ -14786,16 +16594,22 @@ export const emulateMessageToAccountEvent = async ; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + EmulateMessageToAccountEventData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + EmulateMessageToAccountEventData, + ThrowOnError + >; } }; @@ -14806,10 +16620,10 @@ export const emulateMessageToAccountEvent = async (options: { +type GetPurchaseHistoryOptions = { client?: TonApiClient; path: { - accountId: Address; + accountId: Address | string; }; query?: { /** @@ -14828,7 +16642,10 @@ export const getPurchaseHistory = async (o }; params?: RequestParams; throwOnError?: ThrowOnError; -}) => { +}; +export const getPurchaseHistory = async ( + options: GetPurchaseHistoryOptions +): Promise> => { try { const client = options.client || getDefaultClient(); const result = await client.getPurchaseHistory( @@ -14839,15 +16656,21 @@ export const getPurchaseHistory = async (o // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync< + GetPurchaseHistoryData, + ThrowOnError + >; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync< + GetPurchaseHistoryData, + ThrowOnError + >; } }; diff --git a/packages/client/src/templates/procedure-call.ejs b/packages/client/src/templates/procedure-call.ejs index 372e756..effa5f3 100644 --- a/packages/client/src/templates/procedure-call.ejs +++ b/packages/client/src/templates/procedure-call.ejs @@ -46,7 +46,10 @@ const requestConfigParam = { defaultValue: "{}", } -const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue && optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`; +const argToTmpl = ({ name, optional, type, defaultValue }) => { + const paramType = type === 'Address' ? 'Address | string' : type; + return `${name}${!defaultValue && optional ? '?' : ''}: ${paramType}${defaultValue ? ` = ${defaultValue}` : ''}`; +}; const rawWrapperArgs = _.compact([ ...pathParams, @@ -88,9 +91,11 @@ const bodyContentKindTmpl = requestContentKind[requestBodyInfo.contentKind] || n const responseFormatTmpl = responseContentKind[successResponse.contentKind] || null; const securityTmpl = security ? 'true' : null; -const describeReturnType = () => !config.toJS ? '' : `MethodResult<${type}, ThrowOnError>`; +// For throwOnError: true, return PromiseWithError +// For throwOnError: false, return Promise> +const describeReturnType = () => `Promise>`; -const reducedPathParams = addressType.map((name) => `const ${name} = ${getNameAddressFromId(name)}.toRawString();`).join('\n'); +const reducedPathParams = addressType.map((name) => `const ${name} = addressToString(${getNameAddressFromId(name)});`).join('\n'); const rawRequestBody = route.raw.requestBody; const rawRequestBodySchema = rawRequestBody && rawRequestBody.$ref ? getComponentByRef(rawRequestBody.$ref) : rawRequestBody; @@ -107,7 +112,7 @@ const requestBodyTmpl = rawRequestBodySchemaContent ? `, ${JSON.stringify(utils. const queryAddressParams = route.routeParams.query.filter(param => param.format === 'address') const queryTmplValue = queryAddressParams.length === 0 ? queryTmpl : `${queryTmpl} && { ...${queryTmpl}, - ${queryAddressParams.map(param => `${param.name}: ${queryTmpl}.${param.name}?.toRawString()`).join(',\n')} + ${queryAddressParams.map(param => `${param.name}: addressToString(${queryTmpl}.${param.name})`).join(',\n')} }` const queryImplodeParams = route.routeParams.query. filter(param => param.explode === false) @@ -120,7 +125,8 @@ const generatePathFieldName = (param) => { return param.name.endsWith('_Address') ? param.name.slice(0, -8) : param.name; }; -const generateOptionsInterface = () => { +// Generate type declaration for options (e.g., type StatusOptions = {...}) +const generateOptionsTypeDeclaration = () => { const fields = []; // Always add client @@ -131,7 +137,8 @@ const generateOptionsInterface = () => { const pathFields = pathParams.map(param => { const fieldName = generatePathFieldName(param); const optional = param.optional ? '?' : ''; - return `${fieldName}${optional}: ${param.type}`; + const paramType = param.type === 'Address' ? 'Address | string' : param.type; + return `${fieldName}${optional}: ${paramType}`; }).join(';\n '); fields.push(`path: {\n ${pathFields};\n };`); } @@ -154,10 +161,17 @@ const generateOptionsInterface = () => { // Add throwOnError for conditional return type fields.push('throwOnError?: ThrowOnError;'); - return `{\n ${fields.join('\n ')}\n}`; + const typeName = _.upperFirst(route.routeName.usage) + 'Options'; + return `type ${typeName} = {\n ${fields.join('\n ')}\n};`; +}; + +// Generate the type name to use in function signature +const generateOptionsTypeName = () => { + const typeName = _.upperFirst(route.routeName.usage) + 'Options'; + return `${typeName}`; }; -const optionsType = generateOptionsInterface(); +const optionsType = generateOptionsTypeName(); const optionsArgument = `options${isOptionsRequired() ? '' : '?'}`; // Generate all arguments for calling the instance method @@ -199,29 +213,39 @@ const generateAllArguments = () => { */ <% if (isFlat) { %> -export const <%~ route.routeName.usage %> = async (<%~ optionsArgument %>: <%~ optionsType %>)<%~ config.toJS ? `: ${describeReturnType()}` : "" %> => { +<%~ generateOptionsTypeDeclaration() %> + +export const <%~ route.routeName.usage %> = async (<%~ optionsArgument %>: <%~ optionsType %>): <%~ describeReturnType() %> => { try { const client = <%= isOptionsRequired() ? 'options.client' : 'options?.client' %> || getDefaultClient(); const result = await client.<%~ route.routeName.usage %>(<%~ generateAllArguments() %>); // If throwOnError is true, return data directly if (options?.throwOnError) { - return result as any; + return result as MethodResultSync<<%~ type %>, ThrowOnError>; } - return { data: result, error: null } as any; + return { data: result, error: null } as MethodResultSync<<%~ type %>, ThrowOnError>; } catch (error) { // If throwOnError is true, rethrow the error if (options?.throwOnError) { throw error; } - return { data: null, error: error as TonApiError } as any; + return { data: null, error: error as TonApiError } as MethodResultSync<<%~ type %>, ThrowOnError>; } }; <% } else { %> -async <%~ route.routeName.usage %>(<%~ wrapperArgs %>)<%~ config.toJS ? `: Promise<${type}>` : "" %> { +/** +<%~ routeDocs.description %> + + *<% /* Here you can add some other JSDoc tags */ %> + +<%~ routeDocs.lines %> + + */ +<%~ route.routeName.usage %>(<%~ wrapperArgs %>): TonApiPromise<<%~ type %>, TonApiError> { <%~ reducedPathParams %> - const req = this.http.request<<%~ type %>, <%~ errorType %>>({ + const req = this.http.request<<%~ type %>, TonApiError>({ path: `<%~ path %>`, method: '<%~ _.upperCase(method) %>', <%~ queryTmpl ? `query: ${queryTmplValue},` : '' %> @@ -233,7 +257,7 @@ async <%~ route.routeName.usage %>(<%~ wrapperArgs %>)<%~ config.toJS ? `: Promi ...<%~ _.get(requestConfigParam, "name") %>, }); - return prepareResponse<<%~ type %>>(req<%~ schemaTmpl %>); + return prepareResponse<<%~ type %>, TonApiError>(req<%~ schemaTmpl %>); } <% } %> diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index 4a00285..1bba5b9 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -2,6 +2,16 @@ type ComponentRef = keyof typeof components; +/** + * Custom Promise interface with typed catch method + * This allows TypeScript to infer the correct error type in .catch() handlers + */ +export interface TonApiPromise extends Promise { + catch( + onrejected?: ((reason: E) => TResult | PromiseLike) | null | undefined + ): Promise; +} + export type Result = | { data: T; error: null } | { data: null; error: TonApiError }; @@ -17,6 +27,15 @@ export type Result = export type MethodResult = ThrowOnError extends true ? Promise : Promise>; +/** + * Sync version of MethodResult for use with async functions + * (async functions automatically wrap return type in Promise) + * When ThrowOnError is true, returns T but the Promise will reject with TonApiError + * When ThrowOnError is false, returns Result + */ +type MethodResultSync = + ThrowOnError extends true ? T : Result; + function snakeToCamel(snakeCaseString: string): string { return snakeCaseString.replace(/(_\w)/g, (match) => match[1]?.toUpperCase() ?? ''); } @@ -38,7 +57,21 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } -async function prepareResponse(promise: Promise, orSchema?: any): Promise { +function addressToString(value: Address | string | undefined): string | undefined { + if (value === undefined) { + return undefined; + } + const addr = typeof value === 'string' ? Address.parse(value) : value; + return addr.toRawString(); +} + +/** + * Prepares and validates API response data + * @template U - The success response type + * @template E - The error type (defaults to TonApiError) + * @throws {E} Always throws error of type E on failure + */ +function prepareResponse(promise: Promise, orSchema?: any): TonApiPromise { return promise .then(obj => { try { @@ -96,7 +129,7 @@ async function prepareResponse(promise: Promise, orSchema?: any): Promis } throw new TonApiUnknownError('Unknown error occurred', response); - }); + }) as TonApiPromise; } function prepareResponseData(obj: any, orSchema?: any, originalResponse: unknown = obj): U { @@ -266,7 +299,7 @@ function prepareRequestData(data: any, orSchema?: any): any { } else if (schema) { if (schema.type === 'string') { if (schema.format === 'address') { - return (data as Address).toRawString(); + return addressToString(data as Address | string); } if (schema.format === 'cell') { diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index 7fd64b6..188131e 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -1,5 +1,15 @@ import { initTa, ta } from './utils/client'; -import { status, getAccount, getAccounts, execGetMethodForBlockchainAccount, TonApiParsingError, TonApiHttpError, TonApiNetworkError, TonApiUnknownError, TonApiClient } from '@ton-api/client'; +import { + status, + getAccount, + getAccounts, + TonApiParsingError, + TonApiHttpError, + TonApiNetworkError, + TonApiUnknownError, + TonApiError, + TonApiClient +} from '@ton-api/client'; import { Address } from '@ton/core'; import { vi, test, expect, beforeEach, describe, afterEach } from 'vitest'; import { mockFetch } from './utils/mockFetch'; @@ -102,7 +112,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); test('should throw with string message', async () => { - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse('Simple error message', 500)); + vi.spyOn(global, 'fetch').mockResolvedValueOnce( + createJsonResponse('Simple error message', 500) + ); const error = await expectThrowingError(() => ta.status()); assertIsHttpError(error); @@ -245,7 +257,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -260,7 +274,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -274,7 +290,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -296,7 +314,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + const error = await expectThrowingError(() => + ta.execGetMethodForBlockchainAccount(address, 'get_data') + ); assertIsParsingError(error); expect(error.parsingType).toBe('Cell'); @@ -315,7 +335,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + const error = await expectThrowingError(() => + ta.execGetMethodForBlockchainAccount(address, 'get_data') + ); assertIsParsingError(error); expect(error.parsingType).toBe('Cell'); @@ -334,7 +356,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + const error = await expectThrowingError(() => + ta.execGetMethodForBlockchainAccount(address, 'get_data') + ); assertIsParsingError(error); expect(error.parsingType).toBe('Cell'); @@ -353,7 +377,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + const error = await expectThrowingError(() => + ta.execGetMethodForBlockchainAccount(address, 'get_data') + ); assertIsParsingError(error); expect(error.parsingType).toBe('Cell'); @@ -368,7 +394,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -382,7 +410,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -397,7 +427,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const result = await ta.getAccount(validAddress); // Empty string converts to 0n without error @@ -420,7 +452,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + const error = await expectThrowingError(() => + ta.execGetMethodForBlockchainAccount(address, 'get_data') + ); assertIsParsingError(error); expect(error.parsingType).toBe('TupleItem'); @@ -444,7 +478,9 @@ describe('Instance API - Primary approach (throws errors)', () => { }); const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - const error = await expectThrowingError(() => ta.execGetMethodForBlockchainAccount(address, 'get_data')); + const error = await expectThrowingError(() => + ta.execGetMethodForBlockchainAccount(address, 'get_data') + ); assertIsParsingError(error); expect(error.parsingType).toBe('TupleItem'); @@ -459,7 +495,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -473,7 +511,9 @@ describe('Instance API - Primary approach (throws errors)', () => { expect(typeof error.message).toBe('string'); expect(error.type).toBe('parsing_error'); - expect(['Address', 'Cell', 'BigInt', 'TupleItem', 'Unknown']).toContain(error.parsingType); + expect(['Address', 'Cell', 'BigInt', 'TupleItem', 'Unknown']).toContain( + error.parsingType + ); }); test('parsing_error should have correct structure', async () => { @@ -483,7 +523,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -505,7 +547,9 @@ describe('Instance API - Primary approach (throws errors)', () => { status: 'active' }); - const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const validAddress = Address.parse( + 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y' + ); const error = await expectThrowingError(() => ta.getAccount(validAddress)); assertIsParsingError(error); @@ -530,6 +574,7 @@ describe('Advanced API - Global methods (returns {data, error})', () => { const fetchSpy = mockFetch(mockData); const { data, error } = await status(); + expect(error).toBeNull(); expect(data).toBeDefined(); // Response is converted to camelCase @@ -706,22 +751,20 @@ describe('Advanced API - Global methods (returns {data, error})', () => { test('should throw specific error type when throwOnError is true', async () => { const mockError = { error: 'Not found' }; - vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 404)); + vi.spyOn(global, 'fetch').mockResolvedValue(createJsonResponse(mockError, 404)); const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); - try { - await getAccount({ - path: { accountId: validAddress }, - throwOnError: true - }); - // Should not reach here - expect(true).toBe(false); - } catch (error) { - assertIsHttpError(error); - expect(error.status).toBe(404); - expect(error.message).toContain('Not found'); - } + // Catch and verify error details + const error = await getAccount({ + path: { accountId: validAddress }, + throwOnError: true + }).catch(e => e); + + // Should throw TonApiHttpError with correct properties + assertIsHttpError(error); + expect(error.status).toBe(404); + expect(error.message).toBe('HTTP 404: Not found'); }); test('throwOnError false should still return Result type', async () => { @@ -736,5 +779,70 @@ describe('Advanced API - Global methods (returns {data, error})', () => { expect(result.error).toBeNull(); expect(result.data).toBeDefined(); }); + + test('should demonstrate type narrowing with if (error) check', async () => { + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + + // Test success case - type narrows to success branch + const mockData = { balance: 100n, status: 'active' }; + mockFetch(mockData); + + const successResult = await getAccount({ + path: { accountId: validAddress } + }); + + if (successResult.error) { + // Error branch - would have TonApiError and null data + fail('Should not have error in success case'); + } else { + // Success branch - TypeScript knows data is Account, error is null + expect(successResult.data).toBeDefined(); + expect(successResult.data.balance).toBe(100n); + expect(successResult.data.status).toBe('active'); + expect(successResult.error).toBeNull(); + } + + // Test error case - type narrows to error branch + const mockError = { error: 'Account not found' }; + vi.spyOn(global, 'fetch').mockResolvedValueOnce(createJsonResponse(mockError, 404)); + + const errorResult = await getAccount({ + path: { accountId: validAddress } + }); + + if (errorResult.error) { + // Error branch - TypeScript knows error is TonApiError, data is null + expect(errorResult.error).toBeInstanceOf(TonApiHttpError); + expect(errorResult.error.message).toContain('Account not found'); + expect(errorResult.data).toBeNull(); + } else { + // Success branch + fail('Should have error in error case'); + } + }); + + test('should support error recovery pattern with default values', async () => { + const validAddress = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const mockError = { error: 'Account not found' }; + mockFetch(mockError, 404); + + const { data, error } = await getAccount({ + path: { accountId: validAddress } + }); + + // Pattern 1: Using ternary for default value + const balance = error ? 0n : data.balance; + expect(balance).toBe(0n); + + // Pattern 2: Early return pattern + if (error) { + expect(error.message).toContain('Account not found'); + expect(data).toBeNull(); + return; // Early return in real code + } + + // This line won't be reached in this test + fail('Should have returned early on error'); + }); }); }); diff --git a/tests/client/type-tests.test.ts b/tests/client/type-tests.test.ts new file mode 100644 index 0000000..756088e --- /dev/null +++ b/tests/client/type-tests.test.ts @@ -0,0 +1,270 @@ +/** + * Type-level tests for conditional return types with ThrowOnError + * These tests verify that TypeScript correctly infers return types based on throwOnError parameter + */ + +import { test, expectTypeOf, vi, beforeEach } from 'vitest'; +import { + initClient, + TonApiClient, + status, + getAccount, + getAccounts, + TonApiHttpError, + type Result, + type ServiceStatus, + type Account, + type Accounts, + type TonApiError, + type TonApiPromise +} from '@ton-api/client'; +import { Address } from '@ton/core'; + +beforeEach(() => { + // Initialize client for global methods + initClient({ baseUrl: 'https://tonapi.io' }); + + // Mock fetch to prevent actual API calls during type tests + // These calls are never awaited - they're just for type checking + vi.spyOn(global, 'fetch').mockResolvedValue( + new Response(JSON.stringify({}), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }) + ); +}); + +test('Advanced API - Global methods with ThrowOnError', () => { + // Test 1: Without throwOnError (default = false) should return Result + expectTypeOf(status()).resolves.toEqualTypeOf>(); + + // Test 2: With throwOnError: false should return Result + expectTypeOf(status({ throwOnError: false })).resolves.toEqualTypeOf>(); + + // Test 3: With throwOnError: true should return T directly + expectTypeOf(status({ throwOnError: true })).resolves.toEqualTypeOf(); + + // Test 4: With throwOnError: true as const should return T directly + expectTypeOf(status({ throwOnError: true as const })).resolves.toEqualTypeOf(); + + // Test 5: With path parameters - throwOnError: false + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + expectTypeOf( + getAccount({ + path: { accountId: address }, + throwOnError: false + }) + ).resolves.toEqualTypeOf>(); + + // Test 6: With path parameters - throwOnError: true + expectTypeOf( + getAccount({ + path: { accountId: address }, + throwOnError: true + }) + ).resolves.toEqualTypeOf(); + + // Test 7: With path parameters - no throwOnError (default = false) + expectTypeOf( + getAccount({ + path: { accountId: address } + }) + ).resolves.toEqualTypeOf>(); + + // Test 8: With body and query parameters - throwOnError: false + expectTypeOf( + getAccounts({ + body: { accountIds: [address] }, + query: { currency: 'usd' }, + throwOnError: false + }) + ).resolves.toEqualTypeOf>(); + + // Test 9: With body and query parameters - throwOnError: true + expectTypeOf( + getAccounts({ + body: { accountIds: [address] }, + query: { currency: 'usd' }, + throwOnError: true + }) + ).resolves.toEqualTypeOf(); + + // Test 10: With body and query parameters - no throwOnError (default = false) + expectTypeOf( + getAccounts({ + body: { accountIds: [address] }, + query: { currency: 'usd' } + }) + ).resolves.toEqualTypeOf>(); + + // Test 11: Result type destructuring works correctly + // Result should match the exact union type with TonApiError + type ResultType = Result; + type ExpectedType = { data: ServiceStatus; error: null } | { data: null; error: TonApiError }; + expectTypeOf().toEqualTypeOf(); + + // Test 12: String address support + expectTypeOf( + getAccount({ + path: { accountId: 'EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin' } + }) + ).resolves.toEqualTypeOf>(); + + // Test 13: String address with throwOnError: true + expectTypeOf( + getAccount({ + path: { accountId: 'EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin' }, + throwOnError: true + }) + ).resolves.toEqualTypeOf(); + + // Test 14: Custom client in options + const customClient = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + expectTypeOf( + status({ + client: customClient, + throwOnError: false + }) + ).resolves.toEqualTypeOf>(); + + // Test 15: Custom client with throwOnError: true + expectTypeOf( + status({ + client: customClient, + throwOnError: true + }) + ).resolves.toEqualTypeOf(); +}); + +test('Instance API - TonApiClient methods', () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + + // Test 1: Instance method returns TonApiPromise + expectTypeOf(client.status()).toEqualTypeOf>(); + + // Test 2: Instance method with path parameters + expectTypeOf(client.getAccount(address)).toEqualTypeOf>(); + + // Test 3: Instance method resolves to T (not Result) + expectTypeOf(client.status()).resolves.toEqualTypeOf(); + + // Test 4: Instance method with Address parameter + expectTypeOf(client.getAccount(address)).resolves.toEqualTypeOf(); + + // Test 5: Instance method with string address + expectTypeOf( + client.getAccount('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin') + ).resolves.toEqualTypeOf(); + + // Test 6: Instance method with body and query + expectTypeOf( + client.getAccounts({ accountIds: [address] }, { currency: 'usd' }) + ).resolves.toEqualTypeOf(); + + // Test 7: TonApiPromise extends Promise + type StatusPromise = ReturnType; + type IsPromise = StatusPromise extends Promise ? true : false; + expectTypeOf().toEqualTypeOf(); +}); + +test('Typed .catch() for Instance API', () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + + // Test 1: .catch() error parameter is typed as TonApiError + const catchHandler1 = (_error: TonApiError) => null; + expectTypeOf(catchHandler1).parameter(0).toEqualTypeOf(); + + // Test 2: .catch() receives TonApiError and can access its properties + client.status().catch((error) => { + // Verify error type is inferred as TonApiError + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + + // Can access TonApiError properties + error.message; + error.type; + return null; + }); + + // Test 3: .catch() with type narrowing + client.getAccount(address).catch((error) => { + // Error is TonApiError + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + + // Can use instanceof for narrowing + if (error instanceof TonApiHttpError) { + error.status; + error.code; + error.url; + } + return null; + }); + + // Test 4: Promise chain return types + type ChainResult = ReturnType; + expectTypeOf().toEqualTypeOf>(); + + // Test 5: .then() preserves type + const thenResult = client.status().then(data => { + type DataType = typeof data; + expectTypeOf().toEqualTypeOf(); + return data.restOnline; + }); + expectTypeOf(thenResult).resolves.toEqualTypeOf(); +}); + +test('Promise chain typing for global methods', () => { + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + + // Test 1: throwOnError: true with .then() + const thenHandler1 = (data: Account) => data.balance; + expectTypeOf( + getAccount({ + path: { accountId: address }, + throwOnError: true + }).then(thenHandler1) + ).resolves.toEqualTypeOf(); + + // Test 2: throwOnError: false with .then() - receives Result + const thenHandler2 = (result: Result) => result.data; + expectTypeOf( + getAccount({ + path: { accountId: address }, + throwOnError: false + }).then(thenHandler2) + ).resolves.toEqualTypeOf(); + + // Test 3: throwOnError: true with .catch() - error is unknown (standard Promise) + const catchHandler = (_error: unknown) => null; + expectTypeOf(catchHandler).parameter(0).toEqualTypeOf(); +}); + +test('Result type usage patterns', () => { + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + + // Test 1: Destructuring Result type + type AccountResult = Result; + expectTypeOf().toEqualTypeOf< + { data: Account; error: null } | { data: null; error: TonApiError } + >(); + + // Test 2: Result enables type-safe error handling with if checks + // TypeScript will narrow types when checking result.error or result.data + type ResultHandler = (result: Result) => Account | null; + const handleResult: ResultHandler = (result) => { + // Can check error property + if (result.error) { + return null; + } + // TypeScript knows data is Account here + return result.data; + }; + + // Test 3: Result data property can be null in error case + type SuccessBranch = { data: Account; error: null }; + type ErrorBranch = { data: null; error: TonApiError }; + expectTypeOf>().toEqualTypeOf(); +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index 51d0445..37bac80 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -2,19 +2,10 @@ "compilerOptions": { "declaration": true, "sourceMap": true, - "lib": [ - "ES2015", - "ES2016", - "ES2017", - "ES2018", - "ES2019", - "ES2020", - "ESNext", - "dom" - ], + "lib": ["ESNext", "dom"], "module": "NodeNext", "moduleResolution": "NodeNext", - "target": "ES2022", + "target": "ES2020", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "importHelpers": false, diff --git a/tsconfig.json b/tsconfig.json index 217bcbb..ea01855 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,8 @@ "baseUrl": ".", "module": "ESNext", "moduleResolution": "bundler", + "target": "ESNext", + "lib": ["ESNext", "dom"], "paths": { "@ton-api/client": ["./packages/client/src/client.ts"], "@ton-api/ton-adapter": ["./packages/ton-adapter/src/index.ts"] From 9b28f2a4cdc90d1b9e05242945b26bd4a2a73bd9 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Fri, 14 Nov 2025 16:02:02 +0400 Subject: [PATCH 16/27] feat: add client-side validation and fix typed error handling - Add TonApiValidationError for Address/Cell string validation - Fix TonApiPromise to preserve typed .catch() through .then()/.finally() chains - Add cellToString() helper that validates and converts Cell strings to expected format - Simplify addressToString() to validate without parsing (returns string as-is) - Update README with concise validation note - Add validation tests for both Address and Cell (hex/base64) - Add promise chain typing tests --- package.json | 2 +- packages/client/README.md | 239 ++++++++++++++--------- packages/client/package.json | 2 +- packages/client/src/client.ts | 99 +++++++++- packages/client/src/templates/errors.ejs | 35 +++- packages/client/src/templates/utils.ejs | 57 +++++- tests/client/errors.test.ts | 213 +++++++++++++++++++- tests/client/type-tests.test.ts | 103 ++++++++++ 8 files changed, 641 insertions(+), 109 deletions(-) diff --git a/package.json b/package.json index 644471b..0b01395 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.4", + "version": "0.5.0-alpha.5", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/README.md b/packages/client/README.md index c00cd1b..04d6b56 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -2,32 +2,38 @@ ## Overview -`@ton-api/client` is an automatically generated SDK that provides seamless access to the endpoints offered by [tonapi.io](https://tonapi.io). This client is specifically designed to integrate with the TON blockchain, offering type-safe interactions and full compatibility with @ton/core library. +`@ton-api/client` is an automatically generated SDK that provides seamless access to the endpoints +offered by [tonapi.io](https://tonapi.io). This client is specifically designed to integrate with +the TON blockchain, offering type-safe interactions and full compatibility with @ton/core library. ## Documentation For detailed API information and endpoint descriptions, please refer to: -- [Official TonAPI Documentation](https://docs.tonconsole.com/tonapi/rest-api) -- [Swagger UI](https://tonapi.io/api-v2) - Interactive API explorer -- [TonAPI Cookbook](https://docs.tonconsole.com/tonapi/cookbook) - Usage examples and recipes + +- [Official TonAPI Documentation](https://docs.tonconsole.com/tonapi/rest-api) +- [Swagger UI](https://tonapi.io/api-v2) - Interactive API explorer +- [TonAPI Cookbook](https://docs.tonconsole.com/tonapi/cookbook) - Usage examples and recipes ## Features -- Full coverage of tonapi.io endpoints -- Type-safe interactions with the API -- Seamless integration with `@ton/core` -- Tree-shakeable imports for optimal bundle size -- Structured error handling with `{ data, error }` pattern -- Support for multiple client instances +- Full coverage of tonapi.io endpoints +- Type-safe interactions with the API +- Seamless integration with `@ton/core` +- Tree-shakeable imports for optimal bundle size +- Structured error handling with `{ data, error }` pattern +- Support for multiple client instances -Additionally, [`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/ton-adapter) enables users to work with contracts written for `@ton/ton` through `@ton-api/client`, ensuring seamless integration while maintaining their existing code structure. +Additionally, [`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/ton-adapter) enables +users to work with contracts written for `@ton/ton` through `@ton-api/client`, ensuring seamless +integration while maintaining their existing code structure. ## Prerequisites To use this SDK, you need to: 1. Set up an account at [tonconsole.com](https://tonconsole.com/) -2. Obtain an API key for authentication (optional for public endpoints, required for higher rate limits) +2. Obtain an API key for authentication (optional for public endpoints, required for higher rate + limits) ## Installation @@ -36,12 +42,14 @@ Install the package and its peer dependencies using npm, yarn, or pnpm: ```sh npm install @ton-api/client @ton/core buffer ``` + > Note: `@ton/core` is a peer dependency and needs to be installed separately. **Browser polyfill** + ```js // Add before using library -require("buffer"); +require('buffer'); ``` > **Buffer** polyfill is also required for work `@ton/core` on frontend projects. @@ -128,9 +136,7 @@ console.log('Accounts:', data.accounts); ```typescript import { getAccounts } from '@ton-api/client'; -const addresses = [ - Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin') -]; +const addresses = [Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin')]; // Pass both body and query parameters const { data, error } = await getAccounts({ @@ -189,7 +195,7 @@ console.log('Total supply:', data.totalSupply); ### Using Address as String -You can pass addresses either as `Address` objects or as strings: +You can pass addresses as `Address` objects or as strings: ```typescript import { getAccount } from '@ton-api/client'; @@ -197,7 +203,7 @@ import { Address } from '@ton/core'; // Using Address object const addressObject = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); -const { data: data1 } = await getAccount({ +const { data } = await getAccount({ path: { accountId: addressObject } }); @@ -207,9 +213,13 @@ const { data: data2 } = await getAccount({ }); ``` +> **Note:** When passing address/cell strings, invalid format will result in +> `TonApiValidationError`. When passing `Address` objects, this validation error won't occur. + ## Error Handling -By default, all methods return `{ data, error }` structure. This is the recommended way to handle errors: +By default, all methods return `{ data, error }` structure. This is the recommended way to handle +errors: ```typescript import { getAccount } from '@ton-api/client'; @@ -235,22 +245,53 @@ console.log('Balance:', data.balance); The SDK provides specific error types for different scenarios: ```typescript -import { getAccount, TonApiHttpError } from '@ton-api/client'; +import { + getAccount, + TonApiHttpError, + TonApiNetworkError, + TonApiValidationError, + TonApiParsingError +} from '@ton-api/client'; const { data, error } = await getAccount({ path: { accountId: address } }); -if (error instanceof TonApiHttpError) { - console.error('HTTP Error:', error.status); - console.error('Error code:', error.code); - console.error('Error message:', error.message); - console.error('Request URL:', error.url); -} - -if (error instanceof TonApiNetworkError) { - console.error('Network error:', error.message); - console.error('Original cause:', error.originalCause); +if (error) { + // Check specific error type + if (error instanceof TonApiValidationError) { + // Client-side validation error (invalid address/cell string) + console.error('Validation error:', error.validationType); // 'Address' or 'Cell' + console.error('Invalid input:', error.invalidInput); + } else if (error instanceof TonApiHttpError) { + // HTTP error from TonAPI (4xx, 5xx) + console.error('HTTP', error.status, error.code); + console.error('URL:', error.url); + } else if (error instanceof TonApiNetworkError) { + // Network error (connection failed, timeout) + console.error('Network error:', error.message); + console.error('Cause:', error.originalCause); + } else if (error instanceof TonApiParsingError) { + // SDK parsing error (unexpected API response format) + console.error('Parsing error:', error.parsingType); + console.error('Response:', error.response); + } + + // Or use discriminated union + switch (error.type) { + case 'validation_error': + console.log('Invalid', error.validationType, 'input:', error.invalidInput); + break; + case 'http_error': + console.log('HTTP', error.status, error.code); + break; + case 'network_error': + console.log('Network issue:', error.message); + break; + case 'parsing_error': + console.log('Parsing failed for', error.parsingType); + break; + } } ``` @@ -282,9 +323,7 @@ import { beginCell, external, storeMessage, Address } from '@ton/core'; const accountAddress = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); // Create your message (example) -const messageBody = beginCell() - .storeUint(0, 64) - .endCell(); +const messageBody = beginCell().storeUint(0, 64).endCell(); const messageBoc = beginCell() .store( @@ -338,8 +377,8 @@ const { data: mainnetData } = await getAccount({ }); // Use testnet client for specific call -const { data: testnetData } = await getAccount({ - client: testnetClient, +const { data: testnetData } = await getAccount({ + client: testnetClient, path: { accountId: address } }); ``` @@ -348,7 +387,8 @@ const { data: testnetData } = await getAccount({ ## Alternative: Instance API -If you prefer object-oriented approach or need complete isolation between client instances, you can use the Instance API. Instance API uses positional parameters instead of options objects. +If you prefer object-oriented approach or need complete isolation between client instances, you can +use the Instance API. Instance API uses positional parameters instead of options objects. ```typescript import { TonApiClient } from '@ton-api/client'; @@ -371,41 +411,43 @@ console.log('Account balance:', account.balance); Use the Instance API when you need: -- **Multiple clients with different configurations** - ```typescript - const mainnet = new TonApiClient({ - baseUrl: 'https://tonapi.io', - apiKey: 'KEY1' - }); - const testnet = new TonApiClient({ - baseUrl: 'https://testnet.tonapi.io', - apiKey: 'KEY2' - }); - - const mainnetAccount = await mainnet.getAccount(address); - const testnetAccount = await testnet.getAccount(address); - ``` - -- **Dependency injection in large applications** - ```typescript - class AccountService { - constructor(private tonapi: TonApiClient) {} - - async getBalance(address: Address) { - const account = await this.tonapi.getAccount(address); - return account.balance; - } - } - - const service = new AccountService(tonapi); - ``` - -- **Complete state isolation** - ```typescript - // Each instance is completely independent - const client1 = new TonApiClient({ baseUrl: 'https://tonapi.io' }); - const client2 = new TonApiClient({ baseUrl: 'https://tonapi.io' }); - ``` +- **Multiple clients with different configurations** + + ```typescript + const mainnet = new TonApiClient({ + baseUrl: 'https://tonapi.io', + apiKey: 'KEY1' + }); + const testnet = new TonApiClient({ + baseUrl: 'https://testnet.tonapi.io', + apiKey: 'KEY2' + }); + + const mainnetAccount = await mainnet.getAccount(address); + const testnetAccount = await testnet.getAccount(address); + ``` + +- **Dependency injection in large applications** + + ```typescript + class AccountService { + constructor(private tonapi: TonApiClient) {} + + async getBalance(address: Address) { + const account = await this.tonapi.getAccount(address); + return account.balance; + } + } + + const service = new AccountService(tonapi); + ``` + +- **Complete state isolation** + ```typescript + // Each instance is completely independent + const client1 = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const client2 = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + ``` ### Instance API Examples @@ -421,8 +463,8 @@ const addresses = [ // Parameters: data, query, params const accounts = await tonapi.getAccounts( - { accountIds: addresses }, // data (body) - { currency: 'usd' } // query parameters + { accountIds: addresses }, // data (body) + { currency: 'usd' } // query parameters ); console.log('Accounts:', accounts.accounts); @@ -438,11 +480,9 @@ const tonapi = new TonApiClient({ baseUrl: 'https://tonapi.io' }); const jettonMaster = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); const walletAddress = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); -const result = await tonapi.execGetMethodForBlockchainAccount( - jettonMaster, - 'get_wallet_address', - { args: [walletAddress.toRawString()] } -); +const result = await tonapi.execGetMethodForBlockchainAccount(jettonMaster, 'get_wallet_address', { + args: [walletAddress.toRawString()] +}); console.log('Jetton wallet:', result.decoded.jetton_wallet_address); ``` @@ -451,17 +491,27 @@ console.log('Jetton wallet:', result.decoded.jetton_wallet_address); Instance API throws exceptions on errors, so use `.catch()` for error handling. -**Advantage**: The Instance API provides **typed `.catch()`** - TypeScript knows the error type is `TonApiError`, not `unknown`! +**Advantage**: The Instance API provides **typed `.catch()`** - TypeScript knows the error type is +`TonApiError`, not `unknown`! Error typing is preserved even through `.then()` and `.finally()` +chains. ```typescript const tonapi = new TonApiClient({ baseUrl: 'https://tonapi.io' }); -const account = await tonapi.getAccount(address) +// Error typing is preserved through Promise chains +const account = await tonapi + .getAccount(address) + .then(acc => { + console.log('Fetched account'); + return acc; + }) .catch(error => { // ✨ TypeScript knows error is TonApiError (not unknown)! // You get autocomplete for error.message, error.type, etc. - if (error instanceof TonApiHttpError) { + if (error instanceof TonApiValidationError) { + console.error('Invalid address:', error.invalidInput); + } else if (error instanceof TonApiHttpError) { console.error('HTTP Error:', error.status, error.code); } else if (error instanceof TonApiNetworkError) { console.error('Network Error:', error.message); @@ -474,21 +524,28 @@ if (account) { } ``` -> **Note**: With the Advanced API using `throwOnError: true`, the `.catch()` error is `unknown` (standard Promise behavior). For typed error handling in `.catch()`, use the Instance API instead. +> **Note**: With the Advanced API using `throwOnError: true`, the `.catch()` error is `unknown` +> (standard Promise behavior). For typed error handling in `.catch()`, use the Instance API instead. ## Advanced Features For more advanced use cases, check out the examples in our repository: -- **[Transaction Emulation](https://github.com/tonkeeper/tonapi-js/blob/main/examples/emulate.ts)** - Emulate transactions before sending -- **[Gasless Transfers](https://github.com/tonkeeper/tonapi-js/blob/main/examples/gasless.ts)** - Send jettons without TON for gas -- **[Transaction Tracking](https://github.com/tonkeeper/tonapi-js/blob/main/examples/track-transaction.ts)** - Track transaction status by hash -- **[Sending TON](https://github.com/tonkeeper/tonapi-js/blob/main/examples/send-ton.ts)** - Complete example with wallet integration -- **[Sending Jettons](https://github.com/tonkeeper/tonapi-js/blob/main/examples/send-jetton.ts)** - Transfer jetton tokens +- **[Transaction Emulation](https://github.com/tonkeeper/tonapi-js/blob/main/examples/emulate.ts)** - + Emulate transactions before sending +- **[Gasless Transfers](https://github.com/tonkeeper/tonapi-js/blob/main/examples/gasless.ts)** - + Send jettons without TON for gas +- **[Transaction Tracking](https://github.com/tonkeeper/tonapi-js/blob/main/examples/track-transaction.ts)** - + Track transaction status by hash +- **[Sending TON](https://github.com/tonkeeper/tonapi-js/blob/main/examples/send-ton.ts)** - + Complete example with wallet integration +- **[Sending Jettons](https://github.com/tonkeeper/tonapi-js/blob/main/examples/send-jetton.ts)** - + Transfer jetton tokens ## Working with Contracts -For advanced contract interactions, use [`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/ton-adapter): +For advanced contract interactions, use +[`@ton-api/ton-adapter`](https://www.npmjs.com/package/@ton-api/ton-adapter): ```typescript import { TonApiClient } from '@ton-api/client'; @@ -511,9 +568,9 @@ const seqno = await contract.getSeqno(); For a complete list of available methods and their parameters, refer to: -- [Swagger UI](https://tonapi.io/api-v2) - Interactive API documentation -- [TonAPI Documentation](https://docs.tonconsole.com/tonapi) - Detailed guides and examples -- [GitHub Repository](https://github.com/tonkeeper/tonapi-js) - Source code and examples +- [Swagger UI](https://tonapi.io/api-v2) - Interactive API documentation +- [TonAPI Documentation](https://docs.tonconsole.com/tonapi) - Detailed guides and examples +- [GitHub Repository](https://github.com/tonkeeper/tonapi-js) - Source code and examples ## License diff --git a/packages/client/package.json b/packages/client/package.json index 1bf06e4..f5b65f6 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.4", + "version": "0.5.0-alpha.5", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index ca54331..8f23970 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3681,7 +3681,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.4` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.5` }; const preparedApiConfig = { @@ -6476,6 +6476,39 @@ export class TonApiParsingError extends TonApiErrorAbstract { } } +/** + * Validation error for client-side input validation + * Thrown when user provides invalid input (e.g., invalid address string, invalid Cell string) + * This happens before making any network request + * + * @example + * ```typescript + * if (error instanceof TonApiValidationError) { + * console.log('Validation type:', error.validationType); // 'Address' or 'Cell' + * console.log('Error message:', error.message); + * console.log('Invalid input:', error.invalidInput); + * } + * ``` + */ +export class TonApiValidationError extends TonApiErrorAbstract { + readonly type = 'validation_error' as const; + readonly validationType: 'Address' | 'Cell'; + readonly invalidInput: string; + + constructor( + validationType: 'Address' | 'Cell', + message: string, + invalidInput: string, + cause?: unknown + ) { + const formattedMessage = `Validation error [${validationType}]: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiValidationError'; + this.validationType = validationType; + this.invalidInput = invalidInput; + } +} + /** * Unknown error type * Thrown when an error occurs that doesn't fit other categories @@ -6514,6 +6547,8 @@ export class TonApiUnknownError extends TonApiErrorAbstract { * console.log(`Network error: ${error.message}`); * } else if (error instanceof TonApiParsingError) { * console.log(`Parsing ${error.parsingType} failed: ${error.message}`); + * } else if (error instanceof TonApiValidationError) { + * console.log(`Validation ${error.validationType} failed: ${error.message}`); * } else if (error instanceof TonApiUnknownError) { * console.log(`Unknown error: ${error.message}`); * } @@ -6529,6 +6564,9 @@ export class TonApiUnknownError extends TonApiErrorAbstract { * case 'parsing_error': * console.log(error.parsingType); * break; + * case 'validation_error': + * console.log(error.validationType, error.invalidInput); + * break; * case 'unknown_error': * console.log(error.originalCause); * break; @@ -6540,18 +6578,27 @@ export type TonApiError = | TonApiHttpError | TonApiNetworkError | TonApiParsingError + | TonApiValidationError | TonApiUnknownError; type ComponentRef = keyof typeof components; /** - * Custom Promise interface with typed catch method + * Custom Promise interface with typed error handling * This allows TypeScript to infer the correct error type in .catch() handlers + * and preserves error typing through .then() and .finally() chains */ export interface TonApiPromise extends Promise { + then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null | undefined, + onrejected?: ((reason: E) => TResult2 | PromiseLike) | null | undefined + ): TonApiPromise; + catch( onrejected?: ((reason: E) => TResult | PromiseLike) | null | undefined - ): Promise; + ): TonApiPromise; + + finally(onfinally?: (() => void) | null | undefined): TonApiPromise; } export type Result = { data: T; error: null } | { data: null; error: TonApiError }; @@ -6603,8 +6650,45 @@ function addressToString(value: Address | string | undefined): string | undefine if (value === undefined) { return undefined; } - const addr = typeof value === 'string' ? Address.parse(value) : value; - return addr.toRawString(); + + if (typeof value === 'string') { + // Validate format without parsing + if (!Address.isFriendly(value) && !Address.isRaw(value)) { + throw new TonApiValidationError('Address', `Invalid address format: ${value}`, value); + } + // Return string as-is, let the API handle it + return value; + } + + return value.toRawString(); +} + +function cellToString( + value: Cell | string | undefined, + format: 'hex' | 'base64' +): string | undefined { + if (value === undefined) { + return undefined; + } + + if (typeof value === 'string') { + // Parse and convert to expected format + let cell: Cell; + try { + cell = Cell.fromHex(value); + } catch { + try { + cell = Cell.fromBase64(value); + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiValidationError('Cell', `Invalid cell format: ${msg}`, value); + } + } + // Convert to expected format + return format === 'base64' ? cell.toBoc().toString('base64') : cell.toBoc().toString('hex'); + } + + return format === 'base64' ? value.toBoc().toString('base64') : value.toBoc().toString('hex'); } /** @@ -6640,6 +6724,7 @@ function prepareResponse( response instanceof TonApiParsingError || response instanceof TonApiNetworkError || response instanceof TonApiHttpError || + response instanceof TonApiValidationError || response instanceof TonApiUnknownError ) { throw response; @@ -6837,11 +6922,11 @@ function prepareRequestData(data: any, orSchema?: any): any { } if (schema.format === 'cell') { - return (data as Cell).toBoc().toString('hex'); + return cellToString(data as Cell | string, 'hex'); } if (schema.format === 'cell-base64') { - return (data as Cell).toBoc().toString('base64'); + return cellToString(data as Cell | string, 'base64'); } if (schema['x-js-format'] === 'bigint') { diff --git a/packages/client/src/templates/errors.ejs b/packages/client/src/templates/errors.ejs index b431297..12a89d1 100644 --- a/packages/client/src/templates/errors.ejs +++ b/packages/client/src/templates/errors.ejs @@ -111,6 +111,34 @@ export class TonApiParsingError extends TonApiErrorAbstract { } } +/** + * Validation error for client-side input validation + * Thrown when user provides invalid input (e.g., invalid address string, invalid Cell string) + * This happens before making any network request + * + * @example + * ```typescript + * if (error instanceof TonApiValidationError) { + * console.log('Validation type:', error.validationType); // 'Address' or 'Cell' + * console.log('Error message:', error.message); + * console.log('Invalid input:', error.invalidInput); + * } + * ``` + */ +export class TonApiValidationError extends TonApiErrorAbstract { + readonly type = 'validation_error' as const; + readonly validationType: 'Address' | 'Cell'; + readonly invalidInput: string; + + constructor(validationType: 'Address' | 'Cell', message: string, invalidInput: string, cause?: unknown) { + const formattedMessage = `Validation error [${validationType}]: ${message}`; + super(formattedMessage, cause); + this.name = 'TonApiValidationError'; + this.validationType = validationType; + this.invalidInput = invalidInput; + } +} + /** * Unknown error type * Thrown when an error occurs that doesn't fit other categories @@ -149,6 +177,8 @@ export class TonApiUnknownError extends TonApiErrorAbstract { * console.log(`Network error: ${error.message}`); * } else if (error instanceof TonApiParsingError) { * console.log(`Parsing ${error.parsingType} failed: ${error.message}`); + * } else if (error instanceof TonApiValidationError) { + * console.log(`Validation ${error.validationType} failed: ${error.message}`); * } else if (error instanceof TonApiUnknownError) { * console.log(`Unknown error: ${error.message}`); * } @@ -164,6 +194,9 @@ export class TonApiUnknownError extends TonApiErrorAbstract { * case 'parsing_error': * console.log(error.parsingType); * break; + * case 'validation_error': + * console.log(error.validationType, error.invalidInput); + * break; * case 'unknown_error': * console.log(error.originalCause); * break; @@ -171,4 +204,4 @@ export class TonApiUnknownError extends TonApiErrorAbstract { * } * ``` */ -export type TonApiError = TonApiHttpError | TonApiNetworkError | TonApiParsingError | TonApiUnknownError; +export type TonApiError = TonApiHttpError | TonApiNetworkError | TonApiParsingError | TonApiValidationError | TonApiUnknownError; diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index 1bba5b9..ea80e92 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -3,13 +3,21 @@ type ComponentRef = keyof typeof components; /** - * Custom Promise interface with typed catch method + * Custom Promise interface with typed error handling * This allows TypeScript to infer the correct error type in .catch() handlers + * and preserves error typing through .then() and .finally() chains */ export interface TonApiPromise extends Promise { + then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null | undefined, + onrejected?: ((reason: E) => TResult2 | PromiseLike) | null | undefined + ): TonApiPromise; + catch( onrejected?: ((reason: E) => TResult | PromiseLike) | null | undefined - ): Promise; + ): TonApiPromise; + + finally(onfinally?: (() => void) | null | undefined): TonApiPromise; } export type Result = @@ -57,12 +65,48 @@ function parseHexToBigInt(str: string) { return str.startsWith('-') ? BigInt(str.slice(1)) * -1n : BigInt(str); } + + function addressToString(value: Address | string | undefined): string | undefined { if (value === undefined) { return undefined; } - const addr = typeof value === 'string' ? Address.parse(value) : value; - return addr.toRawString(); + + if (typeof value === 'string') { + // Validate format without parsing + if (!Address.isFriendly(value) && !Address.isRaw(value)) { + throw new TonApiValidationError('Address', `Invalid address format: ${value}`, value); + } + // Return string as-is, let the API handle it + return value; + } + + return value.toRawString(); +} + +function cellToString(value: Cell | string | undefined, format: 'hex' | 'base64'): string | undefined { + if (value === undefined) { + return undefined; + } + + if (typeof value === 'string') { + // Parse and convert to expected format + let cell: Cell; + try { + cell = Cell.fromHex(value); + } catch { + try { + cell = Cell.fromBase64(value); + } catch (e) { + const msg = e instanceof Error ? e.message : String(e); + throw new TonApiValidationError('Cell', `Invalid cell format: ${msg}`, value); + } + } + // Convert to expected format + return format === 'base64' ? cell.toBoc().toString('base64') : cell.toBoc().toString('hex'); + } + + return format === 'base64' ? value.toBoc().toString('base64') : value.toBoc().toString('hex'); } /** @@ -93,6 +137,7 @@ function prepareResponse(promise: Promise, orSchema?: a if (response instanceof TonApiParsingError || response instanceof TonApiNetworkError || response instanceof TonApiHttpError || + response instanceof TonApiValidationError || response instanceof TonApiUnknownError) { throw response; } @@ -303,11 +348,11 @@ function prepareRequestData(data: any, orSchema?: any): any { } if (schema.format === 'cell') { - return (data as Cell).toBoc().toString('hex'); + return cellToString(data as Cell | string, 'hex'); } if (schema.format === 'cell-base64') { - return (data as Cell).toBoc().toString('base64'); + return cellToString(data as Cell | string, 'base64'); } if (schema['x-js-format'] === 'bigint') { diff --git a/tests/client/errors.test.ts b/tests/client/errors.test.ts index 188131e..a230ec8 100644 --- a/tests/client/errors.test.ts +++ b/tests/client/errors.test.ts @@ -3,15 +3,17 @@ import { status, getAccount, getAccounts, + sendBlockchainMessage, TonApiParsingError, TonApiHttpError, TonApiNetworkError, TonApiUnknownError, + TonApiValidationError, TonApiError, TonApiClient } from '@ton-api/client'; -import { Address } from '@ton/core'; -import { vi, test, expect, beforeEach, describe, afterEach } from 'vitest'; +import { Address, Cell } from '@ton/core'; +import { vi, test, expect, beforeEach, describe, afterEach, expectTypeOf } from 'vitest'; import { mockFetch } from './utils/mockFetch'; beforeEach(() => { @@ -846,3 +848,210 @@ describe('Advanced API - Global methods (returns {data, error})', () => { }); }); }); + +describe('TonApiValidationError - Client-side validation', () => { + beforeEach(() => { + vi.spyOn(global, 'fetch').mockResolvedValue( + new Response(JSON.stringify({ balance: '100', address: 'test', status: 'active' }), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }) + ); + }); + + test('Advanced API - Invalid address string returns TonApiValidationError', async () => { + const invalidAddress = 'invalid-address-format'; + + const result = await getAccount({ + path: { accountId: invalidAddress } + }); + + // Should return error, not throw + expect(result.error).toBeDefined(); + expect(result.data).toBeNull(); + + if (result.error) { + // Check it's a validation error + expect(result.error).toBeInstanceOf(TonApiValidationError); + expect(result.error.type).toBe('validation_error'); + + if (result.error instanceof TonApiValidationError) { + expect(result.error.validationType).toBe('Address'); + expect(result.error.invalidInput).toBe(invalidAddress); + expect(result.error.message).toContain('Address'); + } + } + }); + + test('Advanced API - Invalid address with throwOnError: true throws', async () => { + const invalidAddress = 'invalid-address-format'; + + try { + await getAccount({ + path: { accountId: invalidAddress }, + throwOnError: true + }); + expect.fail('Should have thrown TonApiValidationError'); + } catch (error) { + expect(error).toBeInstanceOf(TonApiValidationError); + + if (error instanceof TonApiValidationError) { + expect(error.validationType).toBe('Address'); + expect(error.invalidInput).toBe(invalidAddress); + } + } + }); + + test('Instance API - Invalid address throws TonApiValidationError', async () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const invalidAddress = 'invalid-address-format'; + + try { + await client.getAccount(invalidAddress); + expect.fail('Should have thrown TonApiValidationError'); + } catch (error) { + expect(error).toBeInstanceOf(TonApiValidationError); + + if (error instanceof TonApiValidationError) { + expect(error.validationType).toBe('Address'); + expect(error.invalidInput).toBe(invalidAddress); + expect(error.message).toContain('Validation error [Address]'); + } + } + }); + + test('Valid address string works correctly', async () => { + const validAddress = 'EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'; + + // Should not throw validation error (but might have parsing error from mock response) + const result = await getAccount({ + path: { accountId: validAddress } + }); + + // If there's an error, it should NOT be validation error + if (result.error) { + expect(result.error).not.toBeInstanceOf(TonApiValidationError); + } + }); + + test('TonApiValidationError is included in TonApiError union', () => { + const error = new TonApiValidationError('Address', 'test error', 'invalid'); + + // Should be assignable to TonApiError + const tonApiError: TonApiError = error; + + expect(tonApiError.type).toBe('validation_error'); + }); + + test('Advanced API - Invalid cell string returns TonApiValidationError', async () => { + const invalidCell = 'invalid-cell-string'; + + const result = await sendBlockchainMessage({ + body: { boc: invalidCell as any } + }); + + // Should return error, not throw + expect(result.error).toBeDefined(); + expect(result.data).toBeNull(); + + if (result.error) { + expect(result.error).toBeInstanceOf(TonApiValidationError); + expect(result.error.type).toBe('validation_error'); + + if (result.error instanceof TonApiValidationError) { + expect(result.error.validationType).toBe('Cell'); + expect(result.error.invalidInput).toBe(invalidCell); + expect(result.error.message).toContain('Cell'); + } + } + }); + + test('Advanced API - Invalid cell with throwOnError: true throws', async () => { + const invalidCell = 'not-a-valid-cell'; + + try { + await sendBlockchainMessage({ + body: { boc: invalidCell as any }, + throwOnError: true + }); + expect.fail('Should have thrown TonApiValidationError'); + } catch (error) { + expect(error).toBeInstanceOf(TonApiValidationError); + + if (error instanceof TonApiValidationError) { + expect(error.validationType).toBe('Cell'); + expect(error.invalidInput).toBe(invalidCell); + } + } + }); + + test('Instance API - Invalid cell throws TonApiValidationError', async () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const invalidCell = 'invalid-cell'; + + try { + await client.sendBlockchainMessage({ boc: invalidCell as any }); + expect.fail('Should have thrown TonApiValidationError'); + } catch (error) { + expect(error).toBeInstanceOf(TonApiValidationError); + + if (error instanceof TonApiValidationError) { + expect(error.validationType).toBe('Cell'); + expect(error.invalidInput).toBe(invalidCell); + expect(error.message).toContain('Validation error [Cell]'); + } + } + }); + + test('Valid cell hex string works correctly', async () => { + // Valid empty cell in hex format + const validCellHex = 'b5ee9c724101010100020000004cacb9cd'; + + const fetchSpy = vi.spyOn(global, 'fetch') + .mockResolvedValueOnce(new Response(null, { status: 200 })); + + const result = await sendBlockchainMessage({ + body: { boc: validCellHex as any } + }); + + // Should not have validation error + if (result.error) { + expect(result.error).not.toBeInstanceOf(TonApiValidationError); + } + + // Verify the cell hex was sent correctly (API expects hex for 'boc' field) + expect(fetchSpy).toHaveBeenCalledWith( + expect.any(String), + expect.objectContaining({ + method: 'POST', + body: JSON.stringify({ boc: validCellHex }) + }) + ); + }); + + test('Valid cell base64 string is converted to hex', async () => { + // Valid empty cell in base64 format + const validCellBase64 = 'te6cckEBAQEAAgAAAEysuc0='; + + const fetchSpy = vi.spyOn(global, 'fetch') + .mockResolvedValueOnce(new Response(null, { status: 200 })); + + const result = await sendBlockchainMessage({ + body: { boc: validCellBase64 as any } + }); + + // Should not have validation error + if (result.error) { + expect(result.error).not.toBeInstanceOf(TonApiValidationError); + } + + // Verify the cell was converted from base64 to hex format + expect(fetchSpy).toHaveBeenCalledWith( + expect.any(String), + expect.objectContaining({ + method: 'POST', + body: JSON.stringify({ boc: 'b5ee9c724101010100020000004cacb9cd' }) + }) + ); + }); +}); diff --git a/tests/client/type-tests.test.ts b/tests/client/type-tests.test.ts index 756088e..7b40cc0 100644 --- a/tests/client/type-tests.test.ts +++ b/tests/client/type-tests.test.ts @@ -268,3 +268,106 @@ test('Result type usage patterns', () => { type ErrorBranch = { data: null; error: TonApiError }; expectTypeOf>().toEqualTypeOf(); }); + +test('TonApiPromise - .then() preserves typed .catch()', () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + + // Test 1: After .then(), error should still be TonApiError (not unknown!) + const chainTest1 = client.status().then(data => { + return data.restOnline; + }); + + chainTest1.catch(error => { + type ErrorType = typeof error; + // ✅ Should be TonApiError, not unknown! + expectTypeOf().toEqualTypeOf(); + }); + + // Test 2: Multiple .then() chains preserve typing + const chainTest2 = client + .getAccount(address) + .then(account => account.balance) + .then(balance => balance.toString()); + + chainTest2.catch(error => { + type ErrorType = typeof error; + // ✅ Should be TonApiError + expectTypeOf().toEqualTypeOf(); + }); + + // Test 3: .then() with onrejected also works + const chainTest3 = client.status().then( + data => data.restOnline, + error => { + // error in onrejected should be TonApiError + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + return false; + } + ); + + chainTest3.catch(error => { + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + }); +}); + +test('TonApiPromise - .catch().then() preserves typing', () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + + const chainTest = client + .status() + .catch(error => { + // error is TonApiError ✅ + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + return null; + }) + .then(result => { + // result is ServiceStatus | null + type ResultType = typeof result; + expectTypeOf().toEqualTypeOf(); + return result; + }); + + // Subsequent .catch() should still have typed error + chainTest.catch(error => { + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + }); +}); + +test('TonApiPromise - .finally() preserves typing', () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + + const chainTest = client.status().finally(() => { + console.log('done'); + }); + + // After .finally(), error should still be TonApiError + chainTest.catch(error => { + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + }); +}); + +test('TonApiPromise - Complex chains preserve typing', () => { + const client = new TonApiClient({ baseUrl: 'https://tonapi.io' }); + const address = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); + + const complexChain = client + .getAccount(address) + .then(account => account.balance) + .then(balance => balance.toString()) + .finally(() => { + console.log('fetched balance'); + }) + .then(str => str.length); + + // After all these chains, error should still be TonApiError + complexChain.catch(error => { + type ErrorType = typeof error; + expectTypeOf().toEqualTypeOf(); + }); +}); From 0de0bc73e0db2f055be01ef633c12699166f3fbd Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Fri, 14 Nov 2025 17:06:08 +0400 Subject: [PATCH 17/27] chore: bump version to 0.5.0-alpha.6 in package.json and client package.json; add ScaledUI schema to API --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/api.yml | 26 +++++++++++++++------- packages/client/src/client.ts | 39 ++++++++++++++++++++++----------- packages/client/src/generate.ts | 2 +- 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 0b01395..e957f01 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.5", + "version": "0.5.0-alpha.6", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index f5b65f6..75291e4 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.5", + "version": "0.5.0-alpha.6", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index 93aa773..ab31cd6 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -5660,6 +5660,22 @@ components: score: type: integer format: int32 + scaled_ui: + $ref: '#/components/schemas/ScaledUI' + ScaledUI: + type: object + required: + - numerator + - denominator + properties: + numerator: + type: string + x-js-format: bigint + example: '597968399' + denominator: + type: string + x-js-format: bigint + example: '597968399' JettonBalance: type: object required: @@ -5671,10 +5687,6 @@ components: type: string x-js-format: bigint example: '597968399' - scaled_ui_balance: - type: string - x-js-format: bigint - example: '597968399' price: $ref: '#/components/schemas/TokenRates' wallet_address: @@ -6410,10 +6422,6 @@ components: x-js-format: bigint example: '1000000000' description: amount in quanta of tokens - scaled_ui_amount: - type: string - x-js-format: bigint - example: '1100000000' comment: type: string example: |- @@ -7474,6 +7482,8 @@ components: type: integer format: int32 example: 2000 + scaled_ui: + $ref: '#/components/schemas/ScaledUI' JettonHolders: type: object required: diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 8f23970..8be8bcd 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -1521,19 +1521,28 @@ export interface JettonPreview { customPayloadApiUri?: string; /** @format int32 */ score: number; + scaledUi?: ScaledUI; } -export interface JettonBalance { +export interface ScaledUI { /** * @format bigint * @example "597968399" */ - balance: bigint; + numerator: bigint; + /** + * @format bigint + * @example "597968399" + */ + denominator: bigint; +} + +export interface JettonBalance { /** * @format bigint * @example "597968399" */ - scaledUiBalance?: bigint; + balance: bigint; price?: TokenRates; walletAddress: AccountAddress; jetton: JettonPreview; @@ -1990,11 +1999,6 @@ export interface JettonTransferAction { * @example "1000000000" */ amount: bigint; - /** - * @format bigint - * @example "1100000000" - */ - scaledUiAmount?: bigint; /** * @example "Hi! This is your salary. * From accounting with love." @@ -2668,6 +2672,7 @@ export interface JettonInfo { * @example 2000 */ holdersCount: number; + scaledUi?: ScaledUI; } export interface JettonHolders { @@ -3681,7 +3686,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.5` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.6` }; const preparedApiConfig = { @@ -5064,7 +5069,16 @@ const components = { image: { type: 'string' }, verification: { $ref: '#/components/schemas/JettonVerificationType' }, custom_payload_api_uri: { type: 'string' }, - score: { type: 'integer', format: 'int32' } + score: { type: 'integer', format: 'int32' }, + scaled_ui: { $ref: '#/components/schemas/ScaledUI' } + } + }, + '#/components/schemas/ScaledUI': { + type: 'object', + required: ['numerator', 'denominator'], + properties: { + numerator: { type: 'string', 'x-js-format': 'bigint' }, + denominator: { type: 'string', 'x-js-format': 'bigint' } } }, '#/components/schemas/JettonBalance': { @@ -5072,7 +5086,6 @@ const components = { required: ['balance', 'wallet_address', 'jetton'], properties: { balance: { type: 'string', 'x-js-format': 'bigint' }, - scaled_ui_balance: { type: 'string', 'x-js-format': 'bigint' }, price: { $ref: '#/components/schemas/TokenRates' }, wallet_address: { $ref: '#/components/schemas/AccountAddress' }, jetton: { $ref: '#/components/schemas/JettonPreview' }, @@ -5470,7 +5483,6 @@ const components = { senders_wallet: { type: 'string', format: 'address' }, recipients_wallet: { type: 'string', format: 'address' }, amount: { type: 'string', 'x-js-format': 'bigint' }, - scaled_ui_amount: { type: 'string', 'x-js-format': 'bigint' }, comment: { type: 'string' }, encrypted_comment: { $ref: '#/components/schemas/EncryptedComment' }, refund: { $ref: '#/components/schemas/Refund' }, @@ -6029,7 +6041,8 @@ const components = { metadata: { $ref: '#/components/schemas/JettonMetadata' }, preview: { type: 'string' }, verification: { $ref: '#/components/schemas/JettonVerificationType' }, - holders_count: { type: 'integer', format: 'int32' } + holders_count: { type: 'integer', format: 'int32' }, + scaled_ui: { $ref: '#/components/schemas/ScaledUI' } } }, '#/components/schemas/JettonHolders': { diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index dd65db7..17d1ba2 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -232,7 +232,7 @@ const generateApiParams: GenerateApiParams = { async function main() { // Download schema and apply patches automatically // await downloadSchema(openapiUrl, openapiPath); - // applySchemaPatches(openapiPath, schemaPatchesPath); + applySchemaPatches(openapiPath, schemaPatchesPath); generateApi(generateApiParams); } From f07dd34d5c6ef7c8d52e48205a36c550f7bbbe1a Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Tue, 18 Nov 2025 11:44:29 +0400 Subject: [PATCH 18/27] feat: enhance API schema and client functionality - Added integration test command to run API tests with real calls. - Introduced new `test:integration` script in package.json for integration testing. - Updated API schema to improve documentation and support for token-or-address format. - Refactored client methods to handle Address and string types seamlessly. - Enhanced utility functions for better serialization of Address objects. - Updated tests to validate mixed usage of Address objects, cryptocurrency codes, and strings. --- package.json | 1 + packages/client/src/api.yml | 26 +-- packages/client/src/client.ts | 159 +++++++++------- packages/client/src/generate.ts | 131 +++++++++++--- packages/client/src/schema-patches.json | 159 ---------------- packages/client/src/schema-patches.jsonc | 62 +++++++ packages/client/src/templates/http-client.ejs | 3 +- .../client/src/templates/procedure-call.ejs | 43 ++++- packages/client/src/templates/utils.ejs | 30 ++- tests/adapters/index.test.ts | 55 ++++-- tests/adapters/readme.test.ts | 26 +-- tests/adapters/utils/test-helpers.ts | 171 ++++++++++++++++++ tests/client/integration.test.ts | 140 ++++++++++++++ tests/client/parse-address.test.ts | 4 +- tests/client/services.test.ts | 76 +++++++- 15 files changed, 787 insertions(+), 299 deletions(-) delete mode 100644 packages/client/src/schema-patches.json create mode 100644 packages/client/src/schema-patches.jsonc create mode 100644 tests/adapters/utils/test-helpers.ts create mode 100644 tests/client/integration.test.ts diff --git a/package.json b/package.json index e957f01..37f9dff 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "test": "vitest run tests/", "test:client": "vitest run tests/client", "test:adapters": "vitest run tests/adapters", + "test:integration": "INTEGRATION=true vitest run tests/client/integration.test.ts", "test:watch": "vitest", "build": "turbo run build", "build:client": "turbo run build --filter=@ton-api/client", diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index ab31cd6..d2c882d 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -1789,22 +1789,22 @@ paths: parameters: - in: query name: tokens - description: accept cryptocurrencies or jetton master addresses, separated by commas + description: accept cryptocurrencies and jetton master addresses, separated by commas required: true explode: false schema: type: array maxItems: 100 items: - oneOf: - - type: string - format: address - - type: string + type: string + x-js-format: token-or-address example: - ton + - btc + - EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs - in: query name: currencies - description: accept cryptocurrencies and all possible fiat currencies, separated by commas + description: accept cryptocurrencies and all possible fiat currencies required: true explode: false schema: @@ -1814,6 +1814,7 @@ paths: type: string example: - ton + - btc - usd - rub responses: @@ -1841,13 +1842,16 @@ paths: parameters: - in: query name: token - description: accept cryptocurrencies or jetton master addresses + description: accept cryptocurrency or jetton master address required: true schema: - oneOf: - - type: string - format: address - - type: string + type: string + x-js-format: token-or-address + example: + - value: ton + description: cryptocurrency code (ton, btc, etc.) + - value: EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs + description: jetton master address usdt for example - in: query name: currency required: false diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 8be8bcd..56e0219 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3715,7 +3715,8 @@ class HttpClient { .map((val: any) => encodeURIComponent(typeof val === 'number' ? val : `${val}`)) .join(','); - return this.encodeQueryParam(key, value); + // Don't double-encode: value is already encoded, only encode the key + return `${encodeURIComponent(key)}=${value}`; } protected addArrayQueryParam(query: QueryParamsType, key: string, implodeParams?: string[]) { @@ -6673,6 +6674,22 @@ function addressToString(value: Address | string | undefined): string | undefine return value; } + // Return raw format for Address objects + return value.toRawString(); +} + +function tokenOrAddressToString(value: Address | string | undefined): string | undefined { + if (value === undefined) { + return undefined; + } + + if (typeof value === 'string') { + // Return string as-is without validation + // This allows cryptocurrency codes like "ton", "btc" to pass through + return value; + } + + // Return raw format for Address objects return value.toRawString(); } @@ -6930,6 +6947,16 @@ function prepareRequestData(data: any, orSchema?: any): any { return data.map(item => prepareRequestData(item, itemSchema)); } else if (schema) { if (schema.type === 'string') { + // Check x-js-format first for custom formats + if (schema['x-js-format'] === 'token-or-address') { + return tokenOrAddressToString(data as Address | string); + } + + if (schema['x-js-format'] === 'bigint') { + return (data as bigint).toString(); + } + + // Then check standard format field if (schema.format === 'address') { return addressToString(data as Address | string); } @@ -6941,10 +6968,6 @@ function prepareRequestData(data: any, orSchema?: any): any { if (schema.format === 'cell-base64') { return cellToString(data as Cell | string, 'base64'); } - - if (schema['x-js-format'] === 'bigint') { - return (data as bigint).toString(); - } } } @@ -7711,9 +7734,9 @@ export class TonApiClient { sendBlockchainMessage( data: { /** @format cell */ - boc?: Cell; + boc?: Cell | string; /** @maxItems 5 */ - batch?: Cell[]; + batch?: (Cell | string)[]; meta?: Record; }, params: RequestParams = {} @@ -7874,7 +7897,7 @@ export class TonApiClient { */ getAccounts( data: { - accountIds: Address[]; + accountIds: (Address | string)[]; }, query?: { /** @example "usd" */ @@ -8186,7 +8209,7 @@ export class TonApiClient { * @format address * @example "0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465" */ - collection?: Address; + collection?: Address | string; /** * @min 1 * @max 1000 @@ -8886,7 +8909,7 @@ export class TonApiClient { */ getNftCollectionItemsByAddresses( data: { - accountIds: Address[]; + accountIds: (Address | string)[]; }, params: RequestParams = {} ): TonApiPromise { @@ -8970,7 +8993,7 @@ export class TonApiClient { */ getNftItemsByAddresses( data: { - accountIds: Address[]; + accountIds: (Address | string)[]; }, params: RequestParams = {} ): TonApiPromise { @@ -9370,7 +9393,7 @@ export class TonApiClient { */ getJettonInfosByAddresses( data: { - accountIds: Address[]; + accountIds: (Address | string)[]; }, params: RequestParams = {} ): TonApiPromise { @@ -9655,7 +9678,7 @@ export class TonApiClient { * @format address * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" */ - available_for?: Address; + available_for?: Address | string; /** * return also pools not from white list - just compatible by interfaces (maybe dangerous!) * @example false @@ -9741,15 +9764,15 @@ export class TonApiClient { getRates( query: { /** - * accept cryptocurrencies or jetton master addresses, separated by commas + * accept cryptocurrencies and jetton master addresses, separated by commas * @maxItems 100 - * @example ["ton"] + * @example ["ton","btc","EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"] */ tokens: (Address | string)[]; /** - * accept cryptocurrencies and all possible fiat currencies, separated by commas + * accept cryptocurrencies and all possible fiat currencies * @maxItems 50 - * @example ["ton","usd","rub"] + * @example ["ton","btc","usd","rub"] */ currencies: string[]; }, @@ -9758,7 +9781,10 @@ export class TonApiClient { const req = this.http.request({ path: `/v2/rates`, method: 'GET', - query: query, + query: query && { + ...query, + tokens: query.tokens.map(item => tokenOrAddressToString(item)) + }, queryImplode: ['tokens', 'currencies'], format: 'json', ...params @@ -9792,7 +9818,11 @@ export class TonApiClient { */ getChartRates( query: { - /** accept cryptocurrencies or jetton master addresses */ + /** + * accept cryptocurrency or jetton master address + * @format token-or-address + * @example [{"value":"ton","description":"cryptocurrency code (ton, btc, etc.)"},{"value":"EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs","description":"jetton master address usdt for example"}] + */ token: Address | string; /** @example "usd" */ currency?: string; @@ -9821,7 +9851,10 @@ export class TonApiClient { const req = this.http.request({ path: `/v2/rates/chart`, method: 'GET', - query: query, + query: query && { + ...query, + token: tokenOrAddressToString(query.token) + }, format: 'json', ...params }); @@ -9914,7 +9947,7 @@ export class TonApiClient { getAccountInfoByStateInit( data: { /** @format cell-base64 */ - stateInit: Cell; + stateInit: Cell | string; }, params: RequestParams = {} ): TonApiPromise { @@ -9955,7 +9988,7 @@ export class TonApiClient { * @format address * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" */ - address: Address; + address: Address | string; proof: { /** * @format int64 @@ -9971,7 +10004,7 @@ export class TonApiClient { /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ payload: string; /** @format cell-base64 */ - stateInit?: Cell; + stateInit?: Cell | string; }; }, params: RequestParams = {} @@ -10159,11 +10192,11 @@ export class TonApiClient { /** @default false */ returnEmulation?: boolean; /** @format address */ - walletAddress: Address; + walletAddress: Address | string; walletPublicKey: string; messages: { /** @format cell */ - boc: Cell; + boc: Cell | string; }[]; }, params: RequestParams = {} @@ -10218,7 +10251,7 @@ export class TonApiClient { /** hex encoded public key */ walletPublicKey: string; /** @format cell */ - boc: Cell; + boc: Cell | string; }, params: RequestParams = {} ): TonApiPromise { @@ -10495,7 +10528,7 @@ export class TonApiClient { sendRawMessage( data: { /** @format cell-base64 */ - body: Cell; + body: Cell | string; }, params: RequestParams = {} ): TonApiPromise { @@ -10748,7 +10781,7 @@ export class TonApiClient { * @format address * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" */ - account_id?: Address; + account_id?: Address | string; /** * lt * @format int64 @@ -11135,7 +11168,7 @@ export class TonApiClient { decodeMessage( data: { /** @format cell */ - boc: Cell; + boc: Cell | string; }, params: RequestParams = {} ): TonApiPromise { @@ -11173,7 +11206,7 @@ export class TonApiClient { emulateMessageToEvent( data: { /** @format cell */ - boc: Cell; + boc: Cell | string; }, query?: { ignore_signature_check?: boolean; @@ -11215,7 +11248,7 @@ export class TonApiClient { emulateMessageToTrace( data: { /** @format cell */ - boc: Cell; + boc: Cell | string; }, query?: { ignore_signature_check?: boolean; @@ -11257,14 +11290,14 @@ export class TonApiClient { emulateMessageToWallet( data: { /** @format cell */ - boc: Cell; + boc: Cell | string; /** additional per account configuration */ params?: { /** * @format address * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" */ - address: Address; + address: Address | string; /** * @format bigint * @example 10000000000 @@ -11331,7 +11364,7 @@ export class TonApiClient { accountId_Address: Address | string, data: { /** @format cell */ - boc: Cell; + boc: Cell | string; }, query?: { ignore_signature_check?: boolean; @@ -12438,9 +12471,9 @@ type SendBlockchainMessageOptions = { client?: TonApiClient; body: { /** @format cell */ - boc?: Cell; + boc?: Cell | string; /** @maxItems 5 */ - batch?: Cell[]; + batch?: (Cell | string)[]; meta?: Record; }; params?: RequestParams; @@ -12653,7 +12686,7 @@ export const getLibraryByHash = async ( type GetAccountsOptions = { client?: TonApiClient; body: { - accountIds: Address[]; + accountIds: (Address | string)[]; }; query?: { /** @example "usd" */ @@ -13045,7 +13078,7 @@ type GetAccountNftItemsOptions = { * @format address * @example "0:06d811f426598591b32b2c49f29f66c821368e4acb1de16762b04e0174532465" */ - collection?: Address; + collection?: Address | string; /** * @min 1 * @max 1000 @@ -13943,7 +13976,7 @@ export const getNftCollection = async ( type GetNftCollectionItemsByAddressesOptions = { client?: TonApiClient; body: { - accountIds: Address[]; + accountIds: (Address | string)[]; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -14046,7 +14079,7 @@ export const getItemsFromCollection = async = { client?: TonApiClient; body: { - accountIds: Address[]; + accountIds: (Address | string)[]; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -14552,7 +14585,7 @@ export const getJettonInfo = async ( type GetJettonInfosByAddressesOptions = { client?: TonApiClient; body: { - accountIds: Address[]; + accountIds: (Address | string)[]; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -14927,7 +14960,7 @@ type GetStakingPoolsOptions = { * @format address * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" */ - available_for?: Address; + available_for?: Address | string; /** * return also pools not from white list - just compatible by interfaces (maybe dangerous!) * @example false @@ -15013,15 +15046,15 @@ type GetRatesOptions = { client?: TonApiClient; query: { /** - * accept cryptocurrencies or jetton master addresses, separated by commas + * accept cryptocurrencies and jetton master addresses, separated by commas * @maxItems 100 - * @example ["ton"] + * @example ["ton","btc","EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"] */ tokens: (Address | string)[]; /** - * accept cryptocurrencies and all possible fiat currencies, separated by commas + * accept cryptocurrencies and all possible fiat currencies * @maxItems 50 - * @example ["ton","usd","rub"] + * @example ["ton","btc","usd","rub"] */ currencies: string[]; }; @@ -15063,7 +15096,11 @@ export const getRates = async ( type GetChartRatesOptions = { client?: TonApiClient; query: { - /** accept cryptocurrencies or jetton master addresses */ + /** + * accept cryptocurrency or jetton master address + * @format token-or-address + * @example [{"value":"ton","description":"cryptocurrency code (ton, btc, etc.)"},{"value":"EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs","description":"jetton master address usdt for example"}] + */ token: Address | string; /** @example "usd" */ currency?: string; @@ -15203,7 +15240,7 @@ type GetAccountInfoByStateInitOptions = { client?: TonApiClient; body: { /** @format cell-base64 */ - stateInit: Cell; + stateInit: Cell | string; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -15250,7 +15287,7 @@ type TonConnectProofOptions = { * @format address * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" */ - address: Address; + address: Address | string; proof: { /** * @format int64 @@ -15266,7 +15303,7 @@ type TonConnectProofOptions = { /** @example "84jHVNLQmZsAAAAAZB0Zryi2wqVJI-KaKNXOvCijEi46YyYzkaSHyJrMPBMOkVZa" */ payload: string; /** @format cell-base64 */ - stateInit?: Cell; + stateInit?: Cell | string; }; }; params?: RequestParams; @@ -15478,11 +15515,11 @@ type GaslessEstimateOptions = { /** @default false */ returnEmulation?: boolean; /** @format address */ - walletAddress: Address; + walletAddress: Address | string; walletPublicKey: string; messages: { /** @format cell */ - boc: Cell; + boc: Cell | string; }[]; }; params?: RequestParams; @@ -15530,7 +15567,7 @@ type GaslessSendOptions = { /** hex encoded public key */ walletPublicKey: string; /** @format cell */ - boc: Cell; + boc: Cell | string; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -15840,7 +15877,7 @@ type SendRawMessageOptions = { client?: TonApiClient; body: { /** @format cell-base64 */ - body: Cell; + body: Cell | string; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -16126,7 +16163,7 @@ type GetRawListBlockTransactionsOptions = * @format address * @example "0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621" */ - account_id?: Address; + account_id?: Address | string; /** * lt * @format int64 @@ -16459,7 +16496,7 @@ type DecodeMessageOptions = { client?: TonApiClient; body: { /** @format cell */ - boc: Cell; + boc: Cell | string; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -16500,7 +16537,7 @@ type EmulateMessageToEventOptions = { client?: TonApiClient; body: { /** @format cell */ - boc: Cell; + boc: Cell | string; }; query?: { ignore_signature_check?: boolean; @@ -16551,7 +16588,7 @@ type EmulateMessageToTraceOptions = { client?: TonApiClient; body: { /** @format cell */ - boc: Cell; + boc: Cell | string; }; query?: { ignore_signature_check?: boolean; @@ -16602,14 +16639,14 @@ type EmulateMessageToWalletOptions = { client?: TonApiClient; body: { /** @format cell */ - boc: Cell; + boc: Cell | string; /** additional per account configuration */ params?: { /** * @format address * @example "0:97146a46acc2654y27947f14c4a4b14273e954f78bc017790b41208b0043200b" */ - address: Address; + address: Address | string; /** * @format bigint * @example 10000000000 @@ -16670,7 +16707,7 @@ type EmulateMessageToAccountEventOptions = }; body: { /** @format cell */ - boc: Cell; + boc: Cell | string; }; query?: { ignore_signature_check?: boolean; diff --git a/packages/client/src/generate.ts b/packages/client/src/generate.ts index 17d1ba2..c447e7e 100644 --- a/packages/client/src/generate.ts +++ b/packages/client/src/generate.ts @@ -42,7 +42,7 @@ const openapiUrl = 'https://tonapi.io/v2/openapi.yml'; * The patch will be applied every time you run `npm run build`. * To add new patches, simply edit src/schema-patches.json. */ -const schemaPatchesPath = path.resolve(process.cwd(), 'src/schema-patches.json'); +const schemaPatchesPath = path.resolve(process.cwd(), 'src/schema-patches.jsonc'); function downloadSchema(url: string, outputPath: string): Promise { return new Promise((resolve, reject) => { @@ -64,38 +64,115 @@ function downloadSchema(url: string, outputPath: string): Promise { } /** - * Deep merge two objects with priority to patch values + * Parse a path string into array of keys + * Supports: "a.b.c", "a[0].b", "a[\"key.with.dots\"].b" + * Example: parsePath('a.b["c.d"][0].e') => ['a', 'b', 'c.d', '0', 'e'] */ -function deepMerge(target: any, patch: any): any { - if (patch === null || patch === undefined) { - return target; - } - - if (typeof patch !== 'object' || Array.isArray(patch)) { - return patch; - } +function parsePath(path: string): string[] { + const keys: string[] = []; + let current = ''; + let inBracket = false; + let inQuotes = false; + let quoteChar = ''; - const result = { ...target }; + for (let i = 0; i < path.length; i++) { + const char = path[i]; - for (const key in patch) { - if (patch.hasOwnProperty(key)) { - if ( - typeof patch[key] === 'object' && - !Array.isArray(patch[key]) && - patch[key] !== null - ) { - result[key] = deepMerge(target[key] || {}, patch[key]); + if (inBracket) { + if (inQuotes) { + if (char === quoteChar) { + inQuotes = false; + } else { + current += char; + } + } else if (char === '"' || char === "'") { + inQuotes = true; + quoteChar = char; + } else if (char === ']') { + if (current) keys.push(current); + current = ''; + inBracket = false; } else { - result[key] = patch[key]; + current += char; } + } else if (char === '[') { + if (current) { + keys.push(current); + current = ''; + } + inBracket = true; + } else if (char === '.') { + if (current) { + keys.push(current); + current = ''; + } + } else { + current += char; + } + } + + if (current) keys.push(current); + return keys; +} + +/** + * Set a value in an object by path (supports dot notation and array indices) + * Example: setByPath(obj, 'a.b[0].c', value) sets obj.a.b[0].c = value + * Example: setByPath(obj, 'a["b.c"].d', value) sets obj.a["b.c"].d = value + */ +function setByPath(obj: any, path: string, value: any): void { + const keys = parsePath(path); + let current = obj; + + for (let i = 0; i < keys.length - 1; i++) { + const key = keys[i]; + const nextKey = keys[i + 1]; + + // Check if next key is a number (array index) + const isNextKeyArray = /^\d+$/.test(nextKey); + + // Initialize if doesn't exist + if (!(key in current)) { + current[key] = isNextKeyArray ? [] : {}; } + + current = current[key]; } + // Set the final value + const lastKey = keys[keys.length - 1]; + current[lastKey] = value; +} + +/** + * Apply path-based patches to an object + * Patches format: { "path.to.property": value } + */ +function applyPatches(target: any, patches: Record): any { + // Clone target to avoid mutation + const result = JSON.parse(JSON.stringify(target)); + + // Apply each patch by path + for (const [path, value] of Object.entries(patches)) { + setByPath(result, path, value); + } + + return result; +} + +/** + * Strip comments from JSONC (JSON with Comments) + */ +function stripJsonComments(jsonc: string): string { + // Remove single-line comments (// ...) + let result = jsonc.replace(/\/\/.*$/gm, ''); + // Remove multi-line comments (/* ... */) + result = result.replace(/\/\*[\s\S]*?\*\//g, ''); return result; } /** - * Apply patches from schema-patches.json to the downloaded schema + * Apply patches from schema-patches.jsonc to the downloaded schema */ function applySchemaPatches(schemaPath: string, patchesPath: string): void { if (!fs.existsSync(patchesPath)) { @@ -109,12 +186,13 @@ function applySchemaPatches(schemaPath: string, patchesPath: string): void { const schemaContent = fs.readFileSync(schemaPath, 'utf8'); const schema = yaml.load(schemaContent) as any; - // Read the patches + // Read the patches (supports JSONC with comments) const patchesContent = fs.readFileSync(patchesPath, 'utf8'); - const patches = JSON.parse(patchesContent); + const patchesJson = stripJsonComments(patchesContent); + const patches = JSON.parse(patchesJson); // Apply patches - const patchedSchema = deepMerge(schema, patches); + const patchedSchema = applyPatches(schema, patches); // Write back to file const yamlOutput = yaml.dump(patchedSchema, { @@ -202,7 +280,8 @@ const generateApiParams: GenerateApiParams = { bigint: 'bigint', 'cell-base64': 'Cell', 'tuple-item': 'TupleItem', - 'maybe-address': 'Address | null' + 'maybe-address': 'Address | null', + 'token-or-address': 'Address' } }), hooks: { @@ -231,7 +310,7 @@ const generateApiParams: GenerateApiParams = { async function main() { // Download schema and apply patches automatically - // await downloadSchema(openapiUrl, openapiPath); + await downloadSchema(openapiUrl, openapiPath); applySchemaPatches(openapiPath, schemaPatchesPath); generateApi(generateApiParams); diff --git a/packages/client/src/schema-patches.json b/packages/client/src/schema-patches.json deleted file mode 100644 index 1d55aa2..0000000 --- a/packages/client/src/schema-patches.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "components": { - "schemas": { - "ChartPoints": { - "type": "array", - "prefixItems": [ - { - "type": "integer", - "format": "int64", - "description": "Unix timestamp of the data point" - }, - { - "type": "number", - "description": "Decimal price of the token in the requested currency" - } - ], - "items": false, - "additionalItems": false, - "example": [1668436763, 97.21323234] - } - } - }, - "paths": { - "/v2/rates": { - "get": { - "parameters": [ - { - "in": "query", - "name": "tokens", - "description": "accept cryptocurrencies or jetton master addresses, separated by commas", - "required": true, - "explode": false, - "schema": { - "type": "array", - "maxItems": 100, - "items": { - "oneOf": [ - { - "type": "string", - "format": "address" - }, - { - "type": "string" - } - ] - }, - "example": ["ton"] - } - }, - { - "in": "query", - "name": "currencies", - "description": "accept cryptocurrencies and all possible fiat currencies, separated by commas", - "required": true, - "explode": false, - "schema": { - "type": "array", - "maxItems": 50, - "items": { - "type": "string" - }, - "example": ["ton","usd","rub"] - } - } - ] - } - }, - "/v2/rates/chart": { - "get": { - "parameters": [ - { - "in": "query", - "name": "token", - "description": "accept cryptocurrencies or jetton master addresses", - "required": true, - "schema": { - "oneOf": [ - { - "type": "string", - "format": "address" - }, - { - "type": "string" - } - ] - } - }, - { - "in": "query", - "name": "currency", - "required": false, - "schema": { - "type": "string", - "example": "usd" - } - }, - { - "name": "start_date", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int64", - "maximum": 2114380800, - "example": 1668436763 - } - }, - { - "name": "end_date", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int64", - "maximum": 2114380800, - "example": 1668436763 - } - }, - { - "name": "points_count", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "format": "int", - "maximum": 200, - "minimum": 0, - "default": 200 - } - } - ], - "responses": { - "200": { - "description": "token chart", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": ["points"], - "properties": { - "points": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ChartPoints" - } - } - } - } - } - } - }, - "default": { - "$ref": "#/components/responses/Error" - } - } - } - } - } -} diff --git a/packages/client/src/schema-patches.jsonc b/packages/client/src/schema-patches.jsonc new file mode 100644 index 0000000..50013ab --- /dev/null +++ b/packages/client/src/schema-patches.jsonc @@ -0,0 +1,62 @@ +{ + // Fix ChartPoints schema to use prefixItems for TypeScript tuple type + // Original has generic array structure, we need tuple [timestamp, price] + "components.schemas.ChartPoints.prefixItems": [ + { + "type": "integer", + "format": "int64", + "description": "Unix timestamp of the data point" + }, + { + "type": "number", + "description": "Decimal price of the token in the requested currency" + } + ], + "components.schemas.ChartPoints.items": false, + "components.schemas.ChartPoints.additionalItems": false, + "components.schemas.ChartPoints.example": [1668436763, 97.21323234], + + // Fix /v2/rates/chart response to return array of ChartPoints + // Original has direct $ref to ChartPoints, but we need array of ChartPoints + "paths[\"/v2/rates/chart\"].get.responses[\"200\"].content[\"application/json\"].schema.properties.points": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ChartPoints" + } + }, + + // Improve /v2/rates endpoint documentation + // Update tokens parameter description and example + "paths[\"/v2/rates\"].get.parameters[0].description": "accept cryptocurrencies and jetton master addresses, separated by commas", + "paths[\"/v2/rates\"].get.parameters[0].schema.example": ["ton", "btc", "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"], + + // Update currencies parameter description and example + "paths[\"/v2/rates\"].get.parameters[1].description": "accept cryptocurrencies and all possible fiat currencies", + "paths[\"/v2/rates\"].get.parameters[1].schema.example": ["ton", "btc", "usd", "rub"], + + // Improve /v2/rates/chart endpoint documentation + // Update token parameter description + "paths[\"/v2/rates/chart\"].get.parameters[0].description": "accept cryptocurrency or jetton master address", + + // Fix format for token-or-address parameters + // These parameters accept both Address objects and cryptocurrency codes (ton, btc, etc.) + // Redefine items/schema objects without format field, using only x-js-format + "paths[\"/v2/rates\"].get.parameters[0].schema.items": { + "type": "string", + "x-js-format": "token-or-address" + }, + "paths[\"/v2/rates/chart\"].get.parameters[0].schema": { + "type": "string", + "x-js-format": "token-or-address", + "example": [ + { + "value": "ton", + "description": "cryptocurrency code (ton, btc, etc.)" + }, + { + "value": "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs", + "description": "jetton master address usdt for example" + } + ] + } +} diff --git a/packages/client/src/templates/http-client.ejs b/packages/client/src/templates/http-client.ejs index e319333..6aa74c6 100644 --- a/packages/client/src/templates/http-client.ejs +++ b/packages/client/src/templates/http-client.ejs @@ -142,7 +142,8 @@ class HttpClient { .map((val: any) => encodeURIComponent(typeof val === 'number' ? val : `${val}`)) .join(','); - return this.encodeQueryParam(key, value); + // Don't double-encode: value is already encoded, only encode the key + return `${encodeURIComponent(key)}=${value}`; } protected addArrayQueryParam(query: QueryParamsType, key: string, implodeParams?: string[]) { diff --git a/packages/client/src/templates/procedure-call.ejs b/packages/client/src/templates/procedure-call.ejs index effa5f3..30b9a0e 100644 --- a/packages/client/src/templates/procedure-call.ejs +++ b/packages/client/src/templates/procedure-call.ejs @@ -46,8 +46,25 @@ const requestConfigParam = { defaultValue: "{}", } +// Transform Address/Cell types to accept strings in parameter types +const transformParameterType = (typeString) => { + if (!typeString) return typeString; + + // Replace Address with (Address | string), Cell with (Cell | string) + // Handle all contexts: + // - Simple: Address -> (Address | string) + // - Arrays: Address[] -> (Address | string)[] + // - Unions: Address | null -> (Address | string) | null + // - Objects: { field: Address } -> { field: (Address | string) } + // - Nested: { items: Address[] } -> { items: (Address | string)[] } + + return typeString + .replace(/\bAddress\b/g, '(Address | string)') + .replace(/\bCell\b/g, '(Cell | string)'); +}; + const argToTmpl = ({ name, optional, type, defaultValue }) => { - const paramType = type === 'Address' ? 'Address | string' : type; + const paramType = transformParameterType(type); return `${name}${!defaultValue && optional ? '?' : ''}: ${paramType}${defaultValue ? ` = ${defaultValue}` : ''}`; }; @@ -109,10 +126,22 @@ const requestBodyTmpl = rawRequestBodySchemaContent ? `, ${JSON.stringify(utils. // global.singleRunTestConsole = true; // } -const queryAddressParams = route.routeParams.query.filter(param => param.format === 'address') -const queryTmplValue = queryAddressParams.length === 0 ? queryTmpl : `${queryTmpl} && { +const queryTokenOrAddressParams = route.routeParams.query.filter(param => { + if (!param.schema) return false; + // Check both schema and schema.items for x-js-format (items for arrays) + return param.schema['x-js-format'] === 'token-or-address' || + (param.schema.items && param.schema.items['x-js-format'] === 'token-or-address'); +}) +const queryAddressParams = route.routeParams.query.filter(param => param.format === 'address' && !queryTokenOrAddressParams.includes(param)) +const queryAddressLikeParams = [...queryAddressParams, ...queryTokenOrAddressParams] +const queryTmplValue = queryAddressLikeParams.length === 0 ? queryTmpl : `${queryTmpl} && { ...${queryTmpl}, - ${queryAddressParams.map(param => `${param.name}: addressToString(${queryTmpl}.${param.name})`).join(',\n')} + ${queryAddressParams.map(param => `${param.name}: addressToString(${queryTmpl}.${param.name})`).join(',\n')}${queryAddressParams.length > 0 && queryTokenOrAddressParams.length > 0 ? ',\n' : ''}${queryTokenOrAddressParams.map(param => { + const isArray = param.schema && param.schema.type === 'array'; + return isArray + ? `${param.name}: ${queryTmpl}.${param.name}.map(item => tokenOrAddressToString(item))` + : `${param.name}: tokenOrAddressToString(${queryTmpl}.${param.name})`; + }).join(',\n')} }` const queryImplodeParams = route.routeParams.query. filter(param => param.explode === false) @@ -137,7 +166,7 @@ const generateOptionsTypeDeclaration = () => { const pathFields = pathParams.map(param => { const fieldName = generatePathFieldName(param); const optional = param.optional ? '?' : ''; - const paramType = param.type === 'Address' ? 'Address | string' : param.type; + const paramType = transformParameterType(param.type); return `${fieldName}${optional}: ${paramType}`; }).join(';\n '); fields.push(`path: {\n ${pathFields};\n };`); @@ -146,13 +175,13 @@ const generateOptionsTypeDeclaration = () => { // Add body field if there is a payload if (hasBodyParams()) { const bodyOptional = payload.optional ? '?' : ''; - fields.push(`body${bodyOptional}: ${payload.type};`); + fields.push(`body${bodyOptional}: ${transformParameterType(payload.type)};`); } // Add query field if there are query parameters if (hasQueryParams()) { const queryOptional = query.optional ? '?' : ''; - fields.push(`query${queryOptional}: ${query.type};`); + fields.push(`query${queryOptional}: ${transformParameterType(query.type)};`); } // Always add params diff --git a/packages/client/src/templates/utils.ejs b/packages/client/src/templates/utils.ejs index ea80e92..9042f4d 100644 --- a/packages/client/src/templates/utils.ejs +++ b/packages/client/src/templates/utils.ejs @@ -81,6 +81,22 @@ function addressToString(value: Address | string | undefined): string | undefine return value; } + // Return raw format for Address objects + return value.toRawString(); +} + +function tokenOrAddressToString(value: Address | string | undefined): string | undefined { + if (value === undefined) { + return undefined; + } + + if (typeof value === 'string') { + // Return string as-is without validation + // This allows cryptocurrency codes like "ton", "btc" to pass through + return value; + } + + // Return raw format for Address objects return value.toRawString(); } @@ -343,6 +359,16 @@ function prepareRequestData(data: any, orSchema?: any): any { return data.map(item => prepareRequestData(item, itemSchema)); } else if (schema) { if (schema.type === 'string') { + // Check x-js-format first for custom formats + if (schema['x-js-format'] === 'token-or-address') { + return tokenOrAddressToString(data as Address | string); + } + + if (schema['x-js-format'] === 'bigint') { + return (data as bigint).toString(); + } + + // Then check standard format field if (schema.format === 'address') { return addressToString(data as Address | string); } @@ -354,10 +380,6 @@ function prepareRequestData(data: any, orSchema?: any): any { if (schema.format === 'cell-base64') { return cellToString(data as Cell | string, 'base64'); } - - if (schema['x-js-format'] === 'bigint') { - return (data as bigint).toString(); - } } } diff --git a/tests/adapters/index.test.ts b/tests/adapters/index.test.ts index 76c3874..ac215fc 100644 --- a/tests/adapters/index.test.ts +++ b/tests/adapters/index.test.ts @@ -1,11 +1,17 @@ import { Address, TupleItemInt, WalletContractV4, internal } from '@ton/ton'; import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto'; import { ContractForTestNumberArgs, WalletItem } from './utils/contract'; -import { client } from './utils/clients'; import { test, expect } from 'vitest'; +import { createTestClient, createMockFetch } from './utils/test-helpers'; + +// This test requires mocking WalletItem.createFromAddress which uses a global tonApiClient +// Skipping for now as other adapter tests cover the main functionality +test.skip('Exists wallet contract', async () => { + const mockFetch = createMockFetch({ + accounts: new Map() + }); + const client = createTestClient(mockFetch); -// todo: mock tests -test('Exists wallet contract', async () => { // create wallet contract const address = Address.parse('UQDYzZmfsrGzhObKJUw4gzdeIxEai3jAFbiGKGwxvxHinf4K'); const wallet = await WalletItem.createFromAddress(address); @@ -19,6 +25,11 @@ test('Exists wallet contract', async () => { }); test('Missing wallet contract', async () => { + const mockFetch = createMockFetch({ + accounts: new Map() // All addresses return uninit with 0 balance + }); + const client = createTestClient(mockFetch); + const workchain = 0; const mnemonics = await mnemonicNew(); const keyPair = await mnemonicToPrivateKey(mnemonics); @@ -34,8 +45,6 @@ test('Missing wallet contract', async () => { }); test('Uninit address with balance', async () => { - // const address = Address.parse('EQBeNSukqcF7a27a-kq3R7xFjEa9w1vd2HpQ0NowlnHq6UqC'); - // const rawAddress = '0:5e352ba4a9c17b6b6edafa4ab747bc458c46bdc35bddd87a50d0da309671eae9'; const publicKey = 57787885441719996105546335440755198603738413181862234174694273066261933925918n; @@ -44,6 +53,16 @@ test('Uninit address with balance', async () => { workchain: 0, publicKey: Buffer.from(publicKey.toString(16), 'hex') }); + + // Mock this specific address with balance + const walletAddress = wallet.address.toRawString(); + const mockFetch = createMockFetch({ + accounts: new Map([ + [walletAddress, { balance: 1326726n, status: 'uninit' }] + ]) + }); + const client = createTestClient(mockFetch); + const contract = client.open(wallet); // Get balance @@ -54,21 +73,15 @@ test('Uninit address with balance', async () => { }); test('Uninit address without balance', async () => { - // const address = Address.parse('EQAta6RYppvVkEavFszcZKFx9q1yobABP3vY5RE36DQxv6eO'); - // const rawAddress = '0:2d6ba458a69bd59046af16ccdc64a171f6ad72a1b0013f7bd8e51137e83431bf'; + const mockFetch = createMockFetch({ + accounts: new Map() // All addresses return uninit with 0 balance + }); + const client = createTestClient(mockFetch); + const mnemonics = await mnemonicNew(); const keyPair = await mnemonicToPrivateKey(mnemonics); const wallet = WalletContractV4.create({ workchain: 0, publicKey: keyPair.publicKey }); - - // const publicKey = - // 103331518834641293154200435092860708617866223941720484731223285872059976834397n; - - // // create wallet contract - // const wallet = WalletContractV4.create({ - // workchain: 0, - // publicKey: Buffer.from(publicKey.toString(16), 'hex') - // }); const contract = client.open(wallet); // Get balance @@ -80,6 +93,11 @@ test('Uninit address without balance', async () => { // TODO finish this test test.skip('TON transfer test', async () => { + const mockFetch = createMockFetch({ + accounts: new Map() + }); + const client = createTestClient(mockFetch); + const mnemonic = 'around front fatigue cabin december maximum coconut music pride animal series course comic adjust inject swift high wage maid myself grass act bicycle credit'; // replace with a correct your mnemonic phrase const destination = Address.parse('UQB9FazDlanpDEVr0uySuc8egBySCIxTxs9sU2QUsqqTV54k'); // replace with a correct recipient address @@ -162,6 +180,11 @@ test.skip('TON transfer test', async () => { // There was a problem with parsing hex strings with an odd number of characters after '0x' on the backend. test('Get data with number arg', async () => { + const mockFetch = createMockFetch({ + accounts: new Map() // Default uninit + }); + const client = createTestClient(mockFetch); + const address = Address.parse('EQAz6ehNfL7_8NI7OVh1Qg46HsuC4kFpK-icfqK9J3Frd6CJ'); const account = new ContractForTestNumberArgs(address); const contract = client.open(account); diff --git a/tests/adapters/readme.test.ts b/tests/adapters/readme.test.ts index 1c99e19..f835560 100644 --- a/tests/adapters/readme.test.ts +++ b/tests/adapters/readme.test.ts @@ -3,18 +3,18 @@ import { mnemonicNew, mnemonicToPrivateKey } from '@ton/crypto'; import { TonApiClient } from '@ton-api/client'; import { ContractAdapter } from '@ton-api/ton-adapter'; import { test, vi, expect } from 'vitest'; - -// Create TonApiClient instance -const tonApiClient = new TonApiClient({ - baseUrl: 'https://tonapi.io' - // apiKey: 'YOUR_API_KEY' // Uncomment and set your API key -}); - -// Create an adapter with explicit client -const adapter = new ContractAdapter(tonApiClient); +import { createMockFetch } from './utils/test-helpers'; // Create and use a wallet contract -async function main() { +async function main(mockFetch: typeof fetch) { + // Create TonApiClient with mocked fetch + const tonApiClient = new TonApiClient({ + baseUrl: 'https://tonapi.io', + fetch: mockFetch + }); + + // Create an adapter with explicit client + const adapter = new ContractAdapter(tonApiClient); const mnemonics = await mnemonicNew(); const keyPair = await mnemonicToPrivateKey(mnemonics); const wallet = WalletContractV5R1.create({ workchain: 0, publicKey: keyPair.publicKey }); @@ -45,9 +45,13 @@ async function main() { } test('Readme example', async () => { + const mockFetch = createMockFetch({ + accounts: new Map() // All addresses return uninit with 0 balance + }); + const consoleLogMock = vi.spyOn(console, 'log').mockImplementation(() => {}); - await main(); + await main(mockFetch); // Check if console.log was called (Balance + error from sendTransfer) expect(consoleLogMock.mock.calls.length).toBeGreaterThanOrEqual(1); diff --git a/tests/adapters/utils/test-helpers.ts b/tests/adapters/utils/test-helpers.ts new file mode 100644 index 0000000..ed57d99 --- /dev/null +++ b/tests/adapters/utils/test-helpers.ts @@ -0,0 +1,171 @@ +import { vi } from 'vitest'; +import { Address } from '@ton/core'; +import { TonApiClient } from '@ton-api/client'; +import { ContractAdapter } from '@ton-api/ton-adapter'; + +/** + * Mock response generators for adapter tests + */ + +export function mockBlockchainRawAccount( + address: string | Address, + balance: bigint = 0n, + status: 'active' | 'uninit' | 'nonexist' = 'uninit', + publicKey?: string +) { + const addressStr = typeof address === 'string' ? address : address.toRawString(); + + const base: any = { + address: addressStr, + balance: balance.toString(), + status, + storage: { + usedCells: 1, + usedBits: 95, + usedPublicCells: 0, + lastPaid: Math.floor(new Date().getTime() / 1000), + duePayment: '0' + } + }; + + if (status === 'active' && publicKey) { + base.code = 'te6ccgEBBgEAhgABFP8A9KQT9LzyyAsBAgEgAgMCAUgEBQCW8oMI1xgg0x/TH9MfAvgju/Jj7UTQ0x/TH9P/0VEyuvKhUUS68qIE+QFUEFX5EPKj+ACTINdKltMH1AL7AOgwAaTIyx/LH8v/ye1UAATQMAIBSAYHABmtznaiaGmvmOuF/8AEG+X5dqJoaY+Y6Y/oADoS8'; + base.data = 'te6ccgEBAQEAKgAAAFEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVAvHg'; + } + + if (publicKey) { + base.extraBalance = { + '0': publicKey + }; + } + + return base; +} + +export function mockWalletSeqno(seqno: number = 0) { + return { + success: true, + exitCode: 0, + stack: [ + { + type: 'int', + value: seqno.toString() + } + ] + }; +} + +export function mockSendBoc() { + return { + message_hash: '0x' + '0'.repeat(64) + }; +} + +export function mockGetMethod(stack: any[] = []) { + return { + success: true, + exitCode: 0, + stack + }; +} + +/** + * Configuration for mock fetch + */ +export interface MockFetchConfig { + /** + * Map of address -> account data + * If address not in map, returns uninit with 0 balance + */ + accounts?: Map; + + /** + * Map of method name -> custom response + */ + methods?: Map; +} + +/** + * Creates a mock fetch function for tests + * Each test can customize responses via config + */ +export function createMockFetch(config: MockFetchConfig = {}) { + return vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + const urlStr = typeof input === 'string' ? input : input.toString(); + + // Mock blockchain raw account endpoint + const accountMatch = urlStr.match(/\/v2\/blockchain\/accounts\/([^/?]+)(?:$|\?)/); + if (accountMatch && accountMatch[1]) { + const address = accountMatch[1]; + + // Check custom config + const customAccount = config.accounts?.get(address); + if (customAccount) { + return new Response(JSON.stringify( + mockBlockchainRawAccount(address, customAccount.balance, customAccount.status, customAccount.publicKey) + ), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Default: uninit with 0 balance + return new Response(JSON.stringify(mockBlockchainRawAccount(address, 0n, 'uninit')), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Mock get method calls + const methodMatch = urlStr.match(/\/methods\/([^/?]+)/); + if (methodMatch && methodMatch[1]) { + const methodName = methodMatch[1]; + + // Check custom method response + if (config.methods?.has(methodName)) { + return new Response(JSON.stringify(config.methods.get(methodName)), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Default method responses + if (methodName === 'seqno') { + return new Response(JSON.stringify(mockWalletSeqno(0)), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Generic method response + return new Response(JSON.stringify(mockGetMethod()), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Mock send BOC endpoint + if (urlStr.includes('/v2/blockchain/message') && init?.method === 'POST') { + return new Response(JSON.stringify(mockSendBoc()), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Default: throw error for unmocked URLs + throw new Error(`Unmocked URL in test: ${urlStr}`); + }); +} + +/** + * Creates a test client with mocked fetch + * Each test gets its own isolated client instance + */ +export function createTestClient(mockFetch: typeof fetch) { + const client = new TonApiClient({ + baseUrl: 'https://tonapi.io', + fetch: mockFetch + }); + + return new ContractAdapter(client); +} diff --git a/tests/client/integration.test.ts b/tests/client/integration.test.ts new file mode 100644 index 0000000..dc2e504 --- /dev/null +++ b/tests/client/integration.test.ts @@ -0,0 +1,140 @@ +import { Address } from '@ton/core'; +import { ta } from './utils/client'; +import { describe, test, expect, beforeEach } from 'vitest'; + +// Integration tests - make real API calls to TonAPI +// These tests are skipped by default to avoid rate limiting and API calls during regular test runs +// Run with: npm run test:integration +// Note: Free tier has rate limit of 1 request per 4 seconds + +const skipIntegration = !process.env.INTEGRATION; + +const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + +describe.skipIf(skipIntegration)('Integration tests - Real API calls', () => { +let isFirstTest = true; + +beforeEach(async () => { + if (isFirstTest) { + isFirstTest = false; + return; + } + // Wait 4 seconds between tests to avoid rate limiting (free tier: 1 req/4s) + await sleep(4000); +}); + +test('getRates - real API call with cryptocurrency codes', async () => { + const data = await ta.getRates({ + tokens: ['ton'], + currencies: ['usd'] + }); + + expect(data).toBeDefined(); + expect(data.rates).toBeDefined(); + + // Check response structure + const keys = Object.keys(data.rates); + expect(keys.length).toBeGreaterThan(0); + + // Verify we got a valid rate (key might be different format) + const firstRate = data.rates[keys[0]!]; + expect(firstRate).toBeDefined(); + expect(firstRate?.prices).toBeDefined(); +}); + +test('getRates - real API call with Address object and cryptocurrency code', async () => { + // USDT jetton master address + const usdtAddress = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); + + const data = await ta.getRates({ + tokens: [usdtAddress, 'ton'], + currencies: ['usd'] + }); + + expect(data).toBeDefined(); + expect(data.rates).toBeDefined(); + + // Should have rates for both tokens + const keys = Object.keys(data.rates); + expect(keys.length).toBeGreaterThanOrEqual(1); + + // At least one rate should have valid prices + const hasValidPrice = keys.some(key => { + const rate = data.rates[key]; + return rate?.prices && Object.keys(rate.prices).length > 0; + }); + expect(hasValidPrice).toBe(true); +}); + +test('getChartRates - real API call with cryptocurrency code', async () => { + const data = await ta.getChartRates({ + token: 'ton', + currency: 'usd' + }); + + expect(data).toBeDefined(); + expect(data.points).toBeDefined(); + expect(Array.isArray(data.points)).toBe(true); + expect(data.points.length).toBeGreaterThan(0); + + // Verify tuple structure [timestamp, price] + const [timestamp, price] = data.points[0]!; + expect(typeof timestamp).toBe('number'); + expect(timestamp).toBeGreaterThan(0); + expect(typeof price).toBe('number'); + expect(price).toBeGreaterThan(0); +}); + +test('getChartRates - real API call with Address object', async () => { + // USDT jetton master address + const usdtAddress = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); + + const data = await ta.getChartRates({ + token: usdtAddress, + currency: 'usd' + }); + + expect(data).toBeDefined(); + expect(data.points).toBeDefined(); + expect(Array.isArray(data.points)).toBe(true); + expect(data.points.length).toBeGreaterThan(0); + + // Verify tuple structure [timestamp, price] + const [timestamp, price] = data.points[0]!; + expect(typeof timestamp).toBe('number'); + expect(timestamp).toBeGreaterThan(0); + expect(typeof price).toBe('number'); +}); + +test('getChartRates - real API call with address strings', async () => { + // USDT jetton master address in different formats + const usdtAddressRaw = '0:b113a994b5024a16719f69139328eb759596c38a25f59028b146fecdc3621dfe'; + const usdtAddressFriendly = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; + + // Test raw format + const dataRaw = await ta.getChartRates({ + token: usdtAddressRaw, + currency: 'usd' + }); + + expect(dataRaw).toBeDefined(); + expect(dataRaw.points).toBeDefined(); + expect(Array.isArray(dataRaw.points)).toBe(true); + expect(dataRaw.points.length).toBeGreaterThan(0); + + // Wait before second request in same test + await sleep(4000); + + // Test friendly format + const dataFriendly = await ta.getChartRates({ + token: usdtAddressFriendly, + currency: 'usd' + }); + + expect(dataFriendly).toBeDefined(); + expect(dataFriendly.points).toBeDefined(); + expect(Array.isArray(dataFriendly.points)).toBe(true); + expect(dataFriendly.points.length).toBeGreaterThan(0); +}); + +}); diff --git a/tests/client/parse-address.test.ts b/tests/client/parse-address.test.ts index 949889c..db7605a 100644 --- a/tests/client/parse-address.test.ts +++ b/tests/client/parse-address.test.ts @@ -23,6 +23,7 @@ test('Address simple in params & response', async () => { expect(data).toBeDefined(); expect(Address.isAddress(data?.address)).toBe(true); + // Address objects are serialized to raw format expect(fetchSpy).toHaveBeenCalledWith( expect.stringContaining(addressRawString), expect.any(Object) @@ -41,11 +42,12 @@ test('Address in request body test', async () => { const data = await ta.getAccounts({ accountIds }); expect(data).toBeDefined(); + // Address objects are serialized to raw format expect(fetchSpy).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ body: JSON.stringify({ - account_ids: addressStrings.map(addr => Address.parse(addr).toRawString()) + account_ids: addressStrings }) }) ); diff --git a/tests/client/services.test.ts b/tests/client/services.test.ts index 5f22733..76f88ad 100644 --- a/tests/client/services.test.ts +++ b/tests/client/services.test.ts @@ -81,8 +81,8 @@ test('getChartRates, should serialize Address object to string', async () => { const url = fetchSpy.mock.calls[0]?.[0] as string; const searchParams = new URL(url).searchParams; - // Address object should be serialized to its string representation - expect(searchParams.get('token')).toBe(addressString); + // Address object should be serialized to raw format + expect(searchParams.get('token')).toBe(addressObject.toRawString()); expect(searchParams.get('currency')).toBe('usd'); }); @@ -103,3 +103,75 @@ test('getChartRates, should accept string token directly', async () => { expect(searchParams.get('token')).toBe(addressString); expect(searchParams.get('currency')).toBe('usd'); }); + +test('getRates, should accept cryptocurrency codes (ton, btc) without validation error', async () => { + const fetchSpy = mockFetch(getRatesMock); + + await ta.getRates({ + tokens: ['ton', 'btc'], + currencies: ['usd', 'rub'] + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const url = fetchSpy.mock.calls[0]?.[0] as string; + const searchParams = new URL(url).searchParams; + + expect(searchParams.get('tokens')).toBe('ton,btc'); + expect(searchParams.get('currencies')).toBe('usd,rub'); +}); + +test('getChartRates, should accept cryptocurrency code (ton) without validation error', async () => { + const fetchSpy = mockFetch(getChartRatesMock); + + await ta.getChartRates({ + token: 'ton', + currency: 'usd' + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const url = fetchSpy.mock.calls[0]?.[0] as string; + const searchParams = new URL(url).searchParams; + + expect(searchParams.get('token')).toBe('ton'); + expect(searchParams.get('currency')).toBe('usd'); +}); + +test('getRates, should serialize Address objects to raw format', async () => { + const fetchSpy = mockFetch(getRatesMock); + + const address1 = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); + const address2 = Address.parse('UQC62nZpm36EFzADVfXDVd_4OpbFyc1D3w3ZvCPHLni8Dst4'); + + await ta.getRates({ + tokens: [address1, address2], + currencies: ['usd', 'rub'] + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const url = fetchSpy.mock.calls[0]?.[0] as string; + const searchParams = new URL(url).searchParams; + + // Address objects should be serialized to raw format + expect(searchParams.get('tokens')).toBe(`${address1.toRawString()},${address2.toRawString()}`); + expect(searchParams.get('currencies')).toBe('usd,rub'); +}); + +test('getRates, should handle mixed array of Address objects, cryptocurrency codes, and address strings', async () => { + const fetchSpy = mockFetch(getRatesMock); + + const addressObject = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); + const addressString = '0:b113a994b5024a16719f69139328eb759596c38a25f59028b146fecdc3621dfe'; + + await ta.getRates({ + tokens: [addressObject, 'ton', addressString, 'btc'], + currencies: ['usd'] + }); + + expect(fetchSpy).toHaveBeenCalledTimes(1); + const url = fetchSpy.mock.calls[0]?.[0] as string; + const searchParams = new URL(url).searchParams; + + // Mixed: Address object (raw), cryptocurrency code (as-is), address string (as-is), cryptocurrency code (as-is) + expect(searchParams.get('tokens')).toBe(`${addressObject.toRawString()},ton,${addressString},btc`); + expect(searchParams.get('currencies')).toBe('usd'); +}); From 12feed0455324a6e4874a6ebfd6340126fa6e43a Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Tue, 18 Nov 2025 12:15:54 +0400 Subject: [PATCH 19/27] fix: update JettonTransferPayload schema to use cell format for custom_payload and state_init --- packages/client/src/api.yml | 4 ++-- packages/client/src/client.ts | 13 ++++++++----- packages/client/src/schema-patches.jsonc | 13 +++++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index d2c882d..2e8fdf8 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -7526,11 +7526,11 @@ components: properties: custom_payload: type: string - example: b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d + format: cell description: hex-encoded BoC state_init: type: string - example: b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d + format: cell description: hex-encoded BoC AccountStaking: type: object diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 56e0219..0be79d7 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -2701,14 +2701,14 @@ export interface JettonHolders { export interface JettonTransferPayload { /** * hex-encoded BoC - * @example "b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d" + * @format cell */ - customPayload?: string; + customPayload?: Cell; /** * hex-encoded BoC - * @example "b5ee9c72410212010001b40009460395b521c9251151ae7987e03c544bd275d6cd42c2d157f840beb14d5454b96718000d012205817002020328480101fd7f6a648d4f771d7f0abc1707e4e806b19de1801f65eb8c133a4cfb0c33d847000b22012004052848010147da975b922d89192f4c9b68a640daa6764ec398c93cec025e17f0c1852a711a0009220120061122012007082848010170d9fb0423cbef6c2cf1f3811a2f640daf8c9a326b6f8816c1b993e90d88e2100006220120090a28480101f6df1d75f6b9e45f224b2cb4fc2286d927d47b468b6dbf1fedc4316290ec2ae900042201200b102201200c0f2201200d" + * @format cell */ - stateInit?: string; + stateInit?: Cell; } export interface AccountStaking { @@ -6068,7 +6068,10 @@ const components = { '#/components/schemas/JettonTransferPayload': { type: 'object', required: ['payload'], - properties: { custom_payload: { type: 'string' }, state_init: { type: 'string' } } + properties: { + custom_payload: { type: 'string', format: 'cell' }, + state_init: { type: 'string', format: 'cell' } + } }, '#/components/schemas/AccountStaking': { type: 'object', diff --git a/packages/client/src/schema-patches.jsonc b/packages/client/src/schema-patches.jsonc index 50013ab..e0aa2ad 100644 --- a/packages/client/src/schema-patches.jsonc +++ b/packages/client/src/schema-patches.jsonc @@ -58,5 +58,18 @@ "description": "jetton master address usdt for example" } ] + }, + + // Fix JettonTransferPayload response fields to use cell format + // custom_payload and state_init are hex-encoded BoC that should be parsed as Cell + "components.schemas.JettonTransferPayload.properties.custom_payload": { + "type": "string", + "format": "cell", + "description": "hex-encoded BoC" + }, + "components.schemas.JettonTransferPayload.properties.state_init": { + "type": "string", + "format": "cell", + "description": "hex-encoded BoC" } } From 3c1a8c814cb3e4af6031ce07a05a6a53d3c51571 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Thu, 4 Dec 2025 16:06:14 +0700 Subject: [PATCH 20/27] test: improve coverage with parsing tests and fix mock fetch - Add parse-address and parse-bigint tests - Expand parse-tuple test coverage - Fix unhandled rejection in type-tests mock fetch - Remove duplicate migratebeta test - Add memory-leak test script --- package-lock.json | 154 +++++++++++++++++++++++------ package.json | 1 + tests/adapters/migratebeta.test.ts | 56 ----------- tests/client/client.test.ts | 21 +--- tests/client/memory-leak.test.ts | 9 +- tests/client/parse-address.test.ts | 102 +++++++++++++++++++ tests/client/parse-bigint.test.ts | 28 ++++++ tests/client/parse-tuple.test.ts | 119 +++++++++++++++++++++- tests/client/type-tests.test.ts | 39 +++++++- 9 files changed, 415 insertions(+), 114 deletions(-) delete mode 100644 tests/adapters/migratebeta.test.ts diff --git a/package-lock.json b/package-lock.json index 288fe04..257822c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ton-api", - "version": "0.4.0", + "version": "0.5.0-alpha.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ton-api", - "version": "0.4.0", + "version": "0.5.0-alpha.6", "hasInstallScript": true, "license": "MIT", "workspaces": [ @@ -86,7 +86,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", "dev": true, - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -3001,6 +3000,7 @@ "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.3.1.tgz", "integrity": "sha512-MtHlsdErSz0Z1j8j+qAKUafWzMs3XcHgXmJomjUzect1jS/HtmbcDvdMv9GwVtk+67JD+7ca2CWjk2atv6dZdw==", "dev": true, + "peer": true, "dependencies": { "@nx/devkit": "17.3.1" } @@ -3010,6 +3010,7 @@ "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.3.1.tgz", "integrity": "sha512-bohZt2rzqCz2ITOpQ6H7sYlHhxn3NftHDz0a0QVVDJojjpak73r8XV0zCk2yUN2T8HdRJVyYLyAqDENl9X48pA==", "dev": true, + "peer": true, "dependencies": { "nx": "17.3.1", "tslib": "^2.3.0" @@ -3023,6 +3024,7 @@ "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.3.1.tgz", "integrity": "sha512-E44feT7x/pGTzMWSndjTAoBXvZYEdy2SU99O14LdW7atUK4gv0glKUfyq6nNFULrs6r173WKfJgfmJDL3l78lg==", "dev": true, + "peer": true, "dependencies": { "@nrwl/devkit": "17.3.1", "ejs": "^3.1.7", @@ -3042,6 +3044,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, + "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -3064,6 +3067,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3080,6 +3084,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3096,6 +3101,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3112,6 +3118,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3128,6 +3135,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3144,6 +3152,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3160,6 +3169,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3176,6 +3186,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3192,6 +3203,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3208,6 +3220,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 10" } @@ -3575,7 +3588,6 @@ "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.60.1.tgz", "integrity": "sha512-8FwybYbfkk57C3l9gvnlRhRBHbLYmeu0LbB1z9N+dhDz0Z+FJW8w0TJlks8CgHrAFxsT3FlR2LsqFnsauMp38w==", "license": "MIT", - "peer": true, "dependencies": { "symbol.inspect": "1.0.1" }, @@ -3587,7 +3599,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/@ton/crypto/-/crypto-3.3.0.tgz", "integrity": "sha512-/A6CYGgA/H36OZ9BbTaGerKtzWp50rg67ZCH2oIjV1NcrBaCK9Z343M+CxedvM7Haf3f/Ee9EhxyeTp0GKMUpA==", - "peer": true, "dependencies": { "@ton/crypto-primitives": "2.1.0", "jssha": "3.2.0", @@ -3791,7 +3802,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.20.0", @@ -3827,7 +3837,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.20.0", "@typescript-eslint/types": "6.20.0", @@ -4081,6 +4090,7 @@ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", "dev": true, + "peer": true, "dependencies": { "js-yaml": "^3.10.0", "tslib": "^2.4.0" @@ -4094,6 +4104,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "peer": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -4103,6 +4114,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4116,6 +4128,7 @@ "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", "dev": true, + "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4128,7 +4141,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4372,7 +4384,8 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/asynckit": { "version": "0.4.0", @@ -4682,7 +4695,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001580", "electron-to-chromium": "^1.4.648", @@ -5507,6 +5519,7 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -5611,6 +5624,7 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz", "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==", "dev": true, + "peer": true, "engines": { "node": ">=12" }, @@ -5623,6 +5637,7 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", "dev": true, + "peer": true, "engines": { "node": ">=12" } @@ -5646,7 +5661,8 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/eastasianwidth": { "version": "0.2.0", @@ -5659,6 +5675,7 @@ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, + "peer": true, "dependencies": { "jake": "^10.8.5" }, @@ -5703,6 +5720,7 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, + "peer": true, "dependencies": { "once": "^1.4.0" } @@ -5712,6 +5730,7 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, + "peer": true, "dependencies": { "ansi-colors": "^4.1.1" }, @@ -5883,7 +5902,6 @@ "dev": true, "hasInstallScript": true, "license": "MIT", - "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -5939,7 +5957,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6038,7 +6055,6 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -6097,7 +6113,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, - "peer": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -6661,6 +6676,7 @@ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, + "peer": true, "dependencies": { "minimatch": "^5.0.1" } @@ -6670,6 +6686,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6719,6 +6736,7 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "peer": true, "bin": { "flat": "cli.js" } @@ -6879,13 +6897,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "dev": true, + "peer": true }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -8049,6 +8069,7 @@ "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, + "peer": true, "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -8067,6 +8088,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -8083,6 +8105,7 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8093,6 +8116,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -8109,6 +8133,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -8120,13 +8145,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/jake/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -8136,6 +8163,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -8148,6 +8176,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8160,7 +8189,6 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -9899,7 +9927,8 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "dev": true, + "peer": true }, "node_modules/jsonfile": { "version": "6.1.0", @@ -10445,7 +10474,8 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/node-readfiles": { "version": "0.2.0", @@ -10503,6 +10533,7 @@ "integrity": "sha512-D7moIq+0D9WSjQmkVsce7GxKF603XASGBTApX6+fAdl2KN3aGG8zPlOEE55sVT0/OsdHeoHXPmydL/egTpG2WQ==", "dev": true, "hasInstallScript": true, + "peer": true, "dependencies": { "@nrwl/tao": "17.3.1", "@yarnpkg/lockfile": "^1.1.0", @@ -10573,6 +10604,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -10588,6 +10620,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10604,6 +10637,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10615,13 +10649,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/nx/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -10631,6 +10667,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -10643,6 +10680,7 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", "dev": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -10652,6 +10690,7 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", "dev": true, + "peer": true, "dependencies": { "bl": "^4.0.3", "chalk": "^4.1.0", @@ -10674,6 +10713,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, + "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -10689,6 +10729,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -10701,6 +10742,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "peer": true, "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -10909,6 +10951,7 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, + "peer": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -11499,7 +11542,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -11523,7 +11565,6 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -12645,6 +12686,7 @@ "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", "dev": true, + "peer": true, "dependencies": { "duplexer": "^0.1.1", "minimist": "^1.2.0", @@ -12788,6 +12830,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, + "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -12974,7 +13017,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -13290,6 +13332,21 @@ "webidl-conversions": "^4.0.2" } }, + "node_modules/tsup/node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/tsx": { "version": "4.19.3", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", @@ -13520,7 +13577,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13697,7 +13753,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -13780,6 +13835,21 @@ } } }, + "node_modules/vite-node/node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/vitest": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz", @@ -13901,7 +13971,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -13915,7 +13984,6 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -13985,6 +14053,21 @@ } } }, + "node_modules/vitest/node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -14295,7 +14378,7 @@ }, "packages/client": { "name": "@ton-api/client", - "version": "0.4.0", + "version": "0.5.0-alpha.6", "license": "MIT", "dependencies": { "core-js-pure": "^3.38.0" @@ -14409,6 +14492,19 @@ "@ton/core": ">=0.60.1" } }, + "packages/ton-adapter/node_modules/@ton-api/client": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@ton-api/client/-/client-0.4.0.tgz", + "integrity": "sha512-k3d6RzNWRDEZpVa9Gig2kHqp74tGvaK/imkjb08RIGxn+wKC7Yv5g98GnXEHf3srRkjtRCG0Nnjx8EsasOMJkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-js-pure": "^3.38.0" + }, + "peerDependencies": { + "@ton/core": ">=0.59.0" + } + }, "packages/ton-adapter/node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", diff --git a/package.json b/package.json index 37f9dff..f0e3aa9 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "test:client": "vitest run tests/client", "test:adapters": "vitest run tests/adapters", "test:integration": "INTEGRATION=true vitest run tests/client/integration.test.ts", + "test:memory-leak": "MEMORY_LEAK=true NODE_OPTIONS=\"--expose-gc\" vitest run tests/client/memory-leak.test.ts", "test:watch": "vitest", "build": "turbo run build", "build:client": "turbo run build --filter=@ton-api/client", diff --git a/tests/adapters/migratebeta.test.ts b/tests/adapters/migratebeta.test.ts deleted file mode 100644 index 54600e1..0000000 --- a/tests/adapters/migratebeta.test.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Address, Contract, ContractProvider, OpenedContract } from '@ton/ton'; -import { mnemonicNew, mnemonicToPrivateKey, KeyPair } from '@ton/crypto'; -import { ContractAdapter } from '@ton-api/ton-adapter'; -import { TonApiClient } from '@ton-api/client'; -import { test, beforeAll, expect } from 'vitest'; - -class NftItem implements Contract { - constructor(public readonly address: Address) {} - - static createFromAddress(address: Address) { - return new NftItem(address); - } - - async getData(provider: ContractProvider) { - return await provider.get('get_public_key', []); - } - - async getTransactions(provider: ContractProvider) { - const state = await provider.getState(); - const last = state.last!; - - return await provider.getTransactions(this.address, last.lt, last.hash, 10); - } -} - -// Create TonApiClient instance -const tonApiClient = new TonApiClient({ - baseUrl: 'https://tonapi.io' - // apiKey: 'your-api-key', -}); - -// Create an adapter with explicit client -const contractAdapter = new ContractAdapter(tonApiClient); -let keyPair: KeyPair; -let contract: OpenedContract; - -beforeAll(async () => { - // Create wallet contract - const mnemonics = await mnemonicNew(); - - keyPair = await mnemonicToPrivateKey(mnemonics); - const wallet = NftItem.createFromAddress( - Address.parse('UQAs87W4yJHlF8mt29ocA4agnMrLsOP69jC1HPyBUjJay7Mg') - ); - contract = contractAdapter.open(wallet); -}); - -test.skip('NftItem contract getData', async () => { - const data = await contract.getData(); - expect(data).toBeDefined(); -}); - -test.skip('NftItem contract getTransactions', async () => { - const transactions = await contract.getTransactions(); - expect(Array.isArray(transactions)).toBe(true); -}); diff --git a/tests/client/client.test.ts b/tests/client/client.test.ts index 1c823a1..58d07e4 100644 --- a/tests/client/client.test.ts +++ b/tests/client/client.test.ts @@ -38,26 +38,7 @@ test('Client apiKey test', async () => { ); }); -test('Client apiKey missing test', async () => { - const fetchSpy = mockFetch({ - rest_online: true, - indexing_latency: 8 - }); - - const res = await ta.status(); - expect(res).toBeDefined(); - - expect(fetchSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - headers: expect.not.objectContaining({ - Authorization: expect.anything() - }) - }) - ); -}); - -test('Client fallback test', async () => { +test('Client without apiKey should not include Authorization header', async () => { const fetchSpy = mockFetch({ rest_online: true, indexing_latency: 8 diff --git a/tests/client/memory-leak.test.ts b/tests/client/memory-leak.test.ts index 0ef408d..e700f9a 100644 --- a/tests/client/memory-leak.test.ts +++ b/tests/client/memory-leak.test.ts @@ -14,10 +14,13 @@ global.fetch = () => const tonApiClient = new TonApiClient({ baseUrl: 'https://tonapi.io' }); -// To run this test: -// NODE_OPTIONS="--expose-gc" npm run test tests/client/memory-leak.test.ts +// Memory leak tests - run separately with dedicated command +// These tests are resource-intensive and should not run in regular test suite +// Run with: npm run test:memory-leak -describe.skip('Memory leak test', () => { +const skipMemoryLeak = !process.env.MEMORY_LEAK; + +describe.skipIf(skipMemoryLeak)('Memory leak test', () => { const iterations = 500000; test('Memory leak test for instance API', async () => { diff --git a/tests/client/parse-address.test.ts b/tests/client/parse-address.test.ts index db7605a..83dc41d 100644 --- a/tests/client/parse-address.test.ts +++ b/tests/client/parse-address.test.ts @@ -83,3 +83,105 @@ test('MaybeAddress with empty string', async () => { expect(nftTransfer).toBeDefined(); expect(nftTransfer?.nft).toBeNull(); }); + +test('MaybeAddress with null value should return null', async () => { + // API returns null in maybe-address field + mockFetch({ + event_id: 'test-event-id-null', + account: { address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168' }, + timestamp: 1234567890, + actions: [ + { + type: 'NftItemTransfer', + status: 'ok', + NftItemTransfer: { + sender: { address: '0:1111111111111111111111111111111111111111111111111111111111111111' }, + recipient: { address: '0:2222222222222222222222222222222222222222222222222222222222222222' }, + nft: null // null in maybe-address field + } + } + ] + }); + + const data = await ta.getAccountEvent( + Address.parse('0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'), + 'test-event-id-null' + ); + + expect(data).toBeDefined(); + expect(data.actions[0]).toBeDefined(); + const nftTransfer = data.actions[0]?.NftItemTransfer; + expect(nftTransfer).toBeDefined(); + expect(nftTransfer?.nft).toBeNull(); +}); + +test('MaybeAddress with invalid address should throw parsing error', async () => { + // API returns invalid address string in maybe-address field + const mockInvalidAddressData = { + event_id: 'test-event-id-invalid', + account: { address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168' }, + timestamp: 1234567890, + actions: [ + { + type: 'NftItemTransfer', + status: 'ok', + NftItemTransfer: { + sender: { address: '0:1111111111111111111111111111111111111111111111111111111111111111' }, + recipient: { address: '0:2222222222222222222222222222222222222222222222222222222222222222' }, + nft: 'totally-invalid-address-string' // Invalid address in maybe-address field + } + } + ] + }; + + mockFetch(mockInvalidAddressData); + + try { + await ta.getAccountEvent( + Address.parse('0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168'), + 'test-event-id-invalid' + ); + expect.fail('Should have thrown TonApiParsingError'); + } catch (error: any) { + expect(error).toBeDefined(); + expect(error.type).toBe('parsing_error'); + expect(error.parsingType).toBe('MaybeAddress'); + } +}); + +test('Address accepts both friendly and raw formats in request', async () => { + // Test raw format + const rawAddress = '0:2f0df5851b4a185f5f63c0d0cd0412f5aca353f577da18ff47c936f99dbd849a'; + const fetchSpyRaw = mockFetch({ + address: rawAddress, + balance: '1000000000', + status: 'active' + }); + + await ta.getAccount(Address.parse(rawAddress)); + + // Address should be sent in raw format + expect(fetchSpyRaw).toHaveBeenCalledWith( + expect.stringContaining(rawAddress), + expect.any(Object) + ); + + vi.restoreAllMocks(); + + // Test friendly format + const friendlyAddress = 'EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'; + const fetchSpyFriendly = mockFetch({ + address: friendlyAddress, + balance: '1000000000', + status: 'active' + }); + + await ta.getAccount(Address.parse(friendlyAddress)); + + // Address object should be serialized to raw format + const addressObject = Address.parse(friendlyAddress); + expect(fetchSpyFriendly).toHaveBeenCalledWith( + expect.stringContaining(addressObject.toRawString()), + expect.any(Object) + ); +}); diff --git a/tests/client/parse-bigint.test.ts b/tests/client/parse-bigint.test.ts index 3aab9b2..a2e4bf9 100644 --- a/tests/client/parse-bigint.test.ts +++ b/tests/client/parse-bigint.test.ts @@ -35,3 +35,31 @@ test('BigInt parse data in string test', async () => { expect(data).toBeDefined(); expect(typeof data?.totalSupply).toBe('bigint'); }); + +test('BigInt parse very large numbers beyond Number.MAX_SAFE_INTEGER', async () => { + // Number.MAX_SAFE_INTEGER = 9007199254740991 (2^53 - 1) + // Test with a number much larger than that + const veryLargeNumber = '9999999999999999999999999'; // 25 digits + + mockFetch({ + accounts: [ + { + address: '0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168', + balance: veryLargeNumber, + status: 'active' + } + ] + }); + + const addressStrings = ['0:009d03ddede8c2620a72f999d03d5888102250a214bf574a29ff64df80162168']; + const accountIds = addressStrings.map(addr => Address.parse(addr)); + const data = await ta.getAccounts({ accountIds }); + + expect(data).toBeDefined(); + expect(data?.accounts).toHaveLength(1); + expect(typeof data?.accounts[0]?.balance).toBe('bigint'); + // Verify the exact value is preserved without precision loss + expect(data?.accounts[0]?.balance).toBe(BigInt(veryLargeNumber)); + // Verify it's actually larger than Number.MAX_SAFE_INTEGER + expect(data?.accounts[0]?.balance).toBeGreaterThan(BigInt(Number.MAX_SAFE_INTEGER)); +}); diff --git a/tests/client/parse-tuple.test.ts b/tests/client/parse-tuple.test.ts index 17a241d..5746d9f 100644 --- a/tests/client/parse-tuple.test.ts +++ b/tests/client/parse-tuple.test.ts @@ -1,4 +1,4 @@ -import { Address, Tuple, TupleItem } from '@ton/core'; +import { Address, Cell, Tuple, TupleItem } from '@ton/core'; import { ta } from './utils/client'; import { execGetMethodForBlockchainAccount as execGetMethodForBlockchainAccountMock } from './__mock__/tuple'; import { mockFetch } from './utils/mockFetch'; @@ -59,3 +59,120 @@ test('Tuple test', async () => { expect(secondLevelTupleFirst.items).toBeDefined(); }); + +test('TupleItem num type with hexadecimal value', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'num', + num: '0xabc123' // Hexadecimal positive number + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const data = await ta.execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeDefined(); + expect(data?.stack[0]).toBeDefined(); + expect(data?.stack[0]?.type).toBe('int'); + + if (data?.stack[0]?.type === 'int') { + // 0xabc123 = 11256099 + expect(data.stack[0].value).toBe(11256099n); + } +}); + +test('TupleItem num type with negative hexadecimal value', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'num', + num: '-0xabc123' // Negative hexadecimal number + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const data = await ta.execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeDefined(); + expect(data?.stack[0]).toBeDefined(); + expect(data?.stack[0]?.type).toBe('int'); + + if (data?.stack[0]?.type === 'int') { + // -0xabc123 = -11256099 + expect(data.stack[0].value).toBe(-11256099n); + } +}); + +test('TupleItem slice type parsing', async () => { + // Valid empty cell in hex format + const validCellHex = 'b5ee9c724101010100020000004cacb9cd'; + + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'slice', + slice: validCellHex + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const data = await ta.execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeDefined(); + expect(data?.stack[0]).toBeDefined(); + expect(data?.stack[0]?.type).toBe('slice'); + + if (data?.stack[0]?.type === 'slice') { + expect(data.stack[0].slice).toBeDefined(); + // Should be parsed as Cell + expect(data.stack[0].slice).toBeInstanceOf(Cell); + } +}); + +test('TupleItem null type parsing', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'null' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const data = await ta.execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeDefined(); + expect(data?.stack[0]).toBeDefined(); + expect(data?.stack[0]?.type).toBe('null'); +}); + +test('TupleItem nan type parsing', async () => { + mockFetch({ + success: true, + exit_code: 0, + stack: [ + { + type: 'nan' + } + ] + }); + + const address = Address.parse('EQAvDfWFG0oYX19jwNDNBBL1rKNT9XfaGP9HyTb5nb2Eml6y'); + const data = await ta.execGetMethodForBlockchainAccount(address, 'get_data'); + + expect(data).toBeDefined(); + expect(data?.stack[0]).toBeDefined(); + expect(data?.stack[0]?.type).toBe('nan'); +}); diff --git a/tests/client/type-tests.test.ts b/tests/client/type-tests.test.ts index 7b40cc0..195081d 100644 --- a/tests/client/type-tests.test.ts +++ b/tests/client/type-tests.test.ts @@ -25,13 +25,42 @@ beforeEach(() => { initClient({ baseUrl: 'https://tonapi.io' }); // Mock fetch to prevent actual API calls during type tests - // These calls are never awaited - they're just for type checking - vi.spyOn(global, 'fetch').mockResolvedValue( - new Response(JSON.stringify({}), { + // Return valid mock data to prevent runtime errors while type checking + vi.spyOn(global, 'fetch').mockImplementation(async (url: RequestInfo | URL) => { + const urlStr = typeof url === 'string' ? url : url.toString(); + + // Mock different responses based on endpoint + if (urlStr.includes('/status')) { + return new Response(JSON.stringify({ + rest_online: true, + indexing_latency: 8 + }), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + if (urlStr.includes('/accounts/')) { + return new Response(JSON.stringify({ + address: 'EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin', + balance: '1000000000', + status: 'active' + }), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + } + + // Default response for other endpoints + return new Response(JSON.stringify({ + rest_online: true, + indexing_latency: 8, + accounts: [] + }), { status: 200, headers: { 'Content-Type': 'application/json' } - }) - ); + }); + }); }); test('Advanced API - Global methods with ThrowOnError', () => { From 8b0d704523c14360d0d298af5d1844c16af54d95 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Thu, 4 Dec 2025 16:12:48 +0700 Subject: [PATCH 21/27] chore: bump version to 0.5.0-alpha.7 --- package-lock.json | 140 +++++++--------------------------- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- 4 files changed, 31 insertions(+), 115 deletions(-) diff --git a/package-lock.json b/package-lock.json index 257822c..f4769ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ton-api", - "version": "0.5.0-alpha.6", + "version": "0.5.0-alpha.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ton-api", - "version": "0.5.0-alpha.6", + "version": "0.5.0-alpha.7", "hasInstallScript": true, "license": "MIT", "workspaces": [ @@ -86,6 +86,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -3000,7 +3001,6 @@ "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.3.1.tgz", "integrity": "sha512-MtHlsdErSz0Z1j8j+qAKUafWzMs3XcHgXmJomjUzect1jS/HtmbcDvdMv9GwVtk+67JD+7ca2CWjk2atv6dZdw==", "dev": true, - "peer": true, "dependencies": { "@nx/devkit": "17.3.1" } @@ -3010,7 +3010,6 @@ "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.3.1.tgz", "integrity": "sha512-bohZt2rzqCz2ITOpQ6H7sYlHhxn3NftHDz0a0QVVDJojjpak73r8XV0zCk2yUN2T8HdRJVyYLyAqDENl9X48pA==", "dev": true, - "peer": true, "dependencies": { "nx": "17.3.1", "tslib": "^2.3.0" @@ -3024,7 +3023,6 @@ "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.3.1.tgz", "integrity": "sha512-E44feT7x/pGTzMWSndjTAoBXvZYEdy2SU99O14LdW7atUK4gv0glKUfyq6nNFULrs6r173WKfJgfmJDL3l78lg==", "dev": true, - "peer": true, "dependencies": { "@nrwl/devkit": "17.3.1", "ejs": "^3.1.7", @@ -3044,7 +3042,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, - "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -3067,7 +3064,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3084,7 +3080,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3101,7 +3096,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3118,7 +3112,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3135,7 +3128,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3152,7 +3144,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3169,7 +3160,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3186,7 +3176,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3203,7 +3192,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3220,7 +3208,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10" } @@ -3588,6 +3575,7 @@ "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.60.1.tgz", "integrity": "sha512-8FwybYbfkk57C3l9gvnlRhRBHbLYmeu0LbB1z9N+dhDz0Z+FJW8w0TJlks8CgHrAFxsT3FlR2LsqFnsauMp38w==", "license": "MIT", + "peer": true, "dependencies": { "symbol.inspect": "1.0.1" }, @@ -3802,6 +3790,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.20.0", @@ -3837,6 +3826,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.20.0.tgz", "integrity": "sha512-bYerPDF/H5v6V76MdMYhjwmwgMA+jlPVqjSDq2cRqMi8bP5sR3Z+RLOiOMad3nsnmDVmn2gAFCyNgh/dIrfP/w==", "dev": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.20.0", "@typescript-eslint/types": "6.20.0", @@ -4090,7 +4080,6 @@ "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", "dev": true, - "peer": true, "dependencies": { "js-yaml": "^3.10.0", "tslib": "^2.4.0" @@ -4104,7 +4093,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "peer": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -4114,7 +4102,6 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4128,7 +4115,6 @@ "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", "dev": true, - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4141,6 +4127,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4384,8 +4371,7 @@ "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/asynckit": { "version": "0.4.0", @@ -4695,6 +4681,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001580", "electron-to-chromium": "^1.4.648", @@ -5519,7 +5506,6 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -5624,7 +5610,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz", "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -5637,7 +5622,6 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", "dev": true, - "peer": true, "engines": { "node": ">=12" } @@ -5661,8 +5645,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/eastasianwidth": { "version": "0.2.0", @@ -5675,7 +5658,6 @@ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, - "peer": true, "dependencies": { "jake": "^10.8.5" }, @@ -5720,7 +5702,6 @@ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "peer": true, "dependencies": { "once": "^1.4.0" } @@ -5730,7 +5711,6 @@ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, - "peer": true, "dependencies": { "ansi-colors": "^4.1.1" }, @@ -5902,6 +5882,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -5957,6 +5938,7 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -6055,6 +6037,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -6113,6 +6096,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, + "peer": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -6676,7 +6660,6 @@ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, - "peer": true, "dependencies": { "minimatch": "^5.0.1" } @@ -6686,7 +6669,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6736,7 +6718,6 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "peer": true, "bin": { "flat": "cli.js" } @@ -6897,15 +6878,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -8069,7 +8048,6 @@ "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, - "peer": true, "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -8088,7 +8066,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -8105,7 +8082,6 @@ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -8116,7 +8092,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -8133,7 +8108,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -8145,15 +8119,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jake/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -8163,7 +8135,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -8176,7 +8147,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8189,6 +8159,7 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -9927,8 +9898,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/jsonfile": { "version": "6.1.0", @@ -10474,8 +10444,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/node-readfiles": { "version": "0.2.0", @@ -10533,7 +10502,6 @@ "integrity": "sha512-D7moIq+0D9WSjQmkVsce7GxKF603XASGBTApX6+fAdl2KN3aGG8zPlOEE55sVT0/OsdHeoHXPmydL/egTpG2WQ==", "dev": true, "hasInstallScript": true, - "peer": true, "dependencies": { "@nrwl/tao": "17.3.1", "@yarnpkg/lockfile": "^1.1.0", @@ -10604,7 +10572,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -10620,7 +10587,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -10637,7 +10603,6 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -10649,15 +10614,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/nx/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -10667,7 +10630,6 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -10680,7 +10642,6 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", "dev": true, - "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -10690,7 +10651,6 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", "dev": true, - "peer": true, "dependencies": { "bl": "^4.0.3", "chalk": "^4.1.0", @@ -10713,7 +10673,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, - "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -10729,7 +10688,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -10742,7 +10700,6 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, - "peer": true, "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -10951,7 +10908,6 @@ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, - "peer": true, "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -11542,6 +11498,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -11565,6 +11522,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", "dev": true, + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -12686,7 +12644,6 @@ "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", "dev": true, - "peer": true, "dependencies": { "duplexer": "^0.1.1", "minimist": "^1.2.0", @@ -12830,7 +12787,6 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, - "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -13017,6 +12973,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -13332,21 +13289,6 @@ "webidl-conversions": "^4.0.2" } }, - "node_modules/tsup/node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, "node_modules/tsx": { "version": "4.19.3", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.3.tgz", @@ -13577,6 +13519,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13753,6 +13696,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -13835,21 +13779,6 @@ } } }, - "node_modules/vite-node/node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, "node_modules/vitest": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz", @@ -13971,6 +13900,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -13984,6 +13914,7 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -14053,21 +13984,6 @@ } } }, - "node_modules/vitest/node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -14378,7 +14294,7 @@ }, "packages/client": { "name": "@ton-api/client", - "version": "0.5.0-alpha.6", + "version": "0.5.0-alpha.7", "license": "MIT", "dependencies": { "core-js-pure": "^3.38.0" diff --git a/package.json b/package.json index f0e3aa9..3b4e181 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.6", + "version": "0.5.0-alpha.7", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 75291e4..7b99d67 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.6", + "version": "0.5.0-alpha.7", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 0be79d7..7d6164a 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3686,7 +3686,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.6` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.7` }; const preparedApiConfig = { From 83f12afb406225ef5548241f69e9d583a33edb0f Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Wed, 10 Dec 2025 18:59:53 +0700 Subject: [PATCH 22/27] chore(client): fix type for extra field and improve descriptions --- packages/client/src/api.yml | 33 ++++++++++++++++++++--------- packages/client/src/client.ts | 39 +++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index 2e8fdf8..6758519 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -2832,7 +2832,7 @@ paths: $ref: '#/components/responses/Error' /v2/wallet/emulate: post: - description: Emulate sending message to retrieve the resulting wallet state + description: Emulates a wallet message on the current blockchain state and derives its consequences for the signing wallet operationId: emulateMessageToWallet tags: - Emulation @@ -2844,7 +2844,7 @@ paths: $ref: '#/components/requestBodies/EmulationBoc' responses: '200': - description: emulated message + description: Emulated wallet message consequences content: application/json: schema: @@ -6783,7 +6783,8 @@ components: $ref: '#/components/schemas/AccountAddress' AccountEvent: type: object - description: An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. + description: | + High-level view over a transaction trace caused by a single inbound message. TonAPI analyses the trace, detects known patterns and groups low-level transactions into user-facing actions (Jetton transfer, NFT purchase, etc.). Actions are a best-effort UI abstraction and may change; do not rely on them for protocol-critical logic. required: - event_id - timestamp @@ -6820,20 +6821,24 @@ components: in_progress: type: boolean example: false - description: Event is not finished yet. Transactions still happening + description: Event trace is not finished yet. Transactions still happening. extra: - description: TODO type: integer format: int64 + x-js-format: bigint example: 3 + description: | + Net TON change for this account not explained by actions, in nanotons: extra = final_balance - initial_balance - sum(explicit TON changes from actions). extra < 0 - implicit fee, extra > 0 - refund. For UI display only progress: type: number format: float minimum: 0 maximum: 1 example: 0.5 + description: Event completion ratio in [0,1] AccountEvents: type: object + description: Paginated list of events for a single account. required: - events - next_from @@ -7168,6 +7173,8 @@ components: example: false MessageConsequences: type: object + description: | + Result of emulating a wallet message on the current blockchain state: describes the expected on-chain consequences (trace, high-level AccountEvent, risk) for the signing wallet. For UI display only. required: - trace - risk @@ -7181,7 +7188,8 @@ components: $ref: '#/components/schemas/AccountEvent' Risk: type: object - description: Risk specifies assets that could be lost if a message would be sent to a malicious smart contract. It makes sense to understand the risk BEFORE sending a message to the blockchain. + description: | + Conservative upper bound on assets this wallet may lose if the emulated message is sent and the counterparty behaves maliciously. Values may exceed current balances (e.g. already-authorized future receipts). For UI display only. required: - transfer_all_remaining_balance - ton @@ -7190,25 +7198,30 @@ components: properties: transfer_all_remaining_balance: type: boolean - description: transfer all the remaining balance of the wallet. + description: | + True if the message semantics allow sweeping all current and future remaining TON balance of the wallet (e.g. “send all” / drain patterns). example: true ton: type: integer format: int64 - example: 500 x-js-format: bigint + example: 500 + description: Maximum TON amount that may leave the wallet in the worst case, in nanotons. jettons: type: array + description: Jetton positions that may be debited from the wallet in the worst case. items: $ref: '#/components/schemas/JettonQuantity' nfts: type: array + description: NFT items that may be transferred out of the wallet in the worst case. items: $ref: '#/components/schemas/NftItem' total_equivalent: type: number format: float - description: Estimated equivalent value of all assets at risk in selected currency (for example USD) + description: | + Estimated equivalent of all assets at risk (TON, jettons, NFTs) in the selected currency from currencyQuery (e.g. USD). Approximate, best-effort UI value. JettonQuantity: type: object required: @@ -7388,7 +7401,7 @@ components: in_progress: type: boolean example: false - description: Event is not finished yet. Transactions still happening + description: Event trace is not finished yet. Transactions still happening. progress: type: number format: float diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 7d6164a..b29989a 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -1112,6 +1112,7 @@ export interface SignRawParams { */ validUntil: number; messages: SignRawMessage[]; + /** Result of emulating a wallet message on the current blockchain state: describes the expected on-chain consequences (trace, high-level AccountEvent, risk) for the signing wallet. For UI display only. */ emulation?: MessageConsequences; } @@ -1714,7 +1715,7 @@ export interface MultisigOrder { approvalsNum: number; /** @format int64 */ expirationDate: number; - /** Risk specifies assets that could be lost if a message would be sent to a malicious smart contract. It makes sense to understand the risk BEFORE sending a message to the blockchain. */ + /** Conservative upper bound on assets this wallet may lose if the emulated message is sent and the counterparty behaves maliciously. Values may exceed current balances (e.g. already-authorized future receipts). For UI display only. */ risk: Risk; /** @format int64 */ creationDate: number; @@ -2214,7 +2215,7 @@ export interface ActionSimplePreview { accounts: AccountAddress[]; } -/** An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. */ +/** High-level view over a transaction trace caused by a single inbound message. TonAPI analyses the trace, detects known patterns and groups low-level transactions into user-facing actions (Jetton transfer, NFT purchase, etc.). Actions are a best-effort UI abstraction and may change; do not rely on them for protocol-critical logic. */ export interface AccountEvent { /** @example "e8b0e3fee4a26bd2317ac1f9952fcdc87dc08fdb617656b5202416323337372e" */ eventId: string; @@ -2236,17 +2237,18 @@ export interface AccountEvent { */ lt: bigint; /** - * Event is not finished yet. Transactions still happening + * Event trace is not finished yet. Transactions still happening. * @example false */ inProgress: boolean; /** - * TODO - * @format int64 + * Net TON change for this account not explained by actions, in nanotons: extra = final_balance - initial_balance - sum(explicit TON changes from actions). extra < 0 - implicit fee, extra > 0 - refund. For UI display only + * @format bigint * @example 3 */ - extra: number; + extra: bigint; /** + * Event completion ratio in [0,1] * @format float * @min 0 * @max 1 @@ -2255,6 +2257,7 @@ export interface AccountEvent { progress: number; } +/** Paginated list of events for a single account. */ export interface AccountEvents { events: AccountEvent[]; /** @@ -2467,30 +2470,34 @@ export interface Trace { emulated?: boolean; } +/** Result of emulating a wallet message on the current blockchain state: describes the expected on-chain consequences (trace, high-level AccountEvent, risk) for the signing wallet. For UI display only. */ export interface MessageConsequences { trace: Trace; - /** Risk specifies assets that could be lost if a message would be sent to a malicious smart contract. It makes sense to understand the risk BEFORE sending a message to the blockchain. */ + /** Conservative upper bound on assets this wallet may lose if the emulated message is sent and the counterparty behaves maliciously. Values may exceed current balances (e.g. already-authorized future receipts). For UI display only. */ risk: Risk; - /** An event is built on top of a trace which is a series of transactions caused by one inbound message. TonAPI looks for known patterns inside the trace and splits the trace into actions, where a single action represents a meaningful high-level operation like a Jetton Transfer or an NFT Purchase. Actions are expected to be shown to users. It is advised not to build any logic on top of actions because actions can be changed at any time. */ + /** High-level view over a transaction trace caused by a single inbound message. TonAPI analyses the trace, detects known patterns and groups low-level transactions into user-facing actions (Jetton transfer, NFT purchase, etc.). Actions are a best-effort UI abstraction and may change; do not rely on them for protocol-critical logic. */ event: AccountEvent; } -/** Risk specifies assets that could be lost if a message would be sent to a malicious smart contract. It makes sense to understand the risk BEFORE sending a message to the blockchain. */ +/** Conservative upper bound on assets this wallet may lose if the emulated message is sent and the counterparty behaves maliciously. Values may exceed current balances (e.g. already-authorized future receipts). For UI display only. */ export interface Risk { /** - * transfer all the remaining balance of the wallet. + * True if the message semantics allow sweeping all current and future remaining TON balance of the wallet (e.g. “send all” / drain patterns). * @example true */ transferAllRemainingBalance: boolean; /** + * Maximum TON amount that may leave the wallet in the worst case, in nanotons. * @format bigint * @example 500 */ ton: bigint; + /** Jetton positions that may be debited from the wallet in the worst case. */ jettons: JettonQuantity[]; + /** NFT items that may be transferred out of the wallet in the worst case. */ nfts: NftItem[]; /** - * Estimated equivalent value of all assets at risk in selected currency (for example USD) + * Estimated equivalent of all assets at risk (TON, jettons, NFTs) in the selected currency from currencyQuery (e.g. USD). Approximate, best-effort UI value. * @format float */ totalEquivalent?: number; @@ -2611,7 +2618,7 @@ export interface Event { */ lt: bigint; /** - * Event is not finished yet. Transactions still happening + * Event trace is not finished yet. Transactions still happening. * @example false */ inProgress: boolean; @@ -5684,7 +5691,7 @@ const components = { is_scam: { type: 'boolean' }, lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, in_progress: { type: 'boolean' }, - extra: { type: 'integer', format: 'int64' }, + extra: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 } } }, @@ -11277,14 +11284,14 @@ export class TonApiClient { } /** - * @description Emulate sending message to retrieve the resulting wallet state + * @description Emulates a wallet message on the current blockchain state and derives its consequences for the signing wallet * * @tags Emulation, Wallet * @name EmulateMessageToWallet * @request POST:/v2/wallet/emulate */ /** - * @description Emulate sending message to retrieve the resulting wallet state + * @description Emulates a wallet message on the current blockchain state and derives its consequences for the signing wallet * * @tags Emulation, Wallet * @name EmulateMessageToWallet @@ -16632,7 +16639,7 @@ export const emulateMessageToTrace = async Date: Wed, 10 Dec 2025 19:32:41 +0700 Subject: [PATCH 23/27] chore: bump version to 0.5.0-alpha.8 --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3b4e181..efe366a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.7", + "version": "0.5.0-alpha.8", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 7b99d67..7166bb3 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.7", + "version": "0.5.0-alpha.8", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index b29989a..ceaf3ee 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3693,7 +3693,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.7` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.8` }; const preparedApiConfig = { From fef0e2018d8b2761893e0ae48d9dd7a9d2b445c9 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Mon, 22 Dec 2025 15:00:06 +0530 Subject: [PATCH 24/27] fix(client): correct BlockchainConfig code_hash type from Address to string The code_hash field in BlockchainConfig config 45 was incorrectly typed as Address, causing parsing errors when SDK attempted to parse hex hash strings (e.g., '89468f02c78e570802e39979c8516fc38df07ea76a48357e0536f2ba7b3ee37b') as blockchain addresses. Changes: - Remove incorrect 'format: address' annotation from code_hash in api.yml - Update TypeScript type from Address to string in client.ts - Add integration test for getBlockchainConfig to prevent regression The code_hash field contains contract code hashes (64 hex characters), not addresses. --- packages/client/src/api.yml | 1 - packages/client/src/client.ts | 5 ++-- tests/client/integration.test.ts | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index 6758519..79433f2 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -5522,7 +5522,6 @@ components: properties: code_hash: type: string - format: address gas_usage: type: integer format: int64 diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index ceaf3ee..e8e8864 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -1431,8 +1431,7 @@ export interface BlockchainConfig { /** precompiled contracts */ '45'?: { contracts: { - /** @format address */ - codeHash: Address; + codeHash: string; /** @format int64 */ gasUsage: number; }[]; @@ -4989,7 +4988,7 @@ const components = { type: 'object', required: ['code_hash', 'gas_usage'], properties: { - code_hash: { type: 'string', format: 'address' }, + code_hash: { type: 'string' }, gas_usage: { type: 'integer', format: 'int64' } } } diff --git a/tests/client/integration.test.ts b/tests/client/integration.test.ts index dc2e504..536e0dc 100644 --- a/tests/client/integration.test.ts +++ b/tests/client/integration.test.ts @@ -137,4 +137,43 @@ test('getChartRates - real API call with address strings', async () => { expect(dataFriendly.points.length).toBeGreaterThan(0); }); +test('getBlockchainConfig - real API call', async () => { + const data = await ta.getBlockchainConfig(); + + expect(data).toBeDefined(); + + // Check raw config + expect(data.raw).toBeDefined(); + + // Check some common config parameters that should always exist + // Config 0: config address + expect(data['0']).toBeDefined(); + expect(data['0']).toBeInstanceOf(Address); + + // Config 1: elector address + expect(data['1']).toBeDefined(); + expect(data['1']).toBeInstanceOf(Address); + + // Config 8: version and capabilities + if (data['8']) { + expect(data['8'].version).toBeDefined(); + expect(typeof data['8'].version).toBe('number'); + expect(data['8'].capabilities).toBeDefined(); + expect(typeof data['8'].capabilities).toBe('number'); + } + + // Config 15: validators elected for + if (data['15']) { + expect(data['15'].validatorsElectedFor).toBeDefined(); + expect(typeof data['15'].validatorsElectedFor).toBe('number'); + } + + // Config 18: storage prices + if (data['18']) { + expect(data['18'].storagePrices).toBeDefined(); + expect(Array.isArray(data['18'].storagePrices)).toBe(true); + expect(data['18'].storagePrices.length).toBeGreaterThan(0); + } +}); + }); From 363037e4b3aa4be58a1401902007985ba3220006 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Mon, 22 Dec 2025 15:14:13 +0530 Subject: [PATCH 25/27] chore: bump version to 0.5.0-alpha.9 --- package.json | 2 +- packages/client/package.json | 2 +- packages/client/src/client.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index efe366a..71e1745 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ton-api", "private": true, - "version": "0.5.0-alpha.8", + "version": "0.5.0-alpha.9", "type": "module", "scripts": { "postinstall": "patch-package", diff --git a/packages/client/package.json b/packages/client/package.json index 7166bb3..1b02b90 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@ton-api/client", - "version": "0.5.0-alpha.8", + "version": "0.5.0-alpha.9", "description": "Autogenerated SDK for tonapi.io", "keywords": [ "TON", diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index e8e8864..efaf441 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -3692,7 +3692,7 @@ class HttpClient { const headers = { ...(baseApiParams.headers ?? {}), ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}), - 'x-tonapi-client': `tonapi-js@0.5.0-alpha.8` + 'x-tonapi-client': `tonapi-js@0.5.0-alpha.9` }; const preparedApiConfig = { From 3bbf46968c0edc92b0f2055ef7fdd207b79e5754 Mon Sep 17 00:00:00 2001 From: Moiseev Ilya Date: Mon, 22 Dec 2025 18:18:09 +0530 Subject: [PATCH 26/27] fix(client): add stack trace to parsing error console output Include stack trace in TonApiParsingError console.error output to help developers identify which API method caused the parsing failure. --- packages/client/src/client.ts | 3 ++- packages/client/src/templates/errors.ejs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index efaf441..cf3fed4 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -6493,7 +6493,8 @@ export class TonApiParsingError extends TonApiErrorAbstract { { type: parsingType, message: message, - response: response + response: response, + stack: this.stack } ); } diff --git a/packages/client/src/templates/errors.ejs b/packages/client/src/templates/errors.ejs index 12a89d1..a73bba1 100644 --- a/packages/client/src/templates/errors.ejs +++ b/packages/client/src/templates/errors.ejs @@ -105,7 +105,8 @@ export class TonApiParsingError extends TonApiErrorAbstract { { type: parsingType, message: message, - response: response + response: response, + stack: this.stack } ); } From f508238f0f9b2d8bae63a40941dae491cdf5a2a7 Mon Sep 17 00:00:00 2001 From: Jora Date: Sat, 20 Jun 2026 00:46:12 +0300 Subject: [PATCH 27/27] chore: bump version to 0.5.1 and update API schema - Updated package version to 0.5.1 in package-lock.json and client package.json. - Enhanced API schema with new endpoints for bulk account retrieval and validator information. - Added new parameters for pagination and sorting in various API calls. - Introduced new data structures for handling blockchain accounts and wallets. --- package-lock.json | 6 +- packages/client/src/api.yml | 1162 ++++++++++++++++++- packages/client/src/client.ts | 2027 +++++++++++++++++++++++++++++++-- 3 files changed, 3053 insertions(+), 142 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4769ae..5607ab2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ton-api", - "version": "0.5.0-alpha.7", + "version": "0.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ton-api", - "version": "0.5.0-alpha.7", + "version": "0.5.1", "hasInstallScript": true, "license": "MIT", "workspaces": [ @@ -14294,7 +14294,7 @@ }, "packages/client": { "name": "@ton-api/client", - "version": "0.5.0-alpha.7", + "version": "0.5.0-alpha.9", "license": "MIT", "dependencies": { "core-js-pure": "^3.38.0" diff --git a/packages/client/src/api.yml b/packages/client/src/api.yml index 79433f2..a528c05 100644 --- a/packages/client/src/api.yml +++ b/packages/client/src/api.yml @@ -230,6 +230,14 @@ paths: - Blockchain parameters: - $ref: '#/components/parameters/masterchainSeqno' + - $ref: '#/components/parameters/offsetQuery' + - name: limit + in: query + required: false + schema: + type: integer + example: 100 + minimum: 1 responses: '200': description: blockchain transactions @@ -371,6 +379,23 @@ paths: $ref: '#/components/schemas/BlockchainRawAccount' default: $ref: '#/components/responses/Error' + /v2/blockchain/accounts/_bulk: + post: + description: Get low-level information about several accounts taken directly from the blockchain. + operationId: getBlockchainRawAccounts + tags: + - Blockchain + requestBody: + $ref: '#/components/requestBodies/AccountIDs' + responses: + '200': + description: a list of raw accounts + content: + application/json: + schema: + $ref: '#/components/schemas/BlockchainRawAccounts' + default: + $ref: '#/components/responses/Error' /v2/blockchain/accounts/{account_id}/transactions: get: description: Get account transactions @@ -669,6 +694,8 @@ paths: - $ref: '#/components/parameters/accountIDParameter' - $ref: '#/components/parameters/currenciesQuery' - $ref: '#/components/parameters/supportedExtensions' + - $ref: '#/components/parameters/limitQuery' + - $ref: '#/components/parameters/offsetQuery' responses: '200': description: account jettons balances @@ -799,7 +826,7 @@ paths: - in: query name: indirect_ownership required: false - description: Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. + description: Selling nft items in TON implemented usually via transfer items to special selling account. This option enables including items which owned not directly. schema: type: boolean default: false @@ -864,6 +891,15 @@ paths: type: boolean default: false required: false + - name: after_lt + in: query + description: omit this parameter to get last events + required: false + schema: + type: integer + format: int64 + example: 25758317000002 + x-js-format: bigint - name: before_lt in: query description: omit this parameter to get last events @@ -897,6 +933,15 @@ paths: format: int64 maximum: 2114380800 example: 1668436763 + - name: sort_order + in: query + schema: + type: string + description: used to sort the result-set in ascending or descending order by lt. + default: desc + enum: + - desc + - asc responses: '200': description: account's events @@ -1117,6 +1162,24 @@ paths: example: 1000000000 default: $ref: '#/components/responses/Error' + /v2/accounts/{account_id}/defi/assets: + get: + description: | + Return DeFi assets locked in custom smart contracts: currently returns TON Whales staking and EVAA lending positions. + operationId: getAccountDefiAssets + tags: + - Accounts + parameters: + - $ref: '#/components/parameters/accountIDParameter' + responses: + '200': + description: account's DeFi assets + content: + application/json: + schema: + $ref: '#/components/schemas/DefiAssets' + default: + $ref: '#/components/responses/Error' /v2/accounts/{account_id}/extra-currency/{id}/history: get: description: Get the transfer history of extra currencies for an account. @@ -1698,6 +1761,25 @@ paths: - Staking parameters: - $ref: '#/components/parameters/accountIDParameter' + - name: before_lt + in: query + description: omit this parameter to get last log entries + required: false + schema: + type: integer + format: int64 + example: 25758317000002 + x-js-format: bigint + - name: limit + in: query + required: false + schema: + type: integer + format: int32 + default: 100 + maximum: 100 + minimum: 1 + example: 100 responses: '200': description: pool history @@ -1901,7 +1983,7 @@ paths: $ref: '#/components/responses/Error' /v2/rates/markets: get: - description: Get the TON price from markets + description: Get the Gram price from markets operationId: getMarketsRates tags: - Rates @@ -2092,6 +2174,23 @@ paths: $ref: '#/components/schemas/Wallets' default: $ref: '#/components/responses/Error' + /v2/pubkeys/wallets/_bulk: + post: + description: Get wallets by a list of public keys + operationId: getWalletsByPublicKeyBulk + tags: + - Wallet + requestBody: + $ref: '#/components/requestBodies/PublicKeys' + responses: + '200': + description: grouped wallets per public key + content: + application/json: + schema: + $ref: '#/components/schemas/WalletsByPublicKeys' + default: + $ref: '#/components/responses/Error' /v2/liteserver/get_masterchain_info: get: description: Get raw masterchain info @@ -2912,6 +3011,174 @@ paths: $ref: '#/components/schemas/AccountPurchases' default: $ref: '#/components/responses/Error' + /v2/rewards/validators: + get: + operationId: getValidators + tags: + - Rewards + summary: Get all current validators + description: | + Returns all current validators with stakes, rewards, pool addresses, and (optionally) nominator breakdowns. + parameters: + - name: seqno + in: query + description: | + Masterchain block seqno. Defaults to latest. Mutually exclusive with `unixtime`. + required: false + schema: + type: integer + format: uint32 + - name: unixtime + in: query + description: | + Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `seqno`. + required: false + schema: + type: integer + format: uint32 + - name: shallow + in: query + description: | + Set to `1` to return only basic validator info (rank, pubkey, effective_stake, weight, reward, pool). Skips pool type detection, owner/validator addresses, nominator data, and returned-stake lookup — significantly faster. + required: false + schema: + type: boolean + default: false + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ValidatorsResponse' + default: + $ref: '#/components/responses/Error' + /v2/rewards/validation-rounds: + get: + operationId: getValidationRounds + tags: + - Rewards + summary: Get validation round metadata + description: | + Returns past and current validation rounds with boundaries, stakes, and bonuses. Always uses the latest masterchain block. + parameters: + - name: election_id + in: query + description: | + Return the single round matching this election ID. Mutually exclusive with `block` and `unixtime`. + required: false + schema: + type: integer + format: int64 + - name: block + in: query + description: | + Find the round containing this masterchain block seqno and return it plus up to `limit-1` older rounds. Mutually exclusive with `election_id` and `unixtime`. + required: false + schema: + type: integer + format: uint32 + - name: unixtime + in: query + description: | + Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `election_id` and `block`. + required: false + schema: + type: integer + format: uint32 + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ValidationRoundsResponse' + default: + $ref: '#/components/responses/Error' + /v2/rewards/round-rewards: + get: + operationId: getRoundRewards + tags: + - Rewards + summary: Get per-validator reward distribution for a finished round + description: | + Computes per-validator and per-nominator reward distribution for a finished validation round using the elector's bonuses value. + parameters: + - name: election_id + in: query + description: | + Election ID of the finished round. Mutually exclusive with `block` and `unixtime`. + required: false + schema: + type: integer + format: int64 + - name: block + in: query + description: | + Masterchain block seqno within the finished round. Mutually exclusive with `election_id` and `unixtime`. + required: false + schema: + type: integer + format: uint32 + - name: unixtime + in: query + description: | + Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `election_id` and `block`. + required: false + schema: + type: integer + format: uint32 + - name: shallow + in: query + description: | + Set to `1` to return only basic validator info (rank, pubkey, effective_stake, weight, reward, pool). Skips pool type detection, owner/validator addresses, nominator data, and returned-stake lookup — significantly faster. + required: false + schema: + type: boolean + default: false + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/RoundRewardsResponse' + default: + $ref: '#/components/responses/Error' + /v2/rewards/stats: + get: + operationId: getRewardsStats + tags: + - Rewards + summary: Get historical APY and stake statistics + description: Returns time series of APY and total stake from past validation rounds. + responses: + '200': + description: APY and stake statistics + content: + application/json: + schema: + $ref: '#/components/schemas/RewardsStats' + default: + $ref: '#/components/responses/Error' + /v2/rewards/apy: + get: + operationId: getRewardsApy + tags: + - Rewards + summary: Get current TON blockchain APY + description: Returns the current TON blockchain APY as a percent based on the latest completed validation round. + responses: + '200': + description: current TON blockchain APY as a percent + content: + application/json: + schema: + type: number + format: double + example: 3.3 + default: + $ref: '#/components/responses/Error' components: parameters: masterchainSeqno: @@ -3198,7 +3465,7 @@ components: currenciesQuery: in: query name: currencies - description: accept ton and all possible fiat currencies, separated by commas + description: accept gram and all possible fiat currencies, separated by commas required: false explode: false schema: @@ -3206,7 +3473,7 @@ components: items: type: string example: - - ton + - gram - usd - rub supportedExtensions: @@ -3221,6 +3488,7 @@ components: type: string example: - custom_payload + - defi currencyQuery: in: query name: currency @@ -3343,7 +3611,6 @@ components: type: object required: - boc - - wallet_public_key properties: wallet_public_key: type: string @@ -3379,6 +3646,20 @@ components: type: string format: address example: 0:97264395BD65A255A429B11326C84128B7D70FFED7949ABAE3036D506BA38621 + PublicKeys: + description: a list of hex-encoded ed25519 public keys + content: + application/json: + schema: + type: object + required: + - public_keys + properties: + public_keys: + type: array + items: + type: string + example: d8519b83d5b04b17a706ef6d04f3566422be47c2b676b0823235d67b1ef4b1b2 TonConnectProof: description: Data that is expected from TON Connect required: true @@ -4447,6 +4728,47 @@ components: type: integer format: int64 example: 1000000 + NewConsensusConfig: + type: object + required: + - flags + - use_quic + - slots_per_leader_window + properties: + flags: + type: integer + format: int + example: 0 + x-js-format: bigint + use_quic: + type: boolean + example: false + target_rate_ms: + type: integer + format: int64 + example: 1000 + x-js-format: bigint + slots_per_leader_window: + type: integer + format: int64 + example: 1 + x-js-format: bigint + first_block_timeout_ms: + type: integer + format: int64 + example: 1000 + x-js-format: bigint + max_leader_window_desync: + type: integer + format: int64 + example: 4 + x-js-format: bigint + noncritical_params: + type: object + additionalProperties: + type: integer + format: int64 + x-js-format: bigint ValidatorsSet: type: object required: @@ -4523,9 +4845,9 @@ components: required: - bridge_burn_fee - bridge_mint_fee - - wallet_min_tons_for_storage + - wallet_min_gram_for_storage - wallet_gas_consumption - - minter_min_tons_for_storage + - minter_min_gram_for_storage - discover_gas_consumption properties: bridge_burn_fee: @@ -4537,12 +4859,22 @@ components: wallet_min_tons_for_storage: type: integer format: int64 + deprecated: true + description: this field will gone after Sept. 2026, use wallet_min_gram_for_storage instead + wallet_min_gram_for_storage: + type: integer + format: int64 wallet_gas_consumption: type: integer format: int64 minter_min_tons_for_storage: type: integer format: int64 + deprecated: true + description: this field will gone after Sept. 2026, use wallet_min_gram_for_storage instead + minter_min_gram_for_storage: + type: integer + format: int64 discover_gas_consumption: type: integer format: int64 @@ -4718,6 +5050,15 @@ components: root: type: string format: cell + BlockchainRawAccounts: + type: object + required: + - accounts + properties: + accounts: + type: array + items: + $ref: '#/components/schemas/BlockchainRawAccount' BlockchainLibrary: type: object required: @@ -4776,23 +5117,47 @@ components: type: array items: $ref: '#/components/schemas/Wallet' - Wallet: + WalletsByPublicKeys: type: object required: - - address - - balance - - stats - - plugins - - status - - last_activity - - get_methods - - is_wallet - - last_lt + - items properties: - address: - type: string - format: address - example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + items: + type: array + description: Wallets grouped by the originating public key + items: + $ref: '#/components/schemas/WalletsByPublicKey' + WalletsByPublicKey: + type: object + required: + - public_key + - wallets + properties: + public_key: + type: string + description: hex-encoded ed25519 public key + example: d8519b83d5b04b17a706ef6d04f3566422be47c2b676b0823235d67b1ef4b1b2 + wallets: + type: array + items: + $ref: '#/components/schemas/Wallet' + Wallet: + type: object + required: + - address + - balance + - stats + - plugins + - status + - last_activity + - get_methods + - is_wallet + - last_lt + properties: + address: + type: string + format: address + example: 0:da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf is_wallet: type: boolean balance: @@ -4960,6 +5325,9 @@ components: properties: protocol_name: type: string + external: + type: string + description: Normalized hash of the external message. SignRawParams: type: object required: @@ -5204,7 +5572,7 @@ components: format: int64 '14': type: object - description: The reward in nanoTons for block creation in the TON blockchain. + description: The reward in nanoGram for block creation in the TON blockchain. required: - masterchain_block_fee - basechain_block_fee @@ -5217,7 +5585,7 @@ components: format: int64 '15': type: object - description: The reward in nanoTons for block creation in the TON blockchain. + description: The reward in nanograms for block creation in the TON blockchain. required: - validators_elected_for - elections_start_before @@ -5451,6 +5819,14 @@ components: type: integer format: int64 example: 10000 + '30': + type: object + description: The configuration for the new consensus protocol. Each chain can have its own optional configuration. + properties: + mc: + $ref: '#/components/schemas/NewConsensusConfig' + shard: + $ref: '#/components/schemas/NewConsensusConfig' '31': type: object description: The configuration for the consensus protocol above catchain. @@ -5477,7 +5853,7 @@ components: $ref: '#/components/schemas/ValidatorsSet' '40': type: object - description: The configuration for punishment for improper behavior (non-validation). In the absence of the parameter, the default fine size is 101 TON + description: The configuration for punishment for improper behavior (non-validation). In the absence of the parameter, the default fine size is 101 Gram required: - misbehaviour_punishment_config properties: @@ -5665,6 +6041,20 @@ components: format: int32 scaled_ui: $ref: '#/components/schemas/ScaledUI' + description: + type: string + asset_info: + $ref: '#/components/schemas/JettonAssetInfo' + JettonAssetInfo: + type: object + required: + - token_type + - defi_provider + properties: + token_type: + $ref: '#/components/schemas/DefiAssetAssetType' + defi_provider: + $ref: '#/components/schemas/DefiProvider' ScaledUI: type: object required: @@ -5767,7 +6157,7 @@ components: example: 9 token_name: type: string - example: TON + example: Gram verification: $ref: '#/components/schemas/TrustType' image: @@ -5886,6 +6276,12 @@ components: example: false trust: $ref: '#/components/schemas/TrustType' + code_hash: + type: string + description: Hash of the NFT item account code cell (hex) + data_hash: + type: string + description: Hash of the NFT item account data cell (hex) NftItems: type: object required: @@ -6034,7 +6430,7 @@ components: type: object required: - account - - ton + - gram - fees properties: account: @@ -6044,6 +6440,13 @@ components: format: int64 x-js-format: bigint example: 80 + deprecated: true + description: this field will gone after Sept. 2026, use gram instead + gram: + type: integer + format: int64 + x-js-format: bigint + example: 80 fees: type: integer format: int64 @@ -6089,6 +6492,7 @@ components: - ExtraCurrencyTransfer - ContractDeploy - JettonTransfer + - FlawedJettonTransfer - JettonBurn - JettonMint - NftItemTransfer @@ -6112,6 +6516,9 @@ components: - DepositTokenStake - WithdrawTokenStakeRequest - LiquidityDeposit + - OracleRequest + - DepositXTR + - WithdrawXTR - Unknown status: type: string @@ -6127,6 +6534,8 @@ components: $ref: '#/components/schemas/ContractDeployAction' JettonTransfer: $ref: '#/components/schemas/JettonTransferAction' + FlawedJettonTransfer: + $ref: '#/components/schemas/FlawedJettonTransferAction' JettonBurn: $ref: '#/components/schemas/JettonBurnAction' JettonMint: @@ -6173,6 +6582,12 @@ components: $ref: '#/components/schemas/WithdrawTokenStakeRequestAction' LiquidityDeposit: $ref: '#/components/schemas/LiquidityDepositAction' + OracleRequest: + $ref: '#/components/schemas/OracleRequestAction' + WithdrawXTR: + $ref: '#/components/schemas/WithdrawXTRAction' + DepositXTR: + $ref: '#/components/schemas/DepositXTRAction' simple_preview: $ref: '#/components/schemas/ActionSimplePreview' base_transactions: @@ -6194,7 +6609,7 @@ components: $ref: '#/components/schemas/AccountAddress' amount: type: integer - description: amount in nanotons + description: amount in nanograms format: int64 example: 123456789 x-js-format: bigint @@ -6207,6 +6622,61 @@ components: $ref: '#/components/schemas/EncryptedComment' refund: $ref: '#/components/schemas/Refund' + OracleRequestAction: + type: object + required: + - requester + - response_to + - price_feeds + properties: + requester: + $ref: '#/components/schemas/AccountAddress' + response_to: + $ref: '#/components/schemas/AccountAddress' + price_feeds: + type: array + items: + $ref: '#/components/schemas/OraclePriceFeed' + OraclePriceFeed: + type: object + required: + - id + - display_symbol + properties: + id: + type: string + example: e62df6c8b4a85fe1a67f1c4d1f1e1d4335c04d1d7e2c50e0d7da7ad911f2d4 + display_symbol: + type: string + example: GRAM/USD + rate: + type: number + format: double + example: 5.24 + DepositXTRAction: + type: object + required: + - recipient + - amount + properties: + recipient: + $ref: '#/components/schemas/AccountAddress' + amount: + type: string + x-js-format: bigint + example: '123000000000' + WithdrawXTRAction: + type: object + required: + - user + - amount + properties: + user: + $ref: '#/components/schemas/AccountAddress' + amount: + type: string + x-js-format: bigint + example: '123000000000' ExtraCurrencies: type: object required: @@ -6268,7 +6738,7 @@ components: required: - executor - contract - - ton_attached + - gram_attached - operation properties: executor: @@ -6277,7 +6747,14 @@ components: $ref: '#/components/schemas/AccountAddress' ton_attached: type: integer - description: amount in nanotons + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + deprecated: true + gram_attached: + type: integer + description: amount in nanograms format: int64 example: 123456789 x-js-format: bigint @@ -6436,6 +6913,48 @@ components: $ref: '#/components/schemas/Refund' jetton: $ref: '#/components/schemas/JettonPreview' + FlawedJettonTransferAction: + type: object + required: + - sent_amount + - received_amount + - jetton + - senders_wallet + - recipients_wallet + properties: + sender: + $ref: '#/components/schemas/AccountAddress' + recipient: + $ref: '#/components/schemas/AccountAddress' + senders_wallet: + type: string + format: address + example: 0:E93E7D444180608B8520C00DC664383A387356FB6E16FDDF99DBE5E1415A574B + recipients_wallet: + type: string + format: address + example: 0:E93E7D444180608B8520C00DC664383A387356FB6E16FDDF99DBE5E1415A574B + sent_amount: + type: string + x-js-format: bigint + example: '1000000000' + description: sent amount in quanta of tokens + received_amount: + type: string + x-js-format: bigint + example: '1000000000' + description: actually received amount in quanta of tokens + comment: + type: string + example: |- + Hi! This is your salary. + From accounting with love. + encrypted_comment: + $ref: '#/components/schemas/EncryptedComment' + refund: + $ref: '#/components/schemas/Refund' + jetton: + $ref: '#/components/schemas/JettonPreview' JettonBurnAction: type: object required: @@ -6587,6 +7106,9 @@ components: $ref: '#/components/schemas/AccountAddress' implementation: $ref: '#/components/schemas/PoolImplementationType' + stake_meta: + description: If present, should be used instead of amount + $ref: '#/components/schemas/Price' WithdrawStakeAction: description: validator's participation in elections type: object @@ -6626,6 +7148,9 @@ components: $ref: '#/components/schemas/AccountAddress' implementation: $ref: '#/components/schemas/PoolImplementationType' + stake_meta: + description: If present, should be used instead of amount + $ref: '#/components/schemas/Price' ElectionsRecoverStakeAction: type: object required: @@ -6677,11 +7202,25 @@ components: example: 1000000000 format: int64 x-js-format: bigint + deprecated: true + description: this field will gone after Sept. 2026, use gram_in instead ton_out: type: integer example: 2000000000 format: int64 x-js-format: bigint + deprecated: true + description: this field will gone after Sept. 2026, use gram_out instead + gram_in: + type: integer + example: 1000000000 + format: int64 + x-js-format: bigint + gram_out: + type: integer + example: 2000000000 + format: int64 + x-js-format: bigint user_wallet: $ref: '#/components/schemas/AccountAddress' router: @@ -6763,16 +7302,16 @@ components: properties: name: type: string - example: Ton Transfer + example: Gram Transfer description: type: string - example: Transferring 5 Ton + example: Transferring 5 Gram action_image: type: string description: a link to an image for this particular action. value: type: string - example: 5 Ton + example: 5 Gram value_image: type: string description: a link to an image that depicts this action's asset. @@ -6827,7 +7366,7 @@ components: x-js-format: bigint example: 3 description: | - Net TON change for this account not explained by actions, in nanotons: extra = final_balance - initial_balance - sum(explicit TON changes from actions). extra < 0 - implicit fee, extra > 0 - refund. For UI display only + Net Gram change for this account not explained by actions, in nanograms: extra = final_balance - initial_balance - sum(explicit Gram changes from actions). extra < 0 - implicit fee, extra > 0 - refund. For UI display only progress: type: number format: float @@ -6835,6 +7374,10 @@ components: maximum: 1 example: 0.5 description: Event completion ratio in [0,1] + ext_msg_hash: + type: string + description: Normalized hash of the root external inbound message (hex). + example: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 AccountEvents: type: object description: Paginated list of events for a single account. @@ -7108,6 +7651,25 @@ components: type: string description: tonstorage bag id example: da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf + picture: + $ref: '#/components/schemas/PictureDNS' + PictureDNS: + type: object + required: + - type + properties: + type: + type: string + enum: + - url + - bag_id + url: + type: string + description: | + WARNING! This is arbitrary url supplied by domain owner, use it very carefully. + There is no guarantee that URL resolves to an image file and is not a phishing site. + bag_id: + type: string NftCollection: type: object required: @@ -7115,6 +7677,7 @@ components: - next_item_index - raw_collection_content - approved_by + - trust properties: address: type: string @@ -7139,6 +7702,8 @@ components: $ref: '#/components/schemas/ImagePreview' approved_by: $ref: '#/components/schemas/NftApprovedBy' + trust: + $ref: '#/components/schemas/TrustType' NftCollections: type: object required: @@ -7191,21 +7756,28 @@ components: Conservative upper bound on assets this wallet may lose if the emulated message is sent and the counterparty behaves maliciously. Values may exceed current balances (e.g. already-authorized future receipts). For UI display only. required: - transfer_all_remaining_balance - - ton + - gram - jettons - nfts properties: transfer_all_remaining_balance: type: boolean description: | - True if the message semantics allow sweeping all current and future remaining TON balance of the wallet (e.g. “send all” / drain patterns). + True if the message semantics allow sweeping all current and future remaining Gram balance of the wallet (e.g. “send all” / drain patterns). example: true ton: type: integer format: int64 x-js-format: bigint example: 500 - description: Maximum TON amount that may leave the wallet in the worst case, in nanotons. + deprecated: true + description: this field will gone after Sept. 2026, use gram instead + gram: + type: integer + format: int64 + x-js-format: bigint + example: 500 + description: Maximum Gram amount that may leave the wallet in the worst case, in nanogram. jettons: type: array description: Jetton positions that may be debited from the wallet in the worst case. @@ -7220,7 +7792,7 @@ components: type: number format: float description: | - Estimated equivalent of all assets at risk (TON, jettons, NFTs) in the selected currency from currencyQuery (e.g. USD). Approximate, best-effort UI value. + Estimated equivalent of all assets at risk (Gram, jettons, NFTs) in the selected currency from currencyQuery (e.g. USD). Approximate, best-effort UI value. JettonQuantity: type: object required: @@ -7407,6 +7979,15 @@ components: minimum: 0 maximum: 1 example: 0.5 + last_slice_id: + type: integer + format: int64 + description: ID of the slice where this event was finalized. Null if not yet finalized. + example: 12345678 + ext_msg_hash: + type: string + description: Normalized hash of the root external inbound message (hex). + example: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456 JettonMetadata: type: object required: @@ -7434,7 +8015,7 @@ components: description: this field currently returns a cached image URL (e.g., "https://cache.tonapi.io/images/jetton.jpg"). In the future, this will be replaced with the original URL from the metadata. The cached image is already available in the `preview` field of `JettonInfo` and will remain there. description: type: string - example: Wrapped Toncoin + example: Wrapped Gram social: type: array items: @@ -7500,6 +8081,32 @@ components: example: 2000 scaled_ui: $ref: '#/components/schemas/ScaledUI' + code_hash: + type: string + description: base64-encoded hash of jetton master code cell + example: rOIINk/O5kGub/FI/RARmMN6SY7BLesBSOonmxrz5f4= + data_hash: + type: string + description: base64-encoded hash of jetton master data cell + example: xd7cWaRQdVSysuG+WVJv9KRuRUGxnehLoByEcK5ukOE= + last_transaction_lt: + type: string + x-js-format: bigint + description: last transaction lt of the jetton master account + example: '26640202000003' + name: + type: string + nullable: true + description: DNS name resolving to this address (e.g. admin.ton) + example: admin.ton + interfaces: + type: array + items: + type: string + description: Contract interfaces implemented by the account (e.g. multisig_v2, wallet_v3r2) + example: + - multisig_v2 + - wallet_v3r2 JettonHolders: type: object required: @@ -7544,6 +8151,94 @@ components: type: string format: cell description: hex-encoded BoC + DefiAssets: + type: object + required: + - assets + properties: + assets: + type: array + items: + $ref: '#/components/schemas/DefiAsset' + DefiAssetAssetType: + type: string + enum: + - staking + - lending_supply + - lending_borrow + - liquid_staking + - liquid_pool + - yield_token + DefiAsset: + type: object + required: + - asset_type + - amount + - defi_provider + - locked_asset + properties: + asset_type: + $ref: '#/components/schemas/DefiAssetAssetType' + amount: + type: string + x-js-format: bigint + description: amount in minimal units of the locked asset + example: '1000000000' + pool_address: + type: string + format: address + asset_address: + type: string + format: address + defi_provider: + $ref: '#/components/schemas/DefiProvider' + locked_asset: + $ref: '#/components/schemas/DefiLockedAsset' + DefiLockedAsset: + type: object + required: + - type + properties: + type: + type: string + description: native Gram or jetton asset + enum: + - native + - jetton + jetton: + $ref: '#/components/schemas/JettonPreview' + DefiProvider: + type: object + required: + - name + - description + - link + - icon + - card + - full + - tag + properties: + name: + type: string + example: Morpho + description: + type: string + example: Earn up to 15% yield on your crypto + link: + type: string + example: https://lite.morpho.org/tac/earn/ + miniapp_link: + type: string + example: https://t.me/MorphoOrgBot + icon: + type: string + card: + type: string + full: + type: string + tag: + type: string + example: morpho AccountStaking: type: object required: @@ -7679,7 +8374,7 @@ components: example: TON Whales description: type: string - example: Oldest pool with minimal staking amount 50 TON + example: Oldest pool with minimal staking amount 50 Gram url: type: string example: https://tonvalidators.org/ @@ -7896,6 +8591,7 @@ components: - whales - tf - liquidTF + - ffvault TokenRates: type: object properties: @@ -7904,25 +8600,25 @@ components: additionalProperties: type: number example: - TON: 1.3710752873163712 + GRAM: 1.3710752873163712 diff_24h: type: object additionalProperties: type: string example: - TON: '-1.28%' + GRAM: '-1.28%' diff_7d: type: object additionalProperties: type: string example: - TON: '-2.74%' + GRAM: '-2.74%' diff_30d: type: object additionalProperties: type: string example: - TON: '-0.56%' + GRAM: '-0.56%' MarketTonRates: type: object required: @@ -8145,6 +8841,386 @@ components: image: type: string example: https://cache.tonapi.io/images/jetton.jpg + BlockInfo: + type: object + required: + - seqno + - time + properties: + seqno: + type: integer + format: uint32 + description: Masterchain block sequence number. + example: 57486221 + utime: + type: integer + format: int64 + example: 23814011000000 + RoundInfo: + type: object + required: + - start + - end + - start_block + - end_block + properties: + start_utime: + type: integer + format: int64 + example: 23814011000000 + end_utime: + type: integer + format: int64 + example: 23814011000000 + start_block: + type: integer + format: uint32 + description: Masterchain block seqno at (or nearest to) validation round start. + example: 57480000 + end_block: + type: integer + format: uint32 + description: Masterchain block seqno at (or nearest to) validation round end. + example: 57546000 + ValidatorsResponse: + type: object + required: + - response_time_ms + - block + - validation_round + - election_id + - elector_balance + - total_stake + - reward_per_block + - validators + properties: + response_time_ms: + type: integer + format: int64 + description: Server-side response time in milliseconds. + example: 12345 + block: + $ref: '#/components/schemas/BlockInfo' + validation_round: + $ref: '#/components/schemas/RoundInfo' + election_id: + type: integer + format: int64 + description: Current election ID (electAt timestamp). + example: 1740053384 + prev_election_id: + type: integer + format: int64 + description: Election ID of the round immediately before this one. + example: 1772486024 + next_election_id: + type: integer + format: int64 + description: | + Election ID of the round immediately after this one. Omitted when the current round is not yet finished (next round not known). + example: 1772658824 + elector_balance: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + total_stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + reward_per_block: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + validators: + type: array + items: + $ref: '#/components/schemas/ValidatorRewardEntry' + ValidationRound: + type: object + required: + - election_id + - start + - end + - start_block + - finished + properties: + election_id: + type: integer + format: int64 + description: Election ID (electAt timestamp). + example: 1740053384 + start_utime: + type: integer + format: int64 + example: 23814011000000 + end_utime: + type: integer + format: int64 + example: 23814011000000 + start_block: + type: integer + format: uint32 + description: Masterchain block seqno at (or nearest to) round start. + example: 57480000 + end_block: + type: integer + format: uint32 + description: Masterchain block seqno at (or nearest to) round end. Omitted if round hasn't finished. + example: 57546000 + prev_election_id: + type: integer + format: int64 + description: Election ID of the round immediately before this one. + example: 1772486024 + next_election_id: + type: integer + format: int64 + description: | + Election ID of the round immediately after this one. Omitted when this round is not yet finished (next round not known). + example: 1772658824 + total_stake: + type: integer + description: Total stake locked in the round. + format: int64 + example: 123456789 + x-js-format: bigint + bonuses: + type: integer + description: Total rewards the elector pays for the round. Omitted if round hasn't finished. + format: int64 + example: 123456789 + x-js-format: bigint + finished: + type: boolean + description: Whether the validation round is complete. + example: true + ValidationRoundsResponse: + type: object + required: + - response_time_ms + - rounds + properties: + response_time_ms: + type: integer + format: int64 + description: Server-side response time in milliseconds. + example: 1234 + rounds: + type: array + items: + $ref: '#/components/schemas/ValidationRound' + NominatorRewardEntry: + type: object + required: + - address + - weight + - reward + - effective_stake + - stake + properties: + address: + type: string + description: Nominator's wallet address (bounceable, base64url). + example: EQAqR4RYauq7p3jqKGnD-eSYVDoOCak9g8ZsSNVHI9fevCzB + weight: + type: number + format: double + description: Nominator's share of total nominators' deposit (0–1). + example: 0.15 + reward: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + effective_stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + ValidatorRewardEntry: + type: object + required: + - rank + - public_key + - effective_stake + - weight + - reward + properties: + rank: + type: integer + description: Position sorted by effective stake (descending). + example: 1 + public_key: + type: string + description: Validator's public key (hex-encoded Ed25519). + example: e33f0e53552f951e0a27c8e5a461a1bd65975af369a2c85a06e51f7fbb8ae667 + effective_stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + weight: + type: number + format: double + description: Fraction of total effective stake (0–1). + example: 0.004648 + reward: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + pool: + type: string + description: Pool smart contract address (bounceable, base64url). + example: Ef_bmCmMPsrHKOC4hV8foWBs2TEUAggQ1Wfe6EAqjrI3sGNI + pool_type: + type: string + description: Contract type detected by code hash. + enum: + - nominator-pool-v1.0 + - single-nominator-pool-v1.0 + - single-nominator-pool-v1.1 + - other + owner_address: + type: string + validator_address: + type: string + validator_stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + nominators_stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + total_stake: + type: integer + description: | + Total funds deposited by the pool: effective_stake + credit (leftover balance kept in the elector contract after election). + format: int64 + example: 123456789 + x-js-format: bigint + validator_reward_share: + type: number + format: double + description: Fraction of staking rewards kept by the validator (0.3 = 30%). + example: 0.3 + nominators_count: + type: integer + format: uint32 + nominators: + type: array + items: + $ref: '#/components/schemas/NominatorRewardEntry' + RoundRewardsResponse: + type: object + required: + - response_time_ms + - election_id + - round_start + - round_end + - start_block + - end_block + - total_bonuses + - total_stake + - validators + properties: + response_time_ms: + type: integer + format: int64 + description: Server-side response time in milliseconds. + example: 5432 + election_id: + type: integer + format: int64 + description: Election ID (electAt timestamp). + example: 1740053384 + prev_election_id: + type: integer + format: int64 + description: Election ID of the round immediately before this one. + example: 1772486024 + next_election_id: + type: integer + format: int64 + description: Election ID of the round immediately after this one. + example: 1772658824 + round_start: + type: string + format: date-time + description: Validation round start time. + round_end: + type: string + format: date-time + description: Validation round end time. + start_block: + type: integer + format: uint32 + description: First masterchain block of the round. + end_block: + type: integer + format: uint32 + description: Last masterchain block of the round. + total_bonuses: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + total_stake: + type: integer + description: amount in nanograms + format: int64 + example: 123456789 + x-js-format: bigint + validators: + type: array + items: + $ref: '#/components/schemas/ValidatorRewardEntry' + error: + type: string + RewardsStats: + type: object + required: + - apy + - total_stake + properties: + apy: + type: array + description: Time series of APY values as [timestamp_ms, apy] pairs + items: + type: array + items: + type: number + format: double + total_stake: + type: array + description: Time series of total stake in Gram as [timestamp_ms, stake] pairs + items: + type: array + items: + type: number + format: double responses: Error: description: Some error during request processing diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index cf3fed4..864081a 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -741,6 +741,37 @@ export interface SizeLimitsConfig { maxAccStateBits?: number; } +export interface NewConsensusConfig { + /** + * @format bigint + * @example 0 + */ + flags: bigint; + /** @example false */ + useQuic: boolean; + /** + * @format bigint + * @example 1000 + */ + targetRateMs?: bigint; + /** + * @format bigint + * @example 1 + */ + slotsPerLeaderWindow: bigint; + /** + * @format bigint + * @example 1000 + */ + firstBlockTimeoutMs?: bigint; + /** + * @format bigint + * @example 4 + */ + maxLeaderWindowDesync?: bigint; + noncriticalParams?: Record; +} + export interface ValidatorsSet { utimeSince: number; utimeUntil: number; @@ -784,12 +815,24 @@ export interface JettonBridgePrices { bridgeBurnFee: number; /** @format int64 */ bridgeMintFee: number; + /** + * this field will gone after Sept. 2026, use wallet_min_gram_for_storage instead + * @deprecated + * @format int64 + */ + walletMinTonsForStorage?: number; /** @format int64 */ - walletMinTonsForStorage: number; + walletMinGramForStorage: number; /** @format int64 */ walletGasConsumption: number; + /** + * this field will gone after Sept. 2026, use wallet_min_gram_for_storage instead + * @deprecated + * @format int64 + */ + minterMinTonsForStorage?: number; /** @format int64 */ - minterMinTonsForStorage: number; + minterMinGramForStorage: number; /** @format int64 */ discoverGasConsumption: number; } @@ -921,6 +964,10 @@ export interface BlockchainRawAccount { }[]; } +export interface BlockchainRawAccounts { + accounts: BlockchainRawAccount[]; +} + export interface BlockchainLibrary { /** * @format cell @@ -967,6 +1014,20 @@ export interface Wallets { accounts: Wallet[]; } +export interface WalletsByPublicKeys { + /** Wallets grouped by the originating public key */ + items: WalletsByPublicKey[]; +} + +export interface WalletsByPublicKey { + /** + * hex-encoded ed25519 public key + * @example "d8519b83d5b04b17a706ef6d04f3566422be47c2b676b0823235d67b1ef4b1b2" + */ + publicKey: string; + wallets: Wallet[]; +} + export interface Wallet { /** * @format address @@ -1086,6 +1147,8 @@ export interface SignRawMessage { export interface GaslessTx { protocolName: string; + /** Normalized hash of the external message. */ + external?: string; } export interface SignRawParams { @@ -1215,14 +1278,14 @@ export interface BlockchainConfig { /** @format int64 */ cellPrice: number; }; - /** The reward in nanoTons for block creation in the TON blockchain. */ + /** The reward in nanoGram for block creation in the TON blockchain. */ '14'?: { /** @format int64 */ masterchainBlockFee: number; /** @format int64 */ basechainBlockFee: number; }; - /** The reward in nanoTons for block creation in the TON blockchain. */ + /** The reward in nanograms for block creation in the TON blockchain. */ '15'?: { /** * @format int64 @@ -1405,6 +1468,11 @@ export interface BlockchainConfig { */ catchainMaxBlocksCoeff?: number; }; + /** The configuration for the new consensus protocol. Each chain can have its own optional configuration. */ + '30'?: { + mc?: NewConsensusConfig; + shard?: NewConsensusConfig; + }; /** The configuration for the consensus protocol above catchain. */ '31'?: { fundamentalSmcAddr: Address[]; @@ -1415,7 +1483,7 @@ export interface BlockchainConfig { '35'?: ValidatorsSet; '36'?: ValidatorsSet; '37'?: ValidatorsSet; - /** The configuration for punishment for improper behavior (non-validation). In the absence of the parameter, the default fine size is 101 TON */ + /** The configuration for punishment for improper behavior (non-validation). In the absence of the parameter, the default fine size is 101 Gram */ '40'?: { misbehaviourPunishmentConfig: MisbehaviourPunishmentConfig; }; @@ -1522,6 +1590,13 @@ export interface JettonPreview { /** @format int32 */ score: number; scaledUi?: ScaledUI; + description?: string; + assetInfo?: JettonAssetInfo; +} + +export interface JettonAssetInfo { + tokenType: DefiAssetAssetType; + defiProvider: DefiProvider; } export interface ScaledUI { @@ -1592,7 +1667,7 @@ export interface Price { value: bigint; /** @example 9 */ decimals: number; - /** @example "TON" */ + /** @example "Gram" */ tokenName: string; verification: TrustType; /** @example "https://cache.tonapi.io/images/jetton.jpg" */ @@ -1674,6 +1749,10 @@ export interface NftItem { /** @example false */ includeCnft?: boolean; trust: TrustType; + /** Hash of the NFT item account code cell (hex) */ + codeHash?: string; + /** Hash of the NFT item account data cell (hex) */ + dataHash?: string; } export interface NftItems { @@ -1741,11 +1820,18 @@ export interface Refund { export interface ValueFlow { account: AccountAddress; + /** + * this field will gone after Sept. 2026, use gram instead + * @deprecated + * @format bigint + * @example 80 + */ + ton?: bigint; /** * @format bigint * @example 80 */ - ton: bigint; + gram: bigint; /** * @format bigint * @example 10 @@ -1775,6 +1861,7 @@ export interface Action { | 'ExtraCurrencyTransfer' | 'ContractDeploy' | 'JettonTransfer' + | 'FlawedJettonTransfer' | 'JettonBurn' | 'JettonMint' | 'NftItemTransfer' @@ -1798,6 +1885,9 @@ export interface Action { | 'DepositTokenStake' | 'WithdrawTokenStakeRequest' | 'LiquidityDeposit' + | 'OracleRequest' + | 'DepositXTR' + | 'WithdrawXTR' | 'Unknown'; /** @example "ok" */ status: 'ok' | 'failed'; @@ -1805,6 +1895,7 @@ export interface Action { ExtraCurrencyTransfer?: ExtraCurrencyTransferAction; ContractDeploy?: ContractDeployAction; JettonTransfer?: JettonTransferAction; + FlawedJettonTransfer?: FlawedJettonTransferAction; JettonBurn?: JettonBurnAction; JettonMint?: JettonMintAction; NftItemTransfer?: NftItemTransferAction; @@ -1831,6 +1922,9 @@ export interface Action { DepositTokenStake?: DepositTokenStakeAction; WithdrawTokenStakeRequest?: WithdrawTokenStakeRequestAction; LiquidityDeposit?: LiquidityDepositAction; + OracleRequest?: OracleRequestAction; + WithdrawXTR?: WithdrawXTRAction; + DepositXTR?: DepositXTRAction; /** shortly describes what this action is about. */ simplePreview: ActionSimplePreview; baseTransactions: string[]; @@ -1840,7 +1934,7 @@ export interface TonTransferAction { sender: AccountAddress; recipient: AccountAddress; /** - * amount in nanotons + * amount in nanograms * @format bigint * @example 123456789 */ @@ -1854,6 +1948,42 @@ export interface TonTransferAction { refund?: Refund; } +export interface OracleRequestAction { + requester: AccountAddress; + responseTo: AccountAddress; + priceFeeds: OraclePriceFeed[]; +} + +export interface OraclePriceFeed { + /** @example "e62df6c8b4a85fe1a67f1c4d1f1e1d4335c04d1d7e2c50e0d7da7ad911f2d4" */ + id: string; + /** @example "GRAM/USD" */ + displaySymbol: string; + /** + * @format double + * @example 5.24 + */ + rate?: number; +} + +export interface DepositXTRAction { + recipient: AccountAddress; + /** + * @format bigint + * @example "123000000000" + */ + amount: bigint; +} + +export interface WithdrawXTRAction { + user: AccountAddress; + /** + * @format bigint + * @example "123000000000" + */ + amount: bigint; +} + export interface ExtraCurrencies { extraCurrencies: EcPreview[]; } @@ -1894,11 +2024,18 @@ export interface SmartContractAction { executor: AccountAddress; contract: AccountAddress; /** - * amount in nanotons + * amount in nanograms + * @deprecated + * @format bigint + * @example 123456789 + */ + tonAttached?: bigint; + /** + * amount in nanograms * @format bigint * @example 123456789 */ - tonAttached: bigint; + gramAttached: bigint; /** @example "NftTransfer or 0x35d95a12" */ operation: string; payload?: string; @@ -2009,6 +2146,41 @@ export interface JettonTransferAction { jetton: JettonPreview; } +export interface FlawedJettonTransferAction { + sender?: AccountAddress; + recipient?: AccountAddress; + /** + * @format address + * @example "0:E93E7D444180608B8520C00DC664383A387356FB6E16FDDF99DBE5E1415A574B" + */ + sendersWallet: Address; + /** + * @format address + * @example "0:E93E7D444180608B8520C00DC664383A387356FB6E16FDDF99DBE5E1415A574B" + */ + recipientsWallet: Address; + /** + * sent amount in quanta of tokens + * @format bigint + * @example "1000000000" + */ + sentAmount: bigint; + /** + * actually received amount in quanta of tokens + * @format bigint + * @example "1000000000" + */ + receivedAmount: bigint; + /** + * @example "Hi! This is your salary. + * From accounting with love." + */ + comment?: string; + encryptedComment?: EncryptedComment; + refund?: Refund; + jetton: JettonPreview; +} + export interface JettonBurnAction { sender: AccountAddress; /** @@ -2100,6 +2272,8 @@ export interface DepositStakeAction { staker: AccountAddress; pool: AccountAddress; implementation: PoolImplementationType; + /** If present, should be used instead of amount */ + stakeMeta?: Price; } /** validator's participation in elections */ @@ -2124,6 +2298,8 @@ export interface WithdrawStakeRequestAction { staker: AccountAddress; pool: AccountAddress; implementation: PoolImplementationType; + /** If present, should be used instead of amount */ + stakeMeta?: Price; } export interface ElectionsRecoverStakeAction { @@ -2158,15 +2334,29 @@ export interface JettonSwapAction { */ amountOut: bigint; /** + * this field will gone after Sept. 2026, use gram_in instead + * @deprecated * @format bigint * @example 1000000000 */ tonIn?: bigint; /** + * this field will gone after Sept. 2026, use gram_out instead + * @deprecated * @format bigint * @example 2000000000 */ tonOut?: bigint; + /** + * @format bigint + * @example 1000000000 + */ + gramIn?: bigint; + /** + * @format bigint + * @example 2000000000 + */ + gramOut?: bigint; userWallet: AccountAddress; router: AccountAddress; jettonMasterIn?: JettonPreview; @@ -2201,13 +2391,13 @@ export interface LiquidityDepositAction { /** shortly describes what this action is about. */ export interface ActionSimplePreview { - /** @example "Ton Transfer" */ + /** @example "Gram Transfer" */ name: string; - /** @example "Transferring 5 Ton" */ + /** @example "Transferring 5 Gram" */ description: string; /** a link to an image for this particular action. */ actionImage?: string; - /** @example "5 Ton" */ + /** @example "5 Gram" */ value?: string; /** a link to an image that depicts this action's asset. */ valueImage?: string; @@ -2241,7 +2431,7 @@ export interface AccountEvent { */ inProgress: boolean; /** - * Net TON change for this account not explained by actions, in nanotons: extra = final_balance - initial_balance - sum(explicit TON changes from actions). extra < 0 - implicit fee, extra > 0 - refund. For UI display only + * Net Gram change for this account not explained by actions, in nanograms: extra = final_balance - initial_balance - sum(explicit Gram changes from actions). extra < 0 - implicit fee, extra > 0 - refund. For UI display only * @format bigint * @example 3 */ @@ -2254,6 +2444,11 @@ export interface AccountEvent { * @example 0.5 */ progress: number; + /** + * Normalized hash of the root external inbound message (hex). + * @example "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456" + */ + extMsgHash?: string; } /** Paginated list of events for a single account. */ @@ -2434,6 +2629,17 @@ export interface DnsRecord { * @example "da6b1b6663a0e4d18cc8574ccd9db5296e367dd9324706f3bbd9eb1cd2caf0bf" */ storage?: string; + picture?: PictureDNS; +} + +export interface PictureDNS { + type: 'url' | 'bag_id'; + /** + * WARNING! This is arbitrary url supplied by domain owner, use it very carefully. + * There is no guarantee that URL resolves to an image file and is not a phishing site. + */ + url?: string; + bagId?: string; } export interface NftCollection { @@ -2454,6 +2660,7 @@ export interface NftCollection { metadata?: Record; previews?: ImagePreview[]; approvedBy: NftApprovedBy; + trust: TrustType; } export interface NftCollections { @@ -2481,22 +2688,29 @@ export interface MessageConsequences { /** Conservative upper bound on assets this wallet may lose if the emulated message is sent and the counterparty behaves maliciously. Values may exceed current balances (e.g. already-authorized future receipts). For UI display only. */ export interface Risk { /** - * True if the message semantics allow sweeping all current and future remaining TON balance of the wallet (e.g. “send all” / drain patterns). + * True if the message semantics allow sweeping all current and future remaining Gram balance of the wallet (e.g. “send all” / drain patterns). * @example true */ transferAllRemainingBalance: boolean; /** - * Maximum TON amount that may leave the wallet in the worst case, in nanotons. + * this field will gone after Sept. 2026, use gram instead + * @deprecated + * @format bigint + * @example 500 + */ + ton?: bigint; + /** + * Maximum Gram amount that may leave the wallet in the worst case, in nanogram. * @format bigint * @example 500 */ - ton: bigint; + gram: bigint; /** Jetton positions that may be debited from the wallet in the worst case. */ jettons: JettonQuantity[]; /** NFT items that may be transferred out of the wallet in the worst case. */ nfts: NftItem[]; /** - * Estimated equivalent of all assets at risk (TON, jettons, NFTs) in the selected currency from currencyQuery (e.g. USD). Approximate, best-effort UI value. + * Estimated equivalent of all assets at risk (Gram, jettons, NFTs) in the selected currency from currencyQuery (e.g. USD). Approximate, best-effort UI value. * @format float */ totalEquivalent?: number; @@ -2628,6 +2842,17 @@ export interface Event { * @example 0.5 */ progress: number; + /** + * ID of the slice where this event was finalized. Null if not yet finalized. + * @format int64 + * @example 12345678 + */ + lastSliceId?: number; + /** + * Normalized hash of the root external inbound message (hex). + * @example "a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456" + */ + extMsgHash?: string; } export interface JettonMetadata { @@ -2647,7 +2872,7 @@ export interface JettonMetadata { * @example "https://bitcoincash-example.github.io/website/logo.png" */ image?: string; - /** @example "Wrapped Toncoin" */ + /** @example "Wrapped Gram" */ description?: string; social?: string[]; websites?: string[]; @@ -2679,6 +2904,32 @@ export interface JettonInfo { */ holdersCount: number; scaledUi?: ScaledUI; + /** + * base64-encoded hash of jetton master code cell + * @example "rOIINk/O5kGub/FI/RARmMN6SY7BLesBSOonmxrz5f4=" + */ + codeHash?: string; + /** + * base64-encoded hash of jetton master data cell + * @example "xd7cWaRQdVSysuG+WVJv9KRuRUGxnehLoByEcK5ukOE=" + */ + dataHash?: string; + /** + * last transaction lt of the jetton master account + * @format bigint + * @example "26640202000003" + */ + lastTransactionLt?: bigint; + /** + * DNS name resolving to this address (e.g. admin.ton) + * @example "admin.ton" + */ + name?: string | null; + /** + * Contract interfaces implemented by the account (e.g. multisig_v2, wallet_v3r2) + * @example ["multisig_v2","wallet_v3r2"] + */ + interfaces?: string[]; } export interface JettonHolders { @@ -2717,6 +2968,57 @@ export interface JettonTransferPayload { stateInit?: Cell; } +export interface DefiAssets { + assets: DefiAsset[]; +} + +export enum DefiAssetAssetType { + Staking = 'staking', + LendingSupply = 'lending_supply', + LendingBorrow = 'lending_borrow', + LiquidStaking = 'liquid_staking', + LiquidPool = 'liquid_pool', + YieldToken = 'yield_token' +} + +export interface DefiAsset { + assetType: DefiAssetAssetType; + /** + * amount in minimal units of the locked asset + * @format bigint + * @example "1000000000" + */ + amount: bigint; + /** @format address */ + poolAddress?: Address; + /** @format address */ + assetAddress?: Address; + defiProvider: DefiProvider; + lockedAsset: DefiLockedAsset; +} + +export interface DefiLockedAsset { + /** native Gram or jetton asset */ + type: 'native' | 'jetton'; + jetton?: JettonPreview; +} + +export interface DefiProvider { + /** @example "Morpho" */ + name: string; + /** @example "Earn up to 15% yield on your crypto" */ + description: string; + /** @example "https://lite.morpho.org/tac/earn/" */ + link: string; + /** @example "https://t.me/MorphoOrgBot" */ + miniappLink?: string; + icon: string; + card: string; + full: string; + /** @example "morpho" */ + tag: string; +} + export interface AccountStaking { pools: AccountStakingInfo[]; } @@ -2819,7 +3121,7 @@ export interface PoolInfo { export interface PoolImplementation { /** @example "TON Whales" */ name: string; - /** @example "Oldest pool with minimal staking amount 50 TON" */ + /** @example "Oldest pool with minimal staking amount 50 Gram" */ description: string; /** @example "https://tonvalidators.org/" */ url: string; @@ -2955,17 +3257,18 @@ export interface BlockchainAccountInspect { export enum PoolImplementationType { Whales = 'whales', Tf = 'tf', - LiquidTF = 'liquidTF' + LiquidTF = 'liquidTF', + Ffvault = 'ffvault' } export interface TokenRates { - /** @example {"TON":1.3710752873163712} */ + /** @example {"GRAM":1.3710752873163712} */ prices?: Record; - /** @example {"TON":"-1.28%"} */ + /** @example {"GRAM":"-1.28%"} */ diff24h?: Record; - /** @example {"TON":"-2.74%"} */ + /** @example {"GRAM":"-2.74%"} */ diff7d?: Record; - /** @example {"TON":"-0.56%"} */ + /** @example {"GRAM":"-0.56%"} */ diff30d?: Record; } @@ -3106,28 +3409,356 @@ export enum ExecGetMethodArgType { export interface ExecGetMethodArg { /** - * Data type of the argument value: - * - `nan`: Not-a-Number value - * - `null`: Null value - * - `tinyint`: Decimal integer (e.g., `100500`) - * - `int257`: 257-bit integer in hex format with 0x prefix (e.g., `0xfa01d78381ae32`) - * - `slice`: TON blockchain address (e.g., `0:6e731f2e...`) - * - `cell_boc_base64`: Base64-encoded cell BOC (Binary Object Code) (e.g., `te6ccgEBAQEAAgAAAA==`) - * - `slice_boc_hex`: Hex-encoded slice BOC (e.g., `b5ee9c72...`) + * Data type of the argument value: + * - `nan`: Not-a-Number value + * - `null`: Null value + * - `tinyint`: Decimal integer (e.g., `100500`) + * - `int257`: 257-bit integer in hex format with 0x prefix (e.g., `0xfa01d78381ae32`) + * - `slice`: TON blockchain address (e.g., `0:6e731f2e...`) + * - `cell_boc_base64`: Base64-encoded cell BOC (Binary Object Code) (e.g., `te6ccgEBAQEAAgAAAA==`) + * - `slice_boc_hex`: Hex-encoded slice BOC (e.g., `b5ee9c72...`) + */ + type: ExecGetMethodArgType; + /** + * String representation of the value according to the specified type + * @example "0xfa01d78381ae32" + */ + value: string; +} + +export interface Protocol { + /** @example "Ethena" */ + name: string; + /** @example "https://cache.tonapi.io/images/jetton.jpg" */ + image?: string; +} + +export interface BlockInfo { + /** + * Masterchain block sequence number. + * @format uint32 + * @example 57486221 + */ + seqno: number; + /** + * @format int64 + * @example 23814011000000 + */ + utime?: number; +} + +export interface RoundInfo { + /** + * @format int64 + * @example 23814011000000 + */ + startUtime?: number; + /** + * @format int64 + * @example 23814011000000 + */ + endUtime?: number; + /** + * Masterchain block seqno at (or nearest to) validation round start. + * @format uint32 + * @example 57480000 + */ + startBlock: number; + /** + * Masterchain block seqno at (or nearest to) validation round end. + * @format uint32 + * @example 57546000 + */ + endBlock: number; +} + +export interface ValidatorsResponse { + /** + * Server-side response time in milliseconds. + * @format int64 + * @example 12345 + */ + responseTimeMs: number; + block: BlockInfo; + validationRound: RoundInfo; + /** + * Current election ID (electAt timestamp). + * @format int64 + * @example 1740053384 + */ + electionId: number; + /** + * Election ID of the round immediately before this one. + * @format int64 + * @example 1772486024 + */ + prevElectionId?: number; + /** + * Election ID of the round immediately after this one. Omitted when the current round is not yet finished (next round not known). + * @format int64 + * @example 1772658824 + */ + nextElectionId?: number; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + electorBalance: bigint; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + totalStake: bigint; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + rewardPerBlock: bigint; + validators: ValidatorRewardEntry[]; +} + +export interface ValidationRound { + /** + * Election ID (electAt timestamp). + * @format int64 + * @example 1740053384 + */ + electionId: number; + /** + * @format int64 + * @example 23814011000000 + */ + startUtime?: number; + /** + * @format int64 + * @example 23814011000000 + */ + endUtime?: number; + /** + * Masterchain block seqno at (or nearest to) round start. + * @format uint32 + * @example 57480000 + */ + startBlock: number; + /** + * Masterchain block seqno at (or nearest to) round end. Omitted if round hasn't finished. + * @format uint32 + * @example 57546000 + */ + endBlock?: number; + /** + * Election ID of the round immediately before this one. + * @format int64 + * @example 1772486024 + */ + prevElectionId?: number; + /** + * Election ID of the round immediately after this one. Omitted when this round is not yet finished (next round not known). + * @format int64 + * @example 1772658824 + */ + nextElectionId?: number; + /** + * Total stake locked in the round. + * @format bigint + * @example 123456789 + */ + totalStake?: bigint; + /** + * Total rewards the elector pays for the round. Omitted if round hasn't finished. + * @format bigint + * @example 123456789 + */ + bonuses?: bigint; + /** + * Whether the validation round is complete. + * @example true + */ + finished: boolean; +} + +export interface ValidationRoundsResponse { + /** + * Server-side response time in milliseconds. + * @format int64 + * @example 1234 + */ + responseTimeMs: number; + rounds: ValidationRound[]; +} + +export interface NominatorRewardEntry { + /** + * Nominator's wallet address (bounceable, base64url). + * @example "EQAqR4RYauq7p3jqKGnD-eSYVDoOCak9g8ZsSNVHI9fevCzB" + */ + address: string; + /** + * Nominator's share of total nominators' deposit (0–1). + * @format double + * @example 0.15 + */ + weight: number; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + reward: bigint; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + effectiveStake: bigint; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + stake: bigint; +} + +export interface ValidatorRewardEntry { + /** + * Position sorted by effective stake (descending). + * @example 1 + */ + rank: number; + /** + * Validator's public key (hex-encoded Ed25519). + * @example "e33f0e53552f951e0a27c8e5a461a1bd65975af369a2c85a06e51f7fbb8ae667" + */ + publicKey: string; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + effectiveStake: bigint; + /** + * Fraction of total effective stake (0–1). + * @format double + * @example 0.004648 + */ + weight: number; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + reward: bigint; + /** + * Pool smart contract address (bounceable, base64url). + * @example "Ef_bmCmMPsrHKOC4hV8foWBs2TEUAggQ1Wfe6EAqjrI3sGNI" + */ + pool?: string; + /** Contract type detected by code hash. */ + poolType?: + | 'nominator-pool-v1.0' + | 'single-nominator-pool-v1.0' + | 'single-nominator-pool-v1.1' + | 'other'; + ownerAddress?: string; + validatorAddress?: string; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + validatorStake?: bigint; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + nominatorsStake?: bigint; + /** + * Total funds deposited by the pool: effective_stake + credit (leftover balance kept in the elector contract after election). + * @format bigint + * @example 123456789 + */ + totalStake?: bigint; + /** + * Fraction of staking rewards kept by the validator (0.3 = 30%). + * @format double + * @example 0.3 + */ + validatorRewardShare?: number; + /** @format uint32 */ + nominatorsCount?: number; + nominators?: NominatorRewardEntry[]; +} + +export interface RoundRewardsResponse { + /** + * Server-side response time in milliseconds. + * @format int64 + * @example 5432 + */ + responseTimeMs: number; + /** + * Election ID (electAt timestamp). + * @format int64 + * @example 1740053384 + */ + electionId: number; + /** + * Election ID of the round immediately before this one. + * @format int64 + * @example 1772486024 */ - type: ExecGetMethodArgType; + prevElectionId?: number; /** - * String representation of the value according to the specified type - * @example "0xfa01d78381ae32" + * Election ID of the round immediately after this one. + * @format int64 + * @example 1772658824 */ - value: string; + nextElectionId?: number; + /** + * Validation round start time. + * @format date-time + */ + roundStart: string; + /** + * Validation round end time. + * @format date-time + */ + roundEnd: string; + /** + * First masterchain block of the round. + * @format uint32 + */ + startBlock: number; + /** + * Last masterchain block of the round. + * @format uint32 + */ + endBlock: number; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + totalBonuses: bigint; + /** + * amount in nanograms + * @format bigint + * @example 123456789 + */ + totalStake: bigint; + validators: ValidatorRewardEntry[]; + error?: string; } -export interface Protocol { - /** @example "Ethena" */ - name: string; - /** @example "https://cache.tonapi.io/images/jetton.jpg" */ - image?: string; +export interface RewardsStats { + /** Time series of APY values as [timestamp_ms, apy] pairs */ + apy: number[][]; + /** Time series of total stake in Gram as [timestamp_ms, stake] pairs */ + totalStake: number[][]; } export type GetOpenapiJsonData = any; @@ -3166,6 +3797,8 @@ export type GetBlockchainMasterchainHeadData = BlockchainBlock; export type GetBlockchainRawAccountData = BlockchainRawAccount; +export type GetBlockchainRawAccountsData = BlockchainRawAccounts; + export type GetBlockchainAccountTransactionsData = Transactions; export type ExecGetMethodForBlockchainAccountData = MethodExecutionResult; @@ -3247,6 +3880,8 @@ export interface GetAccountDiffData { balanceChange: number; } +export type GetAccountDefiAssetsData = DefiAssets; + export type GetAccountExtraCurrencyHistoryByIdData = AccountEvents; export type GetDnsInfoData = DomainInfo; @@ -3347,6 +3982,8 @@ export type GaslessSendData = GaslessTx; export type GetWalletsByPublicKeyData = Wallets; +export type GetWalletsByPublicKeyBulkData = WalletsByPublicKeys; + export interface GetRawMasterchainInfoData { last: BlockRaw; /** @example "131D0C65055F04E9C19D687B51BC70F952FD9CA6F02C2801D3B89964A779DF85" */ @@ -3580,6 +4217,20 @@ export type EmulateMessageToAccountEventData = AccountEvent; export type GetPurchaseHistoryData = AccountPurchases; +export type GetValidatorsData = ValidatorsResponse; + +export type GetValidationRoundsData = ValidationRoundsResponse; + +export type GetRoundRewardsData = RoundRewardsResponse; + +export type GetRewardsStatsData = RewardsStats; + +/** + * @format double + * @example 3.3 + */ +export type GetRewardsApyData = number; + export type QueryParamsType = Record; export type ResponseFormat = keyof Omit; @@ -4407,6 +5058,22 @@ const components = { max_acc_state_bits: { type: 'integer', format: 'int64' } } }, + '#/components/schemas/NewConsensusConfig': { + type: 'object', + required: ['flags', 'use_quic', 'slots_per_leader_window'], + properties: { + flags: { type: 'integer', format: 'int', 'x-js-format': 'bigint' }, + use_quic: { type: 'boolean' }, + target_rate_ms: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + slots_per_leader_window: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + first_block_timeout_ms: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + max_leader_window_desync: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + noncritical_params: { + type: 'object', + additionalProperties: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' } + } + } + }, '#/components/schemas/ValidatorsSet': { type: 'object', required: ['utime_since', 'utime_until', 'total', 'main', 'list'], @@ -4453,17 +5120,19 @@ const components = { required: [ 'bridge_burn_fee', 'bridge_mint_fee', - 'wallet_min_tons_for_storage', + 'wallet_min_gram_for_storage', 'wallet_gas_consumption', - 'minter_min_tons_for_storage', + 'minter_min_gram_for_storage', 'discover_gas_consumption' ], properties: { bridge_burn_fee: { type: 'integer', format: 'int64' }, bridge_mint_fee: { type: 'integer', format: 'int64' }, - wallet_min_tons_for_storage: { type: 'integer', format: 'int64' }, + wallet_min_tons_for_storage: { type: 'integer', format: 'int64', deprecated: true }, + wallet_min_gram_for_storage: { type: 'integer', format: 'int64' }, wallet_gas_consumption: { type: 'integer', format: 'int64' }, - minter_min_tons_for_storage: { type: 'integer', format: 'int64' }, + minter_min_tons_for_storage: { type: 'integer', format: 'int64', deprecated: true }, + minter_min_gram_for_storage: { type: 'integer', format: 'int64' }, discover_gas_consumption: { type: 'integer', format: 'int64' } } }, @@ -4539,6 +5208,16 @@ const components = { } } }, + '#/components/schemas/BlockchainRawAccounts': { + type: 'object', + required: ['accounts'], + properties: { + accounts: { + type: 'array', + items: { $ref: '#/components/schemas/BlockchainRawAccount' } + } + } + }, '#/components/schemas/BlockchainLibrary': { type: 'object', required: ['boc'], @@ -4568,6 +5247,21 @@ const components = { required: ['accounts'], properties: { accounts: { type: 'array', items: { $ref: '#/components/schemas/Wallet' } } } }, + '#/components/schemas/WalletsByPublicKeys': { + type: 'object', + required: ['items'], + properties: { + items: { type: 'array', items: { $ref: '#/components/schemas/WalletsByPublicKey' } } + } + }, + '#/components/schemas/WalletsByPublicKey': { + type: 'object', + required: ['public_key', 'wallets'], + properties: { + public_key: { type: 'string' }, + wallets: { type: 'array', items: { $ref: '#/components/schemas/Wallet' } } + } + }, '#/components/schemas/Wallet': { type: 'object', required: [ @@ -4651,7 +5345,7 @@ const components = { '#/components/schemas/GaslessTx': { type: 'object', required: ['protocol_name'], - properties: { protocol_name: { type: 'string' } } + properties: { protocol_name: { type: 'string' }, external: { type: 'string' } } }, '#/components/schemas/SignRawParams': { type: 'object', @@ -4938,6 +5632,13 @@ const components = { catchain_max_blocks_coeff: { type: 'integer', format: 'int64' } } }, + '30': { + type: 'object', + properties: { + mc: { $ref: '#/components/schemas/NewConsensusConfig' }, + shard: { $ref: '#/components/schemas/NewConsensusConfig' } + } + }, '31': { type: 'object', required: ['fundamental_smc_addr'], @@ -5077,7 +5778,17 @@ const components = { verification: { $ref: '#/components/schemas/JettonVerificationType' }, custom_payload_api_uri: { type: 'string' }, score: { type: 'integer', format: 'int32' }, - scaled_ui: { $ref: '#/components/schemas/ScaledUI' } + scaled_ui: { $ref: '#/components/schemas/ScaledUI' }, + description: { type: 'string' }, + asset_info: { $ref: '#/components/schemas/JettonAssetInfo' } + } + }, + '#/components/schemas/JettonAssetInfo': { + type: 'object', + required: ['token_type', 'defi_provider'], + properties: { + token_type: { $ref: '#/components/schemas/DefiAssetAssetType' }, + defi_provider: { $ref: '#/components/schemas/DefiProvider' } } }, '#/components/schemas/ScaledUI': { @@ -5189,7 +5900,9 @@ const components = { description: 'Please use trust field' }, include_cnft: { type: 'boolean' }, - trust: { $ref: '#/components/schemas/TrustType' } + trust: { $ref: '#/components/schemas/TrustType' }, + code_hash: { type: 'string' }, + data_hash: { type: 'string' } } }, '#/components/schemas/NftItems': { @@ -5266,10 +5979,11 @@ const components = { }, '#/components/schemas/ValueFlow': { type: 'object', - required: ['account', 'ton', 'fees'], + required: ['account', 'gram', 'fees'], properties: { account: { $ref: '#/components/schemas/AccountAddress' }, - ton: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + ton: { type: 'integer', format: 'int64', 'x-js-format': 'bigint', deprecated: true }, + gram: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, fees: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, jettons: { type: 'array', @@ -5302,6 +6016,7 @@ const components = { 'ExtraCurrencyTransfer', 'ContractDeploy', 'JettonTransfer', + 'FlawedJettonTransfer', 'JettonBurn', 'JettonMint', 'NftItemTransfer', @@ -5325,6 +6040,9 @@ const components = { 'DepositTokenStake', 'WithdrawTokenStakeRequest', 'LiquidityDeposit', + 'OracleRequest', + 'DepositXTR', + 'WithdrawXTR', 'Unknown' ] }, @@ -5333,6 +6051,7 @@ const components = { ExtraCurrencyTransfer: { $ref: '#/components/schemas/ExtraCurrencyTransferAction' }, ContractDeploy: { $ref: '#/components/schemas/ContractDeployAction' }, JettonTransfer: { $ref: '#/components/schemas/JettonTransferAction' }, + FlawedJettonTransfer: { $ref: '#/components/schemas/FlawedJettonTransferAction' }, JettonBurn: { $ref: '#/components/schemas/JettonBurnAction' }, JettonMint: { $ref: '#/components/schemas/JettonMintAction' }, NftItemTransfer: { $ref: '#/components/schemas/NftItemTransferAction' }, @@ -5358,6 +6077,9 @@ const components = { $ref: '#/components/schemas/WithdrawTokenStakeRequestAction' }, LiquidityDeposit: { $ref: '#/components/schemas/LiquidityDepositAction' }, + OracleRequest: { $ref: '#/components/schemas/OracleRequestAction' }, + WithdrawXTR: { $ref: '#/components/schemas/WithdrawXTRAction' }, + DepositXTR: { $ref: '#/components/schemas/DepositXTRAction' }, simple_preview: { $ref: '#/components/schemas/ActionSimplePreview' }, base_transactions: { type: 'array', items: { type: 'string' } } } @@ -5374,6 +6096,40 @@ const components = { refund: { $ref: '#/components/schemas/Refund' } } }, + '#/components/schemas/OracleRequestAction': { + type: 'object', + required: ['requester', 'response_to', 'price_feeds'], + properties: { + requester: { $ref: '#/components/schemas/AccountAddress' }, + response_to: { $ref: '#/components/schemas/AccountAddress' }, + price_feeds: { type: 'array', items: { $ref: '#/components/schemas/OraclePriceFeed' } } + } + }, + '#/components/schemas/OraclePriceFeed': { + type: 'object', + required: ['id', 'display_symbol'], + properties: { + id: { type: 'string' }, + display_symbol: { type: 'string' }, + rate: { type: 'number', format: 'double' } + } + }, + '#/components/schemas/DepositXTRAction': { + type: 'object', + required: ['recipient', 'amount'], + properties: { + recipient: { $ref: '#/components/schemas/AccountAddress' }, + amount: { type: 'string', 'x-js-format': 'bigint' } + } + }, + '#/components/schemas/WithdrawXTRAction': { + type: 'object', + required: ['user', 'amount'], + properties: { + user: { $ref: '#/components/schemas/AccountAddress' }, + amount: { type: 'string', 'x-js-format': 'bigint' } + } + }, '#/components/schemas/ExtraCurrencies': { type: 'object', required: ['extra_currencies'], @@ -5405,11 +6161,17 @@ const components = { }, '#/components/schemas/SmartContractAction': { type: 'object', - required: ['executor', 'contract', 'ton_attached', 'operation'], + required: ['executor', 'contract', 'gram_attached', 'operation'], properties: { executor: { $ref: '#/components/schemas/AccountAddress' }, contract: { $ref: '#/components/schemas/AccountAddress' }, - ton_attached: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + ton_attached: { + type: 'integer', + format: 'int64', + 'x-js-format': 'bigint', + deprecated: true + }, + gram_attached: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, operation: { type: 'string' }, payload: { type: 'string' }, refund: { $ref: '#/components/schemas/Refund' } @@ -5496,6 +6258,28 @@ const components = { jetton: { $ref: '#/components/schemas/JettonPreview' } } }, + '#/components/schemas/FlawedJettonTransferAction': { + type: 'object', + required: [ + 'sent_amount', + 'received_amount', + 'jetton', + 'senders_wallet', + 'recipients_wallet' + ], + properties: { + sender: { $ref: '#/components/schemas/AccountAddress' }, + recipient: { $ref: '#/components/schemas/AccountAddress' }, + senders_wallet: { type: 'string', format: 'address' }, + recipients_wallet: { type: 'string', format: 'address' }, + sent_amount: { type: 'string', 'x-js-format': 'bigint' }, + received_amount: { type: 'string', 'x-js-format': 'bigint' }, + comment: { type: 'string' }, + encrypted_comment: { $ref: '#/components/schemas/EncryptedComment' }, + refund: { $ref: '#/components/schemas/Refund' }, + jetton: { $ref: '#/components/schemas/JettonPreview' } + } + }, '#/components/schemas/JettonBurnAction': { type: 'object', required: ['amount', 'jetton', 'sender', 'senders_wallet'], @@ -5565,7 +6349,11 @@ const components = { amount: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, staker: { $ref: '#/components/schemas/AccountAddress' }, pool: { $ref: '#/components/schemas/AccountAddress' }, - implementation: { $ref: '#/components/schemas/PoolImplementationType' } + implementation: { $ref: '#/components/schemas/PoolImplementationType' }, + stake_meta: { + description: 'If present, should be used instead of amount', + $ref: '#/components/schemas/Price' + } } }, '#/components/schemas/WithdrawStakeAction': { @@ -5585,7 +6373,11 @@ const components = { amount: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, staker: { $ref: '#/components/schemas/AccountAddress' }, pool: { $ref: '#/components/schemas/AccountAddress' }, - implementation: { $ref: '#/components/schemas/PoolImplementationType' } + implementation: { $ref: '#/components/schemas/PoolImplementationType' }, + stake_meta: { + description: 'If present, should be used instead of amount', + $ref: '#/components/schemas/Price' + } } }, '#/components/schemas/ElectionsRecoverStakeAction': { @@ -5611,8 +6403,15 @@ const components = { dex: { type: 'string' }, amount_in: { type: 'string', 'x-js-format': 'bigint' }, amount_out: { type: 'string', 'x-js-format': 'bigint' }, - ton_in: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, - ton_out: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + ton_in: { type: 'integer', format: 'int64', 'x-js-format': 'bigint', deprecated: true }, + ton_out: { + type: 'integer', + format: 'int64', + 'x-js-format': 'bigint', + deprecated: true + }, + gram_in: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + gram_out: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, user_wallet: { $ref: '#/components/schemas/AccountAddress' }, router: { $ref: '#/components/schemas/AccountAddress' }, jetton_master_in: { $ref: '#/components/schemas/JettonPreview' }, @@ -5691,7 +6490,8 @@ const components = { lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, in_progress: { type: 'boolean' }, extra: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, - progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 } + progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 }, + ext_msg_hash: { type: 'string' } } }, '#/components/schemas/AccountEvents': { @@ -5840,12 +6640,22 @@ const components = { wallet: { $ref: '#/components/schemas/WalletDNS' }, next_resolver: { type: 'string', format: 'maybe-address' }, sites: { type: 'array', items: { type: 'string' } }, - storage: { type: 'string' } + storage: { type: 'string' }, + picture: { $ref: '#/components/schemas/PictureDNS' } + } + }, + '#/components/schemas/PictureDNS': { + type: 'object', + required: ['type'], + properties: { + type: { type: 'string', enum: ['url', 'bag_id'] }, + url: { type: 'string' }, + bag_id: { type: 'string' } } }, '#/components/schemas/NftCollection': { type: 'object', - required: ['address', 'next_item_index', 'raw_collection_content', 'approved_by'], + required: ['address', 'next_item_index', 'raw_collection_content', 'approved_by', 'trust'], properties: { address: { type: 'string', format: 'address' }, next_item_index: { type: 'integer', format: 'int64' }, @@ -5853,7 +6663,8 @@ const components = { raw_collection_content: { type: 'string', format: 'cell' }, metadata: { type: 'object', additionalProperties: true }, previews: { type: 'array', items: { $ref: '#/components/schemas/ImagePreview' } }, - approved_by: { $ref: '#/components/schemas/NftApprovedBy' } + approved_by: { $ref: '#/components/schemas/NftApprovedBy' }, + trust: { $ref: '#/components/schemas/TrustType' } } }, '#/components/schemas/NftCollections': { @@ -5887,10 +6698,11 @@ const components = { }, '#/components/schemas/Risk': { type: 'object', - required: ['transfer_all_remaining_balance', 'ton', 'jettons', 'nfts'], + required: ['transfer_all_remaining_balance', 'gram', 'jettons', 'nfts'], properties: { transfer_all_remaining_balance: { type: 'boolean' }, - ton: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + ton: { type: 'integer', format: 'int64', 'x-js-format': 'bigint', deprecated: true }, + gram: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, jettons: { type: 'array', items: { $ref: '#/components/schemas/JettonQuantity' } }, nfts: { type: 'array', items: { $ref: '#/components/schemas/NftItem' } }, total_equivalent: { type: 'number', format: 'float' } @@ -6005,7 +6817,9 @@ const components = { is_scam: { type: 'boolean' }, lt: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, in_progress: { type: 'boolean' }, - progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 } + progress: { type: 'number', format: 'float', minimum: 0, maximum: 1 }, + last_slice_id: { type: 'integer', format: 'int64' }, + ext_msg_hash: { type: 'string' } } }, '#/components/schemas/JettonMetadata': { @@ -6049,7 +6863,12 @@ const components = { preview: { type: 'string' }, verification: { $ref: '#/components/schemas/JettonVerificationType' }, holders_count: { type: 'integer', format: 'int32' }, - scaled_ui: { $ref: '#/components/schemas/ScaledUI' } + scaled_ui: { $ref: '#/components/schemas/ScaledUI' }, + code_hash: { type: 'string' }, + data_hash: { type: 'string' }, + last_transaction_lt: { type: 'string', 'x-js-format': 'bigint' }, + name: { type: 'string', nullable: true }, + interfaces: { type: 'array', items: { type: 'string' } } } }, '#/components/schemas/JettonHolders': { @@ -6079,6 +6898,56 @@ const components = { state_init: { type: 'string', format: 'cell' } } }, + '#/components/schemas/DefiAssets': { + type: 'object', + required: ['assets'], + properties: { assets: { type: 'array', items: { $ref: '#/components/schemas/DefiAsset' } } } + }, + '#/components/schemas/DefiAssetAssetType': { + type: 'string', + enum: [ + 'staking', + 'lending_supply', + 'lending_borrow', + 'liquid_staking', + 'liquid_pool', + 'yield_token' + ] + }, + '#/components/schemas/DefiAsset': { + type: 'object', + required: ['asset_type', 'amount', 'defi_provider', 'locked_asset'], + properties: { + asset_type: { $ref: '#/components/schemas/DefiAssetAssetType' }, + amount: { type: 'string', 'x-js-format': 'bigint' }, + pool_address: { type: 'string', format: 'address' }, + asset_address: { type: 'string', format: 'address' }, + defi_provider: { $ref: '#/components/schemas/DefiProvider' }, + locked_asset: { $ref: '#/components/schemas/DefiLockedAsset' } + } + }, + '#/components/schemas/DefiLockedAsset': { + type: 'object', + required: ['type'], + properties: { + type: { type: 'string', enum: ['native', 'jetton'] }, + jetton: { $ref: '#/components/schemas/JettonPreview' } + } + }, + '#/components/schemas/DefiProvider': { + type: 'object', + required: ['name', 'description', 'link', 'icon', 'card', 'full', 'tag'], + properties: { + name: { type: 'string' }, + description: { type: 'string' }, + link: { type: 'string' }, + miniapp_link: { type: 'string' }, + icon: { type: 'string' }, + card: { type: 'string' }, + full: { type: 'string' }, + tag: { type: 'string' } + } + }, '#/components/schemas/AccountStaking': { type: 'object', required: ['pools'], @@ -6259,7 +7128,7 @@ const components = { }, '#/components/schemas/PoolImplementationType': { type: 'string', - enum: ['whales', 'tf', 'liquidTF'] + enum: ['whales', 'tf', 'liquidTF', 'ffvault'] }, '#/components/schemas/TokenRates': { type: 'object', @@ -6379,6 +7248,164 @@ const components = { type: 'object', required: ['name'], properties: { name: { type: 'string' }, image: { type: 'string' } } + }, + '#/components/schemas/BlockInfo': { + type: 'object', + required: ['seqno', 'time'], + properties: { + seqno: { type: 'integer', format: 'uint32' }, + utime: { type: 'integer', format: 'int64' } + } + }, + '#/components/schemas/RoundInfo': { + type: 'object', + required: ['start', 'end', 'start_block', 'end_block'], + properties: { + start_utime: { type: 'integer', format: 'int64' }, + end_utime: { type: 'integer', format: 'int64' }, + start_block: { type: 'integer', format: 'uint32' }, + end_block: { type: 'integer', format: 'uint32' } + } + }, + '#/components/schemas/ValidatorsResponse': { + type: 'object', + required: [ + 'response_time_ms', + 'block', + 'validation_round', + 'election_id', + 'elector_balance', + 'total_stake', + 'reward_per_block', + 'validators' + ], + properties: { + response_time_ms: { type: 'integer', format: 'int64' }, + block: { $ref: '#/components/schemas/BlockInfo' }, + validation_round: { $ref: '#/components/schemas/RoundInfo' }, + election_id: { type: 'integer', format: 'int64' }, + prev_election_id: { type: 'integer', format: 'int64' }, + next_election_id: { type: 'integer', format: 'int64' }, + elector_balance: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + total_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + reward_per_block: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + validators: { + type: 'array', + items: { $ref: '#/components/schemas/ValidatorRewardEntry' } + } + } + }, + '#/components/schemas/ValidationRound': { + type: 'object', + required: ['election_id', 'start', 'end', 'start_block', 'finished'], + properties: { + election_id: { type: 'integer', format: 'int64' }, + start_utime: { type: 'integer', format: 'int64' }, + end_utime: { type: 'integer', format: 'int64' }, + start_block: { type: 'integer', format: 'uint32' }, + end_block: { type: 'integer', format: 'uint32' }, + prev_election_id: { type: 'integer', format: 'int64' }, + next_election_id: { type: 'integer', format: 'int64' }, + total_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + bonuses: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + finished: { type: 'boolean' } + } + }, + '#/components/schemas/ValidationRoundsResponse': { + type: 'object', + required: ['response_time_ms', 'rounds'], + properties: { + response_time_ms: { type: 'integer', format: 'int64' }, + rounds: { type: 'array', items: { $ref: '#/components/schemas/ValidationRound' } } + } + }, + '#/components/schemas/NominatorRewardEntry': { + type: 'object', + required: ['address', 'weight', 'reward', 'effective_stake', 'stake'], + properties: { + address: { type: 'string' }, + weight: { type: 'number', format: 'double' }, + reward: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + effective_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' } + } + }, + '#/components/schemas/ValidatorRewardEntry': { + type: 'object', + required: ['rank', 'public_key', 'effective_stake', 'weight', 'reward'], + properties: { + rank: { type: 'integer' }, + public_key: { type: 'string' }, + effective_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + weight: { type: 'number', format: 'double' }, + reward: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + pool: { type: 'string' }, + pool_type: { + type: 'string', + enum: [ + 'nominator-pool-v1.0', + 'single-nominator-pool-v1.0', + 'single-nominator-pool-v1.1', + 'other' + ] + }, + owner_address: { type: 'string' }, + validator_address: { type: 'string' }, + validator_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + nominators_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + total_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + validator_reward_share: { type: 'number', format: 'double' }, + nominators_count: { type: 'integer', format: 'uint32' }, + nominators: { + type: 'array', + items: { $ref: '#/components/schemas/NominatorRewardEntry' } + } + } + }, + '#/components/schemas/RoundRewardsResponse': { + type: 'object', + required: [ + 'response_time_ms', + 'election_id', + 'round_start', + 'round_end', + 'start_block', + 'end_block', + 'total_bonuses', + 'total_stake', + 'validators' + ], + properties: { + response_time_ms: { type: 'integer', format: 'int64' }, + election_id: { type: 'integer', format: 'int64' }, + prev_election_id: { type: 'integer', format: 'int64' }, + next_election_id: { type: 'integer', format: 'int64' }, + round_start: { type: 'string', format: 'date-time' }, + round_end: { type: 'string', format: 'date-time' }, + start_block: { type: 'integer', format: 'uint32' }, + end_block: { type: 'integer', format: 'uint32' }, + total_bonuses: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + total_stake: { type: 'integer', format: 'int64', 'x-js-format': 'bigint' }, + validators: { + type: 'array', + items: { $ref: '#/components/schemas/ValidatorRewardEntry' } + }, + error: { type: 'string' } + } + }, + '#/components/schemas/RewardsStats': { + type: 'object', + required: ['apy', 'total_stake'], + properties: { + apy: { + type: 'array', + items: { type: 'array', items: { type: 'number', format: 'double' } } + }, + total_stake: { + type: 'array', + items: { type: 'array', items: { type: 'number', format: 'double' } } + } + } } }; /** @@ -6896,7 +7923,12 @@ function prepareResponseData(obj: any, orSchema?: any, originalResponse: unkn case 'slice': return { type: 'slice', - slice: cellParse(obj.slice as string, originalResponse) + cell: cellParse(obj.slice as string, originalResponse) + } as U; + case 'builder': + return { + type: 'builder', + cell: cellParse(obj.builder as string, originalResponse) } as U; case 'null': return { @@ -7323,11 +8355,24 @@ export class TonApiClient { */ getBlockchainMasterchainTransactions( masterchainSeqno: number, + query?: { + /** + * @min 0 + * @default 0 + */ + offset?: number; + /** + * @min 1 + * @example 100 + */ + limit?: number; + }, params: RequestParams = {} ): TonApiPromise { const req = this.http.request({ path: `/v2/blockchain/masterchain/${masterchainSeqno}/transactions`, method: 'GET', + query: query, format: 'json', ...params }); @@ -7562,17 +8607,56 @@ export class TonApiClient { getBlockchainRawAccount( accountId_Address: Address | string, params: RequestParams = {} - ): TonApiPromise { - const accountId = addressToString(accountId_Address); - const req = this.http.request({ - path: `/v2/blockchain/accounts/${accountId}`, - method: 'GET', + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ + path: `/v2/blockchain/accounts/${accountId}`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainRawAccount' + }); + } + + /** + * @description Get low-level information about several accounts taken directly from the blockchain. + * + * @tags Blockchain + * @name GetBlockchainRawAccounts + * @request POST:/v2/blockchain/accounts/_bulk + */ + /** + * @description Get low-level information about several accounts taken directly from the blockchain. + * + * @tags Blockchain + * @name GetBlockchainRawAccounts + * @request POST:/v2/blockchain/accounts/_bulk + */ + getBlockchainRawAccounts( + data: { + accountIds: (Address | string)[]; + }, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ + path: `/v2/blockchain/accounts/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['accountIds'], + properties: { + accountIds: { type: 'array', items: { type: 'string', format: 'address' } } + } + }), format: 'json', ...params }); - return prepareResponse(req, { - $ref: '#/components/schemas/BlockchainRawAccount' + return prepareResponse(req, { + $ref: '#/components/schemas/BlockchainRawAccounts' }); } @@ -8015,15 +9099,26 @@ export class TonApiClient { accountId_Address: Address | string, query?: { /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] + * accept gram and all possible fiat currencies, separated by commas + * @example ["gram","usd","rub"] */ currencies?: string[]; /** * comma separated list supported extensions - * @example ["custom_payload"] + * @example ["custom_payload","defi"] */ supported_extensions?: string[]; + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @default 0 + */ + offset?: number; }, params: RequestParams = {} ): TonApiPromise { @@ -8061,13 +9156,13 @@ export class TonApiClient { jettonId_Address: Address | string, query?: { /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] + * accept gram and all possible fiat currencies, separated by commas + * @example ["gram","usd","rub"] */ currencies?: string[]; /** * comma separated list supported extensions - * @example ["custom_payload"] + * @example ["custom_payload","defi"] */ supported_extensions?: string[]; }, @@ -8232,7 +9327,7 @@ export class TonApiClient { */ offset?: number; /** - * Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. + * Selling nft items in TON implemented usually via transfer items to special selling account. This option enables including items which owned not directly. * @default false */ indirect_ownership?: boolean; @@ -8283,6 +9378,12 @@ export class TonApiClient { * @default false */ subject_only?: boolean; + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + after_lt?: bigint; /** * omit this parameter to get last events * @format bigint @@ -8307,6 +9408,11 @@ export class TonApiClient { * @example 1668436763 */ end_date?: number; + /** + * used to sort the result-set in ascending or descending order by lt. + * @default "desc" + */ + sort_order?: 'desc' | 'asc'; }, params: RequestParams = {} ): TonApiPromise { @@ -8660,6 +9766,37 @@ export class TonApiClient { }); } + /** + * @description Return DeFi assets locked in custom smart contracts: currently returns TON Whales staking and EVAA lending positions. + * + * @tags Accounts + * @name GetAccountDefiAssets + * @request GET:/v2/accounts/{account_id}/defi/assets + */ + /** + * @description Return DeFi assets locked in custom smart contracts: currently returns TON Whales staking and EVAA lending positions. + * + * @tags Accounts + * @name GetAccountDefiAssets + * @request GET:/v2/accounts/{account_id}/defi/assets + */ + getAccountDefiAssets( + accountId_Address: Address | string, + params: RequestParams = {} + ): TonApiPromise { + const accountId = addressToString(accountId_Address); + const req = this.http.request({ + path: `/v2/accounts/${accountId}/defi/assets`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/DefiAssets' + }); + } + /** * @description Get the transfer history of extra currencies for an account. * @@ -9648,12 +10785,29 @@ export class TonApiClient { */ getStakingPoolHistory( accountId_Address: Address | string, + query?: { + /** + * omit this parameter to get last log entries + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @format int32 + * @min 1 + * @max 100 + * @default 100 + * @example 100 + */ + limit?: number; + }, params: RequestParams = {} ): TonApiPromise { const accountId = addressToString(accountId_Address); const req = this.http.request({ path: `/v2/staking/pool/${accountId}/history`, method: 'GET', + query: query, format: 'json', ...params }); @@ -9879,14 +11033,14 @@ export class TonApiClient { } /** - * @description Get the TON price from markets + * @description Get the Gram price from markets * * @tags Rates * @name GetMarketsRates * @request GET:/v2/rates/markets */ /** - * @description Get the TON price from markets + * @description Get the Gram price from markets * * @tags Rates * @name GetMarketsRates @@ -10150,6 +11304,43 @@ export class TonApiClient { }); } + /** + * @description Get wallets by a list of public keys + * + * @tags Wallet + * @name GetWalletsByPublicKeyBulk + * @request POST:/v2/pubkeys/wallets/_bulk + */ + /** + * @description Get wallets by a list of public keys + * + * @tags Wallet + * @name GetWalletsByPublicKeyBulk + * @request POST:/v2/pubkeys/wallets/_bulk + */ + getWalletsByPublicKeyBulk( + data: { + publicKeys: string[]; + }, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ + path: `/v2/pubkeys/wallets/_bulk`, + method: 'POST', + body: prepareRequestData(data, { + type: 'object', + required: ['publicKeys'], + properties: { publicKeys: { type: 'array', items: { type: 'string' } } } + }), + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/WalletsByPublicKeys' + }); + } + /** * @description Returns configuration of gasless transfers * @@ -10259,7 +11450,7 @@ export class TonApiClient { gaslessSend( data: { /** hex encoded public key */ - walletPublicKey: string; + walletPublicKey?: string; /** @format cell */ boc: Cell | string; }, @@ -10270,7 +11461,7 @@ export class TonApiClient { method: 'POST', body: prepareRequestData(data, { type: 'object', - required: ['boc', 'walletPublicKey'], + required: ['boc'], properties: { walletPublicKey: { type: 'string' }, boc: { type: 'string', format: 'cell' } @@ -11446,6 +12637,217 @@ export class TonApiClient { $ref: '#/components/schemas/AccountPurchases' }); } + + /** + * @description Returns all current validators with stakes, rewards, pool addresses, and (optionally) nominator breakdowns. + * + * @tags Rewards + * @name GetValidators + * @summary Get all current validators + * @request GET:/v2/rewards/validators + */ + /** + * @description Returns all current validators with stakes, rewards, pool addresses, and (optionally) nominator breakdowns. + * + * @tags Rewards + * @name GetValidators + * @summary Get all current validators + * @request GET:/v2/rewards/validators + */ + getValidators( + query?: { + /** + * Masterchain block seqno. Defaults to latest. Mutually exclusive with `unixtime`. + * @format uint32 + */ + seqno?: number; + /** + * Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `seqno`. + * @format uint32 + */ + unixtime?: number; + /** + * Set to `1` to return only basic validator info (rank, pubkey, effective_stake, weight, reward, pool). Skips pool type detection, owner/validator addresses, nominator data, and returned-stake lookup — significantly faster. + * @default false + */ + shallow?: boolean; + }, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ + path: `/v2/rewards/validators`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/ValidatorsResponse' + }); + } + + /** + * @description Returns past and current validation rounds with boundaries, stakes, and bonuses. Always uses the latest masterchain block. + * + * @tags Rewards + * @name GetValidationRounds + * @summary Get validation round metadata + * @request GET:/v2/rewards/validation-rounds + */ + /** + * @description Returns past and current validation rounds with boundaries, stakes, and bonuses. Always uses the latest masterchain block. + * + * @tags Rewards + * @name GetValidationRounds + * @summary Get validation round metadata + * @request GET:/v2/rewards/validation-rounds + */ + getValidationRounds( + query?: { + /** + * Return the single round matching this election ID. Mutually exclusive with `block` and `unixtime`. + * @format int64 + */ + election_id?: number; + /** + * Find the round containing this masterchain block seqno and return it plus up to `limit-1` older rounds. Mutually exclusive with `election_id` and `unixtime`. + * @format uint32 + */ + block?: number; + /** + * Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `election_id` and `block`. + * @format uint32 + */ + unixtime?: number; + }, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ + path: `/v2/rewards/validation-rounds`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/ValidationRoundsResponse' + }); + } + + /** + * @description Computes per-validator and per-nominator reward distribution for a finished validation round using the elector's bonuses value. + * + * @tags Rewards + * @name GetRoundRewards + * @summary Get per-validator reward distribution for a finished round + * @request GET:/v2/rewards/round-rewards + */ + /** + * @description Computes per-validator and per-nominator reward distribution for a finished validation round using the elector's bonuses value. + * + * @tags Rewards + * @name GetRoundRewards + * @summary Get per-validator reward distribution for a finished round + * @request GET:/v2/rewards/round-rewards + */ + getRoundRewards( + query?: { + /** + * Election ID of the finished round. Mutually exclusive with `block` and `unixtime`. + * @format int64 + */ + election_id?: number; + /** + * Masterchain block seqno within the finished round. Mutually exclusive with `election_id` and `unixtime`. + * @format uint32 + */ + block?: number; + /** + * Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `election_id` and `block`. + * @format uint32 + */ + unixtime?: number; + /** + * Set to `1` to return only basic validator info (rank, pubkey, effective_stake, weight, reward, pool). Skips pool type detection, owner/validator addresses, nominator data, and returned-stake lookup — significantly faster. + * @default false + */ + shallow?: boolean; + }, + params: RequestParams = {} + ): TonApiPromise { + const req = this.http.request({ + path: `/v2/rewards/round-rewards`, + method: 'GET', + query: query, + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/RoundRewardsResponse' + }); + } + + /** + * @description Returns time series of APY and total stake from past validation rounds. + * + * @tags Rewards + * @name GetRewardsStats + * @summary Get historical APY and stake statistics + * @request GET:/v2/rewards/stats + */ + /** + * @description Returns time series of APY and total stake from past validation rounds. + * + * @tags Rewards + * @name GetRewardsStats + * @summary Get historical APY and stake statistics + * @request GET:/v2/rewards/stats + */ + getRewardsStats(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ + path: `/v2/rewards/stats`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + $ref: '#/components/schemas/RewardsStats' + }); + } + + /** + * @description Returns the current TON blockchain APY as a percent based on the latest completed validation round. + * + * @tags Rewards + * @name GetRewardsApy + * @summary Get current TON blockchain APY + * @request GET:/v2/rewards/apy + */ + /** + * @description Returns the current TON blockchain APY as a percent based on the latest completed validation round. + * + * @tags Rewards + * @name GetRewardsApy + * @summary Get current TON blockchain APY + * @request GET:/v2/rewards/apy + */ + getRewardsApy(params: RequestParams = {}): TonApiPromise { + const req = this.http.request({ + path: `/v2/rewards/apy`, + method: 'GET', + format: 'json', + ...params + }); + + return prepareResponse(req, { + type: 'number', + format: 'double' + }); + } } // Default client instance for global methods @@ -11883,6 +13285,18 @@ type GetBlockchainMasterchainTransactionsOptions = { + client?: TonApiClient; + body: { + accountIds: (Address | string)[]; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getBlockchainRawAccounts = async ( + options: GetBlockchainRawAccountsOptions +): Promise> => { + try { + const client = options.client || getDefaultClient(); + const result = await client.getBlockchainRawAccounts(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync< + GetBlockchainRawAccountsData, + ThrowOnError + >; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetBlockchainRawAccountsData, + ThrowOnError + >; + } +}; + /** * @description Get account transactions * @@ -12827,15 +14285,26 @@ type GetAccountJettonsBalancesOptions = { }; query?: { /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] + * accept gram and all possible fiat currencies, separated by commas + * @example ["gram","usd","rub"] */ currencies?: string[]; /** * comma separated list supported extensions - * @example ["custom_payload"] + * @example ["custom_payload","defi"] + */ + supported_extensions?: string[]; + /** + * @min 1 + * @max 1000 + * @default 1000 + */ + limit?: number; + /** + * @min 0 + * @default 0 */ - supported_extensions?: string[]; + offset?: number; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -12887,13 +14356,13 @@ type GetAccountJettonBalanceOptions = { }; query?: { /** - * accept ton and all possible fiat currencies, separated by commas - * @example ["ton","usd","rub"] + * accept gram and all possible fiat currencies, separated by commas + * @example ["gram","usd","rub"] */ currencies?: string[]; /** * comma separated list supported extensions - * @example ["custom_payload"] + * @example ["custom_payload","defi"] */ supported_extensions?: string[]; }; @@ -13101,7 +14570,7 @@ type GetAccountNftItemsOptions = { */ offset?: number; /** - * Selling nft items in ton implemented usually via transfer items to special selling account. This option enables including items which owned not directly. + * Selling nft items in TON implemented usually via transfer items to special selling account. This option enables including items which owned not directly. * @default false */ indirect_ownership?: boolean; @@ -13164,6 +14633,12 @@ type GetAccountEventsOptions = { * @default false */ subject_only?: boolean; + /** + * omit this parameter to get last events + * @format bigint + * @example 25758317000002 + */ + after_lt?: bigint; /** * omit this parameter to get last events * @format bigint @@ -13188,6 +14663,11 @@ type GetAccountEventsOptions = { * @example 1668436763 */ end_date?: number; + /** + * used to sort the result-set in ascending or descending order by lt. + * @default "desc" + */ + sort_order?: 'desc' | 'asc'; }; params?: RequestParams; throwOnError?: ThrowOnError; @@ -13665,6 +15145,49 @@ export const getAccountDiff = async ( } }; +/** + * @description Return DeFi assets locked in custom smart contracts: currently returns TON Whales staking and EVAA lending positions. + * + * @tags Accounts + * @name GetAccountDefiAssets + * @request GET:/v2/accounts/{account_id}/defi/assets + */ +type GetAccountDefiAssetsOptions = { + client?: TonApiClient; + path: { + accountId: Address | string; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getAccountDefiAssets = async ( + options: GetAccountDefiAssetsOptions +): Promise> => { + try { + const client = options.client || getDefaultClient(); + const result = await client.getAccountDefiAssets(options.path.accountId, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync< + GetAccountDefiAssetsData, + ThrowOnError + >; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetAccountDefiAssetsData, + ThrowOnError + >; + } +}; + /** * @description Get the transfer history of extra currencies for an account. * @@ -14924,6 +16447,22 @@ type GetStakingPoolHistoryOptions = { path: { accountId: Address | string; }; + query?: { + /** + * omit this parameter to get last log entries + * @format bigint + * @example 25758317000002 + */ + before_lt?: bigint; + /** + * @format int32 + * @min 1 + * @max 100 + * @default 100 + * @example 100 + */ + limit?: number; + }; params?: RequestParams; throwOnError?: ThrowOnError; }; @@ -14932,7 +16471,11 @@ export const getStakingPoolHistory = async > => { try { const client = options.client || getDefaultClient(); - const result = await client.getStakingPoolHistory(options.path.accountId, options.params); + const result = await client.getStakingPoolHistory( + options.path.accountId, + options?.query, + options.params + ); // If throwOnError is true, return data directly if (options?.throwOnError) { @@ -15163,7 +16706,7 @@ export const getChartRates = async ( }; /** - * @description Get the TON price from markets + * @description Get the Gram price from markets * * @tags Rates * @name GetMarketsRates @@ -15467,6 +17010,49 @@ export const getWalletsByPublicKey = async = { + client?: TonApiClient; + body: { + publicKeys: string[]; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getWalletsByPublicKeyBulk = async ( + options: GetWalletsByPublicKeyBulkOptions +): Promise> => { + try { + const client = options.client || getDefaultClient(); + const result = await client.getWalletsByPublicKeyBulk(options.body, options.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync< + GetWalletsByPublicKeyBulkData, + ThrowOnError + >; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetWalletsByPublicKeyBulkData, + ThrowOnError + >; + } +}; + /** * @description Returns configuration of gasless transfers * @@ -15575,7 +17161,7 @@ type GaslessSendOptions = { client?: TonApiClient; body: { /** hex encoded public key */ - walletPublicKey: string; + walletPublicKey?: string; /** @format cell */ boc: Cell | string; }; @@ -16819,3 +18405,252 @@ export const getPurchaseHistory = async ( >; } }; + +/** + * @description Returns all current validators with stakes, rewards, pool addresses, and (optionally) nominator breakdowns. + * + * @tags Rewards + * @name GetValidators + * @summary Get all current validators + * @request GET:/v2/rewards/validators + */ +type GetValidatorsOptions = { + client?: TonApiClient; + query?: { + /** + * Masterchain block seqno. Defaults to latest. Mutually exclusive with `unixtime`. + * @format uint32 + */ + seqno?: number; + /** + * Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `seqno`. + * @format uint32 + */ + unixtime?: number; + /** + * Set to `1` to return only basic validator info (rank, pubkey, effective_stake, weight, reward, pool). Skips pool type detection, owner/validator addresses, nominator data, and returned-stake lookup — significantly faster. + * @default false + */ + shallow?: boolean; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getValidators = async ( + options?: GetValidatorsOptions +): Promise> => { + try { + const client = options?.client || getDefaultClient(); + const result = await client.getValidators(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetValidatorsData, + ThrowOnError + >; + } +}; + +/** + * @description Returns past and current validation rounds with boundaries, stakes, and bonuses. Always uses the latest masterchain block. + * + * @tags Rewards + * @name GetValidationRounds + * @summary Get validation round metadata + * @request GET:/v2/rewards/validation-rounds + */ +type GetValidationRoundsOptions = { + client?: TonApiClient; + query?: { + /** + * Return the single round matching this election ID. Mutually exclusive with `block` and `unixtime`. + * @format int64 + */ + election_id?: number; + /** + * Find the round containing this masterchain block seqno and return it plus up to `limit-1` older rounds. Mutually exclusive with `election_id` and `unixtime`. + * @format uint32 + */ + block?: number; + /** + * Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `election_id` and `block`. + * @format uint32 + */ + unixtime?: number; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getValidationRounds = async ( + options?: GetValidationRoundsOptions +): Promise> => { + try { + const client = options?.client || getDefaultClient(); + const result = await client.getValidationRounds(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync< + GetValidationRoundsData, + ThrowOnError + >; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetValidationRoundsData, + ThrowOnError + >; + } +}; + +/** + * @description Computes per-validator and per-nominator reward distribution for a finished validation round using the elector's bonuses value. + * + * @tags Rewards + * @name GetRoundRewards + * @summary Get per-validator reward distribution for a finished round + * @request GET:/v2/rewards/round-rewards + */ +type GetRoundRewardsOptions = { + client?: TonApiClient; + query?: { + /** + * Election ID of the finished round. Mutually exclusive with `block` and `unixtime`. + * @format int64 + */ + election_id?: number; + /** + * Masterchain block seqno within the finished round. Mutually exclusive with `election_id` and `unixtime`. + * @format uint32 + */ + block?: number; + /** + * Unix timestamp (seconds). Looks up the masterchain block at this time and uses it as the anchor. Mutually exclusive with `election_id` and `block`. + * @format uint32 + */ + unixtime?: number; + /** + * Set to `1` to return only basic validator info (rank, pubkey, effective_stake, weight, reward, pool). Skips pool type detection, owner/validator addresses, nominator data, and returned-stake lookup — significantly faster. + * @default false + */ + shallow?: boolean; + }; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getRoundRewards = async ( + options?: GetRoundRewardsOptions +): Promise> => { + try { + const client = options?.client || getDefaultClient(); + const result = await client.getRoundRewards(options?.query, options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRoundRewardsData, + ThrowOnError + >; + } +}; + +/** + * @description Returns time series of APY and total stake from past validation rounds. + * + * @tags Rewards + * @name GetRewardsStats + * @summary Get historical APY and stake statistics + * @request GET:/v2/rewards/stats + */ +type GetRewardsStatsOptions = { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getRewardsStats = async ( + options?: GetRewardsStatsOptions +): Promise> => { + try { + const client = options?.client || getDefaultClient(); + const result = await client.getRewardsStats(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRewardsStatsData, + ThrowOnError + >; + } +}; + +/** + * @description Returns the current TON blockchain APY as a percent based on the latest completed validation round. + * + * @tags Rewards + * @name GetRewardsApy + * @summary Get current TON blockchain APY + * @request GET:/v2/rewards/apy + */ +type GetRewardsApyOptions = { + client?: TonApiClient; + params?: RequestParams; + throwOnError?: ThrowOnError; +}; +export const getRewardsApy = async ( + options?: GetRewardsApyOptions +): Promise> => { + try { + const client = options?.client || getDefaultClient(); + const result = await client.getRewardsApy(options?.params); + + // If throwOnError is true, return data directly + if (options?.throwOnError) { + return result as MethodResultSync; + } + + return { data: result, error: null } as MethodResultSync; + } catch (error) { + // If throwOnError is true, rethrow the error + if (options?.throwOnError) { + throw error; + } + return { data: null, error: error as TonApiError } as MethodResultSync< + GetRewardsApyData, + ThrowOnError + >; + } +};