@toon-protocol/rig 2.10.2 → 2.10.3
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/README.md +85 -4
- package/dist/{chunk-JILCXMID.js → chunk-AA4RBCSI.js} +2 -2
- package/dist/{chunk-57UY3OGX.js → chunk-FQXNLPUR.js} +5 -5
- package/dist/{chunk-R7G5NYQJ.js → chunk-RZLDFCKS.js} +1 -1
- package/dist/chunk-RZLDFCKS.js.map +1 -0
- package/dist/cli/rig.js +72 -34
- package/dist/cli/rig.js.map +1 -1
- package/dist/{network-bootstrap-KQLKALBI.js → network-bootstrap-IHQ4PWUW.js} +2 -2
- package/dist/standalone/index.js +2 -2
- package/dist/{standalone-mode-CTQKDJBL.js → standalone-mode-YMIY4GL3.js} +11 -8
- package/dist/{standalone-mode-CTQKDJBL.js.map → standalone-mode-YMIY4GL3.js.map} +1 -1
- package/package.json +3 -3
- package/dist/chunk-R7G5NYQJ.js.map +0 -1
- /package/dist/{chunk-JILCXMID.js.map → chunk-AA4RBCSI.js.map} +0 -0
- /package/dist/{chunk-57UY3OGX.js.map → chunk-FQXNLPUR.js.map} +0 -0
- /package/dist/{network-bootstrap-KQLKALBI.js.map → network-bootstrap-IHQ4PWUW.js.map} +0 -0
package/README.md
CHANGED
|
@@ -92,14 +92,22 @@ rig remote list
|
|
|
92
92
|
### 5. Fund your wallet
|
|
93
93
|
|
|
94
94
|
Pushing is paid, so your wallet needs a balance. On devnet, `rig fund` drips test
|
|
95
|
-
|
|
96
|
-
faucet URL because it infers devnet from your `origin` remote.
|
|
95
|
+
**USDC** (the settlement token) to every supported chain — it's free and needs no
|
|
96
|
+
faucet URL because it infers devnet from your `origin` remote. The drip assumes
|
|
97
|
+
your wallet already holds enough native gas (the EVM leg still best-effort tops
|
|
98
|
+
up Base Sepolia gas; hold a little SOL/MINA for the other chains).
|
|
97
99
|
|
|
98
100
|
```sh
|
|
99
|
-
rig fund # devnet
|
|
101
|
+
rig fund # devnet USDC drip, all chains (Mina can take ~75s)
|
|
102
|
+
rig fund sol # or fund a single chain: evm | sol | mina
|
|
100
103
|
rig balance # confirm the funds landed
|
|
101
104
|
```
|
|
102
105
|
|
|
106
|
+
Prefer a browser? The same faucet has a web UI at
|
|
107
|
+
**<https://faucet.devnet.toonprotocol.dev>** — pick a chain, paste an address,
|
|
108
|
+
get USDC. (See [Devnet reference](#devnet-reference-public-chains) for the API
|
|
109
|
+
routes and every deployed contract address.)
|
|
110
|
+
|
|
103
111
|
> On any non-devnet network there is no faucet: `rig fund` prints your wallet
|
|
104
112
|
> address(es) so you can fund them externally, then `rig push` draws from there.
|
|
105
113
|
|
|
@@ -187,7 +195,7 @@ rig pr status <event-id> applied
|
|
|
187
195
|
| `rig identity import` | free | write an existing phrase (read from stdin, never argv) to the keystore |
|
|
188
196
|
| `rig init` | free | one-shot repo setup: git repo + identity + `toon.*` config + repo-local git commit-author from your Nostr identity |
|
|
189
197
|
| `rig remote add/remove/list` | free | relays as REAL git remotes (`origin` = default publish target) |
|
|
190
|
-
| `rig fund [
|
|
198
|
+
| `rig fund [chain]` | free | devnet USDC drip (gas assumed) to the active identity's wallet; `chain` = evm \| sol \| mina \| all; prints addresses to fund externally off-devnet |
|
|
191
199
|
| `rig balance` | free | the active wallet's multi-chain balances |
|
|
192
200
|
| `rig clone <relay-url> <owner>/<repo-id> [dir]` | free | bootstrap a repo from TOON: relay state + SHA-verified Arweave objects → a real git repo. Shadows `git clone` |
|
|
193
201
|
| `rig fetch [remote]` | free | download the missing object delta + update `refs/remotes/<remote>/*`. Shadows `git fetch` |
|
|
@@ -322,6 +330,79 @@ the human-readable snapshot (verified live 2026-07-17), useful when auditing
|
|
|
322
330
|
|
|
323
331
|
---
|
|
324
332
|
|
|
333
|
+
## Devnet reference (public chains)
|
|
334
|
+
|
|
335
|
+
Since 2026-07-19 the TOON devnet settles on **public networks** — there is no
|
|
336
|
+
self-hosted chain infrastructure. The authoritative, machine-readable source for
|
|
337
|
+
everything below is the apex's **kind:10032 announce** on the relay; the
|
|
338
|
+
authoritative doc is
|
|
339
|
+
[toon-meta `docs/deployment.md`](https://github.com/toon-protocol/toon-meta/blob/main/docs/deployment.md).
|
|
340
|
+
|
|
341
|
+
### Endpoints
|
|
342
|
+
|
|
343
|
+
| What | URL |
|
|
344
|
+
|---|---|
|
|
345
|
+
| Faucet (web UI + API) | `https://faucet.devnet.toonprotocol.dev` |
|
|
346
|
+
| Relay (free reads, `rig clone`/`fetch`) | `wss://relay-ws.devnet.toonprotocol.dev` |
|
|
347
|
+
| Payment proxy (paid writes, BTP) | `wss://proxy.devnet.toonprotocol.dev:443` |
|
|
348
|
+
| Store DVM (ArNS buyfor/gas-station jobs, `--via`) | `https://dvm.devnet.toonprotocol.dev` |
|
|
349
|
+
|
|
350
|
+
### Faucet routes
|
|
351
|
+
|
|
352
|
+
| `POST` path | Drips |
|
|
353
|
+
|---|---|
|
|
354
|
+
| `/api/base-sepolia/request` | 1000 USDC (ungated on-chain mint) + best-effort Base Sepolia gas |
|
|
355
|
+
| `/api/solana/usdc-request` | 1000 USDC (treasury transfer, no SOL leg) |
|
|
356
|
+
| `/api/mina/usdc-request` | USDC (treasury self-mint, rate-limited token; no MINA leg) |
|
|
357
|
+
| `/api/solana/request` | 2 SOL + 1000 USDC (airdrop leg subject to the public devnet's per-IP quota) |
|
|
358
|
+
| `/api/mina/request` | 5 MINA + USDC (treasury self-mint, rate-limited token) |
|
|
359
|
+
|
|
360
|
+
Body: `{"address": "<wallet>"}`. `rig fund` hits the **USDC-only** routes
|
|
361
|
+
(`/api/base-sepolia/request`, `/api/solana/usdc-request`, `/api/mina/usdc-request`)
|
|
362
|
+
for the identity's derived wallets — it funds USDC and assumes gas is already
|
|
363
|
+
present. The combined native-plus-USDC routes above remain for manual use.
|
|
364
|
+
|
|
365
|
+
### Settlement contracts
|
|
366
|
+
|
|
367
|
+
Chain ids below are the **announced spellings** — use them verbatim with
|
|
368
|
+
`TOON_CLIENT_CHAIN=<id> rig push` to pin a settlement chain.
|
|
369
|
+
|
|
370
|
+
| Chain (`TOON_CLIENT_CHAIN`) | Payment-channel contract/program/zkApp | USDC token (6dp) | Explorer |
|
|
371
|
+
|---|---|---|---|
|
|
372
|
+
| `evm:84532` (Base Sepolia) | TokenNetwork `0x1E95493fEF46707E034b4a1945f25a8C76A1823D` (registry `0xcC9079adE929b168B54145f6d25262b64FAB9D5b`) | `0x49beE1Bca5d15Fb0963117923403F9498119a9Ce` | [base-sepolia.blockscout.com](https://base-sepolia.blockscout.com) |
|
|
373
|
+
| `solana:devnet` | program `2aEVJ8koKD8LTZrLRSGtAtU7LBt4e7QjjCgf1kzQ7Rip` | mint `xyc5J8MgKFiEN13PnfftdXxUzYH34FEvw1LCrFwN7in` | [explorer.solana.com/?cluster=devnet](https://explorer.solana.com/?cluster=devnet) |
|
|
374
|
+
| `mina:devnet` | PaymentChannel zkApp `B62qmgPhv2Xo6QVEtwjLja8UZJUtu8yapRFAR6gaoGtbM9zE5hG7Tkf` | token `B62qqN1Pu3kF2KGmqLA8EwpqfWrnFTVZJGDSDHQuQRoVt5BCFjhNz3d`<br>tokenId `9497120696276615621907376728658022802954262638363646162765282600447713419198` | [minascan.io/devnet](https://minascan.io/devnet/home) |
|
|
375
|
+
|
|
376
|
+
### Config notes (rig ≥ 2.10.2)
|
|
377
|
+
|
|
378
|
+
Keep `~/.toon-client/config.json` **minimal** — settlement parameters derive
|
|
379
|
+
from the announce. Three additions are load-bearing on today's devnet:
|
|
380
|
+
|
|
381
|
+
```jsonc
|
|
382
|
+
{
|
|
383
|
+
"feePerEvent": "1000", // = the announced route price
|
|
384
|
+
"chainRpcUrls": { // per-field overrides only
|
|
385
|
+
"evm:84532": "https://base-sepolia-rpc.publicnode.com",
|
|
386
|
+
"mina:devnet": "https://api.minascan.io/node/devnet/v1/graphql"
|
|
387
|
+
},
|
|
388
|
+
"minaChannel": { // Mina is not announce-derivable yet
|
|
389
|
+
"graphqlUrl": "https://api.minascan.io/node/devnet/v1/graphql",
|
|
390
|
+
"zkAppAddress": "B62qmgPhv2Xo6QVEtwjLja8UZJUtu8yapRFAR6gaoGtbM9zE5hG7Tkf",
|
|
391
|
+
"tokenId": "9497120696276615621907376728658022802954262638363646162765282600447713419198",
|
|
392
|
+
"networkId": "devnet"
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
- Do **not** set `supportedChains`/`tokenNetworks`/`preferredTokens` explicitly —
|
|
398
|
+
explicit topology bypasses the announce's route prices and paid writes get
|
|
399
|
+
rejected (F06).
|
|
400
|
+
- After config changes, delete `~/.toon-client/rig-topology-cache.json` (cached
|
|
401
|
+
topology can mask edits).
|
|
402
|
+
- Base Sepolia's official RPC (`sepolia.base.org`) is a load-balancer that
|
|
403
|
+
serves stale reads — channel opens need a single-backend RPC like
|
|
404
|
+
`base-sepolia-rpc.publicnode.com` (already in the snippet above).
|
|
405
|
+
|
|
325
406
|
## Strict `--json` stdout (machine consumers)
|
|
326
407
|
|
|
327
408
|
With `--json`, stdout carries **exactly one JSON document** — everything
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
checkDaemonIdentity,
|
|
5
5
|
contentTypeForPath,
|
|
6
6
|
recordKey
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FQXNLPUR.js";
|
|
8
8
|
import {
|
|
9
9
|
MAX_OBJECT_SIZE,
|
|
10
10
|
flooredUploadFee
|
|
@@ -671,4 +671,4 @@ export {
|
|
|
671
671
|
extractArweaveTxId,
|
|
672
672
|
StandalonePublisher
|
|
673
673
|
};
|
|
674
|
-
//# sourceMappingURL=chunk-
|
|
674
|
+
//# sourceMappingURL=chunk-AA4RBCSI.js.map
|
|
@@ -404,9 +404,6 @@ function resolveConflictingPath(paths) {
|
|
|
404
404
|
}
|
|
405
405
|
|
|
406
406
|
export {
|
|
407
|
-
DEFAULT_CONTENT_TYPE,
|
|
408
|
-
contentTypeForPath,
|
|
409
|
-
resolveConflictingPath,
|
|
410
407
|
RIG_CHANNEL_MAP_FILENAME,
|
|
411
408
|
resolveChannelPaths,
|
|
412
409
|
ChannelMapCorruptError,
|
|
@@ -419,6 +416,9 @@ export {
|
|
|
419
416
|
DaemonIdentityConflictError,
|
|
420
417
|
StandaloneLockError,
|
|
421
418
|
checkDaemonIdentity,
|
|
422
|
-
NonceLock
|
|
419
|
+
NonceLock,
|
|
420
|
+
DEFAULT_CONTENT_TYPE,
|
|
421
|
+
contentTypeForPath,
|
|
422
|
+
resolveConflictingPath
|
|
423
423
|
};
|
|
424
|
-
//# sourceMappingURL=chunk-
|
|
424
|
+
//# sourceMappingURL=chunk-FQXNLPUR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/standalone/network-bootstrap.ts"],"sourcesContent":["/**\n * Network bootstrap for the standalone (embedded-client) rig path (#264):\n * resolve the payment topology — uplink, ILP destinations/routes, settlement\n * chain and its on-chain parameters — from the network itself instead of\n * hand-fed constants.\n *\n * Sources, in strict precedence order (first hit wins, per field):\n *\n * 1. EXPLICIT USER CONFIG — env vars / shared client-config file fields.\n * 2. LIVE kind:10032 ANNOUNCE — the payment peer's `IlpPeerInfo` event\n * discovered on the relay-origin (the relay the paid command resolved\n * via `rig remote`, i.e. what the user pointed rig at). The announce\n * carries `btpEndpoint`/`httpEndpoint` (uplink), `ilpAddress` (channel\n * anchor), `supportedChains` + `settlementAddresses` (settlement), and\n * the out-of-band `routes` map (`{publish, store}` ILP destinations).\n * 3. GENESIS SEED — `@toon-protocol/core`'s committed genesis peer seed\n * (core >= 3.1.1 ships the live devnet apex), the offline fallback when\n * the relay is unreachable or serves no valid announce.\n *\n * Chain-level parameters the announce does NOT carry (EVM TokenNetwork\n * contract, token address, RPC URL) are derived per selected chain:\n * explicit config > announce (`tokenNetworks`/`preferredTokens`, when a peer\n * announces them) > core's deterministic chain presets (`CHAIN_PRESETS`,\n * matched by chain id — e.g. `evm:31337` is the Foundry/anvil deploy whose\n * TOON contract addresses are deterministic; `evm:base:84532` and\n * `solana:devnet` are the public networks the TOON devnet settles on since\n * the zone's self-hosted chain nodes were retired, 2026-07).\n *\n * Settlement-chain selection (#260 root cause 4) — simple and predictable:\n *\n * 1. EXPLICIT — `TOON_CLIENT_CHAIN` env / `chain` config field (family or\n * full chain id), or the first entry of an explicit `supportedChains`.\n * 2. PERSISTED CHANNEL — the chain of the most recently used live channel\n * recorded for this identity in the #262 channel map (a channel there\n * means collateral is already locked on that chain).\n * 3. FUNDED — the first announced chain (EVM or Solana, in announce\n * order) where the identity's token balance is > 0 (one `eth_call` /\n * `getTokenAccountsByOwner` per candidate).\n * 4. DEFAULT — the first EVM chain the peer announces (else the first\n * announced chain), with a printed rationale.\n *\n * This module is pure Node + `@toon-protocol/core` (rig's own core 3.x —\n * distinct from the embedded client's internal core; see\n * `../cli/standalone-mode.ts` for the coexistence note).\n */\n\nimport {\n CHAIN_PRESETS,\n GenesisPeerLoader,\n isEventExpired,\n parseIlpPeerInfo,\n resolveClientNetwork,\n type GenesisPeer,\n type IlpPeerInfo,\n} from '@toon-protocol/core';\nimport {\n queryRelay,\n type NostrEvent,\n type WebSocketFactory,\n} from '../remote-state.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** kind:10032 — ILP peer info announcement (mirrors core's constant). */\nexport const ILP_PEER_INFO_KIND = 10032;\n\n/** Publish/store ILP route hints riding out-of-band in announce content. */\nexport interface AnnouncedRoutes {\n publish?: string;\n store?: string;\n}\n\n/**\n * One announced capability with its FLAT route price (out-of-band\n * `capabilities` content field, e.g. `{capability:'os.publish',\n * address:'g.proxy.relay', price:'1000'}`). The connector (≥3.34.6) gates\n * every paid packet at the destination route's price: a balance-proof claim\n * advancing the channel by less is rejected (F06), so per-packet fees to\n * `address` must be floored at `price`.\n */\nexport interface AnnouncedCapability {\n /** Capability name, e.g. `os.publish` / `os.store`. */\n capability: string;\n /** ILP destination address the capability (and its price) applies to. */\n address: string;\n /** Flat per-packet price, base-unit non-negative integer string. */\n price: string;\n}\n\n/** One schema-valid, unexpired kind:10032 announce seen on the relay. */\nexport interface AnnouncedPeer {\n /** Announcing identity (event author, hex). */\n pubkey: string;\n /** Parsed + validated `IlpPeerInfo` (rig's core 3.x parser). */\n info: IlpPeerInfo;\n /** Out-of-band `routes` content field, when present and well-formed. */\n routes?: AnnouncedRoutes;\n /** Out-of-band `capabilities` content field (route prices), when valid. */\n capabilities?: AnnouncedCapability[];\n /** Announce timestamp (freshness tiebreaker). */\n createdAt: number;\n}\n\n/** Per-chain settlement parameters resolved for the embedded client. */\nexport interface ChainSettlement {\n /** Chain id as announced/configured, e.g. `evm:31337`. */\n chain: string;\n /** `evm` | `solana` | `mina` | … (first chain-id segment). */\n family: string;\n /** JSON-RPC / GraphQL endpoint, when derivable. */\n rpcUrl?: string;\n /** Preferred token (USDC / SPL mint) address, when derivable. */\n tokenAddress?: string;\n /** EVM TokenNetwork contract, when derivable (EVM only). */\n tokenNetwork?: string;\n /** Solana payment-channel program id, when derivable (Solana only). */\n programId?: string;\n}\n\n/** Why a settlement chain was selected (documented rule, in order). */\nexport type ChainSelectionReason =\n | 'explicit'\n | 'persisted-channel'\n | 'funded'\n | 'default';\n\n/** The selected settlement chain plus its rationale. */\nexport interface ChainSelection {\n chain: string;\n reason: ChainSelectionReason;\n /** One human-readable line explaining the pick. */\n detail: string;\n}\n\n// ---------------------------------------------------------------------------\n// Announce discovery\n// ---------------------------------------------------------------------------\n\n/** Default bounded wait for the kind:10032 relay query. */\nexport const DISCOVERY_TIMEOUT_MS = 5000;\n\nfunction parseRoutes(content: string): AnnouncedRoutes | undefined {\n try {\n const parsed = JSON.parse(content) as { routes?: unknown };\n const routes = parsed.routes;\n if (typeof routes !== 'object' || routes === null) return undefined;\n const { publish, store } = routes as Record<string, unknown>;\n const out: AnnouncedRoutes = {\n ...(typeof publish === 'string' && publish.length > 0 ? { publish } : {}),\n ...(typeof store === 'string' && store.length > 0 ? { store } : {}),\n };\n return out.publish || out.store ? out : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Parse the announce's out-of-band `capabilities` array (route prices).\n * Malformed entries are skipped; a `price` must be a non-negative integer\n * string (the same base-unit serialization every other announced amount\n * uses). Returns undefined when nothing valid is present.\n */\nfunction parseCapabilities(content: string): AnnouncedCapability[] | undefined {\n try {\n const parsed = JSON.parse(content) as { capabilities?: unknown };\n if (!Array.isArray(parsed.capabilities)) return undefined;\n const out: AnnouncedCapability[] = [];\n for (const entry of parsed.capabilities) {\n if (typeof entry !== 'object' || entry === null) continue;\n const { capability, address, price } = entry as Record<string, unknown>;\n if (\n typeof capability === 'string' &&\n typeof address === 'string' &&\n address.length > 0 &&\n typeof price === 'string' &&\n /^\\d+$/.test(price)\n ) {\n out.push({ capability, address, price });\n }\n }\n return out.length > 0 ? out : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Query `relayUrl` for kind:10032 announces and return the latest\n * schema-valid, unexpired announce per author. Invalid/expired events are\n * skipped silently (the relay serves plenty of non-peer 10032 experiments).\n */\nexport async function discoverAnnouncedPeers(\n relayUrl: string,\n options: {\n timeoutMs?: number;\n webSocketFactory?: WebSocketFactory;\n } = {}\n): Promise<AnnouncedPeer[]> {\n const factory =\n options.webSocketFactory ?? defaultDiscoveryWebSocketFactory();\n const events = await queryRelay(\n relayUrl,\n { kinds: [ILP_PEER_INFO_KIND], limit: 100 },\n options.timeoutMs ?? DISCOVERY_TIMEOUT_MS,\n factory\n );\n\n const latestByAuthor = new Map<string, NostrEvent>();\n for (const event of events) {\n if (event.kind !== ILP_PEER_INFO_KIND) continue;\n const prev = latestByAuthor.get(event.pubkey);\n if (!prev || event.created_at > prev.created_at) {\n latestByAuthor.set(event.pubkey, event);\n }\n }\n\n const peers: AnnouncedPeer[] = [];\n for (const event of latestByAuthor.values()) {\n if (isEventExpired(event as Parameters<typeof isEventExpired>[0])) {\n continue;\n }\n let info: IlpPeerInfo;\n try {\n info = parseIlpPeerInfo(event as Parameters<typeof parseIlpPeerInfo>[0]);\n } catch {\n continue; // not a schema-valid IlpPeerInfo announce\n }\n const routes = parseRoutes(event.content);\n const capabilities = parseCapabilities(event.content);\n peers.push({\n pubkey: event.pubkey,\n info,\n ...(routes ? { routes } : {}),\n ...(capabilities ? { capabilities } : {}),\n createdAt: event.created_at,\n });\n }\n return peers;\n}\n\nfunction defaultDiscoveryWebSocketFactory(): WebSocketFactory {\n return (url) => {\n const ctor = (\n globalThis as {\n WebSocket?: new (url: string) => ReturnType<WebSocketFactory>;\n }\n ).WebSocket;\n if (!ctor) {\n throw new Error(\n 'No global WebSocket constructor (Node >= 22 required) for announce discovery'\n );\n }\n return new ctor(url);\n };\n}\n\n/**\n * Pick THE payment peer among discovered announces:\n *\n * 1. the announce authored by a genesis-seed pubkey (the committed apex\n * identity — the strongest signal),\n * 2. else an announce that can actually take paid writes: has an uplink\n * endpoint AND `settlementAddresses`, preferring one whose own\n * `ilpAddress` is its `routes.publish` (the publish edge — that is\n * where rig pays first),\n * 3. freshest `created_at` breaks remaining ties.\n */\nexport function pickPaymentPeer(\n peers: AnnouncedPeer[],\n seedPubkeys: readonly string[]\n): AnnouncedPeer | undefined {\n const seeded = peers.filter((p) => seedPubkeys.includes(p.pubkey));\n if (seeded.length > 0) {\n return seeded.sort((a, b) => b.createdAt - a.createdAt)[0];\n }\n\n const payable = peers.filter(\n (p) =>\n (p.info.httpEndpoint || p.info.btpEndpoint) &&\n p.info.settlementAddresses &&\n Object.keys(p.info.settlementAddresses).length > 0\n );\n if (payable.length === 0) return undefined;\n const publishEdges = payable.filter(\n (p) => p.routes?.publish !== undefined && p.routes.publish === p.info.ilpAddress\n );\n const pool = publishEdges.length > 0 ? publishEdges : payable;\n return pool.sort((a, b) => b.createdAt - a.createdAt)[0];\n}\n\n// ---------------------------------------------------------------------------\n// Per-chain settlement derivation\n// ---------------------------------------------------------------------------\n\n/** Numeric chain id of an `evm:<id>` / `evm:<name>:<id>` chain key. */\nexport function evmChainIdOf(chain: string): number | undefined {\n const parts = chain.split(':');\n if (parts[0] !== 'evm') return undefined;\n const raw = parts.length >= 3 ? parts[2] : parts[1];\n const id = Number.parseInt(raw ?? '', 10);\n return Number.isNaN(id) ? undefined : id;\n}\n\n/**\n * Core chain preset matching an EVM chain key by numeric chain id. Presets\n * carry the DETERMINISTIC TOON contract addresses per chain (e.g. the\n * `anvil` 31337 Foundry deploy), which is what makes `tokenNetwork`\n * derivable without the announce carrying it. Base Sepolia (84532) resolves\n * from core's `base-sepolia` preset directly (>=3.1.1 carries the current\n * public 6-decimal USDC + TokenNetwork; the earlier stale addresses that this\n * function used to correct locally are gone).\n */\nexport function evmPresetForChain(chain: string):\n | { rpcUrl: string; usdcAddress: string; tokenNetworkAddress: string }\n | undefined {\n const id = evmChainIdOf(chain);\n if (id === undefined) return undefined;\n for (const preset of Object.values(CHAIN_PRESETS)) {\n if (preset.chainId === id) {\n return {\n rpcUrl: preset.rpcUrl,\n usdcAddress: preset.usdcAddress,\n tokenNetworkAddress: preset.tokenNetworkAddress,\n };\n }\n }\n return undefined;\n}\n\n/**\n * Public-cluster Solana preset matching a `solana:<cluster>` chain key. Draws\n * from core's client network presets (`resolveClientNetwork`) — the same\n * tables the daemon and townhouse resolve — so the deployed public-devnet\n * program/mint and the mainnet-beta RPC + Circle USDC mint come from ONE\n * source. `programId` is present only where the TOON payment-channel program\n * is actually deployed (public devnet today; mainnet-beta once deployed).\n * Announce-provided values and explicit config always take precedence over\n * these presets (see {@link resolveChainSettlement}) — that precedence is\n * what protected the devnet's former self-hosted validator, whose regenerated\n * program id rode the announce (retired 2026-07; the devnet now settles on\n * the public clusters).\n */\nexport function solanaPresetForChain(chain: string):\n | { rpcUrl?: string; tokenMint?: string; programId?: string }\n | undefined {\n const [family, cluster] = chain.split(':');\n if (family !== 'solana' || !cluster) return undefined;\n const tier =\n cluster === 'mainnet-beta'\n ? 'mainnet'\n : cluster === 'devnet'\n ? 'devnet'\n : cluster === 'testnet'\n ? 'testnet'\n : undefined;\n if (!tier) return undefined;\n const presets = resolveClientNetwork(tier);\n // Look up by the exact chain key: the `testnet` tier resolves to the\n // deployed `solana:devnet` cluster, so `solana:testnet` correctly finds\n // nothing (TOON has no deployment on Solana's testnet cluster).\n const rpcUrl = presets.chainRpcUrls[chain];\n const tokenMint = presets.preferredTokens[chain];\n const programId =\n presets.solanaChannel && presets.supportedChains.includes(chain)\n ? presets.solanaChannel.programId\n : undefined;\n if (!rpcUrl && !tokenMint && !programId) return undefined;\n return {\n ...(rpcUrl ? { rpcUrl } : {}),\n ...(tokenMint ? { tokenMint } : {}),\n ...(programId ? { programId } : {}),\n };\n}\n\n/** Explicit per-chain maps from the shared client-config file. */\nexport interface ExplicitChainConfig {\n chainRpcUrls?: Record<string, string>;\n preferredTokens?: Record<string, string>;\n tokenNetworks?: Record<string, string>;\n}\n\n/**\n * Resolve one chain's settlement parameters: explicit config > announce >\n * core chain preset. Fields stay undefined when no source covers them —\n * callers decide whether that is fatal (see\n * {@link TokenNetworkUnderivableError} /\n * {@link SolanaChannelUnderivableError}).\n *\n * For `solana:*` chains the chain-keyed maps carry the SPL analogues: the\n * `preferredTokens` entry is the token mint, and the `tokenNetworks` entry is\n * the payment-channel PROGRAM id (the map is chain-keyed settlement-contract\n * addressing — TokenNetwork contract on EVM, channel program on Solana),\n * surfaced as {@link ChainSettlement.programId}.\n */\nexport function resolveChainSettlement(\n chain: string,\n explicit: ExplicitChainConfig,\n announce?: AnnouncedPeer\n): ChainSettlement {\n const family = chain.split(':')[0] ?? chain;\n const evmPreset = family === 'evm' ? evmPresetForChain(chain) : undefined;\n const solPreset = family === 'solana' ? solanaPresetForChain(chain) : undefined;\n\n const rpcUrl =\n explicit.chainRpcUrls?.[chain] ?? evmPreset?.rpcUrl ?? solPreset?.rpcUrl;\n const tokenAddress =\n explicit.preferredTokens?.[chain] ??\n announce?.info.preferredTokens?.[chain] ??\n (evmPreset?.usdcAddress || undefined) ??\n solPreset?.tokenMint;\n const tokenNetwork =\n family === 'evm'\n ? (explicit.tokenNetworks?.[chain] ??\n announce?.info.tokenNetworks?.[chain] ??\n (evmPreset?.tokenNetworkAddress || undefined))\n : undefined;\n const programId =\n family === 'solana'\n ? (explicit.tokenNetworks?.[chain] ??\n announce?.info.tokenNetworks?.[chain] ??\n solPreset?.programId)\n : undefined;\n\n return {\n chain,\n family,\n ...(rpcUrl ? { rpcUrl } : {}),\n ...(tokenAddress ? { tokenAddress } : {}),\n ...(tokenNetwork ? { tokenNetwork } : {}),\n ...(programId ? { programId } : {}),\n };\n}\n\n/** An EVM chain was selected but its TokenNetwork cannot be derived. */\nexport class TokenNetworkUnderivableError extends Error {\n constructor(chain: string, announce: AnnouncedPeer | undefined, relayUrl: string) {\n const announceRef = announce\n ? `the kind:10032 announce from ${announce.pubkey.slice(0, 16)}… on ${relayUrl}`\n : `no kind:10032 announce was found on ${relayUrl}`;\n super(\n `cannot derive the TokenNetwork contract for settlement chain ` +\n `\"${chain}\": ${announceRef} carries no tokenNetworks[\"${chain}\"], ` +\n `and no built-in chain preset matches its chain id — add ` +\n `tokenNetworks[\"${chain}\"] to the client config (or pick another ` +\n `chain via TOON_CLIENT_CHAIN / the chain config field)`\n );\n this.name = 'TokenNetworkUnderivableError';\n }\n}\n\n/**\n * A Solana chain was selected but its channel parameters cannot be derived.\n * The missing pieces are named so the error is directly actionable: a\n * `solanaChannel` config object always works; the chain-keyed maps\n * (`tokenNetworks` = program id, `preferredTokens` = mint,\n * `chainRpcUrls` = RPC) work per-chain.\n */\nexport class SolanaChannelUnderivableError extends Error {\n constructor(\n chain: string,\n missing: string[],\n announce: AnnouncedPeer | undefined,\n relayUrl: string\n ) {\n const announceRef = announce\n ? `the kind:10032 announce from ${announce.pubkey.slice(0, 16)}… on ${relayUrl} does not carry them`\n : `no kind:10032 announce was found on ${relayUrl}`;\n super(\n `cannot derive the Solana channel parameters for settlement chain ` +\n `\"${chain}\" (missing: ${missing.join(', ')}): ${announceRef}, and ` +\n `no built-in preset covers this cluster — add a solanaChannel ` +\n `{ rpcUrl, programId, tokenMint } object to the client config (or ` +\n `set tokenNetworks[\"${chain}\"] = <program id>, ` +\n `preferredTokens[\"${chain}\"] = <mint>, chainRpcUrls[\"${chain}\"]), ` +\n `or pick another chain via TOON_CLIENT_CHAIN / the chain config field`\n );\n this.name = 'SolanaChannelUnderivableError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Settlement-chain selection (#260 root cause 4)\n// ---------------------------------------------------------------------------\n\n/** The slice of a #262 channel-map record chain selection consumes. */\nexport interface ChannelRecordLike {\n chain: string;\n lastUsedAt: string;\n /** True when the withdraw flow closed/settled the channel. */\n closed: boolean;\n}\n\n/** Async token-balance probe (injectable; default is a raw `eth_call`). */\nexport type EvmBalanceProbe = (args: {\n rpcUrl: string;\n tokenAddress: string;\n owner: string;\n}) => Promise<bigint>;\n\n/**\n * Async SPL token-balance probe (injectable; default is a raw\n * `getTokenAccountsByOwner`). `tokenAddress` is the SPL mint and `owner`\n * the identity's base58 Solana address — the same argument shape as\n * {@link EvmBalanceProbe} so both feed the one funded-chain loop.\n */\nexport type SolanaBalanceProbe = (args: {\n rpcUrl: string;\n tokenAddress: string;\n owner: string;\n}) => Promise<bigint>;\n\nexport interface SelectChainOptions {\n /**\n * Explicit chain choice: full chain id (`evm:31337`), a family\n * (`evm` | `solana` | `mina`) matched against announced chains, or the\n * first entry of an explicit `supportedChains` config.\n */\n explicitChain?: string;\n /** Chains the payment peer announces (announce order preserved). */\n announcedChains: readonly string[];\n /** #262 channel-map records for this identity (any anchor). */\n records?: readonly ChannelRecordLike[];\n /** Identity's EVM address (funded-chain probe, `evm:*` candidates). */\n evmAddress?: string;\n /**\n * Identity's base58 Solana address (funded-chain probe, `solana:*`\n * candidates). Absent (e.g. the identity's Ed25519 key could not be\n * derived) means Solana chains are simply not probed.\n */\n solanaAddress?: string;\n /** Per-chain settlement resolver (for RPC/token of probe candidates). */\n resolveSettlement: (chain: string) => ChainSettlement;\n /** EVM balance probe; probe errors just skip the candidate. */\n probeBalance?: EvmBalanceProbe;\n /** Solana balance probe; probe errors just skip the candidate. */\n probeSolanaBalance?: SolanaBalanceProbe;\n}\n\n/**\n * Select the settlement chain per the documented rule: explicit >\n * persisted channel > funded chain (EVM + Solana, in announce order) >\n * first announced EVM chain.\n */\nexport async function selectSettlementChain(\n options: SelectChainOptions\n): Promise<ChainSelection> {\n const { explicitChain, announcedChains } = options;\n\n // 1 — explicit config always wins (even when the peer does not announce\n // it: the user may know better than a stale announce).\n if (explicitChain) {\n if (explicitChain.includes(':')) {\n // Chain negotiation is an EXACT string intersection: a full chain id\n // spelled differently from the announce for the SAME EVM chain\n // (`evm:base:84532` vs announced `evm:84532`) would strand the pin and\n // let negotiation fall through to another chain entirely. Align an\n // explicit EVM chain id to the announced spelling (same rule the\n // configured-supportedChains path applies).\n if (!announcedChains.includes(explicitChain)) {\n const chainId = evmChainIdOf(explicitChain);\n const equivalent =\n chainId !== undefined\n ? announcedChains.find((c) => evmChainIdOf(c) === chainId)\n : undefined;\n if (equivalent) {\n return {\n chain: equivalent,\n reason: 'explicit',\n detail:\n `chain ${explicitChain} set by config → announced spelling ` +\n `${equivalent} (same EVM chain id ${chainId})`,\n };\n }\n }\n return {\n chain: explicitChain,\n reason: 'explicit',\n detail: `chain ${explicitChain} set by config`,\n };\n }\n const familyMatch = announcedChains.find(\n (c) => (c.split(':')[0] ?? c) === explicitChain\n );\n if (!familyMatch) {\n throw new Error(\n `configured chain family \"${explicitChain}\" is not announced by the ` +\n `payment peer (announced: ${announcedChains.join(', ') || 'none'}) — ` +\n 'set a full chain id (e.g. \"evm:31337\") to force it'\n );\n }\n return {\n chain: familyMatch,\n reason: 'explicit',\n detail: `chain family \"${explicitChain}\" set by config → ${familyMatch}`,\n };\n }\n\n // 2 — a live persisted channel means collateral is already locked there.\n const live = (options.records ?? [])\n .filter((r) => !r.closed && announcedChains.includes(r.chain))\n .sort((a, b) => b.lastUsedAt.localeCompare(a.lastUsedAt));\n const persisted = live[0];\n if (persisted) {\n return {\n chain: persisted.chain,\n reason: 'persisted-channel',\n detail: `existing payment channel on ${persisted.chain} (rig channel map)`,\n };\n }\n\n // 3 — first announced chain where the identity holds tokens, probing\n // EVM and Solana candidates in ANNOUNCE ORDER (the peer's stated\n // preference breaks a both-funded tie). Families without an address or\n // probe are skipped, as are candidates whose RPC/token are underivable.\n const evmChains = announcedChains.filter((c) => c.startsWith('evm:'));\n for (const chain of announcedChains) {\n const family = chain.split(':')[0];\n let probe: EvmBalanceProbe | SolanaBalanceProbe | undefined;\n let owner: string | undefined;\n if (family === 'evm') {\n probe = options.probeBalance;\n owner = options.evmAddress;\n } else if (family === 'solana') {\n probe = options.probeSolanaBalance;\n owner = options.solanaAddress;\n }\n if (!probe || !owner) continue;\n const settlement = options.resolveSettlement(chain);\n if (!settlement.rpcUrl || !settlement.tokenAddress) continue;\n try {\n const balance = await probe({\n rpcUrl: settlement.rpcUrl,\n tokenAddress: settlement.tokenAddress,\n owner,\n });\n if (balance > 0n) {\n return {\n chain,\n reason: 'funded',\n detail: `wallet holds ${balance} token base units on ${chain}`,\n };\n }\n } catch {\n // Unreachable RPC / bad token — not a candidate; fall through.\n }\n }\n\n // 4 — predictable default: the first EVM chain the peer announces.\n const fallback = evmChains[0] ?? announcedChains[0];\n if (!fallback) {\n throw new Error(\n 'the payment peer announces no settlement chains — cannot select a ' +\n 'chain for paid writes (set supportedChains/chain in the client config)'\n );\n }\n return {\n chain: fallback,\n reason: 'default',\n detail: evmChains[0]\n ? `first EVM chain announced by the payment peer`\n : `first chain announced by the payment peer (no EVM chain announced)`,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Default balance probes (raw JSON-RPC, no extra deps)\n// ---------------------------------------------------------------------------\n\n/** ERC-20 `balanceOf(address)` selector. */\nconst BALANCE_OF_SELECTOR = '0x70a08231';\n\n/**\n * Read an ERC-20 balance with one raw `eth_call` (keeps the probe free of\n * viem — the embedded client is not started yet when selection runs).\n */\nexport async function evmTokenBalance(args: {\n rpcUrl: string;\n tokenAddress: string;\n owner: string;\n fetchImpl?: typeof fetch;\n timeoutMs?: number;\n}): Promise<bigint> {\n const fetchImpl = args.fetchImpl ?? fetch;\n const owner = args.owner.replace(/^0x/, '').toLowerCase().padStart(64, '0');\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), args.timeoutMs ?? 5000);\n try {\n const res = await fetchImpl(args.rpcUrl, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'eth_call',\n params: [\n { to: args.tokenAddress, data: `${BALANCE_OF_SELECTOR}${owner}` },\n 'latest',\n ],\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`eth_call failed: HTTP ${res.status}`);\n }\n const body = (await res.json()) as { result?: unknown; error?: { message?: string } };\n if (typeof body.result !== 'string') {\n throw new Error(`eth_call failed: ${body.error?.message ?? 'no result'}`);\n }\n return BigInt(body.result === '0x' ? '0x0' : body.result);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Read an SPL token balance with one raw `getTokenAccountsByOwner` call\n * (keeps the probe free of @solana/web3.js — the embedded client is not\n * started yet when selection runs). `tokenAddress` is the mint; balances\n * are summed across all of the owner's token accounts for that mint (an\n * owner can hold the mint in more than one account).\n */\nexport async function solanaTokenBalance(args: {\n rpcUrl: string;\n tokenAddress: string;\n owner: string;\n fetchImpl?: typeof fetch;\n timeoutMs?: number;\n}): Promise<bigint> {\n const fetchImpl = args.fetchImpl ?? fetch;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), args.timeoutMs ?? 5000);\n try {\n const res = await fetchImpl(args.rpcUrl, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: 1,\n method: 'getTokenAccountsByOwner',\n params: [\n args.owner,\n { mint: args.tokenAddress },\n { encoding: 'jsonParsed' },\n ],\n }),\n signal: controller.signal,\n });\n if (!res.ok) {\n throw new Error(`getTokenAccountsByOwner failed: HTTP ${res.status}`);\n }\n const body = (await res.json()) as {\n result?: { value?: unknown };\n error?: { message?: string };\n };\n const accounts = body.result?.value;\n if (!Array.isArray(accounts)) {\n throw new Error(\n `getTokenAccountsByOwner failed: ${body.error?.message ?? 'no result'}`\n );\n }\n let total = 0n;\n for (const account of accounts) {\n const amount = (\n account as {\n account?: {\n data?: {\n parsed?: { info?: { tokenAmount?: { amount?: unknown } } };\n };\n };\n }\n )?.account?.data?.parsed?.info?.tokenAmount?.amount;\n if (typeof amount === 'string') total += BigInt(amount);\n }\n return total;\n } finally {\n clearTimeout(timer);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Genesis seed access (rig's own core 3.x — live devnet apex since core 3.x)\n// ---------------------------------------------------------------------------\n\n/** The committed genesis peer seed (first entry), if any. */\nexport function loadGenesisSeed(): GenesisPeer | undefined {\n return GenesisPeerLoader.loadGenesisPeers()[0];\n}\n\n/** All committed genesis-seed pubkeys (announce-selection preference). */\nexport function genesisSeedPubkeys(): string[] {\n return GenesisPeerLoader.loadGenesisPeers().map((p) => p.pubkey);\n}\n"],"mappings":"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","names":[]}
|
package/dist/cli/rig.js
CHANGED
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
defaultDaemonPort,
|
|
36
36
|
resolveChannelPaths,
|
|
37
37
|
resolveConflictingPath
|
|
38
|
-
} from "../chunk-
|
|
38
|
+
} from "../chunk-FQXNLPUR.js";
|
|
39
39
|
import {
|
|
40
40
|
MAX_OBJECT_SIZE,
|
|
41
41
|
flooredUploadFee
|
|
@@ -1074,7 +1074,7 @@ function loadPaidSession(deps, relayUrl) {
|
|
|
1074
1074
|
});
|
|
1075
1075
|
}
|
|
1076
1076
|
var defaultLoadStandalone = async (options) => {
|
|
1077
|
-
const mod = await import("../standalone-mode-
|
|
1077
|
+
const mod = await import("../standalone-mode-YMIY4GL3.js");
|
|
1078
1078
|
return mod.createStandaloneContext(options);
|
|
1079
1079
|
};
|
|
1080
1080
|
function identityReport(ctx) {
|
|
@@ -3820,21 +3820,35 @@ import { join as join3 } from "path";
|
|
|
3820
3820
|
import { parseArgs as parseArgs9 } from "util";
|
|
3821
3821
|
var DEVNET_FAUCET_URL = "https://faucet.devnet.toonprotocol.dev";
|
|
3822
3822
|
var CHAINS = ["evm", "solana", "mina"];
|
|
3823
|
-
var
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3823
|
+
var CHAIN_ALIASES = {
|
|
3824
|
+
evm: "evm",
|
|
3825
|
+
eth: "evm",
|
|
3826
|
+
sol: "solana",
|
|
3827
|
+
solana: "solana",
|
|
3828
|
+
mina: "mina",
|
|
3829
|
+
all: "all"
|
|
3828
3830
|
};
|
|
3829
|
-
var
|
|
3831
|
+
var CHAIN_ARG_LIST = "evm | sol | solana | mina | all";
|
|
3832
|
+
function resolveChainArg(raw) {
|
|
3833
|
+
if (raw === void 0) return void 0;
|
|
3834
|
+
const canonical = CHAIN_ALIASES[raw.toLowerCase()];
|
|
3835
|
+
if (!canonical) {
|
|
3836
|
+
throw new Error(
|
|
3837
|
+
`chain must be one of ${CHAIN_ARG_LIST}, got ${JSON.stringify(raw)}`
|
|
3838
|
+
);
|
|
3839
|
+
}
|
|
3840
|
+
return canonical;
|
|
3841
|
+
}
|
|
3842
|
+
var FUND_USAGE = `Usage: rig fund [chain] [options]
|
|
3830
3843
|
|
|
3831
|
-
Drip devnet
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3844
|
+
Drip devnet USDC to the active identity's wallet \u2014 free (the faucet pays). Each
|
|
3845
|
+
drip funds ONLY the settlement token (USDC) and assumes the wallet already holds
|
|
3846
|
+
enough native gas to transact. By default funds ALL supported chains (evm +
|
|
3847
|
+
solana + mina) so the wallet matches the multi-chain \`rig balance\` view in one
|
|
3848
|
+
run; name a chain \u2014 positional (\`rig fund sol\`) or \`--chain\` \u2014 to narrow to
|
|
3849
|
+
one. The per-chain drips run in parallel and are independent \u2014 one chain's
|
|
3850
|
+
faucet failing does not abort the others (exit 0 only when every targeted chain
|
|
3851
|
+
funded; exit 1 if any failed, with the per-chain breakdown always shown).
|
|
3838
3852
|
|
|
3839
3853
|
The identity comes from RIG_MNEMONIC (env or a project .env) or the
|
|
3840
3854
|
~/.toon-client keystore/config; the faucet from TOON_CLIENT_FAUCET_URL, the
|
|
@@ -3846,10 +3860,11 @@ chain (there is no --amount). On a network without a faucet, prints the wallet
|
|
|
3846
3860
|
address(es) to fund externally instead.
|
|
3847
3861
|
|
|
3848
3862
|
Options:
|
|
3849
|
-
|
|
3850
|
-
(default: all supported chains)
|
|
3863
|
+
[chain] evm | sol | solana | mina | all \u2014 positional chain to
|
|
3864
|
+
fund (default: all supported chains)
|
|
3865
|
+
--chain <chain> same as the positional chain argument
|
|
3851
3866
|
--address <address> fund this address instead of the identity's own
|
|
3852
|
-
(requires an explicit single
|
|
3867
|
+
(requires an explicit single chain)
|
|
3853
3868
|
--json machine-readable envelope (per-chain results array)
|
|
3854
3869
|
-h, --help show this help`;
|
|
3855
3870
|
var SHARED_DEVNET_SUFFIX = ".devnet.toonprotocol.dev";
|
|
@@ -3924,12 +3939,13 @@ function readFundConfig(env) {
|
|
|
3924
3939
|
}
|
|
3925
3940
|
async function runFund(args, deps) {
|
|
3926
3941
|
const { io: io2, env } = deps;
|
|
3927
|
-
let
|
|
3942
|
+
let resolvedChain;
|
|
3928
3943
|
let addressFlag;
|
|
3929
3944
|
let json = false;
|
|
3930
3945
|
try {
|
|
3931
|
-
const { values } = parseArgs9({
|
|
3946
|
+
const { values, positionals } = parseArgs9({
|
|
3932
3947
|
args,
|
|
3948
|
+
allowPositionals: true,
|
|
3933
3949
|
options: {
|
|
3934
3950
|
chain: { type: "string" },
|
|
3935
3951
|
address: { type: "string" },
|
|
@@ -3941,17 +3957,23 @@ async function runFund(args, deps) {
|
|
|
3941
3957
|
io2.out(FUND_USAGE);
|
|
3942
3958
|
return 0;
|
|
3943
3959
|
}
|
|
3944
|
-
|
|
3945
|
-
addressFlag = values.address;
|
|
3946
|
-
json = values.json ?? false;
|
|
3947
|
-
if (chainFlag !== void 0 && !CHAIN_CHOICES.includes(chainFlag)) {
|
|
3960
|
+
if (positionals.length > 1) {
|
|
3948
3961
|
throw new Error(
|
|
3949
|
-
|
|
3962
|
+
`rig fund takes at most one chain argument, got ${positionals.length}: ${positionals.join(" ")}`
|
|
3950
3963
|
);
|
|
3951
3964
|
}
|
|
3952
|
-
|
|
3965
|
+
const positionalChain = positionals[0];
|
|
3966
|
+
if (positionalChain !== void 0 && values.chain !== void 0) {
|
|
3953
3967
|
throw new Error(
|
|
3954
|
-
"
|
|
3968
|
+
"give the chain as a positional argument (`rig fund sol`) OR with --chain, not both"
|
|
3969
|
+
);
|
|
3970
|
+
}
|
|
3971
|
+
resolvedChain = resolveChainArg(positionalChain ?? values.chain);
|
|
3972
|
+
addressFlag = values.address;
|
|
3973
|
+
json = values.json ?? false;
|
|
3974
|
+
if (addressFlag !== void 0 && (resolvedChain === void 0 || resolvedChain === "all")) {
|
|
3975
|
+
throw new Error(
|
|
3976
|
+
`--address requires an explicit single chain (${CHAIN_ARG_LIST}) \u2014 a single address cannot fund every chain`
|
|
3955
3977
|
);
|
|
3956
3978
|
}
|
|
3957
3979
|
} catch (err) {
|
|
@@ -3961,7 +3983,7 @@ async function runFund(args, deps) {
|
|
|
3961
3983
|
}
|
|
3962
3984
|
try {
|
|
3963
3985
|
const { file } = readFundConfig(env);
|
|
3964
|
-
const targetChains =
|
|
3986
|
+
const targetChains = resolvedChain === void 0 || resolvedChain === "all" ? [...CHAINS] : [resolvedChain];
|
|
3965
3987
|
const network = env["TOON_CLIENT_NETWORK"] ?? file.network;
|
|
3966
3988
|
const canInfer = network === void 0 || network === "custom";
|
|
3967
3989
|
const originRelays = canInfer ? await resolveOriginRelays(deps.cwd) : [];
|
|
@@ -4024,7 +4046,7 @@ async function runFund(args, deps) {
|
|
|
4024
4046
|
if (!json) {
|
|
4025
4047
|
const list = targetChains.join(", ");
|
|
4026
4048
|
io2.out(
|
|
4027
|
-
`Requesting ${targetChains.length === 1 ? "" : "parallel "}drip${targetChains.length === 1 ? "" : "s"} from ${faucetUrl} for ${list} \u2026` + (targetChains.includes("mina") ? " (mina settles slowly; this can take ~2 minutes)" : "")
|
|
4049
|
+
`Requesting ${targetChains.length === 1 ? "" : "parallel "}USDC drip${targetChains.length === 1 ? "" : "s"} from ${faucetUrl} for ${list} \u2026` + (targetChains.includes("mina") ? " (mina settles slowly; this can take ~2 minutes)" : "")
|
|
4028
4050
|
);
|
|
4029
4051
|
}
|
|
4030
4052
|
const singleChain = targetChains.length === 1;
|
|
@@ -4081,7 +4103,7 @@ async function runFund(args, deps) {
|
|
|
4081
4103
|
if (r.funded) {
|
|
4082
4104
|
const slow = r.elapsedMs !== void 0 && r.elapsedMs >= 5e3;
|
|
4083
4105
|
const time = slow ? ` (${Math.round(r.elapsedMs / 1e3)}s)` : "";
|
|
4084
|
-
io2.out(` ${label} \u2713 funded (
|
|
4106
|
+
io2.out(` ${label} \u2713 funded (USDC)${addr}${time}`);
|
|
4085
4107
|
} else {
|
|
4086
4108
|
io2.out(` ${label} \u2717${addr} \u2014 ${r.error ?? "failed"}`);
|
|
4087
4109
|
}
|
|
@@ -4693,7 +4715,7 @@ async function resolveProfileRelay(flagRelay, originRelay, toonRelays) {
|
|
|
4693
4715
|
].filter((u) => u !== void 0 && isWebSocketRelay2(u));
|
|
4694
4716
|
if (candidates[0] !== void 0) return candidates[0];
|
|
4695
4717
|
try {
|
|
4696
|
-
const { loadGenesisSeed } = await import("../network-bootstrap-
|
|
4718
|
+
const { loadGenesisSeed } = await import("../network-bootstrap-IHQ4PWUW.js");
|
|
4697
4719
|
const seed = loadGenesisSeed();
|
|
4698
4720
|
if (seed?.relayUrl && isWebSocketRelay2(seed.relayUrl)) return seed.relayUrl;
|
|
4699
4721
|
} catch {
|
|
@@ -5634,6 +5656,11 @@ Commands:
|
|
|
5634
5656
|
gas-station path (kind:5096) \u2014 you author and
|
|
5635
5657
|
partial-sign, the DVM co-signs as fee payer and pays
|
|
5636
5658
|
the lamports; needs ZERO SOL in this wallet.
|
|
5659
|
+
<txId> may instead be given via --tx-id <id> \u2014 use
|
|
5660
|
+
that instead of the positional when the txId leads
|
|
5661
|
+
with '-' or '_' (Arweave txids are base64url). For a
|
|
5662
|
+
leading '-' write --tx-id=<id> (the '=' form), since
|
|
5663
|
+
"--tx-id -XYZ..." is itself ambiguous to the parser.
|
|
5637
5664
|
name status <name> FREE: registry record (lease/permabuy, expiry), ANT
|
|
5638
5665
|
process id, current target txId(s), TTL, undernames.
|
|
5639
5666
|
|
|
@@ -5644,6 +5671,10 @@ Options:
|
|
|
5644
5671
|
--undername <sub> target the undername <sub>_<name> instead of the base
|
|
5645
5672
|
name (set)
|
|
5646
5673
|
--ttl <seconds> record TTL in seconds (set; default 3600)
|
|
5674
|
+
--tx-id <id> set only: the Arweave txId to point at, as an
|
|
5675
|
+
explicit option instead of the positional (mutually
|
|
5676
|
+
exclusive with the positional <txId>). For a value
|
|
5677
|
+
leading with '-' use --tx-id=<id>.
|
|
5647
5678
|
--network <net> cluster: mainnet | devnet (default mainnet; or
|
|
5648
5679
|
RIG_ARIO_NETWORK). ar.io has no Solana-testnet
|
|
5649
5680
|
deployment. Non-mainnet gateway resolution is
|
|
@@ -5712,6 +5743,7 @@ function parseNameFlags(args, env) {
|
|
|
5712
5743
|
network: { type: "string" },
|
|
5713
5744
|
"process-id": { type: "string" },
|
|
5714
5745
|
via: { type: "string" },
|
|
5746
|
+
"tx-id": { type: "string" },
|
|
5715
5747
|
yes: { type: "boolean", default: false },
|
|
5716
5748
|
json: { type: "boolean", default: false },
|
|
5717
5749
|
help: { type: "boolean", short: "h", default: false }
|
|
@@ -5777,6 +5809,7 @@ function parseNameFlags(args, env) {
|
|
|
5777
5809
|
network: networkRaw,
|
|
5778
5810
|
...processId !== void 0 ? { processId } : {},
|
|
5779
5811
|
...via !== void 0 ? { via } : {},
|
|
5812
|
+
...values["tx-id"] !== void 0 ? { txId: values["tx-id"] } : {},
|
|
5780
5813
|
yes: values.yes ?? false,
|
|
5781
5814
|
json: values.json ?? false
|
|
5782
5815
|
}
|
|
@@ -6169,10 +6202,15 @@ async function runName(args, deps) {
|
|
|
6169
6202
|
try {
|
|
6170
6203
|
if (sub === "buy") return await runBuy(name, flags, deps);
|
|
6171
6204
|
if (sub === "status") return await runStatus(name, flags, deps);
|
|
6172
|
-
|
|
6205
|
+
if (flags.txId !== void 0 && positionals[1] !== void 0) {
|
|
6206
|
+
io2.err("`--tx-id` and a positional <txId> are mutually exclusive");
|
|
6207
|
+
io2.err(NAME_USAGE);
|
|
6208
|
+
return 2;
|
|
6209
|
+
}
|
|
6210
|
+
const txId = flags.txId ?? positionals[1];
|
|
6173
6211
|
if (txId === void 0) {
|
|
6174
6212
|
io2.err(
|
|
6175
|
-
"`rig name set` needs a <txId> (the Arweave transaction to point at)"
|
|
6213
|
+
"`rig name set` needs a <txId> (the Arweave transaction to point at) \u2014 as a positional or via --tx-id"
|
|
6176
6214
|
);
|
|
6177
6215
|
io2.err(NAME_USAGE);
|
|
6178
6216
|
return 2;
|
|
@@ -6196,7 +6234,7 @@ function buildArweaveManifest(entries, indexPath = DEFAULT_INDEX, fallbackTxId)
|
|
|
6196
6234
|
return {
|
|
6197
6235
|
manifest: "arweave/paths",
|
|
6198
6236
|
version: "0.2.0",
|
|
6199
|
-
index: { path: indexPath },
|
|
6237
|
+
...Object.hasOwn(paths, indexPath) ? { index: { path: indexPath } } : {},
|
|
6200
6238
|
...fallbackTxId ? { fallback: { id: fallbackTxId } } : {},
|
|
6201
6239
|
paths
|
|
6202
6240
|
};
|