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