@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 +213 -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 +202 -1
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +216 -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 +205 -1
- package/dist/index.js.map +1 -1
- package/dist/{send-YAYf0YR3.d.cts → job-CSq0DRsC.d.cts} +107 -1
- package/dist/{send-YAYf0YR3.d.ts → job-CSq0DRsC.d.ts} +107 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3131,6 +3131,210 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
3131
3131
|
|
|
3132
3132
|
// src/index.ts
|
|
3133
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
|
+
const arr = typeof bytes === "string" ? Array.from(atob(bytes), (c) => c.charCodeAt(0)) : bytes;
|
|
3167
|
+
let s = "0x";
|
|
3168
|
+
for (const b of arr) s += b.toString(16).padStart(2, "0");
|
|
3169
|
+
return s;
|
|
3170
|
+
}
|
|
3171
|
+
function preflightCreateJob(terms) {
|
|
3172
|
+
const addressCheck = checkSuiAddress(terms.seller);
|
|
3173
|
+
if (!addressCheck.valid) return addressCheck;
|
|
3174
|
+
if (!Number.isFinite(terms.amountUsdc) || terms.amountUsdc <= 0) {
|
|
3175
|
+
return preflightFail("INVALID_AMOUNT", `Amount must be positive. Got ${terms.amountUsdc}.`);
|
|
3176
|
+
}
|
|
3177
|
+
if (terms.amountUsdc > MAX_JOB_USDC) {
|
|
3178
|
+
return preflightFail(
|
|
3179
|
+
"INVALID_AMOUNT",
|
|
3180
|
+
`v1 caps escrow jobs at ${MAX_JOB_USDC} USDC (no-arbitration split only stays fair at small sizes). Got ${terms.amountUsdc}.`
|
|
3181
|
+
);
|
|
3182
|
+
}
|
|
3183
|
+
if (terms.deliverByMs <= Date.now()) {
|
|
3184
|
+
return preflightFail("INVALID_AMOUNT", "deliverByMs must be in the future.");
|
|
3185
|
+
}
|
|
3186
|
+
if (terms.reviewWindowMs < 0) {
|
|
3187
|
+
return preflightFail("INVALID_AMOUNT", "reviewWindowMs must be \u2265 0.");
|
|
3188
|
+
}
|
|
3189
|
+
if (!Number.isInteger(terms.rejectSplitBps) || terms.rejectSplitBps < 0 || terms.rejectSplitBps > 1e4) {
|
|
3190
|
+
return preflightFail("INVALID_AMOUNT", "rejectSplitBps must be an integer 0\u201310000.");
|
|
3191
|
+
}
|
|
3192
|
+
try {
|
|
3193
|
+
hexToBytes2(terms.specHash);
|
|
3194
|
+
} catch (e) {
|
|
3195
|
+
return preflightFail("INVALID_AMOUNT", e.message);
|
|
3196
|
+
}
|
|
3197
|
+
return exports.PREFLIGHT_OK;
|
|
3198
|
+
}
|
|
3199
|
+
async function buildCreateJobTx({
|
|
3200
|
+
client,
|
|
3201
|
+
buyer,
|
|
3202
|
+
terms
|
|
3203
|
+
}) {
|
|
3204
|
+
const pf = preflightCreateJob(terms);
|
|
3205
|
+
if (!pf.valid) throw new exports.T2000Error(pf.code, pf.error);
|
|
3206
|
+
const seller = validateAddress(terms.seller);
|
|
3207
|
+
if (seller === validateAddress(buyer)) {
|
|
3208
|
+
throw new exports.T2000Error("INVALID_ADDRESS", "Buyer and seller must be different wallets.");
|
|
3209
|
+
}
|
|
3210
|
+
const rawAmount = BigInt(Math.floor(terms.amountUsdc * 10 ** USDC_DECIMALS));
|
|
3211
|
+
const tx = new transactions.Transaction();
|
|
3212
|
+
const { coin } = await selectAndSplitCoin(tx, client, buyer, exports.USDC_TYPE, rawAmount, {
|
|
3213
|
+
allowSwapAll: false
|
|
3214
|
+
});
|
|
3215
|
+
tx.moveCall({
|
|
3216
|
+
target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::create`,
|
|
3217
|
+
typeArguments: [exports.USDC_TYPE],
|
|
3218
|
+
arguments: [
|
|
3219
|
+
tx.pure.address(seller),
|
|
3220
|
+
coin,
|
|
3221
|
+
tx.pure.vector("u8", hexToBytes2(terms.specHash)),
|
|
3222
|
+
tx.pure.u64(terms.deliverByMs),
|
|
3223
|
+
tx.pure.u64(terms.reviewWindowMs),
|
|
3224
|
+
tx.pure.u64(terms.rejectSplitBps),
|
|
3225
|
+
tx.object(CLOCK_ID2)
|
|
3226
|
+
]
|
|
3227
|
+
});
|
|
3228
|
+
return tx;
|
|
3229
|
+
}
|
|
3230
|
+
function jobCall(jobId, fn) {
|
|
3231
|
+
const tx = new transactions.Transaction();
|
|
3232
|
+
tx.moveCall({
|
|
3233
|
+
target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::${fn}`,
|
|
3234
|
+
typeArguments: [exports.USDC_TYPE],
|
|
3235
|
+
arguments: [tx.object(jobId), tx.object(CLOCK_ID2)]
|
|
3236
|
+
});
|
|
3237
|
+
return tx;
|
|
3238
|
+
}
|
|
3239
|
+
function buildDeliverJobTx(jobId, deliveryHash) {
|
|
3240
|
+
const tx = new transactions.Transaction();
|
|
3241
|
+
tx.moveCall({
|
|
3242
|
+
target: `${A2A_ESCROW_PACKAGE_ID}::${MODULE}::deliver`,
|
|
3243
|
+
typeArguments: [exports.USDC_TYPE],
|
|
3244
|
+
arguments: [
|
|
3245
|
+
tx.object(jobId),
|
|
3246
|
+
tx.pure.vector("u8", hexToBytes2(deliveryHash)),
|
|
3247
|
+
tx.object(CLOCK_ID2)
|
|
3248
|
+
]
|
|
3249
|
+
});
|
|
3250
|
+
return tx;
|
|
3251
|
+
}
|
|
3252
|
+
function buildReleaseJobTx(jobId) {
|
|
3253
|
+
return jobCall(jobId, "release");
|
|
3254
|
+
}
|
|
3255
|
+
function buildRejectJobTx(jobId) {
|
|
3256
|
+
return jobCall(jobId, "reject");
|
|
3257
|
+
}
|
|
3258
|
+
function buildRefundJobTx(jobId) {
|
|
3259
|
+
return jobCall(jobId, "refund");
|
|
3260
|
+
}
|
|
3261
|
+
async function getJob(client, jobId) {
|
|
3262
|
+
const resp = await client.core.getObject({ objectId: jobId, include: { json: true } }).catch((e) => {
|
|
3263
|
+
throw new exports.T2000Error(
|
|
3264
|
+
"RPC_ERROR",
|
|
3265
|
+
`Job ${jobId} not found: ${e instanceof Error ? e.message : String(e)}`
|
|
3266
|
+
);
|
|
3267
|
+
});
|
|
3268
|
+
const objType = resp.object?.type ?? "";
|
|
3269
|
+
const json = resp.object?.json;
|
|
3270
|
+
if (!json || !objType.includes(`::${MODULE}::Job<`)) {
|
|
3271
|
+
throw new exports.T2000Error("RPC_ERROR", `Object ${jobId} is not an a2a_escrow Job.`);
|
|
3272
|
+
}
|
|
3273
|
+
const stateNum = Number(json.state ?? -1);
|
|
3274
|
+
const state = JOB_STATES[stateNum];
|
|
3275
|
+
if (!state) {
|
|
3276
|
+
throw new exports.T2000Error("RPC_ERROR", `Job ${jobId} has unknown state ${stateNum}.`);
|
|
3277
|
+
}
|
|
3278
|
+
const deliveredAtMs = Number(json.delivered_at_ms ?? 0);
|
|
3279
|
+
const deliveryBytes = json.delivery_hash ?? [];
|
|
3280
|
+
const hasDelivery = deliveredAtMs > 0;
|
|
3281
|
+
return {
|
|
3282
|
+
id: jobId,
|
|
3283
|
+
buyer: String(json.buyer),
|
|
3284
|
+
seller: String(json.seller),
|
|
3285
|
+
amountUsdc: Number(json.amount) / 10 ** USDC_DECIMALS,
|
|
3286
|
+
escrowUsdc: Number(json.escrow) / 10 ** USDC_DECIMALS,
|
|
3287
|
+
specHash: bytesToHex2(json.spec_hash ?? []),
|
|
3288
|
+
deliverByMs: Number(json.deliver_by_ms),
|
|
3289
|
+
reviewWindowMs: Number(json.review_window_ms),
|
|
3290
|
+
rejectSplitBps: Number(json.reject_split_bps),
|
|
3291
|
+
state,
|
|
3292
|
+
deliveryHash: hasDelivery ? bytesToHex2(deliveryBytes) : null,
|
|
3293
|
+
deliveredAtMs: hasDelivery ? deliveredAtMs : null,
|
|
3294
|
+
createdAtMs: Number(json.created_at_ms)
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3297
|
+
function jobActionsFor(job, caller, nowMs = Date.now()) {
|
|
3298
|
+
const me = validateAddress(caller);
|
|
3299
|
+
const isBuyer = me === job.buyer;
|
|
3300
|
+
const isSeller = me === job.seller;
|
|
3301
|
+
const actions = [];
|
|
3302
|
+
if (job.state === "funded") {
|
|
3303
|
+
if (isSeller && nowMs <= job.deliverByMs) actions.push("deliver");
|
|
3304
|
+
if (isBuyer) actions.push("release");
|
|
3305
|
+
if (nowMs > job.deliverByMs) actions.push("refund");
|
|
3306
|
+
} else if (job.state === "delivered") {
|
|
3307
|
+
const windowClosesMs = (job.deliveredAtMs ?? 0) + job.reviewWindowMs;
|
|
3308
|
+
if (isBuyer && nowMs <= windowClosesMs) actions.push("release", "reject");
|
|
3309
|
+
if (nowMs > windowClosesMs) actions.push("release");
|
|
3310
|
+
}
|
|
3311
|
+
return actions;
|
|
3312
|
+
}
|
|
3313
|
+
async function verifyJobForSeller({
|
|
3314
|
+
client,
|
|
3315
|
+
jobId,
|
|
3316
|
+
seller,
|
|
3317
|
+
minAmountUsdc,
|
|
3318
|
+
minRunwayMs = 6e4
|
|
3319
|
+
}) {
|
|
3320
|
+
const job = await getJob(client, jobId);
|
|
3321
|
+
const problems = [];
|
|
3322
|
+
if (job.state !== "funded") {
|
|
3323
|
+
problems.push(`state is "${job.state}", expected "funded"`);
|
|
3324
|
+
}
|
|
3325
|
+
if (job.seller !== validateAddress(seller)) {
|
|
3326
|
+
problems.push(`job pays ${job.seller}, not this seller`);
|
|
3327
|
+
}
|
|
3328
|
+
if (job.escrowUsdc < minAmountUsdc) {
|
|
3329
|
+
problems.push(`escrow holds ${job.escrowUsdc} USDC, price is ${minAmountUsdc}`);
|
|
3330
|
+
}
|
|
3331
|
+
if (job.deliverByMs - Date.now() < minRunwayMs) {
|
|
3332
|
+
problems.push("deadline too close to accept");
|
|
3333
|
+
}
|
|
3334
|
+
return { ok: problems.length === 0, job, problems };
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
// src/index.ts
|
|
3134
3338
|
init_coinSelection();
|
|
3135
3339
|
|
|
3136
3340
|
// src/composeTx.ts
|
|
@@ -3554,6 +3758,7 @@ function displayHandle(label, parentName = AUDRIC_PARENT_NAME) {
|
|
|
3554
3758
|
// src/index.ts
|
|
3555
3759
|
init_preflight();
|
|
3556
3760
|
|
|
3761
|
+
exports.A2A_ESCROW_PACKAGE_ID = A2A_ESCROW_PACKAGE_ID;
|
|
3557
3762
|
exports.AGENT_ID_PARENT = AGENT_ID_PARENT;
|
|
3558
3763
|
exports.AGENT_ID_PARENT_NAME = AGENT_ID_PARENT_NAME;
|
|
3559
3764
|
exports.AGENT_ID_PARENT_NFT_ID = AGENT_ID_PARENT_NFT_ID;
|
|
@@ -3569,11 +3774,13 @@ exports.GASLESS_MIN_STABLE_AMOUNT = GASLESS_MIN_STABLE_AMOUNT;
|
|
|
3569
3774
|
exports.GASLESS_STABLE_TYPES = GASLESS_STABLE_TYPES;
|
|
3570
3775
|
exports.GAS_RESERVE_MIN = GAS_RESERVE_MIN;
|
|
3571
3776
|
exports.InvalidAddressError = InvalidAddressError;
|
|
3777
|
+
exports.JOB_STATES = JOB_STATES;
|
|
3572
3778
|
exports.KNOWN_TARGETS = KNOWN_TARGETS;
|
|
3573
3779
|
exports.KeypairSigner = KeypairSigner;
|
|
3574
3780
|
exports.LABEL_PATTERNS = LABEL_PATTERNS;
|
|
3575
3781
|
exports.LimitEnforcer = LimitEnforcer;
|
|
3576
3782
|
exports.LimitExceededError = LimitExceededError;
|
|
3783
|
+
exports.MAX_JOB_USDC = MAX_JOB_USDC;
|
|
3577
3784
|
exports.MIST_PER_SUI = MIST_PER_SUI;
|
|
3578
3785
|
exports.OPERATION_ASSETS = OPERATION_ASSETS;
|
|
3579
3786
|
exports.SENDABLE_ASSETS = SENDABLE_ASSETS;
|
|
@@ -3597,6 +3804,11 @@ exports.approxUsdValue = approxUsdValue;
|
|
|
3597
3804
|
exports.assertAllowedAsset = assertAllowedAsset;
|
|
3598
3805
|
exports.assertLimitConfig = assertLimitConfig;
|
|
3599
3806
|
exports.buildAddLeafTx = buildAddLeafTx;
|
|
3807
|
+
exports.buildCreateJobTx = buildCreateJobTx;
|
|
3808
|
+
exports.buildDeliverJobTx = buildDeliverJobTx;
|
|
3809
|
+
exports.buildRefundJobTx = buildRefundJobTx;
|
|
3810
|
+
exports.buildRejectJobTx = buildRejectJobTx;
|
|
3811
|
+
exports.buildReleaseJobTx = buildReleaseJobTx;
|
|
3600
3812
|
exports.buildRevokeLeafTx = buildRevokeLeafTx;
|
|
3601
3813
|
exports.buildSendTx = buildSendTx;
|
|
3602
3814
|
exports.buildSwapTx = buildSwapTx;
|
|
@@ -3631,6 +3843,7 @@ exports.getAddress = getAddress;
|
|
|
3631
3843
|
exports.getCoinMeta = getCoinMeta;
|
|
3632
3844
|
exports.getDecimals = getDecimals;
|
|
3633
3845
|
exports.getDecimalsForCoinType = getDecimalsForCoinType;
|
|
3846
|
+
exports.getJob = getJob;
|
|
3634
3847
|
exports.getLimits = getLimits;
|
|
3635
3848
|
exports.getSponsoredSwapProviders = getSponsoredSwapProviders;
|
|
3636
3849
|
exports.getSuiClient = getSuiClient;
|
|
@@ -3640,6 +3853,7 @@ exports.hasLimits = hasLimits;
|
|
|
3640
3853
|
exports.isAllowedAsset = isAllowedAsset;
|
|
3641
3854
|
exports.isCetusRouteFresh = isCetusRouteFresh;
|
|
3642
3855
|
exports.isInRegistry = isInRegistry;
|
|
3856
|
+
exports.jobActionsFor = jobActionsFor;
|
|
3643
3857
|
exports.keypairFromPrivateKey = keypairFromPrivateKey;
|
|
3644
3858
|
exports.listModels = listModels;
|
|
3645
3859
|
exports.loadKey = loadKey;
|
|
@@ -3653,6 +3867,7 @@ exports.normalizeCoinType = normalizeCoinType;
|
|
|
3653
3867
|
exports.parseMppSuiChallenge = parseMppSuiChallenge;
|
|
3654
3868
|
exports.parseSuiRpcTx = parseSuiRpcTx;
|
|
3655
3869
|
exports.payWithMpp = payWithMpp;
|
|
3870
|
+
exports.preflightCreateJob = preflightCreateJob;
|
|
3656
3871
|
exports.preflightFail = preflightFail;
|
|
3657
3872
|
exports.preflightPay = preflightPay;
|
|
3658
3873
|
exports.preflightSend = preflightSend;
|
|
@@ -3684,6 +3899,7 @@ exports.usdcToRaw = usdcToRaw;
|
|
|
3684
3899
|
exports.validateAddress = validateAddress;
|
|
3685
3900
|
exports.validateLabel = validateLabel;
|
|
3686
3901
|
exports.verifyCetusRouteCoinMatch = verifyCetusRouteCoinMatch;
|
|
3902
|
+
exports.verifyJobForSeller = verifyJobForSeller;
|
|
3687
3903
|
exports.verifyReceipt = verifyReceipt;
|
|
3688
3904
|
exports.walletExists = walletExists;
|
|
3689
3905
|
exports.writeLimitsFile = writeLimitsFile;
|