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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +444 -0
  3. package/dist/cli.js +38739 -0
  4. package/dist/daemon/installer-utils.d.ts +103 -0
  5. package/dist/daemon/installer.d.ts +30 -0
  6. package/dist/daemon/linger.d.ts +10 -0
  7. package/dist/daemon/platform.d.ts +47 -0
  8. package/dist/daemon/ports.d.ts +14 -0
  9. package/dist/daemon/rldp-http-proxy-installer.d.ts +10 -0
  10. package/dist/daemon/service.d.ts +36 -0
  11. package/dist/daemon/tonutils-installer.d.ts +10 -0
  12. package/dist/daemon/tonutils-process.d.ts +90 -0
  13. package/dist/deeplink.d.ts +25 -0
  14. package/dist/dns.d.ts +39 -0
  15. package/dist/mcp.js +38097 -0
  16. package/dist/network.d.ts +5 -0
  17. package/dist/sdk/abort.d.ts +25 -0
  18. package/dist/sdk/agentic-config.d.ts +199 -0
  19. package/dist/sdk/agentic-sign.d.ts +48 -0
  20. package/dist/sdk/check.d.ts +24 -0
  21. package/dist/sdk/deploy.d.ts +96 -0
  22. package/dist/sdk/dns-helpers.d.ts +158 -0
  23. package/dist/sdk/dns-onchain.d.ts +39 -0
  24. package/dist/sdk/dns.d.ts +125 -0
  25. package/dist/sdk/endpoints.d.ts +58 -0
  26. package/dist/sdk/json-schemas.d.ts +38 -0
  27. package/dist/sdk/log.d.ts +43 -0
  28. package/dist/sdk/provenance.d.ts +87 -0
  29. package/dist/sdk/resolve-tx.d.ts +70 -0
  30. package/dist/sdk/schemas.d.ts +885 -0
  31. package/dist/sdk/site-record.d.ts +25 -0
  32. package/dist/sdk/status.d.ts +23 -0
  33. package/dist/sdk/walletkit-network.d.ts +30 -0
  34. package/dist/sdk.d.ts +46 -0
  35. package/dist/sdk.js +37789 -0
  36. package/dist/utils/http.d.ts +25 -0
  37. package/dist/utils/tunnel-config.d.ts +20 -0
  38. package/dist/version.d.ts +13 -0
  39. package/dist/wallet/FSStorage.d.ts +12 -0
  40. package/dist/wallet/SendProvider.d.ts +17 -0
  41. package/dist/wallet/Storage.d.ts +5 -0
  42. package/dist/wallet/TonConnectProvider.d.ts +48 -0
  43. package/dist/wallet/constants.d.ts +12 -0
  44. package/dist/wallet/ui.d.ts +13 -0
  45. package/package.json +105 -0
  46. package/skills/mesh-deploy.md +283 -0
  47. package/templates/.well-known/mcp.json +44 -0
  48. package/templates/github-workflow-agentic.yml +94 -0
  49. package/templates/github-workflow.yml +76 -0
@@ -0,0 +1,5 @@
1
+ export interface NetworkConfig {
2
+ tonapiUrl: string;
3
+ daemonConfigUrl: string;
4
+ }
5
+ export declare function getNetworkConfig(testnet?: boolean): NetworkConfig;
@@ -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>;