@anywalletkit/wallet-ton 0.0.0-stage → 0.2.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.
@@ -0,0 +1,704 @@
1
+ import { Cell, StateInit, TupleReader, Address, TupleItem, Transaction, MessageRelaxed } from '@ton/core';
2
+ import { SignerError, IWalletAccountReadOnly, IWalletAccount, Signer, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
3
+ export { HistoryFetch, HistoryUnavailableError, TonChainTx, TonHistoryBackend, TonHistoryCursor, TonHistoryOptions, TonHistoryPage, TonHistoryRaw, TonHistorySource, TonapiAction, TonapiEvent, V3Transaction, createTonHistory, decodeCursor as decodeHistoryCursor, encodeCursor as encodeHistoryCursor, mapActions as mapTonapiActions, mapTonapiEvent, mapToncenterTransaction, rawTonAddress, tonExplorerTxUrl, valueFlowTransfers } from './history.js';
4
+
5
+ /**
6
+ * Set `globalThis.Buffer` to the `buffer` polyfill when the runtime has none (Hermes, browsers).
7
+ * Runs on import.
8
+ */
9
+ declare function installBufferGlobal(): void;
10
+
11
+ /** A toncenter v2 JSON-RPC endpoint (api keys there are meant for client-side wallets). */
12
+ interface TonEndpoint {
13
+ url: string;
14
+ secretKey?: string;
15
+ }
16
+ /** Anything that can answer a toncenter v2 JSON-RPC call (an endpoint wrapper, a test double, a proxy). */
17
+ interface TonRpc {
18
+ call<T = unknown>(method: string, params: Record<string, unknown>): Promise<T>;
19
+ }
20
+ /** A toncenter endpoint (URL and optional key) or a ready `TonRpc`. */
21
+ type TonProvider = TonEndpoint | TonRpc;
22
+ /**
23
+ * Options for a TON wallet manager or account: toncenter endpoints, network, fee caps and emulation
24
+ * before signing.
25
+ */
26
+ interface TonConfig {
27
+ /** toncenter endpoint(s) or `TonRpc`(s). A list fails over in order. Omit for an offline (sign-only) wallet. */
28
+ tonClient?: TonProvider | TonProvider[];
29
+ /** Alias of `tonClient`. */
30
+ provider?: TonProvider | TonProvider[];
31
+ /** Extra rounds across the endpoint list after the first full pass (default 3). */
32
+ retries?: number;
33
+ /** Per-request timeout in ms (default 15 000). */
34
+ timeoutMs?: number;
35
+ /** Injectable fetch (tests, custom agents). Defaults to globalThis.fetch. */
36
+ fetch?: typeof fetch;
37
+ /** Max fee (nanotons) for `transfer`. */
38
+ transferMaxFee?: bigint | number;
39
+ /** Max fee (nanotons) for `sendTransaction` / `signTransaction`. */
40
+ transactionMaxFee?: bigint | number;
41
+ /** toncenter v3 base used for receipts (default https://toncenter.com/api/v3). */
42
+ indexerUrl?: string;
43
+ /** tonapi base used for fee rates and (by default) emulation (default https://tonapi.io/v2). */
44
+ tonApiUrl?: string;
45
+ /** tonapi bearer key (sent as `Authorization: Bearer …`); also sent as X-API-Key to a toncenter-v3 emulator. */
46
+ tonApiKey?: string;
47
+ /**
48
+ * Preflight emulation of every send (zero-signed external). Default
49
+ * `{kind: 'tonapi'}`: `POST {tonApiUrl}/wallet/emulate` (verdict + `risk`),
50
+ * falling back to `/traces/emulate`. `{kind: 'toncenter-v3', url}` posts to a
51
+ * toncenter `emulateTrace` endpoint instead. `false` = `estimateFee` only.
52
+ * A non-zero compute exit, an aborted transaction, a failed action phase or a
53
+ * failed FIRST-HOP internal message throws `SimulationError` before signing.
54
+ */
55
+ emulate?: TonEmulateConfig;
56
+ /** @deprecated Use `emulate: {kind: 'toncenter-v3', url}`. Still honoured when `emulate` is unset. */
57
+ emulateUrl?: string;
58
+ /**
59
+ * Allow a body whose emulated `risk.transfer_all_remaining_balance` is true
60
+ * (send mode 128 / CARRY_ALL_BALANCE). Refused by default — nothing this
61
+ * wallet builds does that, so it only ever comes from a foreign `bodyBoc`.
62
+ */
63
+ allowDrainingTransactions?: boolean;
64
+ /** Run the preflight (estimateFee + emulation when configured) before signing. Default true. */
65
+ simulate?: boolean;
66
+ /** Seconds a signed external stays valid (default 60, max 600). */
67
+ validUntilSeconds?: number;
68
+ /** Nanotons attached to a jetton transfer on top of `forwardTonAmount` (default 0.05 TON). */
69
+ jettonAttachedValue?: bigint | number | string;
70
+ /**
71
+ * 'mainnet' (ton:-239, default) or 'testnet' (ton:-3). Sets the CAIP-2 id, the address flags and the
72
+ * wallet_id network (-239 / -3), so a testnet wallet has its own address and its signed messages are
73
+ * not valid on mainnet (as in Tonkeeper and @ton/ton).
74
+ */
75
+ network?: 'mainnet' | 'testnet';
76
+ /**
77
+ * V5R1 wallet_id parts. Defaults (network id from `network`, subwallet 0) give the
78
+ * addresses Tonkeeper and Tonhub derive for a key; change the subwallet only to
79
+ * reach a wallet that was created with a different one. A networkGlobalId that
80
+ * contradicts `network` is refused.
81
+ */
82
+ walletId?: {
83
+ networkGlobalId?: number;
84
+ subwalletNumber?: number;
85
+ };
86
+ }
87
+ /** One internal message. `value` in nanotons. `body`: text comment or a Cell; `bodyBoc`: the same as base64 BoC. */
88
+ interface TonTransaction {
89
+ to: string;
90
+ value: bigint | number | string;
91
+ /** Defaults to the flag in a friendly address (EQ… bounceable, UQ… not); raw addresses default to bounceable. */
92
+ bounceable?: boolean;
93
+ body?: string | Cell;
94
+ /** Prebuilt message body as base64 BoC (e.g. an Omniston escrow payload). Ignored when `body` is set. */
95
+ bodyBoc?: string;
96
+ /** StateInit to attach (deploys the destination): `{code, data}`, a StateInit cell, or its base64 BoC. */
97
+ stateInit?: StateInit | Cell | string;
98
+ /** Send mode for this message (default PAY_GAS_SEPARATELY; IGNORE_ERRORS is always OR-ed in for externals). */
99
+ sendMode?: number;
100
+ }
101
+ /**
102
+ * What `sendTransaction` / `signTransaction` accept: one message, several
103
+ * messages in ONE external (up to 255 — swaps need it), or an already signed
104
+ * V5R1 external-message body Cell.
105
+ */
106
+ type TonSendable = TonTransaction | TonTransaction[] | Cell;
107
+ /** A native TON or jetton transfer. Amount in nanotons or the jetton's base units. */
108
+ interface TonTransferOptions {
109
+ /** Jetton master address. Omit for native TON. */
110
+ token?: string;
111
+ /** Wallet address that receives (for a jetton, its owner, not its jetton wallet). */
112
+ recipient: string;
113
+ amount: bigint | number | string;
114
+ /** Jetton only: nanotons forwarded to the recipient with the transfer notification (default 1). */
115
+ forwardTonAmount?: bigint | number | string;
116
+ /** Jetton only: forward payload — a text comment or a Cell (DEX / escrow payloads). */
117
+ forwardPayload?: Cell | string;
118
+ /**
119
+ * Text memo (a deposit memo, an exchange tag). Jetton: sent as the forward-payload comment (TEP-74);
120
+ * native TON: the message comment. Cannot be combined with `forwardPayload`.
121
+ */
122
+ memo?: string;
123
+ /** Jetton only: custom payload cell (rarely needed; e.g. mintless jettons). */
124
+ customPayload?: Cell;
125
+ /** Jetton only: where excess TON returns (default: this wallet). */
126
+ responseDestination?: string;
127
+ /** Jetton only: query id (default random). */
128
+ queryId?: bigint | number;
129
+ /** Jetton only: nanotons attached to the jetton-wallet call (default config.jettonAttachedValue + forwardTonAmount). */
130
+ attachedValue?: bigint | number | string;
131
+ }
132
+ /** toncenter `estimateFee` source fees, nanotons. */
133
+ interface TonFees {
134
+ inFwdFee: bigint;
135
+ storageFee: bigint;
136
+ gasFee: bigint;
137
+ fwdFee: bigint;
138
+ /** Sum of the four. */
139
+ total: bigint;
140
+ }
141
+ /**
142
+ * Where to emulate a transaction before signing: tonapi, a toncenter v3 endpoint, or `false` for a
143
+ * fee estimate only.
144
+ */
145
+ type TonEmulateConfig = {
146
+ kind: 'tonapi';
147
+ url?: string;
148
+ } | {
149
+ kind: 'toncenter-v3';
150
+ url: string;
151
+ } | false;
152
+ /** What a message would move out of the wallet, per tonapi's `risk`. */
153
+ interface TonRisk {
154
+ /** Nanotons leaving the wallet (value + fees the emulator attributes). */
155
+ ton: bigint;
156
+ jettons: Array<{
157
+ address: string;
158
+ walletAddress: string;
159
+ amount: bigint;
160
+ symbol?: string;
161
+ decimals?: number;
162
+ }>;
163
+ /** Send mode 128: the whole remaining balance goes with the message. */
164
+ transferAllRemainingBalance: boolean;
165
+ }
166
+ /**
167
+ * Which service produced a simulation; `estimate-only` means fees were estimated without emulation.
168
+ */
169
+ type TonSimulationSource = 'tonapi' | 'toncenter-v3' | 'estimate-only';
170
+ /**
171
+ * Outcome of a simulation: the fees and, when emulated, whether the wallet transaction and its
172
+ * actions succeeded.
173
+ */
174
+ type TonSimulation = {
175
+ ok: true;
176
+ fees: TonFees;
177
+ emulated: boolean;
178
+ source: TonSimulationSource;
179
+ exitCode?: number;
180
+ actionSuccess?: boolean;
181
+ risk?: TonRisk;
182
+ warnings: string[];
183
+ } | {
184
+ ok: false;
185
+ fees?: TonFees;
186
+ emulated: true;
187
+ source: Exclude<TonSimulationSource, 'estimate-only'>;
188
+ reason: string;
189
+ exitCode?: number;
190
+ aborted?: boolean;
191
+ risk?: TonRisk;
192
+ warnings: string[];
193
+ };
194
+ /** Outcome of a sent wallet transaction, found by the body hash `sendTransaction` returned. */
195
+ interface TonReceipt {
196
+ /** The body hash that was returned by sendTransaction. */
197
+ hash: string;
198
+ /** 1 when the wallet transaction completed without abort, 0 otherwise. */
199
+ status: 0 | 1;
200
+ /** Logical time of the account transaction. */
201
+ blockNumber: bigint;
202
+ /** Account transaction hash (base64). */
203
+ transactionHash: string;
204
+ /** Fees of the account transaction, in nanotons. */
205
+ totalFees: bigint;
206
+ /** The raw @ton/core Transaction. */
207
+ raw: unknown;
208
+ }
209
+ /** CAIP-2 ids of TON mainnet and testnet. */
210
+ declare const CAIP2: Record<'mainnet' | 'testnet', string>;
211
+
212
+ /**
213
+ * Refused before signing: the message would almost certainly misbehave or
214
+ * strand funds (zero value, wrong network flag, exotic workchain, a
215
+ * `valid_until` further away than the wallet contract tolerates…).
216
+ */
217
+ declare class UnsafeTransactionError extends SignerError {
218
+ readonly code: string;
219
+ constructor(code: string, message: string);
220
+ }
221
+ /** Emulation of the external message failed (non-zero compute exit, aborted, action phase failed); nothing was signed or sent. */
222
+ declare class SimulationError extends Error {
223
+ readonly exitCode: number | undefined;
224
+ readonly aborted: boolean;
225
+ constructor(reason: string, details?: {
226
+ exitCode?: number;
227
+ aborted?: boolean;
228
+ });
229
+ }
230
+
231
+ /** JSON-RPC over one toncenter v2 endpoint. */
232
+ declare function tonCenterEndpoint(endpoint: TonEndpoint, opts?: {
233
+ fetch?: typeof fetch;
234
+ timeoutMs?: number;
235
+ }): TonRpc;
236
+ /** One RPC, or a failover RPC walking the configured list (`retries` extra rounds after the first full pass). */
237
+ declare function createTonRpc(config: TonConfig): TonRpc | undefined;
238
+ /** State of a TON account on chain. */
239
+ type TonAccountStatus = 'active' | 'uninitialized' | 'frozen' | 'nonexist';
240
+ /** Balance, status, code and data of an account. */
241
+ interface TonAccountState {
242
+ balance: bigint;
243
+ state: TonAccountStatus;
244
+ code: Cell | null;
245
+ data: Cell | null;
246
+ lastTransaction: {
247
+ lt: string;
248
+ hash: string;
249
+ } | null;
250
+ }
251
+ /** Result of a contract get-method call. */
252
+ interface GetMethodResult {
253
+ exitCode: number;
254
+ gasUsed: number;
255
+ stack: TupleReader;
256
+ }
257
+ /** The toncenter calls a wallet uses, with parsed results. */
258
+ declare class TonCenter {
259
+ readonly rpc: TonRpc;
260
+ constructor(rpc: TonRpc);
261
+ /** Balance, status, code and data of an account. */
262
+ getAddressInformation(address: Address): Promise<TonAccountState>;
263
+ /** Call a contract get-method; the result carries the exit code. */
264
+ runGetMethod(address: Address, method: string, stack?: TupleItem[]): Promise<GetMethodResult>;
265
+ /** Like runGetMethod but throws on a non-zero exit code. */
266
+ runGetMethodOk(address: Address, method: string, stack?: TupleItem[]): Promise<GetMethodResult>;
267
+ /** Broadcast a signed external message. */
268
+ sendBoc(message: Cell): Promise<void>;
269
+ /** Broadcast and return the external-message hash (base64) toncenter reports. */
270
+ sendBocReturnHash(message: Cell): Promise<string>;
271
+ getTransactions(address: Address, opts: {
272
+ limit: number;
273
+ lt?: string;
274
+ hash?: string;
275
+ archival?: boolean;
276
+ }): Promise<Transaction[]>;
277
+ estimateFee(address: Address, args: {
278
+ body: Cell;
279
+ init?: StateInit;
280
+ ignoreSignature?: boolean;
281
+ }): Promise<TonFees>;
282
+ }
283
+ /**
284
+ * Whether an emulated wallet transaction succeeded: compute exit code, abort flag, action phase.
285
+ */
286
+ interface EmulationVerdict {
287
+ ok: boolean;
288
+ exitCode?: number;
289
+ aborted?: boolean;
290
+ actionSuccess?: boolean;
291
+ reason?: string;
292
+ }
293
+ /**
294
+ * Reduce an `emulateTrace` response to a verdict for the ROOT transaction (the
295
+ * wallet's own): compute-phase exit code, aborted flag, action-phase success.
296
+ * Tolerant of the field spellings the v3 API has used (`description.compute_ph`
297
+ * / `compute`, `action.success`); anything unrecognisable is a NetworkError, not
298
+ * a silent pass.
299
+ */
300
+ declare function parseEmulation(json: unknown): EmulationVerdict;
301
+ /** POST the external message to a toncenter v3 emulation endpoint and reduce the trace. */
302
+ declare function emulateExternal(url: string, message: Cell, opts?: {
303
+ fetch?: typeof fetch;
304
+ timeoutMs?: number;
305
+ apiKey?: string;
306
+ }): Promise<EmulationVerdict>;
307
+
308
+ /**
309
+ * Preflight emulation of a zero-signed external through tonapi
310
+ * (`POST /v2/wallet/emulate`, fallback `POST /v2/traces/emulate`) or a
311
+ * toncenter v3 `emulateTrace` endpoint. The verdict decides whether the
312
+ * account signs at all; `risk` (tonapi only) summarises what would leave the
313
+ * wallet so a foreign body cannot quietly drain it.
314
+ *
315
+ * tonapi shapes used (OpenAPI v2):
316
+ * MessageConsequences = { trace: Trace, event: AccountEvent, risk: Risk }
317
+ * Trace = { transaction: Transaction, interfaces: string[], children?: Trace[], emulated?: boolean }
318
+ * Transaction.compute_phase = { skipped, skip_reason?, success?, exit_code?, exit_code_description? }
319
+ * Transaction.action_phase = { success, result_code, … }
320
+ * Transaction.{ success, aborted, bounce_phase? }
321
+ * Risk = { transfer_all_remaining_balance, ton, jettons: [{ quantity, wallet_address: { address }, jetton: { address, symbol, decimals } }], nfts }
322
+ */
323
+
324
+ /** Default tonapi root used for emulation. */
325
+ declare const DEFAULT_TONAPI = "https://tonapi.io/v2";
326
+ /** Service an emulation came from. */
327
+ type EmulationSource = 'tonapi' | 'toncenter-v3';
328
+ /** An emulation verdict with its source and any deeper failures. */
329
+ interface EmulationOutcome extends EmulationVerdict {
330
+ source: EmulationSource;
331
+ /** Failed/bounced transactions deeper than the first hop — informational. */
332
+ warnings: string[];
333
+ /** tonapi `risk`: what the message would move out of the wallet. */
334
+ risk?: TonRisk;
335
+ }
336
+ /**
337
+ * Reduce a tonapi `Trace` to a verdict. The root (the wallet's own transaction)
338
+ * decides: compute exit ≠ 0, aborted or a failed action phase → not ok. A
339
+ * failing FIRST-HOP child is also fatal: for every message this wallet builds
340
+ * (TON to a contract, jetton transfer to its own jetton wallet) a bounced
341
+ * first hop means the operation did not happen and the value comes back minus
342
+ * fees. Deeper failures (e.g. a jetton notify the recipient's wallet rejects)
343
+ * become warnings — the transfer itself already settled.
344
+ */
345
+ declare function parseTonapiTrace(trace: unknown): Omit<EmulationOutcome, 'source' | 'risk'>;
346
+ /** tonapi `Risk` → nanotons / jetton base units as bigints. Malformed → NetworkError. */
347
+ declare function parseTonapiRisk(risk: unknown): TonRisk;
348
+ /** tonapi `MessageConsequences` (wallet/emulate) → outcome with risk. */
349
+ declare function parseTonapiConsequences(json: unknown): EmulationOutcome;
350
+ /** Options for emulating a message through tonapi or toncenter v3. */
351
+ interface EmulateOptions {
352
+ fetch?: typeof fetch;
353
+ timeoutMs?: number;
354
+ /** tonapi bearer key / toncenter X-API-Key. */
355
+ apiKey?: string;
356
+ }
357
+ /**
358
+ * Emulate through tonapi: `/wallet/emulate` first (verdict + risk), then
359
+ * `/traces/emulate` when the first is not served (404). The external carries a
360
+ * zero signature; `ignore_signature_check=true` is sent on both calls.
361
+ */
362
+ declare function emulateViaTonapi(baseUrl: string, message: Cell, opts?: EmulateOptions): Promise<EmulationOutcome>;
363
+ /** Resolve the effective emulation config: explicit `emulate`, legacy `emulateUrl`, else tonapi by default. */
364
+ declare function resolveEmulate(config: {
365
+ emulate?: TonEmulateConfig;
366
+ emulateUrl?: string;
367
+ tonApiUrl?: string;
368
+ }): Exclude<TonEmulateConfig, false> | false;
369
+ /** Run the configured emulation for an external message. */
370
+ declare function runEmulation(config: {
371
+ emulate?: TonEmulateConfig;
372
+ emulateUrl?: string;
373
+ tonApiUrl?: string;
374
+ tonApiKey?: string;
375
+ fetch?: typeof fetch;
376
+ timeoutMs?: number;
377
+ }, message: Cell): Promise<EmulationOutcome | undefined>;
378
+
379
+ /** Code of the Wallet V5R1 contract (BoC hex). */
380
+ declare const V5R1_CODE_HEX = "b5ee9c7241021401000281000114ff00f4a413f4bcf2c80b01020120020d020148030402dcd020d749c120915b8f6320d70b1f2082106578746ebd21821073696e74bdb0925f03e082106578746eba8eb48020d72101d074d721fa4030fa44f828fa443058bd915be0ed44d0810141d721f4058307f40e6fa1319130e18040d721707fdb3ce03120d749810280b99130e070e2100f020120050c020120060902016e07080019adce76a2684020eb90eb85ffc00019af1df6a2684010eb90eb858fc00201480a0b0017b325fb51341c75c875c2c7e00011b262fb513435c280200019be5f0f6a2684080a0eb90fa02c0102f20e011e20d70b1f82107369676ebaf2e08a7f0f01e68ef0eda2edfb218308d722028308d723208020d721d31fd31fd31fed44d0d200d31f20d31fd3ffd70a000af90140ccf9109a28945f0adb31e1f2c087df02b35007b0f2d0845125baf2e0855036baf2e086f823bbf2d0882292f800de01a47fc8ca00cb1f01cf16c9ed542092f80fde70db3cd81003f6eda2edfb02f404216e926c218e4c0221d73930709421c700b38e2d01d72820761e436c20d749c008f2e09320d74ac002f2e09320d71d06c712c2005230b0f2d089d74cd7393001a4e86c128407bbf2e093d74ac000f2e093ed55e2d20001c000915be0ebd72c08142091709601d72c081c12e25210b1e30f20d74a111213009601fa4001fa44f828fa443058baf2e091ed44d0810141d718f405049d7fc8ca0040048307f453f2e08b8e14038307f45bf2e08c22d70a00216e01b3b0f2d090e2c85003cf1612f400c9ed54007230d72c08248e2d21f2e092d200ed44d0d2005113baf2d08f54503091319c01810140d721d70a00f2e08ee2c8ca0058cf16c9ed5493f2c08de20010935bdb31e1d74cd0b4d6c35e";
381
+ /** The V5R1 contract code cell (parsed once). */
382
+ declare function v5r1Code(): Cell;
383
+ /** Op codes of Wallet V5R1 messages. */
384
+ declare const V5R1_OP: {
385
+ readonly signedExternal: 1936287598;
386
+ readonly signedInternal: 1936289396;
387
+ readonly extension: 1702392942;
388
+ };
389
+ /** Global id of TON mainnet, part of the V5R1 wallet id. */
390
+ declare const MAINNET_GLOBAL_ID = -239;
391
+ /** Global id of TON testnet. */
392
+ declare const TESTNET_GLOBAL_ID = -3;
393
+ /** PAY_GAS_SEPARATELY | IGNORE_ERRORS — the mode every external-message action carries. */
394
+ declare const DEFAULT_SEND_MODE: number;
395
+ /** Most outgoing messages one V5R1 transaction can carry. */
396
+ declare const MAX_ACTIONS = 255;
397
+ interface V5R1WalletIdParts {
398
+ networkGlobalId?: number;
399
+ workchain?: number;
400
+ subwalletNumber?: number;
401
+ }
402
+ /**
403
+ * Serialized wallet_id (int32): `networkGlobalId XOR context`, where the client
404
+ * context is {1 bit "client", int8 workchain, uint8 version (0 = v5r1), uint15 subwallet}.
405
+ */
406
+ declare function v5r1WalletId(parts?: V5R1WalletIdParts): bigint;
407
+ /** State init (code and data) of a V5R1 wallet for a public key. */
408
+ declare function v5r1StateInit(publicKey: Uint8Array, walletId?: bigint): StateInit;
409
+ /** Address of the V5R1 wallet for a public key. */
410
+ declare function v5r1Address(publicKey: Uint8Array, opts?: {
411
+ workchain?: number;
412
+ walletId?: bigint;
413
+ }): Address;
414
+ interface V5R1Message {
415
+ message: MessageRelaxed;
416
+ mode?: number;
417
+ }
418
+ interface V5R1SigningParams {
419
+ walletId: bigint;
420
+ /** Unix seconds. */
421
+ validUntil: number;
422
+ seqno: number;
423
+ messages: V5R1Message[];
424
+ }
425
+ /** The cell that gets hashed and signed: op | wallet_id | valid_until | seqno | out-list ref | no extended actions. */
426
+ declare function v5r1SigningMessage(p: V5R1SigningParams): Cell;
427
+ /** Signature goes at the tail (V5R1 layout). */
428
+ declare function v5r1PackSigned(signing: Cell, signature: Uint8Array): Cell;
429
+ /** Same body with a zero signature — what `estimateFee(ignore_chksig)` and emulation take. */
430
+ declare function v5r1PackUnsigned(signing: Cell): Cell;
431
+ /** The external-in message (as a cell, ready for sendBoc) carrying `body` to the wallet, with `init` when it is not deployed yet. */
432
+ declare function v5r1ExternalMessage(to: Address, body: Cell, init?: StateInit): Cell;
433
+ interface ParsedV5R1Body {
434
+ op: number;
435
+ walletId: bigint;
436
+ validUntil: number;
437
+ seqno: number;
438
+ messages: Array<{
439
+ message: MessageRelaxed;
440
+ mode: number;
441
+ }>;
442
+ /** True when the 64-byte tail signature is present (externals and internals carry one). */
443
+ signed: boolean;
444
+ }
445
+ /** Parse a signed (or zero-signed) V5R1 external body back into its messages. Returns null for anything else. */
446
+ declare function parseV5R1Body(body: Cell): ParsedV5R1Body | null;
447
+
448
+ /**
449
+ * "What am I signing" for TON — offline. Decodes the messages of a
450
+ * {@link TonSendable} (or a prebuilt V5R1 body) into human-checkable items and
451
+ * flags the classic mistakes before any key is touched.
452
+ */
453
+
454
+ /** TEP-74 `transfer` op code of a jetton wallet. */
455
+ declare const JETTON_TRANSFER_OP = 260734629;
456
+ /** What one outgoing message does. */
457
+ type TonDescribedKind = 'ton-transfer' | 'jetton-transfer' | 'contract-call';
458
+ /** Fields of a TEP-74 jetton `transfer` body. */
459
+ interface TonJettonDetails {
460
+ queryId: bigint;
461
+ amount: bigint;
462
+ destination: string;
463
+ responseDestination: string | null;
464
+ forwardTonAmount: bigint;
465
+ forwardPayload: 'none' | 'comment' | 'cell';
466
+ forwardComment?: string;
467
+ hasCustomPayload: boolean;
468
+ }
469
+ /** One outgoing message of a wallet transaction, decoded. */
470
+ interface TonDescribedMessage {
471
+ kind: TonDescribedKind;
472
+ /** Destination as given (friendly) or raw `wc:hex`. */
473
+ to: string;
474
+ value: bigint;
475
+ bounceable: boolean;
476
+ /** Test-only flag of a friendly address; undefined for raw addresses. */
477
+ testOnly?: boolean;
478
+ /** Text comment (op 0). */
479
+ comment?: string;
480
+ /** Body op code for contract calls (hex). */
481
+ op?: string;
482
+ jetton?: TonJettonDetails;
483
+ hasStateInit: boolean;
484
+ bodyBits: number;
485
+ }
486
+ /** Problems a TON description is flagged with. */
487
+ type TonWarningCode = 'zero-value' | 'non-bounceable-contract-call' | 'unknown-body' | 'large-forward-amount' | 'testnet-address' | 'mainnet-address' | 'exotic-workchain' | 'extended-actions';
488
+ /** One flagged problem; `index` is the message it is about. */
489
+ interface TonWarning {
490
+ code: TonWarningCode;
491
+ message: string;
492
+ index?: number;
493
+ }
494
+ /**
495
+ * A TON wallet transaction decoded for a confirmation screen: each outgoing message and the
496
+ * warnings.
497
+ */
498
+ interface TonDescription {
499
+ kind: TonDescribedKind | 'mixed';
500
+ items: TonDescribedMessage[];
501
+ warnings: TonWarning[];
502
+ /** Present when the input was a prebuilt V5R1 body. */
503
+ external?: {
504
+ seqno: number;
505
+ validUntil: number;
506
+ walletId: bigint;
507
+ signed: boolean;
508
+ };
509
+ }
510
+ /** A message body decoded: empty, a text comment, a jetton transfer, or unknown. */
511
+ type DecodedBody = {
512
+ type: 'empty';
513
+ } | {
514
+ type: 'comment';
515
+ text: string;
516
+ } | {
517
+ type: 'jetton-transfer';
518
+ jetton: TonJettonDetails;
519
+ } | {
520
+ type: 'op';
521
+ op: number;
522
+ } | {
523
+ type: 'unknown';
524
+ };
525
+ /** Decode a message body cell. */
526
+ declare function decodeBody(body: Cell): DecodedBody;
527
+ /** A text comment body (op 0 plus the text), as wallets show it. */
528
+ declare function commentCell(text: string): Cell;
529
+ /** Describe one outgoing message and push its warnings into `warnings`. */
530
+ declare function describeMessageRelaxed(i: number, m: MessageRelaxed, warnings: TonWarning[], ctx?: {
531
+ network?: 'mainnet' | 'testnet';
532
+ }): TonDescribedMessage;
533
+ /** Describe what a {@link TonSendable} will do. Offline; never throws on malformed bodies (they become warnings). */
534
+ declare function describeTransaction(tx: TonSendable, ctx?: {
535
+ network?: 'mainnet' | 'testnet';
536
+ }): TonDescription;
537
+
538
+ /** PAY_GAS_SEPARATELY | IGNORE_ERRORS, the mode every action in an external carries. */
539
+ declare const SEND_MODE: number;
540
+ /**
541
+ * A TON V5R1 wallet without a key: balance, jetton balances, seqno, fee estimates, emulation,
542
+ * receipts and signature checks.
543
+ */
544
+ declare class WalletAccountReadOnlyTon implements IWalletAccountReadOnly {
545
+ readonly chain: string;
546
+ /** Ed25519 public key the wallet is derived from. */
547
+ readonly publicKey: Uint8Array;
548
+ /** User-friendly address. */
549
+ readonly address: string;
550
+ protected readonly _config: TonConfig;
551
+ protected readonly _walletId: bigint;
552
+ protected readonly _init: StateInit;
553
+ protected readonly _address: Address;
554
+ protected readonly _rpc: TonCenter | undefined;
555
+ constructor(publicKey: Uint8Array | string, config?: TonConfig);
556
+ protected requireRpc(what: string): TonCenter;
557
+ /** The user-friendly address. */
558
+ getAddress(): Promise<string>;
559
+ /** Native balance in nanotons. */
560
+ getBalance(): Promise<bigint>;
561
+ /** Current seqno — 0 until the wallet contract is deployed. Always fetched fresh. */
562
+ getSeqno(): Promise<number>;
563
+ /** Resolve this wallet's jetton wallet for a jetton master. */
564
+ getJettonWalletAddress(token: string): Promise<Address>;
565
+ /**
566
+ * Read a jetton wallet and prove it is ours for `token`: `get_wallet_data`
567
+ * must name this wallet as owner and `token` as master. The master's own
568
+ * `get_wallet_address` answer is not trusted on its own — a fake master could
569
+ * point at our real wallet of another jetton (e.g. USDT).
570
+ */
571
+ protected jettonWalletData(token: string, jw: Address): Promise<bigint>;
572
+ /**
573
+ * Jetton balance in base units, read from this wallet's jetton wallet; 0 when it does not exist.
574
+ */
575
+ getTokenBalance(token: string): Promise<bigint>;
576
+ protected stateInitOf(src: TonTransaction['stateInit']): StateInit | undefined;
577
+ protected transactionMessage(tx: TonTransaction): V5R1Message;
578
+ protected jettonTransferMessage(o: TonTransferOptions): Promise<V5R1Message>;
579
+ protected toMessages(tx: TonTransaction | TonTransaction[]): V5R1Message[];
580
+ protected validUntil(): number;
581
+ /** The cell to sign for `messages` at the CURRENT seqno (fetched fresh every time). */
582
+ protected signingCell(messages: V5R1Message[]): Promise<{
583
+ signing: Cell;
584
+ seqno: number;
585
+ validUntil: number;
586
+ }>;
587
+ /** StateInit to attach to an external when the wallet is not deployed yet. */
588
+ protected initIfNeeded(): Promise<StateInit | undefined>;
589
+ /** in_fwd + storage + gas + fwd from toncenter's estimateFee (signature ignored). */
590
+ estimateFees(body: Cell): Promise<TonFees>;
591
+ /**
592
+ * Preflight an external body: fees via estimateFee and, unless
593
+ * `config.emulate === false`, a trace emulation (tonapi by default, see
594
+ * {@link TonConfig.emulate}) whose compute/action phases — and the first-hop
595
+ * internal messages — decide `ok`. Never throws for a failing emulation,
596
+ * only for transport problems or a malformed emulator response.
597
+ */
598
+ simulateBody(body: Cell): Promise<TonSimulation>;
599
+ /** Preflight a {@link TonSendable} (unsigned body, current seqno). */
600
+ simulateTransaction(tx: TonSendable): Promise<TonSimulation>;
601
+ /** Estimated fee of a transaction, in nanotons. */
602
+ quoteSendTransaction(tx: TonSendable): Promise<{
603
+ fee: bigint;
604
+ }>;
605
+ /** Estimated fee of a transfer, in nanotons. */
606
+ quoteTransfer(o: TonTransferOptions): Promise<{
607
+ fee: bigint;
608
+ }>;
609
+ /** Offline description of what `tx` does — see {@link describeTransaction}. */
610
+ describe(tx: TonSendable): TonDescription;
611
+ /**
612
+ * Receipt for a body hash returned by sendTransaction: toncenter v3 maps the
613
+ * message body hash to the account transaction, which is then fetched.
614
+ */
615
+ getTransactionReceipt(hash: string): Promise<TonReceipt | undefined>;
616
+ /** ed25519 over the raw message bytes; `signature` hex. */
617
+ verify(message: string | Uint8Array, signature: string): Promise<boolean>;
618
+ }
619
+
620
+ /**
621
+ * Signing TON account on Wallet V5R1. It never holds a key: the V5R1 body is
622
+ * signed by `signer.sign(signingCell.hash(), {scheme: 'ed25519', context:
623
+ * 'ton-external'})` — a {@link LocalSigner} for seed wallets, anything else
624
+ * (hardware, MPC, backend) through `externalSigner()`.
625
+ *
626
+ * Every send runs: hard checks → fresh seqno → preflight on the zero-signed
627
+ * body (estimateFee, emulation when configured, fee cap) → sign → broadcast.
628
+ * The preflight body carries a zero signature, so the signer is only asked
629
+ * once the transaction has passed.
630
+ */
631
+ declare class WalletAccountTon extends WalletAccountReadOnlyTon implements IWalletAccount {
632
+ /** seqno and fees come from the network before signing. */
633
+ readonly needsNetwork = true;
634
+ /** Derivation path, `ton-mnemonic`, or `external`. */
635
+ readonly path: string;
636
+ /** The signer that holds the key. */
637
+ readonly signer: Signer;
638
+ private _readOnly;
639
+ /** `publicKey` is the signer's 32-byte ed25519 key; the V5R1 address derives from it synchronously. */
640
+ constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: TonConfig);
641
+ /** Back-compat: wrap a raw derived key in a {@link LocalSigner} (the account takes ownership; it cannot derive). */
642
+ static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config?: TonConfig): WalletAccountTon;
643
+ /** Account index for the standard m/44'/607'/i' path. */
644
+ get index(): number | undefined;
645
+ /** Hex ed25519 signature over the raw message bytes (ton_proof and the like). */
646
+ sign(message: string | Uint8Array): Promise<string>;
647
+ private checkMaxFee;
648
+ /**
649
+ * Checks → seqno → preflight → signed body. The preflight runs on the
650
+ * zero-signed body (ignore_chksig), so nothing is signed before it passes.
651
+ */
652
+ private prepare;
653
+ private preflight;
654
+ /** Sign without broadcasting. Returns the external-message BODY as base64 BoC (pass it back to sendTransaction as a Cell). */
655
+ signTransaction(tx: TonSendable): Promise<string>;
656
+ private broadcast;
657
+ /** Sign and broadcast; `hash` is the body hash (hex) — resolve it with getTransactionReceipt. */
658
+ sendTransaction(tx: TonSendable): Promise<TransferResult>;
659
+ /** TON (no `token`) or jetton transfer. */
660
+ transfer(o: TonTransferOptions): Promise<TransferResult>;
661
+ /** The same wallet as a {@link WalletAccountReadOnlyTon}. */
662
+ toReadOnlyAccount(): IWalletAccountReadOnly;
663
+ /** Disposes the signer: a local key is zeroized, an external one is released. */
664
+ dispose(): void;
665
+ }
666
+
667
+ /** Base derivation path for BIP-39 seeds; account `i` is at `m/44'/607'/i'`. */
668
+ declare const TON_BASE_PATH = "m/44'/607'";
669
+ /** Path label of the account a TON-native (Tonkeeper-style) mnemonic yields — there is exactly one. */
670
+ declare const TON_MNEMONIC_PATH = "ton-mnemonic";
671
+ /**
672
+ * One seed → TON accounts at m/44'/607'/i' (SLIP-10 ed25519) on Wallet V5R1 —
673
+ * the derivation Trust Wallet and Ledger use for a BIP-39 phrase. Paths
674
+ * may be relative to m/44'/607' ("0'") or full.
675
+ *
676
+ * Built with an ed25519 `Signer` instead of a seed, the manager wraps it:
677
+ * - a derivable `SeedSigner` sitting at `m/44'/607'` yields `getAccount(i)` → `i'` children;
678
+ * - a `SeedSigner` at a leaf, or any external signer, is `getAccount(0)` (path = the
679
+ * signer's path, or 'external'); other indexes/paths throw.
680
+ *
681
+ * Tonkeeper-style 24-word TON mnemonics (not BIP-39) are imported with
682
+ * {@link WalletManagerTon.fromTonMnemonic}; they yield one account at `ton-mnemonic`.
683
+ */
684
+ declare class WalletManagerTon extends WalletManager<WalletAccountTon, TonConfig> {
685
+ constructor(seedOrSigner: string | Uint8Array | Signer, config?: TonConfig);
686
+ /**
687
+ * Import a TON-native mnemonic (24 words, Tonkeeper / Tonhub / MyTonWallet
688
+ * default): PBKDF2 per @ton/crypto, one ed25519 key, one V5R1 account at
689
+ * path `ton-mnemonic` with the address those wallets show.
690
+ */
691
+ static fromTonMnemonic(words: string[] | string, config?: TonConfig): Promise<WalletManagerTon>;
692
+ getAccount(index?: number): Promise<WalletAccountTon>;
693
+ getAccountByPath(path: string): Promise<WalletAccountTon>;
694
+ /** The one path a non-derivable signer answers to: its own, or 'external'. */
695
+ private singlePath;
696
+ /** Resolve `path` against an injected signer: the signer itself, or a child when it can derive there. */
697
+ private fromSigner;
698
+ /** Watch-only account for a public key (hex or bytes) — TON addresses derive from the key, not the other way round. */
699
+ getReadOnlyAccount(publicKey: Uint8Array | string): WalletAccountReadOnlyTon;
700
+ /** Gas price from config param 21 via tonapi (normal = fast there; slow = ×0.8 here). */
701
+ getFeeRates(): Promise<FeeRates>;
702
+ }
703
+
704
+ export { CAIP2, DEFAULT_SEND_MODE, DEFAULT_TONAPI, type DecodedBody, type EmulateOptions, type EmulationOutcome, type EmulationSource, type EmulationVerdict, type GetMethodResult, JETTON_TRANSFER_OP, MAINNET_GLOBAL_ID, MAX_ACTIONS, type ParsedV5R1Body, SEND_MODE, SimulationError, TESTNET_GLOBAL_ID, TON_BASE_PATH, TON_MNEMONIC_PATH, type TonAccountState, type TonAccountStatus, TonCenter, type TonConfig, type TonDescribedKind, type TonDescribedMessage, type TonDescription, type TonEmulateConfig, type TonEndpoint, type TonFees, type TonJettonDetails, type TonProvider, type TonReceipt, type TonRisk, type TonRpc, type TonSendable, type TonSimulation, type TonSimulationSource, type TonTransaction, type TonTransferOptions, type TonWarning, type TonWarningCode, UnsafeTransactionError, type V5R1Message, type V5R1SigningParams, type V5R1WalletIdParts, V5R1_CODE_HEX, V5R1_OP, WalletAccountReadOnlyTon, WalletAccountTon, WalletManagerTon, commentCell, createTonRpc as createTonClient, createTonRpc, decodeBody, WalletManagerTon as default, describeMessageRelaxed, describeTransaction, emulateExternal, emulateViaTonapi, installBufferGlobal, parseEmulation, parseTonapiConsequences, parseTonapiRisk, parseTonapiTrace, parseV5R1Body, resolveEmulate, runEmulation, tonCenterEndpoint, v5r1Address, v5r1Code, v5r1ExternalMessage, v5r1PackSigned, v5r1PackUnsigned, v5r1SigningMessage, v5r1StateInit, v5r1WalletId };