@pafi-dev/issuer 0.7.0 → 0.7.2
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/index.cjs +299 -160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -7
- package/dist/index.d.ts +63 -7
- package/dist/index.js +296 -160
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -20,12 +20,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
AdapterMisconfiguredError: () => AdapterMisconfiguredError,
|
|
23
24
|
AuthError: () => AuthError,
|
|
24
25
|
AuthService: () => AuthService,
|
|
25
26
|
BalanceAggregator: () => BalanceAggregator,
|
|
26
27
|
BundlerNotConfiguredError: () => BundlerNotConfiguredError,
|
|
27
28
|
BundlerRejectedError: () => BundlerRejectedError,
|
|
28
29
|
BurnIndexer: () => BurnIndexer,
|
|
30
|
+
ConfigurationError: () => ConfigurationError,
|
|
29
31
|
DefaultPolicyEngine: () => DefaultPolicyEngine,
|
|
30
32
|
FeeManager: () => FeeManager,
|
|
31
33
|
InMemoryCursorStore: () => InMemoryCursorStore,
|
|
@@ -53,6 +55,7 @@ __export(index_exports, {
|
|
|
53
55
|
PointIndexer: () => PointIndexer,
|
|
54
56
|
RelayError: () => RelayError,
|
|
55
57
|
RelayService: () => RelayService,
|
|
58
|
+
ValidationError: () => ValidationError,
|
|
56
59
|
authenticateRequest: () => authenticateRequest,
|
|
57
60
|
createIssuerService: () => createIssuerService,
|
|
58
61
|
createNativePtQuoter: () => createNativePtQuoter,
|
|
@@ -88,6 +91,26 @@ var PafiSdkError = class extends Error {
|
|
|
88
91
|
this.name = new.target.name;
|
|
89
92
|
}
|
|
90
93
|
};
|
|
94
|
+
var ValidationError = class extends PafiSdkError {
|
|
95
|
+
httpStatus = "unprocessable";
|
|
96
|
+
code;
|
|
97
|
+
details;
|
|
98
|
+
constructor(code, message, details) {
|
|
99
|
+
super(message);
|
|
100
|
+
this.code = code;
|
|
101
|
+
this.details = details;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var ConfigurationError = class extends PafiSdkError {
|
|
105
|
+
httpStatus = "service_unavailable";
|
|
106
|
+
code;
|
|
107
|
+
details;
|
|
108
|
+
constructor(code, message, details) {
|
|
109
|
+
super(message);
|
|
110
|
+
this.code = code;
|
|
111
|
+
this.details = details;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
91
114
|
|
|
92
115
|
// src/policy/defaultPolicy.ts
|
|
93
116
|
var DefaultPolicyEngine = class {
|
|
@@ -258,12 +281,32 @@ var import_viem2 = require("viem");
|
|
|
258
281
|
var import_core = require("@pafi-dev/core");
|
|
259
282
|
|
|
260
283
|
// src/auth/errors.ts
|
|
261
|
-
|
|
284
|
+
function statusForCode(code) {
|
|
285
|
+
switch (code) {
|
|
286
|
+
case "INVALID_MESSAGE":
|
|
287
|
+
case "DOMAIN_MISMATCH":
|
|
288
|
+
case "CHAIN_MISMATCH":
|
|
289
|
+
case "MESSAGE_EXPIRED":
|
|
290
|
+
case "MESSAGE_NOT_YET_VALID":
|
|
291
|
+
case "MALFORMED_TOKEN":
|
|
292
|
+
return "unprocessable";
|
|
293
|
+
case "NONCE_INVALID":
|
|
294
|
+
case "SIGNATURE_INVALID":
|
|
295
|
+
case "MISSING_TOKEN":
|
|
296
|
+
case "TOKEN_INVALID":
|
|
297
|
+
case "TOKEN_EXPIRED":
|
|
298
|
+
return "forbidden";
|
|
299
|
+
case "SESSION_REVOKED":
|
|
300
|
+
return "not_found";
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
var AuthError = class extends PafiSdkError {
|
|
262
304
|
code;
|
|
305
|
+
httpStatus;
|
|
263
306
|
constructor(code, message) {
|
|
264
307
|
super(message);
|
|
265
|
-
this.name = "AuthError";
|
|
266
308
|
this.code = code;
|
|
309
|
+
this.httpStatus = statusForCode(code);
|
|
267
310
|
}
|
|
268
311
|
};
|
|
269
312
|
|
|
@@ -460,14 +503,15 @@ async function authenticateRequest(authHeader, authService) {
|
|
|
460
503
|
}
|
|
461
504
|
|
|
462
505
|
// src/relay/types.ts
|
|
463
|
-
var RelayError = class extends
|
|
506
|
+
var RelayError = class extends PafiSdkError {
|
|
507
|
+
httpStatus = "unprocessable";
|
|
464
508
|
code;
|
|
465
|
-
cause;
|
|
466
509
|
constructor(code, message, cause) {
|
|
467
510
|
super(message);
|
|
468
|
-
this.name = "RelayError";
|
|
469
511
|
this.code = code;
|
|
470
|
-
if (cause !== void 0)
|
|
512
|
+
if (cause !== void 0) {
|
|
513
|
+
this.cause = cause;
|
|
514
|
+
}
|
|
471
515
|
}
|
|
472
516
|
};
|
|
473
517
|
|
|
@@ -1168,13 +1212,16 @@ var IssuerApiHandlers = class {
|
|
|
1168
1212
|
/** `POST /auth/login` */
|
|
1169
1213
|
async handleLogin(body) {
|
|
1170
1214
|
if (!body || typeof body.message !== "string" || body.message.length === 0 || typeof body.signature !== "string" || body.signature.length <= 2) {
|
|
1171
|
-
throw new
|
|
1215
|
+
throw new ValidationError(
|
|
1216
|
+
"INVALID_LOGIN_BODY",
|
|
1217
|
+
"handleLogin: message and signature are required"
|
|
1218
|
+
);
|
|
1172
1219
|
}
|
|
1173
1220
|
if (body.message.length > 4096) {
|
|
1174
|
-
throw new
|
|
1221
|
+
throw new ValidationError("MESSAGE_TOO_LONG", "message too long");
|
|
1175
1222
|
}
|
|
1176
1223
|
if (body.signature.length > 260) {
|
|
1177
|
-
throw new
|
|
1224
|
+
throw new ValidationError("SIGNATURE_TOO_LONG", "signature too long");
|
|
1178
1225
|
}
|
|
1179
1226
|
const result = await this.authService.login(body.message, body.signature);
|
|
1180
1227
|
return {
|
|
@@ -1191,11 +1238,15 @@ var IssuerApiHandlers = class {
|
|
|
1191
1238
|
*/
|
|
1192
1239
|
async handleConfig(chainId) {
|
|
1193
1240
|
if (!Number.isInteger(chainId) || chainId <= 0) {
|
|
1194
|
-
throw new
|
|
1241
|
+
throw new ValidationError("INVALID_CHAIN_ID", "invalid chainId", {
|
|
1242
|
+
chainId
|
|
1243
|
+
});
|
|
1195
1244
|
}
|
|
1196
1245
|
if (chainId !== this.chainId) {
|
|
1197
|
-
throw new
|
|
1198
|
-
|
|
1246
|
+
throw new ValidationError(
|
|
1247
|
+
"UNSUPPORTED_CHAIN_ID",
|
|
1248
|
+
`handleConfig: unsupported chainId ${chainId}`,
|
|
1249
|
+
{ requested: chainId, supported: this.chainId }
|
|
1199
1250
|
);
|
|
1200
1251
|
}
|
|
1201
1252
|
const contracts = {
|
|
@@ -1212,7 +1263,8 @@ var IssuerApiHandlers = class {
|
|
|
1212
1263
|
/** `GET /gas-fee` — quoted in USDT (6-decimal base units). */
|
|
1213
1264
|
async handleGasFee() {
|
|
1214
1265
|
if (!this.feeManager) {
|
|
1215
|
-
throw new
|
|
1266
|
+
throw new ConfigurationError(
|
|
1267
|
+
"FEE_MANAGER_NOT_CONFIGURED",
|
|
1216
1268
|
"handleGasFee: feeManager is not configured on this issuer"
|
|
1217
1269
|
);
|
|
1218
1270
|
}
|
|
@@ -1234,13 +1286,16 @@ var IssuerApiHandlers = class {
|
|
|
1234
1286
|
*/
|
|
1235
1287
|
async handlePools(_userAddress, request) {
|
|
1236
1288
|
if (!this.poolsProvider) {
|
|
1237
|
-
throw new
|
|
1289
|
+
throw new ConfigurationError(
|
|
1290
|
+
"POOLS_PROVIDER_NOT_CONFIGURED",
|
|
1238
1291
|
"handlePools: poolsProvider is not configured on this issuer"
|
|
1239
1292
|
);
|
|
1240
1293
|
}
|
|
1241
1294
|
if (request.chainId !== this.chainId) {
|
|
1242
|
-
throw new
|
|
1243
|
-
|
|
1295
|
+
throw new ValidationError(
|
|
1296
|
+
"UNSUPPORTED_CHAIN_ID",
|
|
1297
|
+
`handlePools: unsupported chainId ${request.chainId}`,
|
|
1298
|
+
{ requested: request.chainId, supported: this.chainId }
|
|
1244
1299
|
);
|
|
1245
1300
|
}
|
|
1246
1301
|
return this.poolsProvider(request);
|
|
@@ -1254,21 +1309,27 @@ var IssuerApiHandlers = class {
|
|
|
1254
1309
|
*/
|
|
1255
1310
|
async handleUser(userAddress, request) {
|
|
1256
1311
|
if (request.chainId !== this.chainId) {
|
|
1257
|
-
throw new
|
|
1258
|
-
|
|
1312
|
+
throw new ValidationError(
|
|
1313
|
+
"UNSUPPORTED_CHAIN_ID",
|
|
1314
|
+
`handleUser: unsupported chainId ${request.chainId}`,
|
|
1315
|
+
{ requested: request.chainId, supported: this.chainId }
|
|
1259
1316
|
);
|
|
1260
1317
|
}
|
|
1261
1318
|
const normalizedAuthed = (0, import_viem6.getAddress)(userAddress);
|
|
1262
1319
|
const normalizedRequest = (0, import_viem6.getAddress)(request.userAddress);
|
|
1263
1320
|
if (normalizedAuthed !== normalizedRequest) {
|
|
1264
|
-
throw new
|
|
1265
|
-
"
|
|
1321
|
+
throw new ValidationError(
|
|
1322
|
+
"USER_ADDRESS_MISMATCH",
|
|
1323
|
+
"handleUser: request userAddress must match authenticated user",
|
|
1324
|
+
{ authenticated: normalizedAuthed, requested: normalizedRequest }
|
|
1266
1325
|
);
|
|
1267
1326
|
}
|
|
1268
1327
|
const pointToken = (0, import_viem6.getAddress)(request.pointTokenAddress);
|
|
1269
1328
|
if (!this.supportedTokens.has(pointToken)) {
|
|
1270
|
-
throw new
|
|
1271
|
-
|
|
1329
|
+
throw new ValidationError(
|
|
1330
|
+
"UNSUPPORTED_POINT_TOKEN",
|
|
1331
|
+
`handleUser: unsupported pointToken ${pointToken}`,
|
|
1332
|
+
{ requested: pointToken }
|
|
1272
1333
|
);
|
|
1273
1334
|
}
|
|
1274
1335
|
const [mintRequestNonce, receiverConsentNonce, offChainBalance, onChainBalance, minter] = await Promise.all([
|
|
@@ -1464,69 +1525,82 @@ var PTRedeemHandler = class {
|
|
|
1464
1525
|
this.redeemLockDurationMs,
|
|
1465
1526
|
this.pointTokenAddress
|
|
1466
1527
|
);
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
userAddress: request.userAddress,
|
|
1470
|
-
aaNonce: request.aaNonce,
|
|
1471
|
-
pointTokenAddress: this.pointTokenAddress,
|
|
1472
|
-
batchExecutorAddress: this.batchExecutorAddress,
|
|
1473
|
-
burnRequest: sponsoredBurnRequest,
|
|
1474
|
-
burnerSignature: sponsoredSig,
|
|
1475
|
-
feeAmount: fee,
|
|
1476
|
-
feeRecipient
|
|
1477
|
-
});
|
|
1478
|
-
let fallback = void 0;
|
|
1479
|
-
if (fee > 0n) {
|
|
1480
|
-
const fallbackBurnRequest = {
|
|
1481
|
-
from: request.userAddress,
|
|
1482
|
-
amount: request.amount,
|
|
1483
|
-
nonce: burnNonce,
|
|
1484
|
-
deadline
|
|
1485
|
-
};
|
|
1486
|
-
let fallbackSig;
|
|
1487
|
-
try {
|
|
1488
|
-
fallbackSig = (await (0, import_core4.signBurnRequest)(this.burnerSignerWallet, domain, fallbackBurnRequest)).serialized;
|
|
1489
|
-
} catch (err) {
|
|
1490
|
-
throw new PTRedeemError(
|
|
1491
|
-
"SIGNING_FAILED",
|
|
1492
|
-
`failed to sign fallback BurnRequest: ${err instanceof Error ? err.message : String(err)}`
|
|
1493
|
-
);
|
|
1494
|
-
}
|
|
1495
|
-
const fallbackLockId = await this.ledger.reservePendingCredit(
|
|
1496
|
-
request.userAddress,
|
|
1497
|
-
request.amount,
|
|
1498
|
-
this.redeemLockDurationMs,
|
|
1499
|
-
this.pointTokenAddress
|
|
1500
|
-
);
|
|
1501
|
-
const fallbackUserOp = await this.relayService.prepareBurn({
|
|
1528
|
+
try {
|
|
1529
|
+
const sponsoredUserOp = await this.relayService.prepareBurn({
|
|
1502
1530
|
mode: "burnWithSig",
|
|
1503
1531
|
userAddress: request.userAddress,
|
|
1504
1532
|
aaNonce: request.aaNonce,
|
|
1505
1533
|
pointTokenAddress: this.pointTokenAddress,
|
|
1506
1534
|
batchExecutorAddress: this.batchExecutorAddress,
|
|
1507
|
-
burnRequest:
|
|
1508
|
-
burnerSignature:
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
// auto-quoting RelayService would try to quote a fee here
|
|
1512
|
-
// and re-add the PT.transfer we're trying to strip.
|
|
1513
|
-
feeAmount: 0n
|
|
1535
|
+
burnRequest: sponsoredBurnRequest,
|
|
1536
|
+
burnerSignature: sponsoredSig,
|
|
1537
|
+
feeAmount: fee,
|
|
1538
|
+
feeRecipient
|
|
1514
1539
|
});
|
|
1515
|
-
fallback =
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1540
|
+
let fallback = void 0;
|
|
1541
|
+
if (fee > 0n) {
|
|
1542
|
+
const fallbackBurnRequest = {
|
|
1543
|
+
from: request.userAddress,
|
|
1544
|
+
amount: request.amount,
|
|
1545
|
+
nonce: burnNonce,
|
|
1546
|
+
deadline
|
|
1547
|
+
};
|
|
1548
|
+
let fallbackSig;
|
|
1549
|
+
try {
|
|
1550
|
+
fallbackSig = (await (0, import_core4.signBurnRequest)(this.burnerSignerWallet, domain, fallbackBurnRequest)).serialized;
|
|
1551
|
+
} catch (err) {
|
|
1552
|
+
throw new PTRedeemError(
|
|
1553
|
+
"SIGNING_FAILED",
|
|
1554
|
+
`failed to sign fallback BurnRequest: ${err instanceof Error ? err.message : String(err)}`
|
|
1555
|
+
);
|
|
1556
|
+
}
|
|
1557
|
+
const fallbackLockId = await this.ledger.reservePendingCredit(
|
|
1558
|
+
request.userAddress,
|
|
1559
|
+
request.amount,
|
|
1560
|
+
this.redeemLockDurationMs,
|
|
1561
|
+
this.pointTokenAddress
|
|
1562
|
+
);
|
|
1563
|
+
let fallbackUserOp;
|
|
1564
|
+
try {
|
|
1565
|
+
fallbackUserOp = await this.relayService.prepareBurn({
|
|
1566
|
+
mode: "burnWithSig",
|
|
1567
|
+
userAddress: request.userAddress,
|
|
1568
|
+
aaNonce: request.aaNonce,
|
|
1569
|
+
pointTokenAddress: this.pointTokenAddress,
|
|
1570
|
+
batchExecutorAddress: this.batchExecutorAddress,
|
|
1571
|
+
burnRequest: fallbackBurnRequest,
|
|
1572
|
+
burnerSignature: fallbackSig,
|
|
1573
|
+
// Explicit 0n — fallback is fee-free regardless of how
|
|
1574
|
+
// RelayService is configured. Without this, an
|
|
1575
|
+
// auto-quoting RelayService would try to quote a fee here
|
|
1576
|
+
// and re-add the PT.transfer we're trying to strip.
|
|
1577
|
+
feeAmount: 0n
|
|
1578
|
+
});
|
|
1579
|
+
} catch (err) {
|
|
1580
|
+
await this.ledger.releaseLock(fallbackLockId).catch(() => {
|
|
1581
|
+
});
|
|
1582
|
+
throw err;
|
|
1583
|
+
}
|
|
1584
|
+
fallback = {
|
|
1585
|
+
lockId: fallbackLockId,
|
|
1586
|
+
userOp: fallbackUserOp,
|
|
1587
|
+
netCreditAmount: request.amount
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
return {
|
|
1591
|
+
lockId: sponsoredLockId,
|
|
1592
|
+
userOp: sponsoredUserOp,
|
|
1593
|
+
netCreditAmount: sponsoredBurnAmount,
|
|
1594
|
+
feeAmount: fee,
|
|
1595
|
+
fallback,
|
|
1596
|
+
expiresInSeconds: Math.floor(this.redeemLockDurationMs / 1e3),
|
|
1597
|
+
signatureDeadline: deadline
|
|
1519
1598
|
};
|
|
1599
|
+
} catch (err) {
|
|
1600
|
+
await this.ledger.releaseLock(sponsoredLockId).catch(() => {
|
|
1601
|
+
});
|
|
1602
|
+
throw err;
|
|
1520
1603
|
}
|
|
1521
|
-
return {
|
|
1522
|
-
lockId: sponsoredLockId,
|
|
1523
|
-
userOp: sponsoredUserOp,
|
|
1524
|
-
netCreditAmount: sponsoredBurnAmount,
|
|
1525
|
-
feeAmount: fee,
|
|
1526
|
-
fallback,
|
|
1527
|
-
expiresInSeconds: Math.floor(this.redeemLockDurationMs / 1e3),
|
|
1528
|
-
signatureDeadline: deadline
|
|
1529
|
-
};
|
|
1530
1604
|
}
|
|
1531
1605
|
};
|
|
1532
1606
|
|
|
@@ -1794,6 +1868,41 @@ async function prepareMobileUserOp(params) {
|
|
|
1794
1868
|
};
|
|
1795
1869
|
}
|
|
1796
1870
|
|
|
1871
|
+
// src/pafi-backend/types.ts
|
|
1872
|
+
var PafiBackendError = class extends Error {
|
|
1873
|
+
constructor(code, message, httpStatus, details, opts) {
|
|
1874
|
+
super(message);
|
|
1875
|
+
this.code = code;
|
|
1876
|
+
this.httpStatus = httpStatus;
|
|
1877
|
+
this.details = details;
|
|
1878
|
+
this.name = "PafiBackendError";
|
|
1879
|
+
if (opts?.retryAfter !== void 0) this.retryAfter = opts.retryAfter;
|
|
1880
|
+
if (opts?.safeToRetry !== void 0) this.serverSafeToRetry = opts.safeToRetry;
|
|
1881
|
+
}
|
|
1882
|
+
code;
|
|
1883
|
+
httpStatus;
|
|
1884
|
+
details;
|
|
1885
|
+
retryAfter;
|
|
1886
|
+
serverSafeToRetry;
|
|
1887
|
+
get safeToRetry() {
|
|
1888
|
+
if (this.serverSafeToRetry !== void 0) return this.serverSafeToRetry;
|
|
1889
|
+
switch (this.code) {
|
|
1890
|
+
case "RATE_LIMITER_UNAVAILABLE":
|
|
1891
|
+
case "INTERNAL_ERROR":
|
|
1892
|
+
case "TIMEOUT":
|
|
1893
|
+
case "NETWORK_ERROR":
|
|
1894
|
+
return true;
|
|
1895
|
+
case "RATE_LIMIT_EXCEEDED":
|
|
1896
|
+
case "RATE_LIMIT_EXCEEDED_DAILY":
|
|
1897
|
+
case "RATE_LIMIT_EXCEEDED_PER_USER":
|
|
1898
|
+
case "ISSUER_BUDGET_EXCEEDED":
|
|
1899
|
+
return true;
|
|
1900
|
+
default:
|
|
1901
|
+
return false;
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
};
|
|
1905
|
+
|
|
1797
1906
|
// src/pafi-backend/helpers.ts
|
|
1798
1907
|
var BundlerNotConfiguredError = class extends PafiSdkError {
|
|
1799
1908
|
code = "BUNDLER_NOT_CONFIGURED";
|
|
@@ -1829,8 +1938,23 @@ async function requestPaymaster(params) {
|
|
|
1829
1938
|
});
|
|
1830
1939
|
} catch (err) {
|
|
1831
1940
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1832
|
-
|
|
1833
|
-
|
|
1941
|
+
if (err instanceof PafiBackendError && isTransientPaymasterError(err.code)) {
|
|
1942
|
+
params.onWarning?.(`Paymaster sponsorship declined (transient): ${msg}`);
|
|
1943
|
+
return void 0;
|
|
1944
|
+
}
|
|
1945
|
+
throw err;
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
function isTransientPaymasterError(code) {
|
|
1949
|
+
switch (code) {
|
|
1950
|
+
case "NETWORK_ERROR":
|
|
1951
|
+
case "TIMEOUT":
|
|
1952
|
+
case "PAYMASTER_UNAVAILABLE":
|
|
1953
|
+
case "RATE_LIMITER_UNAVAILABLE":
|
|
1954
|
+
case "INTERNAL_ERROR":
|
|
1955
|
+
return true;
|
|
1956
|
+
default:
|
|
1957
|
+
return false;
|
|
1834
1958
|
}
|
|
1835
1959
|
}
|
|
1836
1960
|
function defaultFunctionForScenario(scenario) {
|
|
@@ -2011,39 +2135,19 @@ var PTClaimHandler = class {
|
|
|
2011
2135
|
this.cfg.lockDurationMs,
|
|
2012
2136
|
request.pointTokenAddress
|
|
2013
2137
|
);
|
|
2014
|
-
const signatureDeadline = BigInt(
|
|
2015
|
-
Math.floor(this.cfg.now() / 1e3) + this.cfg.signatureDeadlineSeconds
|
|
2016
|
-
);
|
|
2017
|
-
const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee() : 0n;
|
|
2018
|
-
const domain = {
|
|
2019
|
-
name: this.cfg.pointTokenDomainName,
|
|
2020
|
-
chainId: request.chainId,
|
|
2021
|
-
verifyingContract: request.pointTokenAddress
|
|
2022
|
-
};
|
|
2023
|
-
let userOp;
|
|
2024
2138
|
try {
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
aaNonce: request.aaNonce,
|
|
2028
|
-
batchExecutorAddress,
|
|
2029
|
-
pointTokenAddress: request.pointTokenAddress,
|
|
2030
|
-
amount: request.amount,
|
|
2031
|
-
issuerSignerWallet: this.cfg.issuerSignerWallet,
|
|
2032
|
-
domain,
|
|
2033
|
-
mintRequestNonce: request.mintRequestNonce,
|
|
2034
|
-
deadline: signatureDeadline
|
|
2035
|
-
// No feeAmount/feeRecipient — RelayService auto-resolves.
|
|
2036
|
-
});
|
|
2037
|
-
} catch (err) {
|
|
2038
|
-
throw new PTClaimError(
|
|
2039
|
-
"BUILD_FAILED",
|
|
2040
|
-
`prepareMint failed: ${err instanceof Error ? err.message : String(err)}`
|
|
2139
|
+
const signatureDeadline = BigInt(
|
|
2140
|
+
Math.floor(this.cfg.now() / 1e3) + this.cfg.signatureDeadlineSeconds
|
|
2041
2141
|
);
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2142
|
+
const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee() : 0n;
|
|
2143
|
+
const domain = {
|
|
2144
|
+
name: this.cfg.pointTokenDomainName,
|
|
2145
|
+
chainId: request.chainId,
|
|
2146
|
+
verifyingContract: request.pointTokenAddress
|
|
2147
|
+
};
|
|
2148
|
+
let userOp;
|
|
2045
2149
|
try {
|
|
2046
|
-
|
|
2150
|
+
userOp = await this.cfg.relayService.prepareMint({
|
|
2047
2151
|
userAddress: request.userAddress,
|
|
2048
2152
|
aaNonce: request.aaNonce,
|
|
2049
2153
|
batchExecutorAddress,
|
|
@@ -2052,28 +2156,54 @@ var PTClaimHandler = class {
|
|
|
2052
2156
|
issuerSignerWallet: this.cfg.issuerSignerWallet,
|
|
2053
2157
|
domain,
|
|
2054
2158
|
mintRequestNonce: request.mintRequestNonce,
|
|
2055
|
-
deadline: signatureDeadline
|
|
2056
|
-
feeAmount
|
|
2159
|
+
deadline: signatureDeadline
|
|
2160
|
+
// No feeAmount/feeRecipient — RelayService auto-resolves.
|
|
2057
2161
|
});
|
|
2058
2162
|
} catch (err) {
|
|
2059
2163
|
throw new PTClaimError(
|
|
2060
2164
|
"BUILD_FAILED",
|
|
2061
|
-
`prepareMint
|
|
2165
|
+
`prepareMint failed: ${err instanceof Error ? err.message : String(err)}`
|
|
2062
2166
|
);
|
|
2063
2167
|
}
|
|
2168
|
+
let fallback;
|
|
2169
|
+
if (feeAmount > 0n) {
|
|
2170
|
+
try {
|
|
2171
|
+
fallback = await this.cfg.relayService.prepareMint({
|
|
2172
|
+
userAddress: request.userAddress,
|
|
2173
|
+
aaNonce: request.aaNonce,
|
|
2174
|
+
batchExecutorAddress,
|
|
2175
|
+
pointTokenAddress: request.pointTokenAddress,
|
|
2176
|
+
amount: request.amount,
|
|
2177
|
+
issuerSignerWallet: this.cfg.issuerSignerWallet,
|
|
2178
|
+
domain,
|
|
2179
|
+
mintRequestNonce: request.mintRequestNonce,
|
|
2180
|
+
deadline: signatureDeadline,
|
|
2181
|
+
feeAmount: 0n
|
|
2182
|
+
});
|
|
2183
|
+
} catch (err) {
|
|
2184
|
+
throw new PTClaimError(
|
|
2185
|
+
"BUILD_FAILED",
|
|
2186
|
+
`prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
const calls = (0, import_core8.decodeBatchExecuteCalls)(userOp.callData);
|
|
2191
|
+
const callsFallback = fallback ? (0, import_core8.decodeBatchExecuteCalls)(fallback.callData) : void 0;
|
|
2192
|
+
return {
|
|
2193
|
+
userOp,
|
|
2194
|
+
fallback,
|
|
2195
|
+
lockId,
|
|
2196
|
+
feeAmount,
|
|
2197
|
+
signatureDeadline,
|
|
2198
|
+
expiresInSeconds: Math.floor(this.cfg.lockDurationMs / 1e3),
|
|
2199
|
+
calls,
|
|
2200
|
+
callsFallback
|
|
2201
|
+
};
|
|
2202
|
+
} catch (err) {
|
|
2203
|
+
await this.cfg.ledger.releaseLock(lockId).catch(() => {
|
|
2204
|
+
});
|
|
2205
|
+
throw err;
|
|
2064
2206
|
}
|
|
2065
|
-
const calls = (0, import_core8.decodeBatchExecuteCalls)(userOp.callData);
|
|
2066
|
-
const callsFallback = fallback ? (0, import_core8.decodeBatchExecuteCalls)(fallback.callData) : void 0;
|
|
2067
|
-
return {
|
|
2068
|
-
userOp,
|
|
2069
|
-
fallback,
|
|
2070
|
-
lockId,
|
|
2071
|
-
feeAmount,
|
|
2072
|
-
signatureDeadline,
|
|
2073
|
-
expiresInSeconds: Math.floor(this.cfg.lockDurationMs / 1e3),
|
|
2074
|
-
calls,
|
|
2075
|
-
callsFallback
|
|
2076
|
-
};
|
|
2077
2207
|
}
|
|
2078
2208
|
};
|
|
2079
2209
|
|
|
@@ -2303,9 +2433,45 @@ function createSdkErrorMapper(factories) {
|
|
|
2303
2433
|
// src/api/issuerApiAdapter.ts
|
|
2304
2434
|
var import_viem10 = require("viem");
|
|
2305
2435
|
var import_core11 = require("@pafi-dev/core");
|
|
2436
|
+
var AdapterMisconfiguredError = class extends Error {
|
|
2437
|
+
code = "ADAPTER_MISCONFIGURED";
|
|
2438
|
+
constructor(message) {
|
|
2439
|
+
super(message);
|
|
2440
|
+
this.name = "AdapterMisconfiguredError";
|
|
2441
|
+
}
|
|
2442
|
+
};
|
|
2306
2443
|
var IssuerApiAdapter = class {
|
|
2307
2444
|
cfg;
|
|
2308
2445
|
constructor(config) {
|
|
2446
|
+
if (config.ptClaimHandler) {
|
|
2447
|
+
if (typeof config.ledger.bindMintUserOpHash !== "function") {
|
|
2448
|
+
throw new AdapterMisconfiguredError(
|
|
2449
|
+
"ledger.bindMintUserOpHash is required when ptClaimHandler is wired (mobile claim flow). Implement it on your IPointLedger or omit ptClaimHandler from IssuerApiAdapter config."
|
|
2450
|
+
);
|
|
2451
|
+
}
|
|
2452
|
+
if (typeof config.ledger.getMintLock !== "function") {
|
|
2453
|
+
throw new AdapterMisconfiguredError(
|
|
2454
|
+
"ledger.getMintLock is required when ptClaimHandler is wired \u2014 claimStatus uses it to look up the lock."
|
|
2455
|
+
);
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
if (config.ptRedeemHandler) {
|
|
2459
|
+
if (typeof config.ledger.reservePendingCredit !== "function") {
|
|
2460
|
+
throw new AdapterMisconfiguredError(
|
|
2461
|
+
"ledger.reservePendingCredit is required when ptRedeemHandler is wired (burn/redeem reverse flow). PTRedeemHandler also enforces this at construction; see ledger/types.ts comments."
|
|
2462
|
+
);
|
|
2463
|
+
}
|
|
2464
|
+
if (typeof config.ledger.bindCreditUserOpHash !== "function") {
|
|
2465
|
+
throw new AdapterMisconfiguredError(
|
|
2466
|
+
"ledger.bindCreditUserOpHash is required when ptRedeemHandler is wired (mobile redeem flow)."
|
|
2467
|
+
);
|
|
2468
|
+
}
|
|
2469
|
+
if (typeof config.ledger.getPendingCredit !== "function") {
|
|
2470
|
+
throw new AdapterMisconfiguredError(
|
|
2471
|
+
"ledger.getPendingCredit is required when ptRedeemHandler is wired \u2014 redeemStatus uses it to look up the credit."
|
|
2472
|
+
);
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2309
2475
|
this.cfg = config;
|
|
2310
2476
|
}
|
|
2311
2477
|
// ------------------------------ Read endpoints ---------------------------
|
|
@@ -2606,6 +2772,11 @@ var IssuerApiAdapter = class {
|
|
|
2606
2772
|
/**
|
|
2607
2773
|
* Build + sign a SponsorAuth payload. Returns `undefined` when no
|
|
2608
2774
|
* issuer id is configured, so the controller can skip the field.
|
|
2775
|
+
*
|
|
2776
|
+
* v0.7.1 — `scenario` typed as `SponsorshipScenario` (was `string`).
|
|
2777
|
+
* Previously a typo (`"perp_deposit"` vs `"perp-deposit"`) compiled
|
|
2778
|
+
* fine but rejected at L1 by sponsor-relayer's IntentValidator. See
|
|
2779
|
+
* SDK_ISSUER_AUDIT.md N5.
|
|
2609
2780
|
*/
|
|
2610
2781
|
async buildSponsorAuth(authenticatedAddress, callData, chainId, scenario) {
|
|
2611
2782
|
if (!this.cfg.pafiIssuerId) return void 0;
|
|
@@ -3066,41 +3237,6 @@ var BalanceAggregator = class {
|
|
|
3066
3237
|
}
|
|
3067
3238
|
};
|
|
3068
3239
|
|
|
3069
|
-
// src/pafi-backend/types.ts
|
|
3070
|
-
var PafiBackendError = class extends Error {
|
|
3071
|
-
constructor(code, message, httpStatus, details, opts) {
|
|
3072
|
-
super(message);
|
|
3073
|
-
this.code = code;
|
|
3074
|
-
this.httpStatus = httpStatus;
|
|
3075
|
-
this.details = details;
|
|
3076
|
-
this.name = "PafiBackendError";
|
|
3077
|
-
if (opts?.retryAfter !== void 0) this.retryAfter = opts.retryAfter;
|
|
3078
|
-
if (opts?.safeToRetry !== void 0) this.serverSafeToRetry = opts.safeToRetry;
|
|
3079
|
-
}
|
|
3080
|
-
code;
|
|
3081
|
-
httpStatus;
|
|
3082
|
-
details;
|
|
3083
|
-
retryAfter;
|
|
3084
|
-
serverSafeToRetry;
|
|
3085
|
-
get safeToRetry() {
|
|
3086
|
-
if (this.serverSafeToRetry !== void 0) return this.serverSafeToRetry;
|
|
3087
|
-
switch (this.code) {
|
|
3088
|
-
case "RATE_LIMITER_UNAVAILABLE":
|
|
3089
|
-
case "INTERNAL_ERROR":
|
|
3090
|
-
case "TIMEOUT":
|
|
3091
|
-
case "NETWORK_ERROR":
|
|
3092
|
-
return true;
|
|
3093
|
-
case "RATE_LIMIT_EXCEEDED":
|
|
3094
|
-
case "RATE_LIMIT_EXCEEDED_DAILY":
|
|
3095
|
-
case "RATE_LIMIT_EXCEEDED_PER_USER":
|
|
3096
|
-
case "ISSUER_BUDGET_EXCEEDED":
|
|
3097
|
-
return true;
|
|
3098
|
-
default:
|
|
3099
|
-
return false;
|
|
3100
|
-
}
|
|
3101
|
-
}
|
|
3102
|
-
};
|
|
3103
|
-
|
|
3104
3240
|
// src/pafi-backend/client.ts
|
|
3105
3241
|
function serializeBigInt(_key, value) {
|
|
3106
3242
|
return typeof value === "bigint" ? value.toString(10) : value;
|
|
@@ -3541,15 +3677,17 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
3541
3677
|
};
|
|
3542
3678
|
|
|
3543
3679
|
// src/index.ts
|
|
3544
|
-
var PAFI_ISSUER_SDK_VERSION = "0.
|
|
3680
|
+
var PAFI_ISSUER_SDK_VERSION = true ? "0.7.1" : "dev";
|
|
3545
3681
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3546
3682
|
0 && (module.exports = {
|
|
3683
|
+
AdapterMisconfiguredError,
|
|
3547
3684
|
AuthError,
|
|
3548
3685
|
AuthService,
|
|
3549
3686
|
BalanceAggregator,
|
|
3550
3687
|
BundlerNotConfiguredError,
|
|
3551
3688
|
BundlerRejectedError,
|
|
3552
3689
|
BurnIndexer,
|
|
3690
|
+
ConfigurationError,
|
|
3553
3691
|
DefaultPolicyEngine,
|
|
3554
3692
|
FeeManager,
|
|
3555
3693
|
InMemoryCursorStore,
|
|
@@ -3577,6 +3715,7 @@ var PAFI_ISSUER_SDK_VERSION = "0.4.0";
|
|
|
3577
3715
|
PointIndexer,
|
|
3578
3716
|
RelayError,
|
|
3579
3717
|
RelayService,
|
|
3718
|
+
ValidationError,
|
|
3580
3719
|
authenticateRequest,
|
|
3581
3720
|
createIssuerService,
|
|
3582
3721
|
createNativePtQuoter,
|