@pafi-dev/issuer 0.5.30 → 0.5.32
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/README.md +41 -4
- package/dist/index.cjs +70 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +77 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -369,6 +369,23 @@ declare class RelayError extends Error {
|
|
|
369
369
|
constructor(code: RelayErrorCode, message: string, cause?: unknown);
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Optional config that lets `RelayService` auto-quote the operator fee
|
|
374
|
+
* + auto-resolve the recipient when callers don't pass `feeAmount` /
|
|
375
|
+
* `feeRecipient`. When both `provider` + `chainId` are set, callers can
|
|
376
|
+
* omit the fee params entirely; the service will:
|
|
377
|
+
*
|
|
378
|
+
* 1. Resolve `feeRecipient = getContractAddresses(chainId).pafiFeeRecipient`
|
|
379
|
+
* 2. If `feeAmount` is undefined → run `quoteOperatorFeePt(...)` against
|
|
380
|
+
* Chainlink + V4 subgraph to compute the PT amount.
|
|
381
|
+
*
|
|
382
|
+
* When unset, the legacy "caller passes feeAmount + feeRecipient or no
|
|
383
|
+
* fee" behavior applies, so existing integrations keep working.
|
|
384
|
+
*/
|
|
385
|
+
interface RelayServiceConfig {
|
|
386
|
+
provider?: PublicClient;
|
|
387
|
+
chainId?: number;
|
|
388
|
+
}
|
|
372
389
|
/**
|
|
373
390
|
* Builds unsigned `PartialUserOperation` payloads for the v1.4 sponsored
|
|
374
391
|
* flow. The service is stateless and HTTP-client-free:
|
|
@@ -385,6 +402,26 @@ declare class RelayError extends Error {
|
|
|
385
402
|
* concerns moved to the Bundler + Paymaster in v1.4.
|
|
386
403
|
*/
|
|
387
404
|
declare class RelayService {
|
|
405
|
+
private readonly provider;
|
|
406
|
+
private readonly chainId;
|
|
407
|
+
constructor(config?: RelayServiceConfig);
|
|
408
|
+
/**
|
|
409
|
+
* Resolve the fee recipient + amount applied to the next UserOp:
|
|
410
|
+
*
|
|
411
|
+
* - If caller passed an explicit `feeRecipient`, use it (testing
|
|
412
|
+
* only — sponsor-relayer's L1 will reject any non-canonical
|
|
413
|
+
* recipient with `INSUFFICIENT_FEE`). Otherwise, default to
|
|
414
|
+
* `getContractAddresses(chainId).pafiFeeRecipient` when the
|
|
415
|
+
* service has a `chainId` configured.
|
|
416
|
+
* - If caller passed `feeAmount`, use it. Otherwise, when the
|
|
417
|
+
* service has both `provider` + `chainId`, auto-quote via
|
|
418
|
+
* `quoteOperatorFeePt`.
|
|
419
|
+
* - When the service is unconfigured AND caller passed nothing,
|
|
420
|
+
* return `{ feeAmount: 0n, feeRecipient: undefined }` — legacy
|
|
421
|
+
* "no fee" behavior, caller must opt in for the gas-reimbursement
|
|
422
|
+
* transfer to be added to the batch.
|
|
423
|
+
*/
|
|
424
|
+
private resolveFee;
|
|
388
425
|
/**
|
|
389
426
|
* Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
|
|
390
427
|
* `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
@@ -401,7 +438,7 @@ declare class RelayService {
|
|
|
401
438
|
* burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
|
|
402
439
|
* bytes (typically from `PTRedeemHandler`).
|
|
403
440
|
*/
|
|
404
|
-
prepareBurn(params: PrepareBurnParams): PartialUserOperation
|
|
441
|
+
prepareBurn(params: PrepareBurnParams): Promise<PartialUserOperation>;
|
|
405
442
|
}
|
|
406
443
|
/**
|
|
407
444
|
* v1.4 — sig-gated `PointToken.mint(to, amount, deadline, minterSig)`.
|
package/dist/index.d.ts
CHANGED
|
@@ -369,6 +369,23 @@ declare class RelayError extends Error {
|
|
|
369
369
|
constructor(code: RelayErrorCode, message: string, cause?: unknown);
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Optional config that lets `RelayService` auto-quote the operator fee
|
|
374
|
+
* + auto-resolve the recipient when callers don't pass `feeAmount` /
|
|
375
|
+
* `feeRecipient`. When both `provider` + `chainId` are set, callers can
|
|
376
|
+
* omit the fee params entirely; the service will:
|
|
377
|
+
*
|
|
378
|
+
* 1. Resolve `feeRecipient = getContractAddresses(chainId).pafiFeeRecipient`
|
|
379
|
+
* 2. If `feeAmount` is undefined → run `quoteOperatorFeePt(...)` against
|
|
380
|
+
* Chainlink + V4 subgraph to compute the PT amount.
|
|
381
|
+
*
|
|
382
|
+
* When unset, the legacy "caller passes feeAmount + feeRecipient or no
|
|
383
|
+
* fee" behavior applies, so existing integrations keep working.
|
|
384
|
+
*/
|
|
385
|
+
interface RelayServiceConfig {
|
|
386
|
+
provider?: PublicClient;
|
|
387
|
+
chainId?: number;
|
|
388
|
+
}
|
|
372
389
|
/**
|
|
373
390
|
* Builds unsigned `PartialUserOperation` payloads for the v1.4 sponsored
|
|
374
391
|
* flow. The service is stateless and HTTP-client-free:
|
|
@@ -385,6 +402,26 @@ declare class RelayError extends Error {
|
|
|
385
402
|
* concerns moved to the Bundler + Paymaster in v1.4.
|
|
386
403
|
*/
|
|
387
404
|
declare class RelayService {
|
|
405
|
+
private readonly provider;
|
|
406
|
+
private readonly chainId;
|
|
407
|
+
constructor(config?: RelayServiceConfig);
|
|
408
|
+
/**
|
|
409
|
+
* Resolve the fee recipient + amount applied to the next UserOp:
|
|
410
|
+
*
|
|
411
|
+
* - If caller passed an explicit `feeRecipient`, use it (testing
|
|
412
|
+
* only — sponsor-relayer's L1 will reject any non-canonical
|
|
413
|
+
* recipient with `INSUFFICIENT_FEE`). Otherwise, default to
|
|
414
|
+
* `getContractAddresses(chainId).pafiFeeRecipient` when the
|
|
415
|
+
* service has a `chainId` configured.
|
|
416
|
+
* - If caller passed `feeAmount`, use it. Otherwise, when the
|
|
417
|
+
* service has both `provider` + `chainId`, auto-quote via
|
|
418
|
+
* `quoteOperatorFeePt`.
|
|
419
|
+
* - When the service is unconfigured AND caller passed nothing,
|
|
420
|
+
* return `{ feeAmount: 0n, feeRecipient: undefined }` — legacy
|
|
421
|
+
* "no fee" behavior, caller must opt in for the gas-reimbursement
|
|
422
|
+
* transfer to be added to the batch.
|
|
423
|
+
*/
|
|
424
|
+
private resolveFee;
|
|
388
425
|
/**
|
|
389
426
|
* Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
|
|
390
427
|
* `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
@@ -401,7 +438,7 @@ declare class RelayService {
|
|
|
401
438
|
* burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
|
|
402
439
|
* bytes (typically from `PTRedeemHandler`).
|
|
403
440
|
*/
|
|
404
|
-
prepareBurn(params: PrepareBurnParams): PartialUserOperation
|
|
441
|
+
prepareBurn(params: PrepareBurnParams): Promise<PartialUserOperation>;
|
|
405
442
|
}
|
|
406
443
|
/**
|
|
407
444
|
* v1.4 — sig-gated `PointToken.mint(to, amount, deadline, minterSig)`.
|
package/dist/index.js
CHANGED
|
@@ -388,9 +388,48 @@ import {
|
|
|
388
388
|
import {
|
|
389
389
|
POINT_TOKEN_V2_ABI,
|
|
390
390
|
buildPartialUserOperation,
|
|
391
|
-
signMintRequest
|
|
391
|
+
signMintRequest,
|
|
392
|
+
getContractAddresses,
|
|
393
|
+
quoteOperatorFeePt
|
|
392
394
|
} from "@pafi-dev/core";
|
|
393
395
|
var RelayService = class {
|
|
396
|
+
provider;
|
|
397
|
+
chainId;
|
|
398
|
+
constructor(config = {}) {
|
|
399
|
+
this.provider = config.provider;
|
|
400
|
+
this.chainId = config.chainId;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Resolve the fee recipient + amount applied to the next UserOp:
|
|
404
|
+
*
|
|
405
|
+
* - If caller passed an explicit `feeRecipient`, use it (testing
|
|
406
|
+
* only — sponsor-relayer's L1 will reject any non-canonical
|
|
407
|
+
* recipient with `INSUFFICIENT_FEE`). Otherwise, default to
|
|
408
|
+
* `getContractAddresses(chainId).pafiFeeRecipient` when the
|
|
409
|
+
* service has a `chainId` configured.
|
|
410
|
+
* - If caller passed `feeAmount`, use it. Otherwise, when the
|
|
411
|
+
* service has both `provider` + `chainId`, auto-quote via
|
|
412
|
+
* `quoteOperatorFeePt`.
|
|
413
|
+
* - When the service is unconfigured AND caller passed nothing,
|
|
414
|
+
* return `{ feeAmount: 0n, feeRecipient: undefined }` — legacy
|
|
415
|
+
* "no fee" behavior, caller must opt in for the gas-reimbursement
|
|
416
|
+
* transfer to be added to the batch.
|
|
417
|
+
*/
|
|
418
|
+
async resolveFee(params) {
|
|
419
|
+
const feeRecipient = params.feeRecipient ?? (this.chainId !== void 0 ? getContractAddresses(this.chainId).pafiFeeRecipient : void 0);
|
|
420
|
+
if (params.feeAmount !== void 0) {
|
|
421
|
+
return { feeAmount: params.feeAmount, feeRecipient };
|
|
422
|
+
}
|
|
423
|
+
if (this.provider && this.chainId !== void 0) {
|
|
424
|
+
const feeAmount = await quoteOperatorFeePt({
|
|
425
|
+
provider: this.provider,
|
|
426
|
+
chainId: this.chainId,
|
|
427
|
+
pointTokenAddress: params.pointTokenAddress
|
|
428
|
+
});
|
|
429
|
+
return { feeAmount, feeRecipient };
|
|
430
|
+
}
|
|
431
|
+
return { feeAmount: 0n, feeRecipient };
|
|
432
|
+
}
|
|
394
433
|
/**
|
|
395
434
|
* Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
|
|
396
435
|
* `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
@@ -475,14 +514,19 @@ var RelayService = class {
|
|
|
475
514
|
data: mintCallData
|
|
476
515
|
}
|
|
477
516
|
];
|
|
478
|
-
|
|
479
|
-
|
|
517
|
+
const { feeAmount, feeRecipient } = await this.resolveFee({
|
|
518
|
+
feeAmount: params.feeAmount,
|
|
519
|
+
feeRecipient: params.feeRecipient,
|
|
520
|
+
pointTokenAddress: params.pointTokenAddress
|
|
521
|
+
});
|
|
522
|
+
if (feeAmount > 0n) {
|
|
523
|
+
if (!feeRecipient) {
|
|
480
524
|
throw new RelayError(
|
|
481
525
|
"ENCODE_FAILED",
|
|
482
|
-
"prepareMint: feeRecipient
|
|
526
|
+
"prepareMint: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`."
|
|
483
527
|
);
|
|
484
528
|
}
|
|
485
|
-
if (
|
|
529
|
+
if (feeRecipient === "0x0000000000000000000000000000000000000000") {
|
|
486
530
|
throw new RelayError(
|
|
487
531
|
"ENCODE_FAILED",
|
|
488
532
|
"prepareMint: feeRecipient must not be zero address"
|
|
@@ -494,7 +538,7 @@ var RelayService = class {
|
|
|
494
538
|
data: encodeFunctionData({
|
|
495
539
|
abi: erc20Abi,
|
|
496
540
|
functionName: "transfer",
|
|
497
|
-
args: [
|
|
541
|
+
args: [feeRecipient, feeAmount]
|
|
498
542
|
})
|
|
499
543
|
});
|
|
500
544
|
}
|
|
@@ -520,7 +564,7 @@ var RelayService = class {
|
|
|
520
564
|
* burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
|
|
521
565
|
* bytes (typically from `PTRedeemHandler`).
|
|
522
566
|
*/
|
|
523
|
-
prepareBurn(params) {
|
|
567
|
+
async prepareBurn(params) {
|
|
524
568
|
if (!params.pointTokenAddress) {
|
|
525
569
|
throw new RelayError("ENCODE_FAILED", "prepareBurn: pointTokenAddress required");
|
|
526
570
|
}
|
|
@@ -561,14 +605,19 @@ var RelayService = class {
|
|
|
561
605
|
);
|
|
562
606
|
}
|
|
563
607
|
const operations = [];
|
|
564
|
-
|
|
565
|
-
|
|
608
|
+
const { feeAmount, feeRecipient } = await this.resolveFee({
|
|
609
|
+
feeAmount: params.feeAmount,
|
|
610
|
+
feeRecipient: params.feeRecipient,
|
|
611
|
+
pointTokenAddress: params.pointTokenAddress
|
|
612
|
+
});
|
|
613
|
+
if (feeAmount > 0n) {
|
|
614
|
+
if (!feeRecipient) {
|
|
566
615
|
throw new RelayError(
|
|
567
616
|
"ENCODE_FAILED",
|
|
568
|
-
"prepareBurn: feeRecipient
|
|
617
|
+
"prepareBurn: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`."
|
|
569
618
|
);
|
|
570
619
|
}
|
|
571
|
-
if (
|
|
620
|
+
if (feeRecipient === "0x0000000000000000000000000000000000000000") {
|
|
572
621
|
throw new RelayError(
|
|
573
622
|
"ENCODE_FAILED",
|
|
574
623
|
"prepareBurn: feeRecipient must not be zero address"
|
|
@@ -580,7 +629,7 @@ var RelayService = class {
|
|
|
580
629
|
data: encodeFunctionData({
|
|
581
630
|
abi: erc20Abi,
|
|
582
631
|
functionName: "transfer",
|
|
583
|
-
args: [
|
|
632
|
+
args: [feeRecipient, feeAmount]
|
|
584
633
|
})
|
|
585
634
|
});
|
|
586
635
|
}
|
|
@@ -1420,7 +1469,7 @@ var PTRedeemHandler = class {
|
|
|
1420
1469
|
this.redeemLockDurationMs,
|
|
1421
1470
|
this.pointTokenAddress
|
|
1422
1471
|
);
|
|
1423
|
-
const sponsoredUserOp = this.relayService.prepareBurn({
|
|
1472
|
+
const sponsoredUserOp = await this.relayService.prepareBurn({
|
|
1424
1473
|
mode: "burnWithSig",
|
|
1425
1474
|
userAddress: request.userAddress,
|
|
1426
1475
|
aaNonce: request.aaNonce,
|
|
@@ -1454,15 +1503,19 @@ var PTRedeemHandler = class {
|
|
|
1454
1503
|
this.redeemLockDurationMs,
|
|
1455
1504
|
this.pointTokenAddress
|
|
1456
1505
|
);
|
|
1457
|
-
const fallbackUserOp = this.relayService.prepareBurn({
|
|
1506
|
+
const fallbackUserOp = await this.relayService.prepareBurn({
|
|
1458
1507
|
mode: "burnWithSig",
|
|
1459
1508
|
userAddress: request.userAddress,
|
|
1460
1509
|
aaNonce: request.aaNonce,
|
|
1461
1510
|
pointTokenAddress: this.pointTokenAddress,
|
|
1462
1511
|
batchExecutorAddress: this.batchExecutorAddress,
|
|
1463
1512
|
burnRequest: fallbackBurnRequest,
|
|
1464
|
-
burnerSignature: fallbackSig
|
|
1465
|
-
//
|
|
1513
|
+
burnerSignature: fallbackSig,
|
|
1514
|
+
// Explicit 0n — fallback is fee-free regardless of how
|
|
1515
|
+
// RelayService is configured. Without this, an
|
|
1516
|
+
// auto-quoting RelayService would try to quote a fee here
|
|
1517
|
+
// and re-add the PT.transfer we're trying to strip.
|
|
1518
|
+
feeAmount: 0n
|
|
1466
1519
|
});
|
|
1467
1520
|
fallback = {
|
|
1468
1521
|
lockId: fallbackLockId,
|
|
@@ -2164,7 +2217,7 @@ var PafiBackendClient = class {
|
|
|
2164
2217
|
|
|
2165
2218
|
// src/config.ts
|
|
2166
2219
|
import { getAddress as getAddress8 } from "viem";
|
|
2167
|
-
import { getContractAddresses } from "@pafi-dev/core";
|
|
2220
|
+
import { getContractAddresses as getContractAddresses2 } from "@pafi-dev/core";
|
|
2168
2221
|
function createIssuerService(config) {
|
|
2169
2222
|
if (!config.provider) {
|
|
2170
2223
|
throw new Error("createIssuerService: provider is required");
|
|
@@ -2198,7 +2251,10 @@ function createIssuerService(config) {
|
|
|
2198
2251
|
authServiceConfig.jwtExpiresIn = config.auth.jwtExpiresIn;
|
|
2199
2252
|
}
|
|
2200
2253
|
const authService = new AuthService(authServiceConfig);
|
|
2201
|
-
const relayService = new RelayService(
|
|
2254
|
+
const relayService = new RelayService({
|
|
2255
|
+
provider: config.provider,
|
|
2256
|
+
chainId: config.chainId
|
|
2257
|
+
});
|
|
2202
2258
|
let feeManager;
|
|
2203
2259
|
if (config.fee) {
|
|
2204
2260
|
feeManager = new FeeManager({
|
|
@@ -2231,7 +2287,7 @@ function createIssuerService(config) {
|
|
|
2231
2287
|
indexers.set(tokenAddress, new PointIndexer(indexerConfig));
|
|
2232
2288
|
}
|
|
2233
2289
|
const firstIndexer = indexers.get(tokenAddresses[0]);
|
|
2234
|
-
const chainAddresses =
|
|
2290
|
+
const chainAddresses = getContractAddresses2(config.chainId);
|
|
2235
2291
|
const resolvedContracts = {
|
|
2236
2292
|
batchExecutor: chainAddresses.batchExecutor,
|
|
2237
2293
|
usdt: chainAddresses.usdt,
|
|
@@ -2326,7 +2382,7 @@ import { getAddress as getAddress9 } from "viem";
|
|
|
2326
2382
|
import {
|
|
2327
2383
|
POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI3,
|
|
2328
2384
|
issuerRegistryGetIssuerFlatAbi,
|
|
2329
|
-
getContractAddresses as
|
|
2385
|
+
getContractAddresses as getContractAddresses3
|
|
2330
2386
|
} from "@pafi-dev/core";
|
|
2331
2387
|
|
|
2332
2388
|
// src/issuer-state/types.ts
|
|
@@ -2358,7 +2414,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
2358
2414
|
* `CONTRACT_ADDRESSES` map for the given chain.
|
|
2359
2415
|
*/
|
|
2360
2416
|
static forChain(provider, chainId) {
|
|
2361
|
-
const { issuerRegistry } =
|
|
2417
|
+
const { issuerRegistry } = getContractAddresses3(chainId);
|
|
2362
2418
|
return new _IssuerStateValidator(provider, issuerRegistry);
|
|
2363
2419
|
}
|
|
2364
2420
|
/**
|