@pafi-dev/issuer 0.3.0-beta.3 → 0.3.0-beta.4
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 +118 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +116 -98
- package/dist/index.d.ts +116 -98
- package/dist/index.js +121 -117
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Address, Hex, PublicClient, Chain } from 'viem';
|
|
2
|
-
import { PointTokenDomainConfig, MintRequest, EIP712Signature, MintParams, SwapParams, PartialUserOperation,
|
|
1
|
+
import { Address, Hex, PublicClient, Chain, WalletClient } from 'viem';
|
|
2
|
+
import { PointTokenDomainConfig, MintRequest, EIP712Signature, MintParams, SwapParams, PartialUserOperation, BurnRequest, ReceiverConsent, PathKey, PoolKey, SponsorshipScenario } from '@pafi-dev/core';
|
|
3
3
|
export { encodeExtData } from '@pafi-dev/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -523,14 +523,18 @@ interface RelayServiceConfig {
|
|
|
523
523
|
simulateBeforeSubmit?: boolean;
|
|
524
524
|
}
|
|
525
525
|
/**
|
|
526
|
-
* Submits `mintAndSwap` transactions to the Relay contract
|
|
527
|
-
*
|
|
528
|
-
* MintingGateway calls into `submitMintAndSwap()` after it has signed the
|
|
529
|
-
* MintRequest and verified the ReceiverConsent.
|
|
526
|
+
* Submits `mintAndSwap` transactions to the Relay contract (legacy
|
|
527
|
+
* v0.2 path) and builds unsigned UserOps for the v1.4 sponsored flow.
|
|
530
528
|
*
|
|
531
|
-
*
|
|
532
|
-
*
|
|
533
|
-
*
|
|
529
|
+
* v1.4 flow (post-Relayer-removal):
|
|
530
|
+
* - `prepareMint` — signs `MintRequest` with the issuer signer and
|
|
531
|
+
* encodes `PointToken.mint(to, amount, deadline, minterSig)` into
|
|
532
|
+
* a UserOp the user submits via EIP-7702 + Paymaster.
|
|
533
|
+
* - `prepareBurn` — mirrors on the burn side using `BurnRequest` +
|
|
534
|
+
* `PointToken.burn(from, amount, deadline, burnerSig)`.
|
|
535
|
+
*
|
|
536
|
+
* Legacy v0.2 `submitMintAndSwap` still broadcasts via operator wallet
|
|
537
|
+
* for the deprecated `/claim-and-swap` endpoint.
|
|
534
538
|
*/
|
|
535
539
|
declare class RelayService {
|
|
536
540
|
private readonly relayAddress;
|
|
@@ -548,76 +552,51 @@ declare class RelayService {
|
|
|
548
552
|
*/
|
|
549
553
|
encodeCall(params: SubmitMintAndSwapParams): Hex;
|
|
550
554
|
/**
|
|
551
|
-
* Submit a `mintAndSwap` transaction.
|
|
552
|
-
*
|
|
553
|
-
* 1. (optional) pre-flight simulate via provider
|
|
554
|
-
* 2. writeContract through the operator wallet
|
|
555
|
-
* 3. (optional) wait for the receipt and surface gasUsed / status
|
|
556
|
-
*
|
|
557
|
-
* Throws a typed `RelayError` on any failure so the MintingGateway can
|
|
558
|
-
* decide whether to release the ledger lock (`SUBMIT_FAILED` and
|
|
559
|
-
* `SIMULATION_FAILED` are safe to release; `TX_REVERTED` and `TIMEOUT`
|
|
560
|
-
* need manual review because the tx may still land).
|
|
555
|
+
* Submit a `mintAndSwap` transaction (legacy v0.2 `/claim-and-swap`).
|
|
561
556
|
*
|
|
562
|
-
* @deprecated Since 0.3.0 —
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
* can ship (blocker B1). Kept for v0.2.x consumers. Removed in 2.0.
|
|
557
|
+
* @deprecated Since 0.3.0 — replaced by `prepareMint` / `prepareBurn`
|
|
558
|
+
* in the v1.4 sponsored-UserOp flow. Kept for v0.2.x consumers;
|
|
559
|
+
* scheduled removal in 2.0.
|
|
566
560
|
*/
|
|
567
561
|
submitMintAndSwap(params: SubmitMintAndSwapParams): Promise<RelayResult>;
|
|
568
562
|
/**
|
|
569
|
-
* Build an unsigned UserOp for Scenario 1 (Mint)
|
|
563
|
+
* Build an unsigned UserOp for Scenario 1 (Mint) — sig-gated
|
|
564
|
+
* `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
570
565
|
*
|
|
571
566
|
* Flow:
|
|
572
|
-
* 1.
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*/
|
|
582
|
-
|
|
583
|
-
* Build an unsigned UserOp for Scenario 1 (Mint) — direct
|
|
584
|
-
* `PointToken.mint(amount)` flow (v1.4 post-Relayer-removal).
|
|
585
|
-
*
|
|
586
|
-
* `msg.sender` inside the batch = user EOA via EIP-7702 delegation.
|
|
587
|
-
* `PointToken.mint` checks the caller is on its `minters` allowlist
|
|
588
|
-
* (gg56 BE pre-validates this off-chain to avoid wasted gas).
|
|
589
|
-
*
|
|
590
|
-
* Optional PT fee transfer is appended after the mint when
|
|
591
|
-
* `feeAmount > 0` — this is application-level fee recovery (no
|
|
592
|
-
* Relayer doing it for us). The user must end up with `amount - fee`
|
|
593
|
-
* net PT after the batch executes.
|
|
594
|
-
*/
|
|
595
|
-
prepareMint(params: PrepareMintParams): PartialUserOperation;
|
|
567
|
+
* 1. Issuer backend signs `MintRequest(to=user, amount, nonce, deadline)`
|
|
568
|
+
* with its minter signer (HSM/KMS) → `minterSig`.
|
|
569
|
+
* 2. Encode `PointToken.mint(user, amount, deadline, minterSig)`.
|
|
570
|
+
* On-chain, `msg.sender` must equal `to` — satisfied by EIP-7702
|
|
571
|
+
* delegating the user EOA to BatchExecutor.
|
|
572
|
+
* 3. Optional PT fee transfer appended after mint (application-level
|
|
573
|
+
* fee recovery since Relayer v2 no longer exists).
|
|
574
|
+
* 4. Return `PartialUserOperation` ready for Bundler gas estimate +
|
|
575
|
+
* Paymaster sponsorship + user signature.
|
|
576
|
+
*/
|
|
577
|
+
prepareMint(params: PrepareMintParams): Promise<PartialUserOperation>;
|
|
596
578
|
/**
|
|
597
579
|
* Build an unsigned UserOp for Scenario 2 (Burn/Redeem).
|
|
598
580
|
*
|
|
599
581
|
* Two modes:
|
|
600
|
-
* - `mode: 'burn'` — direct `PointToken.burn(amount)`;
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
582
|
+
* - `mode: 'burn'` — direct `PointToken.burn(from, amount)`; only
|
|
583
|
+
* usable if the user is a whitelisted burner. Not the typical
|
|
584
|
+
* v1.4 path (users aren't burners); kept for admin/operator tools.
|
|
585
|
+
* - `mode: 'burnWithSig'` — `PointToken.burn(from, amount, deadline,
|
|
586
|
+
* burnerSig)`. Issuer signs `BurnRequest` off-chain; user submits
|
|
587
|
+
* via EIP-7702. `msg.sender == from` enforced on-chain. This is
|
|
588
|
+
* the user-initiated redeem path in v1.4.
|
|
607
589
|
*/
|
|
608
590
|
prepareBurn(params: PrepareBurnParams): PartialUserOperation;
|
|
609
591
|
}
|
|
610
592
|
/**
|
|
611
|
-
* v1.4 —
|
|
593
|
+
* v1.4 — sig-gated `PointToken.mint(to, amount, deadline, minterSig)`.
|
|
612
594
|
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
* Then locks the off-chain balance and returns this UserOp for the FE
|
|
619
|
-
* to sponsor + submit. On confirmation, PointIndexer watches the
|
|
620
|
-
* `Transfer(0x0, user, amount)` event and resolves the lock.
|
|
595
|
+
* The issuer backend validates off-chain (balance, policy, KYC), signs
|
|
596
|
+
* a `MintRequest` EIP-712 with its minter signer, and packages the
|
|
597
|
+
* whole thing into a UserOp for the user to submit via EIP-7702 +
|
|
598
|
+
* Paymaster. On confirmation, PointIndexer watches `Transfer(0x0, user,
|
|
599
|
+
* amount)` and resolves the ledger lock.
|
|
621
600
|
*/
|
|
622
601
|
interface PrepareMintParams {
|
|
623
602
|
/** User EOA that will send the UserOp (via EIP-7702 delegation). */
|
|
@@ -626,14 +605,25 @@ interface PrepareMintParams {
|
|
|
626
605
|
aaNonce: bigint;
|
|
627
606
|
/** BatchExecutor delegation target (chain-specific). */
|
|
628
607
|
batchExecutorAddress: Address;
|
|
629
|
-
/** PointToken contract — the call target. */
|
|
608
|
+
/** PointToken contract — the call target + EIP-712 verifying contract. */
|
|
630
609
|
pointTokenAddress: Address;
|
|
631
|
-
/** PT amount to mint to `userAddress
|
|
610
|
+
/** PT amount to mint to `userAddress`. */
|
|
632
611
|
amount: bigint;
|
|
612
|
+
/**
|
|
613
|
+
* Issuer minter signer wallet — signs the `MintRequest` EIP-712.
|
|
614
|
+
* Must be added to `PointToken.minters[]` via `addMinter(signerAddr)`
|
|
615
|
+
* at provisioning time. Typically HSM/KMS-backed in prod.
|
|
616
|
+
*/
|
|
617
|
+
issuerSignerWallet: WalletClient;
|
|
618
|
+
/** EIP-712 domain for MintRequest (name + chainId + verifyingContract). */
|
|
619
|
+
domain: PointTokenDomainConfig;
|
|
620
|
+
/** Current `mintRequestNonces[userAddress]` — caller reads from contract. */
|
|
621
|
+
mintRequestNonce: bigint;
|
|
622
|
+
/** Unix timestamp after which the signature expires. */
|
|
623
|
+
deadline: bigint;
|
|
633
624
|
/**
|
|
634
625
|
* Optional — application-level fee transfer appended after mint.
|
|
635
|
-
* Set both `feeAmount` and `feeRecipient` together.
|
|
636
|
-
* `feeAmount` is undefined or 0.
|
|
626
|
+
* Set both `feeAmount` and `feeRecipient` together.
|
|
637
627
|
*/
|
|
638
628
|
feeAmount?: bigint;
|
|
639
629
|
feeRecipient?: Address;
|
|
@@ -658,8 +648,10 @@ interface PrepareBurnDirectParams extends PrepareBurnCommonParams {
|
|
|
658
648
|
}
|
|
659
649
|
interface PrepareBurnWithSigParams extends PrepareBurnCommonParams {
|
|
660
650
|
mode: "burnWithSig";
|
|
661
|
-
|
|
662
|
-
|
|
651
|
+
/** BurnRequest message the issuer burner signer signed. */
|
|
652
|
+
burnRequest: BurnRequest;
|
|
653
|
+
/** Serialized EIP-712 signature (bytes) over `burnRequest`. */
|
|
654
|
+
burnerSignature: Hex;
|
|
663
655
|
}
|
|
664
656
|
|
|
665
657
|
interface FeeManagerConfig {
|
|
@@ -1356,17 +1348,29 @@ declare class IssuerApiHandlers {
|
|
|
1356
1348
|
}
|
|
1357
1349
|
|
|
1358
1350
|
/**
|
|
1359
|
-
* v1.4 reverse flow —
|
|
1351
|
+
* v1.4 reverse flow — user-initiated PT redeem.
|
|
1352
|
+
*
|
|
1353
|
+
* User has on-chain PT, wants to convert back to off-chain points. The
|
|
1354
|
+
* issuer backend signs a `BurnRequest` with its burner signer, reserves
|
|
1355
|
+
* an off-chain pending credit, and returns an unsigned UserOp. The FE
|
|
1356
|
+
* submits the UserOp via EIP-7702 + Coinbase Paymaster. On confirmation,
|
|
1357
|
+
* `Transfer(user → 0x0)` is emitted; `BurnIndexer` resolves the pending
|
|
1358
|
+
* credit to a real off-chain credit.
|
|
1360
1359
|
*
|
|
1361
|
-
*
|
|
1362
|
-
* sign a `BurnConsent`, the issuer backend verifies it, reserves an
|
|
1363
|
-
* off-chain credit, and returns an unsigned UserOp that the frontend
|
|
1364
|
-
* submits via the Bundler. When the burn lands, the `BurnIndexer`
|
|
1365
|
-
* (elsewhere) resolves the credit.
|
|
1360
|
+
* Contract path (mock ABI — matches deployed PointToken):
|
|
1366
1361
|
*
|
|
1367
|
-
*
|
|
1368
|
-
*
|
|
1369
|
-
*
|
|
1362
|
+
* burn(address from, uint256 amount, uint256 deadline, bytes burnerSig)
|
|
1363
|
+
*
|
|
1364
|
+
* On-chain checks:
|
|
1365
|
+
* - msg.sender == from (enforced via EIP-7702 delegation on user EOA)
|
|
1366
|
+
* - burnerSig signer ∈ burners[]
|
|
1367
|
+
* - nonce == burnRequestNonces[from]
|
|
1368
|
+
* - now <= deadline
|
|
1369
|
+
*
|
|
1370
|
+
* The user never signs an EIP-712 message in this flow. Their only
|
|
1371
|
+
* signature is the ERC-4337 UserOp signature, which the AA wallet
|
|
1372
|
+
* handles. Consent is implicit: by submitting the UserOp they authorize
|
|
1373
|
+
* the burn.
|
|
1370
1374
|
*/
|
|
1371
1375
|
interface PTRedeemHandlerConfig {
|
|
1372
1376
|
ledger: IPointLedger;
|
|
@@ -1376,32 +1380,41 @@ interface PTRedeemHandlerConfig {
|
|
|
1376
1380
|
pointTokenAddress: Address;
|
|
1377
1381
|
/** BatchExecutor delegation target (chain-specific). */
|
|
1378
1382
|
batchExecutorAddress: Address;
|
|
1379
|
-
/** Chain id — used for
|
|
1383
|
+
/** Chain id — used for the BurnRequest EIP-712 domain. */
|
|
1380
1384
|
chainId: number;
|
|
1381
1385
|
/**
|
|
1382
1386
|
* EIP-712 domain fields. Must match the on-chain PointToken's domain
|
|
1383
|
-
* separator
|
|
1384
|
-
* typically the PointToken's ERC-20 name
|
|
1385
|
-
*
|
|
1387
|
+
* separator, or on-chain signature recovery fails. `name` is
|
|
1388
|
+
* typically the PointToken's ERC-20 name. `verifyingContract`
|
|
1389
|
+
* defaults to `pointTokenAddress`.
|
|
1386
1390
|
*/
|
|
1387
1391
|
domain: {
|
|
1388
1392
|
name: string;
|
|
1389
1393
|
verifyingContract?: Address;
|
|
1390
1394
|
};
|
|
1395
|
+
/**
|
|
1396
|
+
* Issuer burner signer wallet — signs the `BurnRequest` EIP-712.
|
|
1397
|
+
* Must be whitelisted via `PointToken.addBurner(signerAddr)` at
|
|
1398
|
+
* provisioning time. Typically HSM/KMS-backed in prod.
|
|
1399
|
+
*/
|
|
1400
|
+
burnerSignerWallet: WalletClient;
|
|
1391
1401
|
/**
|
|
1392
1402
|
* How long the pending credit stays reserved if the burn never lands.
|
|
1393
1403
|
* Default: 15 min — long enough for a bundler submission + confirmation.
|
|
1394
1404
|
*/
|
|
1395
1405
|
redeemLockDurationMs?: number;
|
|
1406
|
+
/**
|
|
1407
|
+
* How far ahead of `now` to set the BurnRequest deadline. Default:
|
|
1408
|
+
* 15 min. Must be long enough for Bundler + EntryPoint to execute;
|
|
1409
|
+
* short enough to prevent replay if the UserOp is abandoned.
|
|
1410
|
+
*/
|
|
1411
|
+
signatureDeadlineSeconds?: number;
|
|
1396
1412
|
/** Clock injection for tests; defaults to `Date.now`. */
|
|
1397
1413
|
now?: () => number;
|
|
1398
1414
|
}
|
|
1399
1415
|
interface PTRedeemRequest {
|
|
1400
1416
|
userAddress: Address;
|
|
1401
1417
|
amount: bigint;
|
|
1402
|
-
/** Serialized EIP-712 signature over the BurnConsent. */
|
|
1403
|
-
consentSignature: Hex;
|
|
1404
|
-
consent: BurnConsent;
|
|
1405
1418
|
/** ERC-4337 account nonce for the user's EOA. */
|
|
1406
1419
|
aaNonce: bigint;
|
|
1407
1420
|
}
|
|
@@ -1412,19 +1425,24 @@ interface PTRedeemResponse {
|
|
|
1412
1425
|
userOp: PartialUserOperation;
|
|
1413
1426
|
/** Seconds until the lock expires if the burn doesn't land. */
|
|
1414
1427
|
expiresInSeconds: number;
|
|
1428
|
+
/** The BurnRequest deadline (unix seconds) — FE uses this to surface a countdown. */
|
|
1429
|
+
signatureDeadline: bigint;
|
|
1415
1430
|
}
|
|
1416
1431
|
declare class PTRedeemError extends Error {
|
|
1417
|
-
code: "
|
|
1418
|
-
constructor(code: "
|
|
1432
|
+
code: "INVALID_AMOUNT" | "NONCE_READ_FAILED" | "LEDGER_NOT_SUPPORTED" | "SIGNING_FAILED";
|
|
1433
|
+
constructor(code: "INVALID_AMOUNT" | "NONCE_READ_FAILED" | "LEDGER_NOT_SUPPORTED" | "SIGNING_FAILED", message: string);
|
|
1419
1434
|
}
|
|
1420
1435
|
declare class PTRedeemHandler {
|
|
1421
1436
|
private readonly ledger;
|
|
1422
1437
|
private readonly relayService;
|
|
1438
|
+
private readonly provider;
|
|
1423
1439
|
private readonly pointTokenAddress;
|
|
1424
1440
|
private readonly batchExecutorAddress;
|
|
1425
1441
|
private readonly chainId;
|
|
1426
1442
|
private readonly domain;
|
|
1443
|
+
private readonly burnerSignerWallet;
|
|
1427
1444
|
private readonly redeemLockDurationMs;
|
|
1445
|
+
private readonly signatureDeadlineSeconds;
|
|
1428
1446
|
private readonly now;
|
|
1429
1447
|
constructor(config: PTRedeemHandlerConfig);
|
|
1430
1448
|
handle(request: PTRedeemRequest): Promise<PTRedeemResponse>;
|
|
@@ -1445,8 +1463,12 @@ declare class PTRedeemHandler {
|
|
|
1445
1463
|
* → burn 200 PT, credit 200 off-chain, voucher proceeds with 500
|
|
1446
1464
|
*
|
|
1447
1465
|
* Delegates the actual burn construction to {@link PTRedeemHandler}
|
|
1448
|
-
* — this handler is pure business logic (
|
|
1449
|
-
*
|
|
1466
|
+
* — this handler is pure business logic (shortfall math + on-chain
|
|
1467
|
+
* balance check) on top.
|
|
1468
|
+
*
|
|
1469
|
+
* v1.4 note: user no longer pre-signs a `BurnConsent`. The issuer
|
|
1470
|
+
* backend signs a `BurnRequest` itself (see `PTRedeemHandler`), so
|
|
1471
|
+
* this handler only needs `userAddress + requiredAmount + aaNonce`.
|
|
1450
1472
|
*/
|
|
1451
1473
|
interface TopUpRedemptionHandlerConfig {
|
|
1452
1474
|
ledger: IPointLedger;
|
|
@@ -1459,12 +1481,8 @@ interface TopUpRedemptionRequest {
|
|
|
1459
1481
|
userAddress: Address;
|
|
1460
1482
|
/** Total points the voucher redemption requires off-chain. */
|
|
1461
1483
|
requiredAmount: bigint;
|
|
1462
|
-
/**
|
|
1463
|
-
|
|
1464
|
-
* with amount set to a worst-case upper bound. Handler inspects the
|
|
1465
|
-
* shortfall and uses the consent if the shortfall ≤ consent.amount.
|
|
1466
|
-
*/
|
|
1467
|
-
redeemRequest: Pick<PTRedeemRequest, "consent" | "consentSignature" | "aaNonce">;
|
|
1484
|
+
/** ERC-4337 account nonce for the user's EOA. */
|
|
1485
|
+
aaNonce: bigint;
|
|
1468
1486
|
}
|
|
1469
1487
|
type TopUpRedemptionResponse = {
|
|
1470
1488
|
action: "NO_TOP_UP_NEEDED";
|
|
@@ -1480,8 +1498,8 @@ type TopUpRedemptionResponse = {
|
|
|
1480
1498
|
redeem: PTRedeemResponse;
|
|
1481
1499
|
};
|
|
1482
1500
|
declare class TopUpRedemptionError extends Error {
|
|
1483
|
-
code: "INSUFFICIENT_ONCHAIN_BALANCE" | "
|
|
1484
|
-
constructor(code: "INSUFFICIENT_ONCHAIN_BALANCE" | "
|
|
1501
|
+
code: "INSUFFICIENT_ONCHAIN_BALANCE" | "LEDGER_NOT_SUPPORTED";
|
|
1502
|
+
constructor(code: "INSUFFICIENT_ONCHAIN_BALANCE" | "LEDGER_NOT_SUPPORTED", message: string);
|
|
1485
1503
|
}
|
|
1486
1504
|
declare class TopUpRedemptionHandler {
|
|
1487
1505
|
private readonly ledger;
|