@pafi-dev/core 0.6.1 → 0.6.2

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.
Files changed (2) hide show
  1. package/README.md +150 -257
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -3,344 +3,237 @@
3
3
  [![npm](https://img.shields.io/npm/v/@pafi-dev/core)](https://www.npmjs.com/package/@pafi-dev/core)
4
4
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
5
5
 
6
- Core TypeScript SDK for the PAFI point token system. Covers EIP-712 signing, contract addresses + ABIs, ERC-4337 UserOp building, swap/perp calldata encoding, and on-chain quoting.
6
+ Pure primitives for the PAFI point-token system. EIP-712 signing,
7
+ contract ABIs + addresses, ERC-4337 UserOp building, EIP-7702
8
+ delegation, sponsor-auth signing, perp deposit calldata, fee quoting.
7
9
 
8
- **No HTTP client.** Safe to use in both browser (frontend) and Node.js (issuer backend).
10
+ **Browser + Node-safe.** Zero HTTP client. Peer-dep: `viem ^2`.
9
11
 
10
12
  ---
11
13
 
12
14
  ## Requirements
13
15
 
14
- - Node.js >= 18
16
+ - Node.js >= 18 (or modern browser with native `fetch`)
15
17
  - TypeScript >= 5.0
16
- - `viem` ^2.0.0 (peer dependency)
17
-
18
- > **Latest:** `0.5.16` — ERC-4337 v0.8 hash + EIP-712 signing fixes for the
19
- > EIP-7702 mobile flow. See [Changelog](#changelog) for the full breakdown
20
- > of the AA24/AA23 bugs this release closes.
18
+ - `viem` ^2.0.0 (peer)
21
19
 
22
20
  ---
23
21
 
24
22
  ## Installation
25
23
 
26
24
  ```bash
27
- npm install @pafi-dev/core viem
28
- # or
29
25
  pnpm add @pafi-dev/core viem
30
26
  ```
31
27
 
32
28
  ---
33
29
 
34
- ## Modules
35
-
36
- | Import path | What it provides |
37
- |---|---|
38
- | `@pafi-dev/core` | All exports below |
39
- | `@pafi-dev/core/eip712` | `signMintRequest`, `verifyMintRequest`, `signBurnRequest`, `signReceiverConsent` |
40
- | `@pafi-dev/core/contract` | `getContractAddresses()`, ABIs, address constants |
41
- | `@pafi-dev/core/swap` | `buildSwapWithGasDeduction()` — PT→USDT via UniversalRouter |
42
- | `@pafi-dev/core/quoting` | `findBestQuote()` on-chain V4 Quoter multicall |
43
- | `@pafi-dev/core/auth` | `createLoginMessage()`, `signSponsorAuth()`, `verifySponsorAuth()` |
44
- | `@pafi-dev/core/relay` | `buildDelegationUserOp()`, `getAaNonce()` |
30
+ ## What's in core (and what's not)
31
+
32
+ Core ships **data + primitives** only. Higher-level orchestration lives
33
+ in sibling packages:
34
+
35
+ | Concern | Package |
36
+ | --- | --- |
37
+ | Pure primitives (this package) | `@pafi-dev/core` |
38
+ | Issuer backend (claim / redeem / mobile flows) | `@pafi-dev/issuer` |
39
+ | Issuer DB ledger (TypeORM + Postgres) | `@pafi-dev/issuer-postgres` |
40
+ | Trading (swap + quote, FE-callable) | `@pafi-dev/trading` |
41
+
42
+ > **0.6.0 (2026-04-27):** swap UserOp builders + V4 quoting moved
43
+ > from core to `@pafi-dev/trading`. Core retains the underlying
44
+ > `universalRouterAbi`, `permit2Abi`, `v4QuoterAbi`, `PoolKey`,
45
+ > `PathKey`, `QuoteResult` types — trading wraps them with the actual
46
+ > swap logic. The `PafiSDK` class also drops `quote` / `swap`
47
+ > namespaces; use trading or import primitives directly.
48
+ >
49
+ > **0.6.1 (2026-04-27):** added `quoteOperatorFeeUsdt` so FE can
50
+ > compute USDT-denominated gas fee without round-tripping the issuer
51
+ > backend (`/gas-fee` is now optional).
45
52
 
46
53
  ---
47
54
 
48
- ## Contract addresses
49
-
50
- All deployed PAFI contract addresses live in one place, keyed by `chainId`:
51
-
52
- ```ts
53
- import { getContractAddresses, POINT_TOKEN_FACTORY_ADDRESSES } from "@pafi-dev/core";
55
+ ## Modules
54
56
 
55
- const addrs = getContractAddresses(8453); // Base mainnet
56
- // addrs.pointToken "0x7d25E7156E51F865D522fd3ef257a6B5DD41b97e"
57
- // addrs.issuerRegistry "0xda2D3338CF70F462Ac175F5f2edfa45660CA4f31"
58
- // addrs.mintingOracle "0xD85165939C700E51c8a45099316C6482634C2Ab9"
59
- // addrs.pafiHook "0x870cAF9882d3160602AaC1769C2B264A2d8EC044"
60
- // addrs.usdt "0x5d313485Ba59C3bb91e1A9C0C11782F0b83d5dcd"
61
- // addrs.batchExecutor "0x7702cb554e6bFb442cb743A7dF23154544a7176C"
57
+ | Symbol / area | What it provides |
58
+ | --- | --- |
59
+ | `getContractAddresses(chainId)` | All deployed PAFI contract addresses keyed by chain |
60
+ | `signMintRequest`, `verifyMintRequest` | EIP-712 sign / recover for `MintRequest` |
61
+ | `signBurnRequest`, `verifyBurnRequest` | EIP-712 sign / recover for `BurnRequest` |
62
+ | `signReceiverConsent`, `verifyReceiverConsent` | EIP-712 for sponsored-mint consent |
63
+ | `signSponsorAuth`, `verifySponsorAuth`, `buildAndSignSponsorAuth` | EIP-712 for sponsor-relayer auth |
64
+ | `buildPartialUserOperation`, `assembleUserOperation`, `computeUserOpHash` | ERC-4337 v0.7+ UserOp builder + hash |
65
+ | `encodeBatchExecute`, `decodeBatchExecuteCalls` | BatchExecutor (Coinbase SW v2) calldata |
66
+ | `buildDelegationUserOp`, `computeAuthorizationHash`, `parseEip7702DelegatedAddress` | EIP-7702 helpers |
67
+ | `splitAuthorizationSig`, `buildEip7702Authorization` | Split user's authSig + assemble bundler tuple |
68
+ | `buildPerpDepositViaRelay`, `buildPerpDepositWithGasDeduction`, `ORDERLY_RELAY_ABI`, `ORDERLY_VAULT_ABI`, `BROKER_HASHES`, `TOKEN_HASHES`, `computeAccountId` | Orderly perp deposit calldata + types |
69
+ | `quoteOperatorFeePt`, `quoteOperatorFeeUsdt` | Off-issuer fee quoter (Chainlink + V4 subgraph) |
70
+ | `fetchPafiPools`, `PAFI_SUBGRAPH_URL` | Pool discovery via PAFI subgraph |
71
+ | `pointTokenAbi` (alias `POINT_TOKEN_V2_ABI`), `issuerRegistryAbi`, `mintingOracleAbi`, `pointTokenFactoryAbi`, `erc20Abi`, `permit2Abi`, `universalRouterAbi`, `v4QuoterAbi` | Contract ABIs |
72
+ | `getMintRequestNonce`, `getBurnRequestNonce`, `getReceiverConsentNonce`, `getPointTokenBalance`, `isMinter`, `getTokenName` | On-chain read helpers |
73
+ | `createLoginMessage` | EIP-4361 SIWE login message builder |
74
+ | `parseEip7702DelegatedAddress`, `checkDelegation`, `isDelegatedTo`, `isDelegatedToTarget` | EIP-7702 delegation introspection |
62
75
 
63
- POINT_TOKEN_FACTORY_ADDRESSES[8453] // "0x36c0BAb2faBE45EfA6d13001143e43A266Af673B"
64
- ```
76
+ ---
65
77
 
66
- Protocol constants (same on all EVM chains):
78
+ ## Contract addresses
67
79
 
68
80
  ```ts
69
- import {
70
- ENTRY_POINT_V07,
71
- ENTRY_POINT_V08,
72
- PERMIT2_ADDRESS,
73
- } from "@pafi-dev/core";
74
- // ENTRY_POINT_V07 "0x0000000071727De22E5E9d8BAf0edAc6f37da032"
75
- // ENTRY_POINT_V08 "0x4337084d9e255ff0702461cf8895ce9e3b5ff108"
76
- // PERMIT2_ADDRESS "0x000000000022D473030F116dDEE9F6B43aC78BA3"
81
+ import { getContractAddresses } from "@pafi-dev/core";
82
+
83
+ const {
84
+ pointToken,
85
+ batchExecutor, // EIP-7702 delegation target (Coinbase SW v2)
86
+ usdt,
87
+ issuerRegistry,
88
+ mintingOracle,
89
+ pafiHook, // Uniswap V4 hook (10% fee on PT→USDT only)
90
+ chainlinkEthUsd,
91
+ orderlyRelay,
92
+ pafiFeeRecipient,
93
+ universalRouter,
94
+ } = getContractAddresses(8453);
77
95
  ```
78
96
 
79
- For Pimlico's `Simple7702Account` (the EIP-7702 delegate target you get
80
- when using Privy embedded wallets) you **must** use `ENTRY_POINT_V08`.
81
- Mixing v0.7 with a v0.8 account reverts with `AA23 reverted account: not
82
- from EntryPoint`.
97
+ Throws if `chainId` isn't in the map. Base mainnet (8453) is the only
98
+ chain in active use.
83
99
 
84
100
  ---
85
101
 
86
102
  ## EIP-712 signing
87
103
 
88
- Used by the **issuer backend** to sign mint/burn authorization. The frontend
89
- sends the signature alongside the UserOp to the Relay contract.
90
-
91
104
  ```ts
92
- import { signMintRequest, verifyMintRequest } from "@pafi-dev/core";
105
+ import { signMintRequest, getContractAddresses } from "@pafi-dev/core";
106
+ import { privateKeyToAccount } from "viem/accounts";
107
+ import { createWalletClient, http } from "viem";
93
108
 
94
- const domain = {
95
- name: "GG56 Points", // must match PointToken.name() on-chain
96
- chainId: 8453,
97
- verifyingContract: addrs.pointToken,
98
- };
99
-
100
- const { signature } = await signMintRequest(issuerWalletClient, domain, {
101
- to: userAddress,
102
- amount: 500n * 10n ** 18n,
103
- nonce: await getMintRequestNonce(publicClient, addrs.pointToken, userAddress),
104
- deadline: BigInt(Math.floor(Date.now() / 1000) + 900), // 15 min
109
+ const wallet = createWalletClient({
110
+ account: privateKeyToAccount(MINTER_PK),
111
+ transport: http(),
105
112
  });
106
113
 
107
- // Offline verification (optional Relay contract verifies on-chain)
108
- const { valid } = await verifyMintRequest(domain, request, signature, expectedSigner);
109
- ```
110
-
111
- ---
112
-
113
- ## SponsorAuth paymaster authorization
114
-
115
- The issuer backend signs a `SponsorAuth` payload so the PAFI paymaster proxy can
116
- verify the request is authorized before spending gas on behalf of the user.
117
-
118
- ```ts
119
- import {
120
- signSponsorAuth,
121
- verifySponsorAuth,
122
- computeCallDataHash,
123
- type SponsorAuthPayload,
124
- } from "@pafi-dev/core";
114
+ const { pointToken } = getContractAddresses(8453);
115
+ const sig = await signMintRequest(
116
+ wallet,
117
+ { name: "POINT", chainId: 8453, verifyingContract: pointToken },
118
+ {
119
+ to: userAddress,
120
+ amount: 1000n * 10n ** 18n,
121
+ nonce: currentMintRequestNonce,
122
+ deadline: BigInt(Math.floor(Date.now() / 1000) + 900),
123
+ },
124
+ );
125
125
 
126
- // Issuer backend: build + sign
127
- const payload: SponsorAuthPayload = {
128
- chainId: 8453,
129
- sender: userAddress,
130
- callDataHash: computeCallDataHash(userOp.callData),
131
- nonce: BigInt(Date.now()) * 1_000_000n + BigInt(Math.floor(Math.random() * 1_000_000)),
132
- expiresAt: Math.floor(Date.now() / 1000) + 600, // 10 min
133
- scenario: "mint", // "mint" | "burn" | "swap"
134
- issuerId: "gg56",
135
- };
136
-
137
- const sig = await signSponsorAuth(issuerWalletClient, payload);
138
-
139
- // Paymaster proxy: verify before forwarding to Pimlico
140
- const result = await verifySponsorAuth(payload, sig, expectedIssuerAddress);
141
- // result.ok true/false
142
- // result.reason "EXPIRED" | "INVALID_SIGNER" | "INVALID_SIGNATURE_FORMAT"
126
+ // sig.serialized bytes hex passed to PointToken.mint(...)
143
127
  ```
144
128
 
145
- ---
129
+ Same pattern for `signBurnRequest`, `signReceiverConsent`,
130
+ `signSponsorAuth`. KMS-backed wallets work — pass any
131
+ `viem WalletClient`.
146
132
 
147
- ## Swap calldata — PT → USDT
133
+ ---
148
134
 
149
- Builds the `callData` for a `BatchExecutor.execute()` call that:
150
- 1. Approves Permit2
151
- 2. Sets a Permit2 allowance for UniversalRouter
152
- 3. Swaps PT → USDT via UniversalRouter
153
- 4. Optionally deducts a gas fee in PT
135
+ ## ERC-4337 UserOp building
154
136
 
155
137
  ```ts
156
- import {
157
- buildSwapWithGasDeduction,
158
- findBestQuote,
159
- getContractAddresses,
160
- UNIVERSAL_ROUTER_ADDRESSES,
161
- } from "@pafi-dev/core";
162
-
163
- const addrs = getContractAddresses(8453);
138
+ import { encodeBatchExecute, buildPartialUserOperation } from "@pafi-dev/core";
164
139
 
165
- // 1. Quote (on-chain V4 Quoter multicall — read-only)
166
- const quote = await findBestQuote(
167
- publicClient,
168
- 8453,
169
- addrs.pointToken,
170
- addrs.usdt,
171
- 500n * 10n ** 18n,
172
- pools, // PoolKey[] from issuer backend GET /pools
173
- );
140
+ const callData = encodeBatchExecute([
141
+ { target: pointToken, value: 0n, data: mintCallData },
142
+ { target: pointToken, value: 0n, data: feeTransferCallData }, // optional
143
+ ]);
174
144
 
175
- // 2. Build unsigned UserOp
176
- const userOp = buildSwapWithGasDeduction({
177
- chainId: 8453,
145
+ const partial = buildPartialUserOperation({
178
146
  sender: userAddress,
179
- pointTokenAddress: addrs.pointToken,
180
- usdtAddress: addrs.usdt,
181
- universalRouterAddress: UNIVERSAL_ROUTER_ADDRESSES[8453],
182
- pafiHookAddress: addrs.pafiHook,
183
- quote,
184
- slippageBps: 50,
185
- deadline: BigInt(Math.floor(Date.now() / 1000) + 300),
186
- aaNonce: await getAaNonce(publicClient, userAddress),
187
- batchExecutorAddress: addrs.batchExecutor,
188
- gasFeePt: 0n, // set > 0 to deduct operator fee in PT
147
+ nonce: aaNonce,
148
+ operations: [...],
149
+ gasLimits: { callGasLimit: 300_000n, verificationGasLimit: 150_000n, preVerificationGas: 50_000n },
189
150
  });
190
151
  ```
191
152
 
192
- ---
153
+ `computeUserOpHash(userOp, chainId)` — EntryPoint v0.8 EIP-712 digest.
154
+ The mobile prepare/submit flow signs this hash via Privy
155
+ `personal_sign`.
193
156
 
194
- ## EIP-7702 delegation
157
+ ---
195
158
 
196
- One-time setup: sponsors the EIP-7702 delegation so the user's EOA gains
197
- `BatchExecutor` capabilities without spending native ETH.
159
+ ## EIP-7702 delegation helpers
198
160
 
199
161
  ```ts
200
162
  import {
201
- buildDelegationUserOp,
202
- getAaNonce,
203
- getContractAddresses,
204
- BATCH_EXECUTOR_ADDRESS_BASE_MAINNET,
163
+ computeAuthorizationHash,
164
+ parseEip7702DelegatedAddress,
165
+ splitAuthorizationSig,
166
+ buildEip7702Authorization,
205
167
  } from "@pafi-dev/core";
206
168
 
207
- const aaNonce = await getAaNonce(publicClient, userAddress);
169
+ // Check whether user EOA already has delegation installed
170
+ const code = await provider.getCode({ address: userAddress });
171
+ const designator = parseEip7702DelegatedAddress(code); // null = not delegated
208
172
 
209
- const userOp = buildDelegationUserOp({
210
- userAddress,
211
- aaNonce,
212
- });
213
-
214
- // Then: sign the EIP-7702 authorization off-chain via Privy
215
- // const authorization = await signAuthorization({ contractAddress: BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, ... });
216
- // await smartClient.sendTransaction({ to: userAddress, data: "0x", authorization });
217
- ```
218
-
219
- ---
220
-
221
- ## SIWE login message
222
-
223
- ```ts
224
- import { createLoginMessage } from "@pafi-dev/core";
173
+ // Build the hash the user signs to authorize delegation
174
+ const accountNonce = BigInt(await provider.getTransactionCount({ address: userAddress }));
175
+ const authHash = computeAuthorizationHash(8453, batchExecutor, accountNonce);
225
176
 
226
- const message = createLoginMessage({
227
- address: userAddress,
228
- domain: "app.gg56.com",
177
+ // On the bundler side: split the user's 65-byte signature into the tuple
178
+ const { r, s, yParity } = splitAuthorizationSig(authSig);
179
+ const authorization = buildEip7702Authorization({
229
180
  chainId: 8453,
230
- nonce: nonceFromServer, // GET /auth/nonce
231
- issuedAt: new Date().toISOString(),
232
- uri: "https://app.gg56.com",
181
+ address: batchExecutor,
182
+ nonce: accountNonce,
183
+ authSig,
233
184
  });
234
-
235
- // User signs with wallet, then POST /auth/login { message, signature }
236
185
  ```
237
186
 
238
187
  ---
239
188
 
240
- ## Perp deposit calldata — USDC → Orderly
189
+ ## Operator fee quoter
190
+
191
+ Two helpers for FE direct-mode usage (no backend round-trip):
241
192
 
242
193
  ```ts
243
- import {
244
- buildPerpDepositWithGasDeduction,
245
- computeAccountId,
246
- BROKER_HASHES,
247
- TOKEN_HASHES,
248
- ORDERLY_VAULT_ADDRESSES,
249
- } from "@pafi-dev/core";
194
+ import { quoteOperatorFeeUsdt, quoteOperatorFeePt } from "@pafi-dev/core";
250
195
 
251
- const accountId = computeAccountId(userAddress, BROKER_HASHES["woofi_pro"]);
196
+ // USDT-denominated (replaces issuer's GET /gas-fee).
197
+ // Pure RPC + Chainlink read.
198
+ const gasFeeUsdt = await quoteOperatorFeeUsdt({ provider, chainId: 8453 });
252
199
 
253
- const userOp = buildPerpDepositWithGasDeduction({
200
+ // PT-denominated (used by the swap flow as operator gas reimbursement
201
+ // in PT). Needs a subgraph call to read PT spot price.
202
+ const gasFeePt = await quoteOperatorFeePt({
203
+ provider,
254
204
  chainId: 8453,
255
- sender: userAddress,
256
- usdcAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
257
- vaultAddress: ORDERLY_VAULT_ADDRESSES[8453],
258
- amount: 100n * 10n ** 6n,
259
- accountId,
260
- brokerHash: BROKER_HASHES["woofi_pro"],
261
- tokenHash: TOKEN_HASHES["USDC"],
262
- layerZeroFee: await vault.getDepositFee(),
263
- aaNonce: await getAaNonce(publicClient, userAddress),
264
- batchExecutorAddress: addrs.batchExecutor,
205
+ pointTokenAddress: POINT_TOKEN,
265
206
  });
266
207
  ```
267
208
 
209
+ Both return `bigint` raw units. Sponsor-relayer's `FeeValidator` runs
210
+ the same math server-side with a 5% tolerance window — minor drift
211
+ between client and server is accepted.
212
+
268
213
  ---
269
214
 
270
- ## Changelog
271
-
272
- ### 0.5.16
273
-
274
- ERC-4337 v0.8 + EIP-7702 mobile flow correctness fixes.
275
-
276
- **Why this release.** The mobile prepare/submit flow (issuer backend computes
277
- the userOpHash, mobile client signs it, backend submits to the bundler)
278
- was reverting on Pimlico with `AA24 signature error` even though the same
279
- UserOp validated cleanly on the web flow via `permissionless`. Three
280
- distinct bugs stacked on top of each other; this release fixes them.
281
-
282
- **1. `computeUserOpHash` now produces the EIP-712 typed digest used by
283
- EntryPoint v0.8.** Previous versions hashed via the v0.7 scheme
284
- (`keccak256(packed userOp || entryPoint || chainId)`), which produces a
285
- totally different hash than what Pimlico's `Simple7702Account` (impl
286
- `0xe6Cae8…`, `entryPoint() = 0x4337084d…`) actually validates against.
287
- Symptom: `AA24` on every mobile UserOp.
288
-
289
- **2. `buildUserOpTypedData()` exposed for client-side signing.** The
290
- deployed Pimlico `Simple7702Account` validates the user signature with
291
- `SignatureCheckerLib.isValidSignatureNow(address(this), userOpHash, sig)`
292
- — **no EIP-191 prefix wrapping.** That means
293
- `personal_sign` / `signMessage({ raw: userOpHash })` produces a signature
294
- that `ecrecover`s to the wrong address; AA24 again. The new helper returns
295
- `{ domain, types, primaryType, message }` ready to pass straight into
296
- `walletClient.signTypedData(...)`. Because `userOpHash` IS the EIP-712
297
- digest of `PackedUserOperation`, signing the typed data yields a
298
- signature that recovers the EOA from the raw userOpHash — which is what
299
- the contract checks.
215
+ ## Sponsor-auth signing
300
216
 
301
217
  ```ts
302
- import { buildUserOpTypedData, computeUserOpHash } from "@pafi-dev/core";
303
-
304
- // Backend (gg56-backend, claim/prepare):
305
- const typedData = buildUserOpTypedData(userOpWithPaymaster, chainId);
306
- const userOpHash = computeUserOpHash(userOpWithPaymaster, chainId);
307
- return { lockId, userOpHash, typedData /* serialise bigints */ };
308
-
309
- // Client (Privy embedded wallet):
310
- const signature = await walletClient.signTypedData({
311
- domain: typedData.domain,
312
- types: typedData.types,
313
- primaryType: typedData.primaryType,
314
- message: typedData.message,
315
- });
316
- // Submit { lockId, signature } to /claim/submit. AA24 stays away.
317
- ```
318
-
319
- **Do NOT use `signMessage({ raw })` or `personal_sign` to sign a v0.8
320
- userOpHash for `Simple7702Account`** — that path is a foot-gun the SDK
321
- intentionally no longer offers a helper for.
218
+ import { buildAndSignSponsorAuth } from "@pafi-dev/core";
322
219
 
323
- **3. `ENTRY_POINT_V08` constant added.** v0.7 EntryPoint
324
- (`0x0000000071727De22E5E9d8BAf0edAc6f37da032`) is incompatible with
325
- v0.8 accounts — calling `pm_sponsorUserOperation` with v0.7 reverts
326
- inside `_validateUserOp` with `"AA23 reverted account: not from
327
- EntryPoint"` because `msg.sender (v0.7 EP) account.entryPoint() (v0.8 EP)`.
220
+ const sponsorAuth = await buildAndSignSponsorAuth({
221
+ userAddress,
222
+ callData: userOp.callData,
223
+ chainId: 8453,
224
+ scenario: "mint", // "mint" | "burn" | "swap" | "perp-deposit" | "delegate"
225
+ issuerId: ISSUER_ID,
226
+ issuerSignerWallet, // KMS-backed in prod
227
+ });
328
228
 
329
- ```ts
330
- import { ENTRY_POINT_V08 } from "@pafi-dev/core";
331
- // 0x4337084d9e255ff0702461cf8895ce9e3b5ff108
229
+ // Pass to sponsor-relayer's POST /paymaster/sponsor as the `sponsorAuth` field.
332
230
  ```
333
231
 
334
- ### 0.4.0
335
- - `sponsorAuth` module added — `signSponsorAuth`, `verifySponsorAuth`, `computeCallDataHash`
336
- - `PERMIT2_ADDRESS` and `ENTRY_POINT_V07` centralised in `constants.ts`
337
- - `BATCH_EXECUTOR_ADDRESS_BASE_*` derived from `addresses.ts` — no duplicate hardcoding
232
+ The issuer signer must be registered in PAFI's `IssuerRegistry`
233
+ (`signerAddress` field).
338
234
 
339
- ### 0.3.0-beta.10
340
- - All Base mainnet contract addresses live and verified against deployed contracts
235
+ ---
341
236
 
342
- ### 0.3.0-beta.8/9
343
- - Full 4-scenario UserOp builders (mint, burn, swap, perp_deposit)
237
+ ## License
344
238
 
345
- ### 0.3.0-alpha.0
346
- - Initial EIP-7702 BatchExecutor support, UserOp primitives
239
+ Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pafi-dev/core",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "EIP-712 signing, contract interaction, and Relay calldata for the PAFI point token system",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",