uvd-x402-sdk 2.85.0 → 2.87.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/backend/index.d.mts +3 -3474
- package/dist/backend/index.d.ts +3 -3474
- package/dist/backend/index.js +302 -49
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/index.mjs +302 -49
- package/dist/backend/index.mjs.map +1 -1
- package/dist/index-BHfYxpzI.d.mts +3865 -0
- package/dist/index-D67eNxY8.d.ts +3865 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +274 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +265 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/backend/index.ts +167 -28
- package/src/index.ts +24 -0
- package/src/lifecycle-auth.ts +690 -0
- package/src/lifecycle-auth.vectors.json +28 -0
package/dist/backend/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import 'ethers';
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
2
|
|
|
3
3
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
4
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
@@ -46,6 +46,19 @@ var CAIP2_IDENTIFIERS = {
|
|
|
46
46
|
var CAIP2_TO_CHAIN = Object.fromEntries(
|
|
47
47
|
Object.entries(CAIP2_IDENTIFIERS).map(([k, v]) => [v, k])
|
|
48
48
|
);
|
|
49
|
+
var X402Error = class _X402Error extends Error {
|
|
50
|
+
code;
|
|
51
|
+
details;
|
|
52
|
+
constructor(message, code, details) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.name = "X402Error";
|
|
55
|
+
this.code = code;
|
|
56
|
+
this.details = details;
|
|
57
|
+
if (Error.captureStackTrace) {
|
|
58
|
+
Error.captureStackTrace(this, _X402Error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
49
62
|
|
|
50
63
|
// src/chains/index.ts
|
|
51
64
|
var DEFAULT_FACILITATOR_URL = "https://facilitator.ultravioletadao.xyz";
|
|
@@ -1113,6 +1126,195 @@ var DEFAULT_MIN_FEE_BPS = 0;
|
|
|
1113
1126
|
var DEFAULT_MAX_FEE_BPS = OPERATOR_FEE_BPS + MAX_PROTOCOL_FEE_BPS;
|
|
1114
1127
|
var REVIEW_WINDOW_SEC = 7 * 24 * 3600;
|
|
1115
1128
|
var REFUND_WINDOW_SEC = 7 * 24 * 3600;
|
|
1129
|
+
var LIFECYCLE_DOMAIN_NAME = "x402 escrow lifecycle";
|
|
1130
|
+
var LIFECYCLE_DOMAIN_VERSION = "1";
|
|
1131
|
+
var LIFECYCLE_MAX_DEADLINE_SECS = 900;
|
|
1132
|
+
var LIFECYCLE_DEFAULT_DEADLINE_SECS = 600;
|
|
1133
|
+
var LIFECYCLE_ACTIONS = ["release", "refundInEscrow"];
|
|
1134
|
+
var LIFECYCLE_ORDER_TYPES = {
|
|
1135
|
+
LifecycleOrder: [
|
|
1136
|
+
{ name: "action", type: "string" },
|
|
1137
|
+
{ name: "amount", type: "uint256" },
|
|
1138
|
+
{ name: "deadline", type: "uint256" },
|
|
1139
|
+
{ name: "nonce", type: "bytes32" },
|
|
1140
|
+
{ name: "paymentInfo", type: "PaymentInfo" }
|
|
1141
|
+
],
|
|
1142
|
+
PaymentInfo: [
|
|
1143
|
+
{ name: "operator", type: "address" },
|
|
1144
|
+
{ name: "payer", type: "address" },
|
|
1145
|
+
{ name: "receiver", type: "address" },
|
|
1146
|
+
{ name: "token", type: "address" },
|
|
1147
|
+
{ name: "maxAmount", type: "uint120" },
|
|
1148
|
+
{ name: "preApprovalExpiry", type: "uint48" },
|
|
1149
|
+
{ name: "authorizationExpiry", type: "uint48" },
|
|
1150
|
+
{ name: "refundExpiry", type: "uint48" },
|
|
1151
|
+
{ name: "minFeeBps", type: "uint16" },
|
|
1152
|
+
{ name: "maxFeeBps", type: "uint16" },
|
|
1153
|
+
{ name: "feeReceiver", type: "address" },
|
|
1154
|
+
{ name: "salt", type: "uint256" }
|
|
1155
|
+
]
|
|
1156
|
+
};
|
|
1157
|
+
var LIFECYCLE_PI_KEYS = [
|
|
1158
|
+
"operator",
|
|
1159
|
+
"receiver",
|
|
1160
|
+
"token",
|
|
1161
|
+
"maxAmount",
|
|
1162
|
+
"preApprovalExpiry",
|
|
1163
|
+
"authorizationExpiry",
|
|
1164
|
+
"refundExpiry",
|
|
1165
|
+
"minFeeBps",
|
|
1166
|
+
"maxFeeBps",
|
|
1167
|
+
"feeReceiver",
|
|
1168
|
+
"salt"
|
|
1169
|
+
];
|
|
1170
|
+
function saltToBigInt(salt) {
|
|
1171
|
+
if (typeof salt === "bigint") return salt;
|
|
1172
|
+
if (typeof salt === "number") {
|
|
1173
|
+
if (!Number.isInteger(salt) || salt < 0) {
|
|
1174
|
+
throw new X402Error(`paymentInfo.salt invalid: ${String(salt)}`, "INVALID_CONFIG");
|
|
1175
|
+
}
|
|
1176
|
+
return BigInt(salt);
|
|
1177
|
+
}
|
|
1178
|
+
if (typeof salt === "string") {
|
|
1179
|
+
const trimmed = salt.trim();
|
|
1180
|
+
const hex = trimmed.startsWith("0x") || trimmed.startsWith("0X") ? trimmed : `0x${trimmed}`;
|
|
1181
|
+
try {
|
|
1182
|
+
return BigInt(hex);
|
|
1183
|
+
} catch {
|
|
1184
|
+
throw new X402Error(`paymentInfo.salt invalid: ${salt}`, "INVALID_CONFIG");
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
throw new X402Error(`paymentInfo.salt invalid: ${String(salt)}`, "INVALID_CONFIG");
|
|
1188
|
+
}
|
|
1189
|
+
function nonceToBytes32(nonce) {
|
|
1190
|
+
if (typeof nonce !== "string") {
|
|
1191
|
+
throw new X402Error(`lifecycleAuth.nonce invalid: ${String(nonce)}`, "INVALID_CONFIG");
|
|
1192
|
+
}
|
|
1193
|
+
const raw = nonce.startsWith("0x") || nonce.startsWith("0X") ? nonce.slice(2) : nonce;
|
|
1194
|
+
if (!/^[0-9a-fA-F]*$/.test(raw)) {
|
|
1195
|
+
throw new X402Error(`lifecycleAuth.nonce is not hex: ${nonce}`, "INVALID_CONFIG");
|
|
1196
|
+
}
|
|
1197
|
+
if (raw.length !== 64) {
|
|
1198
|
+
throw new X402Error(
|
|
1199
|
+
`lifecycleAuth.nonce must be 32 bytes, got ${raw.length / 2}`,
|
|
1200
|
+
"INVALID_CONFIG"
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
return `0x${raw.toLowerCase()}`;
|
|
1204
|
+
}
|
|
1205
|
+
function randomNonce() {
|
|
1206
|
+
const webCrypto = globalThis.crypto;
|
|
1207
|
+
if (webCrypto?.getRandomValues) {
|
|
1208
|
+
const bytes = new Uint8Array(32);
|
|
1209
|
+
webCrypto.getRandomValues(bytes);
|
|
1210
|
+
return ethers.hexlify(bytes);
|
|
1211
|
+
}
|
|
1212
|
+
return ethers.hexlify(ethers.randomBytes(32));
|
|
1213
|
+
}
|
|
1214
|
+
function resolveOrderTiming(params) {
|
|
1215
|
+
const nowSec = params.now === void 0 ? Math.floor(Date.now() / 1e3) : Math.floor(params.now);
|
|
1216
|
+
return {
|
|
1217
|
+
nowSec,
|
|
1218
|
+
deadline: params.deadline === void 0 ? nowSec + LIFECYCLE_DEFAULT_DEADLINE_SECS : Math.floor(params.deadline),
|
|
1219
|
+
nonce: params.nonce === void 0 ? randomNonce() : params.nonce
|
|
1220
|
+
};
|
|
1221
|
+
}
|
|
1222
|
+
function toUintString(value, field) {
|
|
1223
|
+
let n;
|
|
1224
|
+
try {
|
|
1225
|
+
n = typeof value === "bigint" ? value : BigInt(value);
|
|
1226
|
+
} catch {
|
|
1227
|
+
throw new X402Error(`${field} must be a non-negative integer, got ${String(value)}`, "INVALID_CONFIG");
|
|
1228
|
+
}
|
|
1229
|
+
if (n < 0n) {
|
|
1230
|
+
throw new X402Error(`${field} must be a non-negative integer, got ${String(value)}`, "INVALID_CONFIG");
|
|
1231
|
+
}
|
|
1232
|
+
return n.toString();
|
|
1233
|
+
}
|
|
1234
|
+
function buildLifecycleTypedData(params) {
|
|
1235
|
+
const { action, paymentInfo, payer, amount, chainId } = params;
|
|
1236
|
+
const { deadline, nonce } = resolveOrderTiming(params);
|
|
1237
|
+
if (!LIFECYCLE_ACTIONS.includes(action)) {
|
|
1238
|
+
throw new X402Error(
|
|
1239
|
+
`unknown lifecycle action ${String(action)}; the facilitator only signs ${LIFECYCLE_ACTIONS.join(", ")}`,
|
|
1240
|
+
"INVALID_CONFIG"
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
let amountBig;
|
|
1244
|
+
try {
|
|
1245
|
+
amountBig = typeof amount === "bigint" ? amount : BigInt(amount);
|
|
1246
|
+
} catch {
|
|
1247
|
+
throw new X402Error(`amount must be an integer >= 0, got ${String(amount)}`, "INVALID_AMOUNT");
|
|
1248
|
+
}
|
|
1249
|
+
if (amountBig < 0n) {
|
|
1250
|
+
throw new X402Error(`amount must be an integer >= 0, got ${String(amount)}`, "INVALID_AMOUNT");
|
|
1251
|
+
}
|
|
1252
|
+
const pi = paymentInfo ?? {};
|
|
1253
|
+
const missing = LIFECYCLE_PI_KEYS.filter((k) => pi[k] === void 0);
|
|
1254
|
+
if (missing.length > 0) {
|
|
1255
|
+
throw new X402Error(
|
|
1256
|
+
`paymentInfo is missing fields that enter the signature: ${missing.join(", ")}. The paymentInfo that is SENT is the one that is signed; defaulting a field would sign a different struct than the one that reaches the facilitator.`,
|
|
1257
|
+
"INVALID_CONFIG"
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
return {
|
|
1261
|
+
domain: {
|
|
1262
|
+
name: LIFECYCLE_DOMAIN_NAME,
|
|
1263
|
+
version: LIFECYCLE_DOMAIN_VERSION,
|
|
1264
|
+
chainId: Number(chainId)
|
|
1265
|
+
},
|
|
1266
|
+
types: LIFECYCLE_ORDER_TYPES,
|
|
1267
|
+
primaryType: "LifecycleOrder",
|
|
1268
|
+
message: {
|
|
1269
|
+
action,
|
|
1270
|
+
amount: amountBig.toString(),
|
|
1271
|
+
deadline: toUintString(deadline, "deadline"),
|
|
1272
|
+
nonce: nonceToBytes32(nonce),
|
|
1273
|
+
paymentInfo: {
|
|
1274
|
+
operator: ethers.getAddress(paymentInfo.operator),
|
|
1275
|
+
payer: ethers.getAddress(payer),
|
|
1276
|
+
receiver: ethers.getAddress(paymentInfo.receiver),
|
|
1277
|
+
token: ethers.getAddress(paymentInfo.token),
|
|
1278
|
+
maxAmount: toUintString(paymentInfo.maxAmount, "paymentInfo.maxAmount"),
|
|
1279
|
+
preApprovalExpiry: toUintString(paymentInfo.preApprovalExpiry, "paymentInfo.preApprovalExpiry"),
|
|
1280
|
+
authorizationExpiry: toUintString(
|
|
1281
|
+
paymentInfo.authorizationExpiry,
|
|
1282
|
+
"paymentInfo.authorizationExpiry"
|
|
1283
|
+
),
|
|
1284
|
+
refundExpiry: toUintString(paymentInfo.refundExpiry, "paymentInfo.refundExpiry"),
|
|
1285
|
+
minFeeBps: toUintString(paymentInfo.minFeeBps, "paymentInfo.minFeeBps"),
|
|
1286
|
+
maxFeeBps: toUintString(paymentInfo.maxFeeBps, "paymentInfo.maxFeeBps"),
|
|
1287
|
+
feeReceiver: ethers.getAddress(paymentInfo.feeReceiver),
|
|
1288
|
+
// uint256 in the signature, bytes32 on the wire — see saltToBigInt.
|
|
1289
|
+
salt: saltToBigInt(paymentInfo.salt).toString()
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
async function buildLifecycleAuth(params) {
|
|
1295
|
+
const { wallet, ...rest } = params;
|
|
1296
|
+
const { nowSec, deadline: dl, nonce: nonceHex } = resolveOrderTiming(params);
|
|
1297
|
+
if (dl < nowSec) {
|
|
1298
|
+
throw new X402Error(
|
|
1299
|
+
`deadline ${dl} is in the past (now ${nowSec}): the facilitator discards it as \`expired\``,
|
|
1300
|
+
"INVALID_CONFIG"
|
|
1301
|
+
);
|
|
1302
|
+
}
|
|
1303
|
+
if (dl - nowSec > LIFECYCLE_MAX_DEADLINE_SECS) {
|
|
1304
|
+
throw new X402Error(
|
|
1305
|
+
`deadline ${dl} is ${dl - nowSec} s ahead and the facilitator's ceiling is ${LIFECYCLE_MAX_DEADLINE_SECS} s (\`deadline_too_far\`): a leaked order cannot be a standing permission`,
|
|
1306
|
+
"INVALID_CONFIG"
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
const typed = buildLifecycleTypedData({ ...rest, deadline: dl, nonce: nonceHex });
|
|
1310
|
+
const signed = await wallet.signTypedData(JSON.stringify(typed));
|
|
1311
|
+
return {
|
|
1312
|
+
signer: wallet.getAddress(),
|
|
1313
|
+
deadline: dl,
|
|
1314
|
+
nonce: nonceToBytes32(nonceHex),
|
|
1315
|
+
signature: signed.signature
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1116
1318
|
|
|
1117
1319
|
// src/backend/facilitator-error.ts
|
|
1118
1320
|
var WRITER_LEASE_REASONS = [
|
|
@@ -4062,6 +4264,25 @@ var TIER_TIMINGS = {
|
|
|
4062
4264
|
premium: { pre: 14400, auth: 172800, refund: 1209600 },
|
|
4063
4265
|
enterprise: { pre: 86400, auth: 604800, refund: 2592e3 }
|
|
4064
4266
|
};
|
|
4267
|
+
async function resolveLifecycleAuth(action, options, order) {
|
|
4268
|
+
if (options?.lifecycleSigner && options?.lifecycleAuth) {
|
|
4269
|
+
throw new X402Error(
|
|
4270
|
+
"lifecycleSigner and lifecycleAuth are mutually exclusive: the first signs an order here, the second was already signed elsewhere. Passing both means two different orders exist and only one can travel.",
|
|
4271
|
+
"INVALID_CONFIG"
|
|
4272
|
+
);
|
|
4273
|
+
}
|
|
4274
|
+
if (options?.lifecycleAuth) return options.lifecycleAuth;
|
|
4275
|
+
if (!options?.lifecycleSigner) return void 0;
|
|
4276
|
+
return buildLifecycleAuth({
|
|
4277
|
+
action,
|
|
4278
|
+
paymentInfo: order.paymentInfo,
|
|
4279
|
+
payer: order.payer,
|
|
4280
|
+
amount: order.amount,
|
|
4281
|
+
chainId: order.chainId,
|
|
4282
|
+
wallet: options.lifecycleSigner,
|
|
4283
|
+
deadline: options.lifecycleDeadline
|
|
4284
|
+
});
|
|
4285
|
+
}
|
|
4065
4286
|
var OPERATOR_ABI = [
|
|
4066
4287
|
"function release(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint256 amount)",
|
|
4067
4288
|
"function refundInEscrow(tuple(address operator, address payer, address receiver, address token, uint120 maxAmount, uint48 preApprovalExpiry, uint48 authorizationExpiry, uint48 refundExpiry, uint16 minFeeBps, uint16 maxFeeBps, address feeReceiver, uint256 salt) paymentInfo, uint120 amount)",
|
|
@@ -4202,8 +4423,8 @@ var AdvancedEscrowClient = class {
|
|
|
4202
4423
|
* Matches the on-chain AuthCaptureEscrow nonce derivation.
|
|
4203
4424
|
*/
|
|
4204
4425
|
async computeNonce(paymentInfo) {
|
|
4205
|
-
const { ethers:
|
|
4206
|
-
const piTuple =
|
|
4426
|
+
const { ethers: ethers4 } = await import('ethers');
|
|
4427
|
+
const piTuple = ethers4.AbiCoder.defaultAbiCoder().encode(
|
|
4207
4428
|
["bytes32", "tuple(address,address,address,address,uint120,uint48,uint48,uint48,uint16,uint16,address,uint256)"],
|
|
4208
4429
|
[
|
|
4209
4430
|
PAYMENT_INFO_TYPEHASH,
|
|
@@ -4224,12 +4445,12 @@ var AdvancedEscrowClient = class {
|
|
|
4224
4445
|
]
|
|
4225
4446
|
]
|
|
4226
4447
|
);
|
|
4227
|
-
const piHash =
|
|
4228
|
-
const finalEncoded =
|
|
4448
|
+
const piHash = ethers4.keccak256(piTuple);
|
|
4449
|
+
const finalEncoded = ethers4.AbiCoder.defaultAbiCoder().encode(
|
|
4229
4450
|
["uint256", "address", "bytes32"],
|
|
4230
4451
|
[this.chainId, this.contracts.escrow, piHash]
|
|
4231
4452
|
);
|
|
4232
|
-
return
|
|
4453
|
+
return ethers4.keccak256(finalEncoded);
|
|
4233
4454
|
}
|
|
4234
4455
|
/**
|
|
4235
4456
|
* Sign ReceiveWithAuthorization for ERC-3009.
|
|
@@ -4386,17 +4607,17 @@ var AdvancedEscrowClient = class {
|
|
|
4386
4607
|
async release(paymentInfo, amount) {
|
|
4387
4608
|
if (!this.payerAddress) await this.init();
|
|
4388
4609
|
try {
|
|
4389
|
-
const { ethers:
|
|
4610
|
+
const { ethers: ethers4 } = await import('ethers');
|
|
4390
4611
|
const isCreate3 = CREATE3_CHAIN_IDS.has(this.chainId);
|
|
4391
4612
|
const abi = isCreate3 ? OPERATOR_ABI_CREATE3 : OPERATOR_ABI;
|
|
4392
4613
|
const amt = amount || paymentInfo.maxAmount;
|
|
4393
4614
|
const tuple = this.buildTuple(paymentInfo);
|
|
4394
4615
|
if (this.walletAdapter) {
|
|
4395
|
-
return this.sendViaAdapter(
|
|
4616
|
+
return this.sendViaAdapter(ethers4, abi, (iface) => {
|
|
4396
4617
|
return isCreate3 ? iface.encodeFunctionData("release", [tuple, amt, "0x"]) : iface.encodeFunctionData("release", [tuple, amt]);
|
|
4397
4618
|
});
|
|
4398
4619
|
}
|
|
4399
|
-
const contract = new
|
|
4620
|
+
const contract = new ethers4.Contract(this.contracts.operator, abi, this.signer);
|
|
4400
4621
|
const tx = isCreate3 ? await contract.release(tuple, amt, "0x", { gasLimit: this.gasLimit }) : await contract.release(tuple, amt, { gasLimit: this.gasLimit });
|
|
4401
4622
|
const receipt = await tx.wait();
|
|
4402
4623
|
return {
|
|
@@ -4420,17 +4641,17 @@ var AdvancedEscrowClient = class {
|
|
|
4420
4641
|
async refundInEscrow(paymentInfo, amount) {
|
|
4421
4642
|
if (!this.payerAddress) await this.init();
|
|
4422
4643
|
try {
|
|
4423
|
-
const { ethers:
|
|
4644
|
+
const { ethers: ethers4 } = await import('ethers');
|
|
4424
4645
|
const isCreate3 = CREATE3_CHAIN_IDS.has(this.chainId);
|
|
4425
4646
|
const abi = isCreate3 ? OPERATOR_ABI_CREATE3 : OPERATOR_ABI;
|
|
4426
4647
|
const amt = amount || paymentInfo.maxAmount;
|
|
4427
4648
|
const tuple = this.buildTuple(paymentInfo);
|
|
4428
4649
|
if (this.walletAdapter) {
|
|
4429
|
-
return this.sendViaAdapter(
|
|
4650
|
+
return this.sendViaAdapter(ethers4, abi, (iface) => {
|
|
4430
4651
|
return isCreate3 ? iface.encodeFunctionData("refundInEscrow", [tuple, amt, "0x"]) : iface.encodeFunctionData("refundInEscrow", [tuple, amt]);
|
|
4431
4652
|
});
|
|
4432
4653
|
}
|
|
4433
|
-
const contract = new
|
|
4654
|
+
const contract = new ethers4.Contract(this.contracts.operator, abi, this.signer);
|
|
4434
4655
|
const tx = isCreate3 ? await contract.refundInEscrow(tuple, amt, "0x", { gasLimit: this.gasLimit }) : await contract.refundInEscrow(tuple, amt, { gasLimit: this.gasLimit });
|
|
4435
4656
|
const receipt = await tx.wait();
|
|
4436
4657
|
return {
|
|
@@ -4465,30 +4686,53 @@ var AdvancedEscrowClient = class {
|
|
|
4465
4686
|
* const result = await client.releaseViaFacilitator(pi);
|
|
4466
4687
|
* console.log(result.transactionHash);
|
|
4467
4688
|
* ```
|
|
4689
|
+
*
|
|
4690
|
+
* @example Signed release (the payer proves the release is theirs to ask for)
|
|
4691
|
+
* ```typescript
|
|
4692
|
+
* await client.releaseViaFacilitator(pi, undefined, {
|
|
4693
|
+
* lifecycleSigner: payerWallet, // EnvKeyAdapter, OWS, wagmiLifecycleSigner(...)
|
|
4694
|
+
* });
|
|
4695
|
+
* ```
|
|
4696
|
+
*
|
|
4697
|
+
* @example Transporting an order the publisher signed in their browser
|
|
4698
|
+
* ```typescript
|
|
4699
|
+
* // The browser sent back a signature over a document THIS backend built.
|
|
4700
|
+
* const lifecycleAuth = lifecycleAuthFromSignature(typedData, signature, payer);
|
|
4701
|
+
* await client.releaseViaFacilitator(pi, amount, { lifecycleAuth });
|
|
4702
|
+
* ```
|
|
4468
4703
|
*/
|
|
4469
|
-
async releaseViaFacilitator(paymentInfo, amount) {
|
|
4704
|
+
async releaseViaFacilitator(paymentInfo, amount, options) {
|
|
4470
4705
|
if (!this.payerAddress) await this.init();
|
|
4471
4706
|
try {
|
|
4707
|
+
const wirePaymentInfo = {
|
|
4708
|
+
operator: paymentInfo.operator,
|
|
4709
|
+
receiver: paymentInfo.receiver,
|
|
4710
|
+
token: paymentInfo.token,
|
|
4711
|
+
maxAmount: paymentInfo.maxAmount,
|
|
4712
|
+
preApprovalExpiry: paymentInfo.preApprovalExpiry,
|
|
4713
|
+
authorizationExpiry: paymentInfo.authorizationExpiry,
|
|
4714
|
+
refundExpiry: paymentInfo.refundExpiry,
|
|
4715
|
+
minFeeBps: paymentInfo.minFeeBps,
|
|
4716
|
+
maxFeeBps: paymentInfo.maxFeeBps,
|
|
4717
|
+
feeReceiver: paymentInfo.feeReceiver,
|
|
4718
|
+
salt: paymentInfo.salt
|
|
4719
|
+
};
|
|
4720
|
+
const releaseAmount = amount || paymentInfo.maxAmount;
|
|
4721
|
+
const lifecycleAuth = await resolveLifecycleAuth("release", options, {
|
|
4722
|
+
paymentInfo: wirePaymentInfo,
|
|
4723
|
+
payer: this.payerAddress,
|
|
4724
|
+
amount: releaseAmount,
|
|
4725
|
+
chainId: this.chainId
|
|
4726
|
+
});
|
|
4472
4727
|
const payload = {
|
|
4473
4728
|
x402Version: 2,
|
|
4474
4729
|
scheme: "escrow",
|
|
4475
4730
|
action: "release",
|
|
4476
4731
|
payload: {
|
|
4477
|
-
paymentInfo:
|
|
4478
|
-
operator: paymentInfo.operator,
|
|
4479
|
-
receiver: paymentInfo.receiver,
|
|
4480
|
-
token: paymentInfo.token,
|
|
4481
|
-
maxAmount: paymentInfo.maxAmount,
|
|
4482
|
-
preApprovalExpiry: paymentInfo.preApprovalExpiry,
|
|
4483
|
-
authorizationExpiry: paymentInfo.authorizationExpiry,
|
|
4484
|
-
refundExpiry: paymentInfo.refundExpiry,
|
|
4485
|
-
minFeeBps: paymentInfo.minFeeBps,
|
|
4486
|
-
maxFeeBps: paymentInfo.maxFeeBps,
|
|
4487
|
-
feeReceiver: paymentInfo.feeReceiver,
|
|
4488
|
-
salt: paymentInfo.salt
|
|
4489
|
-
},
|
|
4732
|
+
paymentInfo: wirePaymentInfo,
|
|
4490
4733
|
payer: this.payerAddress,
|
|
4491
|
-
amount:
|
|
4734
|
+
amount: releaseAmount,
|
|
4735
|
+
...lifecycleAuth ? { lifecycleAuth } : {}
|
|
4492
4736
|
},
|
|
4493
4737
|
paymentRequirements: {
|
|
4494
4738
|
scheme: "escrow",
|
|
@@ -4591,29 +4835,38 @@ var AdvancedEscrowClient = class {
|
|
|
4591
4835
|
* }
|
|
4592
4836
|
* ```
|
|
4593
4837
|
*/
|
|
4594
|
-
async refundViaFacilitator(paymentInfo, amount) {
|
|
4838
|
+
async refundViaFacilitator(paymentInfo, amount, options) {
|
|
4595
4839
|
if (!this.payerAddress) await this.init();
|
|
4596
4840
|
try {
|
|
4841
|
+
const wirePaymentInfo = {
|
|
4842
|
+
operator: paymentInfo.operator,
|
|
4843
|
+
receiver: paymentInfo.receiver,
|
|
4844
|
+
token: paymentInfo.token,
|
|
4845
|
+
maxAmount: paymentInfo.maxAmount,
|
|
4846
|
+
preApprovalExpiry: paymentInfo.preApprovalExpiry,
|
|
4847
|
+
authorizationExpiry: paymentInfo.authorizationExpiry,
|
|
4848
|
+
refundExpiry: paymentInfo.refundExpiry,
|
|
4849
|
+
minFeeBps: paymentInfo.minFeeBps,
|
|
4850
|
+
maxFeeBps: paymentInfo.maxFeeBps,
|
|
4851
|
+
feeReceiver: paymentInfo.feeReceiver,
|
|
4852
|
+
salt: paymentInfo.salt
|
|
4853
|
+
};
|
|
4854
|
+
const refundAmount = amount || paymentInfo.maxAmount;
|
|
4855
|
+
const lifecycleAuth = await resolveLifecycleAuth("refundInEscrow", options, {
|
|
4856
|
+
paymentInfo: wirePaymentInfo,
|
|
4857
|
+
payer: this.payerAddress,
|
|
4858
|
+
amount: refundAmount,
|
|
4859
|
+
chainId: this.chainId
|
|
4860
|
+
});
|
|
4597
4861
|
const payload = {
|
|
4598
4862
|
x402Version: 2,
|
|
4599
4863
|
scheme: "escrow",
|
|
4600
4864
|
action: "refundInEscrow",
|
|
4601
4865
|
payload: {
|
|
4602
|
-
paymentInfo:
|
|
4603
|
-
operator: paymentInfo.operator,
|
|
4604
|
-
receiver: paymentInfo.receiver,
|
|
4605
|
-
token: paymentInfo.token,
|
|
4606
|
-
maxAmount: paymentInfo.maxAmount,
|
|
4607
|
-
preApprovalExpiry: paymentInfo.preApprovalExpiry,
|
|
4608
|
-
authorizationExpiry: paymentInfo.authorizationExpiry,
|
|
4609
|
-
refundExpiry: paymentInfo.refundExpiry,
|
|
4610
|
-
minFeeBps: paymentInfo.minFeeBps,
|
|
4611
|
-
maxFeeBps: paymentInfo.maxFeeBps,
|
|
4612
|
-
feeReceiver: paymentInfo.feeReceiver,
|
|
4613
|
-
salt: paymentInfo.salt
|
|
4614
|
-
},
|
|
4866
|
+
paymentInfo: wirePaymentInfo,
|
|
4615
4867
|
payer: this.payerAddress,
|
|
4616
|
-
amount:
|
|
4868
|
+
amount: refundAmount,
|
|
4869
|
+
...lifecycleAuth ? { lifecycleAuth } : {}
|
|
4617
4870
|
},
|
|
4618
4871
|
paymentRequirements: {
|
|
4619
4872
|
scheme: "escrow",
|
|
@@ -4733,7 +4986,7 @@ var AdvancedEscrowClient = class {
|
|
|
4733
4986
|
async charge(paymentInfo, amount) {
|
|
4734
4987
|
if (!this.payerAddress) await this.init();
|
|
4735
4988
|
try {
|
|
4736
|
-
const { ethers:
|
|
4989
|
+
const { ethers: ethers4 } = await import('ethers');
|
|
4737
4990
|
const nonce = await this.computeNonce(paymentInfo);
|
|
4738
4991
|
const amt = amount || paymentInfo.maxAmount;
|
|
4739
4992
|
const auth = {
|
|
@@ -4745,10 +4998,10 @@ var AdvancedEscrowClient = class {
|
|
|
4745
4998
|
nonce
|
|
4746
4999
|
};
|
|
4747
5000
|
const signature = await this.signErc3009(auth);
|
|
4748
|
-
const collectorData =
|
|
5001
|
+
const collectorData = ethers4.getBytes(signature);
|
|
4749
5002
|
const tuple = this.buildTuple(paymentInfo);
|
|
4750
5003
|
if (this.walletAdapter) {
|
|
4751
|
-
return this.sendViaAdapter(
|
|
5004
|
+
return this.sendViaAdapter(ethers4, OPERATOR_ABI, (iface) => {
|
|
4752
5005
|
return iface.encodeFunctionData("charge", [
|
|
4753
5006
|
tuple,
|
|
4754
5007
|
amt,
|
|
@@ -4757,7 +5010,7 @@ var AdvancedEscrowClient = class {
|
|
|
4757
5010
|
]);
|
|
4758
5011
|
});
|
|
4759
5012
|
}
|
|
4760
|
-
const contract = new
|
|
5013
|
+
const contract = new ethers4.Contract(this.contracts.operator, OPERATOR_ABI, this.signer);
|
|
4761
5014
|
const tx = await contract.charge(
|
|
4762
5015
|
tuple,
|
|
4763
5016
|
amt,
|
|
@@ -4799,11 +5052,11 @@ var AdvancedEscrowClient = class {
|
|
|
4799
5052
|
async refundPostEscrow(paymentInfo, amount, tokenCollector, collectorData) {
|
|
4800
5053
|
if (!this.payerAddress) await this.init();
|
|
4801
5054
|
try {
|
|
4802
|
-
const { ethers:
|
|
5055
|
+
const { ethers: ethers4 } = await import('ethers');
|
|
4803
5056
|
const amt = amount || paymentInfo.maxAmount;
|
|
4804
5057
|
const tuple = this.buildTuple(paymentInfo);
|
|
4805
5058
|
if (this.walletAdapter) {
|
|
4806
|
-
return this.sendViaAdapter(
|
|
5059
|
+
return this.sendViaAdapter(ethers4, OPERATOR_ABI, (iface) => {
|
|
4807
5060
|
return iface.encodeFunctionData("refundPostEscrow", [
|
|
4808
5061
|
tuple,
|
|
4809
5062
|
amt,
|
|
@@ -4812,7 +5065,7 @@ var AdvancedEscrowClient = class {
|
|
|
4812
5065
|
]);
|
|
4813
5066
|
});
|
|
4814
5067
|
}
|
|
4815
|
-
const contract = new
|
|
5068
|
+
const contract = new ethers4.Contract(this.contracts.operator, OPERATOR_ABI, this.signer);
|
|
4816
5069
|
const tx = await contract.refundPostEscrow(
|
|
4817
5070
|
tuple,
|
|
4818
5071
|
amt,
|