@heyanon-arp/sdk 0.0.9 → 0.0.11
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/assets.d.ts +78 -35
- package/dist/escrow/condition-hash.d.ts +10 -4
- package/dist/escrow/create-lock.d.ts +22 -20
- package/dist/escrow/index.d.ts +3 -1
- package/dist/escrow/lifecycle-instructions.d.ts +45 -0
- package/dist/escrow/lock-account.d.ts +48 -0
- package/dist/index.d.ts +1 -3
- package/dist/index.js +226 -267
- package/dist/index.mjs +208 -259
- package/dist/settlement/index.d.ts +0 -2
- package/dist/types/agent.d.ts +0 -6
- package/dist/types/body.d.ts +1 -116
- package/dist/types/envelope.d.ts +10 -36
- package/dist/types/index.d.ts +2 -2
- package/package.json +1 -1
- package/dist/cosignature/cosign.d.ts +0 -35
- package/dist/cosignature/index.d.ts +0 -2
- package/dist/settlement/settlement.d.ts +0 -111
package/dist/index.mjs
CHANGED
|
@@ -165,56 +165,6 @@ var SETTLEMENT_PURPOSES = [
|
|
|
165
165
|
Purpose.SOLANA_RESOLVE_DISPUTE
|
|
166
166
|
];
|
|
167
167
|
|
|
168
|
-
// src/cosignature/cosign.ts
|
|
169
|
-
var COSIGN_ALLOWED = [Purpose.RECEIPT, Purpose.DISPUTE_RESPONSE];
|
|
170
|
-
function signCosignature(input) {
|
|
171
|
-
const purpose = input.payload.purpose;
|
|
172
|
-
if (!COSIGN_ALLOWED.includes(purpose)) {
|
|
173
|
-
throw new Error(`signCosignature: purpose "${purpose}" is not allowed for co_signature`);
|
|
174
|
-
}
|
|
175
|
-
const digest = sha256(canonicalBytes(input.payload));
|
|
176
|
-
const sigBytes = sign2(digest, input.identitySecretKey);
|
|
177
|
-
const payload_hash = `sha256:${bytesToHex2(digest)}`;
|
|
178
|
-
const sig = `ed25519:${base64.encode(sigBytes)}`;
|
|
179
|
-
return {
|
|
180
|
-
agent_did: input.signerDid,
|
|
181
|
-
purpose,
|
|
182
|
-
payload_hash,
|
|
183
|
-
sig
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
function verifyCosignature(input) {
|
|
187
|
-
if (input.cosignature.purpose !== input.payload.purpose) {
|
|
188
|
-
return { ok: false, reason: "purpose_mismatch" };
|
|
189
|
-
}
|
|
190
|
-
const digest = sha256(canonicalBytes(input.payload));
|
|
191
|
-
const expectedHash = `sha256:${bytesToHex2(digest)}`;
|
|
192
|
-
if (expectedHash !== input.cosignature.payload_hash) {
|
|
193
|
-
return { ok: false, reason: "payload_hash_mismatch" };
|
|
194
|
-
}
|
|
195
|
-
const sigPrefix = "ed25519:";
|
|
196
|
-
if (!input.cosignature.sig.startsWith(sigPrefix)) {
|
|
197
|
-
return { ok: false, reason: "signature_malformed", detail: "sig missing ed25519: prefix" };
|
|
198
|
-
}
|
|
199
|
-
let sigBytes;
|
|
200
|
-
try {
|
|
201
|
-
sigBytes = base64.decode(input.cosignature.sig.slice(sigPrefix.length));
|
|
202
|
-
} catch {
|
|
203
|
-
return { ok: false, reason: "signature_malformed", detail: "sig base64 decode failed" };
|
|
204
|
-
}
|
|
205
|
-
if (sigBytes.length !== 64) {
|
|
206
|
-
return { ok: false, reason: "signature_malformed", detail: `expected 64-byte signature, got ${sigBytes.length}` };
|
|
207
|
-
}
|
|
208
|
-
return verify2(sigBytes, digest, input.signerIdentityPubkey) ? { ok: true } : { ok: false, reason: "signature_invalid" };
|
|
209
|
-
}
|
|
210
|
-
function bytesToHex2(b) {
|
|
211
|
-
let s = "";
|
|
212
|
-
for (let i = 0; i < b.length; i++) {
|
|
213
|
-
s += b[i].toString(16).padStart(2, "0");
|
|
214
|
-
}
|
|
215
|
-
return s;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
168
|
// src/challenge/challenge.ts
|
|
219
169
|
var CHALLENGE_PURPOSE_BYTES = new TextEncoder().encode(Purpose.CHALLENGE);
|
|
220
170
|
function buildSigningInput(challengeBytes) {
|
|
@@ -308,7 +258,7 @@ function verifyKeyLinkAttestation(attestation, scryptKey) {
|
|
|
308
258
|
function signedMessageHash(envelope) {
|
|
309
259
|
const input = envelope.attachments === void 0 ? { protected: envelope.protected, body: envelope.body } : { protected: envelope.protected, body: envelope.body, attachments: envelope.attachments };
|
|
310
260
|
const digest = sha256(canonicalBytes(input));
|
|
311
|
-
return `sha256:${
|
|
261
|
+
return `sha256:${bytesToHex2(digest)}`;
|
|
312
262
|
}
|
|
313
263
|
function serverEventHash(input) {
|
|
314
264
|
const canonicalInput = {
|
|
@@ -319,7 +269,7 @@ function serverEventHash(input) {
|
|
|
319
269
|
sender_signature: input.senderSignature
|
|
320
270
|
};
|
|
321
271
|
const digest = sha256(canonicalBytes(canonicalInput));
|
|
322
|
-
return `sha256:${
|
|
272
|
+
return `sha256:${bytesToHex2(digest)}`;
|
|
323
273
|
}
|
|
324
274
|
function findFirstChainDivergence(events) {
|
|
325
275
|
for (let i = 0; i < events.length; i++) {
|
|
@@ -336,185 +286,13 @@ function findFirstChainDivergence(events) {
|
|
|
336
286
|
}
|
|
337
287
|
return null;
|
|
338
288
|
}
|
|
339
|
-
function
|
|
289
|
+
function bytesToHex2(b) {
|
|
340
290
|
let s = "";
|
|
341
291
|
for (let i = 0; i < b.length; i++) {
|
|
342
292
|
s += b[i].toString(16).padStart(2, "0");
|
|
343
293
|
}
|
|
344
294
|
return s;
|
|
345
295
|
}
|
|
346
|
-
function deriveLockId(delegationId) {
|
|
347
|
-
const bytes16 = delegationIdToBytes16(delegationId);
|
|
348
|
-
const prefix = new TextEncoder().encode("arp-lock-v1");
|
|
349
|
-
const input = new Uint8Array(prefix.length + 16);
|
|
350
|
-
input.set(prefix, 0);
|
|
351
|
-
input.set(bytes16, prefix.length);
|
|
352
|
-
return sha256(input);
|
|
353
|
-
}
|
|
354
|
-
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
355
|
-
function delegationIdToBytes16(delegationId) {
|
|
356
|
-
const uuid = delegationId.startsWith("del_") ? delegationId.slice(4) : delegationId;
|
|
357
|
-
if (!UUID_RE.test(uuid)) {
|
|
358
|
-
if (delegationId.startsWith("del_")) {
|
|
359
|
-
throw new Error(`Invalid delegation_id UUID (must be canonical lowercase): ${JSON.stringify(uuid)}`);
|
|
360
|
-
}
|
|
361
|
-
throw new Error(`Invalid delegation_id format: expected "del_<uuid>" or bare canonical-lowercase UUID, got ${JSON.stringify(delegationId)}`);
|
|
362
|
-
}
|
|
363
|
-
const hex = uuid.replace(/-/g, "");
|
|
364
|
-
const out = new Uint8Array(16);
|
|
365
|
-
for (let i = 0; i < 16; i++) {
|
|
366
|
-
out[i] = Number.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
|
367
|
-
}
|
|
368
|
-
return out;
|
|
369
|
-
}
|
|
370
|
-
function bytes16ToDelegationId(bytes) {
|
|
371
|
-
if (bytes.length !== 16) {
|
|
372
|
-
throw new Error(`bytes16ToDelegationId: expected 16 bytes, got ${bytes.length}`);
|
|
373
|
-
}
|
|
374
|
-
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
375
|
-
return `del_${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
// src/settlement/settlement.ts
|
|
379
|
-
var PURPOSE_RELEASE_STRING = "ARP-SOLANA-RELEASE-v1.5";
|
|
380
|
-
var PURPOSE_PARTIAL_RELEASE_STRING = "ARP-SOLANA-PARTIAL-RELEASE-v1.5";
|
|
381
|
-
var PURPOSE_REFUND_STRING = "ARP-SOLANA-REFUND-v1";
|
|
382
|
-
var PURPOSE_RELEASE = new TextEncoder().encode(PURPOSE_RELEASE_STRING);
|
|
383
|
-
var PURPOSE_PARTIAL_RELEASE = new TextEncoder().encode(PURPOSE_PARTIAL_RELEASE_STRING);
|
|
384
|
-
var PURPOSE_REFUND = new TextEncoder().encode(PURPOSE_REFUND_STRING);
|
|
385
|
-
var ZERO_PUBKEY = new Uint8Array(32);
|
|
386
|
-
function buildReleaseDigest(input) {
|
|
387
|
-
requireLen(input.programId, 32, "programId");
|
|
388
|
-
requireLen(input.lockId, 32, "lockId");
|
|
389
|
-
requireLen(input.payerSettlementPubkey, 32, "payerSettlementPubkey");
|
|
390
|
-
requireLen(input.payeeSettlementPubkey, 32, "payeeSettlementPubkey");
|
|
391
|
-
requireLen(input.mint, 32, "mint");
|
|
392
|
-
requireLen(input.conditionHash, 32, "conditionHash");
|
|
393
|
-
requireLen(input.receiptEventHash, 32, "receiptEventHash");
|
|
394
|
-
requireLen(input.deliverableHash, 32, "deliverableHash");
|
|
395
|
-
const feeBps = input.feeBpsAtLock ?? 0;
|
|
396
|
-
requireFeeBps(feeBps);
|
|
397
|
-
const feeRecipient = input.feeRecipientAtLock ?? ZERO_PUBKEY;
|
|
398
|
-
requireLen(feeRecipient, 32, "feeRecipientAtLock");
|
|
399
|
-
const delegationBytes = delegationIdToBytes16(input.delegationId);
|
|
400
|
-
const buf = concatBytes(
|
|
401
|
-
PURPOSE_RELEASE,
|
|
402
|
-
new Uint8Array([input.clusterTag]),
|
|
403
|
-
input.programId,
|
|
404
|
-
input.lockId,
|
|
405
|
-
input.payerSettlementPubkey,
|
|
406
|
-
input.payeeSettlementPubkey,
|
|
407
|
-
input.mint,
|
|
408
|
-
u64LE(input.amount),
|
|
409
|
-
input.conditionHash,
|
|
410
|
-
delegationBytes,
|
|
411
|
-
input.receiptEventHash,
|
|
412
|
-
input.deliverableHash,
|
|
413
|
-
u64LE(input.expiresAt),
|
|
414
|
-
u16LE(feeBps),
|
|
415
|
-
feeRecipient
|
|
416
|
-
);
|
|
417
|
-
return sha256(buf);
|
|
418
|
-
}
|
|
419
|
-
function buildPartialReleaseDigest(input) {
|
|
420
|
-
requireLen(input.programId, 32, "programId");
|
|
421
|
-
requireLen(input.lockId, 32, "lockId");
|
|
422
|
-
requireLen(input.payerSettlementPubkey, 32, "payerSettlementPubkey");
|
|
423
|
-
requireLen(input.payeeSettlementPubkey, 32, "payeeSettlementPubkey");
|
|
424
|
-
requireLen(input.mint, 32, "mint");
|
|
425
|
-
requireLen(input.conditionHash, 32, "conditionHash");
|
|
426
|
-
requireLen(input.receiptEventHash, 32, "receiptEventHash");
|
|
427
|
-
requireLen(input.deliverableHash, 32, "deliverableHash");
|
|
428
|
-
const feeBps = input.feeBpsAtLock ?? 0;
|
|
429
|
-
requireFeeBps(feeBps);
|
|
430
|
-
const feeRecipient = input.feeRecipientAtLock ?? ZERO_PUBKEY;
|
|
431
|
-
requireLen(feeRecipient, 32, "feeRecipientAtLock");
|
|
432
|
-
const delegationBytes = delegationIdToBytes16(input.delegationId);
|
|
433
|
-
const buf = concatBytes(
|
|
434
|
-
PURPOSE_PARTIAL_RELEASE,
|
|
435
|
-
new Uint8Array([input.clusterTag]),
|
|
436
|
-
input.programId,
|
|
437
|
-
input.lockId,
|
|
438
|
-
input.payerSettlementPubkey,
|
|
439
|
-
input.payeeSettlementPubkey,
|
|
440
|
-
input.mint,
|
|
441
|
-
u64LE(input.amount),
|
|
442
|
-
u64LE(input.payeeAmount),
|
|
443
|
-
input.conditionHash,
|
|
444
|
-
delegationBytes,
|
|
445
|
-
input.receiptEventHash,
|
|
446
|
-
input.deliverableHash,
|
|
447
|
-
u64LE(input.expiresAt),
|
|
448
|
-
u16LE(feeBps),
|
|
449
|
-
feeRecipient
|
|
450
|
-
);
|
|
451
|
-
return sha256(buf);
|
|
452
|
-
}
|
|
453
|
-
var REFUND_REASON_BYTES = {
|
|
454
|
-
expired: 0,
|
|
455
|
-
dispute_resolution: 1,
|
|
456
|
-
payer_cancellation: 2,
|
|
457
|
-
both_parties_agreed: 3
|
|
458
|
-
};
|
|
459
|
-
function buildRefundDigest(input) {
|
|
460
|
-
requireLen(input.programId, 32, "programId");
|
|
461
|
-
requireLen(input.lockId, 32, "lockId");
|
|
462
|
-
requireLen(input.payerSettlementPubkey, 32, "payerSettlementPubkey");
|
|
463
|
-
requireLen(input.payeeSettlementPubkey, 32, "payeeSettlementPubkey");
|
|
464
|
-
requireLen(input.mint, 32, "mint");
|
|
465
|
-
const buf = concatBytes(
|
|
466
|
-
PURPOSE_REFUND,
|
|
467
|
-
new Uint8Array([input.clusterTag]),
|
|
468
|
-
input.programId,
|
|
469
|
-
input.lockId,
|
|
470
|
-
input.payerSettlementPubkey,
|
|
471
|
-
input.payeeSettlementPubkey,
|
|
472
|
-
input.mint,
|
|
473
|
-
u64LE(input.amount),
|
|
474
|
-
new Uint8Array([input.reasonByte]),
|
|
475
|
-
u64LE(input.expiresAt)
|
|
476
|
-
);
|
|
477
|
-
return sha256(buf);
|
|
478
|
-
}
|
|
479
|
-
function requireLen(bytes, expected, name) {
|
|
480
|
-
if (bytes.length !== expected) {
|
|
481
|
-
throw new Error(`settlement digest: ${name} must be ${expected} bytes, got ${bytes.length}`);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
function requireFeeBps(bps) {
|
|
485
|
-
if (!Number.isInteger(bps) || bps < 0 || bps > 65535) {
|
|
486
|
-
throw new Error(`settlement digest: feeBpsAtLock must be a u16 (0..65535), got ${bps}`);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
function concatBytes(...parts) {
|
|
490
|
-
let total = 0;
|
|
491
|
-
for (const p of parts) total += p.length;
|
|
492
|
-
const out = new Uint8Array(total);
|
|
493
|
-
let off = 0;
|
|
494
|
-
for (const p of parts) {
|
|
495
|
-
out.set(p, off);
|
|
496
|
-
off += p.length;
|
|
497
|
-
}
|
|
498
|
-
return out;
|
|
499
|
-
}
|
|
500
|
-
function u64LE(value) {
|
|
501
|
-
if (value < 0n || value > 0xffffffffffffffffn) {
|
|
502
|
-
throw new Error(`settlement digest: u64 value out of range: ${value}`);
|
|
503
|
-
}
|
|
504
|
-
const out = new Uint8Array(8);
|
|
505
|
-
let v = value;
|
|
506
|
-
for (let i = 0; i < 8; i++) {
|
|
507
|
-
out[i] = Number(v & 0xffn);
|
|
508
|
-
v >>= 8n;
|
|
509
|
-
}
|
|
510
|
-
return out;
|
|
511
|
-
}
|
|
512
|
-
function u16LE(value) {
|
|
513
|
-
const out = new Uint8Array(2);
|
|
514
|
-
out[0] = value & 255;
|
|
515
|
-
out[1] = value >> 8 & 255;
|
|
516
|
-
return out;
|
|
517
|
-
}
|
|
518
296
|
|
|
519
297
|
// src/settlement/token-program.ts
|
|
520
298
|
var SPL_TOKEN_PROGRAM_ID_BASE58 = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
@@ -633,32 +411,73 @@ var SOLANA_CLUSTER_IDS = {
|
|
|
633
411
|
"solana-devnet": "EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
|
|
634
412
|
};
|
|
635
413
|
var SLIP44_SOLANA = 501;
|
|
414
|
+
var MAINNET_MINTS = {
|
|
415
|
+
USDC: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
416
|
+
USDT: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
|
|
417
|
+
ANON: "9McvH6w97oewLmPxqQEoHUAv3u5iYMyQ9AeZZhguYf1T"
|
|
418
|
+
};
|
|
419
|
+
var DEVNET_MINTS = {
|
|
420
|
+
USDC: "7ZjP2eJnQrW1SuE1kAP7tdrQuhkTVpco1NQKGjEMHpgg"
|
|
421
|
+
};
|
|
636
422
|
var USDC_MINTS = {
|
|
637
|
-
"solana-mainnet":
|
|
638
|
-
"solana-devnet":
|
|
423
|
+
"solana-mainnet": MAINNET_MINTS.USDC,
|
|
424
|
+
"solana-devnet": DEVNET_MINTS.USDC
|
|
639
425
|
};
|
|
640
|
-
var
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
symbol: "USDC"
|
|
645
|
-
},
|
|
646
|
-
"USDC:solana-devnet": {
|
|
647
|
-
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-devnet"]}/spl:${USDC_MINTS["solana-devnet"]}`,
|
|
648
|
-
decimals: 6,
|
|
649
|
-
symbol: "USDC"
|
|
650
|
-
},
|
|
651
|
-
"SOL:solana-mainnet": {
|
|
652
|
-
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-mainnet"]}/slip44:${SLIP44_SOLANA}`,
|
|
653
|
-
decimals: 9,
|
|
654
|
-
symbol: "SOL"
|
|
655
|
-
},
|
|
656
|
-
"SOL:solana-devnet": {
|
|
657
|
-
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-devnet"]}/slip44:${SLIP44_SOLANA}`,
|
|
658
|
-
decimals: 9,
|
|
659
|
-
symbol: "SOL"
|
|
660
|
-
}
|
|
426
|
+
var SOL_MAINNET = {
|
|
427
|
+
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-mainnet"]}/slip44:${SLIP44_SOLANA}`,
|
|
428
|
+
decimals: 9,
|
|
429
|
+
symbol: "SOL"
|
|
661
430
|
};
|
|
431
|
+
var SOL_DEVNET = {
|
|
432
|
+
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-devnet"]}/slip44:${SLIP44_SOLANA}`,
|
|
433
|
+
decimals: 9,
|
|
434
|
+
symbol: "SOL"
|
|
435
|
+
};
|
|
436
|
+
var USDC_DEVNET = {
|
|
437
|
+
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-devnet"]}/spl:${DEVNET_MINTS.USDC}`,
|
|
438
|
+
decimals: 9,
|
|
439
|
+
symbol: "USDC"
|
|
440
|
+
};
|
|
441
|
+
var ASSET_WHITELIST = {
|
|
442
|
+
"solana-mainnet": [
|
|
443
|
+
SOL_MAINNET,
|
|
444
|
+
{
|
|
445
|
+
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-mainnet"]}/spl:${MAINNET_MINTS.USDC}`,
|
|
446
|
+
decimals: 6,
|
|
447
|
+
symbol: "USDC"
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-mainnet"]}/spl:${MAINNET_MINTS.USDT}`,
|
|
451
|
+
decimals: 6,
|
|
452
|
+
symbol: "USDT"
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
asset_id: `solana:${SOLANA_CLUSTER_IDS["solana-mainnet"]}/spl:${MAINNET_MINTS.ANON}`,
|
|
456
|
+
decimals: 9,
|
|
457
|
+
symbol: "ANON"
|
|
458
|
+
}
|
|
459
|
+
],
|
|
460
|
+
"solana-devnet": [SOL_DEVNET, USDC_DEVNET]
|
|
461
|
+
};
|
|
462
|
+
var WELL_KNOWN_ASSETS = Object.fromEntries(
|
|
463
|
+
Object.entries(ASSET_WHITELIST).flatMap(([cluster, assets]) => assets.map((asset) => [`${asset.symbol}:${cluster}`, asset]))
|
|
464
|
+
);
|
|
465
|
+
var WELL_KNOWN_ASSET_KEYS = Object.keys(WELL_KNOWN_ASSETS);
|
|
466
|
+
function listWhitelistedAssets(cluster) {
|
|
467
|
+
return ASSET_WHITELIST[cluster].map((a) => ({ ...a }));
|
|
468
|
+
}
|
|
469
|
+
function findAssetByAssetId(assetId) {
|
|
470
|
+
for (const [cluster, assets] of Object.entries(ASSET_WHITELIST)) {
|
|
471
|
+
const asset = assets.find((a) => a.asset_id === assetId);
|
|
472
|
+
if (asset) return { asset: { ...asset }, cluster, key: `${asset.symbol}:${cluster}` };
|
|
473
|
+
}
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
function isWhitelistedAssetId(assetId, cluster) {
|
|
477
|
+
const hit = findAssetByAssetId(assetId);
|
|
478
|
+
if (!hit) return false;
|
|
479
|
+
return cluster === void 0 || hit.cluster === cluster;
|
|
480
|
+
}
|
|
662
481
|
var CAIP19_REGEX = /^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}\/[-a-z0-9]{3,8}:[-.%a-zA-Z0-9]{1,128}$/;
|
|
663
482
|
function isAssetIdentifier(value) {
|
|
664
483
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
@@ -672,22 +491,54 @@ function resolveAsset(input) {
|
|
|
672
491
|
const hit = WELL_KNOWN_ASSETS[input];
|
|
673
492
|
if (hit) return { ...hit };
|
|
674
493
|
if (CAIP19_REGEX.test(input)) {
|
|
494
|
+
const whitelisted = findAssetByAssetId(input);
|
|
495
|
+
if (whitelisted) return whitelisted.asset;
|
|
675
496
|
return { asset_id: input, decimals: NaN };
|
|
676
497
|
}
|
|
677
498
|
return null;
|
|
678
499
|
}
|
|
679
|
-
|
|
500
|
+
function deriveLockId(delegationId) {
|
|
501
|
+
const bytes16 = delegationIdToBytes16(delegationId);
|
|
502
|
+
const prefix = new TextEncoder().encode("arp-lock-v1");
|
|
503
|
+
const input = new Uint8Array(prefix.length + 16);
|
|
504
|
+
input.set(prefix, 0);
|
|
505
|
+
input.set(bytes16, prefix.length);
|
|
506
|
+
return sha256(input);
|
|
507
|
+
}
|
|
508
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
509
|
+
function delegationIdToBytes16(delegationId) {
|
|
510
|
+
const uuid = delegationId.startsWith("del_") ? delegationId.slice(4) : delegationId;
|
|
511
|
+
if (!UUID_RE.test(uuid)) {
|
|
512
|
+
if (delegationId.startsWith("del_")) {
|
|
513
|
+
throw new Error(`Invalid delegation_id UUID (must be canonical lowercase): ${JSON.stringify(uuid)}`);
|
|
514
|
+
}
|
|
515
|
+
throw new Error(`Invalid delegation_id format: expected "del_<uuid>" or bare canonical-lowercase UUID, got ${JSON.stringify(delegationId)}`);
|
|
516
|
+
}
|
|
517
|
+
const hex = uuid.replace(/-/g, "");
|
|
518
|
+
const out = new Uint8Array(16);
|
|
519
|
+
for (let i = 0; i < 16; i++) {
|
|
520
|
+
out[i] = Number.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
|
|
521
|
+
}
|
|
522
|
+
return out;
|
|
523
|
+
}
|
|
524
|
+
function bytes16ToDelegationId(bytes) {
|
|
525
|
+
if (bytes.length !== 16) {
|
|
526
|
+
throw new Error(`bytes16ToDelegationId: expected 16 bytes, got ${bytes.length}`);
|
|
527
|
+
}
|
|
528
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
529
|
+
return `del_${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
530
|
+
}
|
|
680
531
|
function deriveDelegationConditionHash(delegation) {
|
|
681
|
-
const required = ["delegationId", "scopeSummary"
|
|
532
|
+
const required = ["delegationId", "scopeSummary"];
|
|
682
533
|
for (const field of required) {
|
|
683
534
|
if (delegation[field] === void 0) {
|
|
684
535
|
throw new Error(`deriveDelegationConditionHash: required field '${String(field)}' is missing from the delegation input`);
|
|
685
536
|
}
|
|
686
537
|
}
|
|
687
538
|
const subset = {
|
|
539
|
+
v: "arp-condition-v2",
|
|
688
540
|
delegationId: delegation.delegationId,
|
|
689
|
-
scopeSummary: delegation.scopeSummary
|
|
690
|
-
pricingModel: delegation.pricingModel
|
|
541
|
+
scopeSummary: delegation.scopeSummary
|
|
691
542
|
};
|
|
692
543
|
if (delegation.currency !== void 0) subset.currency = delegation.currency;
|
|
693
544
|
const bytes = canonicalBytes(subset);
|
|
@@ -716,15 +567,16 @@ function parseCaip19SolanaAssetId(assetId) {
|
|
|
716
567
|
throw new Error(`Unsupported CAIP-19 namespace: ${JSON.stringify(namespaceRaw)} (only 'spl' and 'slip44' are supported on Solana)`);
|
|
717
568
|
}
|
|
718
569
|
var CREATE_LOCK_DISCRIMINATOR = new Uint8Array([171, 216, 92, 167, 165, 8, 153, 90]);
|
|
719
|
-
|
|
570
|
+
var CREATE_LOCK_NATIVE_DISCRIMINATOR = new Uint8Array([234, 19, 218, 36, 23, 74, 218, 108]);
|
|
571
|
+
function buildCreateLockIxData(args, opts = {}) {
|
|
720
572
|
if (args.lockId.length !== 32) throw new Error("create_lock: lockId must be 32 bytes");
|
|
721
573
|
if (args.conditionHash.length !== 32) throw new Error("create_lock: conditionHash must be 32 bytes");
|
|
722
574
|
requireU64(args.amount, "amount");
|
|
723
|
-
|
|
724
|
-
const total = 8 + 32 + 8 + 32
|
|
575
|
+
const disc = opts.native ? CREATE_LOCK_NATIVE_DISCRIMINATOR : CREATE_LOCK_DISCRIMINATOR;
|
|
576
|
+
const total = 8 + 32 + 8 + 32;
|
|
725
577
|
const out = new Uint8Array(total);
|
|
726
578
|
let off = 0;
|
|
727
|
-
out.set(
|
|
579
|
+
out.set(disc, off);
|
|
728
580
|
off += 8;
|
|
729
581
|
out.set(args.lockId, off);
|
|
730
582
|
off += 32;
|
|
@@ -732,8 +584,6 @@ function buildCreateLockIxData(args) {
|
|
|
732
584
|
off += 8;
|
|
733
585
|
out.set(args.conditionHash, off);
|
|
734
586
|
off += 32;
|
|
735
|
-
writeU64LE(out, off, args.expiry);
|
|
736
|
-
off += 8;
|
|
737
587
|
if (off !== total) throw new Error(`create_lock ix data layout drift: ${off} != ${total}`);
|
|
738
588
|
return out;
|
|
739
589
|
}
|
|
@@ -753,5 +603,104 @@ function computeCreateLockDiscriminator() {
|
|
|
753
603
|
const h = sha256(new TextEncoder().encode("global:create_lock"));
|
|
754
604
|
return h.slice(0, 8);
|
|
755
605
|
}
|
|
606
|
+
var ESCROW_PDA_SEEDS = {
|
|
607
|
+
LOCK: "lock",
|
|
608
|
+
ESCROW: "escrow",
|
|
609
|
+
CONFIG: "config",
|
|
610
|
+
STAKE_VAULT: "stake_vault",
|
|
611
|
+
COLLATERAL: "collateral",
|
|
612
|
+
DISPUTE_RESOLUTION: "dispute_resolution",
|
|
613
|
+
OPERATOR_AUTH: "operator_auth",
|
|
614
|
+
EVENT_AUTHORITY: "__event_authority"
|
|
615
|
+
};
|
|
616
|
+
var NO_ARG_LIFECYCLE_INSTRUCTIONS = [
|
|
617
|
+
"accept_lock",
|
|
618
|
+
"submit_work",
|
|
619
|
+
"claim_work_payment",
|
|
620
|
+
"claim_work_payment_native",
|
|
621
|
+
"cancel_lock",
|
|
622
|
+
"cancel_lock_native",
|
|
623
|
+
"claim_expired_work",
|
|
624
|
+
"claim_expired_work_native",
|
|
625
|
+
"open_dispute",
|
|
626
|
+
"close_dispute",
|
|
627
|
+
"close_dispute_native"
|
|
628
|
+
];
|
|
629
|
+
function instructionDiscriminator(ixName) {
|
|
630
|
+
return sha256(new TextEncoder().encode(`global:${ixName}`)).slice(0, 8);
|
|
631
|
+
}
|
|
632
|
+
function buildLifecycleIxData(ixName) {
|
|
633
|
+
if (!NO_ARG_LIFECYCLE_INSTRUCTIONS.includes(ixName)) {
|
|
634
|
+
throw new Error(`buildLifecycleIxData: '${ixName}' is not a no-arg lifecycle instruction`);
|
|
635
|
+
}
|
|
636
|
+
return instructionDiscriminator(ixName);
|
|
637
|
+
}
|
|
638
|
+
function buildResolveDisputeIxData(args, opts = {}) {
|
|
639
|
+
if (args.reasonHash.length !== 32) throw new Error("resolve_dispute: reasonHash must be 32 bytes");
|
|
640
|
+
if (args.disputeId.length !== 16) throw new Error("resolve_dispute: disputeId must be 16 bytes");
|
|
641
|
+
const disc = instructionDiscriminator(opts.native ? "resolve_dispute_native" : "resolve_dispute");
|
|
642
|
+
const total = 8 + 1 + 32 + 16;
|
|
643
|
+
const out = new Uint8Array(total);
|
|
644
|
+
out.set(disc, 0);
|
|
645
|
+
out[8] = args.isPayerWinner ? 1 : 0;
|
|
646
|
+
out.set(args.reasonHash, 9);
|
|
647
|
+
out.set(args.disputeId, 41);
|
|
648
|
+
return out;
|
|
649
|
+
}
|
|
650
|
+
var LOCK_ACCOUNT_SIZE = 269;
|
|
651
|
+
var LOCK_ACCOUNT_DISCRIMINATOR = new Uint8Array([8, 255, 36, 202, 210, 22, 57, 137]);
|
|
652
|
+
var LOCK_STATE_NAMES = ["created", "canceled", "in_progress", "submitted", "paid", "revoked", "disputing", "dispute_resolved", "dispute_closed"];
|
|
653
|
+
var LOCK_TERMINAL_STATES = ["canceled", "paid", "revoked", "dispute_resolved", "dispute_closed"];
|
|
654
|
+
var NATIVE_SOL_MINT_BASE58 = "11111111111111111111111111111111";
|
|
655
|
+
function decodeLockAccount(data) {
|
|
656
|
+
if (data.length !== LOCK_ACCOUNT_SIZE) {
|
|
657
|
+
throw new Error(`decodeLockAccount: expected ${LOCK_ACCOUNT_SIZE} bytes, got ${data.length}`);
|
|
658
|
+
}
|
|
659
|
+
for (let i = 0; i < 8; i++) {
|
|
660
|
+
if (data[i] !== LOCK_ACCOUNT_DISCRIMINATOR[i]) {
|
|
661
|
+
throw new Error("decodeLockAccount: account discriminator is not Lock");
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const stateByte = data[185];
|
|
665
|
+
const state = LOCK_STATE_NAMES[stateByte];
|
|
666
|
+
if (state === void 0) {
|
|
667
|
+
throw new Error(`decodeLockAccount: unknown LockState discriminant ${stateByte}`);
|
|
668
|
+
}
|
|
669
|
+
const mint = base58.encode(data.slice(113, 145));
|
|
670
|
+
return {
|
|
671
|
+
lockId: toHex(data.subarray(8, 40)),
|
|
672
|
+
version: data[40],
|
|
673
|
+
payer: base58.encode(data.slice(41, 73)),
|
|
674
|
+
payee: base58.encode(data.slice(73, 105)),
|
|
675
|
+
amount: readU64LE(data, 105),
|
|
676
|
+
mint,
|
|
677
|
+
isNative: mint === NATIVE_SOL_MINT_BASE58,
|
|
678
|
+
conditionHash: toHex(data.subarray(145, 177)),
|
|
679
|
+
expiry: readU64LE(data, 177),
|
|
680
|
+
state,
|
|
681
|
+
stateByte,
|
|
682
|
+
feeBpsAtLock: data[186] | data[187] << 8,
|
|
683
|
+
feeRecipientAtLock: base58.encode(data.slice(188, 220)),
|
|
684
|
+
workerStakeAtLock: readU64LE(data, 220),
|
|
685
|
+
operatorDisputeFeeAtLock: readU64LE(data, 228),
|
|
686
|
+
treasuryAtLock: base58.encode(data.slice(236, 268)),
|
|
687
|
+
bump: data[268]
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function computeLockAccountDiscriminator() {
|
|
691
|
+
return sha256(new TextEncoder().encode("account:Lock")).slice(0, 8);
|
|
692
|
+
}
|
|
693
|
+
function toHex(bytes) {
|
|
694
|
+
let hex = "";
|
|
695
|
+
for (const b of bytes) hex += b.toString(16).padStart(2, "0");
|
|
696
|
+
return hex;
|
|
697
|
+
}
|
|
698
|
+
function readU64LE(buf, off) {
|
|
699
|
+
let v = 0n;
|
|
700
|
+
for (let i = 0; i < 8; i++) {
|
|
701
|
+
v |= BigInt(buf[off + i]) << BigInt(8 * i);
|
|
702
|
+
}
|
|
703
|
+
return v;
|
|
704
|
+
}
|
|
756
705
|
|
|
757
|
-
export { CAIP19_REGEX, COSIGNATURE_PURPOSES, CREATE_LOCK_DISCRIMINATOR, DECLINE_REASONS,
|
|
706
|
+
export { ASSET_WHITELIST, CAIP19_REGEX, COSIGNATURE_PURPOSES, CREATE_LOCK_DISCRIMINATOR, CREATE_LOCK_NATIVE_DISCRIMINATOR, DECLINE_REASONS, DEVNET_MINTS, ESCROW_PDA_SEEDS, LOCK_ACCOUNT_DISCRIMINATOR, LOCK_ACCOUNT_SIZE, LOCK_STATE_NAMES, LOCK_TERMINAL_STATES, MAINNET_MINTS, NATIVE_SOL_MINT_BASE58, NO_ARG_LIFECYCLE_INSTRUCTIONS, PROTECTED_PURPOSES, Purpose, SCRYPT_PARAMS, SETTLEMENT_PURPOSES, SLIP44_SOLANA, SOLANA_CLUSTER_IDS, SPL_TOKEN_PROGRAM_ID_BASE58, USDC_MINTS, WELL_KNOWN_ASSETS, WELL_KNOWN_ASSET_KEYS, base58btcDecode, base58btcEncode, buildCreateLockIxData, buildLifecycleIxData, buildResolveDisputeIxData, bytes16ToDelegationId, canonicalBytes, canonicalJson, canonicalSha256Hex, computeCreateLockDiscriminator, computeLockAccountDiscriminator, decodeLockAccount, delegationIdToBytes16, deriveDelegationConditionHash, deriveLockId, deriveScryptKey, detectTokenProgramFromOwner, detectTokenProgramFromOwnerBytes, expiresAt, findAssetByAssetId, findFirstChainDivergence, formatDid, generateKeyPair, getPublicKey2 as getPublicKey, instructionDiscriminator, isAssetIdentifier, isDeclineReason, isValidDid, isWhitelistedAssetId, listWhitelistedAssets, parseCaip19SolanaAssetId, parseDid, pollUntil, resolveAsset, rfc3339, scryptPasswordProofSign, scryptPasswordProofVerify, senderNonce, serverEventHash, sign2 as sign, signChallenge, signEnvelope, signKeyLinkAttestation, signedMessageHash, uuidV4, verify2 as verify, verifyChallenge, verifyEnvelope, verifyKeyLinkAttestation };
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
export { buildReleaseDigest, buildPartialReleaseDigest, buildRefundDigest, REFUND_REASON_BYTES, PURPOSE_RELEASE_STRING, PURPOSE_PARTIAL_RELEASE_STRING, PURPOSE_REFUND_STRING, } from './settlement';
|
|
2
|
-
export type { ReleaseDigestInput, PartialReleaseDigestInput, RefundDigestInput, RefundReasonByte } from './settlement';
|
|
3
1
|
export { detectTokenProgramFromOwner, detectTokenProgramFromOwnerBytes, SPL_TOKEN_PROGRAM_ID_BASE58 } from './token-program';
|
|
4
2
|
export type { TokenProgramKind, TokenProgramDetection } from './token-program';
|
package/dist/types/agent.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { PricingModel } from './body';
|
|
2
1
|
/**
|
|
3
2
|
* Agent accept-preferences ("PricingPolicy") — the worker-side "what I
|
|
4
3
|
* accept" constraints a registered agent publishes on its profile.
|
|
@@ -21,11 +20,6 @@ import type { PricingModel } from './body';
|
|
|
21
20
|
* same replace semantics as `tags`.
|
|
22
21
|
*/
|
|
23
22
|
export interface AcceptPrefs {
|
|
24
|
-
/**
|
|
25
|
-
* Accepted pricing models. Empty/absent ⇒ any model. Subset of the
|
|
26
|
-
* closed `PricingModel` set.
|
|
27
|
-
*/
|
|
28
|
-
pricingModels?: PricingModel[];
|
|
29
23
|
/**
|
|
30
24
|
* Accepted currencies with optional per-currency amount bounds.
|
|
31
25
|
* Empty/absent ⇒ any currency, no amount bound. An offer whose
|