@toon-protocol/rig 2.12.0 → 2.13.1
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 +4 -2
- package/dist/{chunk-GZUDRNOK.js → chunk-FFQXFV4W.js} +213 -2
- package/dist/chunk-FFQXFV4W.js.map +1 -0
- package/dist/cli/rig.js +616 -56
- package/dist/cli/rig.js.map +1 -1
- package/dist/{standalone-mode-U3OOSVOB.js → standalone-mode-D2YSANBJ.js} +65 -163
- package/dist/standalone-mode-D2YSANBJ.js.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-GZUDRNOK.js.map +0 -1
- package/dist/standalone-mode-U3OOSVOB.js.map +0 -1
package/dist/cli/rig.js
CHANGED
|
@@ -21,14 +21,16 @@ import {
|
|
|
21
21
|
} from "../chunk-EEUHZNWS.js";
|
|
22
22
|
import {
|
|
23
23
|
DEFAULT_KEYSTORE_PASSWORD,
|
|
24
|
+
MinaZkAppStore,
|
|
24
25
|
MissingIdentityError,
|
|
26
|
+
TOPOLOGY_CACHE_FILENAME,
|
|
25
27
|
clientConfigPath,
|
|
26
28
|
clientKeystorePath,
|
|
27
29
|
linkKeystoreInClientConfig,
|
|
28
30
|
readClientConfigFile,
|
|
29
31
|
resolveAccountIndex,
|
|
30
32
|
resolveIdentity
|
|
31
|
-
} from "../chunk-
|
|
33
|
+
} from "../chunk-FFQXFV4W.js";
|
|
32
34
|
import {
|
|
33
35
|
ChannelMapStore,
|
|
34
36
|
channelStatus,
|
|
@@ -41,6 +43,10 @@ import {
|
|
|
41
43
|
flooredUploadFee
|
|
42
44
|
} from "../chunk-35ALWUDJ.js";
|
|
43
45
|
import {
|
|
46
|
+
minaPresetForChain
|
|
47
|
+
} from "../chunk-ACTH6ISJ.js";
|
|
48
|
+
import {
|
|
49
|
+
ARWEAVE_GATEWAYS,
|
|
44
50
|
COMMENT_KIND,
|
|
45
51
|
authorizedStatusAuthors,
|
|
46
52
|
buildComment,
|
|
@@ -555,6 +561,8 @@ var DEFAULT_RIG_WEB_BUNDLE = {
|
|
|
555
561
|
var RIG_WEB_TX_ENV = "RIG_WEB_TX";
|
|
556
562
|
var RIG_WEB_ENTRY_JS_ENV = "RIG_WEB_ENTRY_JS";
|
|
557
563
|
var RIG_WEB_ENTRY_CSS_ENV = "RIG_WEB_ENTRY_CSS";
|
|
564
|
+
var DEFAULT_RIG_WEB_GATEWAY = "https://arweave.net";
|
|
565
|
+
var RIG_WEB_GATEWAY_ENV = "RIG_WEB_GATEWAY";
|
|
558
566
|
var DEFAULT_RIG_WEB_URL = "https://toon-protocol.github.io/toon-client";
|
|
559
567
|
var RIG_WEB_URL_ENV = "RIG_WEB_URL";
|
|
560
568
|
function repoHashRoute(options) {
|
|
@@ -1074,7 +1082,7 @@ function loadPaidSession(deps, relayUrl) {
|
|
|
1074
1082
|
});
|
|
1075
1083
|
}
|
|
1076
1084
|
var defaultLoadStandalone = async (options) => {
|
|
1077
|
-
const mod = await import("../standalone-mode-
|
|
1085
|
+
const mod = await import("../standalone-mode-D2YSANBJ.js");
|
|
1078
1086
|
return mod.createStandaloneContext(options);
|
|
1079
1087
|
};
|
|
1080
1088
|
function identityReport(ctx) {
|
|
@@ -1210,11 +1218,14 @@ function parsePushArgs(args) {
|
|
|
1210
1218
|
return flags;
|
|
1211
1219
|
}
|
|
1212
1220
|
function pointerGateway(env) {
|
|
1213
|
-
return (env["RIG_ARWEAVE_GATEWAY"] ?? "https://
|
|
1221
|
+
return (env["RIG_ARWEAVE_GATEWAY"] ?? "https://ar-io.dev").replace(
|
|
1214
1222
|
/\/+$/,
|
|
1215
1223
|
""
|
|
1216
1224
|
);
|
|
1217
1225
|
}
|
|
1226
|
+
function mirrorGateway(primary) {
|
|
1227
|
+
return ARWEAVE_GATEWAYS.find((g) => g !== primary);
|
|
1228
|
+
}
|
|
1218
1229
|
function planRigPointer(args) {
|
|
1219
1230
|
const html = generateRigPointerHtml({
|
|
1220
1231
|
bundle: {
|
|
@@ -1222,7 +1233,7 @@ function planRigPointer(args) {
|
|
|
1222
1233
|
entryJs: args.env[RIG_WEB_ENTRY_JS_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.entryJs,
|
|
1223
1234
|
entryCss: args.env[RIG_WEB_ENTRY_CSS_ENV] ?? DEFAULT_RIG_WEB_BUNDLE.entryCss
|
|
1224
1235
|
},
|
|
1225
|
-
gateway:
|
|
1236
|
+
gateway: (args.env[RIG_WEB_GATEWAY_ENV] ?? DEFAULT_RIG_WEB_GATEWAY).replace(/\/+$/, ""),
|
|
1226
1237
|
rigWebUrl: args.env[RIG_WEB_URL_ENV] ?? DEFAULT_RIG_WEB_URL,
|
|
1227
1238
|
relay: args.relay,
|
|
1228
1239
|
ownerNpub: hexToNpub(args.ownerPubkey),
|
|
@@ -1423,6 +1434,12 @@ async function runPush(args, deps) {
|
|
|
1423
1434
|
io2.out(
|
|
1424
1435
|
`Rig page: ${rigPage2.url}` + (rigPage2.status === "published" ? ` paid ${rigPage2.feePaid}` : "") + " (renders this repo from Arweave)"
|
|
1425
1436
|
);
|
|
1437
|
+
const mirror = rigPage2.txId ? mirrorGateway(gateway) : void 0;
|
|
1438
|
+
if (mirror) {
|
|
1439
|
+
io2.out(
|
|
1440
|
+
` also: ${mirror}/${rigPage2.txId} (same page; gateways index fresh uploads at different speeds)`
|
|
1441
|
+
);
|
|
1442
|
+
}
|
|
1426
1443
|
} else if (rigPage2.detail) {
|
|
1427
1444
|
io2.err(`rig page: ${rigPage2.detail}`);
|
|
1428
1445
|
}
|
|
@@ -1941,6 +1958,9 @@ async function runChain(args, deps) {
|
|
|
1941
1958
|
}
|
|
1942
1959
|
|
|
1943
1960
|
// src/cli/channel.ts
|
|
1961
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
1962
|
+
import { homedir as homedir3 } from "os";
|
|
1963
|
+
import { join as join3 } from "path";
|
|
1944
1964
|
import { parseArgs as parseArgs5 } from "util";
|
|
1945
1965
|
var CHANNEL_USAGE = `Usage: rig channel <subcommand>
|
|
1946
1966
|
|
|
@@ -1963,6 +1983,17 @@ Subcommands:
|
|
|
1963
1983
|
apex); --deposit adds that much extra collateral after the
|
|
1964
1984
|
open/resume. On-chain: asks for confirmation (--yes skips).
|
|
1965
1985
|
|
|
1986
|
+
deploy-zkapp [--graphql-url <url>]
|
|
1987
|
+
deploy a dedicated Mina PaymentChannel zkApp for THIS
|
|
1988
|
+
identity (the zkApp is single-pair; Mina channels open on
|
|
1989
|
+
an identity-owned deployment). Normally automatic \u2014 the
|
|
1990
|
+
Mina open path deploys one when needed \u2014 this explicit
|
|
1991
|
+
form pre-deploys it (compile \u22481-3 min, inclusion \u22483-6 min).
|
|
1992
|
+
On-chain: costs the 1 MINA account-creation fee + tx fee
|
|
1993
|
+
from the wallet's MINA. The zkApp key is saved under
|
|
1994
|
+
TOON_CLIENT_HOME/keys/. Asks for confirmation (--yes
|
|
1995
|
+
skips).
|
|
1996
|
+
|
|
1966
1997
|
close <channelId>
|
|
1967
1998
|
close a recorded channel \u2014 an on-chain tx that starts the
|
|
1968
1999
|
settlement challenge window (the peer's settlementTimeout).
|
|
@@ -1986,6 +2017,8 @@ async function runChannel(args, deps) {
|
|
|
1986
2017
|
return runChannelList(rest, deps);
|
|
1987
2018
|
case "open":
|
|
1988
2019
|
return runChannelOpen(rest, deps);
|
|
2020
|
+
case "deploy-zkapp":
|
|
2021
|
+
return runChannelDeployZkApp(rest, deps);
|
|
1989
2022
|
case "close":
|
|
1990
2023
|
return runChannelWithdrawStep(rest, deps, "close");
|
|
1991
2024
|
case "settle":
|
|
@@ -2178,6 +2211,9 @@ async function runChannelOpen(args, deps) {
|
|
|
2178
2211
|
io2.out(
|
|
2179
2212
|
"If a live channel is already recorded for this peer it is RESUMED (no on-chain spend); otherwise an on-chain channel open locks the peer-negotiated initial deposit from your wallet (plus gas)."
|
|
2180
2213
|
);
|
|
2214
|
+
io2.out(
|
|
2215
|
+
"On a Mina chain a first open may also deploy a dedicated PaymentChannel zkApp for this identity (~1.1 MINA + fees; compile \u22481-3 min, inclusion \u22483-6 min \u2014 progress is printed)."
|
|
2216
|
+
);
|
|
2181
2217
|
}
|
|
2182
2218
|
const gate = await confirmOnChain(
|
|
2183
2219
|
io2,
|
|
@@ -2236,6 +2272,160 @@ async function runChannelOpen(args, deps) {
|
|
|
2236
2272
|
await stopQuietly(ctx);
|
|
2237
2273
|
}
|
|
2238
2274
|
}
|
|
2275
|
+
async function runChannelDeployZkApp(args, deps) {
|
|
2276
|
+
const { io: io2, env } = deps;
|
|
2277
|
+
let graphqlFlag;
|
|
2278
|
+
let yes = false;
|
|
2279
|
+
let json = false;
|
|
2280
|
+
try {
|
|
2281
|
+
const { values } = parseArgs5({
|
|
2282
|
+
args,
|
|
2283
|
+
options: {
|
|
2284
|
+
"graphql-url": { type: "string" },
|
|
2285
|
+
yes: { type: "boolean", default: false },
|
|
2286
|
+
json: { type: "boolean", default: false },
|
|
2287
|
+
help: { type: "boolean", short: "h", default: false }
|
|
2288
|
+
}
|
|
2289
|
+
});
|
|
2290
|
+
if (values.help) {
|
|
2291
|
+
io2.out(CHANNEL_USAGE);
|
|
2292
|
+
return 0;
|
|
2293
|
+
}
|
|
2294
|
+
graphqlFlag = values["graphql-url"];
|
|
2295
|
+
yes = values.yes ?? false;
|
|
2296
|
+
json = values.json ?? false;
|
|
2297
|
+
} catch (err) {
|
|
2298
|
+
io2.err(err instanceof Error ? err.message : String(err));
|
|
2299
|
+
io2.err(CHANNEL_USAGE);
|
|
2300
|
+
return 2;
|
|
2301
|
+
}
|
|
2302
|
+
try {
|
|
2303
|
+
const dir = env["TOON_CLIENT_HOME"] ?? join3(homedir3(), ".toon-client");
|
|
2304
|
+
let file = {};
|
|
2305
|
+
try {
|
|
2306
|
+
file = JSON.parse(readFileSync3(join3(dir, "config.json"), "utf8"));
|
|
2307
|
+
} catch {
|
|
2308
|
+
}
|
|
2309
|
+
const pinned = env["TOON_CLIENT_CHAIN"] ?? file.chain;
|
|
2310
|
+
const chain = pinned !== void 0 && pinned.startsWith("mina:") ? pinned : "mina:devnet";
|
|
2311
|
+
const graphqlUrl = graphqlFlag ?? file.minaChannel?.graphqlUrl ?? minaPresetForChain(chain)?.graphqlUrl;
|
|
2312
|
+
if (!graphqlUrl) {
|
|
2313
|
+
throw new Error(
|
|
2314
|
+
`no Mina GraphQL endpoint for ${chain} \u2014 pass --graphql-url or set minaChannel.graphqlUrl in the client config`
|
|
2315
|
+
);
|
|
2316
|
+
}
|
|
2317
|
+
const resolved = await resolveIdentity({
|
|
2318
|
+
env,
|
|
2319
|
+
cwd: deps.cwd,
|
|
2320
|
+
warn: (line) => io2.err(line)
|
|
2321
|
+
});
|
|
2322
|
+
const identity = {
|
|
2323
|
+
pubkey: resolved.pubkey,
|
|
2324
|
+
source: resolved.source,
|
|
2325
|
+
sourceLabel: resolved.sourceLabel
|
|
2326
|
+
};
|
|
2327
|
+
const store = MinaZkAppStore.forHome(dir);
|
|
2328
|
+
const existing = store.lookup(resolved.pubkey, chain);
|
|
2329
|
+
if (existing) {
|
|
2330
|
+
if (json) {
|
|
2331
|
+
io2.emitJson({
|
|
2332
|
+
command: "channel deploy-zkapp",
|
|
2333
|
+
identity,
|
|
2334
|
+
executed: false,
|
|
2335
|
+
plan: { chain, graphqlUrl },
|
|
2336
|
+
result: {
|
|
2337
|
+
zkAppAddress: existing.zkAppAddress,
|
|
2338
|
+
deployTxHash: existing.deployTxHash ?? null,
|
|
2339
|
+
vkHash: existing.vkHash ?? null,
|
|
2340
|
+
storePath: store.filePath
|
|
2341
|
+
},
|
|
2342
|
+
hint: "a zkApp is already recorded for this identity/chain \u2014 the open path reuses it"
|
|
2343
|
+
});
|
|
2344
|
+
return 0;
|
|
2345
|
+
}
|
|
2346
|
+
io2.out(
|
|
2347
|
+
`A Mina zkApp is already recorded for this identity on ${chain}: ` + existing.zkAppAddress
|
|
2348
|
+
);
|
|
2349
|
+
io2.out(`The open path reuses it (record: ${store.filePath}).`);
|
|
2350
|
+
return 0;
|
|
2351
|
+
}
|
|
2352
|
+
const plan = { chain, graphqlUrl };
|
|
2353
|
+
if (!json) {
|
|
2354
|
+
io2.out("Mina zkApp deploy plan:");
|
|
2355
|
+
io2.out(` chain ${chain}`);
|
|
2356
|
+
io2.out(` graphql ${graphqlUrl}`);
|
|
2357
|
+
io2.out(renderIdentityLine(identity));
|
|
2358
|
+
io2.out(
|
|
2359
|
+
"Deploys a dedicated PaymentChannel zkApp for this identity \u2014 on-chain: the 1 MINA account-creation fee + a 0.1 MINA tx fee from your wallet. Compile \u22481-3 min; inclusion \u22483-6 min."
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
const gate = await confirmOnChain(
|
|
2363
|
+
io2,
|
|
2364
|
+
{ yes, json },
|
|
2365
|
+
"Proceed with the on-chain zkApp deploy? [y/N] "
|
|
2366
|
+
);
|
|
2367
|
+
if (gate === "json-plan") {
|
|
2368
|
+
io2.emitJson({
|
|
2369
|
+
command: "channel deploy-zkapp",
|
|
2370
|
+
identity,
|
|
2371
|
+
executed: false,
|
|
2372
|
+
plan,
|
|
2373
|
+
hint: "plan only \u2014 re-run with --yes to deploy (on-chain: ~1.1 MINA + fees)"
|
|
2374
|
+
});
|
|
2375
|
+
return 0;
|
|
2376
|
+
}
|
|
2377
|
+
if (gate !== "proceed") return gate;
|
|
2378
|
+
const client = await import("@toon-protocol/client");
|
|
2379
|
+
const derived = await client.deriveFullIdentity(
|
|
2380
|
+
resolved.mnemonic,
|
|
2381
|
+
resolved.accountIndex
|
|
2382
|
+
);
|
|
2383
|
+
if (!derived.mina.privateKey) {
|
|
2384
|
+
throw new Error(
|
|
2385
|
+
"no Mina key derived \u2014 the optional `mina-signer` dependency is not installed"
|
|
2386
|
+
);
|
|
2387
|
+
}
|
|
2388
|
+
const record = await client.deployMinaChannelZkApp({
|
|
2389
|
+
graphqlUrl,
|
|
2390
|
+
payerPrivateKey: derived.mina.privateKey,
|
|
2391
|
+
onProgress: (line) => io2.err(`rig: mina: ${line}`)
|
|
2392
|
+
});
|
|
2393
|
+
store.save({
|
|
2394
|
+
identity: resolved.pubkey,
|
|
2395
|
+
chain,
|
|
2396
|
+
zkAppAddress: record.zkAppAddress,
|
|
2397
|
+
zkAppPrivateKey: record.zkAppPrivateKey,
|
|
2398
|
+
feePayer: record.feePayer,
|
|
2399
|
+
...record.deployTxHash !== void 0 ? { deployTxHash: record.deployTxHash } : {},
|
|
2400
|
+
...record.vkHash !== void 0 ? { vkHash: record.vkHash } : {},
|
|
2401
|
+
deployedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2402
|
+
source: "rig channel deploy-zkapp (npm @toon-protocol/mina-zkapp build)"
|
|
2403
|
+
});
|
|
2404
|
+
if (json) {
|
|
2405
|
+
io2.emitJson({
|
|
2406
|
+
command: "channel deploy-zkapp",
|
|
2407
|
+
identity,
|
|
2408
|
+
executed: true,
|
|
2409
|
+
plan,
|
|
2410
|
+
result: {
|
|
2411
|
+
zkAppAddress: record.zkAppAddress,
|
|
2412
|
+
deployTxHash: record.deployTxHash ?? null,
|
|
2413
|
+
vkHash: record.vkHash ?? null,
|
|
2414
|
+
storePath: store.filePath
|
|
2415
|
+
}
|
|
2416
|
+
});
|
|
2417
|
+
return 0;
|
|
2418
|
+
}
|
|
2419
|
+
io2.out(`Deployed Mina PaymentChannel zkApp ${record.zkAppAddress}.`);
|
|
2420
|
+
if (record.deployTxHash) io2.out(` deploy tx ${record.deployTxHash}`);
|
|
2421
|
+
if (record.vkHash) io2.out(` vk hash ${record.vkHash}`);
|
|
2422
|
+
io2.out(` record ${store.filePath} (holds the zkApp key \u2014 back it up)`);
|
|
2423
|
+
io2.out("The next Mina channel open/push finds and reuses this zkApp.");
|
|
2424
|
+
return 0;
|
|
2425
|
+
} catch (err) {
|
|
2426
|
+
return emitCliError(io2, json, "channel deploy-zkapp", err);
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2239
2429
|
function withdrawPrecheck(step, channelId, watermark, nowSec) {
|
|
2240
2430
|
const status = channelStatus(watermark, nowSec);
|
|
2241
2431
|
if (status === "settled") {
|
|
@@ -2405,7 +2595,7 @@ async function stopQuietly(ctx) {
|
|
|
2405
2595
|
|
|
2406
2596
|
// src/cli/clone.ts
|
|
2407
2597
|
import { mkdtemp, mkdir, readdir, rename, rm, rmdir } from "fs/promises";
|
|
2408
|
-
import { basename, dirname as dirname2, join as
|
|
2598
|
+
import { basename, dirname as dirname2, join as join4, resolve } from "path";
|
|
2409
2599
|
import { parseArgs as parseArgs6 } from "util";
|
|
2410
2600
|
var CLONE_USAGE = `Usage: rig clone <relay-url> <owner>/<repo-id> [dir] [options]
|
|
2411
2601
|
|
|
@@ -2576,7 +2766,7 @@ async function runClone(args, deps) {
|
|
|
2576
2766
|
}
|
|
2577
2767
|
const parent = dirname2(dest);
|
|
2578
2768
|
await mkdir(parent, { recursive: true });
|
|
2579
|
-
tempDir = await mkdtemp(
|
|
2769
|
+
tempDir = await mkdtemp(join4(parent, `.${basename(dest)}.rig-clone-`));
|
|
2580
2770
|
await runGit(tempDir, [
|
|
2581
2771
|
"init",
|
|
2582
2772
|
"--quiet",
|
|
@@ -3822,8 +4012,288 @@ async function warnIfNotMaintainer(deps, args) {
|
|
|
3822
4012
|
}
|
|
3823
4013
|
}
|
|
3824
4014
|
|
|
3825
|
-
// src/cli/
|
|
4015
|
+
// src/cli/entry.ts
|
|
4016
|
+
import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
4017
|
+
import { homedir as homedir4 } from "os";
|
|
4018
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
3826
4019
|
import { parseArgs as parseArgs9 } from "util";
|
|
4020
|
+
var SANDBOX_BTP_URL = "wss://proxy.sandbox.devnet.toonprotocol.dev:443";
|
|
4021
|
+
var SANDBOX_RELAY_URL = "wss://relay-ws.sandbox.devnet.toonprotocol.dev";
|
|
4022
|
+
var ENTRY_USAGE = `Usage: rig entry [apex | sandbox | <wss-url>] [options]
|
|
4023
|
+
|
|
4024
|
+
Choose which network entry node (payment ingress + relay) rig talks to. Free:
|
|
4025
|
+
only the local config file is touched.
|
|
4026
|
+
|
|
4027
|
+
rig entry show the effective entry endpoints and their source
|
|
4028
|
+
rig entry apex revert to the default apex: clears the btpUrl/
|
|
4029
|
+
relayUrl override so core's genesis seed (or a live
|
|
4030
|
+
announce) applies \u2014 settles evm | sol | mina
|
|
4031
|
+
rig entry sandbox the devnet sandbox entry (Mina USDC ONLY \u2014 the
|
|
4032
|
+
cross-currency multihop demo path):
|
|
4033
|
+
btp ${SANDBOX_BTP_URL}
|
|
4034
|
+
relay ${SANDBOX_RELAY_URL}
|
|
4035
|
+
rig entry <wss-url> an explicit BTP endpoint (ws:// or wss://); pass
|
|
4036
|
+
--relay <url> to also set the relay
|
|
4037
|
+
|
|
4038
|
+
Switching entries deletes the cached topology (the next paid command
|
|
4039
|
+
re-discovers the new entry's announce) and leaves existing payment channels
|
|
4040
|
+
behind \u2014 channels are per-entry-peer; the next paid command opens or resumes
|
|
4041
|
+
one with the new peer.
|
|
4042
|
+
|
|
4043
|
+
NOTE for repos: the relay a repo publishes to is its git \`origin\` remote,
|
|
4044
|
+
which OVERRIDES the config relayUrl. After switching entries, point the repo
|
|
4045
|
+
too: \`rig remote add origin <relay-url>\` (or use a fresh repo).
|
|
4046
|
+
|
|
4047
|
+
Options:
|
|
4048
|
+
--relay <url> with <wss-url>: also set the relay URL
|
|
4049
|
+
--json machine-readable envelope
|
|
4050
|
+
-h, --help show this help`;
|
|
4051
|
+
function configPathFor2(env) {
|
|
4052
|
+
const dir = env["TOON_CLIENT_HOME"] ?? join5(homedir4(), ".toon-client");
|
|
4053
|
+
return join5(dir, "config.json");
|
|
4054
|
+
}
|
|
4055
|
+
function readEntryConfig(configPath) {
|
|
4056
|
+
try {
|
|
4057
|
+
return JSON.parse(readFileSync4(configPath, "utf8"));
|
|
4058
|
+
} catch (err) {
|
|
4059
|
+
if (err.code === "ENOENT") return {};
|
|
4060
|
+
throw new Error(
|
|
4061
|
+
`failed to read client config at ${configPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
4062
|
+
);
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
function writeEntryConfig(configPath, file) {
|
|
4066
|
+
mkdirSync3(dirname3(configPath), { recursive: true });
|
|
4067
|
+
writeFileSync3(configPath, `${JSON.stringify(file, null, 2)}
|
|
4068
|
+
`, "utf8");
|
|
4069
|
+
}
|
|
4070
|
+
async function loadGenesisSeedDefault() {
|
|
4071
|
+
try {
|
|
4072
|
+
const { loadGenesisSeed } = await import("../network-bootstrap-3X2GXNJB.js");
|
|
4073
|
+
return loadGenesisSeed();
|
|
4074
|
+
} catch {
|
|
4075
|
+
return void 0;
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
function classifyEntry(btpUrl, seedBtp, btpSource) {
|
|
4079
|
+
if (btpUrl === null) return null;
|
|
4080
|
+
if (btpUrl === SANDBOX_BTP_URL) return "sandbox";
|
|
4081
|
+
if (btpSource === "genesis-seed" || btpUrl === seedBtp) return "apex";
|
|
4082
|
+
return "custom";
|
|
4083
|
+
}
|
|
4084
|
+
async function runEntry(args, deps) {
|
|
4085
|
+
const { io: io2, env } = deps;
|
|
4086
|
+
let positionals;
|
|
4087
|
+
let relayFlag;
|
|
4088
|
+
let json = false;
|
|
4089
|
+
try {
|
|
4090
|
+
const parsed = parseArgs9({
|
|
4091
|
+
args,
|
|
4092
|
+
allowPositionals: true,
|
|
4093
|
+
options: {
|
|
4094
|
+
relay: { type: "string" },
|
|
4095
|
+
json: { type: "boolean", default: false },
|
|
4096
|
+
help: { type: "boolean", short: "h", default: false }
|
|
4097
|
+
}
|
|
4098
|
+
});
|
|
4099
|
+
if (parsed.values.help) {
|
|
4100
|
+
io2.out(ENTRY_USAGE);
|
|
4101
|
+
return 0;
|
|
4102
|
+
}
|
|
4103
|
+
positionals = parsed.positionals;
|
|
4104
|
+
relayFlag = parsed.values.relay;
|
|
4105
|
+
json = parsed.values.json ?? false;
|
|
4106
|
+
} catch (err) {
|
|
4107
|
+
io2.err(err instanceof Error ? err.message : String(err));
|
|
4108
|
+
io2.err(ENTRY_USAGE);
|
|
4109
|
+
return 2;
|
|
4110
|
+
}
|
|
4111
|
+
if (positionals.length > 1) {
|
|
4112
|
+
io2.err(
|
|
4113
|
+
`rig entry takes at most one argument, got ${positionals.length}: ${positionals.join(" ")}`
|
|
4114
|
+
);
|
|
4115
|
+
io2.err(ENTRY_USAGE);
|
|
4116
|
+
return 2;
|
|
4117
|
+
}
|
|
4118
|
+
const target = positionals[0];
|
|
4119
|
+
let mutation;
|
|
4120
|
+
if (target !== void 0) {
|
|
4121
|
+
if (target === "apex") {
|
|
4122
|
+
if (relayFlag !== void 0) {
|
|
4123
|
+
io2.err("--relay only applies to an explicit <wss-url> entry");
|
|
4124
|
+
io2.err(ENTRY_USAGE);
|
|
4125
|
+
return 2;
|
|
4126
|
+
}
|
|
4127
|
+
mutation = { kind: "apex" };
|
|
4128
|
+
} else if (target === "sandbox") {
|
|
4129
|
+
if (relayFlag !== void 0) {
|
|
4130
|
+
io2.err("--relay only applies to an explicit <wss-url> entry");
|
|
4131
|
+
io2.err(ENTRY_USAGE);
|
|
4132
|
+
return 2;
|
|
4133
|
+
}
|
|
4134
|
+
mutation = { kind: "sandbox" };
|
|
4135
|
+
} else if (/^wss?:\/\/.+/.test(target)) {
|
|
4136
|
+
if (relayFlag !== void 0 && !/^wss?:\/\/.+/.test(relayFlag)) {
|
|
4137
|
+
io2.err(
|
|
4138
|
+
`--relay must be a ws(s) URL, got ${JSON.stringify(relayFlag)}`
|
|
4139
|
+
);
|
|
4140
|
+
io2.err(ENTRY_USAGE);
|
|
4141
|
+
return 2;
|
|
4142
|
+
}
|
|
4143
|
+
mutation = {
|
|
4144
|
+
kind: "url",
|
|
4145
|
+
btpUrl: target,
|
|
4146
|
+
...relayFlag !== void 0 ? { relayUrl: relayFlag } : {}
|
|
4147
|
+
};
|
|
4148
|
+
} else {
|
|
4149
|
+
io2.err(
|
|
4150
|
+
`unknown entry ${JSON.stringify(target)} \u2014 expected \`apex\`, \`sandbox\`, or a ws(s):// URL`
|
|
4151
|
+
);
|
|
4152
|
+
io2.err(ENTRY_USAGE);
|
|
4153
|
+
return 2;
|
|
4154
|
+
}
|
|
4155
|
+
}
|
|
4156
|
+
try {
|
|
4157
|
+
const configPath = configPathFor2(env);
|
|
4158
|
+
const file = readEntryConfig(configPath);
|
|
4159
|
+
const seed = await (deps.loadGenesisSeed ?? loadGenesisSeedDefault)();
|
|
4160
|
+
const effective = () => {
|
|
4161
|
+
const btpExplicit = env["TOON_CLIENT_PROXY_URL"] ?? env["TOON_CLIENT_BTP_URL"] ?? file.proxyUrl ?? file.btpUrl;
|
|
4162
|
+
const btpFromEnv = env["TOON_CLIENT_PROXY_URL"] ?? env["TOON_CLIENT_BTP_URL"];
|
|
4163
|
+
const relayExplicit = env["TOON_CLIENT_RELAY_URL"] ?? file.relayUrl;
|
|
4164
|
+
return {
|
|
4165
|
+
btpUrl: btpExplicit ?? seed?.btpEndpoint ?? null,
|
|
4166
|
+
btpSource: btpExplicit ? btpFromEnv ? "env" : "config" : seed?.btpEndpoint ? "genesis-seed" : null,
|
|
4167
|
+
relayUrl: relayExplicit ?? seed?.relayUrl ?? null,
|
|
4168
|
+
relaySource: env["TOON_CLIENT_RELAY_URL"] ? "env" : file.relayUrl ? "config" : seed?.relayUrl ? "genesis-seed" : null
|
|
4169
|
+
};
|
|
4170
|
+
};
|
|
4171
|
+
if (mutation === void 0) {
|
|
4172
|
+
const state2 = effective();
|
|
4173
|
+
const entry = classifyEntry(state2.btpUrl, seed?.btpEndpoint, state2.btpSource);
|
|
4174
|
+
if (json) {
|
|
4175
|
+
io2.emitJson({
|
|
4176
|
+
command: "entry",
|
|
4177
|
+
entry,
|
|
4178
|
+
btpUrl: state2.btpUrl,
|
|
4179
|
+
btpSource: state2.btpSource,
|
|
4180
|
+
relayUrl: state2.relayUrl,
|
|
4181
|
+
relaySource: state2.relaySource,
|
|
4182
|
+
configPath
|
|
4183
|
+
});
|
|
4184
|
+
return 0;
|
|
4185
|
+
}
|
|
4186
|
+
const label = (source) => source === "env" ? "env" : source === "config" ? `config (${configPath})` : source === "genesis-seed" ? "default apex \u2014 genesis seed" : "not configured";
|
|
4187
|
+
io2.out(
|
|
4188
|
+
`Entry: ${entry ?? "(none)"}${entry === "sandbox" ? " (Mina USDC only \u2014 multihop demo path)" : ""}`
|
|
4189
|
+
);
|
|
4190
|
+
io2.out(` btp ${state2.btpUrl ?? "(none)"} [${label(state2.btpSource)}]`);
|
|
4191
|
+
io2.out(` relay ${state2.relayUrl ?? "(none)"} [${label(state2.relaySource)}]`);
|
|
4192
|
+
io2.out(
|
|
4193
|
+
"Switch with `rig entry apex`, `rig entry sandbox`, or `rig entry <wss-url>`."
|
|
4194
|
+
);
|
|
4195
|
+
return 0;
|
|
4196
|
+
}
|
|
4197
|
+
const warnings = [];
|
|
4198
|
+
for (const envVar of [
|
|
4199
|
+
"TOON_CLIENT_BTP_URL",
|
|
4200
|
+
"TOON_CLIENT_PROXY_URL",
|
|
4201
|
+
"TOON_CLIENT_RELAY_URL"
|
|
4202
|
+
]) {
|
|
4203
|
+
if (env[envVar] !== void 0) {
|
|
4204
|
+
warnings.push(
|
|
4205
|
+
`${envVar}=${env[envVar]} is set in the environment and overrides the config value you just wrote \u2014 unset it for this entry to take effect.`
|
|
4206
|
+
);
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
warnings.push(
|
|
4210
|
+
"Payment channels are per-entry-peer: existing channels (see `rig channels`) are not used with the new entry \u2014 the next paid command opens or resumes a channel with the new peer."
|
|
4211
|
+
);
|
|
4212
|
+
const hadProxyUrl = file.proxyUrl !== void 0;
|
|
4213
|
+
let wroteBtp;
|
|
4214
|
+
let wroteRelay;
|
|
4215
|
+
if (mutation.kind === "apex") {
|
|
4216
|
+
wroteBtp = null;
|
|
4217
|
+
wroteRelay = null;
|
|
4218
|
+
delete file.btpUrl;
|
|
4219
|
+
delete file.relayUrl;
|
|
4220
|
+
delete file.proxyUrl;
|
|
4221
|
+
} else if (mutation.kind === "sandbox") {
|
|
4222
|
+
wroteBtp = SANDBOX_BTP_URL;
|
|
4223
|
+
wroteRelay = SANDBOX_RELAY_URL;
|
|
4224
|
+
file.btpUrl = SANDBOX_BTP_URL;
|
|
4225
|
+
file.relayUrl = SANDBOX_RELAY_URL;
|
|
4226
|
+
delete file.proxyUrl;
|
|
4227
|
+
} else {
|
|
4228
|
+
wroteBtp = mutation.btpUrl;
|
|
4229
|
+
wroteRelay = mutation.relayUrl ?? null;
|
|
4230
|
+
file.btpUrl = mutation.btpUrl;
|
|
4231
|
+
if (mutation.relayUrl !== void 0) file.relayUrl = mutation.relayUrl;
|
|
4232
|
+
delete file.proxyUrl;
|
|
4233
|
+
}
|
|
4234
|
+
if (hadProxyUrl) {
|
|
4235
|
+
warnings.push(
|
|
4236
|
+
"Removed the legacy `proxyUrl` config field \u2014 it outranks `btpUrl` and would have silently kept the old entry."
|
|
4237
|
+
);
|
|
4238
|
+
}
|
|
4239
|
+
writeEntryConfig(configPath, file);
|
|
4240
|
+
let clearedTopologyCache = false;
|
|
4241
|
+
try {
|
|
4242
|
+
unlinkSync(join5(dirname3(configPath), TOPOLOGY_CACHE_FILENAME));
|
|
4243
|
+
clearedTopologyCache = true;
|
|
4244
|
+
} catch {
|
|
4245
|
+
}
|
|
4246
|
+
if (mutation.kind === "sandbox") {
|
|
4247
|
+
const effectiveChain = env["TOON_CLIENT_CHAIN"] ?? file.chain ?? file.supportedChains?.[0];
|
|
4248
|
+
if (effectiveChain === void 0 || !effectiveChain.startsWith("mina")) {
|
|
4249
|
+
warnings.push(
|
|
4250
|
+
"The sandbox entry settles ONLY mina:devnet \u2014 run `rig chain set mina` " + (effectiveChain !== void 0 ? `(currently ${effectiveChain}).` : "to pin it.")
|
|
4251
|
+
);
|
|
4252
|
+
}
|
|
4253
|
+
warnings.push(
|
|
4254
|
+
`Repos publish to their git \`origin\` relay, which OVERRIDES the config relayUrl \u2014 for the sandbox demo run \`rig remote add origin ${SANDBOX_RELAY_URL}\` in the repo (or use a fresh repo).`
|
|
4255
|
+
);
|
|
4256
|
+
}
|
|
4257
|
+
const state = effective();
|
|
4258
|
+
if (json) {
|
|
4259
|
+
io2.emitJson({
|
|
4260
|
+
command: "entry",
|
|
4261
|
+
entry: mutation.kind === "url" ? "custom" : mutation.kind,
|
|
4262
|
+
btpUrl: state.btpUrl,
|
|
4263
|
+
btpSource: state.btpSource,
|
|
4264
|
+
relayUrl: state.relayUrl,
|
|
4265
|
+
relaySource: state.relaySource,
|
|
4266
|
+
wrote: { btpUrl: wroteBtp, relayUrl: wroteRelay },
|
|
4267
|
+
clearedTopologyCache,
|
|
4268
|
+
configPath,
|
|
4269
|
+
...warnings.length ? { warnings } : {}
|
|
4270
|
+
});
|
|
4271
|
+
return 0;
|
|
4272
|
+
}
|
|
4273
|
+
if (mutation.kind === "apex") {
|
|
4274
|
+
io2.out("Entry reverted to the default apex (cleared btpUrl/relayUrl/proxyUrl).");
|
|
4275
|
+
io2.out(` btp ${state.btpUrl ?? "(genesis seed unavailable)"}`);
|
|
4276
|
+
io2.out(` relay ${state.relayUrl ?? "(genesis seed unavailable)"}`);
|
|
4277
|
+
} else if (mutation.kind === "sandbox") {
|
|
4278
|
+
io2.out("Entry set to the devnet sandbox (Mina USDC only \u2014 multihop demo path).");
|
|
4279
|
+
io2.out(` btp ${SANDBOX_BTP_URL}`);
|
|
4280
|
+
io2.out(` relay ${SANDBOX_RELAY_URL}`);
|
|
4281
|
+
} else {
|
|
4282
|
+
io2.out(`Entry set to ${mutation.btpUrl}.`);
|
|
4283
|
+
if (mutation.relayUrl !== void 0) io2.out(` relay ${mutation.relayUrl}`);
|
|
4284
|
+
}
|
|
4285
|
+
io2.out(
|
|
4286
|
+
`Saved to ${configPath}.` + (clearedTopologyCache ? " Cleared the cached topology." : "")
|
|
4287
|
+
);
|
|
4288
|
+
for (const w of warnings) io2.err(`warning: ${w}`);
|
|
4289
|
+
return 0;
|
|
4290
|
+
} catch (err) {
|
|
4291
|
+
return emitCliError(io2, json, "entry", err);
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4295
|
+
// src/cli/fetch.ts
|
|
4296
|
+
import { parseArgs as parseArgs10 } from "util";
|
|
3827
4297
|
var FETCH_USAGE = `Usage: rig fetch [remote] [options]
|
|
3828
4298
|
|
|
3829
4299
|
Fetch from a TOON remote \u2014 FREE (relay reads + Arweave gateway downloads; no
|
|
@@ -3877,7 +4347,7 @@ async function runFetch(args, deps) {
|
|
|
3877
4347
|
let ownerFlag;
|
|
3878
4348
|
let concurrency;
|
|
3879
4349
|
try {
|
|
3880
|
-
const { values, positionals } =
|
|
4350
|
+
const { values, positionals } = parseArgs10({
|
|
3881
4351
|
args,
|
|
3882
4352
|
options: {
|
|
3883
4353
|
json: { type: "boolean", default: false },
|
|
@@ -4042,10 +4512,10 @@ async function runFetch(args, deps) {
|
|
|
4042
4512
|
}
|
|
4043
4513
|
|
|
4044
4514
|
// src/cli/fund.ts
|
|
4045
|
-
import { readFileSync as
|
|
4046
|
-
import { homedir as
|
|
4047
|
-
import { join as
|
|
4048
|
-
import { parseArgs as
|
|
4515
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
4516
|
+
import { homedir as homedir5 } from "os";
|
|
4517
|
+
import { join as join6 } from "path";
|
|
4518
|
+
import { parseArgs as parseArgs11 } from "util";
|
|
4049
4519
|
var DEVNET_FAUCET_URL = "https://faucet.devnet.toonprotocol.dev";
|
|
4050
4520
|
var CHAINS = ["evm", "solana", "mina"];
|
|
4051
4521
|
var CHAIN_ALIASES = {
|
|
@@ -4083,7 +4553,9 @@ The identity comes from RIG_MNEMONIC (env or a project .env) or the
|
|
|
4083
4553
|
faucetUrl config field, or the deployed devnet faucet when the network is
|
|
4084
4554
|
devnet \u2014 including when a configured *.devnet.toonprotocol.dev origin infers
|
|
4085
4555
|
it (a devnet relay/proxy/btp endpoint, or the git origin remote from
|
|
4086
|
-
\`rig remote add origin <devnet relay>\`).
|
|
4556
|
+
\`rig remote add origin <devnet relay>\`). A completely fresh install with NO
|
|
4557
|
+
origin configured anywhere infers devnet from the built-in genesis seed, so a
|
|
4558
|
+
bare \`rig fund\` works with zero config. The faucet drips a FIXED amount per
|
|
4087
4559
|
chain (there is no --amount). On a network without a faucet, prints the wallet
|
|
4088
4560
|
address(es) to fund externally instead.
|
|
4089
4561
|
|
|
@@ -4120,6 +4592,44 @@ function sharedDevnetOrigin(env, file, originRelays = []) {
|
|
|
4120
4592
|
}
|
|
4121
4593
|
return void 0;
|
|
4122
4594
|
}
|
|
4595
|
+
async function loadGenesisSeedDefault2() {
|
|
4596
|
+
try {
|
|
4597
|
+
const { loadGenesisSeed } = await import("../network-bootstrap-3X2GXNJB.js");
|
|
4598
|
+
return loadGenesisSeed();
|
|
4599
|
+
} catch {
|
|
4600
|
+
return void 0;
|
|
4601
|
+
}
|
|
4602
|
+
}
|
|
4603
|
+
async function resolveEffectiveNetwork(opts) {
|
|
4604
|
+
const { env, cwd } = opts;
|
|
4605
|
+
const file = opts.file ?? readFundConfig(env).file;
|
|
4606
|
+
const network = env["TOON_CLIENT_NETWORK"] ?? file.network;
|
|
4607
|
+
const canInfer = network === void 0 || network === "custom";
|
|
4608
|
+
const originRelays = canInfer ? await resolveOriginRelays(cwd) : [];
|
|
4609
|
+
let devnetOrigin = sharedDevnetOrigin(env, file, originRelays);
|
|
4610
|
+
let seededOrigin = false;
|
|
4611
|
+
if (devnetOrigin === void 0 && canInfer) {
|
|
4612
|
+
const anyConfiguredOrigin = [
|
|
4613
|
+
env["TOON_CLIENT_RELAY_URL"] ?? file.relayUrl,
|
|
4614
|
+
env["TOON_CLIENT_PROXY_URL"] ?? file.proxyUrl,
|
|
4615
|
+
env["TOON_CLIENT_BTP_URL"] ?? file.btpUrl,
|
|
4616
|
+
...originRelays
|
|
4617
|
+
].some((url) => url !== void 0);
|
|
4618
|
+
if (!anyConfiguredOrigin) {
|
|
4619
|
+
const seed = await (opts.loadGenesisSeed ?? loadGenesisSeedDefault2)();
|
|
4620
|
+
devnetOrigin = devnetHost(seed?.relayUrl) ?? devnetHost(seed?.btpEndpoint);
|
|
4621
|
+
seededOrigin = devnetOrigin !== void 0;
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
const inferredDevnet = devnetOrigin !== void 0 && canInfer;
|
|
4625
|
+
return {
|
|
4626
|
+
network,
|
|
4627
|
+
effectiveNetwork: inferredDevnet ? "devnet" : network,
|
|
4628
|
+
devnetOrigin,
|
|
4629
|
+
seededOrigin,
|
|
4630
|
+
inferredDevnet
|
|
4631
|
+
};
|
|
4632
|
+
}
|
|
4123
4633
|
async function resolveOriginRelays(cwd) {
|
|
4124
4634
|
let repoRoot;
|
|
4125
4635
|
try {
|
|
@@ -4149,11 +4659,11 @@ function noFaucetGuidance(network, devnetOrigin) {
|
|
|
4149
4659
|
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}`;
|
|
4150
4660
|
}
|
|
4151
4661
|
function readFundConfig(env) {
|
|
4152
|
-
const dir = env["TOON_CLIENT_HOME"] ??
|
|
4153
|
-
const configPath =
|
|
4662
|
+
const dir = env["TOON_CLIENT_HOME"] ?? join6(homedir5(), ".toon-client");
|
|
4663
|
+
const configPath = join6(dir, "config.json");
|
|
4154
4664
|
try {
|
|
4155
4665
|
return {
|
|
4156
|
-
file: JSON.parse(
|
|
4666
|
+
file: JSON.parse(readFileSync5(configPath, "utf8")),
|
|
4157
4667
|
configPath
|
|
4158
4668
|
};
|
|
4159
4669
|
} catch (err) {
|
|
@@ -4171,7 +4681,7 @@ async function runFund(args, deps) {
|
|
|
4171
4681
|
let addressFlag;
|
|
4172
4682
|
let json = false;
|
|
4173
4683
|
try {
|
|
4174
|
-
const { values, positionals } =
|
|
4684
|
+
const { values, positionals } = parseArgs11({
|
|
4175
4685
|
args,
|
|
4176
4686
|
allowPositionals: true,
|
|
4177
4687
|
options: {
|
|
@@ -4213,11 +4723,12 @@ async function runFund(args, deps) {
|
|
|
4213
4723
|
const { file } = readFundConfig(env);
|
|
4214
4724
|
const targetChains = resolvedChain === void 0 || resolvedChain === "all" ? [...CHAINS] : [resolvedChain];
|
|
4215
4725
|
const network = env["TOON_CLIENT_NETWORK"] ?? file.network;
|
|
4216
|
-
const
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4726
|
+
const { devnetOrigin, seededOrigin, inferredDevnet, effectiveNetwork } = await resolveEffectiveNetwork({
|
|
4727
|
+
env,
|
|
4728
|
+
cwd: deps.cwd,
|
|
4729
|
+
file,
|
|
4730
|
+
...deps.loadGenesisSeed ? { loadGenesisSeed: deps.loadGenesisSeed } : {}
|
|
4731
|
+
});
|
|
4221
4732
|
const faucetUrl = env["TOON_CLIENT_FAUCET_URL"] ?? file.faucetUrl ?? (effectiveNetwork === "devnet" ? DEVNET_FAUCET_URL : void 0);
|
|
4222
4733
|
const resolved = await resolveIdentity({
|
|
4223
4734
|
env,
|
|
@@ -4268,7 +4779,7 @@ async function runFund(args, deps) {
|
|
|
4268
4779
|
};
|
|
4269
4780
|
if (!json && inferredDevnet) {
|
|
4270
4781
|
io2.out(
|
|
4271
|
-
`Inferred network 'devnet' from the configured origin ${devnetOrigin} (network was ${JSON.stringify(network ?? "custom")}). Set TOON_CLIENT_NETWORK explicitly to override.`
|
|
4782
|
+
seededOrigin ? `Inferred network 'devnet' from the built-in genesis seed ${devnetOrigin} (nothing configured \u2014 fresh install). Set TOON_CLIENT_NETWORK explicitly to override.` : `Inferred network 'devnet' from the configured origin ${devnetOrigin} (network was ${JSON.stringify(network ?? "custom")}). Set TOON_CLIENT_NETWORK explicitly to override.`
|
|
4272
4783
|
);
|
|
4273
4784
|
}
|
|
4274
4785
|
if (!json) {
|
|
@@ -4321,7 +4832,9 @@ async function runFund(args, deps) {
|
|
|
4321
4832
|
network: effectiveNetwork ?? null,
|
|
4322
4833
|
faucetUrl,
|
|
4323
4834
|
results,
|
|
4324
|
-
...inferredDevnet ? {
|
|
4835
|
+
...inferredDevnet ? {
|
|
4836
|
+
inferredDevnetFrom: seededOrigin ? `${devnetOrigin} (genesis seed)` : devnetOrigin
|
|
4837
|
+
} : {}
|
|
4325
4838
|
});
|
|
4326
4839
|
return allFunded ? 0 : 1;
|
|
4327
4840
|
}
|
|
@@ -4393,10 +4906,10 @@ var runGitPassthrough = (argv2, options = {}) => {
|
|
|
4393
4906
|
};
|
|
4394
4907
|
|
|
4395
4908
|
// src/cli/identity-cmd.ts
|
|
4396
|
-
import { existsSync, mkdirSync as
|
|
4397
|
-
import { dirname as
|
|
4909
|
+
import { existsSync, mkdirSync as mkdirSync4 } from "fs";
|
|
4910
|
+
import { dirname as dirname4 } from "path";
|
|
4398
4911
|
import { createInterface } from "readline/promises";
|
|
4399
|
-
import { parseArgs as
|
|
4912
|
+
import { parseArgs as parseArgs12 } from "util";
|
|
4400
4913
|
async function loadKeyOps() {
|
|
4401
4914
|
return await import("@toon-protocol/client");
|
|
4402
4915
|
}
|
|
@@ -4445,7 +4958,7 @@ async function prepareKeystoreTarget(input) {
|
|
|
4445
4958
|
const envPassword = input.env["TOON_CLIENT_KEYSTORE_PASSWORD"]?.trim() || void 0;
|
|
4446
4959
|
const autoPassword = envPassword === void 0;
|
|
4447
4960
|
const password = envPassword ?? DEFAULT_KEYSTORE_PASSWORD;
|
|
4448
|
-
|
|
4961
|
+
mkdirSync4(dirname4(keystorePath), { recursive: true });
|
|
4449
4962
|
return { keystorePath, password, autoPassword, existing, keyOps };
|
|
4450
4963
|
}
|
|
4451
4964
|
function readAccountIndex(env) {
|
|
@@ -4567,7 +5080,7 @@ async function runIdentity(args, deps) {
|
|
|
4567
5080
|
}
|
|
4568
5081
|
}
|
|
4569
5082
|
function parseMintArgs(args, verb) {
|
|
4570
|
-
const { values, positionals } =
|
|
5083
|
+
const { values, positionals } = parseArgs12({
|
|
4571
5084
|
args,
|
|
4572
5085
|
options: {
|
|
4573
5086
|
force: { type: "boolean", default: false },
|
|
@@ -4672,7 +5185,7 @@ async function runIdentityShow(args, deps) {
|
|
|
4672
5185
|
let json = false;
|
|
4673
5186
|
let help = false;
|
|
4674
5187
|
try {
|
|
4675
|
-
const parsed =
|
|
5188
|
+
const parsed = parseArgs12({
|
|
4676
5189
|
args,
|
|
4677
5190
|
options: {
|
|
4678
5191
|
json: { type: "boolean", default: false },
|
|
@@ -4781,7 +5294,7 @@ async function defaultReadSecretLine(prompt, isInteractive) {
|
|
|
4781
5294
|
|
|
4782
5295
|
// src/cli/init.ts
|
|
4783
5296
|
import { basename as basename2 } from "path";
|
|
4784
|
-
import { parseArgs as
|
|
5297
|
+
import { parseArgs as parseArgs13 } from "util";
|
|
4785
5298
|
|
|
4786
5299
|
// src/cli/git-author.ts
|
|
4787
5300
|
var PROFILE_KIND = 0;
|
|
@@ -4899,7 +5412,7 @@ Options:
|
|
|
4899
5412
|
--json machine-readable report
|
|
4900
5413
|
-h, --help show this help`;
|
|
4901
5414
|
function parseInitArgs(args) {
|
|
4902
|
-
const { values, positionals } =
|
|
5415
|
+
const { values, positionals } = parseArgs13({
|
|
4903
5416
|
args,
|
|
4904
5417
|
options: {
|
|
4905
5418
|
"repo-id": { type: "string" },
|
|
@@ -5132,7 +5645,7 @@ async function runInit(args, deps) {
|
|
|
5132
5645
|
}
|
|
5133
5646
|
|
|
5134
5647
|
// src/cli/maintainers.ts
|
|
5135
|
-
import { parseArgs as
|
|
5648
|
+
import { parseArgs as parseArgs14 } from "util";
|
|
5136
5649
|
var HEX64_RE3 = /^[0-9a-f]{64}$/;
|
|
5137
5650
|
var WS_URL_RE4 = /^wss?:\/\//i;
|
|
5138
5651
|
var MAINTAINERS_USAGE = `Usage: rig maintainers <list|add|remove> [<pubkey>] [options]
|
|
@@ -5237,7 +5750,7 @@ async function runList2(args, deps) {
|
|
|
5237
5750
|
const { io: io2 } = deps;
|
|
5238
5751
|
let flags;
|
|
5239
5752
|
try {
|
|
5240
|
-
const { values, positionals } =
|
|
5753
|
+
const { values, positionals } = parseArgs14({
|
|
5241
5754
|
args,
|
|
5242
5755
|
options: MAINT_OPTIONS,
|
|
5243
5756
|
allowPositionals: true
|
|
@@ -5304,7 +5817,7 @@ async function runMutate(op, args, deps) {
|
|
|
5304
5817
|
let flags;
|
|
5305
5818
|
let pubkey;
|
|
5306
5819
|
try {
|
|
5307
|
-
const { values, positionals } =
|
|
5820
|
+
const { values, positionals } = parseArgs14({
|
|
5308
5821
|
args,
|
|
5309
5822
|
options: MAINT_OPTIONS,
|
|
5310
5823
|
allowPositionals: true
|
|
@@ -5453,7 +5966,7 @@ async function runMutate(op, args, deps) {
|
|
|
5453
5966
|
|
|
5454
5967
|
// src/cli/name.ts
|
|
5455
5968
|
import { randomUUID } from "crypto";
|
|
5456
|
-
import { parseArgs as
|
|
5969
|
+
import { parseArgs as parseArgs15 } from "util";
|
|
5457
5970
|
var ARIO_DECIMALS = 6;
|
|
5458
5971
|
function renderMario(mario) {
|
|
5459
5972
|
return `${mario.toString()} mARIO (~${formatUnits(mario.toString(), ARIO_DECIMALS)} ARIO)`;
|
|
@@ -5857,6 +6370,7 @@ var defaultGasStationClient = {
|
|
|
5857
6370
|
};
|
|
5858
6371
|
}
|
|
5859
6372
|
};
|
|
6373
|
+
var DEVNET_DVM_URL = "https://dvm.devnet.toonprotocol.dev";
|
|
5860
6374
|
var NAME_USAGE = `Usage: rig name <buy|set|status> <name> [options]
|
|
5861
6375
|
|
|
5862
6376
|
ArNS naming for Arweave-served artifacts. A name registered on the ar.io
|
|
@@ -5909,12 +6423,18 @@ Options:
|
|
|
5909
6423
|
unverified.
|
|
5910
6424
|
--process-id <id> explicit ArNS registry program id \u2014 a Solana program
|
|
5911
6425
|
address (overrides --network; or RIG_ARIO_PROCESS_ID)
|
|
5912
|
-
--via <dvm-url>
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
6426
|
+
--via <dvm-url> broker buy/set through a store DVM's job endpoint (or
|
|
6427
|
+
RIG_ARNS_DVM_URL). The DVM pays the mARIO; you own the
|
|
6428
|
+
name via your spawned ANT. Direct backend targeting
|
|
6429
|
+
stubs the job payment (dev/e2e) \u2014 the paid path runs
|
|
6430
|
+
the same job through the connector payment proxy.
|
|
6431
|
+
DEVNET DEFAULT: with --network devnet and the TOON
|
|
6432
|
+
network on devnet too, buy/set default to the deployed
|
|
6433
|
+
devnet store DVM (${DEVNET_DVM_URL})
|
|
6434
|
+
unless --direct opts out.
|
|
6435
|
+
--direct force the direct wallet-paid path: never default (or
|
|
6436
|
+
read RIG_ARNS_DVM_URL as) a --via DVM. Mutually
|
|
6437
|
+
exclusive with an explicit --via.
|
|
5918
6438
|
--yes skip the confirmation (required when not a TTY) for
|
|
5919
6439
|
buy/set
|
|
5920
6440
|
--json machine-readable envelope; for buy/set without --yes it
|
|
@@ -5960,7 +6480,7 @@ async function resolveNameContext(deps, network, processId, mode) {
|
|
|
5960
6480
|
return { identity, solanaAddress, network, processId, sdk, nostrSecretKey };
|
|
5961
6481
|
}
|
|
5962
6482
|
function parseNameFlags(args, env) {
|
|
5963
|
-
const { values, positionals } =
|
|
6483
|
+
const { values, positionals } = parseArgs15({
|
|
5964
6484
|
args,
|
|
5965
6485
|
allowPositionals: true,
|
|
5966
6486
|
options: {
|
|
@@ -5971,6 +6491,7 @@ function parseNameFlags(args, env) {
|
|
|
5971
6491
|
network: { type: "string" },
|
|
5972
6492
|
"process-id": { type: "string" },
|
|
5973
6493
|
via: { type: "string" },
|
|
6494
|
+
direct: { type: "boolean", default: false },
|
|
5974
6495
|
"tx-id": { type: "string" },
|
|
5975
6496
|
yes: { type: "boolean", default: false },
|
|
5976
6497
|
json: { type: "boolean", default: false },
|
|
@@ -5984,6 +6505,7 @@ function parseNameFlags(args, env) {
|
|
|
5984
6505
|
permabuy: false,
|
|
5985
6506
|
ttl: 0,
|
|
5986
6507
|
network: "mainnet",
|
|
6508
|
+
direct: false,
|
|
5987
6509
|
yes: false,
|
|
5988
6510
|
json: false
|
|
5989
6511
|
}
|
|
@@ -6017,7 +6539,12 @@ function parseNameFlags(args, env) {
|
|
|
6017
6539
|
);
|
|
6018
6540
|
}
|
|
6019
6541
|
const processId = values["process-id"] ?? env["RIG_ARIO_PROCESS_ID"];
|
|
6020
|
-
|
|
6542
|
+
if (values.direct && values.via !== void 0) {
|
|
6543
|
+
throw new Error(
|
|
6544
|
+
"--direct and --via are mutually exclusive: --direct forces the wallet-paid path, --via brokers through a DVM"
|
|
6545
|
+
);
|
|
6546
|
+
}
|
|
6547
|
+
const viaRaw = values.direct ? void 0 : values.via ?? env["RIG_ARNS_DVM_URL"];
|
|
6021
6548
|
let via;
|
|
6022
6549
|
if (viaRaw !== void 0) {
|
|
6023
6550
|
if (!/^https?:\/\/.+/.test(viaRaw)) {
|
|
@@ -6037,6 +6564,7 @@ function parseNameFlags(args, env) {
|
|
|
6037
6564
|
network: networkRaw,
|
|
6038
6565
|
...processId !== void 0 ? { processId } : {},
|
|
6039
6566
|
...via !== void 0 ? { via } : {},
|
|
6567
|
+
direct: values.direct ?? false,
|
|
6040
6568
|
...values["tx-id"] !== void 0 ? { txId: values["tx-id"] } : {},
|
|
6041
6569
|
yes: values.yes ?? false,
|
|
6042
6570
|
json: values.json ?? false
|
|
@@ -6427,6 +6955,20 @@ async function runName(args, deps) {
|
|
|
6427
6955
|
io2.err(NAME_USAGE);
|
|
6428
6956
|
return 2;
|
|
6429
6957
|
}
|
|
6958
|
+
if ((sub === "buy" || sub === "set") && !flags.direct && flags.via === void 0 && flags.network === "devnet") {
|
|
6959
|
+
let toonDevnet = false;
|
|
6960
|
+
try {
|
|
6961
|
+
const resolved = await (deps.resolveToonNetwork ?? resolveEffectiveNetwork)({ env: deps.env, cwd: deps.cwd });
|
|
6962
|
+
toonDevnet = resolved.effectiveNetwork === "devnet";
|
|
6963
|
+
} catch {
|
|
6964
|
+
}
|
|
6965
|
+
if (toonDevnet) {
|
|
6966
|
+
flags = { ...flags, via: DEVNET_DVM_URL };
|
|
6967
|
+
io2.err(
|
|
6968
|
+
`Brokering via the devnet store DVM ${DEVNET_DVM_URL} (no --via given; pass --direct for a wallet-paid ${sub}).`
|
|
6969
|
+
);
|
|
6970
|
+
}
|
|
6971
|
+
}
|
|
6430
6972
|
try {
|
|
6431
6973
|
if (sub === "buy") return await runBuy(name, flags, deps);
|
|
6432
6974
|
if (sub === "status") return await runStatus(name, flags, deps);
|
|
@@ -6450,7 +6992,7 @@ async function runName(args, deps) {
|
|
|
6450
6992
|
}
|
|
6451
6993
|
|
|
6452
6994
|
// src/cli/site.ts
|
|
6453
|
-
import { parseArgs as
|
|
6995
|
+
import { parseArgs as parseArgs16 } from "util";
|
|
6454
6996
|
|
|
6455
6997
|
// src/arweave-manifest.ts
|
|
6456
6998
|
var DEFAULT_INDEX = "index.html";
|
|
@@ -6469,22 +7011,22 @@ function buildArweaveManifest(entries, indexPath = DEFAULT_INDEX, fallbackTxId)
|
|
|
6469
7011
|
}
|
|
6470
7012
|
|
|
6471
7013
|
// src/cli/site-record.ts
|
|
6472
|
-
import { mkdirSync as
|
|
6473
|
-
import { homedir as
|
|
6474
|
-
import { join as
|
|
7014
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
7015
|
+
import { homedir as homedir6 } from "os";
|
|
7016
|
+
import { join as join7 } from "path";
|
|
6475
7017
|
var SITE_MANIFEST_FILENAME = "site-manifests.json";
|
|
6476
7018
|
function storeDir2(env) {
|
|
6477
|
-
return env["TOON_CLIENT_HOME"] ??
|
|
7019
|
+
return env["TOON_CLIENT_HOME"] ?? join7(homedir6(), ".toon-client");
|
|
6478
7020
|
}
|
|
6479
7021
|
function storePath2(env) {
|
|
6480
|
-
return
|
|
7022
|
+
return join7(storeDir2(env), SITE_MANIFEST_FILENAME);
|
|
6481
7023
|
}
|
|
6482
7024
|
function keyOf(repoId, ref) {
|
|
6483
7025
|
return `${repoId}\0${ref}`;
|
|
6484
7026
|
}
|
|
6485
7027
|
function readFile2(env) {
|
|
6486
7028
|
try {
|
|
6487
|
-
const parsed = JSON.parse(
|
|
7029
|
+
const parsed = JSON.parse(readFileSync6(storePath2(env), "utf8"));
|
|
6488
7030
|
if (parsed && typeof parsed === "object") return parsed;
|
|
6489
7031
|
return {};
|
|
6490
7032
|
} catch {
|
|
@@ -6496,16 +7038,16 @@ function readSiteRecord(env, repoId, ref) {
|
|
|
6496
7038
|
}
|
|
6497
7039
|
function writeSiteRecord(env, record) {
|
|
6498
7040
|
const dir = storeDir2(env);
|
|
6499
|
-
|
|
7041
|
+
mkdirSync5(dir, { recursive: true });
|
|
6500
7042
|
const file = readFile2(env);
|
|
6501
7043
|
file[keyOf(record.repoId, record.ref)] = record;
|
|
6502
|
-
|
|
7044
|
+
writeFileSync4(storePath2(env), `${JSON.stringify(file, null, 2)}
|
|
6503
7045
|
`, "utf8");
|
|
6504
7046
|
}
|
|
6505
7047
|
|
|
6506
7048
|
// src/cli/site.ts
|
|
6507
7049
|
var MANIFEST_CONTENT_TYPE = "application/x.arweave-manifest+json";
|
|
6508
|
-
var DEFAULT_GATEWAY = "https://
|
|
7050
|
+
var DEFAULT_GATEWAY = "https://ar-io.dev";
|
|
6509
7051
|
var SITE_USAGE = `Usage: rig site <publish|url> [ref] [options]
|
|
6510
7052
|
|
|
6511
7053
|
Serve a pushed repo as a permanent, path-routed website. \`rig push\` already
|
|
@@ -6541,7 +7083,7 @@ Options (publish):
|
|
|
6541
7083
|
estimate (nothing uploaded)
|
|
6542
7084
|
-h, --help show this help`;
|
|
6543
7085
|
function parseSiteArgs(args) {
|
|
6544
|
-
const { values, positionals } =
|
|
7086
|
+
const { values, positionals } = parseArgs16({
|
|
6545
7087
|
args,
|
|
6546
7088
|
options: {
|
|
6547
7089
|
index: { type: "string" },
|
|
@@ -6951,15 +7493,23 @@ Commands rig owns:
|
|
|
6951
7493
|
(free \u2014 chain reads and local state only)
|
|
6952
7494
|
chain [set <c>|unset] choose which chain/USDC settles paid writes
|
|
6953
7495
|
(evm|sol|mina); free \u2014 reads/writes local config
|
|
7496
|
+
entry [apex|sandbox|url] choose the network entry node (payment ingress +
|
|
7497
|
+
relay): apex settles evm|sol|mina, sandbox is the
|
|
7498
|
+
Mina-only multihop demo path; free \u2014 writes local
|
|
7499
|
+
config and clears the cached topology
|
|
6954
7500
|
name buy <name> ArNS naming (#367): buy points a human name at an
|
|
6955
7501
|
name set <name> <txId> Arweave txId, owned + paid by this identity's
|
|
6956
7502
|
name status <name> Solana key. buy spends mARIO on Solana via the
|
|
6957
7503
|
ar.io registry (NOT ILP); status is free. Needs
|
|
6958
7504
|
the optional \`@ar.io/sdk\` dependency
|
|
6959
7505
|
channel list show the payment channels paid commands hold
|
|
6960
|
-
(free \u2014 reads local state
|
|
7506
|
+
(free \u2014 reads local state; \`rig channels\` is a
|
|
7507
|
+
shorthand for \`rig channel list\`)
|
|
6961
7508
|
channel open explicitly open (or resume) the channel for a
|
|
6962
7509
|
peer; --deposit adds collateral (on-chain)
|
|
7510
|
+
channel deploy-zkapp pre-deploy this identity's dedicated Mina
|
|
7511
|
+
PaymentChannel zkApp (on-chain; the Mina open
|
|
7512
|
+
path otherwise does this automatically)
|
|
6963
7513
|
channel close <channelId> start the settlement challenge window (on-chain)
|
|
6964
7514
|
channel settle <channelId> release collateral after the window (on-chain)
|
|
6965
7515
|
|
|
@@ -7022,12 +7572,19 @@ async function dispatch(argv2, deps) {
|
|
|
7022
7572
|
return runMaintainers(rest, deps);
|
|
7023
7573
|
case "channel":
|
|
7024
7574
|
return runChannel(rest, deps);
|
|
7575
|
+
case "channels":
|
|
7576
|
+
return runChannel(
|
|
7577
|
+
rest[0] !== void 0 && !rest[0].startsWith("-") ? rest : ["list", ...rest],
|
|
7578
|
+
deps
|
|
7579
|
+
);
|
|
7025
7580
|
case "fund":
|
|
7026
7581
|
return runFund(rest, deps);
|
|
7027
7582
|
case "balance":
|
|
7028
7583
|
return runBalance(rest, deps);
|
|
7029
7584
|
case "chain":
|
|
7030
7585
|
return runChain(rest, deps);
|
|
7586
|
+
case "entry":
|
|
7587
|
+
return runEntry(rest, deps);
|
|
7031
7588
|
case "name":
|
|
7032
7589
|
return runName(rest, deps);
|
|
7033
7590
|
case "help":
|
|
@@ -7105,8 +7662,11 @@ var RIG_OWNED_VERBS = /* @__PURE__ */ new Set([
|
|
|
7105
7662
|
"pr",
|
|
7106
7663
|
"maintainers",
|
|
7107
7664
|
"channel",
|
|
7665
|
+
"channels",
|
|
7108
7666
|
"fund",
|
|
7109
7667
|
"balance",
|
|
7668
|
+
"chain",
|
|
7669
|
+
"entry",
|
|
7110
7670
|
"name"
|
|
7111
7671
|
]);
|
|
7112
7672
|
function isJsonInvocation(argv2) {
|