@heyanon-arp/cli 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +159 -34
- package/dist/cli.js.map +1 -1
- package/package.json +3 -5
- package/scripts/postinstall.mjs +0 -55
package/dist/cli.js
CHANGED
|
@@ -643,6 +643,22 @@ function formatGenericError(err, verbose = false) {
|
|
|
643
643
|
return `${import_chalk.default.red("Error")} ${message}
|
|
644
644
|
${import_chalk.default.gray(err.stack)}`;
|
|
645
645
|
}
|
|
646
|
+
function onboardingHelpFooter() {
|
|
647
|
+
return [
|
|
648
|
+
"",
|
|
649
|
+
"New here? The guides ship inside the CLI \u2014 read them first, no docs site needed:",
|
|
650
|
+
` ${import_chalk.default.cyan("heyarp guide")} ${import_chalk.default.dim("role-based walkthrough (worker / buyer)")}`,
|
|
651
|
+
` ${import_chalk.default.cyan("heyarp guide --setup")} ${import_chalk.default.dim("one-time setup: keys, server, multi-agent isolation")}`,
|
|
652
|
+
` ${import_chalk.default.cyan("heyarp guide --troubleshoot")} ${import_chalk.default.dim("common errors \u2192 fixes")}`,
|
|
653
|
+
"",
|
|
654
|
+
`${import_chalk.default.bold("Driving heyarp from an AI agent?")} Pipe YOUR role's guide into its system prompt`,
|
|
655
|
+
import_chalk.default.dim("(role is per-deal: BUYER if you send the offer + pay; WORKER if an offer comes to you):"),
|
|
656
|
+
` ${import_chalk.default.cyan("heyarp guide --role worker --format prompt")} ${import_chalk.default.dim("# you do tasks, get paid")}`,
|
|
657
|
+
` ${import_chalk.default.cyan("heyarp guide --role buyer --format prompt")} ${import_chalk.default.dim("# you order tasks, pay")}`,
|
|
658
|
+
"",
|
|
659
|
+
`${import_chalk.default.dim("Then:")} ${import_chalk.default.cyan("heyarp register")} ${import_chalk.default.dim("\u2192 handshake \u2192 delegation \u2192 work \u2192 receipt \u2192 settlement.")}`
|
|
660
|
+
].join("\n");
|
|
661
|
+
}
|
|
646
662
|
function toCliErrorJson(err, includeStack = false) {
|
|
647
663
|
const { ApiError: ApiError2 } = (init_api(), __toCommonJS(api_exports));
|
|
648
664
|
if (err instanceof ApiError2) {
|
|
@@ -3547,9 +3563,15 @@ async function readOnChainLock(api, opts, delegationId) {
|
|
|
3547
3563
|
const programId = new import_web33.PublicKey(resolved.programId);
|
|
3548
3564
|
const { lockPda } = deriveLockPda(programId, delegationId);
|
|
3549
3565
|
const conn = new import_web33.Connection(rpcUrl, "confirmed");
|
|
3550
|
-
|
|
3566
|
+
let info = await conn.getAccountInfo(lockPda);
|
|
3567
|
+
for (let attempt = 1; attempt <= LOCK_READ_NOT_VISIBLE_RETRIES && !info; attempt++) {
|
|
3568
|
+
await new Promise((r) => setTimeout(r, LOCK_READ_RETRY_DELAY_MS));
|
|
3569
|
+
info = await conn.getAccountInfo(lockPda);
|
|
3570
|
+
}
|
|
3551
3571
|
if (!info) {
|
|
3552
|
-
return {
|
|
3572
|
+
return {
|
|
3573
|
+
skipReason: `lock account ${lockPda.toBase58()} not visible on this RPC yet after ${LOCK_READ_NOT_VISIBLE_RETRIES + 1} attempts (create_lock may still be confirming / RPC lag)`
|
|
3574
|
+
};
|
|
3553
3575
|
}
|
|
3554
3576
|
const lock = decodeLockAccount(info.data);
|
|
3555
3577
|
if (!lock) {
|
|
@@ -3832,7 +3854,7 @@ async function autoSignAndDeliverPayeeSig(opts, cmdName = "receipt propose") {
|
|
|
3832
3854
|
serverTimestamp: result.serverTimestamp
|
|
3833
3855
|
};
|
|
3834
3856
|
}
|
|
3835
|
-
var import_sdk10, import_utils3, import_web33, import_chalk17, NATIVE_SOL_MINT2, SETTLEMENT_MIN_EXPIRY_HEADROOM_SECS, SETTLEMENT_REFRESH_HEADROOM_SECS;
|
|
3857
|
+
var import_sdk10, import_utils3, import_web33, import_chalk17, NATIVE_SOL_MINT2, SETTLEMENT_MIN_EXPIRY_HEADROOM_SECS, SETTLEMENT_REFRESH_HEADROOM_SECS, LOCK_READ_NOT_VISIBLE_RETRIES, LOCK_READ_RETRY_DELAY_MS;
|
|
3836
3858
|
var init_settlement = __esm({
|
|
3837
3859
|
"src/commands/settlement.ts"() {
|
|
3838
3860
|
import_sdk10 = require("@heyanon-arp/sdk");
|
|
@@ -3852,6 +3874,8 @@ var init_settlement = __esm({
|
|
|
3852
3874
|
NATIVE_SOL_MINT2 = "11111111111111111111111111111111";
|
|
3853
3875
|
SETTLEMENT_MIN_EXPIRY_HEADROOM_SECS = 120;
|
|
3854
3876
|
SETTLEMENT_REFRESH_HEADROOM_SECS = 600;
|
|
3877
|
+
LOCK_READ_NOT_VISIBLE_RETRIES = 3;
|
|
3878
|
+
LOCK_READ_RETRY_DELAY_MS = 2e3;
|
|
3855
3879
|
}
|
|
3856
3880
|
});
|
|
3857
3881
|
|
|
@@ -3907,6 +3931,14 @@ function registerPropose(parent) {
|
|
|
3907
3931
|
await runPropose(recipientDid, delegationId, requestHash, responseHash, opts);
|
|
3908
3932
|
} catch (err) {
|
|
3909
3933
|
emitActionError(err, cmd);
|
|
3934
|
+
if (!opts.json && err instanceof ApiError && err.payload.code === "RECEIPT_ALREADY_EXISTS") {
|
|
3935
|
+
console.error(
|
|
3936
|
+
import_chalk18.default.dim(
|
|
3937
|
+
` This receipt already exists (a prior propose committed it). Do NOT re-propose \u2014 to (re)deliver the payee settlement signature, run:
|
|
3938
|
+
'heyarp receipt send-payee-sig ${recipientDid} --delegation-id ${delegationId} --auto --cluster-tag ${opts.clusterTag ?? "<0|1>"}'`
|
|
3939
|
+
)
|
|
3940
|
+
);
|
|
3941
|
+
}
|
|
3910
3942
|
process.exitCode = 1;
|
|
3911
3943
|
}
|
|
3912
3944
|
});
|
|
@@ -4054,7 +4086,12 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
4054
4086
|
json.settlement = {
|
|
4055
4087
|
delivered: false,
|
|
4056
4088
|
error: settlementError.message,
|
|
4057
|
-
|
|
4089
|
+
// Authoritative recovery (SR-2/SR-3): re-sign + re-deliver via
|
|
4090
|
+
// --auto, which resolves condition_hash + the on-chain lock
|
|
4091
|
+
// snapshot itself — no hand-typed hashes, no sig file, no
|
|
4092
|
+
// lock_id/condition_hash trap. Do NOT re-run `receipt propose`
|
|
4093
|
+
// (the receipt already exists; a second propose is a duplicate).
|
|
4094
|
+
recovery: `heyarp receipt send-payee-sig ${recipientDid} --delegation-id ${delegationId} --auto --cluster-tag ${opts.clusterTag ?? "<0|1>"} (do NOT re-run 'receipt propose' \u2014 the receipt already exists, a second propose is rejected as a duplicate)`
|
|
4058
4095
|
};
|
|
4059
4096
|
} else if (settlementResult) {
|
|
4060
4097
|
json.settlement = {
|
|
@@ -4079,14 +4116,9 @@ Receipt event hash: ${import_chalk18.default.cyan(result.serverEventHash)}`));
|
|
|
4079
4116
|
if (settlementError) {
|
|
4080
4117
|
console.error(import_chalk18.default.yellow("\nWARNING: receipt proposed, but the payee settlement signature was NOT delivered."));
|
|
4081
4118
|
console.error(import_chalk18.default.yellow(` reason: ${settlementError.message}`));
|
|
4082
|
-
console.error(import_chalk18.default.dim(" The receipt stays committed \u2014 re-
|
|
4083
|
-
console.error(import_chalk18.default.dim(" Recover
|
|
4084
|
-
console.error(
|
|
4085
|
-
import_chalk18.default.dim(
|
|
4086
|
-
` 'heyarp wallet sign-settlement-release ... --write-to <path>' then
|
|
4087
|
-
'heyarp receipt send-payee-sig ${recipientDid} --delegation-id ${delegationId} --receipt-event-hash ${result.serverEventHash} --sig-from-file <path> --expires-at <unix>'`
|
|
4088
|
-
)
|
|
4089
|
-
);
|
|
4119
|
+
console.error(import_chalk18.default.dim(" The receipt stays committed \u2014 do NOT re-run `receipt propose` (the receipt already exists; a second propose is rejected as a duplicate)."));
|
|
4120
|
+
console.error(import_chalk18.default.dim(" Recover authoritatively \u2014 this resolves condition_hash + the on-chain lock snapshot for you (no manual hashes, no sig file):"));
|
|
4121
|
+
console.error(import_chalk18.default.dim(` 'heyarp receipt send-payee-sig ${recipientDid} --delegation-id ${delegationId} --auto --cluster-tag ${opts.clusterTag ?? "<0|1>"}'`));
|
|
4090
4122
|
} else if (settlementResult?.delivered) {
|
|
4091
4123
|
console.log(import_chalk18.default.green("\nPayee settlement signature signed + delivered (escrow)."));
|
|
4092
4124
|
console.log(
|
|
@@ -4551,18 +4583,32 @@ async function runCosign(relationshipId, delegationId, requestHashArg, responseH
|
|
|
4551
4583
|
}
|
|
4552
4584
|
}
|
|
4553
4585
|
function registerSendPayeeSig(parent) {
|
|
4554
|
-
parent.command("send-payee-sig").description(
|
|
4586
|
+
parent.command("send-payee-sig").description(
|
|
4587
|
+
"Send the payee's settlement signature to the buyer via a settlement_signature envelope. Replaces /tmp/*.json coordination for cross-host escrow cycles. Two modes: (1) MANUAL \u2014 supply --receipt-event-hash + --sig-from-file + --expires-at from a prior `wallet sign-settlement-release`; (2) --auto (RECOMMENDED for recovery) \u2014 resolves condition_hash + the on-chain lock snapshot AUTHORITATIVELY and re-signs (force), so you pass NO --sig-from-file and NO hand-typed hashes. Use --auto to recover when `receipt propose` did not deliver the sig (e.g. the just-confirmed lock was not yet RPC-visible); do NOT re-run `receipt propose` (the receipt already exists \u2014 a second propose is rejected as a duplicate)."
|
|
4588
|
+
).argument(
|
|
4589
|
+
"[recipient-did]",
|
|
4590
|
+
"Buyer DID (= caller / offerer of the parent delegation; the cycle sends the sig to the side that will cosign). Optional under --auto \u2014 the buyer is resolved from the delegation/receipt."
|
|
4591
|
+
).requiredOption("--delegation-id <id>", "Parent delegation UUID \u2014 must match what was passed to `heyarp wallet sign-settlement-release`.").option(
|
|
4592
|
+
"--auto",
|
|
4593
|
+
"Authoritative recovery: resolve condition_hash (over the delegation terms) + the on-chain lock snapshot (mint / amount / expiry / fee) and re-sign the release digest (force), then deliver it. Use this to recover when `receipt propose` did not deliver the sig \u2014 you do NOT pass --sig-from-file or --receipt-event-hash with --auto, and there is no lock_id/condition_hash trap. Requires --cluster-tag; mutually exclusive with --sig-from-file. Do NOT re-run `receipt propose` (the receipt already exists; a second propose is rejected as a duplicate)."
|
|
4594
|
+
).option(
|
|
4595
|
+
"--cluster-tag <0|1>",
|
|
4596
|
+
"REQUIRED under --auto: 0 = devnet, 1 = mainnet-beta. Binds the cluster into the signed release digest (no safe default; a wrong cluster fails at the buyer cosign)."
|
|
4597
|
+
).option(
|
|
4598
|
+
"--rpc-url <url>",
|
|
4599
|
+
"Solana RPC endpoint for the --auto on-chain lock read (resolves mint / amount / expiry / fee). Falls back to ARP_ESCROW_RPC_URL then `heyarp config get rpcUrl`; when none is set the on-chain check is skipped and the server stays the boundary."
|
|
4600
|
+
).option("--program-id <pubkey>", "Escrow program id for the --auto on-chain lock read (auto-discovered from the server when omitted).").option("--rel-id <id>", "Relationship UUID \u2014 under --auto, auto-derived from the delegation when omitted.").option(
|
|
4555
4601
|
"--receipt-event-hash <sha256:hex>",
|
|
4556
|
-
"
|
|
4557
|
-
).
|
|
4602
|
+
"MANUAL path: server-assigned `serverEventHash` of the receipt-propose envelope this signature settles. Read it from the JSON response of `heyarp receipt propose` (the field is `Server event hash` in human output, or `.serverEventHash` in --json). MUST equal the value the digest was signed over \u2014 the server cross-checks against `Receipt.receiptEventHash` and rejects with SETTLEMENT_SIG_RECEIPT_NOT_FOUND otherwise. NOT needed with --auto (the helper resolves the receipt; pass it only to disambiguate >1 proposed receipt)."
|
|
4603
|
+
).option(
|
|
4558
4604
|
"--sig-from-file <path>",
|
|
4559
|
-
"JSON file produced by `heyarp wallet sign-settlement-release --write-to <path>`. Reads `{settlement_pubkey, sig, purpose, digest_hex}` \u2014 the digest_hex is bound through for cross-file consistency (catches truncated or hand-edited files)."
|
|
4560
|
-
).
|
|
4605
|
+
"MANUAL path: JSON file produced by `heyarp wallet sign-settlement-release --write-to <path>`. Reads `{settlement_pubkey, sig, purpose, digest_hex}` \u2014 the digest_hex is bound through for cross-file consistency (catches truncated or hand-edited files). MUTUALLY EXCLUSIVE with --auto."
|
|
4606
|
+
).option(
|
|
4561
4607
|
"--expires-at <unix>",
|
|
4562
|
-
"
|
|
4608
|
+
"MANUAL path: unix-seconds expires_at value baked into the signed digest \u2014 MUST match the value passed to `--expires-at` on `heyarp wallet sign-settlement-release`. Server cross-checks against the buyer-side value at cosign time; wrong value \u2192 ESC_SETTLEMENT_EXPIRES_AT_PAST/_TOO_SOON. Under --auto this is optional (derived from the delegation deadline; pass it only to override)."
|
|
4563
4609
|
).option(
|
|
4564
4610
|
"--payee-amount <int>",
|
|
4565
|
-
"Base-unit decimal-integer payee_amount \u2014 REQUIRED when the sig file's purpose is `ARP-SOLANA-PARTIAL-RELEASE-v1.5` (usage_based delegations). Same value passed to `--partial-payee-amount` on sign-settlement-release. FORBIDDEN for `ARP-SOLANA-RELEASE-v1.5` (full release settles the whole lock)."
|
|
4611
|
+
"Base-unit decimal-integer payee_amount \u2014 REQUIRED on the MANUAL path when the sig file's purpose is `ARP-SOLANA-PARTIAL-RELEASE-v1.5` (usage_based delegations). Same value passed to `--partial-payee-amount` on sign-settlement-release. FORBIDDEN for `ARP-SOLANA-RELEASE-v1.5` (full release settles the whole lock). Under --auto the partial amount is bound from the receipt; pass it only as a confirmation that must match."
|
|
4566
4612
|
).option("--server <url>", "Override ARP server base URL").option("--from-did <did>", "Sender DID \u2014 required only if multiple agents are registered against this server (= payee)").option("--ttl <seconds>", "Envelope TTL in seconds", "3600").option("--verbose", "Print the full envelope before sending and the full server response", false).action(async (recipientDid, opts, cmd) => {
|
|
4567
4613
|
try {
|
|
4568
4614
|
await runSendPayeeSig(recipientDid, opts);
|
|
@@ -4574,20 +4620,85 @@ function registerSendPayeeSig(parent) {
|
|
|
4574
4620
|
}
|
|
4575
4621
|
async function runSendPayeeSig(recipientDid, opts) {
|
|
4576
4622
|
const cmdName = "receipt send-payee-sig";
|
|
4623
|
+
if (opts.auto) {
|
|
4624
|
+
if (opts.sigFromFile !== void 0 && opts.sigFromFile !== "") {
|
|
4625
|
+
throw new Error(
|
|
4626
|
+
`${cmdName}: --auto and --sig-from-file are mutually exclusive. --auto re-signs the release digest AUTHORITATIVELY (it resolves condition_hash + the on-chain lock itself); a --sig-from-file is the MANUAL path's pre-signed input. Pick one: --auto for recovery, or the manual --sig-from-file + --receipt-event-hash + --expires-at trio.`
|
|
4627
|
+
);
|
|
4628
|
+
}
|
|
4629
|
+
if (opts.clusterTag === void 0 || opts.clusterTag === "") {
|
|
4630
|
+
throw new Error(
|
|
4631
|
+
`${cmdName}: --cluster-tag is required with --auto (0 = devnet, 1 = mainnet-beta). It binds the cluster into the signed release digest; there is no safe default \u2014 pass the cluster where the create_lock lives.`
|
|
4632
|
+
);
|
|
4633
|
+
}
|
|
4634
|
+
if (opts.clusterTag !== "0" && opts.clusterTag !== "1") {
|
|
4635
|
+
throw new Error(`${cmdName}: --cluster-tag must be '0' (devnet) or '1' (mainnet-beta), got '${opts.clusterTag}'`);
|
|
4636
|
+
}
|
|
4637
|
+
const delegationIdAuto = requireUuidNormalised2(cmdName, opts.delegationId, "--delegation-id");
|
|
4638
|
+
if (recipientDid !== void 0 && recipientDid !== "") {
|
|
4639
|
+
requireDid2(cmdName, recipientDid, "[recipient-did]");
|
|
4640
|
+
}
|
|
4641
|
+
const { autoSignAndDeliverPayeeSig: autoSignAndDeliverPayeeSig2 } = await Promise.resolve().then(() => (init_settlement(), settlement_exports));
|
|
4642
|
+
await autoSignAndDeliverPayeeSig2(
|
|
4643
|
+
{
|
|
4644
|
+
server: opts.server,
|
|
4645
|
+
fromDid: opts.fromDid,
|
|
4646
|
+
delegationId: delegationIdAuto,
|
|
4647
|
+
...opts.relId !== void 0 ? { relId: opts.relId } : {},
|
|
4648
|
+
clusterTag: opts.clusterTag,
|
|
4649
|
+
...opts.expiresAt !== void 0 ? { expiresAt: opts.expiresAt } : {},
|
|
4650
|
+
...opts.rpcUrl !== void 0 ? { rpcUrl: opts.rpcUrl } : {},
|
|
4651
|
+
...opts.programId !== void 0 ? { programId: opts.programId } : {},
|
|
4652
|
+
...opts.payeeAmount !== void 0 ? { partialPayeeAmount: opts.payeeAmount } : {},
|
|
4653
|
+
...opts.receiptEventHash !== void 0 ? { receiptEventHash: opts.receiptEventHash } : {},
|
|
4654
|
+
// Recovery semantics: re-sign + re-deliver even if a (bad) sig
|
|
4655
|
+
// already exists. The helper short-circuits a cosigned receipt.
|
|
4656
|
+
force: true
|
|
4657
|
+
// `send-payee-sig` has no --json flag (the manual path prints a
|
|
4658
|
+
// plain human block); leave the helper in its human-output mode.
|
|
4659
|
+
// Do NOT pass silent — the helper owns + prints the recovery output.
|
|
4660
|
+
},
|
|
4661
|
+
cmdName
|
|
4662
|
+
);
|
|
4663
|
+
return;
|
|
4664
|
+
}
|
|
4665
|
+
if (recipientDid === void 0 || recipientDid === "") {
|
|
4666
|
+
throw new Error(
|
|
4667
|
+
`${cmdName}: <recipient-did> (the buyer DID) is required on the manual path. Pass it, or use --auto --cluster-tag <0|1> to resolve the buyer + re-sign authoritatively.`
|
|
4668
|
+
);
|
|
4669
|
+
}
|
|
4577
4670
|
requireDid2(cmdName, recipientDid, "<recipient-did>");
|
|
4671
|
+
const recipient = recipientDid;
|
|
4578
4672
|
const delegationId = requireUuidNormalised2(cmdName, opts.delegationId, "--delegation-id");
|
|
4673
|
+
if (opts.sigFromFile === void 0 || opts.sigFromFile === "") {
|
|
4674
|
+
throw new Error(
|
|
4675
|
+
`${cmdName}: --sig-from-file is required (the MANUAL path's pre-signed input). For authoritative recovery without a sig file, use --auto --cluster-tag <0|1> instead.`
|
|
4676
|
+
);
|
|
4677
|
+
}
|
|
4678
|
+
if (opts.receiptEventHash === void 0 || opts.receiptEventHash === "") {
|
|
4679
|
+
throw new Error(
|
|
4680
|
+
`${cmdName}: --receipt-event-hash is required on the manual path. For authoritative recovery without hand-typed hashes, use --auto --cluster-tag <0|1> instead.`
|
|
4681
|
+
);
|
|
4682
|
+
}
|
|
4683
|
+
if (opts.expiresAt === void 0 || opts.expiresAt === "") {
|
|
4684
|
+
throw new Error(
|
|
4685
|
+
`${cmdName}: --expires-at is required on the manual path (must match the value signed). For authoritative recovery, use --auto --cluster-tag <0|1> instead.`
|
|
4686
|
+
);
|
|
4687
|
+
}
|
|
4579
4688
|
requireSha256(cmdName, opts.receiptEventHash, "--receipt-event-hash");
|
|
4689
|
+
const receiptEventHash = opts.receiptEventHash;
|
|
4690
|
+
const sigFromFile = opts.sigFromFile;
|
|
4580
4691
|
const expiresAtSeconds = parseInteger(cmdName, "--expires-at", opts.expiresAt);
|
|
4581
4692
|
if (expiresAtSeconds <= 0) {
|
|
4582
4693
|
throw new Error(`${cmdName}: --expires-at must be a positive unix-seconds integer (got ${opts.expiresAt})`);
|
|
4583
4694
|
}
|
|
4584
4695
|
const ttlSeconds = parseTtl2(cmdName, opts.ttl);
|
|
4585
|
-
const sigFile = loadSettlementSigFromFile(
|
|
4696
|
+
const sigFile = loadSettlementSigFromFile(sigFromFile, "--sig-from-file");
|
|
4586
4697
|
const isPartial = sigFile.purpose === "ARP-SOLANA-PARTIAL-RELEASE-v1.5";
|
|
4587
4698
|
const isFull = sigFile.purpose === "ARP-SOLANA-RELEASE-v1.5";
|
|
4588
4699
|
if (!isPartial && !isFull) {
|
|
4589
4700
|
throw new Error(
|
|
4590
|
-
`${cmdName}: sig file at '${
|
|
4701
|
+
`${cmdName}: sig file at '${sigFromFile}' has purpose='${sigFile.purpose}' but only ARP-SOLANA-RELEASE-v1.5 and ARP-SOLANA-PARTIAL-RELEASE-v1.5 are valid on a settlement_signature envelope. (REFUND-v1 sigs ride other paths \u2014 they don't bind to receipt_event_hash, so this envelope isn't the right channel for them.)`
|
|
4591
4702
|
);
|
|
4592
4703
|
}
|
|
4593
4704
|
if (isPartial && (opts.payeeAmount === void 0 || opts.payeeAmount === "")) {
|
|
@@ -4609,7 +4720,7 @@ async function runSendPayeeSig(recipientDid, opts) {
|
|
|
4609
4720
|
const api = new ArpApiClient(opts.server);
|
|
4610
4721
|
const content = {
|
|
4611
4722
|
delegation_id: delegationId,
|
|
4612
|
-
receipt_event_hash:
|
|
4723
|
+
receipt_event_hash: receiptEventHash,
|
|
4613
4724
|
purpose: sigFile.purpose,
|
|
4614
4725
|
payee_settlement_pubkey: sigFile.settlement_pubkey,
|
|
4615
4726
|
sig: sigFile.sig,
|
|
@@ -4618,9 +4729,9 @@ async function runSendPayeeSig(recipientDid, opts) {
|
|
|
4618
4729
|
};
|
|
4619
4730
|
console.log(import_chalk18.default.dim(`Server: ${api.serverUrl}`));
|
|
4620
4731
|
console.log(import_chalk18.default.dim(`Sender (payee): ${sender.did}`));
|
|
4621
|
-
console.log(import_chalk18.default.dim(`Recipient (buyer): ${
|
|
4732
|
+
console.log(import_chalk18.default.dim(`Recipient (buyer): ${recipient}`));
|
|
4622
4733
|
console.log(import_chalk18.default.dim(`Delegation: ${delegationId}`));
|
|
4623
|
-
console.log(import_chalk18.default.dim(`Receipt event hash: ${
|
|
4734
|
+
console.log(import_chalk18.default.dim(`Receipt event hash: ${receiptEventHash}`));
|
|
4624
4735
|
console.log(import_chalk18.default.dim(`Purpose: ${sigFile.purpose}`));
|
|
4625
4736
|
if (isPartial) {
|
|
4626
4737
|
console.log(import_chalk18.default.dim(`Payee amount: ${opts.payeeAmount}`));
|
|
@@ -4630,7 +4741,7 @@ async function runSendPayeeSig(recipientDid, opts) {
|
|
|
4630
4741
|
const result = await sendSettlementSignatureEnvelope({
|
|
4631
4742
|
api,
|
|
4632
4743
|
sender,
|
|
4633
|
-
recipientDid,
|
|
4744
|
+
recipientDid: recipient,
|
|
4634
4745
|
content,
|
|
4635
4746
|
ttlSeconds,
|
|
4636
4747
|
verbose: opts.verbose,
|
|
@@ -4934,7 +5045,7 @@ var import_simple_update_notifier = __toESM(require("simple-update-notifier"));
|
|
|
4934
5045
|
// package.json
|
|
4935
5046
|
var package_default = {
|
|
4936
5047
|
name: "@heyanon-arp/cli",
|
|
4937
|
-
version: "0.0.
|
|
5048
|
+
version: "0.0.10",
|
|
4938
5049
|
description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
4939
5050
|
license: "MIT",
|
|
4940
5051
|
keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
|
|
@@ -4944,7 +5055,7 @@ var package_default = {
|
|
|
4944
5055
|
publishConfig: {
|
|
4945
5056
|
access: "public"
|
|
4946
5057
|
},
|
|
4947
|
-
files: ["dist", "
|
|
5058
|
+
files: ["dist", "LICENSE", "README.md"],
|
|
4948
5059
|
engines: {
|
|
4949
5060
|
node: ">=22"
|
|
4950
5061
|
},
|
|
@@ -4954,8 +5065,7 @@ var package_default = {
|
|
|
4954
5065
|
test: "jest --runInBand --detectOpenHandles --forceExit --passWithNoTests",
|
|
4955
5066
|
lint: "biome check . --write",
|
|
4956
5067
|
prepublishOnly: "pnpm run build",
|
|
4957
|
-
prepare: "pnpm run build"
|
|
4958
|
-
postinstall: "node scripts/postinstall.mjs"
|
|
5068
|
+
prepare: "pnpm run build"
|
|
4959
5069
|
},
|
|
4960
5070
|
dependencies: {
|
|
4961
5071
|
"@heyanon-arp/sdk": "workspace:*",
|
|
@@ -5820,7 +5930,7 @@ var GUIDE_SECTIONS = [
|
|
|
5820
5930
|
{ when: "a `work_request` arrives", then: "do the task, then `heyarp work respond <rel-id> <del-id> <req-id> --output '<json>'`" },
|
|
5821
5931
|
{
|
|
5822
5932
|
when: "your `work respond` is sent",
|
|
5823
|
-
then: "propose the receipt AND deliver your settlement signature in ONE command: `heyarp receipt propose <buyer-did> <del-id> --auto-hashes --rel-id <rel-id> --request-id <req-id> --verdict accepted --cluster-tag <0|1>`. Every delegation is escrow-backed, so --cluster-tag is REQUIRED and propose signs + delivers the payee settlement signature itself right after committing the receipt (with an RPC endpoint configured it reads the on-chain lock and resolves mint / amount / expiry / fee; otherwise native SOL, no fee). If propose reports the receipt was proposed but the settlement sig was NOT delivered (
|
|
5933
|
+
then: "propose the receipt AND deliver your settlement signature in ONE command: `heyarp receipt propose <buyer-did> <del-id> --auto-hashes --rel-id <rel-id> --request-id <req-id> --verdict accepted --cluster-tag <0|1>`. Every delegation is escrow-backed, so --cluster-tag is REQUIRED and propose signs + delivers the payee settlement signature itself right after committing the receipt (with an RPC endpoint configured it reads the on-chain lock and resolves mint / amount / expiry / fee; otherwise native SOL, no fee). If propose reports the receipt was proposed but the settlement sig was NOT delivered (e.g. the just-confirmed lock was not yet RPC-visible), recover AUTHORITATIVELY with `heyarp receipt send-payee-sig <buyer-did> --delegation-id <del-id> --auto --cluster-tag <0|1>` \u2014 it resolves condition_hash + the on-chain lock snapshot itself, so you hand-type NO hashes and supply NO sig file. Do NOT re-run `receipt propose` (the receipt already exists; a second propose is rejected as a duplicate)."
|
|
5824
5934
|
},
|
|
5825
5935
|
{ when: "the buyer cosigns (cycle released)", then: "you are paid \u2014 the cycle is done; wait for the next offer" }
|
|
5826
5936
|
],
|
|
@@ -6016,7 +6126,17 @@ var GUIDE_SECTIONS = [
|
|
|
6016
6126
|
" `heyarp wallet sign-settlement-release` signs the release / partial",
|
|
6017
6127
|
" digest. Output `sig` is RAW base64 (NO `ed25519:` prefix). Pass",
|
|
6018
6128
|
" `--partial-payee-amount <lamports>` to switch the digest to",
|
|
6019
|
-
" `ARP-SOLANA-PARTIAL-RELEASE-v1.5`.",
|
|
6129
|
+
" `ARP-SOLANA-PARTIAL-RELEASE-v1.5`. WARNING: `--condition-hash` here is",
|
|
6130
|
+
" the SAME value `heyarp escrow derive-condition-hash` produces (the hash",
|
|
6131
|
+
" OVER THE TERMS) / the condition_hash on the on-chain lock \u2014 it is NOT",
|
|
6132
|
+
" the `lock_id` from `delegation.fund` attachments. lock_id",
|
|
6133
|
+
' (`sha256("arp-lock-v1"||delegation_id)`) and condition_hash',
|
|
6134
|
+
" (`sha256(terms)`) are DIFFERENT 32-byte values; the release digest binds",
|
|
6135
|
+
" condition_hash, so passing lock_id signs a digest the buyer cosign",
|
|
6136
|
+
" rejects (ESC_SETTLEMENT_SIG_INVALID). For the payee side, prefer",
|
|
6137
|
+
" `heyarp receipt send-payee-sig <buyer> --delegation-id <id> --auto`,",
|
|
6138
|
+
" which resolves condition_hash + the on-chain lock for you instead of",
|
|
6139
|
+
" hand-signing.",
|
|
6020
6140
|
" `heyarp receipt cosign` attaches both parties' signatures into",
|
|
6021
6141
|
" `attachments.settlement_signatures` via --settlement-purpose,",
|
|
6022
6142
|
" --settlement-expires-at, --payer-settlement-{pubkey,sig},",
|
|
@@ -6231,6 +6351,13 @@ var GUIDE_SECTIONS = [
|
|
|
6231
6351
|
" account for that mint exists.",
|
|
6232
6352
|
" \u2022 handshake stuck `pending` / delegation stuck `offered` \u2192 the COUNTERPARTY",
|
|
6233
6353
|
" has not acted; block on it with `heyarp status <rel-id> --wait --until <state>`.",
|
|
6354
|
+
" \u2022 `ESC_SETTLEMENT_SIG_INVALID` at `receipt cosign` \u2192 the payee signed the",
|
|
6355
|
+
" WRONG release digest \u2014 usually `--condition-hash` was set to the `lock_id`",
|
|
6356
|
+
" from a `delegation.fund` attachment (lock_id \u2260 condition_hash; the digest",
|
|
6357
|
+
" binds condition_hash). The payee re-delivers a correct sig with `heyarp",
|
|
6358
|
+
" receipt send-payee-sig <buyer> --delegation-id <id> --auto --cluster-tag",
|
|
6359
|
+
" <0|1>`, which resolves condition_hash from the on-chain lock (no manual",
|
|
6360
|
+
" hashes). Do NOT re-run `receipt propose` (the receipt already exists).",
|
|
6234
6361
|
' \u2022 "wrong move for my role" \u2192 you mixed up buyer vs worker; role is',
|
|
6235
6362
|
' PER-RELATIONSHIP \u2014 re-check with `heyarp guide` ("Which role am I?").',
|
|
6236
6363
|
" More: README at https://www.npmjs.com/package/@heyanon-arp/cli"
|
|
@@ -7069,13 +7196,11 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7069
7196
|
});
|
|
7070
7197
|
const settlementPublicKeyB58 = (0, import_sdk12.base58btcEncode)(keys.settlementPublicKey);
|
|
7071
7198
|
const scryptSaltId = (0, import_sdk12.uuidV4)();
|
|
7072
|
-
const ownerId = (0, import_sdk12.uuidV4)();
|
|
7073
7199
|
const payload = {
|
|
7074
7200
|
purpose: "ARP-KEY-LINK-v1",
|
|
7075
7201
|
agent_did: did,
|
|
7076
7202
|
identity_public_key: identityPublicKeyB58,
|
|
7077
7203
|
settlement_public_key: settlementPublicKeyB58,
|
|
7078
|
-
owner_id: ownerId,
|
|
7079
7204
|
owner_signing_method: "scrypt_password_proof",
|
|
7080
7205
|
link_method: "manual",
|
|
7081
7206
|
created_at: (0, import_sdk12.rfc3339)(),
|
|
@@ -7108,7 +7233,6 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7108
7233
|
scryptKeyB64: Buffer.from(scryptKey).toString("base64"),
|
|
7109
7234
|
scryptSaltB64: Buffer.from(scryptSalt).toString("base64"),
|
|
7110
7235
|
scryptSaltId,
|
|
7111
|
-
ownerId,
|
|
7112
7236
|
// Placeholder until the server confirms registration and returns
|
|
7113
7237
|
// the canonical attestation id (finalized in Step 8 below).
|
|
7114
7238
|
currentAttestationId: "",
|
|
@@ -8293,6 +8417,7 @@ async function main() {
|
|
|
8293
8417
|
process.stderr.write(str);
|
|
8294
8418
|
}
|
|
8295
8419
|
});
|
|
8420
|
+
program.addHelpText("after", () => onboardingHelpFooter());
|
|
8296
8421
|
registerConfigCommand(program);
|
|
8297
8422
|
registerGuideCommand(program);
|
|
8298
8423
|
registerHomesCommand(program);
|