@pafi-dev/issuer 0.5.15 → 0.5.17

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 CHANGED
@@ -607,13 +607,7 @@ var RelayService = class {
607
607
  err
608
608
  );
609
609
  }
610
- const operations = [
611
- {
612
- target: params.pointTokenAddress,
613
- value: 0n,
614
- data: burnCallData
615
- }
616
- ];
610
+ const operations = [];
617
611
  if (params.feeAmount && params.feeAmount > 0n) {
618
612
  if (!params.feeRecipient) {
619
613
  throw new RelayError(
@@ -637,6 +631,11 @@ var RelayService = class {
637
631
  })
638
632
  });
639
633
  }
634
+ operations.push({
635
+ target: params.pointTokenAddress,
636
+ value: 0n,
637
+ data: burnCallData
638
+ });
640
639
  return (0, import_core2.buildPartialUserOperation)({
641
640
  sender: params.userAddress,
642
641
  nonce: params.aaNonce,
@@ -1414,16 +1413,22 @@ var PTRedeemHandler = class {
1414
1413
  }
1415
1414
  }
1416
1415
  async _handleAfterNonceLock(request, burnNonce) {
1416
+ const fee = request.feeAmount && request.feeAmount > 0n ? request.feeAmount : 0n;
1417
+ if (fee > 0n && fee >= request.amount) {
1418
+ throw new PTRedeemError(
1419
+ "INVALID_AMOUNT",
1420
+ `fee (${fee}) must be strictly less than redeem amount (${request.amount})`
1421
+ );
1422
+ }
1417
1423
  const onChainBalance = await (0, import_core4.getPointTokenBalance)(
1418
1424
  this.provider,
1419
1425
  this.pointTokenAddress,
1420
1426
  request.userAddress
1421
1427
  );
1422
- const totalRequired = request.amount + (request.feeAmount && request.feeAmount > 0n ? request.feeAmount : 0n);
1423
- if (onChainBalance < totalRequired) {
1428
+ if (onChainBalance < request.amount) {
1424
1429
  throw new PTRedeemError(
1425
1430
  "INVALID_AMOUNT",
1426
- `insufficient on-chain PT balance: have ${onChainBalance}, need ${totalRequired}` + (request.feeAmount && request.feeAmount > 0n ? ` (${request.amount} burn + ${request.feeAmount} fee)` : "")
1431
+ `insufficient on-chain PT balance: have ${onChainBalance}, need ${request.amount}`
1427
1432
  );
1428
1433
  }
1429
1434
  const deadline = BigInt(
@@ -1434,46 +1439,83 @@ var PTRedeemHandler = class {
1434
1439
  chainId: this.chainId,
1435
1440
  verifyingContract: this.domain.verifyingContract ?? this.pointTokenAddress
1436
1441
  };
1437
- const burnRequest = {
1442
+ const sponsoredBurnAmount = request.amount - fee;
1443
+ const sponsoredBurnRequest = {
1438
1444
  from: request.userAddress,
1439
- amount: request.amount,
1445
+ amount: sponsoredBurnAmount,
1440
1446
  nonce: burnNonce,
1441
1447
  deadline
1442
1448
  };
1443
- let burnerSignature;
1449
+ let sponsoredSig;
1444
1450
  try {
1445
- const sig = await (0, import_core4.signBurnRequest)(
1446
- this.burnerSignerWallet,
1447
- domain,
1448
- burnRequest
1449
- );
1450
- burnerSignature = sig.serialized;
1451
+ sponsoredSig = (await (0, import_core4.signBurnRequest)(this.burnerSignerWallet, domain, sponsoredBurnRequest)).serialized;
1451
1452
  } catch (err) {
1452
1453
  throw new PTRedeemError(
1453
1454
  "SIGNING_FAILED",
1454
- `failed to sign BurnRequest: ${err instanceof Error ? err.message : String(err)}`
1455
+ `failed to sign sponsored BurnRequest: ${err instanceof Error ? err.message : String(err)}`
1455
1456
  );
1456
1457
  }
1457
- const lockId = await this.ledger.reservePendingCredit(
1458
+ const sponsoredLockId = await this.ledger.reservePendingCredit(
1458
1459
  request.userAddress,
1459
- request.amount,
1460
+ sponsoredBurnAmount,
1460
1461
  this.redeemLockDurationMs,
1461
1462
  this.pointTokenAddress
1462
1463
  );
1463
- const userOp = this.relayService.prepareBurn({
1464
+ const sponsoredUserOp = this.relayService.prepareBurn({
1464
1465
  mode: "burnWithSig",
1465
1466
  userAddress: request.userAddress,
1466
1467
  aaNonce: request.aaNonce,
1467
1468
  pointTokenAddress: this.pointTokenAddress,
1468
1469
  batchExecutorAddress: this.batchExecutorAddress,
1469
- burnRequest,
1470
- burnerSignature,
1471
- feeAmount: request.feeAmount,
1470
+ burnRequest: sponsoredBurnRequest,
1471
+ burnerSignature: sponsoredSig,
1472
+ feeAmount: fee,
1472
1473
  feeRecipient: request.feeRecipient
1473
1474
  });
1475
+ let fallback = void 0;
1476
+ if (fee > 0n) {
1477
+ const fallbackBurnRequest = {
1478
+ from: request.userAddress,
1479
+ amount: request.amount,
1480
+ nonce: burnNonce,
1481
+ deadline
1482
+ };
1483
+ let fallbackSig;
1484
+ try {
1485
+ fallbackSig = (await (0, import_core4.signBurnRequest)(this.burnerSignerWallet, domain, fallbackBurnRequest)).serialized;
1486
+ } catch (err) {
1487
+ throw new PTRedeemError(
1488
+ "SIGNING_FAILED",
1489
+ `failed to sign fallback BurnRequest: ${err instanceof Error ? err.message : String(err)}`
1490
+ );
1491
+ }
1492
+ const fallbackLockId = await this.ledger.reservePendingCredit(
1493
+ request.userAddress,
1494
+ request.amount,
1495
+ this.redeemLockDurationMs,
1496
+ this.pointTokenAddress
1497
+ );
1498
+ const fallbackUserOp = this.relayService.prepareBurn({
1499
+ mode: "burnWithSig",
1500
+ userAddress: request.userAddress,
1501
+ aaNonce: request.aaNonce,
1502
+ pointTokenAddress: this.pointTokenAddress,
1503
+ batchExecutorAddress: this.batchExecutorAddress,
1504
+ burnRequest: fallbackBurnRequest,
1505
+ burnerSignature: fallbackSig
1506
+ // No feeAmount/feeRecipient — fallback is fee-free.
1507
+ });
1508
+ fallback = {
1509
+ lockId: fallbackLockId,
1510
+ userOp: fallbackUserOp,
1511
+ netCreditAmount: request.amount
1512
+ };
1513
+ }
1474
1514
  return {
1475
- lockId,
1476
- userOp,
1515
+ lockId: sponsoredLockId,
1516
+ userOp: sponsoredUserOp,
1517
+ netCreditAmount: sponsoredBurnAmount,
1518
+ fallback,
1477
1519
  expiresInSeconds: Math.floor(this.redeemLockDurationMs / 1e3),
1478
1520
  signatureDeadline: deadline
1479
1521
  };