@tonappchain/sdk 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1197 -0
  3. package/dist/adapters/contractOpener.d.ts +19 -0
  4. package/dist/adapters/contractOpener.js +94 -0
  5. package/dist/errors/errors.d.ts +34 -0
  6. package/dist/errors/errors.js +80 -0
  7. package/dist/errors/index.d.ts +2 -0
  8. package/dist/errors/index.js +30 -0
  9. package/dist/errors/instances.d.ts +16 -0
  10. package/dist/errors/instances.js +28 -0
  11. package/dist/index.d.ts +10 -0
  12. package/dist/index.js +35 -0
  13. package/dist/sdk/Consts.d.ts +6 -0
  14. package/dist/sdk/Consts.js +10 -0
  15. package/dist/sdk/OperationTracker.d.ts +15 -0
  16. package/dist/sdk/OperationTracker.js +128 -0
  17. package/dist/sdk/StartTracking.d.ts +2 -0
  18. package/dist/sdk/StartTracking.js +91 -0
  19. package/dist/sdk/TacSdk.d.ts +36 -0
  20. package/dist/sdk/TacSdk.js +361 -0
  21. package/dist/sdk/Utils.d.ts +18 -0
  22. package/dist/sdk/Utils.js +126 -0
  23. package/dist/sender/RawSender.d.ts +13 -0
  24. package/dist/sender/RawSender.js +37 -0
  25. package/dist/sender/SenderAbstraction.d.ts +19 -0
  26. package/dist/sender/SenderAbstraction.js +5 -0
  27. package/dist/sender/SenderFactory.d.ts +33 -0
  28. package/dist/sender/SenderFactory.js +51 -0
  29. package/dist/sender/TonConnectSender.d.ts +10 -0
  30. package/dist/sender/TonConnectSender.js +33 -0
  31. package/dist/sender/index.d.ts +2 -0
  32. package/dist/sender/index.js +18 -0
  33. package/dist/structs/InternalStruct.d.ts +52 -0
  34. package/dist/structs/InternalStruct.js +8 -0
  35. package/dist/structs/Struct.d.ts +210 -0
  36. package/dist/structs/Struct.js +15 -0
  37. package/dist/wrappers/ContentUtils.d.ts +25 -0
  38. package/dist/wrappers/ContentUtils.js +160 -0
  39. package/dist/wrappers/HighloadQueryId.d.ts +17 -0
  40. package/dist/wrappers/HighloadQueryId.js +72 -0
  41. package/dist/wrappers/HighloadWalletV3.d.ts +61 -0
  42. package/dist/wrappers/HighloadWalletV3.js +161 -0
  43. package/dist/wrappers/JettonMaster.d.ts +24 -0
  44. package/dist/wrappers/JettonMaster.js +52 -0
  45. package/dist/wrappers/JettonWallet.d.ts +46 -0
  46. package/dist/wrappers/JettonWallet.js +103 -0
  47. package/dist/wrappers/Settings.d.ts +10 -0
  48. package/dist/wrappers/Settings.js +38 -0
  49. package/package.json +66 -0
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SenderFactory = exports.wallets = void 0;
4
+ const ton_1 = require("@ton/ton");
5
+ const ton_crypto_1 = require("ton-crypto");
6
+ const RawSender_1 = require("./RawSender");
7
+ const TonConnectSender_1 = require("./TonConnectSender");
8
+ const errors_1 = require("../errors");
9
+ const Struct_1 = require("../structs/Struct");
10
+ const HighloadWalletV3_1 = require("../wrappers/HighloadWalletV3");
11
+ exports.wallets = {
12
+ v2r1: ton_1.WalletContractV2R1,
13
+ v2r2: ton_1.WalletContractV2R2,
14
+ v3r1: ton_1.WalletContractV3R1,
15
+ v3r2: ton_1.WalletContractV3R2,
16
+ v4: ton_1.WalletContractV4,
17
+ v5r1: ton_1.WalletContractV5R1,
18
+ highloadV3: HighloadWalletV3_1.HighloadWalletV3,
19
+ };
20
+ class SenderFactory {
21
+ static async getSender(params) {
22
+ if ('tonConnect' in params) {
23
+ return new TonConnectSender_1.TonConnectSender(params.tonConnect);
24
+ }
25
+ if (!(params.version in exports.wallets)) {
26
+ throw (0, errors_1.unknownWalletError)(params.version);
27
+ }
28
+ const keypair = await (0, ton_crypto_1.mnemonicToWalletKey)(params.mnemonic.split(' '));
29
+ const config = {
30
+ workchain: 0,
31
+ publicKey: keypair.publicKey,
32
+ walletId: undefined, // for w5
33
+ subwalletId: undefined, // for highload v3
34
+ timeout: undefined, // for highload v3
35
+ };
36
+ if (params.version === 'v5r1') {
37
+ // manual setup of wallet id required to support wallet w5 both on mainnet and testnet
38
+ config.walletId = {
39
+ networkGlobalId: params.network === Struct_1.Network.Testnet ? -3 : -239,
40
+ context: { walletVersion: 'v5r1', workchain: 0, subwalletNumber: params.options?.v5r1?.subwalletNumber ?? 0 },
41
+ };
42
+ }
43
+ if (params.version === 'highloadV3') {
44
+ config.subwalletId = params.options?.highloadV3?.subwalletId ?? HighloadWalletV3_1.DEFAULT_SUBWALLET_ID;
45
+ config.timeout = params.options?.highloadV3?.timeout ?? HighloadWalletV3_1.DEFAULT_TIMEOUT;
46
+ }
47
+ const wallet = exports.wallets[params.version].create(config);
48
+ return new RawSender_1.RawSender(wallet, keypair.secretKey);
49
+ }
50
+ }
51
+ exports.SenderFactory = SenderFactory;
@@ -0,0 +1,10 @@
1
+ import { TonConnectUI } from '@tonconnect/ui';
2
+ import type { ShardTransaction } from '../structs/InternalStruct';
3
+ import { Network } from '../structs/Struct';
4
+ import { SenderAbstraction } from './SenderAbstraction';
5
+ export declare class TonConnectSender implements SenderAbstraction {
6
+ readonly tonConnect: TonConnectUI;
7
+ constructor(tonConnect: TonConnectUI);
8
+ getSenderAddress(): string;
9
+ sendShardTransaction(shardTransaction: ShardTransaction, delay: number, chain: Network): Promise<void>;
10
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TonConnectSender = void 0;
4
+ const protocol_1 = require("@tonconnect/protocol");
5
+ const ui_1 = require("@tonconnect/ui");
6
+ const Struct_1 = require("../structs/Struct");
7
+ const SenderAbstraction_1 = require("./SenderAbstraction");
8
+ class TonConnectSender {
9
+ constructor(tonConnect) {
10
+ this.tonConnect = tonConnect;
11
+ }
12
+ getSenderAddress() {
13
+ return this.tonConnect.account?.address?.toString() || '';
14
+ }
15
+ async sendShardTransaction(shardTransaction, delay, chain) {
16
+ const messages = [];
17
+ for (const message of shardTransaction.messages) {
18
+ messages.push({
19
+ address: message.address,
20
+ amount: message.value.toString(),
21
+ payload: protocol_1.Base64.encode(message.payload.toBoc()).toString(),
22
+ });
23
+ }
24
+ const transaction = {
25
+ validUntil: shardTransaction.validUntil,
26
+ messages,
27
+ network: chain == Struct_1.Network.Testnet ? ui_1.CHAIN.TESTNET : ui_1.CHAIN.MAINNET,
28
+ };
29
+ await (0, SenderAbstraction_1.sleep)(delay * 1000);
30
+ await this.tonConnect.sendTransaction(transaction);
31
+ }
32
+ }
33
+ exports.TonConnectSender = TonConnectSender;
@@ -0,0 +1,2 @@
1
+ export * from './SenderAbstraction';
2
+ export * from './SenderFactory';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./SenderAbstraction"), exports);
18
+ __exportStar(require("./SenderFactory"), exports);
@@ -0,0 +1,52 @@
1
+ import { Cell } from '@ton/ton';
2
+ import { ContractOpener, EVMSimulationResults, ExecutionStagesByOperationId, Network, OperationIdsByShardsKey, RawAssetBridgingData, StatusInfosByOperationId } from './Struct';
3
+ import { AbstractProvider, ethers, Interface, InterfaceAbi } from 'ethers';
4
+ export type ShardMessage = {
5
+ address: string;
6
+ value: bigint;
7
+ payload: Cell;
8
+ };
9
+ export type ShardTransaction = {
10
+ validUntil: number;
11
+ messages: ShardMessage[];
12
+ network: Network;
13
+ };
14
+ export declare enum AssetOpType {
15
+ JettonBurn = "JettonBurn",
16
+ JettonTransfer = "JettonTransfer"
17
+ }
18
+ export type RandomNumberByTimestamp = {
19
+ timestamp: number;
20
+ randomNumber: number;
21
+ };
22
+ export type JettonBridgingData = RawAssetBridgingData & {
23
+ address: string;
24
+ };
25
+ export type JettonTransferData = JettonBridgingData;
26
+ export type JettonBurnData = JettonBridgingData & {
27
+ notificationReceiverAddress: string;
28
+ };
29
+ export type InternalTONParams = {
30
+ contractOpener: ContractOpener;
31
+ jettonProxyAddress: string;
32
+ crossChainLayerAddress: string;
33
+ jettonMinterCode: Cell;
34
+ jettonWalletCode: Cell;
35
+ };
36
+ export type InternalTACParams = {
37
+ provider: AbstractProvider;
38
+ settingsAddress: string;
39
+ tokenUtilsAddress: string;
40
+ abiCoder: ethers.AbiCoder;
41
+ crossChainLayerABI: Interface | InterfaceAbi;
42
+ crossChainLayerAddress: string;
43
+ crossChainLayerTokenABI: Interface | InterfaceAbi;
44
+ crossChainLayerTokenBytecode: string;
45
+ };
46
+ export type ResponseBase<T> = {
47
+ response: T;
48
+ };
49
+ export type StatusesResponse = ResponseBase<StatusInfosByOperationId>;
50
+ export type OperationIdsByShardsKeyResponse = ResponseBase<OperationIdsByShardsKey>;
51
+ export type StageProfilingResponse = ResponseBase<ExecutionStagesByOperationId>;
52
+ export type EVMSimulationResponse = ResponseBase<EVMSimulationResults>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetOpType = void 0;
4
+ var AssetOpType;
5
+ (function (AssetOpType) {
6
+ AssetOpType["JettonBurn"] = "JettonBurn";
7
+ AssetOpType["JettonTransfer"] = "JettonTransfer";
8
+ })(AssetOpType || (exports.AssetOpType = AssetOpType = {}));
@@ -0,0 +1,210 @@
1
+ import { SandboxContract } from '@ton/sandbox';
2
+ import type { Address, Contract, OpenedContract } from '@ton/ton';
3
+ import { AbstractProvider, Addressable, Interface, InterfaceAbi } from 'ethers';
4
+ export interface ContractOpener {
5
+ open<T extends Contract>(src: T): OpenedContract<T> | SandboxContract<T>;
6
+ getContractState(address: Address): Promise<{
7
+ balance: bigint;
8
+ state: 'active' | 'uninitialized' | 'frozen';
9
+ code: Buffer | null;
10
+ }>;
11
+ closeConnections?: () => unknown;
12
+ }
13
+ export declare enum SimplifiedStatuses {
14
+ Pending = 0,
15
+ Failed = 1,
16
+ Successful = 2,
17
+ OperationIdNotFound = 3
18
+ }
19
+ export declare enum Network {
20
+ Testnet = "testnet",
21
+ Mainnet = "mainnet"
22
+ }
23
+ export type TACParams = {
24
+ /**
25
+ * Provider for TAC side. Use your own provider for tests or to increase ratelimit
26
+ */
27
+ provider?: AbstractProvider;
28
+ /**
29
+ * Address of TAC settings contract. Use only for tests.
30
+ */
31
+ settingsAddress?: string | Addressable;
32
+ /**
33
+ * ABI of TAC settings contract. Use only for tests.
34
+ */
35
+ settingsABI?: Interface | InterfaceAbi;
36
+ /**
37
+ * ABI of TAC CCL contract. Use only for tests.
38
+ */
39
+ crossChainLayerABI?: Interface | InterfaceAbi;
40
+ /**
41
+ * ABI of TAC CrossChainLayerToken contract. Use only for tests.
42
+ */
43
+ crossChainLayerTokenABI?: Interface | InterfaceAbi;
44
+ /**
45
+ * bytecode of TAC CrossChainLayerToken contract. Use only for tests.
46
+ */
47
+ crossChainLayerTokenBytecode?: string;
48
+ };
49
+ export type TONParams = {
50
+ /**
51
+ * Provider for TON side. Use your own provider for tests or to increase ratelimit
52
+ */
53
+ contractOpener?: ContractOpener;
54
+ /**
55
+ * Address of TON settings contract. Use only for tests.
56
+ */
57
+ settingsAddress?: string;
58
+ };
59
+ export type SDKParams = {
60
+ /**
61
+ * TON CHAIN. For your network use Сustom
62
+ */
63
+ network: Network;
64
+ /**
65
+ * Delay in requests to provider
66
+ */
67
+ delay?: number;
68
+ /**
69
+ * Custom parameters for the TAC blockchain
70
+ */
71
+ TACParams?: TACParams;
72
+ /**
73
+ * Custom parameters for the TON blockchain
74
+ */
75
+ TONParams?: TONParams;
76
+ /**
77
+ * URLs of lite sequencers
78
+ */
79
+ customLiteSequencerEndpoints?: string[];
80
+ };
81
+ export type WithAddress = {
82
+ /**
83
+ * Address of TAC or TON token.
84
+ * Empty if sending native TON coin.
85
+ */
86
+ address?: string;
87
+ };
88
+ export type RawAssetBridgingData = {
89
+ /** Raw format, e.g. 12340000000 (=12.34 tokens if decimals is 9) */
90
+ rawAmount: bigint;
91
+ } & WithAddress;
92
+ export type UserFriendlyAssetBridgingData = {
93
+ /**
94
+ * User friendly format, e.g. 12.34 tokens
95
+ * Specified value will be converted automatically to raw format: 12.34 * (10^decimals).
96
+ * No decimals should be specified.
97
+ */
98
+ amount: number;
99
+ /**
100
+ * Decimals may be specified manually.
101
+ * Otherwise, SDK tries to extract them from chain.
102
+ */
103
+ decimals?: number;
104
+ } & WithAddress;
105
+ export type AssetBridgingData = RawAssetBridgingData | UserFriendlyAssetBridgingData;
106
+ export type UserWalletBalanceExtended = {
107
+ exists: true;
108
+ amount: number;
109
+ rawAmount: bigint;
110
+ decimals: number;
111
+ } | {
112
+ exists: false;
113
+ };
114
+ export type EvmProxyMsg = {
115
+ evmTargetAddress: string;
116
+ methodName?: string;
117
+ encodedParameters?: string;
118
+ gasLimit?: bigint;
119
+ };
120
+ export type TransactionLinker = {
121
+ caller: string;
122
+ shardCount: number;
123
+ shardsKey: string;
124
+ timestamp: number;
125
+ sendTransactionResult?: unknown;
126
+ };
127
+ export type EVMSimulationRequest = {
128
+ evmCallParams: {
129
+ arguments: string;
130
+ methodName: string;
131
+ target: string;
132
+ };
133
+ extraData: string;
134
+ feeAssetAddress: string;
135
+ shardsKey: number;
136
+ tvmAssets: {
137
+ amount: string;
138
+ tokenAddress: string;
139
+ }[];
140
+ tvmCaller: string;
141
+ };
142
+ export type TransactionData = {
143
+ hash: string;
144
+ };
145
+ export type NoteInfo = {
146
+ content: string;
147
+ errorName: string;
148
+ internalMsg: string;
149
+ internalBytesError: string;
150
+ };
151
+ export type StageData = {
152
+ success: boolean;
153
+ timestamp: number;
154
+ transactions: TransactionData[] | null;
155
+ note: NoteInfo | null;
156
+ };
157
+ export type StatusInfo = StageData & {
158
+ stage: string;
159
+ };
160
+ export type ProfilingStageData = {
161
+ exists: boolean;
162
+ stageData: StageData | null;
163
+ };
164
+ export type ExecutionStages = {
165
+ evmMerkleMsgCollected: ProfilingStageData;
166
+ evmMerkleRootSet: ProfilingStageData;
167
+ evmMerkleMsgExecuted: ProfilingStageData;
168
+ tvmMerkleMsgCollected: ProfilingStageData;
169
+ tvmMerkleMsgExecuted: ProfilingStageData;
170
+ };
171
+ export type ExecutionStagesByOperationId = Record<string, ExecutionStages>;
172
+ export type StatusInfosByOperationId = Record<string, StatusInfo>;
173
+ export type OperationIds = {
174
+ operationIds: string[];
175
+ };
176
+ export type OperationIdsByShardsKey = Record<string, OperationIds>;
177
+ export type EVMSimulationResults = {
178
+ estimatedGas: bigint;
179
+ estimatedJettonFeeAmount: string;
180
+ feeParams: {
181
+ currentBaseFee: string;
182
+ isEip1559: boolean;
183
+ suggestedGasPrice: string;
184
+ suggestedGasTip: string;
185
+ };
186
+ message: string;
187
+ outMessages: {
188
+ callerAddress: string;
189
+ operationId: string;
190
+ payload: string;
191
+ queryId: number;
192
+ targetAddress: string;
193
+ tokensBurned: {
194
+ amount: string;
195
+ tokenAddress: string;
196
+ }[];
197
+ tokensLocked: {
198
+ amount: string;
199
+ tokenAddress: string;
200
+ }[];
201
+ }[] | null;
202
+ simulationError: string;
203
+ simulationStatus: boolean;
204
+ debugInfo: {
205
+ from: string;
206
+ to: string;
207
+ callData: string;
208
+ blockNumber: number;
209
+ };
210
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Network = exports.SimplifiedStatuses = void 0;
4
+ var SimplifiedStatuses;
5
+ (function (SimplifiedStatuses) {
6
+ SimplifiedStatuses[SimplifiedStatuses["Pending"] = 0] = "Pending";
7
+ SimplifiedStatuses[SimplifiedStatuses["Failed"] = 1] = "Failed";
8
+ SimplifiedStatuses[SimplifiedStatuses["Successful"] = 2] = "Successful";
9
+ SimplifiedStatuses[SimplifiedStatuses["OperationIdNotFound"] = 3] = "OperationIdNotFound";
10
+ })(SimplifiedStatuses || (exports.SimplifiedStatuses = SimplifiedStatuses = {}));
11
+ var Network;
12
+ (function (Network) {
13
+ Network["Testnet"] = "testnet";
14
+ Network["Mainnet"] = "mainnet";
15
+ })(Network || (exports.Network = Network = {}));
@@ -0,0 +1,25 @@
1
+ import { Cell } from '@ton/ton';
2
+ export declare const ONCHAIN_CONTENT_PREFIX = 0;
3
+ export declare const OFFCHAIN_CONTENT_PREFIX = 1;
4
+ export interface JettonMetadata {
5
+ uri?: string;
6
+ name: string;
7
+ description: string;
8
+ image?: string;
9
+ image_data?: string;
10
+ symbol: string;
11
+ decimals?: string;
12
+ }
13
+ export type JettonExtendedMetadata = {
14
+ persistenceType: persistenceType;
15
+ metadata: {
16
+ [s in JettonMetaDataKeys]?: string;
17
+ };
18
+ isJettonDeployerFaultyOnChainData?: boolean;
19
+ contentUri?: string;
20
+ };
21
+ export declare function buildJettonOffChainMetadata(contentUri: string): Cell;
22
+ export type JettonMetaDataKeys = 'uri' | 'name' | 'description' | 'image' | 'symbol' | 'image_data' | 'decimals';
23
+ export declare function buildJettonOnchainMetadata(data: JettonMetadata): Cell;
24
+ export type persistenceType = 'none' | 'onchain' | 'offchain_private_domain' | 'offchain_ipfs';
25
+ export declare function readJettonMetadata(contentCell: Cell): Promise<JettonExtendedMetadata>;
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ // noinspection TypeScriptValidateTypes
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.OFFCHAIN_CONTENT_PREFIX = exports.ONCHAIN_CONTENT_PREFIX = void 0;
8
+ exports.buildJettonOffChainMetadata = buildJettonOffChainMetadata;
9
+ exports.buildJettonOnchainMetadata = buildJettonOnchainMetadata;
10
+ exports.readJettonMetadata = readJettonMetadata;
11
+ const sha256_js_1 = require("@aws-crypto/sha256-js");
12
+ const ton_1 = require("@ton/ton");
13
+ const axios_1 = __importDefault(require("axios"));
14
+ const bn_js_1 = __importDefault(require("bn.js"));
15
+ const errors_1 = require("../errors");
16
+ exports.ONCHAIN_CONTENT_PREFIX = 0x00;
17
+ exports.OFFCHAIN_CONTENT_PREFIX = 0x01;
18
+ const SNAKE_PREFIX = 0x00;
19
+ function buildJettonOffChainMetadata(contentUri) {
20
+ return (0, ton_1.beginCell)().storeInt(exports.OFFCHAIN_CONTENT_PREFIX, 8).storeBuffer(Buffer.from(contentUri, 'ascii')).endCell();
21
+ }
22
+ const jettonOnChainMetadataSpec = {
23
+ uri: 'ascii',
24
+ name: 'utf8',
25
+ description: 'utf8',
26
+ image: 'ascii',
27
+ image_data: 'ascii',
28
+ symbol: 'utf8',
29
+ decimals: 'utf8',
30
+ };
31
+ const sha256 = (str) => {
32
+ const sha = new sha256_js_1.Sha256();
33
+ sha.update(str);
34
+ return Buffer.from(sha.digestSync());
35
+ };
36
+ function storeSnakeContent(content, isFirst) {
37
+ const CELL_MAX_SIZE_BYTES = Math.floor((1023 - 8) / 8);
38
+ const cell = new ton_1.Builder();
39
+ if (isFirst) {
40
+ cell.storeUint(SNAKE_PREFIX, 8);
41
+ }
42
+ cell.storeBuffer(content.subarray(0, CELL_MAX_SIZE_BYTES));
43
+ const remainingContent = content.subarray(CELL_MAX_SIZE_BYTES);
44
+ if (remainingContent.length > 0) {
45
+ cell.storeRef(storeSnakeContent(remainingContent, false));
46
+ }
47
+ return cell.endCell();
48
+ }
49
+ function buildJettonOnchainMetadata(data) {
50
+ const dict = ton_1.Dictionary.empty();
51
+ Object.entries(data).forEach(([k, v]) => {
52
+ if (!jettonOnChainMetadataSpec[k]) {
53
+ throw (0, errors_1.unsupportedKeyError)(k);
54
+ }
55
+ if (!v || v == '' || v == null) {
56
+ return;
57
+ }
58
+ const bufferToStore = Buffer.from(v, jettonOnChainMetadataSpec[k]);
59
+ dict.set(sha256(k), storeSnakeContent(bufferToStore, true));
60
+ });
61
+ return (0, ton_1.beginCell)()
62
+ .storeInt(exports.ONCHAIN_CONTENT_PREFIX, 8)
63
+ .storeDict(dict, ton_1.Dictionary.Keys.Buffer(32), ton_1.Dictionary.Values.Cell())
64
+ .endCell();
65
+ }
66
+ function readSnakeContent(slice, isFirst) {
67
+ if (isFirst && slice.loadUint(8) !== SNAKE_PREFIX) {
68
+ throw errors_1.unsupportedFormatError;
69
+ }
70
+ if (slice.remainingBits % 8 !== 0) {
71
+ throw errors_1.notMultiplyOf8Error;
72
+ }
73
+ let remainingBytes = Buffer.from('');
74
+ if (slice.remainingBits != 0) {
75
+ remainingBytes = slice.loadBuffer(slice.remainingBits / 8);
76
+ }
77
+ if (slice.remainingRefs != 0) {
78
+ const newCell = slice.loadRef();
79
+ remainingBytes = Buffer.concat([remainingBytes, readSnakeContent(newCell.beginParse(), false)]);
80
+ }
81
+ return remainingBytes;
82
+ }
83
+ function parseJettonOnchainMetadata(contentSlice) {
84
+ // Note that this relies on what is (perhaps) an internal implementation detail:
85
+ // "sdk" library dict parser converts: key (provided as buffer) => BN(base10)
86
+ // and upon parsing, it reads it back to a BN(base10)
87
+ // tl;dr if we want to read the map back to a JSON with string keys, we have to convert BN(10) back to hex
88
+ const toKey = (str) => BigInt(new bn_js_1.default(str, 'hex').toString(10));
89
+ const isJettonDeployerFaultyOnChainData = false;
90
+ const cellDict = contentSlice.loadDict(ton_1.Dictionary.Keys.BigUint(256), ton_1.Dictionary.Values.Cell());
91
+ const dict = new Map();
92
+ cellDict.values().forEach((item, index) => {
93
+ dict.set(cellDict.keys()[index], readSnakeContent(item.beginParse(), true));
94
+ });
95
+ const res = {};
96
+ Object.keys(jettonOnChainMetadataSpec).forEach((k) => {
97
+ const val = dict
98
+ .get(toKey(sha256(k).toString('hex')))
99
+ ?.toString(jettonOnChainMetadataSpec[k]);
100
+ if (val) {
101
+ res[k] = val;
102
+ }
103
+ });
104
+ return {
105
+ metadata: res,
106
+ isJettonDeployerFaultyOnChainData,
107
+ };
108
+ }
109
+ async function parseJettonOffchainMetadata(contentSlice) {
110
+ const remainingBits = contentSlice.remainingBits;
111
+ if (remainingBits % 8 !== 0) {
112
+ throw errors_1.notMultiplyOf8Error;
113
+ }
114
+ const jsonURI = contentSlice
115
+ .loadBuffer(remainingBits / 8)
116
+ .toString('ascii')
117
+ .replace('ipfs://', 'https://ipfs.io/ipfs/');
118
+ let metadata = null;
119
+ let isIpfs = null;
120
+ try {
121
+ metadata = (await axios_1.default.get(jsonURI)).data;
122
+ isIpfs = /(^|\/)ipfs[.:]/.test(jsonURI);
123
+ }
124
+ catch {
125
+ // nothing
126
+ }
127
+ return {
128
+ metadata,
129
+ isIpfs,
130
+ contentUri: jsonURI,
131
+ };
132
+ }
133
+ async function readJettonMetadata(contentCell) {
134
+ if (contentCell.bits.length <= 0) {
135
+ return {
136
+ contentUri: undefined,
137
+ isJettonDeployerFaultyOnChainData: false,
138
+ metadata: {},
139
+ persistenceType: 'none',
140
+ };
141
+ }
142
+ const contentSlice = contentCell.beginParse();
143
+ switch (contentSlice.loadUint(8)) {
144
+ case exports.ONCHAIN_CONTENT_PREFIX:
145
+ return {
146
+ persistenceType: 'onchain',
147
+ ...parseJettonOnchainMetadata(contentSlice),
148
+ };
149
+ case exports.OFFCHAIN_CONTENT_PREFIX: {
150
+ const { metadata, isIpfs, contentUri } = await parseJettonOffchainMetadata(contentSlice);
151
+ return {
152
+ persistenceType: isIpfs ? 'offchain_ipfs' : 'offchain_private_domain',
153
+ contentUri,
154
+ metadata,
155
+ };
156
+ }
157
+ default:
158
+ throw errors_1.prefixError;
159
+ }
160
+ }
@@ -0,0 +1,17 @@
1
+ export declare class HighloadQueryId {
2
+ private shift;
3
+ private bitnumber;
4
+ constructor();
5
+ static fromShiftAndBitNumber(shift: bigint, bitnumber: bigint): HighloadQueryId;
6
+ getNext(): HighloadQueryId;
7
+ hasNext(): boolean;
8
+ getShift(): bigint;
9
+ getBitNumber(): bigint;
10
+ getQueryId(): bigint;
11
+ static fromQueryId(queryId: bigint): HighloadQueryId;
12
+ static fromSeqno(i: bigint): HighloadQueryId;
13
+ /**
14
+ * @return {bigint} [0 .. 8380415]
15
+ */
16
+ toSeqno(): bigint;
17
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HighloadQueryId = void 0;
4
+ const BIT_NUMBER_SIZE = 10n; // 10 bit
5
+ const SHIFT_SIZE = 13n; // 13 bit
6
+ const MAX_BIT_NUMBER = 1022n;
7
+ const MAX_SHIFT = 8191n; // 2^13 = 8192
8
+ class HighloadQueryId {
9
+ constructor() {
10
+ this.shift = 0n;
11
+ this.bitnumber = 0n;
12
+ }
13
+ static fromShiftAndBitNumber(shift, bitnumber) {
14
+ const q = new HighloadQueryId();
15
+ q.shift = shift;
16
+ if (q.shift < 0)
17
+ throw new Error('invalid shift');
18
+ if (q.shift > MAX_SHIFT)
19
+ throw new Error('invalid shift');
20
+ q.bitnumber = bitnumber;
21
+ if (q.bitnumber < 0)
22
+ throw new Error('invalid bitnumber');
23
+ if (q.bitnumber > MAX_BIT_NUMBER)
24
+ throw new Error('invalid bitnumber');
25
+ return q;
26
+ }
27
+ getNext() {
28
+ let newBitnumber = this.bitnumber + 1n;
29
+ let newShift = this.shift;
30
+ if (newShift === MAX_SHIFT && newBitnumber > MAX_BIT_NUMBER - 1n) {
31
+ throw new Error('Overload'); // NOTE: we left one queryId for emergency withdraw
32
+ }
33
+ if (newBitnumber > MAX_BIT_NUMBER) {
34
+ newBitnumber = 0n;
35
+ newShift += 1n;
36
+ if (newShift > MAX_SHIFT) {
37
+ throw new Error('Overload');
38
+ }
39
+ }
40
+ return HighloadQueryId.fromShiftAndBitNumber(newShift, newBitnumber);
41
+ }
42
+ hasNext() {
43
+ const isEnd = this.bitnumber >= MAX_BIT_NUMBER - 1n && this.shift === MAX_SHIFT; // NOTE: we left one queryId for emergency withdraw;
44
+ return !isEnd;
45
+ }
46
+ getShift() {
47
+ return this.shift;
48
+ }
49
+ getBitNumber() {
50
+ return this.bitnumber;
51
+ }
52
+ getQueryId() {
53
+ return (this.shift << BIT_NUMBER_SIZE) + this.bitnumber;
54
+ }
55
+ static fromQueryId(queryId) {
56
+ const shift = queryId >> BIT_NUMBER_SIZE;
57
+ const bitnumber = queryId & 1023n;
58
+ return this.fromShiftAndBitNumber(shift, bitnumber);
59
+ }
60
+ static fromSeqno(i) {
61
+ const shift = i / 1023n;
62
+ const bitnumber = i % 1023n;
63
+ return this.fromShiftAndBitNumber(shift, bitnumber);
64
+ }
65
+ /**
66
+ * @return {bigint} [0 .. 8380415]
67
+ */
68
+ toSeqno() {
69
+ return this.bitnumber + this.shift * 1023n;
70
+ }
71
+ }
72
+ exports.HighloadQueryId = HighloadQueryId;