@toon-protocol/rig 5.2.0 → 5.4.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/README.md +9 -9
- package/dist/{chunk-JX5P2KAA.js → chunk-3KS6S4S5.js} +11 -2
- package/dist/chunk-3KS6S4S5.js.map +1 -0
- package/dist/{chunk-S5R44MMB.js → chunk-MIK7SRWE.js} +70 -41
- package/dist/{chunk-S5R44MMB.js.map → chunk-MIK7SRWE.js.map} +1 -1
- package/dist/{chunk-FX5GPZYU.js → chunk-QSUO7J4H.js} +0 -0
- package/dist/{chunk-Y7TUE7JT.js → chunk-Z3XRZ5E5.js} +982 -436
- package/dist/chunk-Z3XRZ5E5.js.map +1 -0
- package/dist/{ci-serve-CA37KQVC.js → ci-serve-4RJCKEPV.js} +5 -5
- package/dist/cli/rig.js +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{publisher-CQi69Nwg.d.ts → publisher-1vY1WABR.d.ts} +15 -5
- package/dist/standalone/index.d.ts +1 -1
- package/dist/{standalone-mode-NWCCRFCL.js → standalone-mode-LUWNCDPL.js} +6 -4
- package/dist/standalone-mode-LUWNCDPL.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-JX5P2KAA.js.map +0 -1
- package/dist/chunk-Y7TUE7JT.js.map +0 -1
- package/dist/standalone-mode-NWCCRFCL.js.map +0 -1
- /package/dist/{chunk-FX5GPZYU.js.map → chunk-QSUO7J4H.js.map} +0 -0
- /package/dist/{ci-serve-CA37KQVC.js.map → ci-serve-4RJCKEPV.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/standalone-mode.ts"],"sourcesContent":["/**\n * The standalone (embedded-client) session behind every paid command.\n *\n * One URL is the whole configuration. A TOON connector describes itself on\n * `GET /ilp` (connector ADR 0050): its ILP addresses, the routes it prices,\n * the x402 `batch-settlement` terms it accepts per chain and the key a payload\n * is sealed to. The client (`@toon-protocol/client` 4.x) reads that once,\n * opens or resumes an x402 channel with the node, and pays each request with a\n * signed voucher naming the running total (connector ADR 0075; the\n * toon-channel claims of client 3.x are refused). There is nothing to\n * discover and nothing to negotiate: kind:10032 announces were removed by\n * ADR 0046, and a node's word about itself replaced them.\n *\n * What this module resolves, in precedence order (env > config file):\n *\n * - `TOON_CONNECTOR` / `connectorUrl` — the node's client-edge URL. The\n * legacy `TOON_CLIENT_PROXY_URL` / `proxyUrl` (…`/ilp`) is still read; the\n * client normalizes a trailing `/ilp` away. `btpUrl` is ignored (the client\n * reads the BTP endpoint from `GET /ilp`).\n * - `TOON_CLIENT_PUBLISH_DESTINATION` / `publishDestination` — the route\n * events go to. Default: the first address the node publishes for itself\n * that it also prices (`defaultDestinationFor`).\n * - `TOON_CLIENT_STORE_DESTINATION` / `storeDestination` — the route git\n * objects go to. Default: the node's first priced route named `*.store`,\n * else `*.ario`. A `--via` override (`rig name`) outranks both.\n * - `TOON_CLIENT_STORE_CONNECTOR_URL` / `storeConnectorUrl` — when the store\n * route terminates on ANOTHER node that holds its own channel: that node's\n * URL. Uploads then ride a second client with its own watermark file.\n * `storeSealTo` alone (same channel, different terminating identity) makes\n * the edge's client seal to that node instead.\n * - `TOON_CLIENT_CHAIN` / `chain` — `evm` or `solana` (a full id such as\n * `evm:8453` is read by its family). Default: the first chain in the node's\n * `batchSettlements[]` this identity holds a key for. A phrase holds both,\n * so name one when the node offers several.\n * - `TOON_CLIENT_RPC_URL` / `rpcUrl` / `chainRpcUrls[<chain>]`.\n * - `TOON_CLIENT_CHANNEL_STORE` / `channelStorePath`: the client's x402\n * channel store. Default `<dir>/channels-x402.json` (+ `.peers.json`). A\n * client 3.x toon-channel store is refused here and never written.\n * - `TOON_CLIENT_FACILITATOR_URL` / `facilitatorUrl`: the x402 facilitator\n * that submits a Base deposit and pays its gas. Solana needs none: the\n * connector sponsors the open.\n * - `RIG_SOLANA_KEY_FILE` / `solanaKeyFile`, `RIG_EVM_PRIVATE_KEY` /\n * `evmPrivateKey` — pay with THIS key instead of the phrase's derived one.\n * The author stays the phrase's Nostr key; who pays and who signs the\n * event are independent facts (the connector attributes payment from the\n * voucher, never from the event).\n *\n * Key derivation: a rig phrase yields its Nostr key at `m/44'/1237'/0'/0/i`,\n * and its EVM account has always been that same secp256k1 key — which the\n * client calls `keyDerivation: 'legacy'`. That is the default here, so every\n * channel an existing identity funded is still its own. `keyDerivation:\n * 'standard'` / `TOON_CLIENT_KEY_DERIVATION=standard` opts into the\n * MetaMask-importable path for a fresh identity.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport {\n PAYMENT_CHANNELS_PROGRAM_ID,\n ToonClient,\n X402_BATCH_SETTLEMENT_ADDRESS,\n defaultDestinationFor,\n evmChainIdOf,\n type BatchChannelSummary,\n type BatchExitResult,\n type ChannelFacade,\n type NodeSelfDescription,\n type ToonClientConfig,\n} from '@toon-protocol/client';\nimport { shaResolverFor } from '../git-sha-resolver.js';\nimport { fetchRemoteState } from '../remote-state.js';\nimport {\n CHANNEL_STORE_FILENAME,\n ChannelMapStore,\n RIG_CHANNEL_MAP_FILENAME,\n isToonChannelStore,\n legacyChannelFiles,\n type ChannelMapRecord,\n} from '../standalone/channel-map.js';\nimport { ConnectorPublisher } from '../standalone/connector-publisher.js';\nimport type {\n ChannelCloseOutcome,\n ChannelOpenOutcome,\n ChannelSettleOutcome,\n StandaloneMoneyOps,\n WalletChainBalanceInfo,\n} from '../standalone/money.js';\nimport {\n NonceLock,\n checkDaemonIdentity,\n standaloneForced,\n} from '../standalone/nonce-guard.js';\nimport { deriveNostrKeyFromMnemonic } from '../standalone/nostr-identity.js';\nimport { resolveIdentity } from './identity.js';\nimport type {\n StandaloneContext,\n StandaloneLoadOptions,\n} from './standalone-context.js';\n\n// ---------------------------------------------------------------------------\n// Config file\n// ---------------------------------------------------------------------------\n\n/** The shared `~/.toon-client/config.json` fields rig reads. */\nexport interface ClientConfigFile {\n /** The connector's client-edge URL (`GET /ilp` lives here). */\n connectorUrl?: string;\n /** @deprecated the pre-2.0 spelling: the connector's `…/ilp` ingress URL. */\n proxyUrl?: string;\n /** @deprecated ignored — the client reads the BTP endpoint from `GET /ilp`. */\n btpUrl?: string;\n /** Free-read relay (WebSocket) for the identity's kind:0 and NIP-34 reads. */\n relayUrl?: string;\n /** @deprecated alias of `publishDestination`. */\n destination?: string;\n publishDestination?: string;\n storeDestination?: string;\n storeConnectorUrl?: string;\n storeSealTo?: string;\n feePerEvent?: string;\n /** The client's x402 channel store; default `<dir>/channels-x402.json`. */\n channelStorePath?: string;\n /** The x402 facilitator for a Base deposit. */\n facilitatorUrl?: string;\n /** `evm` | `solana`, or a full id (`evm:8453`) read by its family. */\n chain?: string;\n /** @deprecated pre-2.0 chain list; the first entry is read as `chain`. */\n supportedChains?: string[];\n rpcUrl?: string;\n chainRpcUrls?: Record<string, string>;\n transport?: 'auto' | 'http' | 'btp';\n keyDerivation?: 'standard' | 'legacy';\n mnemonicAccountIndex?: number;\n /** What each x402 channel is opened with, base units. */\n deposit?: string;\n /** Path to a Solana keypair JSON (64-byte array) that pays instead of the phrase's key. */\n solanaKeyFile?: string;\n /** Hex EVM private key that pays instead of the phrase's key. */\n evmPrivateKey?: string;\n /** Per-packet timeout for uploads, ms. */\n uploadTimeoutMs?: number;\n [key: string]: unknown;\n}\n\nfunction configDir(env: NodeJS.ProcessEnv): string {\n return env['TOON_CLIENT_HOME'] ?? join(homedir(), '.toon-client');\n}\n\nexport function readClientConfig(path: string): ClientConfigFile {\n try {\n return JSON.parse(readFileSync(path, 'utf8')) as ClientConfigFile;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return {};\n throw new Error(\n `failed to read client config at ${path}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\n/** An identity was resolved, but there is no connector to pay. */\nexport class MissingUplinkError extends Error {\n constructor(configPath: string) {\n super(\n \"no connector configured: set TOON_CONNECTOR to the node's URL \" +\n '(the one whose GET /ilp describes it), run `rig entry <url>`, or add ' +\n `connectorUrl to ${configPath}`\n );\n this.name = 'MissingUplinkError';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Settings (pure: env + file → what the client is built from)\n// ---------------------------------------------------------------------------\n\nexport type ChainFamily = 'evm' | 'solana';\n\nexport interface ConnectorSettings {\n connectorUrl?: string;\n connectorSource: 'env' | 'config' | 'legacy-env' | 'legacy-config' | null;\n publishDestination?: string;\n storeDestination?: string;\n storeConnectorUrl?: string;\n storeSealTo?: string;\n relayUrl?: string;\n chain?: ChainFamily;\n /** The full chain id the user named, when they named one (`evm:8453`). */\n chainKey?: string;\n rpcUrl?: string;\n transport: 'auto' | 'http' | 'btp';\n keyDerivation: 'standard' | 'legacy';\n channelStorePath: string;\n facilitatorUrl?: string;\n deposit?: bigint;\n eventFee: bigint;\n solanaKeyFile?: string;\n evmPrivateKey?: string;\n uploadTimeoutMs?: number;\n /** Notes for the caller's stderr: deprecated spellings met on the way. */\n warnings: string[];\n}\n\n/** `evm:8453` → `evm`; `solana` → `solana`; anything else → undefined. */\nexport function chainFamilyOf(\n chain: string | undefined\n): ChainFamily | undefined {\n if (!chain) return undefined;\n const family = chain.split(':')[0];\n return family === 'evm' || family === 'solana' ? family : undefined;\n}\n\nexport function resolveConnectorSettings(args: {\n env: NodeJS.ProcessEnv;\n file: ClientConfigFile;\n configDir: string;\n storeDestinationOverride?: string;\n}): ConnectorSettings {\n const { env, file } = args;\n const warnings: string[] = [];\n\n let connectorUrl: string | undefined;\n let connectorSource: ConnectorSettings['connectorSource'] = null;\n if (env['TOON_CONNECTOR']) {\n connectorUrl = env['TOON_CONNECTOR'];\n connectorSource = 'env';\n } else if (env['TOON_CLIENT_PROXY_URL']) {\n connectorUrl = env['TOON_CLIENT_PROXY_URL'];\n connectorSource = 'legacy-env';\n warnings.push(\n 'rig: TOON_CLIENT_PROXY_URL is the pre-2.0 spelling — set TOON_CONNECTOR to the node URL instead'\n );\n } else if (file.connectorUrl) {\n connectorUrl = file.connectorUrl;\n connectorSource = 'config';\n } else if (file.proxyUrl) {\n connectorUrl = file.proxyUrl;\n connectorSource = 'legacy-config';\n warnings.push(\n 'rig: config `proxyUrl` is the pre-2.0 spelling — `rig entry <url>` records `connectorUrl`'\n );\n }\n if (env['TOON_CLIENT_BTP_URL'] || file.btpUrl) {\n warnings.push(\n \"rig: btpUrl is ignored since 4.0 — the client reads the BTP endpoint from the node's GET /ilp\"\n );\n }\n\n const chainKey =\n env['TOON_CLIENT_CHAIN'] ?? file.chain ?? file.supportedChains?.[0];\n const chain = chainFamilyOf(chainKey);\n if (chainKey && !chain) {\n warnings.push(\n `rig: chain ${JSON.stringify(chainKey)} is not a settlement chain the connector supports (evm | solana) — ignoring it`\n );\n }\n const rpcUrl =\n env['TOON_CLIENT_RPC_URL'] ??\n file.rpcUrl ??\n (chainKey ? file.chainRpcUrls?.[chainKey] : undefined) ??\n (chain ? file.chainRpcUrls?.[chain] : undefined);\n\n const transportRaw = env['TOON_CLIENT_TRANSPORT'] ?? file.transport;\n const transport: ConnectorSettings['transport'] =\n transportRaw === 'http' || transportRaw === 'btp' ? transportRaw : 'auto';\n\n const derivationRaw = env['TOON_CLIENT_KEY_DERIVATION'] ?? file.keyDerivation;\n const keyDerivation: ConnectorSettings['keyDerivation'] =\n derivationRaw === 'standard' ? 'standard' : 'legacy';\n\n const depositRaw = env['TOON_CLIENT_DEPOSIT'] ?? file.deposit;\n const publishDestination =\n env['TOON_CLIENT_PUBLISH_DESTINATION'] ??\n env['TOON_CLIENT_DESTINATION'] ??\n file.publishDestination ??\n file.destination;\n const storeDestination =\n args.storeDestinationOverride ??\n env['TOON_CLIENT_STORE_DESTINATION'] ??\n file.storeDestination;\n const relayUrl = env['TOON_CLIENT_RELAY_URL'] ?? file.relayUrl;\n\n return {\n ...(connectorUrl ? { connectorUrl } : {}),\n connectorSource,\n ...(publishDestination ? { publishDestination } : {}),\n ...(storeDestination ? { storeDestination } : {}),\n ...((env['TOON_CLIENT_STORE_CONNECTOR_URL'] ?? file.storeConnectorUrl)\n ? {\n storeConnectorUrl:\n env['TOON_CLIENT_STORE_CONNECTOR_URL'] ?? file.storeConnectorUrl,\n }\n : {}),\n ...((env['TOON_CLIENT_STORE_SEAL_TO'] ?? file.storeSealTo)\n ? { storeSealTo: env['TOON_CLIENT_STORE_SEAL_TO'] ?? file.storeSealTo }\n : {}),\n ...(relayUrl ? { relayUrl } : {}),\n ...(chain ? { chain } : {}),\n ...(chainKey ? { chainKey } : {}),\n ...(rpcUrl ? { rpcUrl } : {}),\n transport,\n keyDerivation,\n channelStorePath:\n env['TOON_CLIENT_CHANNEL_STORE'] ??\n file.channelStorePath ??\n join(args.configDir, CHANNEL_STORE_FILENAME),\n ...((env['TOON_CLIENT_FACILITATOR_URL'] ?? file.facilitatorUrl) !==\n undefined\n ? {\n facilitatorUrl:\n env['TOON_CLIENT_FACILITATOR_URL'] ?? file.facilitatorUrl,\n }\n : {}),\n ...(depositRaw !== undefined ? { deposit: BigInt(depositRaw) } : {}),\n eventFee: BigInt(\n env['TOON_CLIENT_FEE_PER_EVENT'] ?? file.feePerEvent ?? '0'\n ),\n ...((env['RIG_SOLANA_KEY_FILE'] ?? file.solanaKeyFile)\n ? { solanaKeyFile: env['RIG_SOLANA_KEY_FILE'] ?? file.solanaKeyFile }\n : {}),\n ...((env['RIG_EVM_PRIVATE_KEY'] ?? file.evmPrivateKey)\n ? { evmPrivateKey: env['RIG_EVM_PRIVATE_KEY'] ?? file.evmPrivateKey }\n : {}),\n ...(file.uploadTimeoutMs !== undefined\n ? { uploadTimeoutMs: file.uploadTimeoutMs }\n : {}),\n warnings,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Destinations (pure: settings + the node's self-description)\n// ---------------------------------------------------------------------------\n\n/**\n * The store route a node offers, when the caller named none: its first priced\n * route spelled `*.store`, else `*.ario` (the AR.IO-backed store this\n * repository has always uploaded to), else nothing.\n */\nexport function defaultStoreDestinationFor(\n desc: NodeSelfDescription\n): string | undefined {\n const prefixes = desc.routes.map((r) => r.prefix);\n return (\n prefixes.find((p) => p === 'store' || p.endsWith('.store')) ??\n prefixes.find((p) => p === 'ario' || p.endsWith('.ario')) ??\n prefixes.find((p) => /store/i.test(p))\n );\n}\n\nexport function resolveDestinations(\n desc: NodeSelfDescription,\n settings: Pick<ConnectorSettings, 'publishDestination' | 'storeDestination'>,\n connectorUrl: string\n): { publish: string; store: string } {\n const publish = settings.publishDestination ?? defaultDestinationFor(desc);\n if (!publish) {\n throw new Error(\n `the connector at ${connectorUrl} publishes no priced address of its own — ` +\n 'set publishDestination / TOON_CLIENT_PUBLISH_DESTINATION to one of its GET /ilp routes'\n );\n }\n const store = settings.storeDestination ?? defaultStoreDestinationFor(desc);\n if (!store) {\n throw new Error(\n `the connector at ${connectorUrl} prices no store route (none named *.store or *.ario) — ` +\n 'set storeDestination / TOON_CLIENT_STORE_DESTINATION to the route its store answers on'\n );\n }\n return { publish, store };\n}\n\n// ---------------------------------------------------------------------------\n// Key files\n// ---------------------------------------------------------------------------\n\n/** A Solana keypair file: the 64-byte JSON array `solana-keygen` writes. */\nexport function readSolanaKeyFile(path: string): Uint8Array {\n let parsed: unknown;\n try {\n parsed = JSON.parse(readFileSync(path, 'utf8'));\n } catch (err) {\n throw new Error(\n `failed to read the Solana key file ${path}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (\n !Array.isArray(parsed) ||\n (parsed.length !== 64 && parsed.length !== 32) ||\n !parsed.every((n) => Number.isInteger(n) && n >= 0 && n <= 255)\n ) {\n throw new Error(\n `${path} is not a Solana keypair file (expected a JSON array of 64 bytes)`\n );\n }\n return Uint8Array.from(parsed as number[]);\n}\n\n// ---------------------------------------------------------------------------\n// Money ops on the client's channel and wallet facades\n// ---------------------------------------------------------------------------\n\n/** One x402 channel as the peer→channel map records it. */\nexport function recordFor(\n summary: BatchChannelSummary,\n args: { identity: string; destination: string; peerId: string }\n): Omit<ChannelMapRecord, 'openedAt' | 'lastUsedAt'> {\n const { channel } = summary;\n const tokenNetwork =\n channel.chain === 'evm'\n ? X402_BATCH_SETTLEMENT_ADDRESS\n : PAYMENT_CHANNELS_PROGRAM_ID;\n return {\n channelId: channel.channelId,\n peerId: args.peerId,\n identity: args.identity,\n destination: args.destination,\n chain: channel.network,\n tokenNetwork,\n context: {\n chainType: channel.chain,\n chainId: channel.chain === 'evm' ? evmChainIdOf(channel.network) : 0,\n tokenNetworkAddress: tokenNetwork,\n tokenAddress: channel.config.token,\n recipient: channel.config.receiver,\n },\n depositTotal: summary.depositTotal.toString(),\n };\n}\n\n/**\n * Record `summary` in the peer→channel map, or refresh its deposit when it is\n * already there. A different channel recorded under the same key (one the\n * client replaced when it ran out) is superseded, not overwritten: it still\n * holds what it has left, and `rig channel close/settle` find it by listing.\n */\nexport function recordChannel(\n channelMap: ChannelMapStore,\n summary: BatchChannelSummary,\n args: { identity: string; destination: string; peerId: string }\n): void {\n const next = recordFor(summary, args);\n const previous = channelMap\n .listFor(args.identity, args.destination)\n .find(\n (r) =>\n r.chain === next.chain &&\n r.tokenNetwork === next.tokenNetwork &&\n r.channelId !== next.channelId\n );\n if (previous) channelMap.supersede(previous);\n if (channelMap.list().some((r) => r.channelId === next.channelId)) {\n channelMap.touch(\n {\n identity: next.identity,\n destination: next.destination,\n chain: next.chain,\n tokenNetwork: next.tokenNetwork,\n },\n { depositTotal: next.depositTotal ?? '0' }\n );\n } else {\n channelMap.record(next);\n }\n}\n\n/** The slice of `ToonClient` the money ops drive (structural, so tests fake it). */\nexport interface MoneyClientLike {\n readonly chain: 'evm' | 'solana';\n readonly channel: ChannelFacade;\n readonly wallet: Pick<ToonClient['wallet'], 'balances'>;\n}\n\n/** This channel's step out of a close()/settle() that walks every channel. */\nfunction exitResultFor(\n results: BatchExitResult[],\n channelId: string,\n step: 'close' | 'settle'\n): BatchExitResult | undefined {\n const result = results.find((r) => r.channelId === channelId);\n if (result?.error !== undefined) {\n throw new Error(`channel ${step} of ${channelId} failed: ${result.error}`);\n }\n return result;\n}\n\nexport function buildMoneyOps(args: {\n client: MoneyClientLike;\n channelMap: ChannelMapStore;\n identity: string;\n destination: string;\n peerId: string;\n now?: () => bigint;\n}): StandaloneMoneyOps {\n const { client, channelMap } = args;\n const now = args.now ?? (() => BigInt(Math.floor(Date.now() / 1000)));\n const known = (channelId: string) =>\n channelMap.list().some((r) => r.channelId === channelId);\n /**\n * The client's own record of a recorded channel. Exit is by channel config,\n * which only the client's store holds; a record it does not know belongs to\n * another store or another node.\n */\n const held = (record: ChannelMapRecord): BatchChannelSummary => {\n const summary = client.channel\n .channels()\n .find((c) => c.channel.channelId === record.channelId);\n if (!summary) {\n throw new Error(\n `channel ${record.channelId} is not in this client's x402 channel store: ` +\n 'the record belongs to another store (TOON_CLIENT_CHANNEL_STORE) or another node'\n );\n }\n return summary;\n };\n const record = (summary: BatchChannelSummary) =>\n recordChannel(channelMap, summary, args);\n return {\n async openChannel(opts): Promise<ChannelOpenOutcome> {\n const before = await client.channel.current();\n // A Solana channel has no top-up that costs no SOL: the client opens a\n // fresh sponsored one when the next packet no longer fits instead. Say\n // so before anything is opened, rather than open and then refuse.\n if (opts?.deposit !== undefined && client.chain === 'solana') {\n throw new Error(\n 'a Solana x402 channel cannot be topped up: set TOON_CLIENT_DEPOSIT ' +\n '(config `deposit`) to what a channel opens with; the client opens a ' +\n 'fresh sponsored channel when the current one runs out'\n );\n }\n const resumed = before !== undefined && known(before.channel.channelId);\n let summary = before ?? (await client.channel.open());\n if (opts?.deposit !== undefined) {\n summary = await client.channel.deposit(opts.deposit);\n }\n record(summary);\n return {\n channelId: summary.channel.channelId,\n resumed,\n destination: args.destination,\n chain: summary.channel.network,\n peerId: args.peerId,\n depositTotal: summary.depositTotal.toString(),\n ...(opts?.deposit !== undefined\n ? { depositAdded: opts.deposit.toString() }\n : {}),\n };\n },\n async closeChannel(rec): Promise<ChannelCloseOutcome> {\n held(rec);\n // The client leaves EVERY channel still open with the node in one call:\n // a channel replaced when it ran out still holds what it has left.\n const results = await client.channel.close();\n const result = exitResultFor(results, rec.channelId, 'close');\n const after = held(rec);\n const closedAt = after.closedAt ?? now();\n return {\n channelId: rec.channelId,\n ...(result?.transaction ? { txHash: result.transaction } : {}),\n closedAt: closedAt.toString(),\n settleableAt: (\n result?.settleableAt ??\n after.settleableAt ??\n closedAt\n ).toString(),\n };\n },\n async settleChannel(rec): Promise<ChannelSettleOutcome> {\n held(rec);\n const results = await client.channel.settle();\n const result = exitResultFor(results, rec.channelId, 'settle');\n const after = held(rec);\n if (after.settledAt === undefined) {\n const at = after.settleableAt;\n throw new Error(\n `channel ${rec.channelId} is not settleable yet` +\n (at !== undefined\n ? ` (settleable at ${new Date(Number(at) * 1000).toISOString()})`\n : '') +\n ': nothing was spent; re-run after that time'\n );\n }\n channelMap.supersede(rec);\n return {\n channelId: rec.channelId,\n ...(result?.transaction ? { txHash: result.transaction } : {}),\n };\n },\n async walletChainBalances(): Promise<WalletChainBalanceInfo[]> {\n return (await client.wallet.balances()).map((b) => ({\n chain: b.chain,\n chainKey: b.chainKey,\n address: b.address,\n ...(b.native ? { native: b.native } : {}),\n tokens: b.tokens,\n ...(b.unreadable !== undefined ? { unreadable: b.unreadable } : {}),\n ...(b.error !== undefined ? { error: b.error } : {}),\n }));\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// The context factory\n// ---------------------------------------------------------------------------\n\n/** What `rig balance` gets when nothing is configured to pay with. */\nclass UnconfiguredPublisher {\n constructor(private readonly error: MissingUplinkError) {}\n getFeeRates(): Promise<never> {\n return Promise.reject(this.error);\n }\n uploadGitObject(): Promise<never> {\n return Promise.reject(this.error);\n }\n publishEvent(): Promise<never> {\n return Promise.reject(this.error);\n }\n}\n\nexport async function createStandaloneContext(\n options: StandaloneLoadOptions\n): Promise<StandaloneContext> {\n const { env } = options;\n const warn = (line: string) => options.warn(line);\n const dir = configDir(env);\n const configPath = join(dir, 'config.json');\n const file = readClientConfig(configPath);\n const identity = await resolveIdentity(options);\n const nostr = deriveNostrKeyFromMnemonic(\n identity.mnemonic,\n identity.accountIndex\n );\n\n const settings = resolveConnectorSettings({\n env,\n file,\n configDir: dir,\n ...(options.storeDestination\n ? { storeDestinationOverride: options.storeDestination }\n : {}),\n });\n for (const line of settings.warnings) warn(line);\n const defaultRelayUrls = settings.relayUrl ? [settings.relayUrl] : [];\n\n if (!settings.connectorUrl) {\n const missing = new MissingUplinkError(configPath);\n if (options.requireUplink === false) {\n return {\n ownerPubkey: nostr.pubkey,\n identitySource: identity.source,\n identitySourceLabel: identity.sourceLabel,\n publisher: new UnconfiguredPublisher(missing),\n defaultRelayUrls,\n // SHAs the 30618 object map does not cover are resolved against\n // the configured gateway's GraphQL endpoint, not arweave.net (#183).\n fetchRemote: (args) =>\n fetchRemoteState({\n ...args,\n resolveSha: shaResolverFor(undefined, env),\n }),\n stop: () => Promise.resolve(),\n };\n }\n throw missing;\n }\n const connectorUrl = settings.connectorUrl;\n\n // Client 4.x pays with x402 vouchers from its own store. A 3.x toon-channel\n // store is never handed to it (the connector refuses those claims, and the\n // file is what the 3.x rig needs to take its deposits back): only named.\n if (isToonChannelStore(settings.channelStorePath)) {\n throw new Error(\n `${settings.channelStorePath} is a client 3.x toon-channel store, which a current ` +\n 'connector no longer honours: point TOON_CLIENT_CHANNEL_STORE (config ' +\n `channelStorePath) at a new file, e.g. ${join(dir, CHANNEL_STORE_FILENAME)}; ` +\n 'the old file is left as it is'\n );\n }\n for (const legacy of legacyChannelFiles(dir)) {\n if (legacy === settings.channelStorePath) continue;\n warn(\n `rig: ${legacy} is client 3.x toon-channel state; client 4.x ignores it and keeps its ` +\n `x402 channels in ${settings.channelStorePath}`\n );\n }\n\n // One writer per identity per machine: two rig processes signing vouchers on\n // one channel race the running total, and the connector refuses the loser.\n if (!standaloneForced(env)) await checkDaemonIdentity(nostr.pubkey);\n const lock = await NonceLock.acquire(nostr.pubkey);\n\n const clients: ToonClient[] = [];\n // Set once the client is up: records the channel paid work drew on (the\n // client opens one on first use), so `rig channel list/close/settle` and\n // `rig balance` see it. Best effort: a failure here loses no money, the\n // client's own store still holds the channel.\n let recordHeld: (() => Promise<void>) | undefined;\n const stop = async () => {\n await recordHeld?.().catch(() => undefined);\n for (const c of clients) await c.close();\n lock.release();\n };\n\n try {\n const payerKeys: Pick<\n ToonClientConfig,\n | 'mnemonic'\n | 'accountIndex'\n | 'keyDerivation'\n | 'solanaSecretKey'\n | 'evmPrivateKey'\n > = {\n mnemonic: identity.mnemonic,\n accountIndex: identity.accountIndex,\n keyDerivation: settings.keyDerivation,\n ...(settings.solanaKeyFile\n ? { solanaSecretKey: readSolanaKeyFile(settings.solanaKeyFile) }\n : {}),\n ...(settings.evmPrivateKey\n ? { evmPrivateKey: settings.evmPrivateKey }\n : {}),\n };\n const shared: Omit<ToonClientConfig, 'connector' | 'channelStore'> = {\n ...payerKeys,\n ...(settings.chain ? { chain: settings.chain } : {}),\n ...(settings.rpcUrl ? { rpcUrl: settings.rpcUrl } : {}),\n transport: settings.transport,\n // The first paid send opens the channel (on Solana the connector\n // sponsors the open: USDC for the deposit, no SOL), and a send the\n // channel cannot cover opens a fresh one.\n autoOpenChannel: true,\n ...(settings.deposit !== undefined ? { deposit: settings.deposit } : {}),\n // A Base deposit goes through a facilitator; Solana names none, so an\n // unset facilitator on Solana is '' rather than the devnet default.\n ...(settings.facilitatorUrl !== undefined\n ? { facilitatorUrl: settings.facilitatorUrl }\n : settings.chain === 'solana'\n ? { facilitatorUrl: '' }\n : {}),\n };\n if (settings.chain && !settings.rpcUrl) {\n warn(\n `rig: no rpcUrl configured for ${settings.chain} — the client falls back to its devnet preset; ` +\n 'set TOON_CLIENT_RPC_URL (or config rpcUrl) for a mainnet node'\n );\n }\n\n const client = await ToonClient.create({\n ...shared,\n connector: connectorUrl,\n channelStore: settings.channelStorePath,\n });\n clients.push(client);\n const desc = await client.describe();\n const destinations = resolveDestinations(desc, settings, connectorUrl);\n if (!settings.chain && desc.batchSettlements.length > 1) {\n warn(\n `rig: paying on ${client.chain}, the first chain ${connectorUrl} offers that this ` +\n `identity holds a key for (it offers ${desc.batchSettlements.map((t) => t.network).join(', ')}); ` +\n 'set TOON_CLIENT_CHAIN (config chain) to choose'\n );\n }\n\n // The store leg: the same client unless the store terminates on another\n // node that holds its own channel (then its own client + channel store).\n let storeClient = client;\n if (\n settings.storeConnectorUrl &&\n normalizeUrl(settings.storeConnectorUrl) !== normalizeUrl(connectorUrl)\n ) {\n storeClient = await ToonClient.create({\n ...shared,\n connector: settings.storeConnectorUrl,\n channelStore: settings.channelStorePath.replace(\n /(\\.json)?$/,\n '.store.json'\n ),\n });\n clients.push(storeClient);\n }\n\n const publisher = new ConnectorPublisher({\n publish: { client, destination: destinations.publish },\n store: {\n client: storeClient,\n destination: destinations.store,\n ...(storeClient === client && settings.storeSealTo\n ? { sealTo: settings.storeSealTo }\n : {}),\n },\n nostrSecretKey: nostr.secretKey,\n eventFee: settings.eventFee,\n ...(settings.uploadTimeoutMs !== undefined\n ? { uploadTimeoutMs: settings.uploadTimeoutMs }\n : {}),\n warn,\n });\n\n const channelMap = new ChannelMapStore({\n mapPath: join(dir, RIG_CHANNEL_MAP_FILENAME),\n watermarkPath: settings.channelStorePath,\n });\n const anchor = {\n identity: nostr.pubkey,\n destination: options.channelDestination ?? destinations.publish,\n peerId: desc.edgeIdentity?.keyId ?? connectorUrl,\n };\n const money = buildMoneyOps({ client, channelMap, ...anchor });\n recordHeld = async () => {\n const current = await client.channel.current();\n if (current) recordChannel(channelMap, current, anchor);\n };\n\n return {\n ownerPubkey: nostr.pubkey,\n identitySource: identity.source,\n identitySourceLabel: identity.sourceLabel,\n publisher,\n defaultRelayUrls,\n // As above (#183): the GraphQL fallback follows RIG_ARWEAVE_GATEWAY.\n fetchRemote: (args) =>\n fetchRemoteState({\n ...args,\n resolveSha: shaResolverFor(undefined, env),\n }),\n money,\n stop,\n };\n } catch (err) {\n await stop().catch(() => undefined);\n throw err;\n }\n}\n\nfunction normalizeUrl(url: string): string {\n return url.replace(/\\/+$/, '').replace(/\\/ilp$/, '');\n}\n"],"mappings":"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","names":["record"]}
|
|
File without changes
|
|
File without changes
|