@pafi-dev/core 0.3.0-beta.5 → 0.3.0-beta.7

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.d.cts CHANGED
@@ -5,7 +5,7 @@ export { erc20Abi, issuerRegistryAbi, mintingOracleAbi, permit2Abi, pointTokenAb
5
5
  export { buildBurnRequestTypedData, buildDomain, buildMintRequestTypedData, buildReceiverConsentTypedData, signBurnRequest, signMintRequest, signReceiverConsent, verifyBurnRequest, verifyMintRequest, verifyReceiverConsent } from './eip712/index.cjs';
6
6
  export { getIssuer, getMintRequestNonce, getPointTokenBalance, getPointTokenIssuer, getPointTokenIssuerAddress, getReceiverConsentNonce, getTokenName, isActiveIssuer, isMinter, verifyMintCap } from './contract/index.cjs';
7
7
  export { buildAllPaths, combineRoutes, findBestQuote, quoteBestRoute, quoteExactInput, quoteExactInputSingle } from './quoting/index.cjs';
8
- import { O as Operation, P as PartialUserOperation, U as UserOperation, S as SwapSimulationResult } from './index-B7pGBych.cjs';
8
+ import { P as PartialUserOperation, O as Operation, U as UserOperation, S as SwapSimulationResult } from './index-B7pGBych.cjs';
9
9
  export { B as BuildSwapWithGasDeductionParams, E as ENTRY_POINT_V07, a as PaymasterFields, b as SETTLE_ALL, c as SWAP_EXACT_IN, T as TAKE_ALL, d as UserOpReceipt, V as V4_SWAP, Z as ZERO_VALUE, e as buildErc20ApprovalCalldata, f as buildPermit2ApprovalCalldata, g as buildSwapFromQuote, h as buildSwapWithGasDeduction, i as buildUniversalRouterExecuteArgs, j as buildV4SwapInput, k as checkAllowance, s as simulateSwap } from './index-B7pGBych.cjs';
10
10
  import { LoginMessageParams } from './auth/index.cjs';
11
11
  export { VerifyLoginResult, createLoginMessage, parseLoginMessage, verifyLoginMessage } from './auth/index.cjs';
@@ -87,6 +87,256 @@ declare class ApiError extends PafiSDKError {
87
87
  constructor(message: string, status?: number | undefined);
88
88
  }
89
89
 
90
+ /**
91
+ * Orderly Network Vault — entrypoint for **perp deposit** flow on
92
+ * Base mainnet (Scenario 3).
93
+ *
94
+ * Source of truth for addresses + integration:
95
+ * https://orderly.network/docs/build-on-omnichain/addresses#base
96
+ *
97
+ * ## Architecture
98
+ *
99
+ * User wallet (Base)
100
+ * │ 1. USDC.approve(vault, amount)
101
+ * │ 2. vault.deposit{value: layerZeroFee}({
102
+ * │ accountId, brokerHash, tokenHash, tokenAmount
103
+ * │ })
104
+ * ▼
105
+ * OrderlyVault (Base)
106
+ * │ — locks USDC, emits LayerZero message
107
+ * ▼
108
+ * Orderly chain (off-chain matching engine)
109
+ * │ — credits the user's perp account
110
+ * ▼
111
+ * User can now place perp orders via Orderly REST/WS API
112
+ *
113
+ * **Important:** `value` is required and is the LayerZero cross-chain
114
+ * fee (paid in native ETH on Base). Quote it via
115
+ * `vault.getDepositFee(user, data)` BEFORE calling deposit. Fees vary
116
+ * with destination chain congestion.
117
+ *
118
+ * ## Sponsored vs direct
119
+ *
120
+ * Coinbase Paymaster sponsors GAS, not `msg.value`. So even on the
121
+ * sponsored path the user MUST hold enough native ETH on Base to cover
122
+ * `getDepositFee()` (typically ~0.0002 ETH at quiet times).
123
+ */
124
+ /** Orderly Vault on Base mainnet (EIP-55 checksum). */
125
+ declare const ORDERLY_VAULT_BASE_MAINNET: Address;
126
+ /**
127
+ * Per-chain registry of the Orderly Vault. Add chains here as Orderly
128
+ * deploys them.
129
+ */
130
+ declare const ORDERLY_VAULT_ADDRESSES: Record<number, Address>;
131
+ /**
132
+ * Pre-computed broker hashes — `keccak256(abi.encodePacked(brokerId))`.
133
+ * Add new brokers as they launch.
134
+ *
135
+ * Reference: https://orderly.network/docs/build-on-omnichain/user-flows/accountId
136
+ */
137
+ declare const BROKER_HASHES: {
138
+ /** Default partner broker on Base — most commonly whitelisted. */
139
+ readonly woofi_pro: `0x${string}`;
140
+ /** Orderly's own white-label broker. */
141
+ readonly orderly: `0x${string}`;
142
+ /** LogX. */
143
+ readonly logx: `0x${string}`;
144
+ };
145
+ /**
146
+ * Pre-computed token hashes — `keccak256(abi.encodePacked(tokenSymbol))`.
147
+ * The hash maps to the actual ERC-20 address on each chain via
148
+ * `vault.getAllowedToken(tokenHash)`.
149
+ *
150
+ * Note: Orderly canonicalises by symbol (USDC, not "USD Coin").
151
+ */
152
+ declare const TOKEN_HASHES: {
153
+ readonly USDC: `0x${string}`;
154
+ };
155
+ /**
156
+ * Compute Orderly's `accountId` — uniquely identifies a user+broker
157
+ * tuple. Matches the off-chain formula used by the Orderly SDK so
158
+ * deposits + future REST API calls reference the same account.
159
+ *
160
+ * accountId = keccak256(abi.encode(user, brokerHash))
161
+ *
162
+ * Note `abi.encode` (not `encodePacked`) — uses 32-byte left-padding.
163
+ */
164
+ declare function computeAccountId(user: Address, brokerHash: Hex): Hex;
165
+ /**
166
+ * Minimal Orderly Vault ABI — just the functions PAFI needs for
167
+ * Scenario 3 (perp deposit). Full ABI is on Orderly's docs site.
168
+ */
169
+ declare const ORDERLY_VAULT_ABI: readonly [{
170
+ readonly type: "function";
171
+ readonly name: "deposit";
172
+ readonly stateMutability: "payable";
173
+ readonly inputs: readonly [{
174
+ readonly name: "data";
175
+ readonly type: "tuple";
176
+ readonly components: readonly [{
177
+ readonly name: "accountId";
178
+ readonly type: "bytes32";
179
+ }, {
180
+ readonly name: "brokerHash";
181
+ readonly type: "bytes32";
182
+ }, {
183
+ readonly name: "tokenHash";
184
+ readonly type: "bytes32";
185
+ }, {
186
+ readonly name: "tokenAmount";
187
+ readonly type: "uint128";
188
+ }];
189
+ }];
190
+ readonly outputs: readonly [];
191
+ }, {
192
+ readonly type: "function";
193
+ readonly name: "getDepositFee";
194
+ readonly stateMutability: "view";
195
+ readonly inputs: readonly [{
196
+ readonly name: "user";
197
+ readonly type: "address";
198
+ }, {
199
+ readonly name: "data";
200
+ readonly type: "tuple";
201
+ readonly components: readonly [{
202
+ readonly name: "accountId";
203
+ readonly type: "bytes32";
204
+ }, {
205
+ readonly name: "brokerHash";
206
+ readonly type: "bytes32";
207
+ }, {
208
+ readonly name: "tokenHash";
209
+ readonly type: "bytes32";
210
+ }, {
211
+ readonly name: "tokenAmount";
212
+ readonly type: "uint128";
213
+ }];
214
+ }];
215
+ readonly outputs: readonly [{
216
+ readonly name: "";
217
+ readonly type: "uint256";
218
+ }];
219
+ }, {
220
+ readonly type: "function";
221
+ readonly name: "getAllowedBroker";
222
+ readonly stateMutability: "view";
223
+ readonly inputs: readonly [{
224
+ readonly name: "brokerHash";
225
+ readonly type: "bytes32";
226
+ }];
227
+ readonly outputs: readonly [{
228
+ readonly name: "";
229
+ readonly type: "bool";
230
+ }];
231
+ }, {
232
+ readonly type: "function";
233
+ readonly name: "getAllowedToken";
234
+ readonly stateMutability: "view";
235
+ readonly inputs: readonly [{
236
+ readonly name: "tokenHash";
237
+ readonly type: "bytes32";
238
+ }];
239
+ readonly outputs: readonly [{
240
+ readonly name: "";
241
+ readonly type: "address";
242
+ }];
243
+ }];
244
+ /** Struct mirror of `IOrderlyVault.VaultDepositFE` for type-safe builders. */
245
+ interface VaultDepositFE {
246
+ accountId: Hex;
247
+ brokerHash: Hex;
248
+ tokenHash: Hex;
249
+ /** uint128 — USDC has 6 decimals. */
250
+ tokenAmount: bigint;
251
+ }
252
+
253
+ /**
254
+ * v1.5 — Scenario 3: deposit USDC from the user's wallet into the
255
+ * Orderly perp Vault on Base mainnet.
256
+ *
257
+ * Builds a `PartialUserOperation` packaging the 2 inner calls:
258
+ *
259
+ * 1. `USDC.approve(orderlyVault, amount)` — let the Vault pull USDC
260
+ * 2. `OrderlyVault.deposit{value: layerZeroFee}(VaultDepositFE)` —
261
+ * transfer USDC into the Vault + emit a LayerZero message that
262
+ * credits the user's perp account on the Orderly chain
263
+ *
264
+ * ## ⚠️ Native ETH constraint
265
+ *
266
+ * Coinbase Paymaster sponsors GAS, **not `msg.value`**. The LayerZero
267
+ * cross-chain fee MUST come from the user's own native ETH balance on
268
+ * Base — even when the rest of the UserOp is sponsored.
269
+ *
270
+ * Quote the fee BEFORE calling this builder via:
271
+ *
272
+ * const fee = await client.readContract({
273
+ * address: orderlyVault,
274
+ * abi: ORDERLY_VAULT_ABI,
275
+ * functionName: 'getDepositFee',
276
+ * args: [user, depositData],
277
+ * });
278
+ *
279
+ * If `user.eth < fee`, surface this error to the FE so the user can
280
+ * top up before retrying — the Vault `deposit{value: 0}` call will
281
+ * revert otherwise.
282
+ *
283
+ * ## Why no PT/USDC fee deduction?
284
+ *
285
+ * Unlike Scenario 1/2/4 which deduct an operator fee in PT/USDC inside
286
+ * the batch, perp deposit doesn't append a fee transfer because:
287
+ *
288
+ * - User is paying Orderly's LayerZero fee directly via `msg.value`
289
+ * - There's no PAFI-specific operator cost on top — Orderly handles
290
+ * the off-chain accounting once the LayerZero message lands
291
+ *
292
+ * If we want to charge a PAFI service fee on top later, append a
293
+ * `USDC.transfer(feeRecipient, fee)` op — same pattern as the swap
294
+ * builder.
295
+ */
296
+ interface BuildPerpDepositWithGasDeductionParams {
297
+ /** User EOA (will be `msg.sender` via EIP-7702 delegation). */
298
+ userAddress: Address;
299
+ /** ERC-4337 account nonce — fetched from EntryPoint by the caller. */
300
+ aaNonce: bigint;
301
+ /** Chain ID for Orderly Vault address resolution. */
302
+ chainId: number;
303
+ /**
304
+ * Override Orderly Vault address (e.g. for fork tests). Defaults to
305
+ * `ORDERLY_VAULT_ADDRESSES[chainId]`.
306
+ */
307
+ vaultAddress?: Address;
308
+ /**
309
+ * USDC ERC-20 address — the actual token Orderly accepts. Caller
310
+ * resolves this via `vault.getAllowedToken(TOKEN_HASHES.USDC)` so we
311
+ * don't hardcode the wrong USDC variant (native vs bridged).
312
+ */
313
+ usdcAddress: Address;
314
+ /** USDC amount to deposit (uint128, 6 decimals). */
315
+ amount: bigint;
316
+ /**
317
+ * Pre-built `VaultDepositFE` struct — caller computes accountId via
318
+ * `computeAccountId(user, brokerHash)` and supplies tokenHash.
319
+ */
320
+ depositData: VaultDepositFE;
321
+ /**
322
+ * LayerZero fee in wei — from `vault.getDepositFee(user, data)`.
323
+ * Becomes the `msg.value` on the `deposit()` call. User MUST hold
324
+ * ≥ this much native ETH or the call reverts.
325
+ */
326
+ layerZeroFee: bigint;
327
+ gasLimits?: {
328
+ callGasLimit?: bigint;
329
+ verificationGasLimit?: bigint;
330
+ preVerificationGas?: bigint;
331
+ };
332
+ }
333
+ /**
334
+ * Build an unsigned UserOp for Scenario 3. Returns a
335
+ * `PartialUserOperation` — caller attaches paymaster sponsorship for
336
+ * gas + the user's UserOp-hash signature, then submits to the Bundler.
337
+ */
338
+ declare function buildPerpDepositWithGasDeduction(params: BuildPerpDepositWithGasDeductionParams): PartialUserOperation;
339
+
90
340
  /**
91
341
  * Build an ERC-20 `transfer(to, amount)` operation. Used inside a batch
92
342
  * to move fee tokens from the user to the fee recipient atomically with
@@ -631,21 +881,18 @@ declare const POINT_TOKEN_ABI: readonly [{
631
881
  *
632
882
  * ## Status
633
883
  *
634
- * Per-chain addresses are **still placeholder** (`0x...DE01` / `DE02`)
635
- * pending the SC team's Phase B delivery. When Coinbase publishes a
636
- * canonical BatchExecutor, or PAFI deploys its own and publishes the
637
- * address, swap the constants below callers already import from here
638
- * so no wiring changes.
884
+ * Base mainnet: points at **Coinbase Smart Wallet v2**
885
+ * (`0x7702cb554e6bFb442cb743A7dF23154544a7176C`). Coinbase publishes
886
+ * this as the canonical EIP-7702 delegation target on Base — every
887
+ * user that wants gas sponsorship via Coinbase Paymaster delegates to
888
+ * this single contract. One contract, all issuers.
639
889
  *
640
- * The ABI (`execute(Call[])`) itself is real and stable it lives
641
- * under `../../userop/batchExecute.ts` and is re-exported below so
642
- * consumers can grab both ABI + address from one import path.
890
+ * Base Sepolia: placeholder; Sepolia is not in active use for PAFI.
643
891
  *
644
- * ## Why checksum with DEAD0001 / DEAD0002 suffix
645
- *
646
- * The placeholder pattern makes the fact-of-mockness obvious in logs
647
- * and block explorers. A request targeting `0x...DE01` is impossible
648
- * to confuse with a production contract.
892
+ * The ABI (`execute(Call[])`) is exported from
893
+ * `../../userop/batchExecute.ts` and works against the Coinbase
894
+ * contract without change Coinbase Smart Wallet v2 implements the
895
+ * same call-array signature we already use.
649
896
  */
650
897
  declare const BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA: Address;
651
898
  declare const BATCH_EXECUTOR_ADDRESS_BASE_MAINNET: Address;
@@ -653,30 +900,28 @@ declare const BATCH_EXECUTOR_ADDRESS_BASE_MAINNET: Address;
653
900
  /**
654
901
  * Per-chain deployed contract addresses — v1.4 flow.
655
902
  *
656
- * ## Status (2026-04-21)
903
+ * ## Status (2026-04-22)
904
+ *
905
+ * Base mainnet (8453): **all real**. BatchExecutor now points at the
906
+ * canonical Coinbase Smart Wallet v2 contract which PAFI reuses as the
907
+ * EIP-7702 delegation target (no per-app deploy required — one
908
+ * contract, every issuer).
657
909
  *
658
- * Base mainnet (8453): all SC-delivered and real, EXCEPT `batchExecutor`
659
- * which is still a `0x...DE02` placeholder pending the Phase B delivery.
660
910
  * Base Sepolia (84532): entire row is placeholder — not in active use.
661
911
  *
662
912
  * ## What lives where
663
913
  *
664
914
  * pointToken — live POINT instance (clone of PointToken impl)
665
- * batchExecutor — EIP-7702 delegation target (PLACEHOLDER)
915
+ * batchExecutor — EIP-7702 delegation target (Coinbase Smart Wallet v2)
666
916
  * usdt — MockERC20 used by Uniswap pools
667
917
  * issuerRegistry — registry of all issuers on this chain
668
918
  * mintingOracle — per-issuer mint cap enforcer
919
+ * pafiHook — Uniswap V4 hook enforcing the 10% PT→USDT fee
669
920
  *
670
921
  * PointTokenFactory + PointToken implementation addresses live in
671
922
  * separate exports below — they're only needed at provisioning /
672
923
  * observability time, not in the hot mint/burn path, so excluded from
673
924
  * the per-chain bundle.
674
- *
675
- * ## Swap workflow when BatchExecutor lands
676
- *
677
- * 1. Replace `batchExecutor` placeholder with real address
678
- * 2. Structure / imports don't change — callers are stable
679
- * 3. Bump core to next beta and update release notes
680
925
  */
681
926
  interface ContractAddresses {
682
927
  pointToken: Address;
@@ -684,6 +929,13 @@ interface ContractAddresses {
684
929
  usdt: Address;
685
930
  issuerRegistry: Address;
686
931
  mintingOracle: Address;
932
+ /**
933
+ * Uniswap V4 hook that enforces the 10% fee on PT→USDT swaps
934
+ * (USDT→PT is free). FE reads this to build `PoolKey.hooks` when
935
+ * constructing a swap; quoters + routers need it to resolve the
936
+ * correct pool.
937
+ */
938
+ pafiHook: Address;
687
939
  }
688
940
  declare const CONTRACT_ADDRESSES: Record<number, ContractAddresses>;
689
941
  /**
@@ -1041,4 +1293,4 @@ declare class PafiSDK {
1041
1293
  signLoginMessage(message: string): Promise<Hex>;
1042
1294
  }
1043
1295
 
1044
- export { ApiError, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BestQuote, type BuildPartialUserOpParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, LoginMessageParams, MintRequest, type ModalOpenOptions, Operation, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, POINT_TOKEN_ABI as POINT_TOKEN_V2_ABI, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, PartialUserOperation, type PaymasterConfig, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, _resetPaymasterConfigForTests, assembleUserOperation, buildPartialUserOperation, burnRequestTypes, checkEthAndBranch, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, webPopupAdapter };
1296
+ export { ApiError, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, BestQuote, type BuildPartialUserOpParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, Operation, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, POINT_TOKEN_ABI as POINT_TOKEN_V2_ABI, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, PartialUserOperation, type PaymasterConfig, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildPartialUserOperation, buildPerpDepositWithGasDeduction, burnRequestTypes, checkEthAndBranch, computeAccountId, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, webPopupAdapter };