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,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK DNS-write integration. Pulls the substance of `cli/dns.ts` into the
|
|
3
|
+
* SDK so `deploy()` can emit `awaiting_signature → dns_signing →
|
|
4
|
+
* dns_confirmed → verifying` and the MCP server's `mesh_deploy`
|
|
5
|
+
* tool can complete a `domain`-bearing deploy without the CLI.
|
|
6
|
+
*
|
|
7
|
+
* Spec: docs/v0.8/mcp-core-requirements.md §F3 (event ordering),
|
|
8
|
+
* §F4 (cancellation), §F5 (ERR_DNS_*).
|
|
9
|
+
*
|
|
10
|
+
* NO `console.*` ANYWHERE IN THIS FILE — lint-enforced.
|
|
11
|
+
*/
|
|
12
|
+
import type { DeployEvent } from './schemas';
|
|
13
|
+
export interface DnsWriteOptions {
|
|
14
|
+
/** `.ton` domain (e.g. `"myprotocol.ton"`). */
|
|
15
|
+
domain: string;
|
|
16
|
+
/** Bag id to publish in the `storage` DNS record. */
|
|
17
|
+
bag_id: string;
|
|
18
|
+
/** Optional 64-hex ADNL to publish as the `site` DNS record. */
|
|
19
|
+
site_adnl?: string | null;
|
|
20
|
+
/** Default false → mainnet. */
|
|
21
|
+
testnet?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* `Tonkeeper`, `MyTonWallet`, etc. — substring match against the
|
|
24
|
+
* TonConnect manifest's wallet list. Defaults to `Tonkeeper`.
|
|
25
|
+
*/
|
|
26
|
+
connector_name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional Toncenter API key for the tx-hash resolve. The agentic path
|
|
29
|
+
* sources this from `~/.config/ton/config.json`; the TonConnect path has no
|
|
30
|
+
* such config, so without a key the resolve hits the public per-IP rate
|
|
31
|
+
* limit and `dns_tx_hash` may come back null even on a landed write. (#120)
|
|
32
|
+
*/
|
|
33
|
+
toncenter_api_key?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface DnsWriteControl {
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}
|
|
38
|
+
/** Outcome the caller surfaces to the user / consumer. */
|
|
39
|
+
export interface DnsWriteResult {
|
|
40
|
+
/**
|
|
41
|
+
* The signed message BOC returned by TonConnect. NOT the on-chain tx
|
|
42
|
+
* hash — that requires a follow-up TONAPI lookup. Surface as
|
|
43
|
+
* `message_boc` in `next_actions`, not as `dns_tx_hash`.
|
|
44
|
+
*/
|
|
45
|
+
message_boc: string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Real on-chain transaction hash, resolved via Toncenter v3's
|
|
48
|
+
* `transactionsByMessage` lookup (computed from the BOC cell hash).
|
|
49
|
+
* `null` if Toncenter's index hadn't caught up by the time the DNS
|
|
50
|
+
* poll succeeded — `message_boc` is still the indexable identifier.
|
|
51
|
+
*/
|
|
52
|
+
tx_hash: string | null;
|
|
53
|
+
/**
|
|
54
|
+
* True when the tx-hash resolve was rate-limited / unauthorized by Toncenter
|
|
55
|
+
* (so `tx_hash` is null because the resolver never had a fair chance, not
|
|
56
|
+
* because the tx isn't indexed). Lets the caller hint "supply a Toncenter
|
|
57
|
+
* API key" rather than a silent null. (#120)
|
|
58
|
+
*/
|
|
59
|
+
tx_resolve_throttled: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Whether a Toncenter API key backed the tx-hash resolve. When false and
|
|
62
|
+
* `tx_hash` is null, the public per-IP rate limit / slow index is the likely
|
|
63
|
+
* cause (not a hard 429), so the caller should advise setting a key — the
|
|
64
|
+
* #120 throttle flag only catches hard rate-limits, missing the common
|
|
65
|
+
* no-key case. (#132)
|
|
66
|
+
*/
|
|
67
|
+
resolver_api_key_used: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Drive the TonConnect-mediated `.ton` DNS record write. Yields F3 event
|
|
71
|
+
* phases in order:
|
|
72
|
+
* awaiting_signature (with signing_url) → dns_signing (after wallet
|
|
73
|
+
* returns the signed message) → dns_confirmed (after TONAPI polling
|
|
74
|
+
* sees the record) → verifying (TONAPI bag accessibility probe).
|
|
75
|
+
*
|
|
76
|
+
* The caller (deploy()) tracks `phase_at_cancel` / `bag_id` for F4
|
|
77
|
+
* cancellation accuracy; this generator throws bare ERR_CANCELLED on
|
|
78
|
+
* abort and the caller decorates with F4 `data`. `wallet.dispose()`
|
|
79
|
+
* always runs via finally so the TonConnect bridge listener never leaks.
|
|
80
|
+
*/
|
|
81
|
+
export declare function writeDnsRecord(opts: DnsWriteOptions, control?: DnsWriteControl): AsyncGenerator<DeployEvent, DnsWriteResult, void>;
|
|
82
|
+
export interface DnsWriteAgenticOptions {
|
|
83
|
+
domain: string;
|
|
84
|
+
bag_id: string;
|
|
85
|
+
site_adnl?: string | null;
|
|
86
|
+
testnet?: boolean;
|
|
87
|
+
/** Optional override for the config file location. */
|
|
88
|
+
config_path?: string;
|
|
89
|
+
/** Optional wallet selector (id, name, or address). */
|
|
90
|
+
wallet_label?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface DnsWriteAgenticControl {
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
}
|
|
95
|
+
export interface DnsWriteAgenticResult {
|
|
96
|
+
/** Normalized message hash (`0x<hex>`) returned by Toncenter. */
|
|
97
|
+
message_hash: string;
|
|
98
|
+
/** Wallet address that sent the batch (user-friendly). */
|
|
99
|
+
from_address: string;
|
|
100
|
+
/**
|
|
101
|
+
* Real on-chain transaction hash (`0x<hex>`), resolved via Toncenter's
|
|
102
|
+
* `transactionsByMessage` lookup. `null` if Toncenter's index hadn't
|
|
103
|
+
* caught up to the broadcast by the time the DNS poll succeeded —
|
|
104
|
+
* the message_hash is still the indexable identifier explorers use
|
|
105
|
+
* and is surfaced in `next_actions`.
|
|
106
|
+
*/
|
|
107
|
+
tx_hash: string | null;
|
|
108
|
+
/** True when the tx-hash resolve was rate-limited / unauthorized (#120). */
|
|
109
|
+
tx_resolve_throttled: boolean;
|
|
110
|
+
/** Whether a Toncenter API key backed the tx-hash resolve (#132). */
|
|
111
|
+
resolver_api_key_used: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Drive the agentic-wallet-signed `.ton` DNS record write. No human in
|
|
115
|
+
* the loop — `awaiting_signature` is emitted informationally (so the
|
|
116
|
+
* F3 phase contract stays consistent across paths) and resolves in
|
|
117
|
+
* milliseconds because the signing key is read from disk.
|
|
118
|
+
*
|
|
119
|
+
* F4 cancellation: cancellation BEFORE `dns_signing` is safe
|
|
120
|
+
* (`may_have_published: false`); cancellation AFTER `dns_signing`
|
|
121
|
+
* implies the broadcast already left this process, so the caller
|
|
122
|
+
* decorates with `may_have_published: true` (same as the TonConnect
|
|
123
|
+
* path's post-awaiting_signature semantics).
|
|
124
|
+
*/
|
|
125
|
+
export declare function writeDnsRecordAgentic(opts: DnsWriteAgenticOptions, control?: DnsWriteAgenticControl): AsyncGenerator<DeployEvent, DnsWriteAgenticResult, void>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for external service URLs the SDK + CLI talk to.
|
|
3
|
+
*
|
|
4
|
+
* Centralised here so endpoint changes (e.g. Toncenter migrating to a
|
|
5
|
+
* new domain) flip in one place rather than three.
|
|
6
|
+
*
|
|
7
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
8
|
+
*/
|
|
9
|
+
import type { AgenticNetwork } from './agentic-config';
|
|
10
|
+
/**
|
|
11
|
+
* Toncenter v3 HTTP API base URLs. Used by `ApiClientToncenter` in
|
|
12
|
+
* `agentic-sign.ts` (signing path) and `resolve-tx.ts` (tx-hash
|
|
13
|
+
* lookup). Mirror the defaults `@ton/mcp` itself uses.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TONCENTER_ENDPOINTS: Record<AgenticNetwork, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Lift our boolean `testnet` flag (the CLI / SDK input convention) to
|
|
18
|
+
* the string-discriminated `AgenticNetwork` (the config / endpoint
|
|
19
|
+
* key). `testnet === true` → `'testnet'`; anything else → `'mainnet'`.
|
|
20
|
+
*
|
|
21
|
+
* Hoisted so we don't repeat the same ternary in N places.
|
|
22
|
+
*/
|
|
23
|
+
export declare function networkFromTestnetFlag(testnet: boolean | undefined): AgenticNetwork;
|
|
24
|
+
/**
|
|
25
|
+
* Build a tonviewer.com transaction URL. Accepts hashes with or without
|
|
26
|
+
* the `0x` prefix; emits the canonical no-prefix form tonviewer expects.
|
|
27
|
+
*
|
|
28
|
+
* Note: tonviewer.com is the mainnet UI; testnet.tonviewer.com is the
|
|
29
|
+
* testnet UI. Caller is expected to know which network the hash belongs
|
|
30
|
+
* to (we don't smuggle that into the hash itself).
|
|
31
|
+
*/
|
|
32
|
+
export declare function tonviewerTxUrl(txHash: string, testnet?: boolean): string;
|
|
33
|
+
/**
|
|
34
|
+
* The ton.run SITE gateway URL for a `.ton` domain. The gateway resolves the
|
|
35
|
+
* domain's `site` record (an ADNL identity) over RLDP, so this opens in an
|
|
36
|
+
* ordinary browser once that record is on chain AND a reachable rldp-http-proxy
|
|
37
|
+
* backs the ADNL (verified 2026-06-22: foundation.ton.run → 200). Only
|
|
38
|
+
* meaningful for a deploy that writes a `site` record — a storage-only domain
|
|
39
|
+
* has no ADNL to resolve and 404s — so callers must emit it ONLY after a site
|
|
40
|
+
* record is signed, or label it as a would-be URL for a storage-only deploy
|
|
41
|
+
* (see `storageOnlyViewabilityHint`). (#70, #118)
|
|
42
|
+
*/
|
|
43
|
+
export declare function siteGatewayUrl(domain: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Human/agent-facing breadcrumb for a STORAGE-ONLY domain deploy (the only
|
|
46
|
+
* kind `deploy()` does — it never writes a `site`/ADNL record). Explains why
|
|
47
|
+
* `<domain>.ton` is not browser-openable via the ton.run RLDP gateway, what
|
|
48
|
+
* URL it WOULD resolve at once a site record + reachable gateway exist, and
|
|
49
|
+
* how to get there. When the bag is no longer seeded (`seed_status==='stopped'`)
|
|
50
|
+
* it also notes the content is not retrievable until a reachable node seeds it.
|
|
51
|
+
* (#118 — the deploy result carried no viewability signal, so a "green" deploy
|
|
52
|
+
* could 404 everywhere with no breadcrumb.)
|
|
53
|
+
*/
|
|
54
|
+
export declare function storageOnlyViewabilityHint(args: {
|
|
55
|
+
domain: string;
|
|
56
|
+
seedStatus: 'seeding' | 'stopped';
|
|
57
|
+
testnet?: boolean;
|
|
58
|
+
}): string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema export of the public zod schemas — what the MCP `tools/list`
|
|
3
|
+
* response will surface to agent clients.
|
|
4
|
+
*
|
|
5
|
+
* The schemas are generated at module-load time and frozen so a snapshot
|
|
6
|
+
* test ([V1] #11 / `test/sdk-json-schemas.test.ts`) can lock the contract
|
|
7
|
+
* shape: any accidental drift in zod definitions fails the snapshot.
|
|
8
|
+
*
|
|
9
|
+
* Run `bunx vitest run test/sdk-json-schemas.test.ts -u` to update the
|
|
10
|
+
* snapshot when an intentional schema change ships.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Opaque JSON Schema type. We deliberately don't inline the full structural
|
|
14
|
+
* type from `zod-to-json-schema` — its inferred shape against our deeply
|
|
15
|
+
* nested discriminated unions (DeployEventSchema has 9 phase variants)
|
|
16
|
+
* caused tsc to OOM at type-check time.
|
|
17
|
+
*/
|
|
18
|
+
export type JsonSchema = Record<string, unknown>;
|
|
19
|
+
export interface ToolJsonSchema {
|
|
20
|
+
/** Stable tool name as it appears in MCP `tools/list`. */
|
|
21
|
+
name: string;
|
|
22
|
+
/** Generated JSON Schema for the tool's input. */
|
|
23
|
+
input: JsonSchema;
|
|
24
|
+
/** Generated JSON Schema for the tool's output (success path). */
|
|
25
|
+
output: JsonSchema;
|
|
26
|
+
}
|
|
27
|
+
declare const SCHEMA_VERSION = "0.13.0";
|
|
28
|
+
export declare const MESH_DEPLOY_TOOL: ToolJsonSchema;
|
|
29
|
+
export declare const MESH_CHECK_ENV_TOOL: ToolJsonSchema;
|
|
30
|
+
export declare const MESH_STATUS_TOOL: ToolJsonSchema;
|
|
31
|
+
export declare const MESH_SITE_RECORD_TOOL: ToolJsonSchema;
|
|
32
|
+
export declare const ALL_TOOLS: readonly ToolJsonSchema[];
|
|
33
|
+
export declare const SUPPLEMENTARY_SCHEMAS: {
|
|
34
|
+
WalletSpec: JsonSchema;
|
|
35
|
+
DeployEvent: JsonSchema;
|
|
36
|
+
ErrorPayload: JsonSchema;
|
|
37
|
+
};
|
|
38
|
+
export { SCHEMA_VERSION };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny stderr-only structured logger. Honours the `DEBUG` env var with
|
|
3
|
+
* `debug`-compatible glob grammar so contributors familiar with that
|
|
4
|
+
* library find it ergonomic, but no runtime dep on `debug` itself.
|
|
5
|
+
*
|
|
6
|
+
* Grammar (matches `debug` semantics):
|
|
7
|
+
* DEBUG="*" — all namespaces enabled
|
|
8
|
+
* DEBUG="mesh:*" — every mesh:<sub> namespace
|
|
9
|
+
* DEBUG="mesh:deploy,mesh:dns"
|
|
10
|
+
* — specific namespaces only
|
|
11
|
+
* DEBUG="" | unset — fully disabled
|
|
12
|
+
* DEBUG="*,-mesh:resolve-tx" — wildcard with exclusion
|
|
13
|
+
*
|
|
14
|
+
* Output always goes to STDERR. Never stdout — the CLI's `--json-output`
|
|
15
|
+
* mode requires stdout to remain valid JSON, and the MCP server's stdio
|
|
16
|
+
* transport requires stdout to be JSON-RPC frames only. Both would break
|
|
17
|
+
* if logger output landed on stdout. Tests cover this invariant.
|
|
18
|
+
*
|
|
19
|
+
* NO `console.*` IN THIS FILE — uses `process.stderr.write` directly.
|
|
20
|
+
*/
|
|
21
|
+
export interface SdkLogger {
|
|
22
|
+
/** Always emitted when the namespace is enabled. */
|
|
23
|
+
debug(message: string, data?: unknown): void;
|
|
24
|
+
/** Always emitted when the namespace is enabled. */
|
|
25
|
+
info(message: string, data?: unknown): void;
|
|
26
|
+
/** Always emitted when the namespace is enabled. */
|
|
27
|
+
warn(message: string, data?: unknown): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build a logger for `namespace`. The enabled state is computed ONCE at
|
|
31
|
+
* construction time (it doesn't react to runtime env changes). The
|
|
32
|
+
* returned logger is cheap when disabled — each method short-circuits
|
|
33
|
+
* without formatting the message.
|
|
34
|
+
*
|
|
35
|
+
* Convention: namespaces follow `mesh:<area>` where area mirrors
|
|
36
|
+
* the SDK module name (`deploy`, `dns`, `agentic-sign`, `resolve-tx`).
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSdkLogger(namespace: string): SdkLogger;
|
|
39
|
+
/**
|
|
40
|
+
* Probe variant — exposed for tests so they can inject a controlled
|
|
41
|
+
* `debugVar` instead of mutating `process.env`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isNamespaceEnabledForTesting(namespace: string, debugVar: string | undefined): boolean;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance manifest (#34) — a signed claim the deployer publishes inside
|
|
3
|
+
* the bag at `.well-known/ton-deploy.json`, so a verifier can confirm
|
|
4
|
+
* "this `.ton` domain was deployed by this wallet, with this kit, on this
|
|
5
|
+
* date".
|
|
6
|
+
*
|
|
7
|
+
* Design notes:
|
|
8
|
+
* - The claim deliberately does NOT carry `bag_id` (it lives inside the
|
|
9
|
+
* bag, whose id is the content hash — including bag_id would be
|
|
10
|
+
* circular) nor `dns_tx_hash` (not known until after the bag exists).
|
|
11
|
+
* The bag_id ↔ domain binding is provided by the on-chain DNS record,
|
|
12
|
+
* which the deployer's wallet signed in the change_dns_record tx.
|
|
13
|
+
* - Signing is feasible only on the agentic path (we hold an Ed25519
|
|
14
|
+
* operator/standard key). TonConnect can't sign arbitrary bytes, so a
|
|
15
|
+
* TonConnect deploy emits an UNSIGNED manifest (`signed: false`).
|
|
16
|
+
*
|
|
17
|
+
* NO `console.*` IN THIS FILE — lint-enforced (src/sdk/*).
|
|
18
|
+
*/
|
|
19
|
+
export declare const PROVENANCE_MANIFEST_VERSION = 1;
|
|
20
|
+
export declare const PROVENANCE_KIT_NAME = "ton-mesh-harness";
|
|
21
|
+
export declare const PROVENANCE_RELPATH = ".well-known/ton-deploy.json";
|
|
22
|
+
/** The signed part of the manifest — the immutable, pre-bag-creation claim. */
|
|
23
|
+
export interface ProvenanceClaim {
|
|
24
|
+
manifest_version: number;
|
|
25
|
+
kit: string;
|
|
26
|
+
kit_version: string;
|
|
27
|
+
domain: string;
|
|
28
|
+
/** Deployer wallet address; null when unknown at write time (TonConnect). */
|
|
29
|
+
deployer_address: string | null;
|
|
30
|
+
/** ISO-8601 UTC. */
|
|
31
|
+
deployed_at: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ProvenanceManifest extends ProvenanceClaim {
|
|
34
|
+
signed: boolean;
|
|
35
|
+
/** Ed25519 public key (hex) that signed the claim; null when unsigned. */
|
|
36
|
+
public_key: string | null;
|
|
37
|
+
/** Ed25519 detached signature over the canonical claim (base64); null when unsigned. */
|
|
38
|
+
signature: string | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Deterministic serialization of the claim — sorted keys, no insignificant
|
|
42
|
+
* whitespace — so signer and verifier hash byte-identical input.
|
|
43
|
+
*/
|
|
44
|
+
export declare function canonicalizeClaim(claim: ProvenanceClaim): string;
|
|
45
|
+
/**
|
|
46
|
+
* Extract a 32-byte Ed25519 seed from a hex private key. Accepts a 32-byte
|
|
47
|
+
* (64 hex) seed or a 64-byte (128 hex) combined keypair — the seed is the
|
|
48
|
+
* first 32 bytes either way (matches @ton/mcp's convention).
|
|
49
|
+
*/
|
|
50
|
+
export declare function seedFromHex(privateKeyHex: string): Buffer;
|
|
51
|
+
/** Build a manifest from a claim; sign it if a seed is provided. */
|
|
52
|
+
export declare function buildManifest(claim: ProvenanceClaim, seed?: Buffer | null): ProvenanceManifest;
|
|
53
|
+
export interface ProvenanceVerifyResult {
|
|
54
|
+
signed: boolean;
|
|
55
|
+
valid: boolean;
|
|
56
|
+
claim: ProvenanceClaim;
|
|
57
|
+
reason?: string;
|
|
58
|
+
}
|
|
59
|
+
/** Verify a manifest's signature (if any) against its embedded public key. */
|
|
60
|
+
export declare function verifyManifest(manifest: ProvenanceManifest): ProvenanceVerifyResult;
|
|
61
|
+
/** Write the manifest into `<sourceDir>/.well-known/ton-deploy.json`. */
|
|
62
|
+
export declare function writeManifest(sourceDir: string, manifest: ProvenanceManifest): string;
|
|
63
|
+
export interface EmitProvenanceParams {
|
|
64
|
+
sourceDir: string;
|
|
65
|
+
domain: string;
|
|
66
|
+
walletKind: 'tonconnect' | 'agentic';
|
|
67
|
+
testnet: boolean;
|
|
68
|
+
/** For the agentic path: how to locate the signing wallet. */
|
|
69
|
+
agentic?: {
|
|
70
|
+
config_path?: string;
|
|
71
|
+
wallet_label?: string;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export interface EmitProvenanceResult {
|
|
75
|
+
written: boolean;
|
|
76
|
+
file?: string;
|
|
77
|
+
signed?: boolean;
|
|
78
|
+
/** Set when `written` is false — the (non-fatal) reason emission was skipped. */
|
|
79
|
+
reason?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Best-effort provenance emission shared by the SDK deploy() hook and the
|
|
83
|
+
* CLI adapter. NEVER throws — any failure returns `{ written: false,
|
|
84
|
+
* reason }`. Signs on the agentic path (operator/standard key); emits an
|
|
85
|
+
* unsigned claim on TonConnect (no address known, can't sign).
|
|
86
|
+
*/
|
|
87
|
+
export declare function emitProvenanceManifest(params: EmitProvenanceParams): EmitProvenanceResult;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the on-chain transaction hash for a broadcast we already sent.
|
|
3
|
+
*
|
|
4
|
+
* `agenticSignAndSend` returns Toncenter's normalized external-in
|
|
5
|
+
* *message* hash. That's NOT the transaction hash explorers display.
|
|
6
|
+
* To upgrade `dns_tx_hash` from null → real value, we look up the
|
|
7
|
+
* resulting tx via Toncenter v3's `/api/v3/transactionsByMessage`
|
|
8
|
+
* endpoint. Best-effort: returns null on timeout / 404 / network error
|
|
9
|
+
* rather than throwing — the caller decides whether to surface null
|
|
10
|
+
* with a fix-hint or wait longer.
|
|
11
|
+
*
|
|
12
|
+
* Toncenter's tx index OFTEN catches up within ~5-15s of broadcast, but
|
|
13
|
+
* NOT always before TONAPI's DNS-record poll succeeds: on 2026-06-25 a
|
|
14
|
+
* live mainnet deploy saw TONAPI propagate the storage record FIRST, so
|
|
15
|
+
* the resolve had not finished when the DNS poll returned (#117). The
|
|
16
|
+
* resolve runs in parallel with the propagation poll and adds latency
|
|
17
|
+
* only when still pending at the grace cutoff (`TX_HASH_GRACE_MS` in
|
|
18
|
+
* dns-helpers.ts). Because the order is not guaranteed, `dns_tx_hash` is
|
|
19
|
+
* best-effort and may be null even on a fully-successful deploy.
|
|
20
|
+
*
|
|
21
|
+
* Spec: docs/v0.8/mcp-core-requirements.md §F2 (DeployResult.dns_tx_hash).
|
|
22
|
+
*
|
|
23
|
+
* NO `console.*` IN THIS FILE — lint-enforced.
|
|
24
|
+
*/
|
|
25
|
+
import type { AgenticNetwork } from './agentic-config';
|
|
26
|
+
/**
|
|
27
|
+
* Compute the normalized external-in message hash per TEP-467 — the
|
|
28
|
+
* `hash_norm` value Toncenter indexes (NOT the raw cell hash). For an
|
|
29
|
+
* `external-in` message, normalization zeros `src` (→ addr_none) and
|
|
30
|
+
* `import_fee` (→ 0) before hashing. Other fields (dest, init, body)
|
|
31
|
+
* are preserved.
|
|
32
|
+
*
|
|
33
|
+
* Spec: https://docs.ton.org/ecosystem/ton-connect/message-lookup
|
|
34
|
+
*
|
|
35
|
+
* @returns hex (no `0x`), or `null` if the BOC isn't a parseable
|
|
36
|
+
* external-in message.
|
|
37
|
+
*/
|
|
38
|
+
export declare function normalizedExternalInHashHex(bocBase64: string): string | null;
|
|
39
|
+
export interface ResolveTxOptions {
|
|
40
|
+
/** Total time to keep polling. Default 60s. */
|
|
41
|
+
timeout_ms?: number;
|
|
42
|
+
/** Pause between polls. Default 2s. */
|
|
43
|
+
interval_ms?: number;
|
|
44
|
+
/** Cancel the resolve early. */
|
|
45
|
+
signal?: AbortSignal;
|
|
46
|
+
/** Optional Toncenter API key (lifts the per-IP rate limit). */
|
|
47
|
+
toncenter_api_key?: string;
|
|
48
|
+
}
|
|
49
|
+
/** Outcome of a tx-hash resolve. */
|
|
50
|
+
export interface TxHashResolution {
|
|
51
|
+
/** Tx hash as `0x<hex>` if Toncenter indexed the message, else null. */
|
|
52
|
+
txHash: string | null;
|
|
53
|
+
/**
|
|
54
|
+
* True when the resolve kept hitting auth / rate-limit / 5xx responses and
|
|
55
|
+
* never got a fair chance — as opposed to the tx simply not being indexed
|
|
56
|
+
* yet. Only meaningful when `txHash` is null; lets the caller surface "add a
|
|
57
|
+
* Toncenter API key" instead of an indistinguishable silent null. (#120)
|
|
58
|
+
*/
|
|
59
|
+
throttled: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Look up the transaction whose inbound message has the given hash.
|
|
63
|
+
*
|
|
64
|
+
* @param messageHashHex Normalized message hash returned by
|
|
65
|
+
* `ApiClientToncenter.sendBoc()` — either `0x<hex>` or bare hex.
|
|
66
|
+
* @returns `{ txHash, throttled }` — `txHash` is `0x<hex>` if Toncenter has
|
|
67
|
+
* indexed the message, else null (with `throttled` distinguishing a
|
|
68
|
+
* rate-limited/unauthorized resolve from a not-yet-indexed one).
|
|
69
|
+
*/
|
|
70
|
+
export declare function resolveTxHashFromMessageHash(messageHashHex: string, network: AgenticNetwork, opts?: ResolveTxOptions): Promise<TxHashResolution>;
|