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,103 @@
1
+ /** All daemon binaries live here. Created on demand by callers. */
2
+ export declare const BIN_DIR: string;
3
+ /**
4
+ * Atomically download `url` to `dest`. Uses `curl -fsSL` (HTTPS, follow
5
+ * redirects, fail on HTTP error) and writes through a `.tmp` file
6
+ * renamed via Node's `renameSync` so the move is portable across
7
+ * darwin/linux/win32 (`mv` isn't on PATH on stock Windows).
8
+ *
9
+ * Throws on non-zero curl exit. The caller is responsible for `chmod +x`
10
+ * and quarantine removal (see `chmodExecutable` / `removeQuarantine`).
11
+ */
12
+ export declare function downloadFile(url: string, dest: string): void;
13
+ /**
14
+ * Apply executable permission on POSIX. No-op on Windows (the .exe
15
+ * extension is the executable marker there).
16
+ */
17
+ export declare function chmodExecutable(absPath: string): void;
18
+ /**
19
+ * Strip platform-specific download quarantine markers:
20
+ * - macOS: `xattr -c <file>` removes `com.apple.quarantine` (and
21
+ * other extended attributes — equivalent to a fresh download).
22
+ * - Windows: PowerShell `Unblock-File` clears the
23
+ * `Zone.Identifier` alternate data stream that triggers the
24
+ * "this file came from another computer" prompt.
25
+ * - Linux: no-op (no quarantine system).
26
+ *
27
+ * Failures are silent — the binary may still launch fine.
28
+ */
29
+ export declare function removeQuarantine(absPath: string): void;
30
+ /**
31
+ * Spec for a daemon installer. `installBinary` and `resolveBinaryPaths`
32
+ * consume one. Lets the two release-asset-shaped installers
33
+ * (tonutils-storage, rldp-http-proxy) live as ~25 LOC each instead of
34
+ * 85 LOC of copy-paste.
35
+ */
36
+ export interface BinaryInstallerSpec {
37
+ /** Human-readable banner name (`Downloading <name> (<version>)…`). */
38
+ name: string;
39
+ /** Pinned version string written into the on-disk version file. */
40
+ version: string;
41
+ /** Base file name; `.exe` is appended on win32 automatically. */
42
+ exeName: string;
43
+ /** Version-stamp file name (kept next to the binary in BIN_DIR). */
44
+ versionFileName: string;
45
+ /** `${process.platform}-${process.arch}` → release asset file name. */
46
+ assetMap: Record<string, string>;
47
+ /** Builds the download URL for a given (version, asset). */
48
+ downloadUrl: (version: string, asset: string) => string;
49
+ /** Trailing line appended to the "no asset for $platform-$arch" error. */
50
+ unsupportedHint: string;
51
+ /**
52
+ * Pinned SHA-256 hashes per `${platform}-${arch}` key. Verified after
53
+ * download — mismatch deletes the partial file and throws. Required
54
+ * for supply-chain integrity: without it, a compromised GitHub
55
+ * release asset or MITM'd CDN endpoint would execute as the user.
56
+ * Codex pre-GA review round 11 (self-audit) caught the missing
57
+ * verification. v0.8 hashes pinned for the version of each binary
58
+ * embedded above; bump them in lockstep with `version` when
59
+ * upgrading.
60
+ *
61
+ * An empty / missing entry for the current platform-arch falls back
62
+ * to TOFU (trust on first use) + a loud stderr warning. Hashes for
63
+ * ALL supported platforms should be pinned before GA tag.
64
+ */
65
+ expectedSha256?: Partial<Record<string, string>>;
66
+ }
67
+ export interface BinaryPaths {
68
+ binDir: string;
69
+ daemon: string;
70
+ versionFile: string;
71
+ }
72
+ export declare function resolveBinaryPaths(spec: BinaryInstallerSpec): BinaryPaths;
73
+ export interface InstallBinaryOptions {
74
+ /** Suppress the human-readable download banner (JSON-output mode). */
75
+ silent?: boolean;
76
+ }
77
+ /**
78
+ * Idempotent installer: returns immediately if the binary at
79
+ * `spec.exeName` already matches `spec.version`; otherwise downloads
80
+ * the platform-appropriate asset, chmods it, strips quarantine, and
81
+ * writes the version stamp.
82
+ *
83
+ * Throws if no asset is mapped for the current platform/arch.
84
+ */
85
+ export declare function installBinary(spec: BinaryInstallerSpec, opts?: InstallBinaryOptions): void;
86
+ /**
87
+ * Verify a downloaded file's SHA-256 against an expected hash. Throws
88
+ * + `unlinkSync`'s the file on mismatch so the next install attempt
89
+ * starts fresh. Pass `expected: undefined` to opt into TOFU (emits a
90
+ * loud stderr warning and proceeds).
91
+ *
92
+ * Public helper exported for installers that don't go through
93
+ * `installBinary` — e.g. `src/daemon/installer.ts` downloads two
94
+ * binaries + two config files in its own loop. Used inline there
95
+ * after each `downloadFile` call.
96
+ */
97
+ export declare function verifyFileSha256(args: {
98
+ name: string;
99
+ version: string;
100
+ platformKey: string;
101
+ filePath: string;
102
+ expected: string | undefined;
103
+ }): void;
@@ -0,0 +1,30 @@
1
+ /** @internal Exported for the #101 regression test (TOFU-gap guard). */
2
+ export declare const STORAGE_DAEMON_HASHES: Record<string, string>;
3
+ /** @internal Exported for the #101 regression test (TOFU-gap guard). */
4
+ export declare const STORAGE_DAEMON_CLI_HASHES: Record<string, string>;
5
+ export interface DaemonPaths {
6
+ binDir: string;
7
+ daemon: string;
8
+ cli: string;
9
+ mainnetConfig: string;
10
+ testnetConfig: string;
11
+ versionFile: string;
12
+ }
13
+ /**
14
+ * Get all daemon-related file paths
15
+ */
16
+ export declare function getDaemonPaths(): DaemonPaths;
17
+ export interface EnsureBinariesOptions {
18
+ /** Suppress the download banner. Use when stdout must stay JSON-clean. */
19
+ silent?: boolean;
20
+ }
21
+ /**
22
+ * Ensure daemon binaries (storage-daemon + storage-daemon-cli) are
23
+ * installed and up-to-date. Also downloads the appropriate network
24
+ * config JSON if missing. Idempotent.
25
+ *
26
+ * All progress banners go to STDERR so `--json-output` stdout stays
27
+ * parseable (matches the convention `tonutils-installer.ts` /
28
+ * `rldp-http-proxy-installer.ts` use via `installer-utils`).
29
+ */
30
+ export declare function ensureBinaries(useTestnet?: boolean, opts?: EnsureBinariesOptions): void;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Advisory line when a `--daemon-mode service` unit will NOT survive an
3
+ * unattended reboot — i.e. the host is Linux AND systemd lingering is disabled
4
+ * for the current user. Returns `null` when:
5
+ * - not Linux (launchd handles reboot via RunAtLoad), or
6
+ * - lingering is already enabled, or
7
+ * - we can't determine it (loginctl absent / user not known to logind) —
8
+ * stay quiet rather than print a command that might not apply.
9
+ */
10
+ export declare function lingerAdvisory(): string | null;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Platform detection and binary naming utilities
3
+ */
4
+ export declare const PLATFORM_MAP: Record<string, string>;
5
+ /**
6
+ * Get the platform key for the current system
7
+ * @throws {Error} if platform is not supported
8
+ */
9
+ export declare function getPlatformKey(): string;
10
+ /**
11
+ * Get the release-asset name for the current platform.
12
+ *
13
+ * Asset naming on ton-blockchain/ton GitHub releases:
14
+ * - macOS / Linux: `<base>-<platform-suffix>` (e.g. `storage-daemon-mac-arm64`)
15
+ * - Windows: `<base>.exe` (NO platform suffix — single
16
+ * x86_64 asset across Win
17
+ * architectures)
18
+ *
19
+ * Pre-rc11 the Windows branch returned `<base>-<suffix>.exe` (e.g.
20
+ * `storage-daemon-win-x86-64.exe`) which doesn't exist on GitHub —
21
+ * Windows users got a 404 from curl. Self-audit caught this while
22
+ * pinning SHA-256 hashes for the legacy installer.
23
+ *
24
+ * @param base - Base binary name
25
+ */
26
+ export declare function getBinaryName(base: 'storage-daemon' | 'storage-daemon-cli'): string;
27
+ /**
28
+ * Resolve the platform key used to look up a pinned SHA-256 for the legacy
29
+ * storage-daemon binaries (src/daemon/installer.ts).
30
+ *
31
+ * TON publishes a SINGLE x86-64 Windows asset (`storage-daemon.exe`) for all
32
+ * Windows architectures — `getBinaryName` returns that one file regardless of
33
+ * arch — but the hash map only pins `win32-x64`. Without this mapping,
34
+ * `win32-arm64` / `win32-ia32` look up an `undefined` hash and the integrity
35
+ * check is silently skipped (trust-on-first-use), installing an unverified —
36
+ * and on 32-bit, unrunnable — binary.
37
+ *
38
+ * - `win32-arm64` → `win32-x64`: the downloaded file IS the x64 `.exe`, which
39
+ * 64-bit ARM Windows runs under its built-in x64 emulation; verify it against
40
+ * the known x64 hash.
41
+ * - `win32-ia32` → throw: a 32-bit OS cannot run an x64 binary, so fail fast
42
+ * with a clear message instead of installing a broken, unverified binary.
43
+ * - every other key passes through unchanged.
44
+ *
45
+ * @throws {Error} on 32-bit Windows (`win32-ia32`).
46
+ */
47
+ export declare function daemonHashKey(platformKey: string): string;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Probe TCP ports in `[min, max]` on 127.0.0.1. Returns the first port
3
+ * that accepts a listener. Throws if the entire range is busy.
4
+ *
5
+ * Default range matches the legacy export from `tonutils-process.ts`
6
+ * (7100–7199) so call sites that did `findFreePort()` without arguments
7
+ * keep working.
8
+ */
9
+ export declare function findFreeTcpPort(min?: number, max?: number): Promise<number>;
10
+ /**
11
+ * Probe UDP ports in `[min, max]` on 0.0.0.0. Returns the first that
12
+ * binds. Throws if every port in the range is busy.
13
+ */
14
+ export declare function findFreeUdpPort(min?: number, max?: number): Promise<number>;
@@ -0,0 +1,10 @@
1
+ import { type BinaryPaths, type InstallBinaryOptions } from './installer-utils';
2
+ export declare const RLDP_HTTP_PROXY_VERSION: string;
3
+ export type RldpHttpProxyPaths = BinaryPaths;
4
+ export type EnsureRldpHttpProxyBinaryOptions = InstallBinaryOptions;
5
+ export declare function getRldpHttpProxyPaths(): RldpHttpProxyPaths;
6
+ /**
7
+ * Idempotently install the rldp-http-proxy binary at the expected version.
8
+ * No-ops when already installed.
9
+ */
10
+ export declare function ensureRldpHttpProxyBinary(opts?: EnsureRldpHttpProxyBinaryOptions): void;
@@ -0,0 +1,36 @@
1
+ export declare const SEEDS_ROOT: string;
2
+ export interface ServiceMeta {
3
+ bag_id: string;
4
+ label: string;
5
+ db_dir: string;
6
+ api_port: number;
7
+ network_config_path: string | null;
8
+ daemon_path: string;
9
+ created_at: string;
10
+ }
11
+ export interface ServiceStatus {
12
+ bag_id: string;
13
+ label: string;
14
+ running: boolean;
15
+ api_url: string;
16
+ db_dir: string;
17
+ }
18
+ export declare class ServiceError extends Error {
19
+ }
20
+ export declare function serviceLabel(bagId: string): string;
21
+ export declare function seedDir(bagId: string): string;
22
+ export declare function buildLaunchdPlist(meta: ServiceMeta): string;
23
+ export declare function buildSystemdUnit(meta: ServiceMeta): string;
24
+ /**
25
+ * Install + load a per-bag seed service. `db_dir` must already contain the
26
+ * created bag (the daemon will resume seeding it from there).
27
+ */
28
+ export declare function installService(meta: ServiceMeta): void;
29
+ export declare function listServices(): ServiceStatus[];
30
+ /**
31
+ * Stop + unload a bag's seed service. Removes the unit file; removes the
32
+ * seed dir (db + metadata) only when `removeDb` is true.
33
+ */
34
+ export declare function stopService(bagId: string, opts?: {
35
+ removeDb?: boolean;
36
+ }): void;
@@ -0,0 +1,10 @@
1
+ import { type BinaryPaths, type InstallBinaryOptions } from './installer-utils';
2
+ export type TonutilsPaths = BinaryPaths;
3
+ export type EnsureTonutilsBinaryOptions = InstallBinaryOptions;
4
+ export declare function getTonutilsPaths(): TonutilsPaths;
5
+ /**
6
+ * Ensure the tonutils-storage binary is installed and at the expected
7
+ * version. Idempotent — does nothing if the binary is already present
8
+ * with a matching .tonutils-version file.
9
+ */
10
+ export declare function ensureTonutilsBinary(opts?: EnsureTonutilsBinaryOptions): void;
@@ -0,0 +1,90 @@
1
+ import { type ChildProcess } from 'child_process';
2
+ import { findFreeTcpPort, findFreeUdpPort } from './ports';
3
+ export interface TonutilsHandle {
4
+ apiUrl: string;
5
+ dbDir: string;
6
+ process: ChildProcess;
7
+ kill: () => void;
8
+ reachable?: boolean | null;
9
+ }
10
+ export { findFreeTcpPort as findFreePort, findFreeUdpPort };
11
+ export declare function ensureTonutilsNetworkConfig(testnet: boolean): Promise<string | undefined>;
12
+ export interface EnsureTonutilsConfigOptions {
13
+ tunnelConfigPath?: string;
14
+ externalIp?: string;
15
+ listenPort?: number;
16
+ }
17
+ export interface AnnounceConfig {
18
+ externalIp?: string;
19
+ listenPort?: number;
20
+ }
21
+ export declare function announceIpFromEnv(env: NodeJS.ProcessEnv): string | undefined;
22
+ export declare function announcePortFromEnv(env: NodeJS.ProcessEnv): number | undefined;
23
+ export declare function parseAnnounceEnv(env: NodeJS.ProcessEnv): AnnounceConfig;
24
+ export declare function resolveAnnounce(explicit: AnnounceConfig, env: NodeJS.ProcessEnv): AnnounceConfig;
25
+ export declare function ensureTonutilsConfig(daemonPath: string, dbDir: string, cfgOpts?: EnsureTonutilsConfigOptions): Promise<void>;
26
+ export declare function parseServerMode(output: string): boolean | null;
27
+ export interface StartTonutilsDaemonOptions {
28
+ tunnelConfigPath?: string;
29
+ /** Path to a global network config (testnet); omit for mainnet default. */
30
+ networkConfigPath?: string;
31
+ /**
32
+ * Cloud-seeder announce overrides (#69), already validated by the caller.
33
+ * Take precedence (per-field) over the MESH_ANNOUNCE_IP / _PORT env
34
+ * vars; when both are omitted the env vars are used (the #67 behaviour).
35
+ */
36
+ externalIp?: string;
37
+ listenPort?: number;
38
+ /**
39
+ * Persistent db dir (#37 service mode). When set, the daemon uses this
40
+ * dir instead of an ephemeral mkdtemp one, and kill() does NOT delete it
41
+ * (the OS service unit resumes seeding from here). Omit for the default
42
+ * ephemeral behaviour.
43
+ */
44
+ dbDir?: string;
45
+ }
46
+ export declare function startTonutilsDaemon(opts?: StartTonutilsDaemonOptions): Promise<TonutilsHandle>;
47
+ export interface TonutilsBagSummary {
48
+ bag_id: string;
49
+ description: string;
50
+ downloaded: number;
51
+ size: number;
52
+ files_count: number;
53
+ dir_name: string;
54
+ completed: boolean;
55
+ header_loaded: boolean;
56
+ info_loaded: boolean;
57
+ active: boolean;
58
+ seeding: boolean;
59
+ }
60
+ export interface TonutilsBagDetails extends TonutilsBagSummary {
61
+ piece_size: number;
62
+ bag_size: number;
63
+ merkle_hash: string;
64
+ path: string;
65
+ files: Array<{
66
+ index: number;
67
+ name: string;
68
+ size: number;
69
+ }>;
70
+ peers?: Array<{
71
+ addr: string;
72
+ id: string;
73
+ }>;
74
+ }
75
+ export declare function tonutilsCreate(handle: TonutilsHandle, args: {
76
+ path: string;
77
+ description: string;
78
+ }): Promise<{
79
+ bag_id: string;
80
+ }>;
81
+ export declare function tonutilsDetails(handle: TonutilsHandle, bagId: string): Promise<TonutilsBagDetails>;
82
+ export declare function tonutilsList(handle: TonutilsHandle): Promise<{
83
+ bags: TonutilsBagSummary[];
84
+ }>;
85
+ export declare function tonutilsRemove(handle: TonutilsHandle, args: {
86
+ bag_id: string;
87
+ with_files?: boolean;
88
+ }): Promise<{
89
+ ok: boolean;
90
+ }>;
@@ -0,0 +1,25 @@
1
+ import { Address, Cell } from '@ton/ton';
2
+ /**
3
+ * RFC 4648 §5 base64url: `+`→`-`, `/`→`_`, strip `=` padding. Tonkeeper's
4
+ * `bin` parameter expects the message-body BOC encoded this way.
5
+ */
6
+ export declare function toBase64Url(buf: Buffer): string;
7
+ export interface TonkeeperTransferLink {
8
+ /** Destination contract (here: the `.ton` domain NFT item). */
9
+ to: Address;
10
+ /** Attached value in nanoTON; must be positive (covers gas). */
11
+ amountNano: bigint;
12
+ /** Message body cell (here: a `change_dns_record` op). */
13
+ body: Cell;
14
+ /** Encode `to` in testnet form (`testOnly` address flag). */
15
+ testnet?: boolean;
16
+ }
17
+ /**
18
+ * Build a Tonkeeper transfer deeplink for a single signed message.
19
+ *
20
+ * The address is encoded bounceable (it targets a deployed contract) and
21
+ * url-safe; the body is serialized to BOC and base64url-encoded into `bin`.
22
+ * Both `amount` and `bin` use URL-safe characters, so the query string is
23
+ * left intact by `URLSearchParams`.
24
+ */
25
+ export declare function buildTonkeeperTransferDeeplink(link: TonkeeperTransferLink): string;
package/dist/dns.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { Address, Cell } from '@ton/ton';
2
+ export interface DnsRegistrationOptions {
3
+ domain: string;
4
+ bagId: string;
5
+ }
6
+ export interface DnsCheckResult {
7
+ registered: boolean;
8
+ currentBagId?: string;
9
+ }
10
+ export declare function buildDnsStorageRecord(bagId: string): Cell;
11
+ export declare function buildDnsAdnlRecord(adnlHex: string, flags?: number): Cell;
12
+ export declare function buildChangeDnsRecordBody(bagId: string): Cell;
13
+ export declare function buildChangeDnsSiteRecordBody(adnlHex: string, flags?: number): Cell;
14
+ export declare function getDomainNftAddress(domain: string, testnet?: boolean): Promise<Address>;
15
+ interface TonApiDnsRecord {
16
+ storage?: string | {
17
+ bag_id?: string;
18
+ };
19
+ sites?: string[];
20
+ }
21
+ export declare function extractStorageBagId(data: TonApiDnsRecord | null | undefined): string | null;
22
+ /**
23
+ * @param opts.silent suppresses ora spinner + console.log fallback message
24
+ * so the SDK / MCP path can call this without polluting stdout (the MCP
25
+ * stdio framing breaks if console.log writes to stdout). CLI continues
26
+ * to pass silent: false (default) for human output.
27
+ */
28
+ export declare function pollDnsRecord(domain: string, expectedBagId: string, timeoutMs?: number, intervalMs?: number, testnet?: boolean, opts?: {
29
+ silent?: boolean;
30
+ signal?: AbortSignal;
31
+ }): Promise<boolean>;
32
+ /**
33
+ * @param opts.silent see pollDnsRecord.
34
+ */
35
+ export declare function pollDnsSiteRecord(domain: string, expectedAdnlHex: string, timeoutMs?: number, intervalMs?: number, testnet?: boolean, opts?: {
36
+ silent?: boolean;
37
+ signal?: AbortSignal;
38
+ }): Promise<boolean>;
39
+ export {};