@heyanon-arp/cli 0.0.8 → 0.0.9
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 +140 -31
- package/dist/cli.js.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -3547,9 +3547,15 @@ async function readOnChainLock(api, opts, delegationId) {
|
|
|
3547
3547
|
const programId = new import_web33.PublicKey(resolved.programId);
|
|
3548
3548
|
const { lockPda } = deriveLockPda(programId, delegationId);
|
|
3549
3549
|
const conn = new import_web33.Connection(rpcUrl, "confirmed");
|
|
3550
|
-
|
|
3550
|
+
let info = await conn.getAccountInfo(lockPda);
|
|
3551
|
+
for (let attempt = 1; attempt <= LOCK_READ_NOT_VISIBLE_RETRIES && !info; attempt++) {
|
|
3552
|
+
await new Promise((r) => setTimeout(r, LOCK_READ_RETRY_DELAY_MS));
|
|
3553
|
+
info = await conn.getAccountInfo(lockPda);
|
|
3554
|
+
}
|
|
3551
3555
|
if (!info) {
|
|
3552
|
-
return {
|
|
3556
|
+
return {
|
|
3557
|
+
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)`
|
|
3558
|
+
};
|
|
3553
3559
|
}
|
|
3554
3560
|
const lock = decodeLockAccount(info.data);
|
|
3555
3561
|
if (!lock) {
|
|
@@ -3832,7 +3838,7 @@ async function autoSignAndDeliverPayeeSig(opts, cmdName = "receipt propose") {
|
|
|
3832
3838
|
serverTimestamp: result.serverTimestamp
|
|
3833
3839
|
};
|
|
3834
3840
|
}
|
|
3835
|
-
var import_sdk10, import_utils3, import_web33, import_chalk17, NATIVE_SOL_MINT2, SETTLEMENT_MIN_EXPIRY_HEADROOM_SECS, SETTLEMENT_REFRESH_HEADROOM_SECS;
|
|
3841
|
+
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
3842
|
var init_settlement = __esm({
|
|
3837
3843
|
"src/commands/settlement.ts"() {
|
|
3838
3844
|
import_sdk10 = require("@heyanon-arp/sdk");
|
|
@@ -3852,6 +3858,8 @@ var init_settlement = __esm({
|
|
|
3852
3858
|
NATIVE_SOL_MINT2 = "11111111111111111111111111111111";
|
|
3853
3859
|
SETTLEMENT_MIN_EXPIRY_HEADROOM_SECS = 120;
|
|
3854
3860
|
SETTLEMENT_REFRESH_HEADROOM_SECS = 600;
|
|
3861
|
+
LOCK_READ_NOT_VISIBLE_RETRIES = 3;
|
|
3862
|
+
LOCK_READ_RETRY_DELAY_MS = 2e3;
|
|
3855
3863
|
}
|
|
3856
3864
|
});
|
|
3857
3865
|
|
|
@@ -3907,6 +3915,14 @@ function registerPropose(parent) {
|
|
|
3907
3915
|
await runPropose(recipientDid, delegationId, requestHash, responseHash, opts);
|
|
3908
3916
|
} catch (err) {
|
|
3909
3917
|
emitActionError(err, cmd);
|
|
3918
|
+
if (!opts.json && err instanceof ApiError && err.payload.code === "RECEIPT_ALREADY_EXISTS") {
|
|
3919
|
+
console.error(
|
|
3920
|
+
import_chalk18.default.dim(
|
|
3921
|
+
` This receipt already exists (a prior propose committed it). Do NOT re-propose \u2014 to (re)deliver the payee settlement signature, run:
|
|
3922
|
+
'heyarp receipt send-payee-sig ${recipientDid} --delegation-id ${delegationId} --auto --cluster-tag ${opts.clusterTag ?? "<0|1>"}'`
|
|
3923
|
+
)
|
|
3924
|
+
);
|
|
3925
|
+
}
|
|
3910
3926
|
process.exitCode = 1;
|
|
3911
3927
|
}
|
|
3912
3928
|
});
|
|
@@ -4054,7 +4070,12 @@ async function runPropose(recipientDid, delegationId, requestHashArg, responseHa
|
|
|
4054
4070
|
json.settlement = {
|
|
4055
4071
|
delivered: false,
|
|
4056
4072
|
error: settlementError.message,
|
|
4057
|
-
|
|
4073
|
+
// Authoritative recovery (SR-2/SR-3): re-sign + re-deliver via
|
|
4074
|
+
// --auto, which resolves condition_hash + the on-chain lock
|
|
4075
|
+
// snapshot itself — no hand-typed hashes, no sig file, no
|
|
4076
|
+
// lock_id/condition_hash trap. Do NOT re-run `receipt propose`
|
|
4077
|
+
// (the receipt already exists; a second propose is a duplicate).
|
|
4078
|
+
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
4079
|
};
|
|
4059
4080
|
} else if (settlementResult) {
|
|
4060
4081
|
json.settlement = {
|
|
@@ -4079,14 +4100,9 @@ Receipt event hash: ${import_chalk18.default.cyan(result.serverEventHash)}`));
|
|
|
4079
4100
|
if (settlementError) {
|
|
4080
4101
|
console.error(import_chalk18.default.yellow("\nWARNING: receipt proposed, but the payee settlement signature was NOT delivered."));
|
|
4081
4102
|
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
|
-
);
|
|
4103
|
+
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)."));
|
|
4104
|
+
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):"));
|
|
4105
|
+
console.error(import_chalk18.default.dim(` 'heyarp receipt send-payee-sig ${recipientDid} --delegation-id ${delegationId} --auto --cluster-tag ${opts.clusterTag ?? "<0|1>"}'`));
|
|
4090
4106
|
} else if (settlementResult?.delivered) {
|
|
4091
4107
|
console.log(import_chalk18.default.green("\nPayee settlement signature signed + delivered (escrow)."));
|
|
4092
4108
|
console.log(
|
|
@@ -4551,18 +4567,32 @@ async function runCosign(relationshipId, delegationId, requestHashArg, responseH
|
|
|
4551
4567
|
}
|
|
4552
4568
|
}
|
|
4553
4569
|
function registerSendPayeeSig(parent) {
|
|
4554
|
-
parent.command("send-payee-sig").description(
|
|
4570
|
+
parent.command("send-payee-sig").description(
|
|
4571
|
+
"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)."
|
|
4572
|
+
).argument(
|
|
4573
|
+
"[recipient-did]",
|
|
4574
|
+
"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."
|
|
4575
|
+
).requiredOption("--delegation-id <id>", "Parent delegation UUID \u2014 must match what was passed to `heyarp wallet sign-settlement-release`.").option(
|
|
4576
|
+
"--auto",
|
|
4577
|
+
"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)."
|
|
4578
|
+
).option(
|
|
4579
|
+
"--cluster-tag <0|1>",
|
|
4580
|
+
"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)."
|
|
4581
|
+
).option(
|
|
4582
|
+
"--rpc-url <url>",
|
|
4583
|
+
"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."
|
|
4584
|
+
).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
4585
|
"--receipt-event-hash <sha256:hex>",
|
|
4556
|
-
"
|
|
4557
|
-
).
|
|
4586
|
+
"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)."
|
|
4587
|
+
).option(
|
|
4558
4588
|
"--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
|
-
).
|
|
4589
|
+
"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."
|
|
4590
|
+
).option(
|
|
4561
4591
|
"--expires-at <unix>",
|
|
4562
|
-
"
|
|
4592
|
+
"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
4593
|
).option(
|
|
4564
4594
|
"--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)."
|
|
4595
|
+
"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
4596
|
).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
4597
|
try {
|
|
4568
4598
|
await runSendPayeeSig(recipientDid, opts);
|
|
@@ -4574,20 +4604,85 @@ function registerSendPayeeSig(parent) {
|
|
|
4574
4604
|
}
|
|
4575
4605
|
async function runSendPayeeSig(recipientDid, opts) {
|
|
4576
4606
|
const cmdName = "receipt send-payee-sig";
|
|
4607
|
+
if (opts.auto) {
|
|
4608
|
+
if (opts.sigFromFile !== void 0 && opts.sigFromFile !== "") {
|
|
4609
|
+
throw new Error(
|
|
4610
|
+
`${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.`
|
|
4611
|
+
);
|
|
4612
|
+
}
|
|
4613
|
+
if (opts.clusterTag === void 0 || opts.clusterTag === "") {
|
|
4614
|
+
throw new Error(
|
|
4615
|
+
`${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.`
|
|
4616
|
+
);
|
|
4617
|
+
}
|
|
4618
|
+
if (opts.clusterTag !== "0" && opts.clusterTag !== "1") {
|
|
4619
|
+
throw new Error(`${cmdName}: --cluster-tag must be '0' (devnet) or '1' (mainnet-beta), got '${opts.clusterTag}'`);
|
|
4620
|
+
}
|
|
4621
|
+
const delegationIdAuto = requireUuidNormalised2(cmdName, opts.delegationId, "--delegation-id");
|
|
4622
|
+
if (recipientDid !== void 0 && recipientDid !== "") {
|
|
4623
|
+
requireDid2(cmdName, recipientDid, "[recipient-did]");
|
|
4624
|
+
}
|
|
4625
|
+
const { autoSignAndDeliverPayeeSig: autoSignAndDeliverPayeeSig2 } = await Promise.resolve().then(() => (init_settlement(), settlement_exports));
|
|
4626
|
+
await autoSignAndDeliverPayeeSig2(
|
|
4627
|
+
{
|
|
4628
|
+
server: opts.server,
|
|
4629
|
+
fromDid: opts.fromDid,
|
|
4630
|
+
delegationId: delegationIdAuto,
|
|
4631
|
+
...opts.relId !== void 0 ? { relId: opts.relId } : {},
|
|
4632
|
+
clusterTag: opts.clusterTag,
|
|
4633
|
+
...opts.expiresAt !== void 0 ? { expiresAt: opts.expiresAt } : {},
|
|
4634
|
+
...opts.rpcUrl !== void 0 ? { rpcUrl: opts.rpcUrl } : {},
|
|
4635
|
+
...opts.programId !== void 0 ? { programId: opts.programId } : {},
|
|
4636
|
+
...opts.payeeAmount !== void 0 ? { partialPayeeAmount: opts.payeeAmount } : {},
|
|
4637
|
+
...opts.receiptEventHash !== void 0 ? { receiptEventHash: opts.receiptEventHash } : {},
|
|
4638
|
+
// Recovery semantics: re-sign + re-deliver even if a (bad) sig
|
|
4639
|
+
// already exists. The helper short-circuits a cosigned receipt.
|
|
4640
|
+
force: true
|
|
4641
|
+
// `send-payee-sig` has no --json flag (the manual path prints a
|
|
4642
|
+
// plain human block); leave the helper in its human-output mode.
|
|
4643
|
+
// Do NOT pass silent — the helper owns + prints the recovery output.
|
|
4644
|
+
},
|
|
4645
|
+
cmdName
|
|
4646
|
+
);
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
if (recipientDid === void 0 || recipientDid === "") {
|
|
4650
|
+
throw new Error(
|
|
4651
|
+
`${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.`
|
|
4652
|
+
);
|
|
4653
|
+
}
|
|
4577
4654
|
requireDid2(cmdName, recipientDid, "<recipient-did>");
|
|
4655
|
+
const recipient = recipientDid;
|
|
4578
4656
|
const delegationId = requireUuidNormalised2(cmdName, opts.delegationId, "--delegation-id");
|
|
4657
|
+
if (opts.sigFromFile === void 0 || opts.sigFromFile === "") {
|
|
4658
|
+
throw new Error(
|
|
4659
|
+
`${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.`
|
|
4660
|
+
);
|
|
4661
|
+
}
|
|
4662
|
+
if (opts.receiptEventHash === void 0 || opts.receiptEventHash === "") {
|
|
4663
|
+
throw new Error(
|
|
4664
|
+
`${cmdName}: --receipt-event-hash is required on the manual path. For authoritative recovery without hand-typed hashes, use --auto --cluster-tag <0|1> instead.`
|
|
4665
|
+
);
|
|
4666
|
+
}
|
|
4667
|
+
if (opts.expiresAt === void 0 || opts.expiresAt === "") {
|
|
4668
|
+
throw new Error(
|
|
4669
|
+
`${cmdName}: --expires-at is required on the manual path (must match the value signed). For authoritative recovery, use --auto --cluster-tag <0|1> instead.`
|
|
4670
|
+
);
|
|
4671
|
+
}
|
|
4579
4672
|
requireSha256(cmdName, opts.receiptEventHash, "--receipt-event-hash");
|
|
4673
|
+
const receiptEventHash = opts.receiptEventHash;
|
|
4674
|
+
const sigFromFile = opts.sigFromFile;
|
|
4580
4675
|
const expiresAtSeconds = parseInteger(cmdName, "--expires-at", opts.expiresAt);
|
|
4581
4676
|
if (expiresAtSeconds <= 0) {
|
|
4582
4677
|
throw new Error(`${cmdName}: --expires-at must be a positive unix-seconds integer (got ${opts.expiresAt})`);
|
|
4583
4678
|
}
|
|
4584
4679
|
const ttlSeconds = parseTtl2(cmdName, opts.ttl);
|
|
4585
|
-
const sigFile = loadSettlementSigFromFile(
|
|
4680
|
+
const sigFile = loadSettlementSigFromFile(sigFromFile, "--sig-from-file");
|
|
4586
4681
|
const isPartial = sigFile.purpose === "ARP-SOLANA-PARTIAL-RELEASE-v1.5";
|
|
4587
4682
|
const isFull = sigFile.purpose === "ARP-SOLANA-RELEASE-v1.5";
|
|
4588
4683
|
if (!isPartial && !isFull) {
|
|
4589
4684
|
throw new Error(
|
|
4590
|
-
`${cmdName}: sig file at '${
|
|
4685
|
+
`${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
4686
|
);
|
|
4592
4687
|
}
|
|
4593
4688
|
if (isPartial && (opts.payeeAmount === void 0 || opts.payeeAmount === "")) {
|
|
@@ -4609,7 +4704,7 @@ async function runSendPayeeSig(recipientDid, opts) {
|
|
|
4609
4704
|
const api = new ArpApiClient(opts.server);
|
|
4610
4705
|
const content = {
|
|
4611
4706
|
delegation_id: delegationId,
|
|
4612
|
-
receipt_event_hash:
|
|
4707
|
+
receipt_event_hash: receiptEventHash,
|
|
4613
4708
|
purpose: sigFile.purpose,
|
|
4614
4709
|
payee_settlement_pubkey: sigFile.settlement_pubkey,
|
|
4615
4710
|
sig: sigFile.sig,
|
|
@@ -4618,9 +4713,9 @@ async function runSendPayeeSig(recipientDid, opts) {
|
|
|
4618
4713
|
};
|
|
4619
4714
|
console.log(import_chalk18.default.dim(`Server: ${api.serverUrl}`));
|
|
4620
4715
|
console.log(import_chalk18.default.dim(`Sender (payee): ${sender.did}`));
|
|
4621
|
-
console.log(import_chalk18.default.dim(`Recipient (buyer): ${
|
|
4716
|
+
console.log(import_chalk18.default.dim(`Recipient (buyer): ${recipient}`));
|
|
4622
4717
|
console.log(import_chalk18.default.dim(`Delegation: ${delegationId}`));
|
|
4623
|
-
console.log(import_chalk18.default.dim(`Receipt event hash: ${
|
|
4718
|
+
console.log(import_chalk18.default.dim(`Receipt event hash: ${receiptEventHash}`));
|
|
4624
4719
|
console.log(import_chalk18.default.dim(`Purpose: ${sigFile.purpose}`));
|
|
4625
4720
|
if (isPartial) {
|
|
4626
4721
|
console.log(import_chalk18.default.dim(`Payee amount: ${opts.payeeAmount}`));
|
|
@@ -4630,7 +4725,7 @@ async function runSendPayeeSig(recipientDid, opts) {
|
|
|
4630
4725
|
const result = await sendSettlementSignatureEnvelope({
|
|
4631
4726
|
api,
|
|
4632
4727
|
sender,
|
|
4633
|
-
recipientDid,
|
|
4728
|
+
recipientDid: recipient,
|
|
4634
4729
|
content,
|
|
4635
4730
|
ttlSeconds,
|
|
4636
4731
|
verbose: opts.verbose,
|
|
@@ -4934,7 +5029,7 @@ var import_simple_update_notifier = __toESM(require("simple-update-notifier"));
|
|
|
4934
5029
|
// package.json
|
|
4935
5030
|
var package_default = {
|
|
4936
5031
|
name: "@heyanon-arp/cli",
|
|
4937
|
-
version: "0.0.
|
|
5032
|
+
version: "0.0.9",
|
|
4938
5033
|
description: "Command-line client for the Agent Relationship Protocol \u2014 register agents, sign envelopes, run escrowed work cycles on Solana.",
|
|
4939
5034
|
license: "MIT",
|
|
4940
5035
|
keywords: ["arp", "agent-relationship-protocol", "did", "solana", "escrow", "ed25519", "agents", "a2a", "cli"],
|
|
@@ -5820,7 +5915,7 @@ var GUIDE_SECTIONS = [
|
|
|
5820
5915
|
{ when: "a `work_request` arrives", then: "do the task, then `heyarp work respond <rel-id> <del-id> <req-id> --output '<json>'`" },
|
|
5821
5916
|
{
|
|
5822
5917
|
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 (
|
|
5918
|
+
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
5919
|
},
|
|
5825
5920
|
{ when: "the buyer cosigns (cycle released)", then: "you are paid \u2014 the cycle is done; wait for the next offer" }
|
|
5826
5921
|
],
|
|
@@ -6016,7 +6111,17 @@ var GUIDE_SECTIONS = [
|
|
|
6016
6111
|
" `heyarp wallet sign-settlement-release` signs the release / partial",
|
|
6017
6112
|
" digest. Output `sig` is RAW base64 (NO `ed25519:` prefix). Pass",
|
|
6018
6113
|
" `--partial-payee-amount <lamports>` to switch the digest to",
|
|
6019
|
-
" `ARP-SOLANA-PARTIAL-RELEASE-v1.5`.",
|
|
6114
|
+
" `ARP-SOLANA-PARTIAL-RELEASE-v1.5`. WARNING: `--condition-hash` here is",
|
|
6115
|
+
" the SAME value `heyarp escrow derive-condition-hash` produces (the hash",
|
|
6116
|
+
" OVER THE TERMS) / the condition_hash on the on-chain lock \u2014 it is NOT",
|
|
6117
|
+
" the `lock_id` from `delegation.fund` attachments. lock_id",
|
|
6118
|
+
' (`sha256("arp-lock-v1"||delegation_id)`) and condition_hash',
|
|
6119
|
+
" (`sha256(terms)`) are DIFFERENT 32-byte values; the release digest binds",
|
|
6120
|
+
" condition_hash, so passing lock_id signs a digest the buyer cosign",
|
|
6121
|
+
" rejects (ESC_SETTLEMENT_SIG_INVALID). For the payee side, prefer",
|
|
6122
|
+
" `heyarp receipt send-payee-sig <buyer> --delegation-id <id> --auto`,",
|
|
6123
|
+
" which resolves condition_hash + the on-chain lock for you instead of",
|
|
6124
|
+
" hand-signing.",
|
|
6020
6125
|
" `heyarp receipt cosign` attaches both parties' signatures into",
|
|
6021
6126
|
" `attachments.settlement_signatures` via --settlement-purpose,",
|
|
6022
6127
|
" --settlement-expires-at, --payer-settlement-{pubkey,sig},",
|
|
@@ -6231,6 +6336,13 @@ var GUIDE_SECTIONS = [
|
|
|
6231
6336
|
" account for that mint exists.",
|
|
6232
6337
|
" \u2022 handshake stuck `pending` / delegation stuck `offered` \u2192 the COUNTERPARTY",
|
|
6233
6338
|
" has not acted; block on it with `heyarp status <rel-id> --wait --until <state>`.",
|
|
6339
|
+
" \u2022 `ESC_SETTLEMENT_SIG_INVALID` at `receipt cosign` \u2192 the payee signed the",
|
|
6340
|
+
" WRONG release digest \u2014 usually `--condition-hash` was set to the `lock_id`",
|
|
6341
|
+
" from a `delegation.fund` attachment (lock_id \u2260 condition_hash; the digest",
|
|
6342
|
+
" binds condition_hash). The payee re-delivers a correct sig with `heyarp",
|
|
6343
|
+
" receipt send-payee-sig <buyer> --delegation-id <id> --auto --cluster-tag",
|
|
6344
|
+
" <0|1>`, which resolves condition_hash from the on-chain lock (no manual",
|
|
6345
|
+
" hashes). Do NOT re-run `receipt propose` (the receipt already exists).",
|
|
6234
6346
|
' \u2022 "wrong move for my role" \u2192 you mixed up buyer vs worker; role is',
|
|
6235
6347
|
' PER-RELATIONSHIP \u2014 re-check with `heyarp guide` ("Which role am I?").',
|
|
6236
6348
|
" More: README at https://www.npmjs.com/package/@heyanon-arp/cli"
|
|
@@ -7069,13 +7181,11 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7069
7181
|
});
|
|
7070
7182
|
const settlementPublicKeyB58 = (0, import_sdk12.base58btcEncode)(keys.settlementPublicKey);
|
|
7071
7183
|
const scryptSaltId = (0, import_sdk12.uuidV4)();
|
|
7072
|
-
const ownerId = (0, import_sdk12.uuidV4)();
|
|
7073
7184
|
const payload = {
|
|
7074
7185
|
purpose: "ARP-KEY-LINK-v1",
|
|
7075
7186
|
agent_did: did,
|
|
7076
7187
|
identity_public_key: identityPublicKeyB58,
|
|
7077
7188
|
settlement_public_key: settlementPublicKeyB58,
|
|
7078
|
-
owner_id: ownerId,
|
|
7079
7189
|
owner_signing_method: "scrypt_password_proof",
|
|
7080
7190
|
link_method: "manual",
|
|
7081
7191
|
created_at: (0, import_sdk12.rfc3339)(),
|
|
@@ -7108,7 +7218,6 @@ async function runRegister(opts, deps = defaultRegisterDeps) {
|
|
|
7108
7218
|
scryptKeyB64: Buffer.from(scryptKey).toString("base64"),
|
|
7109
7219
|
scryptSaltB64: Buffer.from(scryptSalt).toString("base64"),
|
|
7110
7220
|
scryptSaltId,
|
|
7111
|
-
ownerId,
|
|
7112
7221
|
// Placeholder until the server confirms registration and returns
|
|
7113
7222
|
// the canonical attestation id (finalized in Step 8 below).
|
|
7114
7223
|
currentAttestationId: "",
|