@toon-protocol/rig 2.9.0 → 2.10.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 +35 -2
- package/dist/{chunk-XGFBDUQX.js → chunk-GZUDRNOK.js} +22 -2
- package/dist/chunk-GZUDRNOK.js.map +1 -0
- package/dist/{chunk-LTQPBBHA.js → chunk-RALCZLP6.js} +14 -3
- package/dist/chunk-RALCZLP6.js.map +1 -0
- package/dist/cli/rig.js +612 -71
- package/dist/cli/rig.js.map +1 -1
- package/dist/{network-bootstrap-HTNM7BBX.js → network-bootstrap-GRBEPZMI.js} +4 -2
- package/dist/{standalone-mode-FPFEEL72.js → standalone-mode-6KIBWGLP.js} +3 -3
- package/package.json +5 -2
- package/dist/chunk-LTQPBBHA.js.map +0 -1
- package/dist/chunk-XGFBDUQX.js.map +0 -1
- /package/dist/{network-bootstrap-HTNM7BBX.js.map → network-bootstrap-GRBEPZMI.js.map} +0 -0
- /package/dist/{standalone-mode-FPFEEL72.js.map → standalone-mode-6KIBWGLP.js.map} +0 -0
package/dist/cli/rig.js
CHANGED
|
@@ -26,8 +26,9 @@ import {
|
|
|
26
26
|
clientKeystorePath,
|
|
27
27
|
linkKeystoreInClientConfig,
|
|
28
28
|
readClientConfigFile,
|
|
29
|
+
resolveAccountIndex,
|
|
29
30
|
resolveIdentity
|
|
30
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-GZUDRNOK.js";
|
|
31
32
|
import {
|
|
32
33
|
ChannelMapStore,
|
|
33
34
|
channelStatus,
|
|
@@ -312,9 +313,7 @@ function nonFastForwardLines(refs) {
|
|
|
312
313
|
function oversizeLines(objects) {
|
|
313
314
|
return [
|
|
314
315
|
`Push rejected: ${objects.length} object(s) exceed the ${MAX_OBJECT_SIZE}-byte (95KB) upload limit:`,
|
|
315
|
-
...objects.map(
|
|
316
|
-
(o) => ` ${o.path ?? o.sha} ${o.type}, ${o.size} bytes`
|
|
317
|
-
),
|
|
316
|
+
...objects.map((o) => ` ${o.path ?? o.sha} ${o.type}, ${o.size} bytes`),
|
|
318
317
|
"Objects over 95KB are a hard error in v1 \u2014 split or remove the file(s) from history to push.",
|
|
319
318
|
"Large-object support is tracked in toon-client#235."
|
|
320
319
|
];
|
|
@@ -345,7 +344,11 @@ function describeError(err, command = "push") {
|
|
|
345
344
|
return {
|
|
346
345
|
code: "unknown_remote",
|
|
347
346
|
lines: err.message.split("\n"),
|
|
348
|
-
json: {
|
|
347
|
+
json: {
|
|
348
|
+
error: "unknown_remote",
|
|
349
|
+
detail: err.message,
|
|
350
|
+
remote: err.remote
|
|
351
|
+
}
|
|
349
352
|
};
|
|
350
353
|
}
|
|
351
354
|
if (err instanceof MultiUrlRemoteError) {
|
|
@@ -406,6 +409,13 @@ function describeError(err, command = "push") {
|
|
|
406
409
|
json: { error: "arns_sdk_unavailable", detail: err.message }
|
|
407
410
|
};
|
|
408
411
|
}
|
|
412
|
+
if (err instanceof Error && err.name === "ArnsSdkIncompatibleError") {
|
|
413
|
+
return {
|
|
414
|
+
code: "arns_sdk_incompatible",
|
|
415
|
+
lines: err.message.split("\n"),
|
|
416
|
+
json: { error: "arns_sdk_incompatible", detail: err.message }
|
|
417
|
+
};
|
|
418
|
+
}
|
|
409
419
|
if (err instanceof DaemonRouteError) {
|
|
410
420
|
const envelope = err.envelope;
|
|
411
421
|
if (envelope.error === "non_fast_forward" && Array.isArray(envelope["refs"])) {
|
|
@@ -1063,7 +1073,7 @@ function loadPaidSession(deps, relayUrl) {
|
|
|
1063
1073
|
});
|
|
1064
1074
|
}
|
|
1065
1075
|
var defaultLoadStandalone = async (options) => {
|
|
1066
|
-
const mod = await import("../standalone-mode-
|
|
1076
|
+
const mod = await import("../standalone-mode-6KIBWGLP.js");
|
|
1067
1077
|
return mod.createStandaloneContext(options);
|
|
1068
1078
|
};
|
|
1069
1079
|
function identityReport(ctx) {
|
|
@@ -4188,7 +4198,7 @@ async function prepareKeystoreTarget(input) {
|
|
|
4188
4198
|
}
|
|
4189
4199
|
function readAccountIndex(env) {
|
|
4190
4200
|
const file = readClientConfigFile(clientConfigPath(env));
|
|
4191
|
-
return
|
|
4201
|
+
return resolveAccountIndex(env, "keystore", file);
|
|
4192
4202
|
}
|
|
4193
4203
|
function finishMint(input, target, mnemonic) {
|
|
4194
4204
|
const configPath = linkKeystoreInClientConfig(
|
|
@@ -4681,7 +4691,7 @@ async function resolveProfileRelay(flagRelay, originRelay, toonRelays) {
|
|
|
4681
4691
|
].filter((u) => u !== void 0 && isWebSocketRelay2(u));
|
|
4682
4692
|
if (candidates[0] !== void 0) return candidates[0];
|
|
4683
4693
|
try {
|
|
4684
|
-
const { loadGenesisSeed } = await import("../network-bootstrap-
|
|
4694
|
+
const { loadGenesisSeed } = await import("../network-bootstrap-GRBEPZMI.js");
|
|
4685
4695
|
const seed = loadGenesisSeed();
|
|
4686
4696
|
if (seed?.relayUrl && isWebSocketRelay2(seed.relayUrl)) return seed.relayUrl;
|
|
4687
4697
|
} catch {
|
|
@@ -5190,67 +5200,411 @@ async function runMutate(op, args, deps) {
|
|
|
5190
5200
|
}
|
|
5191
5201
|
|
|
5192
5202
|
// src/cli/name.ts
|
|
5203
|
+
import { randomUUID } from "crypto";
|
|
5193
5204
|
import { parseArgs as parseArgs13 } from "util";
|
|
5194
5205
|
var ARIO_DECIMALS = 6;
|
|
5195
5206
|
function renderMario(mario) {
|
|
5196
5207
|
return `${mario.toString()} mARIO (~${formatUnits(mario.toString(), ARIO_DECIMALS)} ARIO)`;
|
|
5197
5208
|
}
|
|
5198
5209
|
var MARIO_PAYMENT_NOTE = "Payment is mARIO from this identity's Solana wallet, charged on-chain by the ar.io registry program \u2014 NOT through TOON ILP payment channels. Fund this wallet with `rig fund --chain solana` (or send $ARIO to the Solana address above).";
|
|
5210
|
+
var DVM_PAYMENT_NOTE = "Brokered buy (--via): the DVM pays the mARIO name price from ITS Solana wallet via the kind:5095 job; this wallet needs only dust SOL to spawn the ANT it owns. On the paid path the job fee is enforced by the connector payment proxy in front of the DVM; when --via targets the DVM backend directly the job payment is STUBBED (dev/e2e only). The ArNS purchase itself is real either way, and the name is owned by YOUR ANT from inception.";
|
|
5211
|
+
var MIN_ARIO_SDK_VERSION = "4.0.3";
|
|
5199
5212
|
var ArnsSdkUnavailableError = class extends Error {
|
|
5200
|
-
constructor(cause) {
|
|
5213
|
+
constructor(cause, module = "@ar.io/sdk") {
|
|
5201
5214
|
super(
|
|
5202
|
-
|
|
5215
|
+
`\`rig name\` needs the optional \`${module}\` dependency, which is not installed. It is intentionally NOT a base \`rig\` dependency (keeps the install lean). Add it to use ArNS naming:
|
|
5216
|
+
npm i @ar.io/sdk@^${MIN_ARIO_SDK_VERSION} # or: pnpm add @ar.io/sdk@^${MIN_ARIO_SDK_VERSION}
|
|
5217
|
+
(\`@solana/kit\` installs alongside it) then re-run your \`rig name\` command.` + (cause instanceof Error ? `
|
|
5203
5218
|
(underlying error: ${cause.message})` : "")
|
|
5204
5219
|
);
|
|
5205
5220
|
this.name = "ArnsSdkUnavailableError";
|
|
5206
5221
|
}
|
|
5207
5222
|
};
|
|
5208
|
-
var
|
|
5223
|
+
var ArnsSdkIncompatibleError = class extends Error {
|
|
5224
|
+
constructor(detail) {
|
|
5225
|
+
super(
|
|
5226
|
+
`the installed @ar.io/sdk is incompatible with \`rig name\`: ${detail}.
|
|
5227
|
+
\`rig name\` requires @ar.io/sdk >= ${MIN_ARIO_SDK_VERSION} (the Solana-native release driven via a \`@solana/kit\` rpc + signer). Upgrade with:
|
|
5228
|
+
npm i @ar.io/sdk@latest # or: pnpm add @ar.io/sdk@latest`
|
|
5229
|
+
);
|
|
5230
|
+
this.name = "ArnsSdkIncompatibleError";
|
|
5231
|
+
}
|
|
5232
|
+
};
|
|
5233
|
+
var SOLANA_MAINNET_RPC_URL = "https://api.mainnet-beta.solana.com";
|
|
5234
|
+
var SOLANA_DEVNET_RPC_URL = "https://api.devnet.solana.com";
|
|
5209
5235
|
var defaultLoadArns = async (options) => {
|
|
5210
|
-
const
|
|
5236
|
+
const sdkSpecifier = "@ar.io/sdk";
|
|
5211
5237
|
let mod;
|
|
5212
5238
|
try {
|
|
5213
|
-
mod = await import(
|
|
5239
|
+
mod = await import(sdkSpecifier);
|
|
5214
5240
|
} catch (err) {
|
|
5215
5241
|
throw new ArnsSdkUnavailableError(err);
|
|
5216
5242
|
}
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
);
|
|
5221
|
-
}
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5243
|
+
const kitSpecifier = "@solana/kit";
|
|
5244
|
+
let kit;
|
|
5245
|
+
try {
|
|
5246
|
+
kit = await import(kitSpecifier);
|
|
5247
|
+
} catch (err) {
|
|
5248
|
+
throw new ArnsSdkUnavailableError(err, "@solana/kit");
|
|
5249
|
+
}
|
|
5250
|
+
const arioInit = mod.ARIO?.init;
|
|
5251
|
+
const antInit = mod.ANT?.init;
|
|
5252
|
+
if (!arioInit || !antInit) {
|
|
5253
|
+
throw new ArnsSdkIncompatibleError("it exposes no ARIO.init / ANT.init");
|
|
5254
|
+
}
|
|
5255
|
+
const {
|
|
5256
|
+
createSolanaRpc,
|
|
5257
|
+
createSolanaRpcSubscriptions,
|
|
5258
|
+
createKeyPairSignerFromBytes
|
|
5259
|
+
} = kit;
|
|
5260
|
+
if (!createSolanaRpc || !createSolanaRpcSubscriptions || !createKeyPairSignerFromBytes) {
|
|
5261
|
+
throw new ArnsSdkIncompatibleError(
|
|
5262
|
+
"the resolved @solana/kit exposes no createSolanaRpc / createSolanaRpcSubscriptions / createKeyPairSignerFromBytes"
|
|
5228
5263
|
);
|
|
5229
5264
|
}
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5265
|
+
const rpcUrl = options.network === "devnet" ? mod.DEVNET_RPC_URL ?? SOLANA_DEVNET_RPC_URL : mod.DEFAULT_SOLANA_RPC_URL ?? mod.MAINNET_RPC_URL ?? SOLANA_MAINNET_RPC_URL;
|
|
5266
|
+
const devnetIds = options.network === "devnet" ? mod.DEVNET_PROGRAM_IDS : void 0;
|
|
5267
|
+
if (options.network === "devnet" && devnetIds === void 0) {
|
|
5268
|
+
throw new ArnsSdkIncompatibleError(
|
|
5269
|
+
"it exposes no DEVNET_PROGRAM_IDS \u2014 devnet targeting needs the SDK's staging program ids"
|
|
5235
5270
|
);
|
|
5236
5271
|
}
|
|
5237
|
-
const
|
|
5238
|
-
const
|
|
5239
|
-
|
|
5272
|
+
const antProgramId = devnetIds?.ant;
|
|
5273
|
+
const programOverrides = {
|
|
5274
|
+
...devnetIds?.core !== void 0 ? { coreProgramId: devnetIds.core } : {},
|
|
5275
|
+
...devnetIds?.gar !== void 0 ? { garProgramId: devnetIds.gar } : {},
|
|
5276
|
+
...devnetIds?.arns !== void 0 ? { arnsProgramId: devnetIds.arns } : {},
|
|
5277
|
+
...antProgramId !== void 0 ? { antProgramId } : {},
|
|
5278
|
+
// --process-id / RIG_ARIO_PROCESS_ID: explicit ArNS registry program
|
|
5279
|
+
// override (wins over the cluster default).
|
|
5280
|
+
...options.processId !== void 0 ? { arnsProgramId: options.processId } : {}
|
|
5281
|
+
};
|
|
5282
|
+
const rpc = createSolanaRpc(rpcUrl);
|
|
5283
|
+
const writeExtras = options.mode === "write" ? {
|
|
5284
|
+
signer: await createKeyPairSignerFromBytes(options.solanaSecretKey),
|
|
5285
|
+
rpcSubscriptions: createSolanaRpcSubscriptions(
|
|
5286
|
+
rpcUrl.replace(/^http/, "ws")
|
|
5287
|
+
)
|
|
5288
|
+
} : {};
|
|
5289
|
+
const ario = arioInit({ rpc, ...writeExtras, ...programOverrides });
|
|
5240
5290
|
return {
|
|
5241
5291
|
getTokenCost: async (args) => BigInt(String(await ario.getTokenCost(args))),
|
|
5242
|
-
buyRecord: async (args) =>
|
|
5243
|
-
|
|
5292
|
+
buyRecord: async (args) => {
|
|
5293
|
+
if (typeof ario.buyRecord !== "function") {
|
|
5294
|
+
throw new ArnsSdkIncompatibleError(
|
|
5295
|
+
"the signed ARIO client exposes no buyRecord"
|
|
5296
|
+
);
|
|
5297
|
+
}
|
|
5298
|
+
return await ario.buyRecord(args);
|
|
5299
|
+
},
|
|
5300
|
+
spawnAnt: async (args) => {
|
|
5301
|
+
const spawn2 = mod.ANT?.spawn;
|
|
5302
|
+
if (typeof spawn2 !== "function") {
|
|
5303
|
+
throw new ArnsSdkIncompatibleError("it exposes no ANT.spawn");
|
|
5304
|
+
}
|
|
5305
|
+
if (options.mode !== "write") {
|
|
5306
|
+
throw new ArnsSdkIncompatibleError(
|
|
5307
|
+
"ANT.spawn requires the write-mode SDK (a signer) \u2014 this client was built signerless"
|
|
5308
|
+
);
|
|
5309
|
+
}
|
|
5310
|
+
const result = await spawn2({
|
|
5311
|
+
rpc,
|
|
5312
|
+
...writeExtras,
|
|
5313
|
+
state: { name: args.name },
|
|
5314
|
+
...antProgramId !== void 0 ? { antProgramId } : {}
|
|
5315
|
+
});
|
|
5316
|
+
return { processId: result.processId, signature: result.signature };
|
|
5317
|
+
},
|
|
5318
|
+
buildSetRecordTransaction: async (args) => {
|
|
5319
|
+
if (options.mode !== "write") {
|
|
5320
|
+
throw new ArnsSdkIncompatibleError(
|
|
5321
|
+
"buildSetRecordTransaction requires the write-mode SDK (a client partial-signature) \u2014 this client was built signerless"
|
|
5322
|
+
);
|
|
5323
|
+
}
|
|
5324
|
+
const contractsSpecifier = "@ar.io/solana-contracts/ant";
|
|
5325
|
+
let contracts;
|
|
5326
|
+
try {
|
|
5327
|
+
contracts = await import(contractsSpecifier);
|
|
5328
|
+
} catch (err) {
|
|
5329
|
+
throw new ArnsSdkUnavailableError(err, "@ar.io/solana-contracts");
|
|
5330
|
+
}
|
|
5331
|
+
const getSetRecordInstructionAsync = contracts.getSetRecordInstructionAsync;
|
|
5332
|
+
const getAntRecordPDA = mod.getAntRecordPDA;
|
|
5333
|
+
const {
|
|
5334
|
+
createKeyPairFromBytes,
|
|
5335
|
+
createNoopSigner,
|
|
5336
|
+
address: toAddr,
|
|
5337
|
+
blockhash: toBlockhash,
|
|
5338
|
+
createTransactionMessage,
|
|
5339
|
+
setTransactionMessageFeePayer,
|
|
5340
|
+
setTransactionMessageLifetimeUsingBlockhash,
|
|
5341
|
+
appendTransactionMessageInstructions,
|
|
5342
|
+
compileTransaction,
|
|
5343
|
+
partiallySignTransaction,
|
|
5344
|
+
getBase64EncodedWireTransaction
|
|
5345
|
+
} = kit;
|
|
5346
|
+
if (!getSetRecordInstructionAsync || !getAntRecordPDA || !createKeyPairFromBytes || !createNoopSigner || !toAddr || !toBlockhash || !createTransactionMessage || !setTransactionMessageFeePayer || !setTransactionMessageLifetimeUsingBlockhash || !appendTransactionMessageInstructions || !compileTransaction || !partiallySignTransaction || !getBase64EncodedWireTransaction) {
|
|
5347
|
+
throw new ArnsSdkIncompatibleError(
|
|
5348
|
+
"the installed @ar.io/sdk / @ar.io/solana-contracts / @solana/kit do not expose the record-set transaction builder surface"
|
|
5349
|
+
);
|
|
5350
|
+
}
|
|
5351
|
+
const asset = toAddr(args.antProcessId);
|
|
5352
|
+
const antProgram = antProgramId !== void 0 ? toAddr(antProgramId) : void 0;
|
|
5353
|
+
const [recordPda] = await getAntRecordPDA(
|
|
5354
|
+
asset,
|
|
5355
|
+
args.undername,
|
|
5356
|
+
antProgram
|
|
5357
|
+
);
|
|
5358
|
+
const ix = await getSetRecordInstructionAsync(
|
|
5359
|
+
{
|
|
5360
|
+
asset,
|
|
5361
|
+
record: recordPda,
|
|
5362
|
+
caller: createNoopSigner(toAddr(options.solanaPublicKey)),
|
|
5363
|
+
undername: args.undername,
|
|
5364
|
+
target: args.transactionId,
|
|
5365
|
+
targetProtocol: 0,
|
|
5366
|
+
ttlSeconds: args.ttlSeconds,
|
|
5367
|
+
priority: null,
|
|
5368
|
+
recordOwner: null
|
|
5369
|
+
},
|
|
5370
|
+
antProgram !== void 0 ? { programAddress: antProgram } : void 0
|
|
5371
|
+
);
|
|
5372
|
+
let message = createTransactionMessage({ version: 0 });
|
|
5373
|
+
message = setTransactionMessageFeePayer(toAddr(args.feePayer), message);
|
|
5374
|
+
message = setTransactionMessageLifetimeUsingBlockhash(
|
|
5375
|
+
{
|
|
5376
|
+
blockhash: toBlockhash(args.recentBlockhash),
|
|
5377
|
+
lastValidBlockHeight: 0n
|
|
5378
|
+
},
|
|
5379
|
+
message
|
|
5380
|
+
);
|
|
5381
|
+
message = appendTransactionMessageInstructions([ix], message);
|
|
5382
|
+
const keyPair = await createKeyPairFromBytes(options.solanaSecretKey);
|
|
5383
|
+
const signed = await partiallySignTransaction(
|
|
5384
|
+
[keyPair],
|
|
5385
|
+
compileTransaction(message)
|
|
5386
|
+
);
|
|
5387
|
+
return getBase64EncodedWireTransaction(signed);
|
|
5388
|
+
},
|
|
5389
|
+
getArNSRecord: async (args) => {
|
|
5390
|
+
let raw;
|
|
5391
|
+
try {
|
|
5392
|
+
raw = await ario.getArNSRecord(args);
|
|
5393
|
+
} catch (err) {
|
|
5394
|
+
if (err instanceof Error && /not found/i.test(err.message)) return null;
|
|
5395
|
+
throw err;
|
|
5396
|
+
}
|
|
5397
|
+
return {
|
|
5398
|
+
processId: raw.processId ?? null,
|
|
5399
|
+
type: raw.type ?? null,
|
|
5400
|
+
...raw.startTimestamp !== void 0 ? { startTimestamp: raw.startTimestamp * 1e3 } : {},
|
|
5401
|
+
...raw.endTimestamp !== void 0 ? { endTimestamp: raw.endTimestamp * 1e3 } : {},
|
|
5402
|
+
...raw.undernameLimit !== void 0 ? { undernameLimit: raw.undernameLimit } : {}
|
|
5403
|
+
};
|
|
5404
|
+
},
|
|
5244
5405
|
ant: async (pid) => {
|
|
5245
|
-
const ant = antInit({
|
|
5406
|
+
const ant = await antInit({
|
|
5407
|
+
processId: pid,
|
|
5408
|
+
rpc,
|
|
5409
|
+
...writeExtras,
|
|
5410
|
+
...antProgramId !== void 0 ? { antProgramId } : {}
|
|
5411
|
+
});
|
|
5246
5412
|
return {
|
|
5247
|
-
getRecords: () =>
|
|
5248
|
-
|
|
5249
|
-
|
|
5413
|
+
getRecords: async () => {
|
|
5414
|
+
const records = await ant.getRecords();
|
|
5415
|
+
const targets = {};
|
|
5416
|
+
for (const [undername, record] of Object.entries(records)) {
|
|
5417
|
+
targets[undername] = {
|
|
5418
|
+
transactionId: record.transactionId,
|
|
5419
|
+
ttlSeconds: record.ttlSeconds
|
|
5420
|
+
};
|
|
5421
|
+
}
|
|
5422
|
+
return targets;
|
|
5423
|
+
},
|
|
5424
|
+
setBaseNameRecord: async (a) => {
|
|
5425
|
+
if (typeof ant.setBaseNameRecord !== "function") {
|
|
5426
|
+
throw new ArnsSdkIncompatibleError(
|
|
5427
|
+
"the signed ANT client exposes no setBaseNameRecord"
|
|
5428
|
+
);
|
|
5429
|
+
}
|
|
5430
|
+
return ant.setBaseNameRecord(a);
|
|
5431
|
+
},
|
|
5432
|
+
setUndernameRecord: async (a) => {
|
|
5433
|
+
if (typeof ant.setUndernameRecord !== "function") {
|
|
5434
|
+
throw new ArnsSdkIncompatibleError(
|
|
5435
|
+
"the signed ANT client exposes no setUndernameRecord"
|
|
5436
|
+
);
|
|
5437
|
+
}
|
|
5438
|
+
return ant.setUndernameRecord(a);
|
|
5439
|
+
}
|
|
5250
5440
|
};
|
|
5251
5441
|
}
|
|
5252
5442
|
};
|
|
5253
5443
|
};
|
|
5444
|
+
var ARNS_BUY_JOB_KIND = 5095;
|
|
5445
|
+
var DvmBuyJobError = class extends Error {
|
|
5446
|
+
constructor(message) {
|
|
5447
|
+
super(message);
|
|
5448
|
+
this.name = "DvmBuyJobError";
|
|
5449
|
+
}
|
|
5450
|
+
};
|
|
5451
|
+
var defaultSubmitDvmBuyJob = async (request) => {
|
|
5452
|
+
const { finalizeEvent } = await import("nostr-tools/pure");
|
|
5453
|
+
const event = finalizeEvent(
|
|
5454
|
+
{
|
|
5455
|
+
kind: ARNS_BUY_JOB_KIND,
|
|
5456
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
5457
|
+
content: "",
|
|
5458
|
+
tags: [
|
|
5459
|
+
["param", "name", request.name],
|
|
5460
|
+
["param", "type", request.type],
|
|
5461
|
+
...request.years !== null ? [["param", "years", String(request.years)]] : [],
|
|
5462
|
+
["param", "processId", request.processId]
|
|
5463
|
+
]
|
|
5464
|
+
},
|
|
5465
|
+
request.nostrSecretKey
|
|
5466
|
+
);
|
|
5467
|
+
const url = `${request.viaUrl.replace(/\/+$/, "")}/store`;
|
|
5468
|
+
let response;
|
|
5469
|
+
try {
|
|
5470
|
+
response = await fetch(url, {
|
|
5471
|
+
method: "POST",
|
|
5472
|
+
headers: { "content-type": "application/json" },
|
|
5473
|
+
body: JSON.stringify({ event })
|
|
5474
|
+
});
|
|
5475
|
+
} catch (err) {
|
|
5476
|
+
throw new DvmBuyJobError(
|
|
5477
|
+
`could not reach the DVM at ${url}: ${err instanceof Error ? err.message : String(err)}`
|
|
5478
|
+
);
|
|
5479
|
+
}
|
|
5480
|
+
let body;
|
|
5481
|
+
try {
|
|
5482
|
+
body = await response.json();
|
|
5483
|
+
} catch {
|
|
5484
|
+
throw new DvmBuyJobError(
|
|
5485
|
+
`the DVM at ${url} returned a non-JSON response (HTTP ${response.status})`
|
|
5486
|
+
);
|
|
5487
|
+
}
|
|
5488
|
+
if (!response.ok || body.accept !== true) {
|
|
5489
|
+
throw new DvmBuyJobError(
|
|
5490
|
+
`the DVM rejected the kind:${ARNS_BUY_JOB_KIND} buy job (HTTP ${response.status}${body.code ? `, ${body.code}` : ""})${body.message ? `: ${body.message}` : ""}`
|
|
5491
|
+
);
|
|
5492
|
+
}
|
|
5493
|
+
const registryTxId = body.result?.registryTxId;
|
|
5494
|
+
if (typeof registryTxId !== "string" || registryTxId.length === 0) {
|
|
5495
|
+
throw new DvmBuyJobError(
|
|
5496
|
+
`the DVM accepted the job but returned no registryTxId \u2014 response: ` + JSON.stringify(body.result ?? null)
|
|
5497
|
+
);
|
|
5498
|
+
}
|
|
5499
|
+
return {
|
|
5500
|
+
registryTxId,
|
|
5501
|
+
quotedMario: typeof body.result?.quotedMario === "string" ? body.result.quotedMario : null,
|
|
5502
|
+
syncAttributesTxId: typeof body.result?.syncAttributesTxId === "string" ? body.result.syncAttributesTxId : null
|
|
5503
|
+
};
|
|
5504
|
+
};
|
|
5505
|
+
var GAS_STATION_JOB_KIND = 5096;
|
|
5506
|
+
var GasStationJobError = class extends Error {
|
|
5507
|
+
constructor(reason, message) {
|
|
5508
|
+
super(message);
|
|
5509
|
+
this.reason = reason;
|
|
5510
|
+
this.name = "GasStationJobError";
|
|
5511
|
+
}
|
|
5512
|
+
reason;
|
|
5513
|
+
};
|
|
5514
|
+
async function postGasStationJob(viaUrl, params, nostrSecretKey) {
|
|
5515
|
+
const { finalizeEvent } = await import("nostr-tools/pure");
|
|
5516
|
+
const event = finalizeEvent(
|
|
5517
|
+
{
|
|
5518
|
+
kind: GAS_STATION_JOB_KIND,
|
|
5519
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
5520
|
+
content: "",
|
|
5521
|
+
tags: params.map(([k, v]) => ["param", k, v])
|
|
5522
|
+
},
|
|
5523
|
+
nostrSecretKey
|
|
5524
|
+
);
|
|
5525
|
+
const url = `${viaUrl.replace(/\/+$/, "")}/store`;
|
|
5526
|
+
let response;
|
|
5527
|
+
try {
|
|
5528
|
+
response = await fetch(url, {
|
|
5529
|
+
method: "POST",
|
|
5530
|
+
headers: { "content-type": "application/json" },
|
|
5531
|
+
body: JSON.stringify({ event })
|
|
5532
|
+
});
|
|
5533
|
+
} catch (err) {
|
|
5534
|
+
throw new GasStationJobError(
|
|
5535
|
+
"unreachable",
|
|
5536
|
+
`could not reach the DVM at ${url}: ${err instanceof Error ? err.message : String(err)}`
|
|
5537
|
+
);
|
|
5538
|
+
}
|
|
5539
|
+
let body;
|
|
5540
|
+
try {
|
|
5541
|
+
body = await response.json();
|
|
5542
|
+
} catch {
|
|
5543
|
+
throw new GasStationJobError(
|
|
5544
|
+
"bad_response",
|
|
5545
|
+
`the DVM at ${url} returned a non-JSON response (HTTP ${response.status})`
|
|
5546
|
+
);
|
|
5547
|
+
}
|
|
5548
|
+
if (!response.ok || body.accept !== true || !body.result) {
|
|
5549
|
+
throw new GasStationJobError(
|
|
5550
|
+
String(body.code ?? "rejected"),
|
|
5551
|
+
`the DVM rejected the kind:${GAS_STATION_JOB_KIND} job (HTTP ${response.status}${body.code ? `, ${body.code}` : ""})${body.message ? `: ${body.message}` : ""}`
|
|
5552
|
+
);
|
|
5553
|
+
}
|
|
5554
|
+
const result = body.result;
|
|
5555
|
+
if (result["status"] === "failed") {
|
|
5556
|
+
throw new GasStationJobError(
|
|
5557
|
+
String(result["reason"] ?? "failed"),
|
|
5558
|
+
`gas-station job failed: ${String(result["reason"] ?? "unknown")} \u2014 ${String(result["detail"] ?? "")}`
|
|
5559
|
+
);
|
|
5560
|
+
}
|
|
5561
|
+
return result;
|
|
5562
|
+
}
|
|
5563
|
+
var defaultGasStationClient = {
|
|
5564
|
+
quote: async (args) => {
|
|
5565
|
+
const result = await postGasStationJob(
|
|
5566
|
+
args.viaUrl,
|
|
5567
|
+
[
|
|
5568
|
+
["phase", "quote"],
|
|
5569
|
+
...args.transaction !== void 0 ? [["transaction", args.transaction]] : []
|
|
5570
|
+
],
|
|
5571
|
+
args.nostrSecretKey
|
|
5572
|
+
);
|
|
5573
|
+
const { quoteId, feePayer, maxLamports, recentBlockhash, expiresAt } = result;
|
|
5574
|
+
if (typeof quoteId !== "string" || typeof feePayer !== "string" || typeof maxLamports !== "string" || typeof recentBlockhash !== "string" || typeof expiresAt !== "number") {
|
|
5575
|
+
throw new GasStationJobError(
|
|
5576
|
+
"bad_response",
|
|
5577
|
+
`the DVM quote is missing fields: ${JSON.stringify(result)}`
|
|
5578
|
+
);
|
|
5579
|
+
}
|
|
5580
|
+
return { quoteId, feePayer, maxLamports, recentBlockhash, expiresAt };
|
|
5581
|
+
},
|
|
5582
|
+
execute: async (args) => {
|
|
5583
|
+
const result = await postGasStationJob(
|
|
5584
|
+
args.viaUrl,
|
|
5585
|
+
[
|
|
5586
|
+
["phase", "execute"],
|
|
5587
|
+
["transaction", args.transaction],
|
|
5588
|
+
["quoteId", args.quoteId],
|
|
5589
|
+
["idempotencyKey", args.idempotencyKey]
|
|
5590
|
+
],
|
|
5591
|
+
args.nostrSecretKey
|
|
5592
|
+
);
|
|
5593
|
+
const signature = result["signature"];
|
|
5594
|
+
if (typeof signature !== "string" || signature.length === 0) {
|
|
5595
|
+
throw new GasStationJobError(
|
|
5596
|
+
"bad_response",
|
|
5597
|
+
`the DVM execute result carries no signature: ${JSON.stringify(result)}`
|
|
5598
|
+
);
|
|
5599
|
+
}
|
|
5600
|
+
return {
|
|
5601
|
+
signature,
|
|
5602
|
+
slot: typeof result["slot"] === "string" ? result["slot"] : null,
|
|
5603
|
+
feeLamportsActual: typeof result["feeLamportsActual"] === "string" ? result["feeLamportsActual"] : null,
|
|
5604
|
+
...result["replayed"] === true ? { replayed: true } : {}
|
|
5605
|
+
};
|
|
5606
|
+
}
|
|
5607
|
+
};
|
|
5254
5608
|
var NAME_USAGE = `Usage: rig name <buy|set|status> <name> [options]
|
|
5255
5609
|
|
|
5256
5610
|
ArNS naming for Arweave-served artifacts. A name registered on the ar.io
|
|
@@ -5263,14 +5617,21 @@ mnemonic that pays for pushes (derived at m/44'/501'/0'/0'). Fund it with
|
|
|
5263
5617
|
registry program \u2014 NOT through TOON ILP payment channels.
|
|
5264
5618
|
|
|
5265
5619
|
Commands:
|
|
5266
|
-
name buy <name> [--years n | --permabuy]
|
|
5620
|
+
name buy <name> [--years n | --permabuy] [--via <dvm-url>]
|
|
5267
5621
|
quote (mARIO) \u2192 confirm \u2192 register. The spawned ANT is
|
|
5268
5622
|
owned by this identity's Solana key. Default: 1-year
|
|
5269
5623
|
lease. PAID \u2014 spends mARIO from the Solana wallet.
|
|
5270
|
-
|
|
5624
|
+
With --via: BROKERED \u2014 this identity spawns and owns
|
|
5625
|
+
the ANT (dust SOL only), then a store DVM executes the
|
|
5626
|
+
kind:5095 buy job and pays the mARIO from ITS wallet;
|
|
5627
|
+
the name is owned by your ANT from inception.
|
|
5628
|
+
name set <name> <txId> [--undername <sub>] [--ttl <seconds>] [--via <dvm-url>]
|
|
5271
5629
|
point the name (or an undername) at an Arweave txId
|
|
5272
5630
|
(typically a deployed path manifest). Signs an ANT
|
|
5273
|
-
record update with the Solana key.
|
|
5631
|
+
record update with the Solana key. With --via: the
|
|
5632
|
+
gas-station path (kind:5096) \u2014 you author and
|
|
5633
|
+
partial-sign, the DVM co-signs as fee payer and pays
|
|
5634
|
+
the lamports; needs ZERO SOL in this wallet.
|
|
5274
5635
|
name status <name> FREE: registry record (lease/permabuy, expiry), ANT
|
|
5275
5636
|
process id, current target txId(s), TTL, undernames.
|
|
5276
5637
|
|
|
@@ -5281,11 +5642,18 @@ Options:
|
|
|
5281
5642
|
--undername <sub> target the undername <sub>_<name> instead of the base
|
|
5282
5643
|
name (set)
|
|
5283
5644
|
--ttl <seconds> record TTL in seconds (set; default 3600)
|
|
5284
|
-
--network <net>
|
|
5285
|
-
|
|
5645
|
+
--network <net> cluster: mainnet | devnet (default mainnet; or
|
|
5646
|
+
RIG_ARIO_NETWORK). ar.io has no Solana-testnet
|
|
5647
|
+
deployment. Non-mainnet gateway resolution is
|
|
5286
5648
|
unverified.
|
|
5287
|
-
--process-id <id> explicit registry
|
|
5288
|
-
RIG_ARIO_PROCESS_ID)
|
|
5649
|
+
--process-id <id> explicit ArNS registry program id \u2014 a Solana program
|
|
5650
|
+
address (overrides --network; or RIG_ARIO_PROCESS_ID)
|
|
5651
|
+
--via <dvm-url> buy only: broker the purchase through a store DVM's
|
|
5652
|
+
kind:5095 job endpoint (or RIG_ARNS_DVM_URL). The DVM
|
|
5653
|
+
pays the mARIO; you own the name via your spawned ANT.
|
|
5654
|
+
Direct backend targeting stubs the job payment
|
|
5655
|
+
(dev/e2e) \u2014 the paid path runs the same job through
|
|
5656
|
+
the connector payment proxy.
|
|
5289
5657
|
--yes skip the confirmation (required when not a TTY) for
|
|
5290
5658
|
buy/set
|
|
5291
5659
|
--json machine-readable envelope; for buy/set without --yes it
|
|
@@ -5293,8 +5661,8 @@ Options:
|
|
|
5293
5661
|
-h, --help show this help`;
|
|
5294
5662
|
var DEFAULT_TTL_SECONDS = 3600;
|
|
5295
5663
|
var DEFAULT_LEASE_YEARS = 1;
|
|
5296
|
-
var NETWORKS = ["mainnet", "devnet"
|
|
5297
|
-
async function resolveNameContext(deps, network, processId) {
|
|
5664
|
+
var NETWORKS = ["mainnet", "devnet"];
|
|
5665
|
+
async function resolveNameContext(deps, network, processId, mode) {
|
|
5298
5666
|
const { io: io2, env } = deps;
|
|
5299
5667
|
const resolved = await resolveIdentity({
|
|
5300
5668
|
env,
|
|
@@ -5318,12 +5686,17 @@ async function resolveNameContext(deps, network, processId) {
|
|
|
5318
5686
|
);
|
|
5319
5687
|
}
|
|
5320
5688
|
const sdk = await (deps.loadArns ?? defaultLoadArns)({
|
|
5689
|
+
mode,
|
|
5321
5690
|
solanaSecretKey: derived.solana.secretKey,
|
|
5322
5691
|
solanaPublicKey: solanaAddress,
|
|
5323
5692
|
network,
|
|
5324
5693
|
...processId !== void 0 ? { processId } : {}
|
|
5325
5694
|
});
|
|
5326
|
-
|
|
5695
|
+
const nostrSecretKey = client.deriveNostrKeyFromMnemonic(
|
|
5696
|
+
resolved.mnemonic,
|
|
5697
|
+
resolved.accountIndex
|
|
5698
|
+
).secretKey;
|
|
5699
|
+
return { identity, solanaAddress, network, processId, sdk, nostrSecretKey };
|
|
5327
5700
|
}
|
|
5328
5701
|
function parseNameFlags(args, env) {
|
|
5329
5702
|
const { values, positionals } = parseArgs13({
|
|
@@ -5336,19 +5709,31 @@ function parseNameFlags(args, env) {
|
|
|
5336
5709
|
ttl: { type: "string" },
|
|
5337
5710
|
network: { type: "string" },
|
|
5338
5711
|
"process-id": { type: "string" },
|
|
5712
|
+
via: { type: "string" },
|
|
5339
5713
|
yes: { type: "boolean", default: false },
|
|
5340
5714
|
json: { type: "boolean", default: false },
|
|
5341
5715
|
help: { type: "boolean", short: "h", default: false }
|
|
5342
5716
|
}
|
|
5343
5717
|
});
|
|
5344
5718
|
if (values.help) {
|
|
5345
|
-
return {
|
|
5719
|
+
return {
|
|
5720
|
+
positionals: ["--help"],
|
|
5721
|
+
flags: {
|
|
5722
|
+
permabuy: false,
|
|
5723
|
+
ttl: 0,
|
|
5724
|
+
network: "mainnet",
|
|
5725
|
+
yes: false,
|
|
5726
|
+
json: false
|
|
5727
|
+
}
|
|
5728
|
+
};
|
|
5346
5729
|
}
|
|
5347
5730
|
let years;
|
|
5348
5731
|
if (values.years !== void 0) {
|
|
5349
5732
|
years = Number(values.years);
|
|
5350
5733
|
if (!Number.isInteger(years) || years <= 0) {
|
|
5351
|
-
throw new Error(
|
|
5734
|
+
throw new Error(
|
|
5735
|
+
`--years must be a positive integer, got ${JSON.stringify(values.years)}`
|
|
5736
|
+
);
|
|
5352
5737
|
}
|
|
5353
5738
|
}
|
|
5354
5739
|
if (years !== void 0 && values.permabuy) {
|
|
@@ -5358,14 +5743,28 @@ function parseNameFlags(args, env) {
|
|
|
5358
5743
|
if (values.ttl !== void 0) {
|
|
5359
5744
|
ttl = Number(values.ttl);
|
|
5360
5745
|
if (!Number.isInteger(ttl) || ttl <= 0) {
|
|
5361
|
-
throw new Error(
|
|
5746
|
+
throw new Error(
|
|
5747
|
+
`--ttl must be a positive integer number of seconds, got ${JSON.stringify(values.ttl)}`
|
|
5748
|
+
);
|
|
5362
5749
|
}
|
|
5363
5750
|
}
|
|
5364
5751
|
const networkRaw = values.network ?? env["RIG_ARIO_NETWORK"] ?? "mainnet";
|
|
5365
5752
|
if (!NETWORKS.includes(networkRaw)) {
|
|
5366
|
-
throw new Error(
|
|
5753
|
+
throw new Error(
|
|
5754
|
+
`--network must be one of ${NETWORKS.join(" | ")}, got ${JSON.stringify(networkRaw)}`
|
|
5755
|
+
);
|
|
5367
5756
|
}
|
|
5368
5757
|
const processId = values["process-id"] ?? env["RIG_ARIO_PROCESS_ID"];
|
|
5758
|
+
const viaRaw = values.via ?? env["RIG_ARNS_DVM_URL"];
|
|
5759
|
+
let via;
|
|
5760
|
+
if (viaRaw !== void 0) {
|
|
5761
|
+
if (!/^https?:\/\/.+/.test(viaRaw)) {
|
|
5762
|
+
throw new Error(
|
|
5763
|
+
`--via must be an http(s) DVM endpoint URL, got ${JSON.stringify(viaRaw)}`
|
|
5764
|
+
);
|
|
5765
|
+
}
|
|
5766
|
+
via = viaRaw;
|
|
5767
|
+
}
|
|
5369
5768
|
return {
|
|
5370
5769
|
positionals,
|
|
5371
5770
|
flags: {
|
|
@@ -5375,6 +5774,7 @@ function parseNameFlags(args, env) {
|
|
|
5375
5774
|
ttl,
|
|
5376
5775
|
network: networkRaw,
|
|
5377
5776
|
...processId !== void 0 ? { processId } : {},
|
|
5777
|
+
...via !== void 0 ? { via } : {},
|
|
5378
5778
|
yes: values.yes ?? false,
|
|
5379
5779
|
json: values.json ?? false
|
|
5380
5780
|
}
|
|
@@ -5384,7 +5784,12 @@ async function runBuy(name, flags, deps) {
|
|
|
5384
5784
|
const { io: io2 } = deps;
|
|
5385
5785
|
const type = flags.permabuy ? "permabuy" : "lease";
|
|
5386
5786
|
const years = type === "lease" ? flags.years ?? DEFAULT_LEASE_YEARS : null;
|
|
5387
|
-
const ctx = await resolveNameContext(
|
|
5787
|
+
const ctx = await resolveNameContext(
|
|
5788
|
+
deps,
|
|
5789
|
+
flags.network,
|
|
5790
|
+
flags.processId,
|
|
5791
|
+
"read"
|
|
5792
|
+
);
|
|
5388
5793
|
const mario = await ctx.sdk.getTokenCost({
|
|
5389
5794
|
intent: "Buy-Name",
|
|
5390
5795
|
name,
|
|
@@ -5395,6 +5800,8 @@ async function runBuy(name, flags, deps) {
|
|
|
5395
5800
|
mARIO: mario.toString(),
|
|
5396
5801
|
ARIO: formatUnits(mario.toString(), ARIO_DECIMALS)
|
|
5397
5802
|
};
|
|
5803
|
+
const via = flags.via ?? null;
|
|
5804
|
+
const paymentNote = via === null ? MARIO_PAYMENT_NOTE : DVM_PAYMENT_NOTE;
|
|
5398
5805
|
const buildJson = (executed, extra = {}) => ({
|
|
5399
5806
|
command: "name",
|
|
5400
5807
|
action: "buy",
|
|
@@ -5403,46 +5810,100 @@ async function runBuy(name, flags, deps) {
|
|
|
5403
5810
|
years,
|
|
5404
5811
|
network: ctx.network,
|
|
5405
5812
|
processId: ctx.processId ?? null,
|
|
5813
|
+
via,
|
|
5406
5814
|
identity: ctx.identity,
|
|
5407
5815
|
solanaAddress: ctx.solanaAddress,
|
|
5408
5816
|
quote,
|
|
5409
|
-
payment:
|
|
5817
|
+
payment: paymentNote,
|
|
5410
5818
|
executed,
|
|
5411
5819
|
...extra
|
|
5412
5820
|
});
|
|
5413
5821
|
if (!flags.json) {
|
|
5414
5822
|
io2.out(
|
|
5415
|
-
`Buy ArNS name "${name}" \u2014 ${type}` + (years !== null ? ` (${years} year${years === 1 ? "" : "s"})` : "") + ` on ${ctx.network}`
|
|
5823
|
+
`Buy ArNS name "${name}" \u2014 ${type}` + (years !== null ? ` (${years} year${years === 1 ? "" : "s"})` : "") + ` on ${ctx.network}` + (via !== null ? ` \u2014 brokered via DVM ${via}` : "")
|
|
5824
|
+
);
|
|
5825
|
+
io2.out(
|
|
5826
|
+
via === null ? ` Cost: ${renderMario(mario)}` : ` Name cost (paid by the DVM): ${renderMario(mario)}`
|
|
5416
5827
|
);
|
|
5417
|
-
io2.out(` Cost: ${renderMario(mario)}`);
|
|
5418
5828
|
io2.out(` Solana wallet: ${ctx.solanaAddress}`);
|
|
5419
|
-
io2.out(` ${
|
|
5829
|
+
io2.out(` ${paymentNote}`);
|
|
5420
5830
|
io2.out(renderIdentityLine(ctx.identity));
|
|
5421
5831
|
}
|
|
5422
5832
|
if (!flags.yes) {
|
|
5423
5833
|
if (flags.json) {
|
|
5424
5834
|
io2.emitJson(
|
|
5425
5835
|
buildJson(false, {
|
|
5426
|
-
hint: "estimate only \u2014 re-run with --yes to buy (spends mARIO on Solana, non-refundable)"
|
|
5836
|
+
hint: via === null ? "estimate only \u2014 re-run with --yes to buy (spends mARIO on Solana, non-refundable)" : "estimate only \u2014 re-run with --yes to spawn your ANT and submit the kind:5095 buy job to the DVM"
|
|
5427
5837
|
})
|
|
5428
5838
|
);
|
|
5429
5839
|
return 0;
|
|
5430
5840
|
}
|
|
5431
5841
|
if (!io2.isInteractive) {
|
|
5432
5842
|
io2.err(
|
|
5433
|
-
"refusing to spend mARIO without confirmation in a non-interactive session \u2014 re-run with --yes (or use --json for a pure estimate)"
|
|
5843
|
+
via === null ? "refusing to spend mARIO without confirmation in a non-interactive session \u2014 re-run with --yes (or use --json for a pure estimate)" : "refusing to spawn an ANT and submit a paid DVM job without confirmation in a non-interactive session \u2014 re-run with --yes (or use --json for a pure estimate)"
|
|
5434
5844
|
);
|
|
5435
5845
|
return 1;
|
|
5436
5846
|
}
|
|
5437
5847
|
const proceed = await io2.confirm(
|
|
5438
|
-
`Proceed \u2014 buy "${name}" for ${renderMario(mario)} from your Solana wallet? [y/N] `
|
|
5848
|
+
via === null ? `Proceed \u2014 buy "${name}" for ${renderMario(mario)} from your Solana wallet? [y/N] ` : `Proceed \u2014 spawn your ANT and have the DVM at ${via} buy "${name}" for ${renderMario(mario)} from ITS wallet? [y/N] `
|
|
5439
5849
|
);
|
|
5440
5850
|
if (!proceed) {
|
|
5441
5851
|
io2.err("aborted \u2014 nothing was bought or paid.");
|
|
5442
5852
|
return 1;
|
|
5443
5853
|
}
|
|
5444
5854
|
}
|
|
5445
|
-
const
|
|
5855
|
+
const signed = await resolveNameContext(
|
|
5856
|
+
deps,
|
|
5857
|
+
flags.network,
|
|
5858
|
+
flags.processId,
|
|
5859
|
+
"write"
|
|
5860
|
+
);
|
|
5861
|
+
if (via !== null) {
|
|
5862
|
+
const spawn2 = await signed.sdk.spawnAnt({ name });
|
|
5863
|
+
if (!flags.json) {
|
|
5864
|
+
io2.out(`Spawned ANT ${spawn2.processId} (tx ${spawn2.signature})`);
|
|
5865
|
+
}
|
|
5866
|
+
const submit = deps.submitDvmBuyJob ?? defaultSubmitDvmBuyJob;
|
|
5867
|
+
const receipt2 = await submit({
|
|
5868
|
+
viaUrl: via,
|
|
5869
|
+
name,
|
|
5870
|
+
type,
|
|
5871
|
+
years,
|
|
5872
|
+
processId: spawn2.processId,
|
|
5873
|
+
nostrSecretKey: signed.nostrSecretKey
|
|
5874
|
+
});
|
|
5875
|
+
const result2 = {
|
|
5876
|
+
registryTxId: receipt2.registryTxId,
|
|
5877
|
+
antProcessId: spawn2.processId,
|
|
5878
|
+
syncAttributesTxId: receipt2.syncAttributesTxId,
|
|
5879
|
+
dvmQuotedMario: receipt2.quotedMario
|
|
5880
|
+
};
|
|
5881
|
+
if (flags.json) {
|
|
5882
|
+
io2.emitJson(
|
|
5883
|
+
buildJson(true, {
|
|
5884
|
+
spawn: { processId: spawn2.processId, signature: spawn2.signature },
|
|
5885
|
+
result: result2
|
|
5886
|
+
})
|
|
5887
|
+
);
|
|
5888
|
+
} else {
|
|
5889
|
+
io2.out(
|
|
5890
|
+
`Registered "${name}" via the DVM \u2014 registry tx ${result2.registryTxId}`
|
|
5891
|
+
);
|
|
5892
|
+
io2.out(` ANT process (owned by YOU): ${spawn2.processId}`);
|
|
5893
|
+
if (receipt2.syncAttributesTxId) {
|
|
5894
|
+
io2.out(` Trait sync: ${receipt2.syncAttributesTxId}`);
|
|
5895
|
+
} else {
|
|
5896
|
+
io2.out(
|
|
5897
|
+
" Trait sync: not run by the DVM (holder-gated on this deployment) \u2014 as the ANT holder you can reconcile with syncAttributes later; resolution works regardless."
|
|
5898
|
+
);
|
|
5899
|
+
}
|
|
5900
|
+
io2.out(
|
|
5901
|
+
`Point it at content with \`rig name set ${name} <txId>\`, then it resolves at https://${name}.<gateway>/`
|
|
5902
|
+
);
|
|
5903
|
+
}
|
|
5904
|
+
return 0;
|
|
5905
|
+
}
|
|
5906
|
+
const receipt = await signed.sdk.buyRecord({
|
|
5446
5907
|
name,
|
|
5447
5908
|
type,
|
|
5448
5909
|
...years !== null ? { years } : {}
|
|
@@ -5464,7 +5925,12 @@ async function runBuy(name, flags, deps) {
|
|
|
5464
5925
|
}
|
|
5465
5926
|
async function runSet(name, txId, flags, deps) {
|
|
5466
5927
|
const { io: io2 } = deps;
|
|
5467
|
-
const ctx = await resolveNameContext(
|
|
5928
|
+
const ctx = await resolveNameContext(
|
|
5929
|
+
deps,
|
|
5930
|
+
flags.network,
|
|
5931
|
+
flags.processId,
|
|
5932
|
+
"read"
|
|
5933
|
+
);
|
|
5468
5934
|
const record = await ctx.sdk.getArNSRecord({ name });
|
|
5469
5935
|
if (!record || !record.processId) {
|
|
5470
5936
|
throw new Error(
|
|
@@ -5473,6 +5939,7 @@ async function runSet(name, txId, flags, deps) {
|
|
|
5473
5939
|
}
|
|
5474
5940
|
const antProcessId = record.processId;
|
|
5475
5941
|
const undername = flags.undername ?? null;
|
|
5942
|
+
const via = flags.via ?? null;
|
|
5476
5943
|
const buildJson = (executed, extra = {}) => ({
|
|
5477
5944
|
command: "name",
|
|
5478
5945
|
action: "set",
|
|
@@ -5482,6 +5949,7 @@ async function runSet(name, txId, flags, deps) {
|
|
|
5482
5949
|
ttl: flags.ttl,
|
|
5483
5950
|
network: ctx.network,
|
|
5484
5951
|
processId: ctx.processId ?? null,
|
|
5952
|
+
via,
|
|
5485
5953
|
identity: ctx.identity,
|
|
5486
5954
|
solanaAddress: ctx.solanaAddress,
|
|
5487
5955
|
antProcessId,
|
|
@@ -5490,16 +5958,23 @@ async function runSet(name, txId, flags, deps) {
|
|
|
5490
5958
|
});
|
|
5491
5959
|
const targetLabel = undername ? `undername "${undername}_${name}"` : `base name "${name}"`;
|
|
5492
5960
|
if (!flags.json) {
|
|
5493
|
-
io2.out(
|
|
5961
|
+
io2.out(
|
|
5962
|
+
`Set ${targetLabel} \u2192 txId ${txId} (ttl ${flags.ttl}s) on ${ctx.network}` + (via !== null ? ` \u2014 gas paid by the DVM at ${via} (kind:5096)` : "")
|
|
5963
|
+
);
|
|
5494
5964
|
io2.out(` ANT process: ${antProcessId}`);
|
|
5495
5965
|
io2.out(` Signed by the identity's Solana key (${ctx.solanaAddress}).`);
|
|
5966
|
+
if (via !== null) {
|
|
5967
|
+
io2.out(
|
|
5968
|
+
" Gas station: you author + partial-sign the record update; the DVM co-signs as fee payer and pays the lamports (toon-meta#163). Direct backend targeting stubs the job payment (dev/e2e)."
|
|
5969
|
+
);
|
|
5970
|
+
}
|
|
5496
5971
|
io2.out(renderIdentityLine(ctx.identity));
|
|
5497
5972
|
}
|
|
5498
5973
|
if (!flags.yes) {
|
|
5499
5974
|
if (flags.json) {
|
|
5500
5975
|
io2.emitJson(
|
|
5501
5976
|
buildJson(false, {
|
|
5502
|
-
hint: "estimate only \u2014 re-run with --yes to write the ANT record"
|
|
5977
|
+
hint: via === null ? "estimate only \u2014 re-run with --yes to write the ANT record" : "estimate only \u2014 re-run with --yes to quote the gas-station and write the ANT record (DVM pays the gas)"
|
|
5503
5978
|
})
|
|
5504
5979
|
);
|
|
5505
5980
|
return 0;
|
|
@@ -5511,28 +5986,90 @@ async function runSet(name, txId, flags, deps) {
|
|
|
5511
5986
|
return 1;
|
|
5512
5987
|
}
|
|
5513
5988
|
const proceed = await io2.confirm(
|
|
5514
|
-
`Proceed \u2014 point ${targetLabel} at ${txId}? [y/N]
|
|
5989
|
+
`Proceed \u2014 point ${targetLabel} at ${txId}?` + (via !== null ? " (the DVM pays the gas)" : "") + " [y/N] "
|
|
5515
5990
|
);
|
|
5516
5991
|
if (!proceed) {
|
|
5517
5992
|
io2.err("aborted \u2014 the ANT record was not changed.");
|
|
5518
5993
|
return 1;
|
|
5519
5994
|
}
|
|
5520
5995
|
}
|
|
5521
|
-
const
|
|
5522
|
-
|
|
5996
|
+
const signed = await resolveNameContext(
|
|
5997
|
+
deps,
|
|
5998
|
+
flags.network,
|
|
5999
|
+
flags.processId,
|
|
6000
|
+
"write"
|
|
6001
|
+
);
|
|
6002
|
+
if (via !== null) {
|
|
6003
|
+
const gas = deps.gasStation ?? defaultGasStationClient;
|
|
6004
|
+
const quote = await gas.quote({
|
|
6005
|
+
viaUrl: via,
|
|
6006
|
+
nostrSecretKey: signed.nostrSecretKey
|
|
6007
|
+
});
|
|
6008
|
+
const wireTx = await signed.sdk.buildSetRecordTransaction({
|
|
6009
|
+
antProcessId,
|
|
6010
|
+
undername: undername ?? "@",
|
|
6011
|
+
transactionId: txId,
|
|
6012
|
+
ttlSeconds: flags.ttl,
|
|
6013
|
+
feePayer: quote.feePayer,
|
|
6014
|
+
recentBlockhash: quote.recentBlockhash
|
|
6015
|
+
});
|
|
6016
|
+
const executed = await gas.execute({
|
|
6017
|
+
viaUrl: via,
|
|
6018
|
+
transaction: wireTx,
|
|
6019
|
+
quoteId: quote.quoteId,
|
|
6020
|
+
idempotencyKey: randomUUID(),
|
|
6021
|
+
nostrSecretKey: signed.nostrSecretKey
|
|
6022
|
+
});
|
|
6023
|
+
const gasStation = {
|
|
6024
|
+
quoteId: quote.quoteId,
|
|
6025
|
+
feePayer: quote.feePayer,
|
|
6026
|
+
maxLamports: quote.maxLamports,
|
|
6027
|
+
expiresAt: quote.expiresAt,
|
|
6028
|
+
feeLamportsActual: executed.feeLamportsActual
|
|
6029
|
+
};
|
|
6030
|
+
const result2 = { messageId: executed.signature };
|
|
6031
|
+
if (flags.json) {
|
|
6032
|
+
io2.emitJson(buildJson(true, { gasStation, result: result2 }));
|
|
6033
|
+
} else {
|
|
6034
|
+
io2.out(
|
|
6035
|
+
`Updated \u2014 record-set tx ${executed.signature} (gas paid by ${quote.feePayer})`
|
|
6036
|
+
);
|
|
6037
|
+
const host = undername ? `${undername}_${name}` : name;
|
|
6038
|
+
io2.out(
|
|
6039
|
+
` Resolves at https://${host}.<gateway>/ (allow for gateway cache/TTL).`
|
|
6040
|
+
);
|
|
6041
|
+
}
|
|
6042
|
+
return 0;
|
|
6043
|
+
}
|
|
6044
|
+
const ant = await signed.sdk.ant(antProcessId);
|
|
6045
|
+
const receipt = undername ? await ant.setUndernameRecord({
|
|
6046
|
+
undername,
|
|
6047
|
+
transactionId: txId,
|
|
6048
|
+
ttlSeconds: flags.ttl
|
|
6049
|
+
}) : await ant.setBaseNameRecord({
|
|
6050
|
+
transactionId: txId,
|
|
6051
|
+
ttlSeconds: flags.ttl
|
|
6052
|
+
});
|
|
5523
6053
|
const result = { messageId: receipt.id };
|
|
5524
6054
|
if (flags.json) {
|
|
5525
6055
|
io2.emitJson(buildJson(true, { result }));
|
|
5526
6056
|
} else {
|
|
5527
6057
|
io2.out(`Updated \u2014 ANT message ${result.messageId}`);
|
|
5528
6058
|
const host = undername ? `${undername}_${name}` : name;
|
|
5529
|
-
io2.out(
|
|
6059
|
+
io2.out(
|
|
6060
|
+
` Resolves at https://${host}.<gateway>/ (allow for gateway cache/TTL).`
|
|
6061
|
+
);
|
|
5530
6062
|
}
|
|
5531
6063
|
return 0;
|
|
5532
6064
|
}
|
|
5533
6065
|
async function runStatus(name, flags, deps) {
|
|
5534
6066
|
const { io: io2 } = deps;
|
|
5535
|
-
const ctx = await resolveNameContext(
|
|
6067
|
+
const ctx = await resolveNameContext(
|
|
6068
|
+
deps,
|
|
6069
|
+
flags.network,
|
|
6070
|
+
flags.processId,
|
|
6071
|
+
"read"
|
|
6072
|
+
);
|
|
5536
6073
|
const record = await ctx.sdk.getArNSRecord({ name });
|
|
5537
6074
|
let targets = null;
|
|
5538
6075
|
if (record?.processId) {
|
|
@@ -5580,7 +6117,9 @@ async function runStatus(name, flags, deps) {
|
|
|
5580
6117
|
io2.out(" Records:");
|
|
5581
6118
|
for (const [under, target] of Object.entries(targets)) {
|
|
5582
6119
|
const label = under === "@" ? "(base)" : `${under}_${name}`;
|
|
5583
|
-
io2.out(
|
|
6120
|
+
io2.out(
|
|
6121
|
+
` ${label} \u2192 ${target.transactionId} (ttl ${target.ttlSeconds}s)`
|
|
6122
|
+
);
|
|
5584
6123
|
}
|
|
5585
6124
|
} else {
|
|
5586
6125
|
io2.out(" Records: none set \u2014 point one with `rig name set`.");
|
|
@@ -5630,7 +6169,9 @@ async function runName(args, deps) {
|
|
|
5630
6169
|
if (sub === "status") return await runStatus(name, flags, deps);
|
|
5631
6170
|
const txId = positionals[1];
|
|
5632
6171
|
if (txId === void 0) {
|
|
5633
|
-
io2.err(
|
|
6172
|
+
io2.err(
|
|
6173
|
+
"`rig name set` needs a <txId> (the Arweave transaction to point at)"
|
|
6174
|
+
);
|
|
5634
6175
|
io2.err(NAME_USAGE);
|
|
5635
6176
|
return 2;
|
|
5636
6177
|
}
|