@t2000/sdk 9.6.0 → 9.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/browser.cjs CHANGED
@@ -1314,15 +1314,219 @@ async function buildSendTx({
1314
1314
  return tx;
1315
1315
  }
1316
1316
 
1317
+ // src/wallet/job.ts
1318
+ init_errors();
1319
+ init_token_registry();
1320
+ init_coinSelection();
1321
+ var A2A_ESCROW_PACKAGE_ID = process.env.A2A_ESCROW_PACKAGE_ID ?? "0x9e67c380fb7079d793d6d15ff916b24d82779d7119bfa4631863102ed485c0a0";
1322
+ var CLOCK_ID2 = "0x6";
1323
+ var MODULE = "escrow";
1324
+ var MAX_JOB_USDC = 50;
1325
+ var JOB_STATES = [
1326
+ "funded",
1327
+ "delivered",
1328
+ "released",
1329
+ "refunded",
1330
+ "rejected"
1331
+ ];
1332
+ function hexToBytes(hex) {
1333
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
1334
+ if (clean.length === 0 || clean.length % 2 !== 0 || /[^0-9a-fA-F]/.test(clean)) {
1335
+ throw new exports.T2000Error(
1336
+ "INVALID_AMOUNT",
1337
+ `Expected a hex hash (0x\u2026), got "${hex.slice(0, 32)}"`
1338
+ );
1339
+ }
1340
+ const out = [];
1341
+ for (let i = 0; i < clean.length; i += 2) {
1342
+ out.push(Number.parseInt(clean.slice(i, i + 2), 16));
1343
+ }
1344
+ return out;
1345
+ }
1346
+ function bytesToHex(bytes) {
1347
+ const arr = typeof bytes === "string" ? Array.from(atob(bytes), (c) => c.charCodeAt(0)) : bytes;
1348
+ let s = "0x";
1349
+ for (const b of arr) s += b.toString(16).padStart(2, "0");
1350
+ return s;
1351
+ }
1352
+ function preflightCreateJob(terms) {
1353
+ const addressCheck = checkSuiAddress(terms.seller);
1354
+ if (!addressCheck.valid) return addressCheck;
1355
+ if (!Number.isFinite(terms.amountUsdc) || terms.amountUsdc <= 0) {
1356
+ return preflightFail("INVALID_AMOUNT", `Amount must be positive. Got ${terms.amountUsdc}.`);
1357
+ }
1358
+ if (terms.amountUsdc > MAX_JOB_USDC) {
1359
+ return preflightFail(
1360
+ "INVALID_AMOUNT",
1361
+ `v1 caps escrow jobs at ${MAX_JOB_USDC} USDC (no-arbitration split only stays fair at small sizes). Got ${terms.amountUsdc}.`
1362
+ );
1363
+ }
1364
+ if (terms.deliverByMs <= Date.now()) {
1365
+ return preflightFail("INVALID_AMOUNT", "deliverByMs must be in the future.");
1366
+ }
1367
+ if (terms.reviewWindowMs < 0) {
1368
+ return preflightFail("INVALID_AMOUNT", "reviewWindowMs must be \u2265 0.");
1369
+ }
1370
+ if (!Number.isInteger(terms.rejectSplitBps) || terms.rejectSplitBps < 0 || terms.rejectSplitBps > 1e4) {
1371
+ return preflightFail("INVALID_AMOUNT", "rejectSplitBps must be an integer 0\u201310000.");
1372
+ }
1373
+ try {
1374
+ hexToBytes(terms.specHash);
1375
+ } catch (e) {
1376
+ return preflightFail("INVALID_AMOUNT", e.message);
1377
+ }
1378
+ return PREFLIGHT_OK;
1379
+ }
1380
+ async function buildCreateJobTx({
1381
+ client,
1382
+ buyer,
1383
+ terms
1384
+ }) {
1385
+ const pf = preflightCreateJob(terms);
1386
+ if (!pf.valid) throw new exports.T2000Error(pf.code, pf.error);
1387
+ const seller = validateAddress(terms.seller);
1388
+ if (seller === validateAddress(buyer)) {
1389
+ throw new exports.T2000Error("INVALID_ADDRESS", "Buyer and seller must be different wallets.");
1390
+ }
1391
+ const rawAmount = BigInt(Math.floor(terms.amountUsdc * 10 ** USDC_DECIMALS));
1392
+ const tx = new transactions.Transaction();
1393
+ const { coin } = await selectAndSplitCoin(tx, client, buyer, exports.USDC_TYPE, rawAmount, {
1394
+ allowSwapAll: false
1395
+ });
1396
+ tx.moveCall({
1397
+ target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::create`,
1398
+ typeArguments: [exports.USDC_TYPE],
1399
+ arguments: [
1400
+ tx.pure.address(seller),
1401
+ coin,
1402
+ tx.pure.vector("u8", hexToBytes(terms.specHash)),
1403
+ tx.pure.u64(terms.deliverByMs),
1404
+ tx.pure.u64(terms.reviewWindowMs),
1405
+ tx.pure.u64(terms.rejectSplitBps),
1406
+ tx.object(CLOCK_ID2)
1407
+ ]
1408
+ });
1409
+ return tx;
1410
+ }
1411
+ function jobCall(jobId, fn) {
1412
+ const tx = new transactions.Transaction();
1413
+ tx.moveCall({
1414
+ target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::${fn}`,
1415
+ typeArguments: [exports.USDC_TYPE],
1416
+ arguments: [tx.object(jobId), tx.object(CLOCK_ID2)]
1417
+ });
1418
+ return tx;
1419
+ }
1420
+ function buildDeliverJobTx(jobId, deliveryHash) {
1421
+ const tx = new transactions.Transaction();
1422
+ tx.moveCall({
1423
+ target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::deliver`,
1424
+ typeArguments: [exports.USDC_TYPE],
1425
+ arguments: [
1426
+ tx.object(jobId),
1427
+ tx.pure.vector("u8", hexToBytes(deliveryHash)),
1428
+ tx.object(CLOCK_ID2)
1429
+ ]
1430
+ });
1431
+ return tx;
1432
+ }
1433
+ function buildReleaseJobTx(jobId) {
1434
+ return jobCall(jobId, "release");
1435
+ }
1436
+ function buildRejectJobTx(jobId) {
1437
+ return jobCall(jobId, "reject");
1438
+ }
1439
+ function buildRefundJobTx(jobId) {
1440
+ return jobCall(jobId, "refund");
1441
+ }
1442
+ async function getJob(client, jobId) {
1443
+ const resp = await client.core.getObject({ objectId: jobId, include: { json: true } }).catch((e) => {
1444
+ throw new exports.T2000Error(
1445
+ "RPC_ERROR",
1446
+ `Job ${jobId} not found: ${e instanceof Error ? e.message : String(e)}`
1447
+ );
1448
+ });
1449
+ const objType = resp.object?.type ?? "";
1450
+ const json = resp.object?.json;
1451
+ if (!json || !objType.includes(`::${MODULE}::Job<`)) {
1452
+ throw new exports.T2000Error("RPC_ERROR", `Object ${jobId} is not an a2a_escrow Job.`);
1453
+ }
1454
+ const stateNum = Number(json.state ?? -1);
1455
+ const state = JOB_STATES[stateNum];
1456
+ if (!state) {
1457
+ throw new exports.T2000Error("RPC_ERROR", `Job ${jobId} has unknown state ${stateNum}.`);
1458
+ }
1459
+ const deliveredAtMs = Number(json.delivered_at_ms ?? 0);
1460
+ const deliveryBytes = json.delivery_hash ?? [];
1461
+ const hasDelivery = deliveredAtMs > 0;
1462
+ return {
1463
+ id: jobId,
1464
+ buyer: String(json.buyer),
1465
+ seller: String(json.seller),
1466
+ amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
1467
+ escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,
1468
+ specHash: bytesToHex(json.spec_hash ?? []),
1469
+ deliverByMs: Number(json.deliver_by_ms),
1470
+ reviewWindowMs: Number(json.review_window_ms),
1471
+ rejectSplitBps: Number(json.reject_split_bps),
1472
+ state,
1473
+ deliveryHash: hasDelivery ? bytesToHex(deliveryBytes) : null,
1474
+ deliveredAtMs: hasDelivery ? deliveredAtMs : null,
1475
+ createdAtMs: Number(json.created_at_ms)
1476
+ };
1477
+ }
1478
+ function jobActionsFor(job, caller, nowMs = Date.now()) {
1479
+ const me = validateAddress(caller);
1480
+ const isBuyer = me === job.buyer;
1481
+ const isSeller = me === job.seller;
1482
+ const actions = [];
1483
+ if (job.state === "funded") {
1484
+ if (isSeller && nowMs <= job.deliverByMs) actions.push("deliver");
1485
+ if (isBuyer) actions.push("release");
1486
+ if (nowMs > job.deliverByMs) actions.push("refund");
1487
+ } else if (job.state === "delivered") {
1488
+ const windowClosesMs = (job.deliveredAtMs ?? 0) + job.reviewWindowMs;
1489
+ if (isBuyer && nowMs <= windowClosesMs) actions.push("release", "reject");
1490
+ if (nowMs > windowClosesMs) actions.push("release");
1491
+ }
1492
+ return actions;
1493
+ }
1494
+ async function verifyJobForSeller({
1495
+ client,
1496
+ jobId,
1497
+ seller,
1498
+ minAmountUsdc,
1499
+ minRunwayMs = 6e4
1500
+ }) {
1501
+ const job = await getJob(client, jobId);
1502
+ const problems = [];
1503
+ if (job.state !== "funded") {
1504
+ problems.push(`state is "${job.state}", expected "funded"`);
1505
+ }
1506
+ if (job.seller !== validateAddress(seller)) {
1507
+ problems.push(`job pays ${job.seller}, not this seller`);
1508
+ }
1509
+ if (job.escrowUsdc < minAmountUsdc) {
1510
+ problems.push(`escrow holds ${job.escrowUsdc} USDC, price is ${minAmountUsdc}`);
1511
+ }
1512
+ if (job.deliverByMs - Date.now() < minRunwayMs) {
1513
+ problems.push("deadline too close to accept");
1514
+ }
1515
+ return { ok: problems.length === 0, job, problems };
1516
+ }
1517
+
1317
1518
  // src/browser.ts
1318
1519
  init_token_registry();
1319
1520
 
1521
+ exports.A2A_ESCROW_PACKAGE_ID = A2A_ESCROW_PACKAGE_ID;
1320
1522
  exports.CLOCK_ID = CLOCK_ID;
1321
1523
  exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
1322
1524
  exports.GAS_RESERVE_MIN = GAS_RESERVE_MIN;
1525
+ exports.JOB_STATES = JOB_STATES;
1323
1526
  exports.KNOWN_TARGETS = KNOWN_TARGETS;
1324
1527
  exports.KeypairSigner = KeypairSigner;
1325
1528
  exports.LABEL_PATTERNS = LABEL_PATTERNS;
1529
+ exports.MAX_JOB_USDC = MAX_JOB_USDC;
1326
1530
  exports.MIST_PER_SUI = MIST_PER_SUI;
1327
1531
  exports.OVERLAY_FEE_RATE = OVERLAY_FEE_RATE;
1328
1532
  exports.PREFLIGHT_MAX_AMOUNT = PREFLIGHT_MAX_AMOUNT;
@@ -1333,6 +1537,11 @@ exports.SUPPORTED_ASSETS = SUPPORTED_ASSETS;
1333
1537
  exports.T2000_OVERLAY_FEE_WALLET = T2000_OVERLAY_FEE_WALLET;
1334
1538
  exports.USDC_DECIMALS = USDC_DECIMALS;
1335
1539
  exports.ZkLoginSigner = ZkLoginSigner;
1540
+ exports.buildCreateJobTx = buildCreateJobTx;
1541
+ exports.buildDeliverJobTx = buildDeliverJobTx;
1542
+ exports.buildRefundJobTx = buildRefundJobTx;
1543
+ exports.buildRejectJobTx = buildRejectJobTx;
1544
+ exports.buildReleaseJobTx = buildReleaseJobTx;
1336
1545
  exports.buildSendTx = buildSendTx;
1337
1546
  exports.buildSwapTx = buildSwapTx;
1338
1547
  exports.checkPositiveAmount = checkPositiveAmount;
@@ -1353,12 +1562,15 @@ exports.formatUsd = formatUsd;
1353
1562
  exports.fromBase64 = fromBase642;
1354
1563
  exports.getDecimals = getDecimals;
1355
1564
  exports.getDecimalsForCoinType = getDecimalsForCoinType;
1565
+ exports.getJob = getJob;
1566
+ exports.jobActionsFor = jobActionsFor;
1356
1567
  exports.mapMoveAbortCode = mapMoveAbortCode;
1357
1568
  exports.mapWalletError = mapWalletError;
1358
1569
  exports.mistToSui = mistToSui;
1359
1570
  exports.parseMppSuiChallenge = parseMppSuiChallenge;
1360
1571
  exports.parseSuiRpcTx = parseSuiRpcTx;
1361
1572
  exports.payWithMpp = payWithMpp;
1573
+ exports.preflightCreateJob = preflightCreateJob;
1362
1574
  exports.preflightFail = preflightFail;
1363
1575
  exports.preflightPay = preflightPay;
1364
1576
  exports.preflightSend = preflightSend;
@@ -1374,5 +1586,6 @@ exports.toBase64 = toBase64;
1374
1586
  exports.truncateAddress = truncateAddress;
1375
1587
  exports.usdcToRaw = usdcToRaw;
1376
1588
  exports.validateAddress = validateAddress;
1589
+ exports.verifyJobForSeller = verifyJobForSeller;
1377
1590
  //# sourceMappingURL=browser.cjs.map
1378
1591
  //# sourceMappingURL=browser.cjs.map