@t2000/sdk 9.5.0 → 9.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs +221 -0
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +210 -1
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +224 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +213 -1
- package/dist/index.js.map +1 -1
- package/dist/{send-DEK6aOGe.d.cts → job-CSq0DRsC.d.cts} +121 -2
- package/dist/{send-DEK6aOGe.d.ts → job-CSq0DRsC.d.ts} +121 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1051,6 +1051,7 @@ var KeypairSigner = class {
|
|
|
1051
1051
|
constructor(keypair) {
|
|
1052
1052
|
this.keypair = keypair;
|
|
1053
1053
|
}
|
|
1054
|
+
kind = "keypair";
|
|
1054
1055
|
getAddress() {
|
|
1055
1056
|
return this.keypair.getPublicKey().toSuiAddress();
|
|
1056
1057
|
}
|
|
@@ -1157,6 +1158,13 @@ async function payWithMpp(args) {
|
|
|
1157
1158
|
}
|
|
1158
1159
|
const headerChallenge = await parseMppSuiChallenge(probe);
|
|
1159
1160
|
if (headerChallenge) {
|
|
1161
|
+
if (signer.kind === "zklogin") {
|
|
1162
|
+
throw new exports.T2000Error(
|
|
1163
|
+
"DIALECT_UNSUPPORTED",
|
|
1164
|
+
"This seller only offers the MPP header dialect, which zkLogin (Passport) wallets cannot safely pay: the seller cannot verify zkLogin signatures, so the payment would settle on-chain without the service delivering. No payment was made. Use an x402-capable service, or pay from a keypair wallet (t2 CLI / MCP).",
|
|
1165
|
+
{ dialect: "mpp-header", signerKind: "zklogin" }
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1160
1168
|
const result = await payViaMppHeader({ signer, client, options });
|
|
1161
1169
|
await reportDirectPayment(result, options.url);
|
|
1162
1170
|
return result;
|
|
@@ -1394,6 +1402,7 @@ var ZkLoginSigner = class {
|
|
|
1394
1402
|
this.userAddress = userAddress;
|
|
1395
1403
|
this.maxEpoch = maxEpoch;
|
|
1396
1404
|
}
|
|
1405
|
+
kind = "zklogin";
|
|
1397
1406
|
getAddress() {
|
|
1398
1407
|
return this.userAddress;
|
|
1399
1408
|
}
|
|
@@ -3122,6 +3131,209 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
3122
3131
|
|
|
3123
3132
|
// src/index.ts
|
|
3124
3133
|
init_errors();
|
|
3134
|
+
|
|
3135
|
+
// src/wallet/job.ts
|
|
3136
|
+
init_errors();
|
|
3137
|
+
init_token_registry();
|
|
3138
|
+
init_preflight();
|
|
3139
|
+
init_coinSelection();
|
|
3140
|
+
var A2A_ESCROW_PACKAGE_ID = process.env.A2A_ESCROW_PACKAGE_ID ?? "0x9e67c380fb7079d793d6d15ff916b24d82779d7119bfa4631863102ed485c0a0";
|
|
3141
|
+
var CLOCK_ID2 = "0x6";
|
|
3142
|
+
var MODULE = "escrow";
|
|
3143
|
+
var MAX_JOB_USDC = 50;
|
|
3144
|
+
var JOB_STATES = [
|
|
3145
|
+
"funded",
|
|
3146
|
+
"delivered",
|
|
3147
|
+
"released",
|
|
3148
|
+
"refunded",
|
|
3149
|
+
"rejected"
|
|
3150
|
+
];
|
|
3151
|
+
function hexToBytes2(hex) {
|
|
3152
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
3153
|
+
if (clean.length === 0 || clean.length % 2 !== 0 || /[^0-9a-fA-F]/.test(clean)) {
|
|
3154
|
+
throw new exports.T2000Error(
|
|
3155
|
+
"INVALID_AMOUNT",
|
|
3156
|
+
`Expected a hex hash (0x\u2026), got "${hex.slice(0, 32)}"`
|
|
3157
|
+
);
|
|
3158
|
+
}
|
|
3159
|
+
const out = [];
|
|
3160
|
+
for (let i = 0; i < clean.length; i += 2) {
|
|
3161
|
+
out.push(Number.parseInt(clean.slice(i, i + 2), 16));
|
|
3162
|
+
}
|
|
3163
|
+
return out;
|
|
3164
|
+
}
|
|
3165
|
+
function bytesToHex2(bytes) {
|
|
3166
|
+
let s = "0x";
|
|
3167
|
+
for (const b of bytes) s += b.toString(16).padStart(2, "0");
|
|
3168
|
+
return s;
|
|
3169
|
+
}
|
|
3170
|
+
function preflightCreateJob(terms) {
|
|
3171
|
+
const addressCheck = checkSuiAddress(terms.seller);
|
|
3172
|
+
if (!addressCheck.valid) return addressCheck;
|
|
3173
|
+
if (!Number.isFinite(terms.amountUsdc) || terms.amountUsdc <= 0) {
|
|
3174
|
+
return preflightFail("INVALID_AMOUNT", `Amount must be positive. Got ${terms.amountUsdc}.`);
|
|
3175
|
+
}
|
|
3176
|
+
if (terms.amountUsdc > MAX_JOB_USDC) {
|
|
3177
|
+
return preflightFail(
|
|
3178
|
+
"INVALID_AMOUNT",
|
|
3179
|
+
`v1 caps escrow jobs at ${MAX_JOB_USDC} USDC (no-arbitration split only stays fair at small sizes). Got ${terms.amountUsdc}.`
|
|
3180
|
+
);
|
|
3181
|
+
}
|
|
3182
|
+
if (terms.deliverByMs <= Date.now()) {
|
|
3183
|
+
return preflightFail("INVALID_AMOUNT", "deliverByMs must be in the future.");
|
|
3184
|
+
}
|
|
3185
|
+
if (terms.reviewWindowMs < 0) {
|
|
3186
|
+
return preflightFail("INVALID_AMOUNT", "reviewWindowMs must be \u2265 0.");
|
|
3187
|
+
}
|
|
3188
|
+
if (!Number.isInteger(terms.rejectSplitBps) || terms.rejectSplitBps < 0 || terms.rejectSplitBps > 1e4) {
|
|
3189
|
+
return preflightFail("INVALID_AMOUNT", "rejectSplitBps must be an integer 0\u201310000.");
|
|
3190
|
+
}
|
|
3191
|
+
try {
|
|
3192
|
+
hexToBytes2(terms.specHash);
|
|
3193
|
+
} catch (e) {
|
|
3194
|
+
return preflightFail("INVALID_AMOUNT", e.message);
|
|
3195
|
+
}
|
|
3196
|
+
return exports.PREFLIGHT_OK;
|
|
3197
|
+
}
|
|
3198
|
+
async function buildCreateJobTx({
|
|
3199
|
+
client,
|
|
3200
|
+
buyer,
|
|
3201
|
+
terms
|
|
3202
|
+
}) {
|
|
3203
|
+
const pf = preflightCreateJob(terms);
|
|
3204
|
+
if (!pf.valid) throw new exports.T2000Error(pf.code, pf.error);
|
|
3205
|
+
const seller = validateAddress(terms.seller);
|
|
3206
|
+
if (seller === validateAddress(buyer)) {
|
|
3207
|
+
throw new exports.T2000Error("INVALID_ADDRESS", "Buyer and seller must be different wallets.");
|
|
3208
|
+
}
|
|
3209
|
+
const rawAmount = BigInt(Math.floor(terms.amountUsdc * 10 ** USDC_DECIMALS));
|
|
3210
|
+
const tx = new transactions.Transaction();
|
|
3211
|
+
const { coin } = await selectAndSplitCoin(tx, client, buyer, exports.USDC_TYPE, rawAmount, {
|
|
3212
|
+
allowSwapAll: false
|
|
3213
|
+
});
|
|
3214
|
+
tx.moveCall({
|
|
3215
|
+
target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::create`,
|
|
3216
|
+
typeArguments: [exports.USDC_TYPE],
|
|
3217
|
+
arguments: [
|
|
3218
|
+
tx.pure.address(seller),
|
|
3219
|
+
coin,
|
|
3220
|
+
tx.pure.vector("u8", hexToBytes2(terms.specHash)),
|
|
3221
|
+
tx.pure.u64(terms.deliverByMs),
|
|
3222
|
+
tx.pure.u64(terms.reviewWindowMs),
|
|
3223
|
+
tx.pure.u64(terms.rejectSplitBps),
|
|
3224
|
+
tx.object(CLOCK_ID2)
|
|
3225
|
+
]
|
|
3226
|
+
});
|
|
3227
|
+
return tx;
|
|
3228
|
+
}
|
|
3229
|
+
function jobCall(jobId, fn) {
|
|
3230
|
+
const tx = new transactions.Transaction();
|
|
3231
|
+
tx.moveCall({
|
|
3232
|
+
target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::${fn}`,
|
|
3233
|
+
typeArguments: [exports.USDC_TYPE],
|
|
3234
|
+
arguments: [tx.object(jobId), tx.object(CLOCK_ID2)]
|
|
3235
|
+
});
|
|
3236
|
+
return tx;
|
|
3237
|
+
}
|
|
3238
|
+
function buildDeliverJobTx(jobId, deliveryHash) {
|
|
3239
|
+
const tx = new transactions.Transaction();
|
|
3240
|
+
tx.moveCall({
|
|
3241
|
+
target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::deliver`,
|
|
3242
|
+
typeArguments: [exports.USDC_TYPE],
|
|
3243
|
+
arguments: [
|
|
3244
|
+
tx.object(jobId),
|
|
3245
|
+
tx.pure.vector("u8", hexToBytes2(deliveryHash)),
|
|
3246
|
+
tx.object(CLOCK_ID2)
|
|
3247
|
+
]
|
|
3248
|
+
});
|
|
3249
|
+
return tx;
|
|
3250
|
+
}
|
|
3251
|
+
function buildReleaseJobTx(jobId) {
|
|
3252
|
+
return jobCall(jobId, "release");
|
|
3253
|
+
}
|
|
3254
|
+
function buildRejectJobTx(jobId) {
|
|
3255
|
+
return jobCall(jobId, "reject");
|
|
3256
|
+
}
|
|
3257
|
+
function buildRefundJobTx(jobId) {
|
|
3258
|
+
return jobCall(jobId, "refund");
|
|
3259
|
+
}
|
|
3260
|
+
async function getJob(client, jobId) {
|
|
3261
|
+
const resp = await client.core.getObject({ objectId: jobId, include: { json: true } }).catch((e) => {
|
|
3262
|
+
throw new exports.T2000Error(
|
|
3263
|
+
"RPC_ERROR",
|
|
3264
|
+
`Job ${jobId} not found: ${e instanceof Error ? e.message : String(e)}`
|
|
3265
|
+
);
|
|
3266
|
+
});
|
|
3267
|
+
const objType = resp.object?.type ?? "";
|
|
3268
|
+
const json = resp.object?.json;
|
|
3269
|
+
if (!json || !objType.includes(`::${MODULE}::Job<`)) {
|
|
3270
|
+
throw new exports.T2000Error("RPC_ERROR", `Object ${jobId} is not an a2a_escrow Job.`);
|
|
3271
|
+
}
|
|
3272
|
+
const stateNum = Number(json.state ?? -1);
|
|
3273
|
+
const state = JOB_STATES[stateNum];
|
|
3274
|
+
if (!state) {
|
|
3275
|
+
throw new exports.T2000Error("RPC_ERROR", `Job ${jobId} has unknown state ${stateNum}.`);
|
|
3276
|
+
}
|
|
3277
|
+
const deliveredAtMs = Number(json.delivered_at_ms ?? 0);
|
|
3278
|
+
const deliveryBytes = json.delivery_hash ?? [];
|
|
3279
|
+
const hasDelivery = deliveredAtMs > 0;
|
|
3280
|
+
return {
|
|
3281
|
+
id: jobId,
|
|
3282
|
+
buyer: String(json.buyer),
|
|
3283
|
+
seller: String(json.seller),
|
|
3284
|
+
amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
|
|
3285
|
+
escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,
|
|
3286
|
+
specHash: bytesToHex2(json.spec_hash ?? []),
|
|
3287
|
+
deliverByMs: Number(json.deliver_by_ms),
|
|
3288
|
+
reviewWindowMs: Number(json.review_window_ms),
|
|
3289
|
+
rejectSplitBps: Number(json.reject_split_bps),
|
|
3290
|
+
state,
|
|
3291
|
+
deliveryHash: hasDelivery ? bytesToHex2(deliveryBytes) : null,
|
|
3292
|
+
deliveredAtMs: hasDelivery ? deliveredAtMs : null,
|
|
3293
|
+
createdAtMs: Number(json.created_at_ms)
|
|
3294
|
+
};
|
|
3295
|
+
}
|
|
3296
|
+
function jobActionsFor(job, caller, nowMs = Date.now()) {
|
|
3297
|
+
const me = validateAddress(caller);
|
|
3298
|
+
const isBuyer = me === job.buyer;
|
|
3299
|
+
const isSeller = me === job.seller;
|
|
3300
|
+
const actions = [];
|
|
3301
|
+
if (job.state === "funded") {
|
|
3302
|
+
if (isSeller && nowMs <= job.deliverByMs) actions.push("deliver");
|
|
3303
|
+
if (isBuyer) actions.push("release");
|
|
3304
|
+
if (nowMs > job.deliverByMs) actions.push("refund");
|
|
3305
|
+
} else if (job.state === "delivered") {
|
|
3306
|
+
const windowClosesMs = (job.deliveredAtMs ?? 0) + job.reviewWindowMs;
|
|
3307
|
+
if (isBuyer && nowMs <= windowClosesMs) actions.push("release", "reject");
|
|
3308
|
+
if (nowMs > windowClosesMs) actions.push("release");
|
|
3309
|
+
}
|
|
3310
|
+
return actions;
|
|
3311
|
+
}
|
|
3312
|
+
async function verifyJobForSeller({
|
|
3313
|
+
client,
|
|
3314
|
+
jobId,
|
|
3315
|
+
seller,
|
|
3316
|
+
minAmountUsdc,
|
|
3317
|
+
minRunwayMs = 6e4
|
|
3318
|
+
}) {
|
|
3319
|
+
const job = await getJob(client, jobId);
|
|
3320
|
+
const problems = [];
|
|
3321
|
+
if (job.state !== "funded") {
|
|
3322
|
+
problems.push(`state is "${job.state}", expected "funded"`);
|
|
3323
|
+
}
|
|
3324
|
+
if (job.seller !== validateAddress(seller)) {
|
|
3325
|
+
problems.push(`job pays ${job.seller}, not this seller`);
|
|
3326
|
+
}
|
|
3327
|
+
if (job.escrowUsdc < minAmountUsdc) {
|
|
3328
|
+
problems.push(`escrow holds ${job.escrowUsdc} USDC, price is ${minAmountUsdc}`);
|
|
3329
|
+
}
|
|
3330
|
+
if (job.deliverByMs - Date.now() < minRunwayMs) {
|
|
3331
|
+
problems.push("deadline too close to accept");
|
|
3332
|
+
}
|
|
3333
|
+
return { ok: problems.length === 0, job, problems };
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
// src/index.ts
|
|
3125
3337
|
init_coinSelection();
|
|
3126
3338
|
|
|
3127
3339
|
// src/composeTx.ts
|
|
@@ -3545,6 +3757,7 @@ function displayHandle(label, parentName = AUDRIC_PARENT_NAME) {
|
|
|
3545
3757
|
// src/index.ts
|
|
3546
3758
|
init_preflight();
|
|
3547
3759
|
|
|
3760
|
+
exports.A2A_ESCROW_PACKAGE_ID = A2A_ESCROW_PACKAGE_ID;
|
|
3548
3761
|
exports.AGENT_ID_PARENT = AGENT_ID_PARENT;
|
|
3549
3762
|
exports.AGENT_ID_PARENT_NAME = AGENT_ID_PARENT_NAME;
|
|
3550
3763
|
exports.AGENT_ID_PARENT_NFT_ID = AGENT_ID_PARENT_NFT_ID;
|
|
@@ -3560,11 +3773,13 @@ exports.GASLESS_MIN_STABLE_AMOUNT = GASLESS_MIN_STABLE_AMOUNT;
|
|
|
3560
3773
|
exports.GASLESS_STABLE_TYPES = GASLESS_STABLE_TYPES;
|
|
3561
3774
|
exports.GAS_RESERVE_MIN = GAS_RESERVE_MIN;
|
|
3562
3775
|
exports.InvalidAddressError = InvalidAddressError;
|
|
3776
|
+
exports.JOB_STATES = JOB_STATES;
|
|
3563
3777
|
exports.KNOWN_TARGETS = KNOWN_TARGETS;
|
|
3564
3778
|
exports.KeypairSigner = KeypairSigner;
|
|
3565
3779
|
exports.LABEL_PATTERNS = LABEL_PATTERNS;
|
|
3566
3780
|
exports.LimitEnforcer = LimitEnforcer;
|
|
3567
3781
|
exports.LimitExceededError = LimitExceededError;
|
|
3782
|
+
exports.MAX_JOB_USDC = MAX_JOB_USDC;
|
|
3568
3783
|
exports.MIST_PER_SUI = MIST_PER_SUI;
|
|
3569
3784
|
exports.OPERATION_ASSETS = OPERATION_ASSETS;
|
|
3570
3785
|
exports.SENDABLE_ASSETS = SENDABLE_ASSETS;
|
|
@@ -3588,6 +3803,11 @@ exports.approxUsdValue = approxUsdValue;
|
|
|
3588
3803
|
exports.assertAllowedAsset = assertAllowedAsset;
|
|
3589
3804
|
exports.assertLimitConfig = assertLimitConfig;
|
|
3590
3805
|
exports.buildAddLeafTx = buildAddLeafTx;
|
|
3806
|
+
exports.buildCreateJobTx = buildCreateJobTx;
|
|
3807
|
+
exports.buildDeliverJobTx = buildDeliverJobTx;
|
|
3808
|
+
exports.buildRefundJobTx = buildRefundJobTx;
|
|
3809
|
+
exports.buildRejectJobTx = buildRejectJobTx;
|
|
3810
|
+
exports.buildReleaseJobTx = buildReleaseJobTx;
|
|
3591
3811
|
exports.buildRevokeLeafTx = buildRevokeLeafTx;
|
|
3592
3812
|
exports.buildSendTx = buildSendTx;
|
|
3593
3813
|
exports.buildSwapTx = buildSwapTx;
|
|
@@ -3622,6 +3842,7 @@ exports.getAddress = getAddress;
|
|
|
3622
3842
|
exports.getCoinMeta = getCoinMeta;
|
|
3623
3843
|
exports.getDecimals = getDecimals;
|
|
3624
3844
|
exports.getDecimalsForCoinType = getDecimalsForCoinType;
|
|
3845
|
+
exports.getJob = getJob;
|
|
3625
3846
|
exports.getLimits = getLimits;
|
|
3626
3847
|
exports.getSponsoredSwapProviders = getSponsoredSwapProviders;
|
|
3627
3848
|
exports.getSuiClient = getSuiClient;
|
|
@@ -3631,6 +3852,7 @@ exports.hasLimits = hasLimits;
|
|
|
3631
3852
|
exports.isAllowedAsset = isAllowedAsset;
|
|
3632
3853
|
exports.isCetusRouteFresh = isCetusRouteFresh;
|
|
3633
3854
|
exports.isInRegistry = isInRegistry;
|
|
3855
|
+
exports.jobActionsFor = jobActionsFor;
|
|
3634
3856
|
exports.keypairFromPrivateKey = keypairFromPrivateKey;
|
|
3635
3857
|
exports.listModels = listModels;
|
|
3636
3858
|
exports.loadKey = loadKey;
|
|
@@ -3644,6 +3866,7 @@ exports.normalizeCoinType = normalizeCoinType;
|
|
|
3644
3866
|
exports.parseMppSuiChallenge = parseMppSuiChallenge;
|
|
3645
3867
|
exports.parseSuiRpcTx = parseSuiRpcTx;
|
|
3646
3868
|
exports.payWithMpp = payWithMpp;
|
|
3869
|
+
exports.preflightCreateJob = preflightCreateJob;
|
|
3647
3870
|
exports.preflightFail = preflightFail;
|
|
3648
3871
|
exports.preflightPay = preflightPay;
|
|
3649
3872
|
exports.preflightSend = preflightSend;
|
|
@@ -3675,6 +3898,7 @@ exports.usdcToRaw = usdcToRaw;
|
|
|
3675
3898
|
exports.validateAddress = validateAddress;
|
|
3676
3899
|
exports.validateLabel = validateLabel;
|
|
3677
3900
|
exports.verifyCetusRouteCoinMatch = verifyCetusRouteCoinMatch;
|
|
3901
|
+
exports.verifyJobForSeller = verifyJobForSeller;
|
|
3678
3902
|
exports.verifyReceipt = verifyReceipt;
|
|
3679
3903
|
exports.walletExists = walletExists;
|
|
3680
3904
|
exports.writeLimitsFile = writeLimitsFile;
|