@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/README.md
CHANGED
|
@@ -17,10 +17,10 @@ ledger, policy engine, EIP-712 issuer signing, relay submission, and mint/burn e
|
|
|
17
17
|
- TypeScript >= 5.0
|
|
18
18
|
- `viem` ^2.0.0 and `@pafi-dev/core` ^0.5.16 (peer dependencies)
|
|
19
19
|
|
|
20
|
-
> **Latest:** `0.5.
|
|
21
|
-
>
|
|
22
|
-
>
|
|
23
|
-
>
|
|
20
|
+
> **Latest:** `0.5.31` — `RelayService.prepareMint` / `prepareBurn`
|
|
21
|
+
> now auto-quote the operator fee and auto-resolve the PAFI fee
|
|
22
|
+
> recipient. Drop `feeAmount` / `feeRecipient` from your call sites;
|
|
23
|
+
> SDK reads gas price + Chainlink + V4 subgraph internally. See
|
|
24
24
|
> [Changelog](#changelog).
|
|
25
25
|
|
|
26
26
|
---
|
|
@@ -386,6 +386,43 @@ try {
|
|
|
386
386
|
|
|
387
387
|
## Changelog
|
|
388
388
|
|
|
389
|
+
### 0.5.31
|
|
390
|
+
|
|
391
|
+
`RelayService.prepareMint` / `prepareBurn` now auto-quote the operator
|
|
392
|
+
fee + auto-resolve the PAFI fee recipient when the service is
|
|
393
|
+
constructed with `provider + chainId`. `createIssuerService` wires
|
|
394
|
+
this automatically — issuer integrations don't need to change
|
|
395
|
+
anything to pick it up.
|
|
396
|
+
|
|
397
|
+
**API changes** (additive, backwards-compatible):
|
|
398
|
+
|
|
399
|
+
- `RelayService` constructor accepts an optional `RelayServiceConfig`
|
|
400
|
+
with `provider` + `chainId`. When set, callers can drop `feeAmount`
|
|
401
|
+
/ `feeRecipient` from `prepareMint` / `prepareBurn` calls — the
|
|
402
|
+
service runs `quoteOperatorFeePt` (Chainlink ETH/USD + V4 subgraph
|
|
403
|
+
PT/USDT spot price) internally and pulls the canonical recipient
|
|
404
|
+
from `getContractAddresses(chainId).pafiFeeRecipient`.
|
|
405
|
+
- `prepareBurn` is now `async` (was sync) — the auto-quote requires
|
|
406
|
+
RPC + subgraph reads. Callers must `await`. `PTRedeemHandler`
|
|
407
|
+
already does this.
|
|
408
|
+
- `feeAmount: 0n` explicit means "no fee transfer" (force unsponsored
|
|
409
|
+
fallback variant). `undefined` means "auto-quote".
|
|
410
|
+
- Existing callers that pass `feeAmount + feeRecipient` keep working
|
|
411
|
+
— those values override the auto-resolve.
|
|
412
|
+
|
|
413
|
+
**Migration**: in your controller, drop the manual fee fetch when
|
|
414
|
+
calling `relayService.prepareMint`:
|
|
415
|
+
|
|
416
|
+
```diff
|
|
417
|
+
- const { pafiFeeRecipient: feeRecipient } = getContractAddresses(chainId);
|
|
418
|
+
- const feeAmount = await issuerService.fee.estimateGasFee();
|
|
419
|
+
const userOp = await relayService.prepareMint({
|
|
420
|
+
...,
|
|
421
|
+
- feeAmount,
|
|
422
|
+
- feeRecipient,
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
389
426
|
### 0.5.28
|
|
390
427
|
|
|
391
428
|
`PafiBackendClient.getUserOpReceipt(userOpHash)` added.
|
package/dist/index.cjs
CHANGED
|
@@ -438,6 +438,43 @@ var RelayError = class extends Error {
|
|
|
438
438
|
var import_viem3 = require("viem");
|
|
439
439
|
var import_core2 = require("@pafi-dev/core");
|
|
440
440
|
var RelayService = class {
|
|
441
|
+
provider;
|
|
442
|
+
chainId;
|
|
443
|
+
constructor(config = {}) {
|
|
444
|
+
this.provider = config.provider;
|
|
445
|
+
this.chainId = config.chainId;
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Resolve the fee recipient + amount applied to the next UserOp:
|
|
449
|
+
*
|
|
450
|
+
* - If caller passed an explicit `feeRecipient`, use it (testing
|
|
451
|
+
* only — sponsor-relayer's L1 will reject any non-canonical
|
|
452
|
+
* recipient with `INSUFFICIENT_FEE`). Otherwise, default to
|
|
453
|
+
* `getContractAddresses(chainId).pafiFeeRecipient` when the
|
|
454
|
+
* service has a `chainId` configured.
|
|
455
|
+
* - If caller passed `feeAmount`, use it. Otherwise, when the
|
|
456
|
+
* service has both `provider` + `chainId`, auto-quote via
|
|
457
|
+
* `quoteOperatorFeePt`.
|
|
458
|
+
* - When the service is unconfigured AND caller passed nothing,
|
|
459
|
+
* return `{ feeAmount: 0n, feeRecipient: undefined }` — legacy
|
|
460
|
+
* "no fee" behavior, caller must opt in for the gas-reimbursement
|
|
461
|
+
* transfer to be added to the batch.
|
|
462
|
+
*/
|
|
463
|
+
async resolveFee(params) {
|
|
464
|
+
const feeRecipient = params.feeRecipient ?? (this.chainId !== void 0 ? (0, import_core2.getContractAddresses)(this.chainId).pafiFeeRecipient : void 0);
|
|
465
|
+
if (params.feeAmount !== void 0) {
|
|
466
|
+
return { feeAmount: params.feeAmount, feeRecipient };
|
|
467
|
+
}
|
|
468
|
+
if (this.provider && this.chainId !== void 0) {
|
|
469
|
+
const feeAmount = await (0, import_core2.quoteOperatorFeePt)({
|
|
470
|
+
provider: this.provider,
|
|
471
|
+
chainId: this.chainId,
|
|
472
|
+
pointTokenAddress: params.pointTokenAddress
|
|
473
|
+
});
|
|
474
|
+
return { feeAmount, feeRecipient };
|
|
475
|
+
}
|
|
476
|
+
return { feeAmount: 0n, feeRecipient };
|
|
477
|
+
}
|
|
441
478
|
/**
|
|
442
479
|
* Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
|
|
443
480
|
* `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
@@ -522,14 +559,19 @@ var RelayService = class {
|
|
|
522
559
|
data: mintCallData
|
|
523
560
|
}
|
|
524
561
|
];
|
|
525
|
-
|
|
526
|
-
|
|
562
|
+
const { feeAmount, feeRecipient } = await this.resolveFee({
|
|
563
|
+
feeAmount: params.feeAmount,
|
|
564
|
+
feeRecipient: params.feeRecipient,
|
|
565
|
+
pointTokenAddress: params.pointTokenAddress
|
|
566
|
+
});
|
|
567
|
+
if (feeAmount > 0n) {
|
|
568
|
+
if (!feeRecipient) {
|
|
527
569
|
throw new RelayError(
|
|
528
570
|
"ENCODE_FAILED",
|
|
529
|
-
"prepareMint: feeRecipient
|
|
571
|
+
"prepareMint: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`."
|
|
530
572
|
);
|
|
531
573
|
}
|
|
532
|
-
if (
|
|
574
|
+
if (feeRecipient === "0x0000000000000000000000000000000000000000") {
|
|
533
575
|
throw new RelayError(
|
|
534
576
|
"ENCODE_FAILED",
|
|
535
577
|
"prepareMint: feeRecipient must not be zero address"
|
|
@@ -541,7 +583,7 @@ var RelayService = class {
|
|
|
541
583
|
data: (0, import_viem3.encodeFunctionData)({
|
|
542
584
|
abi: import_viem3.erc20Abi,
|
|
543
585
|
functionName: "transfer",
|
|
544
|
-
args: [
|
|
586
|
+
args: [feeRecipient, feeAmount]
|
|
545
587
|
})
|
|
546
588
|
});
|
|
547
589
|
}
|
|
@@ -567,7 +609,7 @@ var RelayService = class {
|
|
|
567
609
|
* burnerSig)`. Caller provides a pre-signed `BurnRequest` + sig
|
|
568
610
|
* bytes (typically from `PTRedeemHandler`).
|
|
569
611
|
*/
|
|
570
|
-
prepareBurn(params) {
|
|
612
|
+
async prepareBurn(params) {
|
|
571
613
|
if (!params.pointTokenAddress) {
|
|
572
614
|
throw new RelayError("ENCODE_FAILED", "prepareBurn: pointTokenAddress required");
|
|
573
615
|
}
|
|
@@ -608,14 +650,19 @@ var RelayService = class {
|
|
|
608
650
|
);
|
|
609
651
|
}
|
|
610
652
|
const operations = [];
|
|
611
|
-
|
|
612
|
-
|
|
653
|
+
const { feeAmount, feeRecipient } = await this.resolveFee({
|
|
654
|
+
feeAmount: params.feeAmount,
|
|
655
|
+
feeRecipient: params.feeRecipient,
|
|
656
|
+
pointTokenAddress: params.pointTokenAddress
|
|
657
|
+
});
|
|
658
|
+
if (feeAmount > 0n) {
|
|
659
|
+
if (!feeRecipient) {
|
|
613
660
|
throw new RelayError(
|
|
614
661
|
"ENCODE_FAILED",
|
|
615
|
-
"prepareBurn: feeRecipient
|
|
662
|
+
"prepareBurn: feeRecipient could not be resolved \u2014 pass `feeRecipient` explicitly or construct RelayService with a `chainId`."
|
|
616
663
|
);
|
|
617
664
|
}
|
|
618
|
-
if (
|
|
665
|
+
if (feeRecipient === "0x0000000000000000000000000000000000000000") {
|
|
619
666
|
throw new RelayError(
|
|
620
667
|
"ENCODE_FAILED",
|
|
621
668
|
"prepareBurn: feeRecipient must not be zero address"
|
|
@@ -627,7 +674,7 @@ var RelayService = class {
|
|
|
627
674
|
data: (0, import_viem3.encodeFunctionData)({
|
|
628
675
|
abi: import_viem3.erc20Abi,
|
|
629
676
|
functionName: "transfer",
|
|
630
|
-
args: [
|
|
677
|
+
args: [feeRecipient, feeAmount]
|
|
631
678
|
})
|
|
632
679
|
});
|
|
633
680
|
}
|
|
@@ -1461,7 +1508,7 @@ var PTRedeemHandler = class {
|
|
|
1461
1508
|
this.redeemLockDurationMs,
|
|
1462
1509
|
this.pointTokenAddress
|
|
1463
1510
|
);
|
|
1464
|
-
const sponsoredUserOp = this.relayService.prepareBurn({
|
|
1511
|
+
const sponsoredUserOp = await this.relayService.prepareBurn({
|
|
1465
1512
|
mode: "burnWithSig",
|
|
1466
1513
|
userAddress: request.userAddress,
|
|
1467
1514
|
aaNonce: request.aaNonce,
|
|
@@ -1495,15 +1542,19 @@ var PTRedeemHandler = class {
|
|
|
1495
1542
|
this.redeemLockDurationMs,
|
|
1496
1543
|
this.pointTokenAddress
|
|
1497
1544
|
);
|
|
1498
|
-
const fallbackUserOp = this.relayService.prepareBurn({
|
|
1545
|
+
const fallbackUserOp = await this.relayService.prepareBurn({
|
|
1499
1546
|
mode: "burnWithSig",
|
|
1500
1547
|
userAddress: request.userAddress,
|
|
1501
1548
|
aaNonce: request.aaNonce,
|
|
1502
1549
|
pointTokenAddress: this.pointTokenAddress,
|
|
1503
1550
|
batchExecutorAddress: this.batchExecutorAddress,
|
|
1504
1551
|
burnRequest: fallbackBurnRequest,
|
|
1505
|
-
burnerSignature: fallbackSig
|
|
1506
|
-
//
|
|
1552
|
+
burnerSignature: fallbackSig,
|
|
1553
|
+
// Explicit 0n — fallback is fee-free regardless of how
|
|
1554
|
+
// RelayService is configured. Without this, an
|
|
1555
|
+
// auto-quoting RelayService would try to quote a fee here
|
|
1556
|
+
// and re-add the PT.transfer we're trying to strip.
|
|
1557
|
+
feeAmount: 0n
|
|
1507
1558
|
});
|
|
1508
1559
|
fallback = {
|
|
1509
1560
|
lockId: fallbackLockId,
|
|
@@ -2239,7 +2290,10 @@ function createIssuerService(config) {
|
|
|
2239
2290
|
authServiceConfig.jwtExpiresIn = config.auth.jwtExpiresIn;
|
|
2240
2291
|
}
|
|
2241
2292
|
const authService = new AuthService(authServiceConfig);
|
|
2242
|
-
const relayService = new RelayService(
|
|
2293
|
+
const relayService = new RelayService({
|
|
2294
|
+
provider: config.provider,
|
|
2295
|
+
chainId: config.chainId
|
|
2296
|
+
});
|
|
2243
2297
|
let feeManager;
|
|
2244
2298
|
if (config.fee) {
|
|
2245
2299
|
feeManager = new FeeManager({
|