ton-mesh-harness 0.13.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.
- package/LICENSE +21 -0
- package/README.md +444 -0
- package/dist/cli.js +38739 -0
- package/dist/daemon/installer-utils.d.ts +103 -0
- package/dist/daemon/installer.d.ts +30 -0
- package/dist/daemon/linger.d.ts +10 -0
- package/dist/daemon/platform.d.ts +47 -0
- package/dist/daemon/ports.d.ts +14 -0
- package/dist/daemon/rldp-http-proxy-installer.d.ts +10 -0
- package/dist/daemon/service.d.ts +36 -0
- package/dist/daemon/tonutils-installer.d.ts +10 -0
- package/dist/daemon/tonutils-process.d.ts +90 -0
- package/dist/deeplink.d.ts +25 -0
- package/dist/dns.d.ts +39 -0
- package/dist/mcp.js +38097 -0
- package/dist/network.d.ts +5 -0
- package/dist/sdk/abort.d.ts +25 -0
- package/dist/sdk/agentic-config.d.ts +199 -0
- package/dist/sdk/agentic-sign.d.ts +48 -0
- package/dist/sdk/check.d.ts +24 -0
- package/dist/sdk/deploy.d.ts +96 -0
- package/dist/sdk/dns-helpers.d.ts +158 -0
- package/dist/sdk/dns-onchain.d.ts +39 -0
- package/dist/sdk/dns.d.ts +125 -0
- package/dist/sdk/endpoints.d.ts +58 -0
- package/dist/sdk/json-schemas.d.ts +38 -0
- package/dist/sdk/log.d.ts +43 -0
- package/dist/sdk/provenance.d.ts +87 -0
- package/dist/sdk/resolve-tx.d.ts +70 -0
- package/dist/sdk/schemas.d.ts +885 -0
- package/dist/sdk/site-record.d.ts +25 -0
- package/dist/sdk/status.d.ts +23 -0
- package/dist/sdk/walletkit-network.d.ts +30 -0
- package/dist/sdk.d.ts +46 -0
- package/dist/sdk.js +37789 -0
- package/dist/utils/http.d.ts +25 -0
- package/dist/utils/tunnel-config.d.ts +20 -0
- package/dist/version.d.ts +13 -0
- package/dist/wallet/FSStorage.d.ts +12 -0
- package/dist/wallet/SendProvider.d.ts +17 -0
- package/dist/wallet/Storage.d.ts +5 -0
- package/dist/wallet/TonConnectProvider.d.ts +48 -0
- package/dist/wallet/constants.d.ts +12 -0
- package/dist/wallet/ui.d.ts +13 -0
- package/package.json +105 -0
- package/skills/mesh-deploy.md +283 -0
- package/templates/.well-known/mcp.json +44 -0
- package/templates/github-workflow-agentic.yml +94 -0
- package/templates/github-workflow.yml +76 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny AbortSignal → ERR_CANCELLED bridge. Used at every phase
|
|
3
|
+
* boundary in long-running async generators (`writeDnsRecord`,
|
|
4
|
+
* `writeDnsRecordAgentic`) and at race-window checkpoints in
|
|
5
|
+
* `agenticSignAndSend`.
|
|
6
|
+
*
|
|
7
|
+
* Kept in its own file so consumers that don't need any other
|
|
8
|
+
* dns-helpers / deploy machinery can still get the abort-check
|
|
9
|
+
* pattern without pulling those in.
|
|
10
|
+
*
|
|
11
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Build a `checkAborted()` thunk that throws `ERR_CANCELLED` when the
|
|
15
|
+
* signal has fired. `message` is included in the error so logs
|
|
16
|
+
* distinguish which surface the cancel originated from.
|
|
17
|
+
*/
|
|
18
|
+
export declare function makeAbortChecker(signal: AbortSignal | undefined, message: string): () => void;
|
|
19
|
+
/**
|
|
20
|
+
* Best-effort `controller.abort()` for use in `finally` blocks. Some
|
|
21
|
+
* runtimes throw on a double-abort or on aborting a controller whose
|
|
22
|
+
* signal is already aborted; we swallow because the goal is "make sure
|
|
23
|
+
* dependents stop running" and any further error is noise.
|
|
24
|
+
*/
|
|
25
|
+
export declare function safeAbort(controller: AbortController): void;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic-wallet config loader for `~/.config/ton/config.json` (the file
|
|
3
|
+
* `@ton/mcp@alpha` writes via `agentic_start_root_wallet_setup`).
|
|
4
|
+
*
|
|
5
|
+
* Spec source: docs/v0.8/mcp-core-requirements.md §NF6 (filesystem-level
|
|
6
|
+
* compose) + cross-verified against `@ton/mcp@0.1.15-alpha.15`'s
|
|
7
|
+
* `dist/types/config.d.ts` and `dist/registry/config.d.ts` on 2026-05-11.
|
|
8
|
+
*
|
|
9
|
+
* Scope for v0.8.0 GA: this loader ONLY supports `type: "standard"` wallet
|
|
10
|
+
* entries (mnemonic OR private_key direct sign). `type: "agentic"` entries
|
|
11
|
+
* (NFT-delegated operator-key signing via the agentic collection contract)
|
|
12
|
+
* are rejected with a clear error — that path requires the @ton/mcp
|
|
13
|
+
* collection-contract dance which is out of scope for this release.
|
|
14
|
+
*
|
|
15
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
16
|
+
*/
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
export type AgenticNetwork = 'mainnet' | 'testnet';
|
|
19
|
+
export type StandardWalletVersion = 'v5r1' | 'v4r2';
|
|
20
|
+
/** What deploy() asks for. */
|
|
21
|
+
export interface AgenticConfigLookup {
|
|
22
|
+
/** Override path; falls back to TON_CONFIG_PATH env, then `~/.config/ton/config.json`. */
|
|
23
|
+
config_path?: string;
|
|
24
|
+
/** Match by id, name, or address. Empty = use `active_wallet_id`. */
|
|
25
|
+
wallet_label?: string;
|
|
26
|
+
/** Filter wallets to this network. */
|
|
27
|
+
network: AgenticNetwork;
|
|
28
|
+
}
|
|
29
|
+
export interface AgenticConfigSelection {
|
|
30
|
+
wallet: StoredSelectableWallet;
|
|
31
|
+
/** Per-network toncenter API key from the config (may be undefined). */
|
|
32
|
+
toncenter_api_key: string | undefined;
|
|
33
|
+
/** Resolved config path actually loaded (for diagnostics). */
|
|
34
|
+
config_path: string;
|
|
35
|
+
}
|
|
36
|
+
declare const StoredStandardWalletSchema: z.ZodEffects<z.ZodObject<{
|
|
37
|
+
id: z.ZodString;
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
type: z.ZodLiteral<"standard">;
|
|
40
|
+
wallet_version: z.ZodEnum<["v5r1", "v4r2"]>;
|
|
41
|
+
network: z.ZodEnum<["mainnet", "testnet"]>;
|
|
42
|
+
address: z.ZodString;
|
|
43
|
+
mnemonic: z.ZodOptional<z.ZodString>;
|
|
44
|
+
private_key: z.ZodOptional<z.ZodString>;
|
|
45
|
+
removed: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
removed_at: z.ZodOptional<z.ZodString>;
|
|
47
|
+
created_at: z.ZodString;
|
|
48
|
+
updated_at: z.ZodString;
|
|
49
|
+
}, "strict", z.ZodTypeAny, {
|
|
50
|
+
type: "standard";
|
|
51
|
+
name: string;
|
|
52
|
+
id: string;
|
|
53
|
+
wallet_version: "v5r1" | "v4r2";
|
|
54
|
+
network: "testnet" | "mainnet";
|
|
55
|
+
address: string;
|
|
56
|
+
created_at: string;
|
|
57
|
+
updated_at: string;
|
|
58
|
+
mnemonic?: string | undefined;
|
|
59
|
+
private_key?: string | undefined;
|
|
60
|
+
removed?: boolean | undefined;
|
|
61
|
+
removed_at?: string | undefined;
|
|
62
|
+
}, {
|
|
63
|
+
type: "standard";
|
|
64
|
+
name: string;
|
|
65
|
+
id: string;
|
|
66
|
+
wallet_version: "v5r1" | "v4r2";
|
|
67
|
+
network: "testnet" | "mainnet";
|
|
68
|
+
address: string;
|
|
69
|
+
created_at: string;
|
|
70
|
+
updated_at: string;
|
|
71
|
+
mnemonic?: string | undefined;
|
|
72
|
+
private_key?: string | undefined;
|
|
73
|
+
removed?: boolean | undefined;
|
|
74
|
+
removed_at?: string | undefined;
|
|
75
|
+
}>, {
|
|
76
|
+
type: "standard";
|
|
77
|
+
name: string;
|
|
78
|
+
id: string;
|
|
79
|
+
wallet_version: "v5r1" | "v4r2";
|
|
80
|
+
network: "testnet" | "mainnet";
|
|
81
|
+
address: string;
|
|
82
|
+
created_at: string;
|
|
83
|
+
updated_at: string;
|
|
84
|
+
mnemonic?: string | undefined;
|
|
85
|
+
private_key?: string | undefined;
|
|
86
|
+
removed?: boolean | undefined;
|
|
87
|
+
removed_at?: string | undefined;
|
|
88
|
+
}, {
|
|
89
|
+
type: "standard";
|
|
90
|
+
name: string;
|
|
91
|
+
id: string;
|
|
92
|
+
wallet_version: "v5r1" | "v4r2";
|
|
93
|
+
network: "testnet" | "mainnet";
|
|
94
|
+
address: string;
|
|
95
|
+
created_at: string;
|
|
96
|
+
updated_at: string;
|
|
97
|
+
mnemonic?: string | undefined;
|
|
98
|
+
private_key?: string | undefined;
|
|
99
|
+
removed?: boolean | undefined;
|
|
100
|
+
removed_at?: string | undefined;
|
|
101
|
+
}>;
|
|
102
|
+
export type StoredStandardWallet = z.infer<typeof StoredStandardWalletSchema>;
|
|
103
|
+
declare const StoredAgenticWalletSchema: z.ZodEffects<z.ZodObject<{
|
|
104
|
+
id: z.ZodString;
|
|
105
|
+
name: z.ZodString;
|
|
106
|
+
type: z.ZodLiteral<"agentic">;
|
|
107
|
+
network: z.ZodEnum<["mainnet", "testnet"]>;
|
|
108
|
+
address: z.ZodString;
|
|
109
|
+
owner_address: z.ZodString;
|
|
110
|
+
operator_private_key: z.ZodOptional<z.ZodString>;
|
|
111
|
+
operator_public_key: z.ZodOptional<z.ZodString>;
|
|
112
|
+
source: z.ZodOptional<z.ZodString>;
|
|
113
|
+
collection_address: z.ZodOptional<z.ZodString>;
|
|
114
|
+
wallet_nft_index: z.ZodOptional<z.ZodString>;
|
|
115
|
+
origin_operator_public_key: z.ZodOptional<z.ZodString>;
|
|
116
|
+
deployed_by_user: z.ZodOptional<z.ZodBoolean>;
|
|
117
|
+
removed: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
removed_at: z.ZodOptional<z.ZodString>;
|
|
119
|
+
created_at: z.ZodString;
|
|
120
|
+
updated_at: z.ZodString;
|
|
121
|
+
}, "strict", z.ZodTypeAny, {
|
|
122
|
+
type: "agentic";
|
|
123
|
+
name: string;
|
|
124
|
+
id: string;
|
|
125
|
+
network: "testnet" | "mainnet";
|
|
126
|
+
address: string;
|
|
127
|
+
created_at: string;
|
|
128
|
+
updated_at: string;
|
|
129
|
+
owner_address: string;
|
|
130
|
+
removed?: boolean | undefined;
|
|
131
|
+
removed_at?: string | undefined;
|
|
132
|
+
operator_private_key?: string | undefined;
|
|
133
|
+
operator_public_key?: string | undefined;
|
|
134
|
+
source?: string | undefined;
|
|
135
|
+
collection_address?: string | undefined;
|
|
136
|
+
wallet_nft_index?: string | undefined;
|
|
137
|
+
origin_operator_public_key?: string | undefined;
|
|
138
|
+
deployed_by_user?: boolean | undefined;
|
|
139
|
+
}, {
|
|
140
|
+
type: "agentic";
|
|
141
|
+
name: string;
|
|
142
|
+
id: string;
|
|
143
|
+
network: "testnet" | "mainnet";
|
|
144
|
+
address: string;
|
|
145
|
+
created_at: string;
|
|
146
|
+
updated_at: string;
|
|
147
|
+
owner_address: string;
|
|
148
|
+
removed?: boolean | undefined;
|
|
149
|
+
removed_at?: string | undefined;
|
|
150
|
+
operator_private_key?: string | undefined;
|
|
151
|
+
operator_public_key?: string | undefined;
|
|
152
|
+
source?: string | undefined;
|
|
153
|
+
collection_address?: string | undefined;
|
|
154
|
+
wallet_nft_index?: string | undefined;
|
|
155
|
+
origin_operator_public_key?: string | undefined;
|
|
156
|
+
deployed_by_user?: boolean | undefined;
|
|
157
|
+
}>, {
|
|
158
|
+
type: "agentic";
|
|
159
|
+
name: string;
|
|
160
|
+
id: string;
|
|
161
|
+
network: "testnet" | "mainnet";
|
|
162
|
+
address: string;
|
|
163
|
+
created_at: string;
|
|
164
|
+
updated_at: string;
|
|
165
|
+
owner_address: string;
|
|
166
|
+
removed?: boolean | undefined;
|
|
167
|
+
removed_at?: string | undefined;
|
|
168
|
+
operator_private_key?: string | undefined;
|
|
169
|
+
operator_public_key?: string | undefined;
|
|
170
|
+
source?: string | undefined;
|
|
171
|
+
collection_address?: string | undefined;
|
|
172
|
+
wallet_nft_index?: string | undefined;
|
|
173
|
+
origin_operator_public_key?: string | undefined;
|
|
174
|
+
deployed_by_user?: boolean | undefined;
|
|
175
|
+
}, {
|
|
176
|
+
type: "agentic";
|
|
177
|
+
name: string;
|
|
178
|
+
id: string;
|
|
179
|
+
network: "testnet" | "mainnet";
|
|
180
|
+
address: string;
|
|
181
|
+
created_at: string;
|
|
182
|
+
updated_at: string;
|
|
183
|
+
owner_address: string;
|
|
184
|
+
removed?: boolean | undefined;
|
|
185
|
+
removed_at?: string | undefined;
|
|
186
|
+
operator_private_key?: string | undefined;
|
|
187
|
+
operator_public_key?: string | undefined;
|
|
188
|
+
source?: string | undefined;
|
|
189
|
+
collection_address?: string | undefined;
|
|
190
|
+
wallet_nft_index?: string | undefined;
|
|
191
|
+
origin_operator_public_key?: string | undefined;
|
|
192
|
+
deployed_by_user?: boolean | undefined;
|
|
193
|
+
}>;
|
|
194
|
+
export type StoredNftAgenticWallet = z.infer<typeof StoredAgenticWalletSchema>;
|
|
195
|
+
/** Discriminated union of both supported wallet types. */
|
|
196
|
+
export type StoredSelectableWallet = StoredStandardWallet | StoredNftAgenticWallet;
|
|
197
|
+
export declare function getAgenticConfigPath(override?: string): string;
|
|
198
|
+
export declare function loadAgenticConfig(lookup: AgenticConfigLookup): AgenticConfigSelection;
|
|
199
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic signing — dispatches by `wallet.type`:
|
|
3
|
+
*
|
|
4
|
+
* - `standard`: walletkit's `Signer` + `WalletV5R1Adapter`/`WalletV4R2Adapter`
|
|
5
|
+
* (direct sign — operator IS the wallet).
|
|
6
|
+
* - `agentic`: @ton/mcp's `AgenticWalletAdapter` (operator key signs via
|
|
7
|
+
* the agentic NFT collection contract on behalf of owner_address; v0.8.x).
|
|
8
|
+
*
|
|
9
|
+
* Both adapters implement `WalletAdapter` so the rest of this module is
|
|
10
|
+
* agnostic to the path — `buildAdapter()` returns the right adapter and
|
|
11
|
+
* `getSignedSendTransaction → sendBoc` is identical.
|
|
12
|
+
*
|
|
13
|
+
* The result is the normalized message hash (`0x<hex>`) returned by
|
|
14
|
+
* `ApiClientToncenter.sendBoc`, suitable as `dns_tx_hash` (it indexes the
|
|
15
|
+
* external-in message; explorers resolve to the on-chain tx within seconds).
|
|
16
|
+
*
|
|
17
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
18
|
+
*/
|
|
19
|
+
import type { Address, Cell } from '@ton/core';
|
|
20
|
+
import type { StoredSelectableWallet } from './agentic-config';
|
|
21
|
+
export interface AgenticSignSendInput {
|
|
22
|
+
wallet: StoredSelectableWallet;
|
|
23
|
+
toncenter_api_key: string | undefined;
|
|
24
|
+
messages: Array<{
|
|
25
|
+
address: Address;
|
|
26
|
+
amount: bigint;
|
|
27
|
+
payload: Cell;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* AbortSignal for the cancel-before-broadcast race window. Checked
|
|
31
|
+
* after adapter construction and after signing, immediately before
|
|
32
|
+
* `sendBoc`. Once `sendBoc` is invoked the broadcast is no longer
|
|
33
|
+
* cancellable from our side.
|
|
34
|
+
*/
|
|
35
|
+
signal?: AbortSignal;
|
|
36
|
+
}
|
|
37
|
+
export interface AgenticSignSendResult {
|
|
38
|
+
/** Normalized message hash returned by Toncenter (`0x<hex>`). */
|
|
39
|
+
message_hash: string;
|
|
40
|
+
/** Wallet address that sent the batch (user-friendly form). */
|
|
41
|
+
from_address: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build adapter → sign → broadcast. The returned `message_hash` is the
|
|
45
|
+
* normalized external-in hash that explorers / TONAPI resolve to the
|
|
46
|
+
* actual tx within ~10s. We surface it as `dns_tx_hash`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function agenticSignAndSend(input: AgenticSignSendInput): Promise<AgenticSignSendResult>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic environment check — the "did the user's machine actually
|
|
3
|
+
* have everything we need" probe that powers both the CLI's `doctor`
|
|
4
|
+
* subcommand and the MCP server's `mesh_check_env` tool.
|
|
5
|
+
*
|
|
6
|
+
* Spec: docs/v0.8/mcp-core-requirements.md §F2 / §F3.
|
|
7
|
+
*
|
|
8
|
+
* NO `console.*` ANYWHERE IN THIS FILE — lint-enforced (planned [S4]).
|
|
9
|
+
*/
|
|
10
|
+
import type { CheckEnvOptions, CheckEnvResult } from './schemas';
|
|
11
|
+
/**
|
|
12
|
+
* Pre-flight readiness probe. Returns a structured `CheckEnvResult` per the
|
|
13
|
+
* F2 zod schema — no IO side effects beyond the network probes the function
|
|
14
|
+
* documents (TONAPI, TonConnect manifest, dns lookups).
|
|
15
|
+
*
|
|
16
|
+
* The CLI's `doctor` subcommand and the MCP `mesh_check_env` tool both
|
|
17
|
+
* route through here.
|
|
18
|
+
*/
|
|
19
|
+
export declare function checkEnv(opts?: CheckEnvOptions): Promise<CheckEnvResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Re-export tied to tonutils' assumed UDP port so downstream renderers can
|
|
22
|
+
* label the "port busy" line with the actual number rather than a magic literal.
|
|
23
|
+
*/
|
|
24
|
+
export declare const TONUTILS_DEFAULT_UDP_PORT = 17555;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic deploy SDK — the seam that powers both the CLI's
|
|
3
|
+
* `runDeployTonutils` adapter and (future) the MCP server's
|
|
4
|
+
* `mesh_deploy` tool.
|
|
5
|
+
*
|
|
6
|
+
* Spec: docs/v0.8/mcp-core-requirements.md §F2 / §F3 / §F4 / §F5.
|
|
7
|
+
*
|
|
8
|
+
* Scope (rc5):
|
|
9
|
+
* env_check → daemon_starting → bag_creating → bag_uploaded →
|
|
10
|
+
* [awaiting_signature → dns_signing → dns_confirmed → verifying]? →
|
|
11
|
+
* done. The DNS phases fire iff `opts.domain` is set, routed through
|
|
12
|
+
* writeDnsRecord (TonConnect) or writeDnsRecordAgentic depending on
|
|
13
|
+
* wallet.kind. watch + site-auto remain CLI-only orchestration —
|
|
14
|
+
* they have no MCP-callable equivalent.
|
|
15
|
+
*
|
|
16
|
+
* NO `console.*` ANYWHERE IN THIS FILE — lint-enforced.
|
|
17
|
+
*/
|
|
18
|
+
import { type DeployEvent, type DeployOptions, type DeployResult, type ErrCode, type WalletSpec } from './schemas';
|
|
19
|
+
import { type TonutilsHandle } from '../daemon/tonutils-process';
|
|
20
|
+
export type DeployInput = Omit<Partial<DeployOptions>, 'wallet'> & {
|
|
21
|
+
source_dir: string;
|
|
22
|
+
wallet?: string | WalletSpec;
|
|
23
|
+
};
|
|
24
|
+
export interface DeployControl {
|
|
25
|
+
/**
|
|
26
|
+
* AbortSignal honoured at every event boundary AND just-after the daemon
|
|
27
|
+
* spawns. When fired:
|
|
28
|
+
* - the SDK kills the daemon (regardless of `keep_alive`);
|
|
29
|
+
* - in-flight HTTP calls to the daemon will reject (the daemon is gone);
|
|
30
|
+
* - the generator throws `SdkError(ERR_CANCELLED)` with `phase_at_cancel`
|
|
31
|
+
* set to the most recent yielded phase (or "env_check" if cancellation
|
|
32
|
+
* occurred before any yield).
|
|
33
|
+
*
|
|
34
|
+
* Per F4: `may_have_published` is `false` for any cancellation that
|
|
35
|
+
* occurs before `awaiting_signature` fires. Once that phase yields,
|
|
36
|
+
* the flag is path-aware:
|
|
37
|
+
* - tonconnect: `true` (the QR is shown; user may have approved
|
|
38
|
+
* out-of-band by the time we abort)
|
|
39
|
+
* - agentic: `dnsBroadcastEnqueued` (set when `dns_signing` fires,
|
|
40
|
+
* i.e. after Toncenter accepted the BOC)
|
|
41
|
+
*/
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
/**
|
|
44
|
+
* Internal hook — fires once with the live `TonutilsHandle` immediately
|
|
45
|
+
* after the daemon spawns. The CLI uses this to capture the real handle
|
|
46
|
+
* for watch-mode re-uploads (so it can call `tonutilsCreate(handle, …)`
|
|
47
|
+
* later without needing the SDK to re-spawn).
|
|
48
|
+
*
|
|
49
|
+
* MCP consumers should NOT use this hook — the MCP server has no
|
|
50
|
+
* persistent watch-mode that needs the underlying ChildProcess.
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
onDaemonReady?: (handle: TonutilsHandle) => void;
|
|
55
|
+
}
|
|
56
|
+
export declare class SdkError extends Error {
|
|
57
|
+
readonly code: ErrCode;
|
|
58
|
+
readonly severity: 'fatal' | 'recoverable';
|
|
59
|
+
readonly fixHint?: string;
|
|
60
|
+
readonly data?: Record<string, unknown>;
|
|
61
|
+
constructor(code: ErrCode, message: string, options?: {
|
|
62
|
+
severity?: 'fatal' | 'recoverable';
|
|
63
|
+
fixHint?: string;
|
|
64
|
+
data?: Record<string, unknown>;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Heuristic mapping from `startTonutilsDaemon` failure messages to F5 codes.
|
|
69
|
+
* The daemon-process module throws `Error(message)` for several distinct
|
|
70
|
+
* causes (spawn crash / config gen / port collision / API never came up);
|
|
71
|
+
* we route them to the right ERR_* code by message inspection.
|
|
72
|
+
*
|
|
73
|
+
* @internal Exported for unit tests only. The published SDK surface is
|
|
74
|
+
* curated in `src/sdk.ts` (which omits this); the `export *` in
|
|
75
|
+
* `src/sdk/index.ts` is an internal-only bundle, not a published entry.
|
|
76
|
+
*/
|
|
77
|
+
export declare function mapDaemonStartError(err: unknown): SdkError;
|
|
78
|
+
/**
|
|
79
|
+
* Async-generator deploy SDK. Yields typed `DeployEvent` values in phase
|
|
80
|
+
* order. The terminal `done` event carries the full `DeployResult`; consumers
|
|
81
|
+
* can also read it from the generator's return value.
|
|
82
|
+
*
|
|
83
|
+
* Daemon lifecycle:
|
|
84
|
+
* - Normal `keep_alive: false` success → daemon killed BEFORE yielding
|
|
85
|
+
* the `done` event, so consumers reading the terminal event already
|
|
86
|
+
* see `seed_status: "stopped"`.
|
|
87
|
+
* - Normal `keep_alive: true` success → daemon kept alive; CALLER owns
|
|
88
|
+
* the kill. Ownership transfers BEFORE the `done` yield so a consumer
|
|
89
|
+
* that breaks at `done` doesn't leak via the generator's `return()`.
|
|
90
|
+
* - Cancellation (AbortSignal) → daemon ALWAYS killed; throws ERR_CANCELLED.
|
|
91
|
+
* - Error → daemon ALWAYS killed.
|
|
92
|
+
*
|
|
93
|
+
* Concurrency: this SDK serialises within a process. A second concurrent
|
|
94
|
+
* `deploy()` invocation throws `SdkError(ERR_BUSY)` per F5 / spec §3.2.
|
|
95
|
+
*/
|
|
96
|
+
export declare function deploy(rawInput: DeployInput, control?: DeployControl): AsyncGenerator<DeployEvent, DeployResult, void>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for `writeDnsRecord` (TonConnect) and
|
|
3
|
+
* `writeDnsRecordAgentic`. Both paths converged on the same post-
|
|
4
|
+
* broadcast pipeline:
|
|
5
|
+
*
|
|
6
|
+
* resolve NFT address → build message batch → broadcast (path-specific)
|
|
7
|
+
* → kick off Toncenter tx-hash resolve in parallel → poll TONAPI for
|
|
8
|
+
* record propagation → await tx-hash with grace → yield dns_confirmed
|
|
9
|
+
* + verifying.
|
|
10
|
+
*
|
|
11
|
+
* Only the broadcast step + the awaiting_signature event differ by path
|
|
12
|
+
* (TonConnect: QR/connector dance; agentic: filesystem-key sign+send).
|
|
13
|
+
* Everything else was duplicated 2× pre-refactor. This module is the
|
|
14
|
+
* dedup boundary.
|
|
15
|
+
*
|
|
16
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
17
|
+
*/
|
|
18
|
+
import { Address, type Cell } from '@ton/core';
|
|
19
|
+
import { type TxHashResolution } from './resolve-tx';
|
|
20
|
+
import type { AgenticNetwork } from './agentic-config';
|
|
21
|
+
import type { DeployEvent } from './schemas';
|
|
22
|
+
/**
|
|
23
|
+
* 0.02 TON per DNS update message. v0.6.2 tuned. See cli/dns.ts for
|
|
24
|
+
* the field-test rationale (compute fee ~0.0015 TON; 10× buffer).
|
|
25
|
+
*/
|
|
26
|
+
export declare const DNS_UPDATE_AMOUNT_NANO = 20000000n;
|
|
27
|
+
/**
|
|
28
|
+
* Wraps `getDomainNftAddress` and re-throws TONAPI failures as
|
|
29
|
+
* `ERR_NO_DOMAIN`. `ownershipFixHint` is appended to the fix_hint so
|
|
30
|
+
* each path can point at its own wallet source (TonConnect: "signing
|
|
31
|
+
* wallet"; agentic: "wallet at ${address}").
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveDomainNftOrThrow(domain: string, testnet: boolean, ownershipFixHint: string): Promise<Address>;
|
|
34
|
+
export interface DnsMessage {
|
|
35
|
+
address: Address;
|
|
36
|
+
amount: bigint;
|
|
37
|
+
payload: Cell;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build the `change_dns_record` op batch:
|
|
41
|
+
* - always: `storage` record → bag id
|
|
42
|
+
* - optional: `site` (ADNL) record → ADNL hex
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildDnsMessageBatch(nftAddress: Address, bagId: string, siteAdnl: string | null | undefined): DnsMessage[];
|
|
45
|
+
/**
|
|
46
|
+
* Poll TONAPI for storage-record propagation; optionally also poll the
|
|
47
|
+
* site (ADNL) record. Throws `ERR_DNS_TX_TIMEOUT` if either times out.
|
|
48
|
+
*
|
|
49
|
+
* `checkAborted` is called between polls so caller-side aborts
|
|
50
|
+
* short-circuit the long TONAPI wait.
|
|
51
|
+
*
|
|
52
|
+
* `timeoutHint` is appended to the timeout error so each path can
|
|
53
|
+
* include a path-specific identifier (e.g. agentic includes the
|
|
54
|
+
* Toncenter message hash).
|
|
55
|
+
*/
|
|
56
|
+
export declare function pollDnsConfirmationOrThrow(args: {
|
|
57
|
+
domain: string;
|
|
58
|
+
bagId: string;
|
|
59
|
+
siteAdnl: string | null | undefined;
|
|
60
|
+
testnet: boolean;
|
|
61
|
+
/** Optional — called between polls to short-circuit on caller abort. */
|
|
62
|
+
checkAborted?: () => void;
|
|
63
|
+
/**
|
|
64
|
+
* Optional caller abort signal, threaded into the pollers so a cancellation
|
|
65
|
+
* mid-poll bails within one interval (and interrupts the sleep) instead of
|
|
66
|
+
* waiting out the full 5-min/3-min timeout. The poller returns false on
|
|
67
|
+
* abort; `checkAborted` below then throws ERR_CANCELLED. (#135)
|
|
68
|
+
*/
|
|
69
|
+
signal?: AbortSignal;
|
|
70
|
+
/** Optional — when omitted, the inner poller emits its own spinner. */
|
|
71
|
+
silent?: boolean;
|
|
72
|
+
timeoutHint: string;
|
|
73
|
+
}): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Start a best-effort Toncenter `transactionsByMessage` lookup in the
|
|
76
|
+
* background. Returns a promise that resolves to the tx hash
|
|
77
|
+
* (`0x<hex>`) when Toncenter has indexed, or `null` on timeout / error.
|
|
78
|
+
*
|
|
79
|
+
* Signal is chained from BOTH the caller's signal AND the internal
|
|
80
|
+
* abort controller so early generator exit cancels the resolve cleanly.
|
|
81
|
+
* The internal abort controller is what `finally` aborts to clean up
|
|
82
|
+
* after success / early consumer break.
|
|
83
|
+
*
|
|
84
|
+
* Caller MUST pass the internal `txResolveAbort.signal` so the helper
|
|
85
|
+
* can wire the chain. Returns the promise wrapped in `.catch(() => null)`
|
|
86
|
+
* so unhandled rejection is impossible.
|
|
87
|
+
*/
|
|
88
|
+
export declare function kickoffTxHashResolve(args: {
|
|
89
|
+
messageHashHex: string;
|
|
90
|
+
network: AgenticNetwork;
|
|
91
|
+
internalAbortSignal: AbortSignal;
|
|
92
|
+
callerSignal?: AbortSignal;
|
|
93
|
+
toncenterApiKey?: string;
|
|
94
|
+
}): Promise<TxHashResolution>;
|
|
95
|
+
/**
|
|
96
|
+
* Default grace the deploy waits for the parallel Toncenter tx-hash
|
|
97
|
+
* resolver AFTER TONAPI confirms DNS propagation. Raised from 3s → 15s
|
|
98
|
+
* (#117): when TONAPI propagates the storage record BEFORE Toncenter
|
|
99
|
+
* indexes the tx — the inverse of the order `resolve-tx.ts` once assumed —
|
|
100
|
+
* a 3s grace expired and left `dns_tx_hash` null on fully-successful
|
|
101
|
+
* deploys. 15s lets Toncenter catch up in the common lagging case while
|
|
102
|
+
* only ever adding latency to that case (the happy path returns early the
|
|
103
|
+
* moment the resolver settles). It cannot eliminate the race, so the
|
|
104
|
+
* tx-hash field stays best-effort / nullable by contract.
|
|
105
|
+
*/
|
|
106
|
+
export declare const TX_HASH_GRACE_MS = 15000;
|
|
107
|
+
/**
|
|
108
|
+
* After TONAPI confirms DNS propagation, give the tx-hash resolver a grace
|
|
109
|
+
* period. Returns whatever it has at the cutoff (real hash, or null if
|
|
110
|
+
* Toncenter is still lagging beyond the grace).
|
|
111
|
+
*/
|
|
112
|
+
export declare function awaitTxHashWithGrace(resolvePromise: Promise<TxHashResolution>, graceMs?: number): Promise<TxHashResolution>;
|
|
113
|
+
/**
|
|
114
|
+
* Confirm a DNS write, preferring TONAPI propagation but falling back to an
|
|
115
|
+
* AUTHORITATIVE on-chain check. `pollDnsConfirmationOrThrow` throws
|
|
116
|
+
* `ERR_DNS_TX_TIMEOUT` when TONAPI's (flaky, cache-lagged) `/dns/resolve`
|
|
117
|
+
* doesn't reflect the record within its window — yet the write may have landed.
|
|
118
|
+
*
|
|
119
|
+
* On that timeout we ask `verifyOnChain()`, which reads the NFT's `storage`
|
|
120
|
+
* record directly via the `dnsresolve` get-method (`resolveStorageRecordOnChain`)
|
|
121
|
+
* and returns true iff it equals the deployed bag. This proves the
|
|
122
|
+
* `change_dns_record` ACTION succeeded — unlike trusting the resolved wallet tx
|
|
123
|
+
* hash, which only proves the wallet's transaction was indexed (a non-owner
|
|
124
|
+
* wallet's tx still indexes while the DNS never changes; #119 Codex-P1). Only a
|
|
125
|
+
* timeout with NO on-chain confirmation surfaces the recoverable error.
|
|
126
|
+
*
|
|
127
|
+
* @throws the original `ERR_DNS_TX_TIMEOUT` when TONAPI lagged AND the on-chain
|
|
128
|
+
* record does not (yet) match; rethrows any other error unchanged.
|
|
129
|
+
*/
|
|
130
|
+
export declare function confirmDnsWriteOrThrow(args: {
|
|
131
|
+
poll: () => Promise<void>;
|
|
132
|
+
txHashResolvePromise: Promise<TxHashResolution>;
|
|
133
|
+
verifyOnChain: () => Promise<boolean>;
|
|
134
|
+
}): Promise<{
|
|
135
|
+
txHash: string | null;
|
|
136
|
+
throttled: boolean;
|
|
137
|
+
viaChainFallback: boolean;
|
|
138
|
+
}>;
|
|
139
|
+
/**
|
|
140
|
+
* Build the F3 `verifying` event. The data shape is identical for both
|
|
141
|
+
* paths (verifier = TONAPI for both); only the human-readable `message`
|
|
142
|
+
* differs slightly by path, so we expose it as a param.
|
|
143
|
+
*/
|
|
144
|
+
export declare function buildVerifyingEvent(message: string): DeployEvent;
|
|
145
|
+
/**
|
|
146
|
+
* Build the F3 `awaiting_signature` event for the TonConnect path.
|
|
147
|
+
* `signing_url` is either the live tonkeeper://... deeplink (fresh
|
|
148
|
+
* session) or a sentinel for a restored session. Per
|
|
149
|
+
* `AwaitingSignatureDataSchema.tonconnect`.
|
|
150
|
+
*/
|
|
151
|
+
export declare function buildAwaitingSignatureTonConnect(message: string, signingUrl: string): DeployEvent;
|
|
152
|
+
/**
|
|
153
|
+
* Build the F3 `awaiting_signature` event for the agentic path. Per
|
|
154
|
+
* `AwaitingSignatureDataSchema.agentic` — `signing_url` is null
|
|
155
|
+
* (no QR / external app), `wallet_label` is informational for the
|
|
156
|
+
* agent's logs.
|
|
157
|
+
*/
|
|
158
|
+
export declare function buildAwaitingSignatureAgentic(message: string, walletLabel: string): DeployEvent;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authoritative ON-CHAIN read of a `.ton` domain's `storage` DNS record, used
|
|
3
|
+
* to confirm a deploy landed when TONAPI's (flaky, cache-lagged) `/dns/resolve`
|
|
4
|
+
* propagation poll times out (#119).
|
|
5
|
+
*
|
|
6
|
+
* It calls the domain NFT's `dnsresolve` get-method via Toncenter — independent
|
|
7
|
+
* of TONAPI — and parses the returned `dns_storage_address#7473 bag:bits256`
|
|
8
|
+
* record. Crucially this verifies the NFT's record itself, NOT the signing
|
|
9
|
+
* wallet's transaction: a resolved wallet tx only proves the wallet broadcast
|
|
10
|
+
* was indexed, not that the `change_dns_record` action succeeded (e.g. a
|
|
11
|
+
* non-owner wallet's tx still indexes while the DNS never changes).
|
|
12
|
+
*
|
|
13
|
+
* Encoding proven against masashi-ono0611.ton on 2026-06-26:
|
|
14
|
+
* dnsresolve(`\0` slice, sha256("storage")) → (8, dns_storage_address#7473 bag:bits256)
|
|
15
|
+
*
|
|
16
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
17
|
+
*/
|
|
18
|
+
import { Address } from '@ton/core';
|
|
19
|
+
import type { AgenticNetwork } from './agentic-config';
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the domain NFT's on-chain `storage` record to its bag id (lowercased
|
|
22
|
+
* 64-hex), or `null` on any error / missing-or-non-storage record. Best-effort:
|
|
23
|
+
* never throws — the caller treats `null` as "could not confirm on-chain".
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveStorageRecordOnChain(args: {
|
|
26
|
+
nftAddress: Address;
|
|
27
|
+
network: AgenticNetwork;
|
|
28
|
+
toncenterApiKey?: string;
|
|
29
|
+
}): Promise<string | null>;
|
|
30
|
+
/**
|
|
31
|
+
* True iff the domain's on-chain `storage` record points at `expectedBag`.
|
|
32
|
+
* `null`-safe (a failed on-chain read is `false`, never a throw).
|
|
33
|
+
*/
|
|
34
|
+
export declare function storageRecordMatchesOnChain(args: {
|
|
35
|
+
nftAddress: Address;
|
|
36
|
+
network: AgenticNetwork;
|
|
37
|
+
expectedBag: string;
|
|
38
|
+
toncenterApiKey?: string;
|
|
39
|
+
}): Promise<boolean>;
|