@pafi-dev/issuer 0.3.0-beta.1 → 0.3.0-beta.11
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 +164 -292
- package/dist/index.cjs +437 -1029
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +234 -616
- package/dist/index.d.ts +234 -616
- package/dist/index.js +421 -1013
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,352 +1,224 @@
|
|
|
1
1
|
# @pafi-dev/issuer
|
|
2
2
|
|
|
3
|
-
Issuer backend
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**What ships in this alpha:**
|
|
18
|
-
|
|
19
|
-
- `PafiBackendClient` — HTTP client for `paymaster-proxy` with retry +
|
|
20
|
-
backoff on `safeToRetry` errors (opt-in via `retry.maxAttempts`)
|
|
21
|
-
- `BalanceAggregator` — merge off-chain + on-chain balance into one number
|
|
22
|
-
- `BurnIndexer` — watches `Transfer(user → 0x0)` events, finalizes
|
|
23
|
-
pending off-chain credits for the reverse flow
|
|
24
|
-
- `IPointLedger.reservePendingCredit()` / `resolveCreditByBurnTx()` —
|
|
25
|
-
additive ledger methods for burn→credit flow
|
|
26
|
-
- `ApiConfigResponse.pafiWebUrl` + `contracts.pointTokens[]` — new
|
|
27
|
-
fields surfaced by `handleConfig()`
|
|
28
|
-
- `FeeManager` slimmed: no more `operatorWallet` /
|
|
29
|
-
`usdtAddress` / `nativeWrappedAddress`; rebalancing gone (operator
|
|
30
|
-
doesn't hold ETH anymore); `quoteNativeToFee` replaces
|
|
31
|
-
`quoteNativeToUsdt` so fee currency is caller-chosen (PT for
|
|
32
|
-
mint/burn, USDT for swap/perp_deposit)
|
|
33
|
-
|
|
34
|
-
**What's still blocked (comes in 0.3.0-beta / stable):**
|
|
35
|
-
|
|
36
|
-
- `processMint()` / `processBurn()` — blocked on SC Relayer v2 ABI
|
|
37
|
-
(blocker B1). Current `processMintAndCashOut()` is `@deprecated`
|
|
38
|
-
but still works
|
|
39
|
-
- `PTRedeemHandler` + `TopUpRedemptionHandler` — blocked on B1 +
|
|
40
|
-
`paymaster-proxy` staging env being live
|
|
41
|
-
- Deletion of legacy `claimAndSwap` flow — kept for v0.2.x consumers
|
|
42
|
-
until 2.0
|
|
43
|
-
|
|
44
|
-
**Install the alpha:**
|
|
3
|
+
Issuer backend SDK for the PAFI point token system. Wraps `@pafi-dev/core`
|
|
4
|
+
with everything a partner needs to run the off-chain side of the cashout
|
|
5
|
+
flow: SIWE authentication, point ledger, policy engine, EIP-712 issuer
|
|
6
|
+
signing, relay submission, and mint/burn event indexing.
|
|
7
|
+
|
|
8
|
+
**Version:** `0.3.0-beta.10`
|
|
9
|
+
|
|
10
|
+
> This package runs on the **issuer backend server only** (Node.js). Do not
|
|
11
|
+
> import into browser bundles — it pulls in `jose`, `node:crypto`, and
|
|
12
|
+
> server-side dependencies.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
45
17
|
|
|
46
18
|
```bash
|
|
47
|
-
pnpm add @pafi-dev/issuer
|
|
19
|
+
pnpm add @pafi-dev/issuer @pafi-dev/core viem
|
|
48
20
|
```
|
|
49
21
|
|
|
50
|
-
|
|
22
|
+
---
|
|
51
23
|
|
|
52
|
-
## What
|
|
24
|
+
## What this package provides
|
|
53
25
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
|
|
26
|
+
| Module | What it does |
|
|
27
|
+
|--------|-------------|
|
|
28
|
+
| `relay/` | `RelayService.prepareMint()` / `prepareBurn()` — build unsigned UserOps |
|
|
29
|
+
| `indexer/` | `PointIndexer` (Mint events) + `BurnIndexer` (Transfer→0x0 events) |
|
|
30
|
+
| `auth/` | `AuthService` (SIWE verify + JWT issue) + `authenticateRequest` middleware |
|
|
31
|
+
| `ledger/` | `IPointLedger` interface — implement against your own database |
|
|
32
|
+
| `policy/` | `DefaultPolicyEngine` + `IPolicyEngine` interface |
|
|
33
|
+
| `pools/` | `PoolsProvider` — fetch V4 pool list from PAFI subgraph |
|
|
34
|
+
| `balance/` | `BalanceAggregator` — merge off-chain ledger + on-chain `balanceOf` |
|
|
35
|
+
| `api/` | `IssuerApiHandlers`, `PTRedeemHandler`, `TopUpRedemptionHandler` |
|
|
59
36
|
|
|
60
|
-
|
|
61
|
-
Single-token issuers can ignore it — legacy 0.1.x code keeps working.
|
|
62
|
-
Multi-token issuers must persist balances keyed by `(user, token)`.
|
|
37
|
+
---
|
|
63
38
|
|
|
64
|
-
|
|
65
|
-
one-element list. No code change is required if you only have one token.
|
|
39
|
+
## What you must bring
|
|
66
40
|
|
|
67
|
-
|
|
41
|
+
The SDK deliberately does not ship production implementations for these
|
|
42
|
+
three concerns — every issuer's infrastructure is different:
|
|
68
43
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
44
|
+
| What | Why you own it |
|
|
45
|
+
|------|---------------|
|
|
46
|
+
| **`IPointLedger`** | Your database, your schema, your locking strategy |
|
|
47
|
+
| **`ISessionStore`** | Must be shared across pods — Redis, Postgres, etc. |
|
|
48
|
+
| **Signing wallet** | Private key must never touch server memory — use KMS |
|
|
72
49
|
|
|
73
|
-
|
|
50
|
+
See [`examples/adapters/`](./examples/adapters/) for reference implementations
|
|
51
|
+
of all three (Postgres ledger, Redis session store, AWS KMS wallet).
|
|
74
52
|
|
|
75
|
-
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Quick start
|
|
76
56
|
|
|
77
57
|
```ts
|
|
78
|
-
import { createIssuerService
|
|
58
|
+
import { createIssuerService } from "@pafi-dev/issuer";
|
|
79
59
|
import { createPublicClient, createWalletClient, http } from "viem";
|
|
80
|
-
import { privateKeyToAccount } from "viem/accounts";
|
|
81
60
|
import { base } from "viem/chains";
|
|
82
61
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
62
|
+
// --- Production: replace with KMS-backed wallet (see examples/adapters/kms-signer.ts)
|
|
63
|
+
// --- Dev only: raw private key
|
|
64
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
65
|
+
const issuerSignerWallet = createWalletClient({
|
|
66
|
+
account: privateKeyToAccount(process.env.MINTER_PRIVATE_KEY as `0x${string}`),
|
|
86
67
|
chain: base,
|
|
87
|
-
transport: http(RPC_URL),
|
|
68
|
+
transport: http(process.env.RPC_URL),
|
|
88
69
|
});
|
|
89
70
|
|
|
90
71
|
const service = createIssuerService({
|
|
91
72
|
chainId: 8453,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
pointTokenAddresses: ["0x<PointToken>"],
|
|
74
|
+
contracts: {
|
|
75
|
+
relay: "0x<Relay>",
|
|
76
|
+
issuerRegistry: "0x<IssuerRegistry>",
|
|
77
|
+
usdt: "0x<USDT>",
|
|
78
|
+
batchExecutor: "0x<BatchExecutor>",
|
|
79
|
+
},
|
|
80
|
+
provider: createPublicClient({ chain: base, transport: http(process.env.RPC_URL) }),
|
|
97
81
|
auth: {
|
|
98
82
|
jwtSecret: process.env.JWT_SECRET!,
|
|
99
83
|
domain: "app.example.com",
|
|
100
84
|
},
|
|
101
|
-
|
|
102
|
-
|
|
85
|
+
ledger: new YourPostgresLedger(), // implements IPointLedger
|
|
86
|
+
sessionStore: new YourRedisSessionStore(), // implements ISessionStore
|
|
87
|
+
claim: {
|
|
88
|
+
issuerSignerWallet,
|
|
89
|
+
batchExecutorAddress: "0x<BatchExecutor>",
|
|
90
|
+
},
|
|
103
91
|
});
|
|
104
92
|
|
|
105
|
-
//
|
|
106
|
-
|
|
93
|
+
// Mount handlers into your framework (Express, Fastify, NestJS, Hono...)
|
|
94
|
+
app.get("/auth/nonce", () => service.handlers.handleGetNonce());
|
|
95
|
+
app.post("/auth/login", (req) => service.handlers.handleLogin(req.body));
|
|
96
|
+
app.get("/user", (req) => service.handlers.handleUser(req.user, req.query));
|
|
97
|
+
app.post("/claim", (req) => service.handlers.handleClaim(req.user, req.body));
|
|
107
98
|
```
|
|
108
99
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
| Component | Default | Replace for production? |
|
|
112
|
-
| ----------------------- | --------------------- | ------------------------------------- |
|
|
113
|
-
| `IPointLedger` | `MemoryPointLedger` | ✅ Postgres / Prisma |
|
|
114
|
-
| `ISessionStore` | `MemorySessionStore` | ✅ Redis |
|
|
115
|
-
| `IPolicyEngine` | `DefaultPolicyEngine` | ➕ extend for KYC / caps / claim budget |
|
|
116
|
-
| `IIssuerSigner` | `PrivateKeySigner` | 🚨 **MUST replace** — KMS / HSM / MPC |
|
|
117
|
-
| `AuthService` | ✅ built-in | — |
|
|
118
|
-
| `RelayService` | ✅ built-in | — |
|
|
119
|
-
| `FeeManager` | ✅ built-in (opt-in) | injection-based — no DEX lock-in |
|
|
120
|
-
| `MintingGateway` | ✅ built-in | — |
|
|
121
|
-
| `PointIndexer` | ✅ built-in (polling) | — |
|
|
122
|
-
| `IssuerApiHandlers` | ✅ built-in | — |
|
|
123
|
-
|
|
124
|
-
See [`examples/adapters/`](./examples/adapters) for reference
|
|
125
|
-
implementations of the three interfaces you must replace.
|
|
100
|
+
---
|
|
126
101
|
|
|
127
|
-
##
|
|
102
|
+
## Implementing IPointLedger
|
|
128
103
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
104
|
+
```ts
|
|
105
|
+
import type { IPointLedger } from "@pafi-dev/issuer";
|
|
106
|
+
import type { Address, Hex } from "viem";
|
|
107
|
+
|
|
108
|
+
export class PostgresPointLedger implements IPointLedger {
|
|
109
|
+
async getBalance(user: Address, tokenAddress?: Address): Promise<bigint> { ... }
|
|
110
|
+
async lockForMinting(user: Address, amount: bigint, durationMs: number, tokenAddress?: Address): Promise<string> { ... }
|
|
111
|
+
async releaseLock(lockId: string): Promise<void> { ... }
|
|
112
|
+
async deductBalance(user: Address, amount: bigint, txHash: Hex, tokenAddress?: Address): Promise<void> { ... }
|
|
113
|
+
async creditBalance(user: Address, amount: bigint, reason: string, tokenAddress?: Address): Promise<void> { ... }
|
|
114
|
+
async getLockedRequests(user: Address, tokenAddress?: Address): Promise<LockedMintRequest[]> { ... }
|
|
115
|
+
async updateMintStatus(lockId: string, status: MintingStatus, txHash?: Hex): Promise<void> { ... }
|
|
116
|
+
// v1.4 reverse flow (burn → off-chain credit):
|
|
117
|
+
async reservePendingCredit(user: Address, amount: bigint, durationMs: number, tokenAddress?: Address): Promise<string> { ... }
|
|
118
|
+
async resolveCreditByBurnTx(lockId: string, txHash: Hex): Promise<void> { ... }
|
|
119
|
+
}
|
|
145
120
|
```
|
|
146
121
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
broadcast and receipt, the indexer still finalizes the ledger the next
|
|
151
|
-
time it polls.
|
|
122
|
+
Critical: `lockForMinting` must use a **row-level lock** (e.g. `SELECT ... FOR UPDATE`)
|
|
123
|
+
so concurrent requests from multiple pods cannot read the same available balance and
|
|
124
|
+
double-spend.
|
|
152
125
|
|
|
153
|
-
|
|
126
|
+
See `examples/adapters/postgres-ledger.ts` for a full Prisma implementation.
|
|
154
127
|
|
|
155
|
-
|
|
156
|
-
tells the API layer whether the underlying ledger lock was released:
|
|
128
|
+
---
|
|
157
129
|
|
|
158
|
-
|
|
159
|
-
| --------------------------- | -------------- | ------------- |
|
|
160
|
-
| `INVALID_REQUEST` | never locked | `true` |
|
|
161
|
-
| `INVALID_CONSENT_SIGNATURE` | never locked | `true` |
|
|
162
|
-
| `CONSENT_EXPIRED` | never locked | `true` |
|
|
163
|
-
| `POLICY_REJECTED` | never locked | `true` |
|
|
164
|
-
| `INSUFFICIENT_BALANCE` | never locked | `true` |
|
|
165
|
-
| `SIGNER_FAILED` | ✅ released | `true` |
|
|
166
|
-
| `RELAY_SIMULATION_FAILED` | ✅ released | `true` |
|
|
167
|
-
| `RELAY_SUBMIT_FAILED` | ✅ released | `true` |
|
|
168
|
-
| `RELAY_REVERTED` | 🔒 kept | `false` |
|
|
169
|
-
| `RELAY_TIMEOUT` | 🔒 kept | `false` |
|
|
130
|
+
## Production signing — KMS
|
|
170
131
|
|
|
171
|
-
`
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
cases and require manual reconciliation.
|
|
132
|
+
The `claim.issuerSignerWallet` must be backed by a hardware key in production.
|
|
133
|
+
The SDK accepts any viem `WalletClient` — wire it to AWS KMS by giving viem
|
|
134
|
+
a custom account:
|
|
175
135
|
|
|
176
|
-
|
|
136
|
+
```ts
|
|
137
|
+
import { createKmsWalletClient } from "./adapters/kms-signer";
|
|
138
|
+
import { KMSClient } from "@aws-sdk/client-kms";
|
|
177
139
|
|
|
178
|
-
|
|
140
|
+
const kms = new KMSClient({ region: "us-east-1" });
|
|
179
141
|
|
|
142
|
+
const issuerSignerWallet = createKmsWalletClient({
|
|
143
|
+
kms,
|
|
144
|
+
keyId: process.env.KMS_MINTER_KEY_ID!,
|
|
145
|
+
address: process.env.KMS_MINTER_ADDRESS! as `0x${string}`,
|
|
146
|
+
chain: base,
|
|
147
|
+
});
|
|
180
148
|
```
|
|
181
|
-
Frontend Issuer backend
|
|
182
|
-
──────── ──────────────
|
|
183
|
-
1. GET /auth/nonce → authService.getNonce()
|
|
184
|
-
← { nonce }
|
|
185
|
-
2. Build EIP-4361 message with
|
|
186
|
-
nonce (via PafiSDK or
|
|
187
|
-
@pafi-dev/core createLoginMessage)
|
|
188
|
-
3. Sign with wallet
|
|
189
|
-
4. POST /auth/login → authService.login(message, sig)
|
|
190
|
-
{ message, signature } → parse → verify → consume nonce
|
|
191
|
-
→ create session → issue JWT
|
|
192
|
-
← { token, userAddress, expiresAt }
|
|
193
|
-
5. Authorization: Bearer <jwt> → authenticateRequest()
|
|
194
|
-
→ verify JWT + session
|
|
195
|
-
→ pass { userAddress, chainId } to handlers
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Key property: a failed signature does **not** burn the nonce. Users can
|
|
199
|
-
retry with the correct wallet on the same nonce without hitting the
|
|
200
|
-
backend again.
|
|
201
|
-
|
|
202
|
-
## HTTP endpoints
|
|
203
149
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
whatever you use. See `examples/express-issuer/server.ts` for the full
|
|
207
|
-
wiring.
|
|
150
|
+
See `examples/adapters/kms-signer.ts` for the full implementation including
|
|
151
|
+
DER→(r,s) conversion and v-byte recovery.
|
|
208
152
|
|
|
209
|
-
|
|
210
|
-
| ------ | ---------------- | ---- | -------------------- |
|
|
211
|
-
| GET | /auth/nonce | no | `handleGetNonce` |
|
|
212
|
-
| POST | /auth/login | no | `handleLogin` |
|
|
213
|
-
| GET | /config | no | `handleConfig` |
|
|
214
|
-
| GET | /gas-fee | no | `handleGasFee` |
|
|
215
|
-
| POST | /auth/logout | yes | `handleLogout` |
|
|
216
|
-
| GET | /pools | yes | `handlePools` |
|
|
217
|
-
| GET | /user | yes | `handleUser` |
|
|
218
|
-
| POST | /claim-and-swap | yes | `handleClaimAndSwap` |
|
|
153
|
+
---
|
|
219
154
|
|
|
220
|
-
##
|
|
155
|
+
## Indexers
|
|
221
156
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
157
|
+
```ts
|
|
158
|
+
import { PointIndexer, BurnIndexer } from "@pafi-dev/issuer";
|
|
159
|
+
|
|
160
|
+
// Watches Transfer(0x0 → user) — deducts off-chain balance when mint confirmed.
|
|
161
|
+
const pointIndexer = new PointIndexer({
|
|
162
|
+
provider: publicClient,
|
|
163
|
+
pointTokenAddress: "0x<PointToken>",
|
|
164
|
+
ledger,
|
|
165
|
+
cursorStore, // PostgresCursorStore recommended
|
|
166
|
+
fromBlock: 28_000_000n,
|
|
167
|
+
confirmations: 2,
|
|
168
|
+
pollIntervalMs: 3_000,
|
|
169
|
+
});
|
|
170
|
+
pointIndexer.start();
|
|
171
|
+
|
|
172
|
+
// Watches Transfer(user → 0x0) — resolves pending credit when burn confirmed.
|
|
173
|
+
const burnIndexer = new BurnIndexer({
|
|
174
|
+
provider: publicClient,
|
|
175
|
+
pointTokenAddress: "0x<PointToken>",
|
|
176
|
+
ledger,
|
|
177
|
+
cursorStore,
|
|
178
|
+
matchLockId: async (evt) => {
|
|
179
|
+
// Return the lockId from ledger.reservePendingCredit() that matches
|
|
180
|
+
// this burn event. Typically a DB lookup by (from, amount, status=PENDING).
|
|
181
|
+
return yourDb.findPendingCreditLockId(evt.from, evt.amount);
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
burnIndexer.start();
|
|
234
185
|
```
|
|
235
186
|
|
|
236
|
-
|
|
187
|
+
Indexers must be **singletons** — run exactly one instance per token per deployment.
|
|
188
|
+
Use a Kubernetes Deployment with `replicas: 1`, not a Deployment behind a load balancer.
|
|
189
|
+
|
|
190
|
+
---
|
|
237
191
|
|
|
238
|
-
##
|
|
192
|
+
## Error codes
|
|
239
193
|
|
|
240
194
|
```ts
|
|
241
|
-
import {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
type IPointLedger,
|
|
250
|
-
type LockedMintRequest,
|
|
251
|
-
type MintingStatus,
|
|
252
|
-
|
|
253
|
-
// Policy
|
|
254
|
-
DefaultPolicyEngine,
|
|
255
|
-
type IPolicyEngine,
|
|
256
|
-
type PolicyDecision,
|
|
257
|
-
type PolicyEvalRequest,
|
|
258
|
-
|
|
259
|
-
// Signer
|
|
260
|
-
PrivateKeySigner, // DEV ONLY
|
|
261
|
-
type IIssuerSigner,
|
|
262
|
-
|
|
263
|
-
// Auth
|
|
264
|
-
AuthService,
|
|
265
|
-
AuthError,
|
|
266
|
-
type AuthErrorCode,
|
|
267
|
-
type AuthContext,
|
|
268
|
-
MemorySessionStore,
|
|
269
|
-
type ISessionStore,
|
|
270
|
-
type Session,
|
|
271
|
-
NonceManager,
|
|
272
|
-
authenticateRequest,
|
|
273
|
-
|
|
274
|
-
// Relay + fees
|
|
275
|
-
RelayService,
|
|
276
|
-
RelayError,
|
|
277
|
-
type RelayErrorCode,
|
|
278
|
-
type SubmitMintAndSwapParams,
|
|
279
|
-
type RelayResult,
|
|
280
|
-
type OperatorWalletLike,
|
|
281
|
-
FeeManager,
|
|
282
|
-
type FeeManagerConfig,
|
|
283
|
-
|
|
284
|
-
// Gateway
|
|
285
|
-
MintingGateway,
|
|
286
|
-
MintingGatewayError,
|
|
287
|
-
type MintingGatewayErrorCode,
|
|
288
|
-
type MintAndCashOutRequest,
|
|
289
|
-
type MintAndCashOutResponse,
|
|
290
|
-
encodeExtData,
|
|
291
|
-
|
|
292
|
-
// Indexer
|
|
293
|
-
PointIndexer,
|
|
294
|
-
type PointIndexerConfig,
|
|
295
|
-
type MintEvent,
|
|
296
|
-
type IIndexerCursorStore,
|
|
297
|
-
InMemoryCursorStore,
|
|
298
|
-
|
|
299
|
-
// API handlers + HTTP contract (source of truth — FE imports these type-only)
|
|
300
|
-
IssuerApiHandlers,
|
|
301
|
-
type IssuerApiHandlersConfig,
|
|
302
|
-
type ApiConfigResponse,
|
|
303
|
-
type ApiNonceResponse,
|
|
304
|
-
type ApiLoginRequest,
|
|
305
|
-
type ApiLoginResponse,
|
|
306
|
-
type ApiGasFeeResponse,
|
|
307
|
-
type ApiPoolsRequest,
|
|
308
|
-
type ApiPoolsResponse,
|
|
309
|
-
type ApiUserRequest,
|
|
310
|
-
type ApiUserResponse,
|
|
311
|
-
type ApiClaimAndSwapRequest,
|
|
312
|
-
type ApiClaimAndSwapResponse,
|
|
313
|
-
type PoolsProvider,
|
|
314
|
-
} from "@pafi-dev/issuer";
|
|
195
|
+
import { PafiBackendError, type PafiBackendErrorCode } from "@pafi-dev/issuer";
|
|
196
|
+
|
|
197
|
+
type PafiBackendErrorCode =
|
|
198
|
+
| "RATE_LIMIT_EXCEEDED" | "RATE_LIMIT_EXCEEDED_DAILY" | "RATE_LIMIT_EXCEEDED_PER_USER"
|
|
199
|
+
| "RATE_LIMITER_UNAVAILABLE"
|
|
200
|
+
| "INTENT_REJECTED" | "MINT_CAP_EXCEEDED" | "ISSUER_INACTIVE"
|
|
201
|
+
| "ISSUER_UNAUTHORIZED" | "USER_UNAUTHORIZED"
|
|
202
|
+
| "BAD_REQUEST" | "INTERNAL_ERROR" | "TIMEOUT" | "NETWORK_ERROR";
|
|
315
203
|
```
|
|
316
204
|
|
|
317
|
-
|
|
205
|
+
---
|
|
318
206
|
|
|
319
|
-
|
|
320
|
-
between the issuer backend and any frontend / mobile / SDK consumer. The
|
|
321
|
-
request/response types above are defined once here, then imported
|
|
322
|
-
**type-only** by frontend code so browser bundles never pull in server
|
|
323
|
-
code (`jose`, `node:crypto`, indexer polling loops, etc):
|
|
207
|
+
## Changelog
|
|
324
208
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
ApiUserResponse,
|
|
331
|
-
} from "@pafi-dev/issuer";
|
|
332
|
-
|
|
333
|
-
// Build your own fetch call with full type safety
|
|
334
|
-
const res = await fetch(`${API_URL}/claim-and-swap`, {
|
|
335
|
-
method: "POST",
|
|
336
|
-
headers: {
|
|
337
|
-
"Content-Type": "application/json",
|
|
338
|
-
Authorization: `Bearer ${token}`,
|
|
339
|
-
},
|
|
340
|
-
body: JSON.stringify(request satisfies ApiClaimAndSwapRequest),
|
|
341
|
-
});
|
|
342
|
-
const body = (await res.json()) as ApiClaimAndSwapResponse;
|
|
343
|
-
```
|
|
209
|
+
### 0.3.0-beta.10
|
|
210
|
+
- `MemoryPointLedger` removed from public exports — each issuer implements `IPointLedger` against their own DB
|
|
211
|
+
- `PrivateKeySigner` / `IIssuerSigner` removed — SDK accepts viem `WalletClient` directly; see `examples/adapters/kms-signer.ts`
|
|
212
|
+
- `ledger` is now a required field in `IssuerServiceConfig` (was optional with in-memory default)
|
|
213
|
+
- `handleClaim` added to `IssuerApiHandlers` — enforces policy evaluation atomically before signing
|
|
344
214
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
contract in exactly one place.
|
|
215
|
+
### 0.3.0-beta.9
|
|
216
|
+
- `handleBuildConsentTypedData` validates `receiverConsent.originalReceiver` against authenticated user
|
|
217
|
+
- `PTRedeemHandler` enforces on-chain balance check before signing BurnRequest
|
|
349
218
|
|
|
350
|
-
|
|
219
|
+
### 0.3.0-beta.8
|
|
220
|
+
- `BalanceAggregator`, `BurnIndexer`, `PTRedeemHandler`, `TopUpRedemptionHandler`
|
|
221
|
+
- `BurnIndexer.matchLockId` is now required (throws if not provided)
|
|
351
222
|
|
|
352
|
-
|
|
223
|
+
### 0.3.0-alpha.0
|
|
224
|
+
- Initial `RelayService`, `PointIndexer`, `AuthService`, `IssuerApiHandlers`
|