@zkp2p/sdk 0.1.0 → 0.1.1

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 CHANGED
@@ -1,30 +1,36 @@
1
1
  # @zkp2p/sdk
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@zkp2p/sdk.svg)](https://www.npmjs.com/package/@zkp2p/sdk)
4
+ [![npm types](https://img.shields.io/npm/types/@zkp2p/sdk.svg)](https://www.npmjs.com/package/@zkp2p/sdk)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
6
 
6
- TypeScript SDK for ZKP2P liquidity providers and integrators.
7
+ Stable TypeScript SDK for trustless fiat-to-crypto on Base. ZKP2P combines escrowed on-chain settlement, TLS attestations for payment verification, and API/indexer helpers so makers, takers, wallets, and embedded ramps can ship production-grade fiat liquidity flows without building their own contract or indexing stack.
7
8
 
8
- Current version: `0.1.0-rc.14`. Includes V1/V2 contract routing, referral-fee intent signaling, signed oracle spreads, EscrowV2 batch currency-config updates, Pyth oracle feeds, on-chain oracle feed validation, and indexer helpers.
9
+ Current version: `0.1.0`
10
+
11
+ ## Why This SDK
12
+
13
+ - Build maker, taker, vault, and embedded ramp flows from one client.
14
+ - Read live protocol state directly from ProtocolViewer instead of waiting on indexer sync.
15
+ - Route cleanly across legacy and V2 contract stacks without app-level ABI branching.
16
+ - Use prepareable write methods for smart accounts, relayers, gas estimation, and batching.
17
+ - Keep advanced analytics, fund activity history, and vault stats behind `client.indexer.*`.
9
18
 
10
19
  ## Who This Is For
11
20
 
12
- - maker/liquidity-provider applications
13
- - internal client apps (web, extension)
14
- - tools that need contract-safe deposit/intent operations
15
- - dashboard/reporting services that query `client.indexer.*`
21
+ - maker and liquidity-provider applications
22
+ - wallets and embedded onramp/offramp products
23
+ - backends that need contract-safe deposit and intent operations
24
+ - dashboards and analytics services that query `client.indexer.*`
25
+ - React apps that want first-party hooks instead of writing transaction glue
16
26
 
17
- ## Core Capabilities
27
+ ## Architecture
18
28
 
19
- | Area | Highlights |
20
- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
21
- | Deposit lifecycle | `createDeposit`, `addFunds`, `removeFunds`, `withdrawDeposit` |
22
- | Intent lifecycle | `signalIntent`, `fulfillIntent`, `cancelIntent`, `releaseFundsToPayer` |
23
- | Vault/DRM | `createRateManager`, `setRateManager`, `clearRateManager`, `setVaultFee`, `setVaultMinRate`, `setVaultMinRatesBatch`, `setVaultConfig` |
24
- | Oracle config | `setOracleRateConfig`, `setOracleRateConfigBatch`, `updateCurrencyConfigBatch`, `deactivateCurrenciesBatch`, `validateOracleFeedsOnChain` |
25
- | RPC-first reads | `getDeposits`, `getDeposit`, `getIntents`, `getIntent` |
26
- | Indexer services | `client.indexer.*`, `IndexerRateManagerService`, `getIntentFulfillmentAmounts` |
27
- | React hooks | `@zkp2p/sdk/react` hooks for deposit/intent/vault operations |
29
+ - RPC-first reads: primary reads use ProtocolViewer and on-chain fallbacks, so `getDeposits()`, `getDeposit()`, `getIntents()`, `getIntent()`, and the `getPv*` methods are not blocked on indexer lag.
30
+ - Indexer for history and filtering: use `client.indexer.*` for pagination, historical volumes, fund activities, daily snapshots, and vault analytics.
31
+ - Dual-stack routing: the client resolves V1/V2 escrow and orchestrator contexts at runtime. `preferV2ByDefault` lets you override the rollout baseline when both stacks are available.
32
+ - Modular internals: stable `0.1.0` extracted intent, vault, and ProtocolViewer logic into `IntentOperations`, `VaultOperations`, and `ProtocolViewerReader`, keeping `Zkp2pClient` focused on orchestration.
33
+ - App-level rollout control: the SDK is capability-based. Product gating and phase flags belong in your app layer, not inside transaction helpers.
28
34
 
29
35
  ## Installation
30
36
 
@@ -33,7 +39,13 @@ npm install @zkp2p/sdk viem
33
39
  # or
34
40
  pnpm add @zkp2p/sdk viem
35
41
  # or
36
- yarn add @zkp2p/sdk viem
42
+ bun add @zkp2p/sdk viem
43
+ ```
44
+
45
+ If you use React hooks, add React as well:
46
+
47
+ ```bash
48
+ pnpm add react
37
49
  ```
38
50
 
39
51
  ## Quick Start
@@ -51,213 +63,462 @@ const walletClient = createWalletClient({
51
63
  const client = new Zkp2pClient({
52
64
  walletClient,
53
65
  chainId: base.id,
54
- runtimeEnv: 'staging', // 'production' | 'staging'
55
- indexerApiKey: 'YOUR_INDEXER_API_KEY',
56
66
  });
57
67
  ```
58
68
 
59
- ## Routing Defaults
60
-
61
- - SDK methods are capability-based and do not enforce product rollout flags.
62
- - SDK defaults to V2 routing when V2 contracts are deployed, with legacy fallback when not.
63
- - Apply phase/rollout gating in app layers above the SDK (web/extension/backend).
69
+ `runtimeEnv` defaults to `'production'`. Use `'preproduction'` or `'staging'` when you want to point the SDK at those deployments.
64
70
 
65
- ## Authentication
71
+ ## Environment and Authentication
66
72
 
67
- - `apiKey` is optional and is forwarded to curator API endpoints when provided.
68
- - `authorizationToken` and `getAuthorizationToken` support optional bearer auth.
69
- - `indexerApiKey` adds `x-api-key` for indexer proxy auth.
73
+ - Supported runtime environments: `'production'`, `'preproduction'`, `'staging'`
74
+ - `runtimeEnv` default: `'production'`
75
+ - `apiKey`: optional curator API key for authenticated service endpoints
76
+ - `authorizationToken` / `getAuthorizationToken`: optional bearer auth for hybrid client and indexer flows
77
+ - `indexerApiKey`: optional `x-api-key` for indexer proxy auth
78
+ - `indexerUrl` and `baseApiUrl`: override defaults when you are targeting custom deployments
79
+ - `preferV2ByDefault`: default to V2 contracts when both legacy and V2 are live
70
80
 
71
- If you provide both bearer and indexer API key, both headers are sent.
81
+ Indexer defaults by environment:
72
82
 
73
- ## Indexer Defaults
83
+ - `production`: `https://indexer.zkp2p.xyz/v1/graphql`
84
+ - `preproduction`: `https://indexer-preprod.zkp2p.xyz/v1/graphql`
85
+ - `staging`: `https://indexer-staging.zkp2p.xyz/v1/graphql`
74
86
 
75
- - Production: `https://indexer.zkp2p.xyz/v1/graphql`
76
- - Preproduction: `https://indexer-preprod.zkp2p.xyz/v1/graphql`
77
- - Staging: `https://indexer-staging.zkp2p.xyz/v1/graphql`
78
-
79
- ## Common Operations
87
+ ## Core Capabilities
80
88
 
81
- ### Create a Deposit
89
+ | Area | Stable surface |
90
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | Deposits | `createDeposit`, `addFunds`, `removeFunds`, `withdrawDeposit`, `ensureAllowance`, `setAcceptingIntents`, `setIntentRange`, `setCurrencyMinRate`, `setRetainOnEmpty` |
92
+ | Payment methods and currencies | `addPaymentMethods`, `removePaymentMethod`, `setPaymentMethodActive`, `addCurrencies`, `removeCurrency`, `deactivateCurrency`, `pruneExpiredIntents` |
93
+ | Intents | `signalIntent`, `fulfillIntent`, `cancelIntent`, `releaseFundsToPayer`, `getFulfillIntentInputs` |
94
+ | Prepared transactions | `client.prepareCreateDeposit(...)`, `client.signalIntent.prepare(...)`, `client.fulfillIntent.prepare(...)`, `client.setVaultFee.prepare(...)`, and equivalent prepare flows across the rest of the prepareable write surface |
95
+ | Payee and quote APIs | `registerPayeeDetails`, `resolvePayeeHash`, `getQuote`, `getTakerTier` |
96
+ | Delegation and hooks | `setDelegate`, `removeDelegate`, `setRateManager`, `clearRateManager`, `setDepositRateManager`, `clearDepositRateManager`, `setDepositPreIntentHook`, `setDepositWhitelistHook` |
97
+ | Vault / DRM | `createRateManager`, `setVaultMinRate`, `setVaultMinRatesBatch`, `setVaultFee`, `setVaultConfig`, `getDepositRateManager`, `getManagerFee`, `getEffectiveRate` |
98
+ | Oracle config | `setOracleRateConfig`, `setOracleRateConfigBatch`, `removeOracleRateConfig`, `updateCurrencyConfigBatch`, `deactivateCurrenciesBatch`, `supportsInlineOracleRateConfig`, `validateOracleFeedsOnChain` |
99
+ | RPC reads | `getDeposits`, `getDeposit`, `getDepositsById`, `getIntents`, `getIntent`, `getPvDepositById`, `getPvDepositsFromIds`, `getPvAccountDeposits`, `getPvAccountIntents`, `getPvIntent` |
100
+ | Indexer | `client.indexer.getDeposits`, `getDepositsWithRelations`, `getDepositById`, `getIntentFulfillmentAmounts`, `getDepositFundActivities`, `getDepositDailySnapshots`, `getRateManagers`, `getRateManagerDetail`, `getManagerDailySnapshots` |
101
+ | React hooks | `@zkp2p/sdk/react` exports hooks for deposits, intents, delegation, vaults, payment methods, and taker tier |
102
+ | Attribution | ERC-8021 helpers like `sendTransactionWithAttribution`, `encodeWithAttribution`, and `txOverrides.referrer` support |
103
+
104
+ ## Create a Deposit
82
105
 
83
106
  ```ts
84
107
  import { Currency } from '@zkp2p/sdk';
85
108
 
86
- await client.createDeposit({
87
- token: '0xUSDC_ADDRESS',
109
+ const result = await client.createDeposit({
110
+ token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
88
111
  amount: 10_000_000n,
89
112
  intentAmountRange: { min: 100_000n, max: 5_000_000n },
90
113
  processorNames: ['wise'],
91
114
  depositData: [{ email: 'maker@example.com' }],
92
115
  conversionRates: [[{ currency: Currency.USD, conversionRate: '1020000000000000000' }]],
93
116
  });
117
+
118
+ console.log(result.hash);
119
+ console.log(result.depositDetails);
94
120
  ```
95
121
 
96
- ### Configure Oracle Spread (EscrowV2)
122
+ If you do not pass `payeeDetailsHashes`, `createDeposit()` can register the payee details for you. If you want to pre-register or reuse hashes across deposits, use `registerPayeeDetails()` first.
123
+
124
+ ## Payee Registration, Quotes, and Taker Tier
97
125
 
98
126
  ```ts
99
- await client.setOracleRateConfig({
100
- depositId: 42n,
101
- paymentMethodHash: '0x...',
102
- currencyHash: '0x...',
103
- config: {
104
- adapter: '0x...',
105
- adapterConfig: '0x',
106
- spreadBps: -50, // signed int16 bps: -0.50% below market
107
- maxStaleness: 180,
108
- },
127
+ import { resolvePaymentMethodHash } from '@zkp2p/sdk';
128
+
129
+ const { hashedOnchainIds } = await client.registerPayeeDetails({
130
+ processorNames: ['wise'],
131
+ depositData: [{ email: 'maker@example.com' }],
109
132
  });
110
- ```
111
133
 
112
- ### Validate Oracle Feed Availability
134
+ const quote = await client.getQuote({
135
+ paymentPlatforms: ['wise'],
136
+ fiatCurrency: 'USD',
137
+ user: '0xBuyer',
138
+ recipient: '0xBuyer',
139
+ destinationChainId: 8453,
140
+ destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
141
+ amount: '250',
142
+ isExactFiat: true,
143
+ });
113
144
 
114
- ```ts
115
- import { validateOracleFeedsOnChain } from '@zkp2p/sdk';
145
+ const takerTier = await client.getTakerTier({
146
+ owner: '0xBuyer',
147
+ chainId: 8453,
148
+ });
116
149
 
117
- // Validate all Chainlink + Pyth feeds on Base via multicall
118
- const availableCurrencies = await validateOracleFeedsOnChain(publicClient);
119
- // Set<CurrencyType> only currencies whose feeds responded successfully
150
+ const payeeHash = await client.resolvePayeeHash(
151
+ 42n,
152
+ resolvePaymentMethodHash('wise', { env: 'production' }),
153
+ );
120
154
  ```
121
155
 
122
- ### Signal an Intent with Referral Fees
156
+ `getQuote()` returns available liquidity plus payee details when authenticated. `getTakerTier()` returns limits and cooldown data for taker UX.
157
+
158
+ ## Signal, Fulfill, and Release Intents
123
159
 
124
160
  ```ts
125
- await client.signalIntent({
161
+ const intentHash = await client.signalIntent({
126
162
  depositId: 42n,
127
163
  amount: 250_000n,
128
- to: '0xBuyer',
129
- paymentMethod: 'wise',
164
+ toAddress: '0xBuyer',
165
+ processorName: 'wise',
166
+ payeeDetails: '0xPAYEE_DETAILS_HASH',
130
167
  fiatCurrencyCode: 'USD',
131
- conversionRate: '1020000000000000000',
168
+ conversionRate: 1_020_000_000_000_000_000n,
132
169
  referralFees: [
133
170
  { recipient: '0xPlatformFeeRecipient', fee: 2_500n },
134
171
  { recipient: '0xPartnerFeeRecipient', fee: 1_250n },
135
172
  ],
136
173
  });
174
+
175
+ await client.fulfillIntent({
176
+ intentHash,
177
+ proof: zkTlsProofJson,
178
+ });
179
+
180
+ await client.releaseFundsToPayer({
181
+ intentHash,
182
+ });
137
183
  ```
138
184
 
139
- Legacy `referrer` / `referrerFee` fields are still accepted as a backwards-compatible fallback, but new integrations should send `referralFees[]`.
185
+ For OrchestratorV2 flows, prefer `referralFees[]`. Legacy `referrer` and `referrerFee` fields remain available for compatibility.
186
+
187
+ ## Prepared Transactions
140
188
 
141
- ### Vault / DRM Operations
189
+ Most write methods expose `.prepare(params)` and return a `PreparedTransaction` without sending the transaction. `createDeposit()` is the main exception and uses `client.prepareCreateDeposit(params)`, which returns `{ depositDetails, prepared }`. This is the stable pattern for smart accounts, batched user-ops, relayers, gas estimation, and custom senders.
142
190
 
143
191
  ```ts
144
- // Create a vault (rate manager)
145
- await client.createRateManager({
192
+ const prepared = await client.signalIntent.prepare({
193
+ depositId: 42n,
194
+ amount: 250_000n,
195
+ toAddress: '0xBuyer',
196
+ processorName: 'wise',
197
+ payeeDetails: '0xPAYEE_DETAILS_HASH',
198
+ fiatCurrencyCode: 'USD',
199
+ conversionRate: 1_020_000_000_000_000_000n,
200
+ });
201
+
202
+ console.log(prepared);
203
+ // { to, data, value, chainId }
204
+ ```
205
+
206
+ React hooks mirror this where useful. For example, `useSignalIntent()` returns `prepareSignalIntent()` and `prepared`.
207
+
208
+ ## Error Handling
209
+
210
+ The SDK exports a normalized error model:
211
+
212
+ - `ZKP2PError`
213
+ - `ValidationError`
214
+ - `NetworkError`
215
+ - `APIError`
216
+ - `ContractError`
217
+ - `ErrorCode`
218
+
219
+ ```ts
220
+ import { APIError, ErrorCode, ValidationError, ZKP2PError } from '@zkp2p/sdk';
221
+
222
+ try {
223
+ await client.createDeposit({
224
+ token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
225
+ amount: 10_000_000n,
226
+ intentAmountRange: { min: 100_000n, max: 5_000_000n },
227
+ processorNames: ['wise'],
228
+ depositData: [{ email: 'maker@example.com' }],
229
+ conversionRates: [[{ currency: 'USD', conversionRate: '1020000000000000000' }]],
230
+ });
231
+ } catch (error) {
232
+ if (error instanceof ValidationError) {
233
+ console.error('Invalid field:', error.field, error.message);
234
+ } else if (error instanceof APIError) {
235
+ console.error('HTTP status:', error.status, error.message);
236
+ } else if (error instanceof ZKP2PError) {
237
+ console.error('SDK error:', error.code ?? ErrorCode.UNKNOWN, error.details);
238
+ } else {
239
+ console.error('Unknown error:', error);
240
+ }
241
+ }
242
+ ```
243
+
244
+ You should still handle generic `Error` for lower-level transport or wallet failures that originate outside the normalized SDK wrappers.
245
+
246
+ ## Oracle Configuration
247
+
248
+ The SDK exports Chainlink and Pyth adapter helpers, plus a Chainlink-first `getSpreadOracleConfig()` resolver for bundled feed metadata.
249
+
250
+ ```ts
251
+ import {
252
+ getSpreadOracleConfig,
253
+ resolveFiatCurrencyBytes32,
254
+ resolvePaymentMethodHash,
255
+ validateOracleFeedsOnChain,
256
+ } from '@zkp2p/sdk';
257
+
258
+ const paymentMethodHash = resolvePaymentMethodHash('wise', { env: 'production' });
259
+ const currencyHash = resolveFiatCurrencyBytes32('USD');
260
+ const oracle = getSpreadOracleConfig('USD');
261
+
262
+ if (!oracle) throw new Error('No bundled oracle config for USD');
263
+
264
+ await client.setOracleRateConfig({
265
+ depositId: 42n,
266
+ paymentMethodHash,
267
+ currencyHash,
268
+ config: {
269
+ adapter: oracle.adapter,
270
+ adapterConfig: oracle.adapterConfig,
271
+ spreadBps: -50,
272
+ maxStaleness: oracle.maxStaleness,
273
+ },
274
+ });
275
+
276
+ await client.updateCurrencyConfigBatch({
277
+ depositId: 42n,
278
+ paymentMethods: [paymentMethodHash],
279
+ updates: [
280
+ [
281
+ {
282
+ code: currencyHash,
283
+ minConversionRate: 1_020_000_000_000_000_000n,
284
+ updateOracle: true,
285
+ oracleRateConfig: {
286
+ adapter: oracle.adapter,
287
+ adapterConfig: oracle.adapterConfig,
288
+ spreadBps: -50,
289
+ maxStaleness: oracle.maxStaleness,
290
+ },
291
+ },
292
+ ],
293
+ ],
294
+ });
295
+
296
+ const availableFeeds = await validateOracleFeedsOnChain(client.publicClient);
297
+ console.log([...availableFeeds].sort());
298
+ ```
299
+
300
+ Useful helpers and methods in this area:
301
+
302
+ - `CHAINLINK_ORACLE_ADAPTER`
303
+ - `PYTH_ORACLE_ADAPTER`
304
+ - `encodeSpreadOracleAdapterConfig`
305
+ - `encodePythAdapterConfig`
306
+ - `getSpreadOracleConfig`
307
+ - `setOracleRateConfigBatch`
308
+ - `updateCurrencyConfigBatch`
309
+ - `deactivateCurrenciesBatch`
310
+
311
+ ## Delegation and Hooks
312
+
313
+ ```ts
314
+ await client.setDelegate({
315
+ depositId: 42n,
316
+ delegate: '0xDelegate',
317
+ });
318
+
319
+ await client.setRateManager({
320
+ depositId: 42n,
321
+ rateManagerAddress: '0xVaultAddress',
322
+ rateManagerId: '0xVaultId',
323
+ });
324
+
325
+ await client.setDepositPreIntentHook({
326
+ depositId: 42n,
327
+ preIntentHook: '0xHookAddress',
328
+ });
329
+
330
+ await client.setDepositWhitelistHook({
331
+ depositId: 42n,
332
+ whitelistHook: '0xHookAddress',
333
+ });
334
+ ```
335
+
336
+ Use `removeDelegate()` and `clearRateManager()` to unwind delegation. Phase-4 hook methods are available when the target deployment supports them.
337
+
338
+ ## Vault / DRM
339
+
340
+ ```ts
341
+ const createHash = await client.createRateManager({
146
342
  config: {
147
343
  manager: '0xManager',
148
344
  feeRecipient: '0xFeeRecipient',
149
345
  maxFee: 50_000_000_000_000_000n,
150
346
  fee: 10_000_000_000_000_000n,
151
347
  name: 'My Vault',
152
- uri: 'ipfs://...',
348
+ uri: 'ipfs://vault-metadata',
153
349
  },
154
350
  });
155
351
 
156
- // Delegate a deposit to a vault
157
- await client.setRateManager({
158
- depositId: 42n,
159
- rateManagerAddress: '0xVaultAddress',
352
+ await client.setVaultFee({
353
+ rateManagerId: '0xVaultId',
354
+ newFee: 20_000_000_000_000_000n,
355
+ });
356
+
357
+ await client.setVaultMinRate({
160
358
  rateManagerId: '0xVaultId',
359
+ paymentMethodHash: resolvePaymentMethodHash('wise', { env: 'production' }),
360
+ currencyHash: resolveFiatCurrencyBytes32('USD'),
361
+ rate: 1_010_000_000_000_000_000n,
161
362
  });
162
363
 
163
- // Update vault fee and config
164
- await client.setVaultFee({ rateManagerId: '0xVaultId', newFee: 20_000_000_000_000_000n });
165
364
  await client.setVaultConfig({
166
365
  rateManagerId: '0xVaultId',
167
366
  newManager: '0xNewManager',
168
367
  newFeeRecipient: '0xNewFeeRecipient',
169
368
  newName: 'Updated Vault',
170
- newUri: 'ipfs://updated',
369
+ newUri: 'ipfs://updated-vault-metadata',
171
370
  });
172
371
  ```
173
372
 
174
- ### Query Indexer Data
373
+ ## Protocol Viewer (RPC) Reads
374
+
375
+ ProtocolViewer methods bypass indexer lag and are the right default for primary user-facing reads.
376
+
377
+ ```ts
378
+ const deposit = await client.getPvDepositById(42n);
379
+ const deposits = await client.getPvDepositsFromIds([42n, 43n]);
380
+ const makerDeposits = await client.getPvAccountDeposits('0xMaker');
381
+ const takerIntents = await client.getPvAccountIntents('0xTaker');
382
+ const intent = await client.getPvIntent('0xIntentHash');
383
+ ```
384
+
385
+ You can also use the convenience wrappers `getDeposits()`, `getDeposit()`, `getIntents()`, and `getIntent()` for common flows.
386
+
387
+ ## Indexer Queries
388
+
389
+ Use the indexer for filtered queries, pagination, fund activity history, snapshots, and vault analytics.
175
390
 
176
391
  ```ts
177
392
  const deposits = await client.indexer.getDeposits(
178
- { status: 'ACTIVE', depositor: '0xYourAddress' },
179
- { limit: 25 },
393
+ { status: 'ACTIVE', depositor: '0xMaker' },
394
+ { limit: 25, orderBy: 'updatedAt', orderDirection: 'desc' },
180
395
  );
181
396
 
182
- const amounts = await client.indexer.getIntentFulfillmentAmounts('0xIntentHash');
183
- // amounts?.releasedAmount, amounts?.takerAmountNetFees
397
+ const depositWithRelations = await client.indexer.getDepositById('8453_0xEscrowAddress_42', {
398
+ includeIntents: true,
399
+ });
400
+
401
+ const fulfillment = await client.indexer.getIntentFulfillmentAmounts('0xIntentHash');
402
+ const fundActivities = await client.indexer.getDepositFundActivities('8453_0xEscrowAddress_42');
403
+ const snapshots = await client.indexer.getDepositDailySnapshots('8453_0xEscrowAddress_42', 30);
404
+
405
+ const managers = await client.indexer.getRateManagers({
406
+ limit: 10,
407
+ orderBy: 'currentDelegatedBalance',
408
+ orderDirection: 'desc',
409
+ });
410
+
411
+ const managerDetail = await client.indexer.getRateManagerDetail('0xVaultId', {
412
+ rateManagerAddress: '0xVaultAddress',
413
+ });
184
414
  ```
185
415
 
416
+ `managerDetail?.aggregate` gives you current delegated balance and filled volume stats alongside recent snapshots and delegation history.
417
+
186
418
  ## React Hooks
187
419
 
420
+ Install React and import hooks from `@zkp2p/sdk/react`. React is an optional peer dependency of the SDK.
421
+
422
+ Most mutation hooks return a named action plus status fields such as `isLoading`, `error`, and `txHash`. Hooks with prepare support expose dedicated `prepare...` helpers, and some of them also store the latest `prepared` transaction in hook state. Every hook exports a matching `Use*Options` type.
423
+
188
424
  ```tsx
189
425
  import {
190
- // Deposit lifecycle
191
426
  useCreateDeposit,
192
- useAddFunds,
193
- useRemoveFunds,
194
- useWithdrawDeposit,
195
- useSetAcceptingIntents,
196
- useSetIntentRange,
197
- useSetCurrencyMinRate,
198
- useSetRetainOnEmpty,
199
-
200
- // Payment method management
201
- useAddPaymentMethods,
202
- useRemovePaymentMethod,
203
- useSetPaymentMethodActive,
204
- useAddCurrencies,
205
- useRemoveCurrency,
206
- useDeactivateCurrency,
207
-
208
- // Intent lifecycle
209
427
  useSignalIntent,
210
- useFulfillIntent,
211
- useReleaseFundsToPayer,
212
- usePruneExpiredIntents,
213
-
214
- // Delegation
215
- useSetDelegate,
216
- useRemoveDelegate,
217
-
218
- // Vault / DRM
219
428
  useCreateVault,
220
429
  useVaultDelegation,
221
- useSetVaultFee,
222
- useSetVaultMinRate,
223
- useSetVaultConfig,
224
-
225
- // Taker tier
226
430
  useGetTakerTier,
227
431
  } from '@zkp2p/sdk/react';
432
+
433
+ const createDeposit = useCreateDeposit({ client });
434
+ const signalIntent = useSignalIntent({ client });
435
+ const createVault = useCreateVault({ client, sendTransaction });
436
+ const vaultDelegation = useVaultDelegation({ client, sendTransaction, sendBatch });
437
+ const takerTier = useGetTakerTier({ client, owner, chainId, autoFetch: true });
228
438
  ```
229
439
 
440
+ Hook groups:
441
+
442
+ - Deposit lifecycle: `useCreateDeposit`, `useAddFunds`, `useRemoveFunds`, `useWithdrawDeposit`, `useSetAcceptingIntents`, `useSetIntentRange`, `useSetCurrencyMinRate`, `useSetRetainOnEmpty`
443
+ - Payment and currency management: `useAddPaymentMethods`, `useRemovePaymentMethod`, `useSetPaymentMethodActive`, `useAddCurrencies`, `useRemoveCurrency`, `useDeactivateCurrency`
444
+ - Intent lifecycle: `useSignalIntent`, `useFulfillIntent`, `useReleaseFundsToPayer`, `usePruneExpiredIntents`
445
+ - Delegation: `useSetDelegate`, `useRemoveDelegate`
446
+ - Vault / DRM: `useCreateVault`, `useVaultDelegation`, `useSetVaultFee`, `useSetVaultMinRate`, `useSetVaultConfig`
447
+ - Taker tier: `useGetTakerTier`, plus `getTierDisplayInfo()` and `getNextTierCap()` helpers
448
+
449
+ `useVaultDelegation()` is the batching-oriented hook. It returns `delegateDeposit`, `delegateDeposits`, `clearDelegation`, and `clearDelegations`.
450
+
230
451
  ## Contracts and Catalog Helpers
231
452
 
232
453
  ```ts
233
454
  import {
234
455
  getContracts,
235
- getRateManagerContracts,
236
456
  getPaymentMethodsCatalog,
457
+ getRateManagerContracts,
237
458
  resolveFiatCurrencyBytes32,
238
459
  resolvePaymentMethodHash,
239
460
  } from '@zkp2p/sdk';
240
461
 
241
- const { addresses } = getContracts(8453, 'staging');
242
- const rateManager = getRateManagerContracts(8453, 'staging');
243
- const catalog = getPaymentMethodsCatalog(8453, 'staging');
462
+ const contracts = getContracts(8453, 'production');
463
+ const rateManagerContracts = getRateManagerContracts(8453, 'production');
464
+ const paymentMethods = getPaymentMethodsCatalog(8453, 'production');
465
+ const usdHash = resolveFiatCurrencyBytes32('USD');
466
+ const wiseHash = resolvePaymentMethodHash('wise', { env: 'production' });
244
467
  ```
245
468
 
469
+ ## Supported Currencies
470
+
471
+ The SDK ships currency metadata for 34 fiat currencies:
472
+
473
+ `AED`, `ARS`, `AUD`, `BRL`, `CAD`, `CHF`, `CNY`, `CZK`, `DKK`, `EUR`, `GBP`, `HKD`, `HUF`, `IDR`, `ILS`, `INR`, `JPY`, `KES`, `MXN`, `MYR`, `NOK`, `NZD`, `PHP`, `PLN`, `RON`, `SAR`, `SEK`, `SGD`, `THB`, `TRY`, `UGX`, `USD`, `VND`, `ZAR`
474
+
246
475
  ## Supported Payment Platforms
247
476
 
248
477
  `wise`, `venmo`, `revolut`, `cashapp`, `mercadopago`, `zelle`, `paypal`, `monzo`, `chime`, `luxon`, `n26`
249
478
 
250
- ## Extension SDK Helpers
479
+ ## Attribution (ERC-8021)
480
+
481
+ The SDK includes builder-code attribution helpers and transaction overrides for partner attribution:
482
+
483
+ ```ts
484
+ const hash = await client.signalIntent({
485
+ depositId: 42n,
486
+ amount: 250_000n,
487
+ toAddress: '0xBuyer',
488
+ processorName: 'wise',
489
+ payeeDetails: '0xPAYEE_DETAILS_HASH',
490
+ fiatCurrencyCode: 'USD',
491
+ conversionRate: 1_020_000_000_000_000_000n,
492
+ txOverrides: {
493
+ referrer: ['my-app', 'campaign-42'],
494
+ },
495
+ });
496
+ ```
497
+
498
+ Lower-level helpers are also exported: `BASE_BUILDER_CODE`, `getAttributionDataSuffix()`, `appendAttributionToCalldata()`, `encodeWithAttribution()`, and `sendTransactionWithAttribution()`.
499
+
500
+ ## TypeDoc API Reference
251
501
 
252
- If you integrate with the Peer extension:
502
+ The package already includes TypeDoc configuration. Generate the full API reference locally with:
503
+
504
+ ```bash
505
+ pnpm --filter @zkp2p/sdk docs
506
+ ```
507
+
508
+ This writes documentation to [`packages/sdk/docs`](./docs) and now includes the React entry point as well as the main SDK and extension surfaces.
509
+
510
+ ## Debug Logging
511
+
512
+ Use `setLogLevel()` when you want verbose SDK logging during local development or integration debugging.
253
513
 
254
514
  ```ts
255
- import { peerExtensionSdk } from '@zkp2p/sdk';
515
+ import { setLogLevel } from '@zkp2p/sdk';
256
516
 
257
- const state = await peerExtensionSdk.getState();
258
- if (state === 'needs_install') peerExtensionSdk.openInstallPage();
517
+ setLogLevel('debug');
259
518
  ```
260
519
 
520
+ Supported log levels: `'error'`, `'info'`, `'debug'`
521
+
261
522
  ## Development
262
523
 
263
524
  ```bash
@@ -266,10 +527,12 @@ pnpm build
266
527
  pnpm test
267
528
  pnpm typecheck
268
529
  pnpm lint
530
+ pnpm docs
269
531
  ```
270
532
 
271
533
  ## Links
272
534
 
273
535
  - NPM: https://www.npmjs.com/package/@zkp2p/sdk
274
- - Monorepo: https://github.com/zkp2p/zkp2p-clients
275
536
  - Docs: https://docs.zkp2p.xyz
537
+ - Monorepo: https://github.com/zkp2p/zkp2p-clients
538
+ - TypeDoc output: [`packages/sdk/docs`](./docs)
@@ -121,6 +121,9 @@ function pickAbi(source, names) {
121
121
  for (const name of names) {
122
122
  const candidate = source[name];
123
123
  if (Array.isArray(candidate)) return candidate;
124
+ if (candidate && typeof candidate === "object" && Array.isArray(candidate.default)) {
125
+ return candidate.default;
126
+ }
124
127
  }
125
128
  return void 0;
126
129
  }
@@ -577,5 +580,5 @@ function enrichPvIntentView(view, chainId, env = "production") {
577
580
  }
578
581
 
579
582
  export { HISTORICAL_ESCROW_ADDRESSES, asciiToBytes32, enrichPvDepositView, enrichPvIntentView, ensureBytes32, getContracts, getGatingServiceAddress, getPaymentMethodsCatalog, getRateManagerContracts, parseBigIntLike, parseDepositView, parseIntentView, resolveFiatCurrencyBytes32, resolvePaymentMethodHash, resolvePaymentMethodHashFromCatalog, resolvePaymentMethodNameFromHash };
580
- //# sourceMappingURL=chunk-JH74HXTS.mjs.map
581
- //# sourceMappingURL=chunk-JH74HXTS.mjs.map
583
+ //# sourceMappingURL=chunk-YQ7VL7ZJ.mjs.map
584
+ //# sourceMappingURL=chunk-YQ7VL7ZJ.mjs.map