@toon-protocol/rig 2.10.2 → 2.11.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/dist/cli/rig.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  defaultDaemonPort,
36
36
  resolveChannelPaths,
37
37
  resolveConflictingPath
38
- } from "../chunk-57UY3OGX.js";
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-CTQKDJBL.js");
1077
+ const mod = await import("../standalone-mode-YMIY4GL3.js");
1078
1078
  return mod.createStandaloneContext(options);
1079
1079
  };
1080
1080
  function identityReport(ctx) {
@@ -1712,8 +1712,236 @@ async function runBalance(args, deps) {
1712
1712
  }
1713
1713
  }
1714
1714
 
1715
- // src/cli/channel.ts
1715
+ // src/cli/chain.ts
1716
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
1717
+ import { homedir as homedir2 } from "os";
1718
+ import { dirname, join as join2 } from "path";
1716
1719
  import { parseArgs as parseArgs4 } from "util";
1720
+ var FAMILY_USDC = {
1721
+ evm: "EVM USDC (Base Sepolia on devnet)",
1722
+ solana: "Solana USDC",
1723
+ mina: "Mina USDC"
1724
+ };
1725
+ var FAMILY_ALIASES = {
1726
+ evm: "evm",
1727
+ eth: "evm",
1728
+ sol: "solana",
1729
+ solana: "solana",
1730
+ mina: "mina"
1731
+ };
1732
+ var CHAIN_ARG_LIST = "evm | sol | solana | mina (or a full id like evm:base:84532)";
1733
+ var CHAIN_USAGE = `Usage: rig chain [set <chain> | unset]
1734
+
1735
+ Choose which chain \u2014 and therefore which USDC token \u2014 settles paid \`rig\`
1736
+ writes. The choice is saved to the client config's \`chain\` field and applies to
1737
+ every subsequent paid command (there is no per-command chain flag). Free: only
1738
+ the local config file is touched.
1739
+
1740
+ rig chain show the current settlement-chain preference
1741
+ rig chain set <chain> pin the settlement chain / USDC:
1742
+ evm \u2192 EVM USDC (Base Sepolia on devnet)
1743
+ sol \u2192 Solana USDC
1744
+ mina \u2192 Mina USDC
1745
+ (a full id like evm:base:84532 or solana:devnet also
1746
+ works; \`solana\` is accepted for \`sol\`, \`eth\` for \`evm\`)
1747
+ rig chain unset clear the pin \u2014 revert to automatic selection
1748
+
1749
+ When nothing is pinned, rig auto-selects: your most-recently-used open channel's
1750
+ chain, else the first announced chain your wallet holds USDC on, else the first
1751
+ announced EVM chain.
1752
+
1753
+ Options:
1754
+ --json machine-readable envelope
1755
+ -h, --help show this help`;
1756
+ function configPathFor(env) {
1757
+ const dir = env["TOON_CLIENT_HOME"] ?? join2(homedir2(), ".toon-client");
1758
+ return join2(dir, "config.json");
1759
+ }
1760
+ function readChainConfig(configPath) {
1761
+ try {
1762
+ return JSON.parse(readFileSync2(configPath, "utf8"));
1763
+ } catch (err) {
1764
+ if (err.code === "ENOENT") return {};
1765
+ throw new Error(
1766
+ `failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`
1767
+ );
1768
+ }
1769
+ }
1770
+ function writeChainConfig(configPath, file) {
1771
+ mkdirSync2(dirname(configPath), { recursive: true });
1772
+ writeFileSync2(configPath, `${JSON.stringify(file, null, 2)}
1773
+ `, "utf8");
1774
+ }
1775
+ function normalizeChain(raw) {
1776
+ if (raw.includes(":")) {
1777
+ const family = raw.split(":")[0]?.toLowerCase() ?? "";
1778
+ if (!(family in FAMILY_USDC)) {
1779
+ throw new Error(
1780
+ `unknown chain family in ${JSON.stringify(raw)} \u2014 must start with evm:, solana:, or mina:`
1781
+ );
1782
+ }
1783
+ return raw;
1784
+ }
1785
+ const canonical = FAMILY_ALIASES[raw.toLowerCase()];
1786
+ if (!canonical) {
1787
+ throw new Error(`chain must be one of ${CHAIN_ARG_LIST}, got ${JSON.stringify(raw)}`);
1788
+ }
1789
+ return canonical;
1790
+ }
1791
+ function usdcFor(chain) {
1792
+ const family = (chain.includes(":") ? chain.split(":")[0] ?? chain : chain).toLowerCase();
1793
+ return FAMILY_USDC[family] ?? `${family} USDC`;
1794
+ }
1795
+ async function runChain(args, deps) {
1796
+ const { io: io2, env } = deps;
1797
+ let positionals;
1798
+ let json = false;
1799
+ try {
1800
+ const parsed = parseArgs4({
1801
+ args,
1802
+ allowPositionals: true,
1803
+ options: {
1804
+ json: { type: "boolean", default: false },
1805
+ help: { type: "boolean", short: "h", default: false }
1806
+ }
1807
+ });
1808
+ if (parsed.values.help) {
1809
+ io2.out(CHAIN_USAGE);
1810
+ return 0;
1811
+ }
1812
+ positionals = parsed.positionals;
1813
+ json = parsed.values.json ?? false;
1814
+ } catch (err) {
1815
+ io2.err(err instanceof Error ? err.message : String(err));
1816
+ io2.err(CHAIN_USAGE);
1817
+ return 2;
1818
+ }
1819
+ const [sub, ...subRest] = positionals;
1820
+ if (sub !== void 0 && sub !== "set" && sub !== "unset") {
1821
+ io2.err(`unknown subcommand ${JSON.stringify(sub)} \u2014 expected \`set\`, \`unset\`, or no argument`);
1822
+ io2.err(CHAIN_USAGE);
1823
+ return 2;
1824
+ }
1825
+ if (sub === "set" && subRest.length !== 1) {
1826
+ io2.err(
1827
+ subRest.length === 0 ? `rig chain set needs a chain: ${CHAIN_ARG_LIST}` : `rig chain set takes exactly one chain, got ${subRest.length}: ${subRest.join(" ")}`
1828
+ );
1829
+ io2.err(CHAIN_USAGE);
1830
+ return 2;
1831
+ }
1832
+ if (sub === "unset" && subRest.length !== 0) {
1833
+ io2.err(`rig chain unset takes no arguments, got: ${subRest.join(" ")}`);
1834
+ io2.err(CHAIN_USAGE);
1835
+ return 2;
1836
+ }
1837
+ let setValue;
1838
+ if (sub === "set") {
1839
+ try {
1840
+ setValue = normalizeChain(subRest[0]);
1841
+ } catch (err) {
1842
+ io2.err(err instanceof Error ? err.message : String(err));
1843
+ io2.err(CHAIN_USAGE);
1844
+ return 2;
1845
+ }
1846
+ }
1847
+ try {
1848
+ const configPath = configPathFor(env);
1849
+ const file = readChainConfig(configPath);
1850
+ const envChain = env["TOON_CLIENT_CHAIN"];
1851
+ const supported0 = file.supportedChains?.[0];
1852
+ const precedenceWarnings = (targetField) => {
1853
+ const w = [];
1854
+ if (envChain !== void 0) {
1855
+ w.push(
1856
+ `TOON_CLIENT_CHAIN=${envChain} is set in the environment and overrides the config ${targetField === "chain" ? "value you just wrote" : "file"} \u2014 unset it for the config to take effect.`
1857
+ );
1858
+ }
1859
+ if (supported0 !== void 0) {
1860
+ w.push(
1861
+ `config \`supportedChains\` is set (first entry ${JSON.stringify(supported0)}) and takes precedence over \`chain\` \u2014 clear or reorder it for this pin to take effect.`
1862
+ );
1863
+ }
1864
+ return w;
1865
+ };
1866
+ if (sub === "set") {
1867
+ const value = setValue;
1868
+ file.chain = value;
1869
+ writeChainConfig(configPath, file);
1870
+ const warnings = precedenceWarnings("chain");
1871
+ if (json) {
1872
+ io2.emitJson({
1873
+ command: "chain",
1874
+ chain: envChain ?? value,
1875
+ source: envChain !== void 0 ? "env" : "config",
1876
+ usdc: usdcFor(envChain ?? value),
1877
+ wrote: value,
1878
+ configPath,
1879
+ ...warnings.length ? { warnings } : {}
1880
+ });
1881
+ return 0;
1882
+ }
1883
+ io2.out(`Settlement chain set to ${value} \u2192 spends ${usdcFor(value)}.`);
1884
+ io2.out(`Saved to ${configPath}. Applies to the next paid command (e.g. \`rig push\`).`);
1885
+ for (const w of warnings) io2.err(`warning: ${w}`);
1886
+ return 0;
1887
+ }
1888
+ if (sub === "unset") {
1889
+ const had = file.chain;
1890
+ delete file.chain;
1891
+ writeChainConfig(configPath, file);
1892
+ const stillPinned = envChain ?? supported0;
1893
+ if (json) {
1894
+ io2.emitJson({
1895
+ command: "chain",
1896
+ chain: stillPinned ?? null,
1897
+ source: envChain !== void 0 ? "env" : supported0 !== void 0 ? "supportedChains" : "auto",
1898
+ usdc: stillPinned ? usdcFor(stillPinned) : null,
1899
+ wrote: null,
1900
+ configPath,
1901
+ ...precedenceWarnings(null).length ? { warnings: precedenceWarnings(null) } : {}
1902
+ });
1903
+ return 0;
1904
+ }
1905
+ io2.out(
1906
+ had !== void 0 ? `Cleared the settlement-chain pin (was ${had}).` : "No settlement-chain pin was set."
1907
+ );
1908
+ if (stillPinned !== void 0) {
1909
+ io2.out(`Still pinned to ${stillPinned} by ${envChain !== void 0 ? "TOON_CLIENT_CHAIN" : "config supportedChains"} \u2192 ${usdcFor(stillPinned)}.`);
1910
+ } else {
1911
+ io2.out("Reverted to automatic selection (most-recent channel \u2192 first funded announced chain \u2192 first EVM).");
1912
+ }
1913
+ return 0;
1914
+ }
1915
+ const effective = envChain ?? file.chain ?? supported0;
1916
+ const source = envChain !== void 0 ? "env" : file.chain !== void 0 ? "config" : supported0 !== void 0 ? "supportedChains" : "auto";
1917
+ if (json) {
1918
+ io2.emitJson({
1919
+ command: "chain",
1920
+ chain: effective ?? null,
1921
+ source,
1922
+ usdc: effective ? usdcFor(effective) : null,
1923
+ configPath
1924
+ });
1925
+ return 0;
1926
+ }
1927
+ if (effective !== void 0) {
1928
+ const via = source === "env" ? "TOON_CLIENT_CHAIN env" : source === "config" ? `config \`chain\` (${configPath})` : `config \`supportedChains[0]\``;
1929
+ io2.out(`Settlement chain: ${effective} \u2192 spends ${usdcFor(effective)} (from ${via}).`);
1930
+ io2.out("Change it with `rig chain set <evm|sol|mina>`, or `rig chain unset` for auto.");
1931
+ } else {
1932
+ io2.out("Settlement chain: (auto) \u2014 no pin set.");
1933
+ io2.out("rig picks your most-recent open channel, else the first announced chain your");
1934
+ io2.out("wallet holds USDC on, else the first announced EVM chain.");
1935
+ io2.out("Pin one with `rig chain set <evm|sol|mina>`.");
1936
+ }
1937
+ return 0;
1938
+ } catch (err) {
1939
+ return emitCliError(io2, json, "chain", err);
1940
+ }
1941
+ }
1942
+
1943
+ // src/cli/channel.ts
1944
+ import { parseArgs as parseArgs5 } from "util";
1717
1945
  var CHANNEL_USAGE = `Usage: rig channel <subcommand>
1718
1946
 
1719
1947
  Manage the payment channels paid rig commands hold with relay/store peers.
@@ -1780,7 +2008,7 @@ function runChannelList(args, deps) {
1780
2008
  const { io: io2, env } = deps;
1781
2009
  let json = false;
1782
2010
  try {
1783
- const { values } = parseArgs4({
2011
+ const { values } = parseArgs5({
1784
2012
  args,
1785
2013
  options: {
1786
2014
  json: { type: "boolean", default: false },
@@ -1899,7 +2127,7 @@ async function runChannelOpen(args, deps) {
1899
2127
  let yes = false;
1900
2128
  let json = false;
1901
2129
  try {
1902
- const { values } = parseArgs4({
2130
+ const { values } = parseArgs5({
1903
2131
  args,
1904
2132
  options: {
1905
2133
  peer: { type: "string" },
@@ -2036,7 +2264,7 @@ async function runChannelWithdrawStep(args, deps, step) {
2036
2264
  let yes = false;
2037
2265
  let json = false;
2038
2266
  try {
2039
- const { values, positionals } = parseArgs4({
2267
+ const { values, positionals } = parseArgs5({
2040
2268
  args,
2041
2269
  options: {
2042
2270
  yes: { type: "boolean", default: false },
@@ -2177,8 +2405,8 @@ async function stopQuietly(ctx) {
2177
2405
 
2178
2406
  // src/cli/clone.ts
2179
2407
  import { mkdtemp, mkdir, readdir, rename, rm, rmdir } from "fs/promises";
2180
- import { basename, dirname, join as join2, resolve } from "path";
2181
- import { parseArgs as parseArgs5 } from "util";
2408
+ import { basename, dirname as dirname2, join as join3, resolve } from "path";
2409
+ import { parseArgs as parseArgs6 } from "util";
2182
2410
  var CLONE_USAGE = `Usage: rig clone <relay-url> <owner>/<repo-id> [dir] [options]
2183
2411
 
2184
2412
  Clone a TOON repository \u2014 FREE (relay reads + Arweave gateway downloads; no
@@ -2219,7 +2447,7 @@ var MissingRemoteObjectsError = class extends Error {
2219
2447
  };
2220
2448
  var WS_URL_RE = /^wss?:\/\//i;
2221
2449
  function parseCloneArgs(args) {
2222
- const { values, positionals } = parseArgs5({
2450
+ const { values, positionals } = parseArgs6({
2223
2451
  args,
2224
2452
  options: {
2225
2453
  json: { type: "boolean", default: false },
@@ -2346,9 +2574,9 @@ async function runClone(args, deps) {
2346
2574
  `warning: unreachable object ${sha} (tx ${txId}) could not be downloaded \u2014 not needed by any ref, continuing`
2347
2575
  );
2348
2576
  }
2349
- const parent = dirname(dest);
2577
+ const parent = dirname2(dest);
2350
2578
  await mkdir(parent, { recursive: true });
2351
- tempDir = await mkdtemp(join2(parent, `.${basename(dest)}.rig-clone-`));
2579
+ tempDir = await mkdtemp(join3(parent, `.${basename(dest)}.rig-clone-`));
2352
2580
  await runGit(tempDir, [
2353
2581
  "init",
2354
2582
  "--quiet",
@@ -2418,7 +2646,7 @@ async function runClone(args, deps) {
2418
2646
 
2419
2647
  // src/cli/events.ts
2420
2648
  import { readFile } from "fs/promises";
2421
- import { parseArgs as parseArgs7 } from "util";
2649
+ import { parseArgs as parseArgs8 } from "util";
2422
2650
  import {
2423
2651
  REPOSITORY_ANNOUNCEMENT_KIND as REPOSITORY_ANNOUNCEMENT_KIND2,
2424
2652
  STATUS_APPLIED_KIND as STATUS_APPLIED_KIND2,
@@ -2428,7 +2656,7 @@ import {
2428
2656
  } from "@toon-protocol/core/nip34";
2429
2657
 
2430
2658
  // src/cli/tracker.ts
2431
- import { parseArgs as parseArgs6 } from "util";
2659
+ import { parseArgs as parseArgs7 } from "util";
2432
2660
  import {
2433
2661
  ISSUE_KIND,
2434
2662
  PATCH_KIND,
@@ -2761,7 +2989,7 @@ async function runList(args, deps, spec) {
2761
2989
  const { io: io2 } = deps;
2762
2990
  let flags;
2763
2991
  try {
2764
- const { values, positionals } = parseArgs6({
2992
+ const { values, positionals } = parseArgs7({
2765
2993
  args,
2766
2994
  options: TRACKER_OPTIONS,
2767
2995
  allowPositionals: true
@@ -2825,7 +3053,7 @@ async function runShow(args, deps, spec) {
2825
3053
  let flags;
2826
3054
  let eventId;
2827
3055
  try {
2828
- const { values, positionals } = parseArgs6({
3056
+ const { values, positionals } = parseArgs7({
2829
3057
  args,
2830
3058
  options: TRACKER_OPTIONS,
2831
3059
  allowPositionals: true
@@ -3212,7 +3440,7 @@ async function runIssue(args, deps) {
3212
3440
  let bodyFile;
3213
3441
  let labels;
3214
3442
  try {
3215
- const { values } = parseArgs7({
3443
+ const { values } = parseArgs8({
3216
3444
  args: rest,
3217
3445
  options: {
3218
3446
  ...COMMON_OPTIONS,
@@ -3288,7 +3516,7 @@ async function runComment(args, deps) {
3288
3516
  let parentAuthor;
3289
3517
  let marker;
3290
3518
  try {
3291
- const { values, positionals } = parseArgs7({
3519
+ const { values, positionals } = parseArgs8({
3292
3520
  args,
3293
3521
  options: {
3294
3522
  ...COMMON_OPTIONS,
@@ -3388,7 +3616,7 @@ async function runPrCreate(rest, deps) {
3388
3616
  let bodyFlag;
3389
3617
  let bodyFile;
3390
3618
  try {
3391
- const { values } = parseArgs7({
3619
+ const { values } = parseArgs8({
3392
3620
  args: rest,
3393
3621
  options: {
3394
3622
  ...COMMON_OPTIONS,
@@ -3516,7 +3744,7 @@ async function runPrStatus(args, deps) {
3516
3744
  let targetEventId;
3517
3745
  let status;
3518
3746
  try {
3519
- const { values, positionals } = parseArgs7({
3747
+ const { values, positionals } = parseArgs8({
3520
3748
  args,
3521
3749
  options: COMMON_OPTIONS,
3522
3750
  allowPositionals: true
@@ -3595,7 +3823,7 @@ async function warnIfNotMaintainer(deps, args) {
3595
3823
  }
3596
3824
 
3597
3825
  // src/cli/fetch.ts
3598
- import { parseArgs as parseArgs8 } from "util";
3826
+ import { parseArgs as parseArgs9 } from "util";
3599
3827
  var FETCH_USAGE = `Usage: rig fetch [remote] [options]
3600
3828
 
3601
3829
  Fetch from a TOON remote \u2014 FREE (relay reads + Arweave gateway downloads; no
@@ -3649,7 +3877,7 @@ async function runFetch(args, deps) {
3649
3877
  let ownerFlag;
3650
3878
  let concurrency;
3651
3879
  try {
3652
- const { values, positionals } = parseArgs8({
3880
+ const { values, positionals } = parseArgs9({
3653
3881
  args,
3654
3882
  options: {
3655
3883
  json: { type: "boolean", default: false },
@@ -3814,27 +4042,41 @@ async function runFetch(args, deps) {
3814
4042
  }
3815
4043
 
3816
4044
  // src/cli/fund.ts
3817
- import { readFileSync as readFileSync2 } from "fs";
3818
- import { homedir as homedir2 } from "os";
3819
- import { join as join3 } from "path";
3820
- import { parseArgs as parseArgs9 } from "util";
4045
+ import { readFileSync as readFileSync3 } from "fs";
4046
+ import { homedir as homedir3 } from "os";
4047
+ import { join as join4 } from "path";
4048
+ import { parseArgs as parseArgs10 } from "util";
3821
4049
  var DEVNET_FAUCET_URL = "https://faucet.devnet.toonprotocol.dev";
3822
4050
  var CHAINS = ["evm", "solana", "mina"];
3823
- var CHAIN_CHOICES = [...CHAINS, "all"];
3824
- var NATIVE_COIN = {
3825
- evm: "ETH",
3826
- solana: "SOL",
3827
- mina: "MINA"
4051
+ var CHAIN_ALIASES = {
4052
+ evm: "evm",
4053
+ eth: "evm",
4054
+ sol: "solana",
4055
+ solana: "solana",
4056
+ mina: "mina",
4057
+ all: "all"
3828
4058
  };
3829
- var FUND_USAGE = `Usage: rig fund [options]
4059
+ var CHAIN_ARG_LIST2 = "evm | sol | solana | mina | all";
4060
+ function resolveChainArg(raw) {
4061
+ if (raw === void 0) return void 0;
4062
+ const canonical = CHAIN_ALIASES[raw.toLowerCase()];
4063
+ if (!canonical) {
4064
+ throw new Error(
4065
+ `chain must be one of ${CHAIN_ARG_LIST2}, got ${JSON.stringify(raw)}`
4066
+ );
4067
+ }
4068
+ return canonical;
4069
+ }
4070
+ var FUND_USAGE = `Usage: rig fund [chain] [options]
3830
4071
 
3831
- Drip devnet test funds to the active identity's wallet \u2014 free (the faucet
3832
- pays). By default funds ALL supported chains (evm + solana + mina), each drip
3833
- covering the native coin AND USDC, so the wallet matches the multi-chain
3834
- \`rig balance\` view in one run. The per-chain drips run in parallel and are
3835
- independent \u2014 one chain's faucet failing does not abort the others (exit 0
3836
- only when every targeted chain funded; exit 1 if any failed, with the
3837
- per-chain breakdown always shown).
4072
+ Drip devnet USDC to the active identity's wallet \u2014 free (the faucet pays). Each
4073
+ drip funds ONLY the settlement token (USDC) and assumes the wallet already holds
4074
+ enough native gas to transact. By default funds ALL supported chains (evm +
4075
+ solana + mina) so the wallet matches the multi-chain \`rig balance\` view in one
4076
+ run; name a chain \u2014 positional (\`rig fund sol\`) or \`--chain\` \u2014 to narrow to
4077
+ one. The per-chain drips run in parallel and are independent \u2014 one chain's
4078
+ faucet failing does not abort the others (exit 0 only when every targeted chain
4079
+ funded; exit 1 if any failed, with the per-chain breakdown always shown).
3838
4080
 
3839
4081
  The identity comes from RIG_MNEMONIC (env or a project .env) or the
3840
4082
  ~/.toon-client keystore/config; the faucet from TOON_CLIENT_FAUCET_URL, the
@@ -3846,10 +4088,11 @@ chain (there is no --amount). On a network without a faucet, prints the wallet
3846
4088
  address(es) to fund externally instead.
3847
4089
 
3848
4090
  Options:
3849
- --chain <chain> evm | solana | mina | all \u2014 fund one chain, or all
3850
- (default: all supported chains)
4091
+ [chain] evm | sol | solana | mina | all \u2014 positional chain to
4092
+ fund (default: all supported chains)
4093
+ --chain <chain> same as the positional chain argument
3851
4094
  --address <address> fund this address instead of the identity's own
3852
- (requires an explicit single --chain)
4095
+ (requires an explicit single chain)
3853
4096
  --json machine-readable envelope (per-chain results array)
3854
4097
  -h, --help show this help`;
3855
4098
  var SHARED_DEVNET_SUFFIX = ".devnet.toonprotocol.dev";
@@ -3906,11 +4149,11 @@ function noFaucetGuidance(network, devnetOrigin) {
3906
4149
  return `${head}. If you meant the shared devnet, set TOON_CLIENT_NETWORK=devnet and re-run \`rig fund\` \u2014 no faucet URL is needed there. If this is a self-hosted network with its own faucet, set TOON_CLIENT_FAUCET_URL (or the faucetUrl config field). ${external}`;
3907
4150
  }
3908
4151
  function readFundConfig(env) {
3909
- const dir = env["TOON_CLIENT_HOME"] ?? join3(homedir2(), ".toon-client");
3910
- const configPath = join3(dir, "config.json");
4152
+ const dir = env["TOON_CLIENT_HOME"] ?? join4(homedir3(), ".toon-client");
4153
+ const configPath = join4(dir, "config.json");
3911
4154
  try {
3912
4155
  return {
3913
- file: JSON.parse(readFileSync2(configPath, "utf8")),
4156
+ file: JSON.parse(readFileSync3(configPath, "utf8")),
3914
4157
  configPath
3915
4158
  };
3916
4159
  } catch (err) {
@@ -3924,12 +4167,13 @@ function readFundConfig(env) {
3924
4167
  }
3925
4168
  async function runFund(args, deps) {
3926
4169
  const { io: io2, env } = deps;
3927
- let chainFlag;
4170
+ let resolvedChain;
3928
4171
  let addressFlag;
3929
4172
  let json = false;
3930
4173
  try {
3931
- const { values } = parseArgs9({
4174
+ const { values, positionals } = parseArgs10({
3932
4175
  args,
4176
+ allowPositionals: true,
3933
4177
  options: {
3934
4178
  chain: { type: "string" },
3935
4179
  address: { type: "string" },
@@ -3941,17 +4185,23 @@ async function runFund(args, deps) {
3941
4185
  io2.out(FUND_USAGE);
3942
4186
  return 0;
3943
4187
  }
3944
- chainFlag = values.chain;
3945
- addressFlag = values.address;
3946
- json = values.json ?? false;
3947
- if (chainFlag !== void 0 && !CHAIN_CHOICES.includes(chainFlag)) {
4188
+ if (positionals.length > 1) {
3948
4189
  throw new Error(
3949
- `--chain must be one of ${CHAIN_CHOICES.join(" | ")}, got ${JSON.stringify(chainFlag)}`
4190
+ `rig fund takes at most one chain argument, got ${positionals.length}: ${positionals.join(" ")}`
3950
4191
  );
3951
4192
  }
3952
- if (addressFlag !== void 0 && (chainFlag === void 0 || chainFlag === "all")) {
4193
+ const positionalChain = positionals[0];
4194
+ if (positionalChain !== void 0 && values.chain !== void 0) {
4195
+ throw new Error(
4196
+ "give the chain as a positional argument (`rig fund sol`) OR with --chain, not both"
4197
+ );
4198
+ }
4199
+ resolvedChain = resolveChainArg(positionalChain ?? values.chain);
4200
+ addressFlag = values.address;
4201
+ json = values.json ?? false;
4202
+ if (addressFlag !== void 0 && (resolvedChain === void 0 || resolvedChain === "all")) {
3953
4203
  throw new Error(
3954
- "--address requires an explicit single --chain (evm | solana | mina) \u2014 a single address cannot fund every chain"
4204
+ `--address requires an explicit single chain (${CHAIN_ARG_LIST2}) \u2014 a single address cannot fund every chain`
3955
4205
  );
3956
4206
  }
3957
4207
  } catch (err) {
@@ -3961,7 +4211,7 @@ async function runFund(args, deps) {
3961
4211
  }
3962
4212
  try {
3963
4213
  const { file } = readFundConfig(env);
3964
- const targetChains = chainFlag === void 0 || chainFlag === "all" ? [...CHAINS] : [chainFlag];
4214
+ const targetChains = resolvedChain === void 0 || resolvedChain === "all" ? [...CHAINS] : [resolvedChain];
3965
4215
  const network = env["TOON_CLIENT_NETWORK"] ?? file.network;
3966
4216
  const canInfer = network === void 0 || network === "custom";
3967
4217
  const originRelays = canInfer ? await resolveOriginRelays(deps.cwd) : [];
@@ -4024,7 +4274,7 @@ async function runFund(args, deps) {
4024
4274
  if (!json) {
4025
4275
  const list = targetChains.join(", ");
4026
4276
  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)" : "")
4277
+ `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
4278
  );
4029
4279
  }
4030
4280
  const singleChain = targetChains.length === 1;
@@ -4081,7 +4331,7 @@ async function runFund(args, deps) {
4081
4331
  if (r.funded) {
4082
4332
  const slow = r.elapsedMs !== void 0 && r.elapsedMs >= 5e3;
4083
4333
  const time = slow ? ` (${Math.round(r.elapsedMs / 1e3)}s)` : "";
4084
- io2.out(` ${label} \u2713 funded (${NATIVE_COIN[r.chain]} + USDC)${addr}${time}`);
4334
+ io2.out(` ${label} \u2713 funded (USDC)${addr}${time}`);
4085
4335
  } else {
4086
4336
  io2.out(` ${label} \u2717${addr} \u2014 ${r.error ?? "failed"}`);
4087
4337
  }
@@ -4143,10 +4393,10 @@ var runGitPassthrough = (argv2, options = {}) => {
4143
4393
  };
4144
4394
 
4145
4395
  // src/cli/identity-cmd.ts
4146
- import { existsSync, mkdirSync as mkdirSync2 } from "fs";
4147
- import { dirname as dirname2 } from "path";
4396
+ import { existsSync, mkdirSync as mkdirSync3 } from "fs";
4397
+ import { dirname as dirname3 } from "path";
4148
4398
  import { createInterface } from "readline/promises";
4149
- import { parseArgs as parseArgs10 } from "util";
4399
+ import { parseArgs as parseArgs11 } from "util";
4150
4400
  async function loadKeyOps() {
4151
4401
  return await import("@toon-protocol/client");
4152
4402
  }
@@ -4195,7 +4445,7 @@ async function prepareKeystoreTarget(input) {
4195
4445
  const envPassword = input.env["TOON_CLIENT_KEYSTORE_PASSWORD"]?.trim() || void 0;
4196
4446
  const autoPassword = envPassword === void 0;
4197
4447
  const password = envPassword ?? DEFAULT_KEYSTORE_PASSWORD;
4198
- mkdirSync2(dirname2(keystorePath), { recursive: true });
4448
+ mkdirSync3(dirname3(keystorePath), { recursive: true });
4199
4449
  return { keystorePath, password, autoPassword, existing, keyOps };
4200
4450
  }
4201
4451
  function readAccountIndex(env) {
@@ -4317,7 +4567,7 @@ async function runIdentity(args, deps) {
4317
4567
  }
4318
4568
  }
4319
4569
  function parseMintArgs(args, verb) {
4320
- const { values, positionals } = parseArgs10({
4570
+ const { values, positionals } = parseArgs11({
4321
4571
  args,
4322
4572
  options: {
4323
4573
  force: { type: "boolean", default: false },
@@ -4422,7 +4672,7 @@ async function runIdentityShow(args, deps) {
4422
4672
  let json = false;
4423
4673
  let help = false;
4424
4674
  try {
4425
- const parsed = parseArgs10({
4675
+ const parsed = parseArgs11({
4426
4676
  args,
4427
4677
  options: {
4428
4678
  json: { type: "boolean", default: false },
@@ -4531,7 +4781,7 @@ async function defaultReadSecretLine(prompt, isInteractive) {
4531
4781
 
4532
4782
  // src/cli/init.ts
4533
4783
  import { basename as basename2 } from "path";
4534
- import { parseArgs as parseArgs11 } from "util";
4784
+ import { parseArgs as parseArgs12 } from "util";
4535
4785
 
4536
4786
  // src/cli/git-author.ts
4537
4787
  var PROFILE_KIND = 0;
@@ -4649,7 +4899,7 @@ Options:
4649
4899
  --json machine-readable report
4650
4900
  -h, --help show this help`;
4651
4901
  function parseInitArgs(args) {
4652
- const { values, positionals } = parseArgs11({
4902
+ const { values, positionals } = parseArgs12({
4653
4903
  args,
4654
4904
  options: {
4655
4905
  "repo-id": { type: "string" },
@@ -4693,7 +4943,7 @@ async function resolveProfileRelay(flagRelay, originRelay, toonRelays) {
4693
4943
  ].filter((u) => u !== void 0 && isWebSocketRelay2(u));
4694
4944
  if (candidates[0] !== void 0) return candidates[0];
4695
4945
  try {
4696
- const { loadGenesisSeed } = await import("../network-bootstrap-KQLKALBI.js");
4946
+ const { loadGenesisSeed } = await import("../network-bootstrap-IHQ4PWUW.js");
4697
4947
  const seed = loadGenesisSeed();
4698
4948
  if (seed?.relayUrl && isWebSocketRelay2(seed.relayUrl)) return seed.relayUrl;
4699
4949
  } catch {
@@ -4882,7 +5132,7 @@ async function runInit(args, deps) {
4882
5132
  }
4883
5133
 
4884
5134
  // src/cli/maintainers.ts
4885
- import { parseArgs as parseArgs12 } from "util";
5135
+ import { parseArgs as parseArgs13 } from "util";
4886
5136
  var HEX64_RE3 = /^[0-9a-f]{64}$/;
4887
5137
  var WS_URL_RE4 = /^wss?:\/\//i;
4888
5138
  var MAINTAINERS_USAGE = `Usage: rig maintainers <list|add|remove> [<pubkey>] [options]
@@ -4987,7 +5237,7 @@ async function runList2(args, deps) {
4987
5237
  const { io: io2 } = deps;
4988
5238
  let flags;
4989
5239
  try {
4990
- const { values, positionals } = parseArgs12({
5240
+ const { values, positionals } = parseArgs13({
4991
5241
  args,
4992
5242
  options: MAINT_OPTIONS,
4993
5243
  allowPositionals: true
@@ -5054,7 +5304,7 @@ async function runMutate(op, args, deps) {
5054
5304
  let flags;
5055
5305
  let pubkey;
5056
5306
  try {
5057
- const { values, positionals } = parseArgs12({
5307
+ const { values, positionals } = parseArgs13({
5058
5308
  args,
5059
5309
  options: MAINT_OPTIONS,
5060
5310
  allowPositionals: true
@@ -5203,7 +5453,7 @@ async function runMutate(op, args, deps) {
5203
5453
 
5204
5454
  // src/cli/name.ts
5205
5455
  import { randomUUID } from "crypto";
5206
- import { parseArgs as parseArgs13 } from "util";
5456
+ import { parseArgs as parseArgs14 } from "util";
5207
5457
  var ARIO_DECIMALS = 6;
5208
5458
  function renderMario(mario) {
5209
5459
  return `${mario.toString()} mARIO (~${formatUnits(mario.toString(), ARIO_DECIMALS)} ARIO)`;
@@ -5634,6 +5884,11 @@ Commands:
5634
5884
  gas-station path (kind:5096) \u2014 you author and
5635
5885
  partial-sign, the DVM co-signs as fee payer and pays
5636
5886
  the lamports; needs ZERO SOL in this wallet.
5887
+ <txId> may instead be given via --tx-id <id> \u2014 use
5888
+ that instead of the positional when the txId leads
5889
+ with '-' or '_' (Arweave txids are base64url). For a
5890
+ leading '-' write --tx-id=<id> (the '=' form), since
5891
+ "--tx-id -XYZ..." is itself ambiguous to the parser.
5637
5892
  name status <name> FREE: registry record (lease/permabuy, expiry), ANT
5638
5893
  process id, current target txId(s), TTL, undernames.
5639
5894
 
@@ -5644,6 +5899,10 @@ Options:
5644
5899
  --undername <sub> target the undername <sub>_<name> instead of the base
5645
5900
  name (set)
5646
5901
  --ttl <seconds> record TTL in seconds (set; default 3600)
5902
+ --tx-id <id> set only: the Arweave txId to point at, as an
5903
+ explicit option instead of the positional (mutually
5904
+ exclusive with the positional <txId>). For a value
5905
+ leading with '-' use --tx-id=<id>.
5647
5906
  --network <net> cluster: mainnet | devnet (default mainnet; or
5648
5907
  RIG_ARIO_NETWORK). ar.io has no Solana-testnet
5649
5908
  deployment. Non-mainnet gateway resolution is
@@ -5701,7 +5960,7 @@ async function resolveNameContext(deps, network, processId, mode) {
5701
5960
  return { identity, solanaAddress, network, processId, sdk, nostrSecretKey };
5702
5961
  }
5703
5962
  function parseNameFlags(args, env) {
5704
- const { values, positionals } = parseArgs13({
5963
+ const { values, positionals } = parseArgs14({
5705
5964
  args,
5706
5965
  allowPositionals: true,
5707
5966
  options: {
@@ -5712,6 +5971,7 @@ function parseNameFlags(args, env) {
5712
5971
  network: { type: "string" },
5713
5972
  "process-id": { type: "string" },
5714
5973
  via: { type: "string" },
5974
+ "tx-id": { type: "string" },
5715
5975
  yes: { type: "boolean", default: false },
5716
5976
  json: { type: "boolean", default: false },
5717
5977
  help: { type: "boolean", short: "h", default: false }
@@ -5777,6 +6037,7 @@ function parseNameFlags(args, env) {
5777
6037
  network: networkRaw,
5778
6038
  ...processId !== void 0 ? { processId } : {},
5779
6039
  ...via !== void 0 ? { via } : {},
6040
+ ...values["tx-id"] !== void 0 ? { txId: values["tx-id"] } : {},
5780
6041
  yes: values.yes ?? false,
5781
6042
  json: values.json ?? false
5782
6043
  }
@@ -6169,10 +6430,15 @@ async function runName(args, deps) {
6169
6430
  try {
6170
6431
  if (sub === "buy") return await runBuy(name, flags, deps);
6171
6432
  if (sub === "status") return await runStatus(name, flags, deps);
6172
- const txId = positionals[1];
6433
+ if (flags.txId !== void 0 && positionals[1] !== void 0) {
6434
+ io2.err("`--tx-id` and a positional <txId> are mutually exclusive");
6435
+ io2.err(NAME_USAGE);
6436
+ return 2;
6437
+ }
6438
+ const txId = flags.txId ?? positionals[1];
6173
6439
  if (txId === void 0) {
6174
6440
  io2.err(
6175
- "`rig name set` needs a <txId> (the Arweave transaction to point at)"
6441
+ "`rig name set` needs a <txId> (the Arweave transaction to point at) \u2014 as a positional or via --tx-id"
6176
6442
  );
6177
6443
  io2.err(NAME_USAGE);
6178
6444
  return 2;
@@ -6184,7 +6450,7 @@ async function runName(args, deps) {
6184
6450
  }
6185
6451
 
6186
6452
  // src/cli/site.ts
6187
- import { parseArgs as parseArgs14 } from "util";
6453
+ import { parseArgs as parseArgs15 } from "util";
6188
6454
 
6189
6455
  // src/arweave-manifest.ts
6190
6456
  var DEFAULT_INDEX = "index.html";
@@ -6196,29 +6462,29 @@ function buildArweaveManifest(entries, indexPath = DEFAULT_INDEX, fallbackTxId)
6196
6462
  return {
6197
6463
  manifest: "arweave/paths",
6198
6464
  version: "0.2.0",
6199
- index: { path: indexPath },
6465
+ ...Object.hasOwn(paths, indexPath) ? { index: { path: indexPath } } : {},
6200
6466
  ...fallbackTxId ? { fallback: { id: fallbackTxId } } : {},
6201
6467
  paths
6202
6468
  };
6203
6469
  }
6204
6470
 
6205
6471
  // src/cli/site-record.ts
6206
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
6207
- import { homedir as homedir3 } from "os";
6208
- import { join as join4 } from "path";
6472
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
6473
+ import { homedir as homedir4 } from "os";
6474
+ import { join as join5 } from "path";
6209
6475
  var SITE_MANIFEST_FILENAME = "site-manifests.json";
6210
6476
  function storeDir2(env) {
6211
- return env["TOON_CLIENT_HOME"] ?? join4(homedir3(), ".toon-client");
6477
+ return env["TOON_CLIENT_HOME"] ?? join5(homedir4(), ".toon-client");
6212
6478
  }
6213
6479
  function storePath2(env) {
6214
- return join4(storeDir2(env), SITE_MANIFEST_FILENAME);
6480
+ return join5(storeDir2(env), SITE_MANIFEST_FILENAME);
6215
6481
  }
6216
6482
  function keyOf(repoId, ref) {
6217
6483
  return `${repoId}\0${ref}`;
6218
6484
  }
6219
6485
  function readFile2(env) {
6220
6486
  try {
6221
- const parsed = JSON.parse(readFileSync3(storePath2(env), "utf8"));
6487
+ const parsed = JSON.parse(readFileSync4(storePath2(env), "utf8"));
6222
6488
  if (parsed && typeof parsed === "object") return parsed;
6223
6489
  return {};
6224
6490
  } catch {
@@ -6230,10 +6496,10 @@ function readSiteRecord(env, repoId, ref) {
6230
6496
  }
6231
6497
  function writeSiteRecord(env, record) {
6232
6498
  const dir = storeDir2(env);
6233
- mkdirSync3(dir, { recursive: true });
6499
+ mkdirSync4(dir, { recursive: true });
6234
6500
  const file = readFile2(env);
6235
6501
  file[keyOf(record.repoId, record.ref)] = record;
6236
- writeFileSync2(storePath2(env), `${JSON.stringify(file, null, 2)}
6502
+ writeFileSync3(storePath2(env), `${JSON.stringify(file, null, 2)}
6237
6503
  `, "utf8");
6238
6504
  }
6239
6505
 
@@ -6275,7 +6541,7 @@ Options (publish):
6275
6541
  estimate (nothing uploaded)
6276
6542
  -h, --help show this help`;
6277
6543
  function parseSiteArgs(args) {
6278
- const { values, positionals } = parseArgs14({
6544
+ const { values, positionals } = parseArgs15({
6279
6545
  args,
6280
6546
  options: {
6281
6547
  index: { type: "string" },
@@ -6683,6 +6949,8 @@ Commands rig owns:
6683
6949
  address(es) to fund externally
6684
6950
  balance wallet balances + payment-channel holdings
6685
6951
  (free \u2014 chain reads and local state only)
6952
+ chain [set <c>|unset] choose which chain/USDC settles paid writes
6953
+ (evm|sol|mina); free \u2014 reads/writes local config
6686
6954
  name buy <name> ArNS naming (#367): buy points a human name at an
6687
6955
  name set <name> <txId> Arweave txId, owned + paid by this identity's
6688
6956
  name status <name> Solana key. buy spends mARIO on Solana via the
@@ -6758,6 +7026,8 @@ async function dispatch(argv2, deps) {
6758
7026
  return runFund(rest, deps);
6759
7027
  case "balance":
6760
7028
  return runBalance(rest, deps);
7029
+ case "chain":
7030
+ return runChain(rest, deps);
6761
7031
  case "name":
6762
7032
  return runName(rest, deps);
6763
7033
  case "help":