@pafi-dev/issuer 0.11.0 → 0.12.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 +64 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +65 -2
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
package/dist/index.d.cts
CHANGED
|
@@ -1080,7 +1080,23 @@ interface ApiConfigResponse {
|
|
|
1080
1080
|
* a swap; the pool is only discoverable when the hook matches.
|
|
1081
1081
|
*/
|
|
1082
1082
|
pafiHook?: Address;
|
|
1083
|
+
/**
|
|
1084
|
+
* v1.6 — single global MintFeeWrapper that skims a fee on every
|
|
1085
|
+
* sig-gated mint and distributes across the configured recipients.
|
|
1086
|
+
*/
|
|
1087
|
+
mintFeeWrapper?: Address;
|
|
1083
1088
|
};
|
|
1089
|
+
/**
|
|
1090
|
+
* v1.6 — per-PointToken mint fee (in basis points, 0–10000) read from
|
|
1091
|
+
* `MintFeeWrapper.totalFeeBps(pointToken)`. Frontend uses this to show
|
|
1092
|
+
* "you'll receive X PT (Y% mint fee)" before user signs.
|
|
1093
|
+
*
|
|
1094
|
+
* Map keyed by lower-cased PointToken address (JSON-friendly) so the
|
|
1095
|
+
* FE can look up the fee without iterating. Omitted (or with zero
|
|
1096
|
+
* values) when the chain has no wrapper deployed or recipients are
|
|
1097
|
+
* not configured.
|
|
1098
|
+
*/
|
|
1099
|
+
mintFeeBpsByToken?: Record<string, number>;
|
|
1084
1100
|
/**
|
|
1085
1101
|
* Absolute URL that the Issuer App opens after a successful claim to
|
|
1086
1102
|
* let the user swap PT → USDT or deposit into the perp DEX on PAFI
|
|
@@ -1331,6 +1347,13 @@ interface IssuerApiHandlersConfig {
|
|
|
1331
1347
|
* See [MOBILE_SDK_INTEGRATION.md] "PAFI Web Handoff".
|
|
1332
1348
|
*/
|
|
1333
1349
|
pafiWebUrl?: string;
|
|
1350
|
+
/**
|
|
1351
|
+
* v1.6 — MintFeeWrapper address used to read per-PointToken fee
|
|
1352
|
+
* basis points for `/config`. When omitted, the response will not
|
|
1353
|
+
* include `mintFeeBpsByToken` and FE must assume zero fee. Wrapper
|
|
1354
|
+
* is shared across PointTokens; per-token recipients live inside it.
|
|
1355
|
+
*/
|
|
1356
|
+
mintFeeWrapperAddress?: Address;
|
|
1334
1357
|
/** Required by `handleGasFee`; omit to disable the endpoint. */
|
|
1335
1358
|
feeManager?: FeeManager;
|
|
1336
1359
|
/** Required by `handlePools`; omit to disable the endpoint. */
|
|
@@ -1376,6 +1399,14 @@ declare class IssuerApiHandlers {
|
|
|
1376
1399
|
private readonly poolsProvider?;
|
|
1377
1400
|
private readonly redemption?;
|
|
1378
1401
|
private readonly rateLimiter;
|
|
1402
|
+
private readonly mintFeeWrapperAddress?;
|
|
1403
|
+
/**
|
|
1404
|
+
* Per-token feeBps cache. Refreshed on /config when stale. feeBps
|
|
1405
|
+
* changes only when ops calls `wrapper.setRecipients`, so 5-min TTL
|
|
1406
|
+
* is more than safe for FE display purposes.
|
|
1407
|
+
*/
|
|
1408
|
+
private readonly feeBpsCache;
|
|
1409
|
+
private static readonly FEE_BPS_TTL_MS;
|
|
1379
1410
|
constructor(config: IssuerApiHandlersConfig);
|
|
1380
1411
|
/**
|
|
1381
1412
|
* `GET /auth/nonce`
|
|
@@ -1402,6 +1433,13 @@ declare class IssuerApiHandlers {
|
|
|
1402
1433
|
* needs to build EIP-712 messages and interact with on-chain.
|
|
1403
1434
|
*/
|
|
1404
1435
|
handleConfig(chainId: number): Promise<ApiConfigResponse>;
|
|
1436
|
+
/**
|
|
1437
|
+
* Read `totalFeeBps(pointToken)` for every supported PointToken from
|
|
1438
|
+
* the wrapper. Cached per-token for 5 minutes. Returns `undefined`
|
|
1439
|
+
* (caller drops the field) if every read fails — FE must treat
|
|
1440
|
+
* "field missing" as "fee unknown, do not display".
|
|
1441
|
+
*/
|
|
1442
|
+
private resolveFeeBpsByToken;
|
|
1405
1443
|
/** `GET /gas-fee` — quoted in USDT (6-decimal base units). */
|
|
1406
1444
|
handleGasFee(): Promise<ApiGasFeeResponse>;
|
|
1407
1445
|
/** `POST /auth/logout` */
|
package/dist/index.d.ts
CHANGED
|
@@ -1080,7 +1080,23 @@ interface ApiConfigResponse {
|
|
|
1080
1080
|
* a swap; the pool is only discoverable when the hook matches.
|
|
1081
1081
|
*/
|
|
1082
1082
|
pafiHook?: Address;
|
|
1083
|
+
/**
|
|
1084
|
+
* v1.6 — single global MintFeeWrapper that skims a fee on every
|
|
1085
|
+
* sig-gated mint and distributes across the configured recipients.
|
|
1086
|
+
*/
|
|
1087
|
+
mintFeeWrapper?: Address;
|
|
1083
1088
|
};
|
|
1089
|
+
/**
|
|
1090
|
+
* v1.6 — per-PointToken mint fee (in basis points, 0–10000) read from
|
|
1091
|
+
* `MintFeeWrapper.totalFeeBps(pointToken)`. Frontend uses this to show
|
|
1092
|
+
* "you'll receive X PT (Y% mint fee)" before user signs.
|
|
1093
|
+
*
|
|
1094
|
+
* Map keyed by lower-cased PointToken address (JSON-friendly) so the
|
|
1095
|
+
* FE can look up the fee without iterating. Omitted (or with zero
|
|
1096
|
+
* values) when the chain has no wrapper deployed or recipients are
|
|
1097
|
+
* not configured.
|
|
1098
|
+
*/
|
|
1099
|
+
mintFeeBpsByToken?: Record<string, number>;
|
|
1084
1100
|
/**
|
|
1085
1101
|
* Absolute URL that the Issuer App opens after a successful claim to
|
|
1086
1102
|
* let the user swap PT → USDT or deposit into the perp DEX on PAFI
|
|
@@ -1331,6 +1347,13 @@ interface IssuerApiHandlersConfig {
|
|
|
1331
1347
|
* See [MOBILE_SDK_INTEGRATION.md] "PAFI Web Handoff".
|
|
1332
1348
|
*/
|
|
1333
1349
|
pafiWebUrl?: string;
|
|
1350
|
+
/**
|
|
1351
|
+
* v1.6 — MintFeeWrapper address used to read per-PointToken fee
|
|
1352
|
+
* basis points for `/config`. When omitted, the response will not
|
|
1353
|
+
* include `mintFeeBpsByToken` and FE must assume zero fee. Wrapper
|
|
1354
|
+
* is shared across PointTokens; per-token recipients live inside it.
|
|
1355
|
+
*/
|
|
1356
|
+
mintFeeWrapperAddress?: Address;
|
|
1334
1357
|
/** Required by `handleGasFee`; omit to disable the endpoint. */
|
|
1335
1358
|
feeManager?: FeeManager;
|
|
1336
1359
|
/** Required by `handlePools`; omit to disable the endpoint. */
|
|
@@ -1376,6 +1399,14 @@ declare class IssuerApiHandlers {
|
|
|
1376
1399
|
private readonly poolsProvider?;
|
|
1377
1400
|
private readonly redemption?;
|
|
1378
1401
|
private readonly rateLimiter;
|
|
1402
|
+
private readonly mintFeeWrapperAddress?;
|
|
1403
|
+
/**
|
|
1404
|
+
* Per-token feeBps cache. Refreshed on /config when stale. feeBps
|
|
1405
|
+
* changes only when ops calls `wrapper.setRecipients`, so 5-min TTL
|
|
1406
|
+
* is more than safe for FE display purposes.
|
|
1407
|
+
*/
|
|
1408
|
+
private readonly feeBpsCache;
|
|
1409
|
+
private static readonly FEE_BPS_TTL_MS;
|
|
1379
1410
|
constructor(config: IssuerApiHandlersConfig);
|
|
1380
1411
|
/**
|
|
1381
1412
|
* `GET /auth/nonce`
|
|
@@ -1402,6 +1433,13 @@ declare class IssuerApiHandlers {
|
|
|
1402
1433
|
* needs to build EIP-712 messages and interact with on-chain.
|
|
1403
1434
|
*/
|
|
1404
1435
|
handleConfig(chainId: number): Promise<ApiConfigResponse>;
|
|
1436
|
+
/**
|
|
1437
|
+
* Read `totalFeeBps(pointToken)` for every supported PointToken from
|
|
1438
|
+
* the wrapper. Cached per-token for 5 minutes. Returns `undefined`
|
|
1439
|
+
* (caller drops the field) if every read fails — FE must treat
|
|
1440
|
+
* "field missing" as "fee unknown, do not display".
|
|
1441
|
+
*/
|
|
1442
|
+
private resolveFeeBpsByToken;
|
|
1405
1443
|
/** `GET /gas-fee` — quoted in USDT (6-decimal base units). */
|
|
1406
1444
|
handleGasFee(): Promise<ApiGasFeeResponse>;
|
|
1407
1445
|
/** `POST /auth/logout` */
|
package/dist/index.js
CHANGED
|
@@ -1340,12 +1340,13 @@ var BurnIndexer = class {
|
|
|
1340
1340
|
// src/api/handlers.ts
|
|
1341
1341
|
import { getAddress as getAddress5 } from "viem";
|
|
1342
1342
|
import {
|
|
1343
|
+
getMintFeeBps,
|
|
1343
1344
|
getMintRequestNonce,
|
|
1344
1345
|
getPointTokenBalance,
|
|
1345
1346
|
getReceiverConsentNonce,
|
|
1346
1347
|
isMinter
|
|
1347
1348
|
} from "@pafi-dev/core";
|
|
1348
|
-
var IssuerApiHandlers = class {
|
|
1349
|
+
var IssuerApiHandlers = class _IssuerApiHandlers {
|
|
1349
1350
|
authService;
|
|
1350
1351
|
ledger;
|
|
1351
1352
|
provider;
|
|
@@ -1361,6 +1362,14 @@ var IssuerApiHandlers = class {
|
|
|
1361
1362
|
poolsProvider;
|
|
1362
1363
|
redemption;
|
|
1363
1364
|
rateLimiter;
|
|
1365
|
+
mintFeeWrapperAddress;
|
|
1366
|
+
/**
|
|
1367
|
+
* Per-token feeBps cache. Refreshed on /config when stale. feeBps
|
|
1368
|
+
* changes only when ops calls `wrapper.setRecipients`, so 5-min TTL
|
|
1369
|
+
* is more than safe for FE display purposes.
|
|
1370
|
+
*/
|
|
1371
|
+
feeBpsCache = /* @__PURE__ */ new Map();
|
|
1372
|
+
static FEE_BPS_TTL_MS = 5 * 60 * 1e3;
|
|
1364
1373
|
constructor(config) {
|
|
1365
1374
|
this.authService = config.authService;
|
|
1366
1375
|
this.ledger = config.ledger;
|
|
@@ -1380,6 +1389,9 @@ var IssuerApiHandlers = class {
|
|
|
1380
1389
|
if (config.feeManager) this.feeManager = config.feeManager;
|
|
1381
1390
|
if (config.poolsProvider) this.poolsProvider = config.poolsProvider;
|
|
1382
1391
|
if (config.redemption) this.redemption = config.redemption;
|
|
1392
|
+
if (config.mintFeeWrapperAddress) {
|
|
1393
|
+
this.mintFeeWrapperAddress = getAddress5(config.mintFeeWrapperAddress);
|
|
1394
|
+
}
|
|
1383
1395
|
}
|
|
1384
1396
|
// =========================================================================
|
|
1385
1397
|
// Public handlers (no auth required)
|
|
@@ -1479,13 +1491,58 @@ var IssuerApiHandlers = class {
|
|
|
1479
1491
|
...this.contracts,
|
|
1480
1492
|
pointTokens: Array.from(this.supportedTokens)
|
|
1481
1493
|
};
|
|
1494
|
+
if (this.mintFeeWrapperAddress) {
|
|
1495
|
+
contracts.mintFeeWrapper = this.mintFeeWrapperAddress;
|
|
1496
|
+
}
|
|
1482
1497
|
const response = {
|
|
1483
1498
|
chainId: this.chainId,
|
|
1484
1499
|
contracts
|
|
1485
1500
|
};
|
|
1501
|
+
if (this.mintFeeWrapperAddress) {
|
|
1502
|
+
const byToken = await this.resolveFeeBpsByToken(
|
|
1503
|
+
this.mintFeeWrapperAddress
|
|
1504
|
+
);
|
|
1505
|
+
if (byToken) response.mintFeeBpsByToken = byToken;
|
|
1506
|
+
}
|
|
1486
1507
|
if (this.pafiWebUrl) response.pafiWebUrl = this.pafiWebUrl;
|
|
1487
1508
|
return response;
|
|
1488
1509
|
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Read `totalFeeBps(pointToken)` for every supported PointToken from
|
|
1512
|
+
* the wrapper. Cached per-token for 5 minutes. Returns `undefined`
|
|
1513
|
+
* (caller drops the field) if every read fails — FE must treat
|
|
1514
|
+
* "field missing" as "fee unknown, do not display".
|
|
1515
|
+
*/
|
|
1516
|
+
async resolveFeeBpsByToken(wrapper) {
|
|
1517
|
+
const now = Date.now();
|
|
1518
|
+
const out = {};
|
|
1519
|
+
let anyFresh = false;
|
|
1520
|
+
await Promise.all(
|
|
1521
|
+
Array.from(this.supportedTokens).map(async (token) => {
|
|
1522
|
+
const cached = this.feeBpsCache.get(token);
|
|
1523
|
+
if (cached && cached.expiresAt > now) {
|
|
1524
|
+
out[token.toLowerCase()] = cached.value;
|
|
1525
|
+
anyFresh = true;
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
try {
|
|
1529
|
+
const bps = await getMintFeeBps(this.provider, wrapper, token);
|
|
1530
|
+
this.feeBpsCache.set(token, {
|
|
1531
|
+
value: bps,
|
|
1532
|
+
expiresAt: now + _IssuerApiHandlers.FEE_BPS_TTL_MS
|
|
1533
|
+
});
|
|
1534
|
+
out[token.toLowerCase()] = bps;
|
|
1535
|
+
anyFresh = true;
|
|
1536
|
+
} catch {
|
|
1537
|
+
if (cached) {
|
|
1538
|
+
out[token.toLowerCase()] = cached.value;
|
|
1539
|
+
anyFresh = true;
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
})
|
|
1543
|
+
);
|
|
1544
|
+
return anyFresh ? out : void 0;
|
|
1545
|
+
}
|
|
1489
1546
|
/** `GET /gas-fee` — quoted in USDT (6-decimal base units). */
|
|
1490
1547
|
async handleGasFee() {
|
|
1491
1548
|
if (!this.feeManager) {
|
|
@@ -4231,6 +4288,9 @@ function createIssuerService(config) {
|
|
|
4231
4288
|
pafiHook: chainAddresses.pafiHook,
|
|
4232
4289
|
...config.contracts
|
|
4233
4290
|
};
|
|
4291
|
+
if (resolvedWrapperAddress !== void 0) {
|
|
4292
|
+
resolvedContracts.mintFeeWrapper = resolvedWrapperAddress;
|
|
4293
|
+
}
|
|
4234
4294
|
let redemption;
|
|
4235
4295
|
if (config.redemption) {
|
|
4236
4296
|
const policyConfig = {
|
|
@@ -4261,6 +4321,9 @@ function createIssuerService(config) {
|
|
|
4261
4321
|
if (feeManager) handlersConfig.feeManager = feeManager;
|
|
4262
4322
|
if (config.poolsProvider) handlersConfig.poolsProvider = config.poolsProvider;
|
|
4263
4323
|
if (redemption) handlersConfig.redemption = redemption;
|
|
4324
|
+
if (resolvedWrapperAddress !== void 0) {
|
|
4325
|
+
handlersConfig.mintFeeWrapperAddress = resolvedWrapperAddress;
|
|
4326
|
+
}
|
|
4264
4327
|
const handlers = new IssuerApiHandlers(handlersConfig);
|
|
4265
4328
|
if (config.indexer?.autoStart) {
|
|
4266
4329
|
for (const idx of indexers.values()) {
|
|
@@ -4478,7 +4541,7 @@ var MemoryRedemptionHistoryStore = class {
|
|
|
4478
4541
|
};
|
|
4479
4542
|
|
|
4480
4543
|
// src/index.ts
|
|
4481
|
-
var PAFI_ISSUER_SDK_VERSION = true ? "0.
|
|
4544
|
+
var PAFI_ISSUER_SDK_VERSION = true ? "0.12.0" : "dev";
|
|
4482
4545
|
export {
|
|
4483
4546
|
AdapterMisconfiguredError,
|
|
4484
4547
|
AuthError,
|