@pafi-dev/issuer 0.23.0 → 0.25.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/index.cjs +244 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -25
- package/dist/index.d.ts +78 -25
- package/dist/index.js +252 -134
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
BundlerNotConfiguredError: () => BundlerNotConfiguredError,
|
|
27
27
|
BundlerRejectedError: () => BundlerRejectedError,
|
|
28
28
|
BurnIndexer: () => BurnIndexer,
|
|
29
|
+
BurnIndexerFinalizeError: () => BurnIndexerFinalizeError,
|
|
29
30
|
ConfigurationError: () => ConfigurationError,
|
|
30
31
|
DEFAULT_REDEMPTION_POLICY: () => DEFAULT_REDEMPTION_POLICY,
|
|
31
32
|
DefaultPolicyEngine: () => DefaultPolicyEngine,
|
|
@@ -57,6 +58,7 @@ __export(index_exports, {
|
|
|
57
58
|
PerpDepositError: () => PerpDepositError,
|
|
58
59
|
PerpDepositHandler: () => PerpDepositHandler,
|
|
59
60
|
PointIndexer: () => PointIndexer,
|
|
61
|
+
PointIndexerFinalizeError: () => PointIndexerFinalizeError,
|
|
60
62
|
PointTokenDomainResolver: () => PointTokenDomainResolver,
|
|
61
63
|
PolicyProvider: () => PolicyProvider,
|
|
62
64
|
REDEMPTION_HISTORY_WINDOW_SEC: () => REDEMPTION_HISTORY_WINDOW_SEC,
|
|
@@ -908,6 +910,7 @@ var RelayService = class {
|
|
|
908
910
|
"prepareMint: deadline exceeds maximum allowed window (1 hour)"
|
|
909
911
|
);
|
|
910
912
|
}
|
|
913
|
+
const MINT_SOURCE = import_core5.Source.EQUITY;
|
|
911
914
|
const useWrapper = params.mintFeeWrapperAddress !== void 0;
|
|
912
915
|
const receiverForSig = useWrapper ? params.mintFeeWrapperAddress : params.userAddress;
|
|
913
916
|
let minterSig;
|
|
@@ -919,6 +922,7 @@ var RelayService = class {
|
|
|
919
922
|
user: params.userAddress,
|
|
920
923
|
receiver: receiverForSig,
|
|
921
924
|
amount: params.amount,
|
|
925
|
+
source: MINT_SOURCE,
|
|
922
926
|
nonce: params.mintRequestNonce,
|
|
923
927
|
deadline: params.deadline
|
|
924
928
|
}
|
|
@@ -949,9 +953,15 @@ var RelayService = class {
|
|
|
949
953
|
mintTarget = params.mintFeeWrapperAddress;
|
|
950
954
|
} else {
|
|
951
955
|
mintCallData = (0, import_viem3.encodeFunctionData)({
|
|
952
|
-
abi: import_core5.
|
|
956
|
+
abi: import_core5.POINT_TOKEN_MINT_SIG_ABI,
|
|
953
957
|
functionName: "mint",
|
|
954
|
-
args: [
|
|
958
|
+
args: [
|
|
959
|
+
params.userAddress,
|
|
960
|
+
params.amount,
|
|
961
|
+
MINT_SOURCE,
|
|
962
|
+
params.deadline,
|
|
963
|
+
minterSig
|
|
964
|
+
]
|
|
955
965
|
});
|
|
956
966
|
mintTarget = params.pointTokenAddress;
|
|
957
967
|
}
|
|
@@ -1036,11 +1046,12 @@ var RelayService = class {
|
|
|
1036
1046
|
let burnCallData;
|
|
1037
1047
|
try {
|
|
1038
1048
|
burnCallData = (0, import_viem3.encodeFunctionData)({
|
|
1039
|
-
abi: import_core5.
|
|
1049
|
+
abi: import_core5.POINT_TOKEN_BURN_SIG_ABI,
|
|
1040
1050
|
functionName: "burn",
|
|
1041
1051
|
args: [
|
|
1042
1052
|
params.burnRequest.from,
|
|
1043
1053
|
params.burnRequest.amount,
|
|
1054
|
+
params.burnRequest.source,
|
|
1044
1055
|
params.burnRequest.deadline,
|
|
1045
1056
|
params.burnerSignature
|
|
1046
1057
|
]
|
|
@@ -1135,11 +1146,12 @@ var RelayService = class {
|
|
|
1135
1146
|
mintTarget = params.mintFeeWrapperAddress;
|
|
1136
1147
|
} else {
|
|
1137
1148
|
mintCallData = (0, import_viem3.encodeFunctionData)({
|
|
1138
|
-
abi: import_core5.
|
|
1149
|
+
abi: import_core5.POINT_TOKEN_MINT_SIG_ABI,
|
|
1139
1150
|
functionName: "mint",
|
|
1140
1151
|
args: [
|
|
1141
1152
|
params.userAddress,
|
|
1142
1153
|
params.amount,
|
|
1154
|
+
import_core5.Source.EQUITY,
|
|
1143
1155
|
params.deadline,
|
|
1144
1156
|
PLACEHOLDER_SIG_65
|
|
1145
1157
|
]
|
|
@@ -1161,11 +1173,12 @@ var RelayService = class {
|
|
|
1161
1173
|
/** Burn-side mirror of `previewMintUserOp`. */
|
|
1162
1174
|
previewBurnUserOp(params) {
|
|
1163
1175
|
const burnCallData = (0, import_viem3.encodeFunctionData)({
|
|
1164
|
-
abi: import_core5.
|
|
1176
|
+
abi: import_core5.POINT_TOKEN_BURN_SIG_ABI,
|
|
1165
1177
|
functionName: "burn",
|
|
1166
1178
|
args: [
|
|
1167
1179
|
params.userAddress,
|
|
1168
1180
|
params.amount,
|
|
1181
|
+
import_core5.Source.EQUITY,
|
|
1169
1182
|
params.deadline,
|
|
1170
1183
|
PLACEHOLDER_SIG_65
|
|
1171
1184
|
]
|
|
@@ -1383,6 +1396,16 @@ var InMemoryCursorStore = class _InMemoryCursorStore {
|
|
|
1383
1396
|
|
|
1384
1397
|
// src/indexer/pointIndexer.ts
|
|
1385
1398
|
var import_viem4 = require("viem");
|
|
1399
|
+
var PointIndexerFinalizeError = class extends Error {
|
|
1400
|
+
constructor(message, context, cause) {
|
|
1401
|
+
super(message);
|
|
1402
|
+
this.context = context;
|
|
1403
|
+
this.cause = cause;
|
|
1404
|
+
this.name = "PointIndexerFinalizeError";
|
|
1405
|
+
}
|
|
1406
|
+
context;
|
|
1407
|
+
cause;
|
|
1408
|
+
};
|
|
1386
1409
|
var TRANSFER_EVENT = (0, import_viem4.parseAbiItem)(
|
|
1387
1410
|
"event Transfer(address indexed from, address indexed to, uint256 value)"
|
|
1388
1411
|
);
|
|
@@ -1608,8 +1631,18 @@ var PointIndexer = class {
|
|
|
1608
1631
|
evt.txHash,
|
|
1609
1632
|
this.pointTokenAddress
|
|
1610
1633
|
);
|
|
1611
|
-
} catch {
|
|
1612
|
-
|
|
1634
|
+
} catch (err) {
|
|
1635
|
+
throw new PointIndexerFinalizeError(
|
|
1636
|
+
`PointIndexer.deductBalance failed for tx ${evt.txHash} (to=${evt.to}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`,
|
|
1637
|
+
{
|
|
1638
|
+
pointToken: this.pointTokenAddress,
|
|
1639
|
+
to: evt.to,
|
|
1640
|
+
amount: evt.amount,
|
|
1641
|
+
txHash: evt.txHash,
|
|
1642
|
+
blockNumber: evt.blockNumber
|
|
1643
|
+
},
|
|
1644
|
+
err
|
|
1645
|
+
);
|
|
1613
1646
|
}
|
|
1614
1647
|
try {
|
|
1615
1648
|
await this.ledger.updateMintStatus(match.lockId, "MINTED", evt.txHash);
|
|
@@ -1631,6 +1664,16 @@ function pickMatchingLock(locks, amount) {
|
|
|
1631
1664
|
|
|
1632
1665
|
// src/indexer/burnIndexer.ts
|
|
1633
1666
|
var import_viem5 = require("viem");
|
|
1667
|
+
var BurnIndexerFinalizeError = class extends Error {
|
|
1668
|
+
constructor(message, context, cause) {
|
|
1669
|
+
super(message);
|
|
1670
|
+
this.context = context;
|
|
1671
|
+
this.cause = cause;
|
|
1672
|
+
this.name = "BurnIndexerFinalizeError";
|
|
1673
|
+
}
|
|
1674
|
+
context;
|
|
1675
|
+
cause;
|
|
1676
|
+
};
|
|
1634
1677
|
var TRANSFER_EVENT2 = (0, import_viem5.parseAbiItem)(
|
|
1635
1678
|
"event Transfer(address indexed from, address indexed to, uint256 value)"
|
|
1636
1679
|
);
|
|
@@ -1798,7 +1841,18 @@ var BurnIndexer = class {
|
|
|
1798
1841
|
try {
|
|
1799
1842
|
await this.ledger.resolveCreditByBurnTx(lockId, evt.txHash);
|
|
1800
1843
|
} catch (err) {
|
|
1801
|
-
|
|
1844
|
+
throw new BurnIndexerFinalizeError(
|
|
1845
|
+
`BurnIndexer.resolveCreditByBurnTx failed for tx ${evt.txHash} (lockId=${lockId}, from=${evt.from}, amount=${evt.amount}, block=${evt.blockNumber}); cursor will NOT advance, next tick retries.`,
|
|
1846
|
+
{
|
|
1847
|
+
pointToken: this.pointTokenAddress,
|
|
1848
|
+
from: evt.from,
|
|
1849
|
+
amount: evt.amount,
|
|
1850
|
+
txHash: evt.txHash,
|
|
1851
|
+
blockNumber: evt.blockNumber,
|
|
1852
|
+
lockId
|
|
1853
|
+
},
|
|
1854
|
+
err
|
|
1855
|
+
);
|
|
1802
1856
|
}
|
|
1803
1857
|
}
|
|
1804
1858
|
};
|
|
@@ -2113,14 +2167,12 @@ var IssuerApiHandlers = class _IssuerApiHandlers {
|
|
|
2113
2167
|
{ requested: pointToken }
|
|
2114
2168
|
);
|
|
2115
2169
|
}
|
|
2116
|
-
const [
|
|
2117
|
-
(0, import_core6.getMintRequestNonce)(this.provider, pointToken, normalizedAuthed),
|
|
2170
|
+
const [offChainBalance, onChainBalance, minter] = await Promise.all([
|
|
2118
2171
|
this.ledger.getBalance(normalizedAuthed, pointToken),
|
|
2119
2172
|
(0, import_core6.getPointTokenBalance)(this.provider, pointToken, normalizedAuthed),
|
|
2120
2173
|
(0, import_core6.isMinter)(this.provider, pointToken, normalizedAuthed)
|
|
2121
2174
|
]);
|
|
2122
2175
|
return {
|
|
2123
|
-
mintRequestNonce,
|
|
2124
2176
|
offChainBalance,
|
|
2125
2177
|
onChainBalance,
|
|
2126
2178
|
totalBalance: offChainBalance + onChainBalance,
|
|
@@ -2257,7 +2309,8 @@ var PointTokenDomainResolver = class {
|
|
|
2257
2309
|
var import_viem8 = require("viem");
|
|
2258
2310
|
var import_core7 = require("@pafi-dev/core");
|
|
2259
2311
|
var DEFAULT_REDEEM_LOCK_MS = 15 * 60 * 1e3;
|
|
2260
|
-
var
|
|
2312
|
+
var M11_SAFETY_MARGIN_MS = 30 * 1e3;
|
|
2313
|
+
var DEFAULT_SIG_DEADLINE_SEC = (DEFAULT_REDEEM_LOCK_MS - M11_SAFETY_MARGIN_MS) / 1e3;
|
|
2261
2314
|
var PTRedeemError = class extends import_core.PafiSdkError {
|
|
2262
2315
|
httpStatus = "unprocessable";
|
|
2263
2316
|
code;
|
|
@@ -2324,6 +2377,13 @@ var PTRedeemHandler = class {
|
|
|
2324
2377
|
this.redeemLockDurationMs = config.redeemLockDurationMs ?? DEFAULT_REDEEM_LOCK_MS;
|
|
2325
2378
|
this.signatureDeadlineSeconds = config.signatureDeadlineSeconds ?? DEFAULT_SIG_DEADLINE_SEC;
|
|
2326
2379
|
this.now = config.now ?? (() => Date.now());
|
|
2380
|
+
const maxAllowedSignatureMs = this.redeemLockDurationMs - M11_SAFETY_MARGIN_MS;
|
|
2381
|
+
if (this.signatureDeadlineSeconds * 1e3 > maxAllowedSignatureMs) {
|
|
2382
|
+
throw new PTRedeemError(
|
|
2383
|
+
"INVALID_AMOUNT",
|
|
2384
|
+
`PTRedeemHandler config: signatureDeadlineSeconds (${this.signatureDeadlineSeconds}s) must be at most redeemLockDurationMs - safety margin = ${maxAllowedSignatureMs / 1e3}s (redeemLockDurationMs=${this.redeemLockDurationMs / 1e3}s, safety=${M11_SAFETY_MARGIN_MS / 1e3}s). See audit M-11.`
|
|
2385
|
+
);
|
|
2386
|
+
}
|
|
2327
2387
|
if (config.redemptionService) {
|
|
2328
2388
|
this.redemptionService = config.redemptionService;
|
|
2329
2389
|
}
|
|
@@ -2389,8 +2449,14 @@ var PTRedeemHandler = class {
|
|
|
2389
2449
|
}
|
|
2390
2450
|
}
|
|
2391
2451
|
async _handleAfterNonceLock(request, burnNonce, pointTokenAddress) {
|
|
2452
|
+
const referenceMs = this.now();
|
|
2453
|
+
const projectedLockExpiresAtMs = referenceMs + this.redeemLockDurationMs;
|
|
2454
|
+
const requestedDeadlineSec = Math.floor(referenceMs / 1e3) + this.signatureDeadlineSeconds;
|
|
2455
|
+
const lockBoundedDeadlineSec = Math.floor(
|
|
2456
|
+
(projectedLockExpiresAtMs - M11_SAFETY_MARGIN_MS) / 1e3
|
|
2457
|
+
);
|
|
2392
2458
|
const previewDeadline = BigInt(
|
|
2393
|
-
Math.
|
|
2459
|
+
Math.min(requestedDeadlineSec, lockBoundedDeadlineSec)
|
|
2394
2460
|
);
|
|
2395
2461
|
let fee;
|
|
2396
2462
|
if (request.feeAmount !== void 0) {
|
|
@@ -2398,7 +2464,7 @@ var PTRedeemHandler = class {
|
|
|
2398
2464
|
} else if (this.feeService) {
|
|
2399
2465
|
const previewUserOp = this.relayService.previewBurnUserOp({
|
|
2400
2466
|
userAddress: request.userAddress,
|
|
2401
|
-
aaNonce:
|
|
2467
|
+
aaNonce: request.aaNonce,
|
|
2402
2468
|
pointTokenAddress,
|
|
2403
2469
|
amount: request.amount,
|
|
2404
2470
|
deadline: previewDeadline
|
|
@@ -2440,10 +2506,12 @@ var PTRedeemHandler = class {
|
|
|
2440
2506
|
chainId: this.chainId,
|
|
2441
2507
|
verifyingContract: pointTokenAddress
|
|
2442
2508
|
};
|
|
2509
|
+
const BURN_SOURCE = import_core7.Source.EQUITY;
|
|
2443
2510
|
const sponsoredBurnAmount = request.amount - fee;
|
|
2444
2511
|
const sponsoredBurnRequest = {
|
|
2445
2512
|
from: request.userAddress,
|
|
2446
2513
|
amount: sponsoredBurnAmount,
|
|
2514
|
+
source: BURN_SOURCE,
|
|
2447
2515
|
nonce: burnNonce,
|
|
2448
2516
|
deadline
|
|
2449
2517
|
};
|
|
@@ -2479,6 +2547,7 @@ var PTRedeemHandler = class {
|
|
|
2479
2547
|
const fallbackBurnRequest = {
|
|
2480
2548
|
from: request.userAddress,
|
|
2481
2549
|
amount: request.amount,
|
|
2550
|
+
source: BURN_SOURCE,
|
|
2482
2551
|
nonce: burnNonce,
|
|
2483
2552
|
deadline
|
|
2484
2553
|
};
|
|
@@ -3047,14 +3116,30 @@ function isNoWrapper2(address) {
|
|
|
3047
3116
|
return lower === "0x0000000000000000000000000000000000000000" || lower === "0x000000000000000000000000000000000000dead";
|
|
3048
3117
|
}
|
|
3049
3118
|
var DEFAULT_LOCK_MS = 15 * 60 * 1e3;
|
|
3050
|
-
var
|
|
3119
|
+
var M11_SAFETY_MARGIN_MS2 = 30 * 1e3;
|
|
3120
|
+
var DEFAULT_SIG_DEADLINE_SEC2 = (DEFAULT_LOCK_MS - M11_SAFETY_MARGIN_MS2) / 1e3;
|
|
3051
3121
|
var PTClaimHandler = class {
|
|
3052
3122
|
cfg;
|
|
3123
|
+
inFlightNonces = /* @__PURE__ */ new Map();
|
|
3053
3124
|
constructor(config) {
|
|
3125
|
+
const lockDurationMs = config.lockDurationMs ?? DEFAULT_LOCK_MS;
|
|
3126
|
+
const signatureDeadlineSeconds = config.signatureDeadlineSeconds ?? DEFAULT_SIG_DEADLINE_SEC2;
|
|
3127
|
+
const maxAllowedSignatureMs = lockDurationMs - M11_SAFETY_MARGIN_MS2;
|
|
3128
|
+
if (signatureDeadlineSeconds * 1e3 > maxAllowedSignatureMs) {
|
|
3129
|
+
throw new PTClaimError(
|
|
3130
|
+
"VALIDATION_FAILED",
|
|
3131
|
+
`PTClaimHandler config: signatureDeadlineSeconds (${signatureDeadlineSeconds}s) must be at most lockDurationMs - safety margin = ${maxAllowedSignatureMs / 1e3}s (lockDurationMs=${lockDurationMs / 1e3}s, safety=${M11_SAFETY_MARGIN_MS2 / 1e3}s). See audit M-11.`,
|
|
3132
|
+
{
|
|
3133
|
+
lockDurationMs,
|
|
3134
|
+
signatureDeadlineSeconds,
|
|
3135
|
+
maxAllowedSignatureSec: maxAllowedSignatureMs / 1e3
|
|
3136
|
+
}
|
|
3137
|
+
);
|
|
3138
|
+
}
|
|
3054
3139
|
this.cfg = {
|
|
3055
3140
|
...config,
|
|
3056
|
-
lockDurationMs
|
|
3057
|
-
signatureDeadlineSeconds
|
|
3141
|
+
lockDurationMs,
|
|
3142
|
+
signatureDeadlineSeconds,
|
|
3058
3143
|
now: config.now ?? (() => Date.now())
|
|
3059
3144
|
};
|
|
3060
3145
|
}
|
|
@@ -3084,77 +3169,82 @@ var PTClaimHandler = class {
|
|
|
3084
3169
|
}
|
|
3085
3170
|
const chainAddresses = (0, import_core11.getContractAddresses)(request.chainId);
|
|
3086
3171
|
const { batchExecutor: batchExecutorAddress } = chainAddresses;
|
|
3172
|
+
let mintRequestNonce;
|
|
3173
|
+
try {
|
|
3174
|
+
mintRequestNonce = await this.cfg.provider.readContract({
|
|
3175
|
+
address: request.pointTokenAddress,
|
|
3176
|
+
abi: import_core11.POINT_TOKEN_ABI,
|
|
3177
|
+
functionName: "mintRequestNonces",
|
|
3178
|
+
args: [request.userAddress]
|
|
3179
|
+
});
|
|
3180
|
+
} catch (err) {
|
|
3181
|
+
throw new PTClaimError(
|
|
3182
|
+
"NONCE_READ_FAILED",
|
|
3183
|
+
`failed to read mintRequestNonces(${request.userAddress}): ${err instanceof Error ? err.message : String(err)}`
|
|
3184
|
+
);
|
|
3185
|
+
}
|
|
3186
|
+
const nonceKey = `${(0, import_viem10.getAddress)(request.userAddress).toLowerCase()}:${request.pointTokenAddress.toLowerCase()}`;
|
|
3187
|
+
let userNonces = this.inFlightNonces.get(nonceKey);
|
|
3188
|
+
if (!userNonces) {
|
|
3189
|
+
userNonces = /* @__PURE__ */ new Set();
|
|
3190
|
+
this.inFlightNonces.set(nonceKey, userNonces);
|
|
3191
|
+
}
|
|
3192
|
+
if (userNonces.has(mintRequestNonce)) {
|
|
3193
|
+
throw new PTClaimError(
|
|
3194
|
+
"NONCE_IN_FLIGHT",
|
|
3195
|
+
`concurrent claim for nonce ${mintRequestNonce} in progress; retry after the prior request completes`,
|
|
3196
|
+
{ userAddress: request.userAddress, pointToken: request.pointTokenAddress, nonce: mintRequestNonce.toString() }
|
|
3197
|
+
);
|
|
3198
|
+
}
|
|
3199
|
+
userNonces.add(mintRequestNonce);
|
|
3087
3200
|
const wrapperOverride = this.cfg.mintFeeWrapperAddress;
|
|
3088
3201
|
const wrapperFromSdk = chainAddresses.mintFeeWrapper;
|
|
3089
3202
|
const resolvedWrapper = wrapperOverride !== void 0 ? isNoWrapper2(wrapperOverride) ? void 0 : wrapperOverride : isNoWrapper2(wrapperFromSdk) ? void 0 : wrapperFromSdk;
|
|
3090
|
-
const lockId = await this.cfg.ledger.lockForMinting(
|
|
3091
|
-
request.userAddress,
|
|
3092
|
-
request.amount,
|
|
3093
|
-
this.cfg.lockDurationMs,
|
|
3094
|
-
request.pointTokenAddress
|
|
3095
|
-
);
|
|
3096
3203
|
try {
|
|
3097
|
-
const
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
pointTokenAddress: request.pointTokenAddress,
|
|
3104
|
-
amount: request.amount,
|
|
3105
|
-
deadline: signatureDeadline,
|
|
3106
|
-
mintFeeWrapperAddress: resolvedWrapper
|
|
3107
|
-
});
|
|
3108
|
-
const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee({
|
|
3109
|
-
scenario: resolvedWrapper ? "mint-wrapped" : "mint",
|
|
3110
|
-
contractAddress: request.pointTokenAddress,
|
|
3111
|
-
partialUserOp: {
|
|
3112
|
-
sender: previewUserOp.sender,
|
|
3113
|
-
nonce: previewUserOp.nonce,
|
|
3114
|
-
callData: previewUserOp.callData
|
|
3115
|
-
}
|
|
3116
|
-
}) : 0n;
|
|
3117
|
-
const domainName = await this.cfg.domainResolver.resolve(
|
|
3204
|
+
const lockCreatedAtMs = this.cfg.now();
|
|
3205
|
+
const lockExpiresAtMs = lockCreatedAtMs + this.cfg.lockDurationMs;
|
|
3206
|
+
const lockId = await this.cfg.ledger.lockForMinting(
|
|
3207
|
+
request.userAddress,
|
|
3208
|
+
request.amount,
|
|
3209
|
+
this.cfg.lockDurationMs,
|
|
3118
3210
|
request.pointTokenAddress
|
|
3119
3211
|
);
|
|
3120
|
-
const domain = {
|
|
3121
|
-
name: domainName,
|
|
3122
|
-
chainId: request.chainId,
|
|
3123
|
-
verifyingContract: request.pointTokenAddress
|
|
3124
|
-
};
|
|
3125
|
-
let userOp;
|
|
3126
3212
|
try {
|
|
3127
|
-
|
|
3213
|
+
const requestedDeadlineSec = Math.floor(lockCreatedAtMs / 1e3) + this.cfg.signatureDeadlineSeconds;
|
|
3214
|
+
const lockBoundedDeadlineSec = Math.floor(
|
|
3215
|
+
(lockExpiresAtMs - M11_SAFETY_MARGIN_MS2) / 1e3
|
|
3216
|
+
);
|
|
3217
|
+
const signatureDeadline = BigInt(
|
|
3218
|
+
Math.min(requestedDeadlineSec, lockBoundedDeadlineSec)
|
|
3219
|
+
);
|
|
3220
|
+
const previewUserOp = this.cfg.relayService.previewMintUserOp({
|
|
3128
3221
|
userAddress: request.userAddress,
|
|
3129
3222
|
aaNonce: request.aaNonce,
|
|
3130
|
-
batchExecutorAddress,
|
|
3131
3223
|
pointTokenAddress: request.pointTokenAddress,
|
|
3132
3224
|
amount: request.amount,
|
|
3133
|
-
issuerSignerWallet: this.cfg.issuerSignerWallet,
|
|
3134
|
-
domain,
|
|
3135
|
-
mintRequestNonce: request.mintRequestNonce,
|
|
3136
3225
|
deadline: signatureDeadline,
|
|
3137
|
-
mintFeeWrapperAddress: resolvedWrapper
|
|
3138
|
-
// Pass the bundler-estimated `feeAmount` explicitly so the
|
|
3139
|
-
// RelayService skips its legacy `quoteOperatorFeePt` path
|
|
3140
|
-
// (which uses the SDK's old 12_000 bps premium default).
|
|
3141
|
-
// Without this, the response's `feeAmount` (from FeeManager,
|
|
3142
|
-
// 100% premium on top of PAFI's 110% server-side estimate)
|
|
3143
|
-
// would diverge from the actual PT.transfer amount in the
|
|
3144
|
-
// UserOp batch (`quoteOperatorFeePt`'s 120%), and the user
|
|
3145
|
-
// would see one value while the wallet transferred another.
|
|
3146
|
-
feeAmount
|
|
3226
|
+
mintFeeWrapperAddress: resolvedWrapper
|
|
3147
3227
|
});
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3228
|
+
const feeAmount = this.cfg.feeService ? await this.cfg.feeService.estimateGasFee({
|
|
3229
|
+
scenario: resolvedWrapper ? "mint-wrapped" : "mint",
|
|
3230
|
+
contractAddress: request.pointTokenAddress,
|
|
3231
|
+
partialUserOp: {
|
|
3232
|
+
sender: previewUserOp.sender,
|
|
3233
|
+
nonce: previewUserOp.nonce,
|
|
3234
|
+
callData: previewUserOp.callData
|
|
3235
|
+
}
|
|
3236
|
+
}) : 0n;
|
|
3237
|
+
const domainName = await this.cfg.domainResolver.resolve(
|
|
3238
|
+
request.pointTokenAddress
|
|
3152
3239
|
);
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3240
|
+
const domain = {
|
|
3241
|
+
name: domainName,
|
|
3242
|
+
chainId: request.chainId,
|
|
3243
|
+
verifyingContract: request.pointTokenAddress
|
|
3244
|
+
};
|
|
3245
|
+
let userOp;
|
|
3156
3246
|
try {
|
|
3157
|
-
|
|
3247
|
+
userOp = await this.cfg.relayService.prepareMint({
|
|
3158
3248
|
userAddress: request.userAddress,
|
|
3159
3249
|
aaNonce: request.aaNonce,
|
|
3160
3250
|
batchExecutorAddress,
|
|
@@ -3162,34 +3252,68 @@ var PTClaimHandler = class {
|
|
|
3162
3252
|
amount: request.amount,
|
|
3163
3253
|
issuerSignerWallet: this.cfg.issuerSignerWallet,
|
|
3164
3254
|
domain,
|
|
3165
|
-
mintRequestNonce
|
|
3255
|
+
mintRequestNonce,
|
|
3166
3256
|
deadline: signatureDeadline,
|
|
3167
|
-
|
|
3168
|
-
|
|
3257
|
+
mintFeeWrapperAddress: resolvedWrapper,
|
|
3258
|
+
// Pass the bundler-estimated `feeAmount` explicitly so the
|
|
3259
|
+
// RelayService skips its legacy `quoteOperatorFeePt` path
|
|
3260
|
+
// (which uses the SDK's old 12_000 bps premium default).
|
|
3261
|
+
// Without this, the response's `feeAmount` (from FeeManager,
|
|
3262
|
+
// 100% premium on top of PAFI's 110% server-side estimate)
|
|
3263
|
+
// would diverge from the actual PT.transfer amount in the
|
|
3264
|
+
// UserOp batch (`quoteOperatorFeePt`'s 120%), and the user
|
|
3265
|
+
// would see one value while the wallet transferred another.
|
|
3266
|
+
feeAmount
|
|
3169
3267
|
});
|
|
3170
3268
|
} catch (err) {
|
|
3171
3269
|
throw new PTClaimError(
|
|
3172
3270
|
"BUILD_FAILED",
|
|
3173
|
-
`prepareMint
|
|
3271
|
+
`prepareMint failed: ${err instanceof Error ? err.message : String(err)}`
|
|
3174
3272
|
);
|
|
3175
3273
|
}
|
|
3274
|
+
let fallback;
|
|
3275
|
+
if (feeAmount > 0n) {
|
|
3276
|
+
try {
|
|
3277
|
+
fallback = await this.cfg.relayService.prepareMint({
|
|
3278
|
+
userAddress: request.userAddress,
|
|
3279
|
+
aaNonce: request.aaNonce,
|
|
3280
|
+
batchExecutorAddress,
|
|
3281
|
+
pointTokenAddress: request.pointTokenAddress,
|
|
3282
|
+
amount: request.amount,
|
|
3283
|
+
issuerSignerWallet: this.cfg.issuerSignerWallet,
|
|
3284
|
+
domain,
|
|
3285
|
+
mintRequestNonce,
|
|
3286
|
+
deadline: signatureDeadline,
|
|
3287
|
+
feeAmount: 0n,
|
|
3288
|
+
mintFeeWrapperAddress: resolvedWrapper
|
|
3289
|
+
});
|
|
3290
|
+
} catch (err) {
|
|
3291
|
+
throw new PTClaimError(
|
|
3292
|
+
"BUILD_FAILED",
|
|
3293
|
+
`prepareMint (fallback) failed: ${err instanceof Error ? err.message : String(err)}`
|
|
3294
|
+
);
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
const calls = (0, import_core11.decodeBatchExecuteCalls)(userOp.callData);
|
|
3298
|
+
const callsFallback = fallback ? (0, import_core11.decodeBatchExecuteCalls)(fallback.callData) : void 0;
|
|
3299
|
+
return {
|
|
3300
|
+
userOp,
|
|
3301
|
+
fallback,
|
|
3302
|
+
lockId,
|
|
3303
|
+
feeAmount,
|
|
3304
|
+
signatureDeadline,
|
|
3305
|
+
expiresInSeconds: Math.floor(this.cfg.lockDurationMs / 1e3),
|
|
3306
|
+
calls,
|
|
3307
|
+
callsFallback
|
|
3308
|
+
};
|
|
3309
|
+
} catch (err) {
|
|
3310
|
+
await this.cfg.ledger.releaseLock(lockId).catch(() => {
|
|
3311
|
+
});
|
|
3312
|
+
throw err;
|
|
3176
3313
|
}
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
userOp,
|
|
3181
|
-
fallback,
|
|
3182
|
-
lockId,
|
|
3183
|
-
feeAmount,
|
|
3184
|
-
signatureDeadline,
|
|
3185
|
-
expiresInSeconds: Math.floor(this.cfg.lockDurationMs / 1e3),
|
|
3186
|
-
calls,
|
|
3187
|
-
callsFallback
|
|
3188
|
-
};
|
|
3189
|
-
} catch (err) {
|
|
3190
|
-
await this.cfg.ledger.releaseLock(lockId).catch(() => {
|
|
3191
|
-
});
|
|
3192
|
-
throw err;
|
|
3314
|
+
} finally {
|
|
3315
|
+
userNonces.delete(mintRequestNonce);
|
|
3316
|
+
if (userNonces.size === 0) this.inFlightNonces.delete(nonceKey);
|
|
3193
3317
|
}
|
|
3194
3318
|
}
|
|
3195
3319
|
};
|
|
@@ -3504,7 +3628,6 @@ var IssuerApiAdapter = class {
|
|
|
3504
3628
|
}
|
|
3505
3629
|
);
|
|
3506
3630
|
return {
|
|
3507
|
-
mintRequestNonce: result.mintRequestNonce.toString(),
|
|
3508
3631
|
offChainBalance: result.offChainBalance.toString(),
|
|
3509
3632
|
onChainBalance: result.onChainBalance.toString(),
|
|
3510
3633
|
totalBalance: result.totalBalance.toString(),
|
|
@@ -3528,8 +3651,7 @@ var IssuerApiAdapter = class {
|
|
|
3528
3651
|
amount: input.amount,
|
|
3529
3652
|
pointTokenAddress,
|
|
3530
3653
|
chainId: input.chainId,
|
|
3531
|
-
aaNonce: input.aaNonce
|
|
3532
|
-
mintRequestNonce: input.mintRequestNonce
|
|
3654
|
+
aaNonce: input.aaNonce
|
|
3533
3655
|
});
|
|
3534
3656
|
const sponsorAuth = await this.buildSponsorAuth(
|
|
3535
3657
|
input.authenticatedAddress,
|
|
@@ -3625,8 +3747,7 @@ var IssuerApiAdapter = class {
|
|
|
3625
3747
|
amount: input.amount,
|
|
3626
3748
|
pointTokenAddress,
|
|
3627
3749
|
chainId: input.chainId,
|
|
3628
|
-
aaNonce: input.aaNonce
|
|
3629
|
-
mintRequestNonce: input.mintRequestNonce
|
|
3750
|
+
aaNonce: input.aaNonce
|
|
3630
3751
|
});
|
|
3631
3752
|
const prepared = await this.runMobilePrepare(
|
|
3632
3753
|
input.authenticatedAddress,
|
|
@@ -4990,22 +5111,22 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
4990
5111
|
}
|
|
4991
5112
|
throw err;
|
|
4992
5113
|
}
|
|
4993
|
-
const { issuer,
|
|
5114
|
+
const { issuer, equityCap, equitySupply, remaining } = state;
|
|
4994
5115
|
if (!issuer.active) {
|
|
4995
5116
|
throw new IssuerStateError(
|
|
4996
5117
|
"ISSUER_INACTIVE",
|
|
4997
|
-
`Issuer ${issuer.
|
|
4998
|
-
{
|
|
5118
|
+
`Issuer "${issuer.name}" is deactivated on IssuerRegistry`,
|
|
5119
|
+
{ pointToken }
|
|
4999
5120
|
);
|
|
5000
5121
|
}
|
|
5001
|
-
if (
|
|
5122
|
+
if (equitySupply + amount > equityCap.hardCap) {
|
|
5002
5123
|
throw new IssuerStateError(
|
|
5003
5124
|
"MINT_CAP_EXCEEDED",
|
|
5004
|
-
`Requested ${amount} PT would exceed mint cap. Cap=${hardCap},
|
|
5125
|
+
`Requested ${amount} PT would exceed EQUITY mint cap. Cap=${equityCap.hardCap}, equityMinted=${equitySupply}, remaining=${remaining}`,
|
|
5005
5126
|
{
|
|
5006
5127
|
requested: amount.toString(),
|
|
5007
|
-
cap: hardCap.toString(),
|
|
5008
|
-
|
|
5128
|
+
cap: equityCap.hardCap.toString(),
|
|
5129
|
+
equityMinted: equitySupply.toString(),
|
|
5009
5130
|
remaining: remaining.toString()
|
|
5010
5131
|
}
|
|
5011
5132
|
);
|
|
@@ -5021,33 +5142,28 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
5021
5142
|
args: [issuerAddr]
|
|
5022
5143
|
});
|
|
5023
5144
|
const issuer = {
|
|
5024
|
-
issuerAddress: issuerStruct.issuerAddress,
|
|
5025
5145
|
signerAddress: issuerStruct.signerAddress,
|
|
5026
5146
|
name: issuerStruct.name,
|
|
5027
|
-
symbol: issuerStruct.symbol,
|
|
5028
5147
|
active: issuerStruct.active,
|
|
5029
|
-
|
|
5030
|
-
|
|
5148
|
+
capitalBase: issuerStruct.capitalBase,
|
|
5149
|
+
basisPoints: Number(issuerStruct.basisPoints)
|
|
5031
5150
|
};
|
|
5032
|
-
const
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
capBasisPoints: tokenCap.capBasisPoints
|
|
5151
|
+
const equitySupply = await this.provider.readContract({
|
|
5152
|
+
address: tokenAddr,
|
|
5153
|
+
abi: import_core19.POINT_TOKEN_ABI,
|
|
5154
|
+
functionName: "equitySupply"
|
|
5155
|
+
});
|
|
5156
|
+
const hardCap = issuer.capitalBase * BigInt(issuer.basisPoints) / 10000n;
|
|
5157
|
+
const equityCap = {
|
|
5158
|
+
capitalBase: issuer.capitalBase,
|
|
5159
|
+
basisPoints: issuer.basisPoints,
|
|
5160
|
+
hardCap
|
|
5043
5161
|
};
|
|
5044
|
-
const
|
|
5045
|
-
const remaining = hardCap > totalSupply ? hardCap - totalSupply : 0n;
|
|
5162
|
+
const remaining = hardCap > equitySupply ? hardCap - equitySupply : 0n;
|
|
5046
5163
|
return {
|
|
5047
5164
|
issuer,
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
hardCap,
|
|
5165
|
+
equityCap,
|
|
5166
|
+
equitySupply,
|
|
5051
5167
|
remaining
|
|
5052
5168
|
};
|
|
5053
5169
|
}
|
|
@@ -5090,7 +5206,7 @@ var MemoryRedemptionHistoryStore = class {
|
|
|
5090
5206
|
};
|
|
5091
5207
|
|
|
5092
5208
|
// src/index.ts
|
|
5093
|
-
var PAFI_ISSUER_SDK_VERSION = true ? "0.
|
|
5209
|
+
var PAFI_ISSUER_SDK_VERSION = true ? "0.25.0" : "dev";
|
|
5094
5210
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5095
5211
|
0 && (module.exports = {
|
|
5096
5212
|
AdapterMisconfiguredError,
|
|
@@ -5099,6 +5215,7 @@ var PAFI_ISSUER_SDK_VERSION = true ? "0.23.0" : "dev";
|
|
|
5099
5215
|
BundlerNotConfiguredError,
|
|
5100
5216
|
BundlerRejectedError,
|
|
5101
5217
|
BurnIndexer,
|
|
5218
|
+
BurnIndexerFinalizeError,
|
|
5102
5219
|
ConfigurationError,
|
|
5103
5220
|
DEFAULT_REDEMPTION_POLICY,
|
|
5104
5221
|
DefaultPolicyEngine,
|
|
@@ -5130,6 +5247,7 @@ var PAFI_ISSUER_SDK_VERSION = true ? "0.23.0" : "dev";
|
|
|
5130
5247
|
PerpDepositError,
|
|
5131
5248
|
PerpDepositHandler,
|
|
5132
5249
|
PointIndexer,
|
|
5250
|
+
PointIndexerFinalizeError,
|
|
5133
5251
|
PointTokenDomainResolver,
|
|
5134
5252
|
PolicyProvider,
|
|
5135
5253
|
REDEMPTION_HISTORY_WINDOW_SEC,
|