@zkp2p/sdk 0.1.0 → 0.2.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/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 against the upgraded escrow/orchestrator stack while preserving historical deposit visibility.
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
+ - Current-stack routing: the client resolves against the upgraded escrow and orchestrator contracts by default, while keeping historical escrow lookups available for reads and legacy deposits.
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,461 @@ 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
70
79
 
71
- If you provide both bearer and indexer API key, both headers are sent.
80
+ Indexer defaults by environment:
72
81
 
73
- ## Indexer Defaults
82
+ - `production`: `https://indexer.zkp2p.xyz/v1/graphql`
83
+ - `preproduction`: `https://indexer-preprod.zkp2p.xyz/v1/graphql`
84
+ - `staging`: `https://indexer-staging.zkp2p.xyz/v1/graphql`
74
85
 
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
86
+ ## Core Capabilities
80
87
 
81
- ### Create a Deposit
88
+ | Area | Stable surface |
89
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90
+ | Deposits | `createDeposit`, `addFunds`, `removeFunds`, `withdrawDeposit`, `ensureAllowance`, `setAcceptingIntents`, `setIntentRange`, `setCurrencyMinRate`, `setRetainOnEmpty` |
91
+ | Payment methods and currencies | `addPaymentMethods`, `removePaymentMethod`, `setPaymentMethodActive`, `addCurrencies`, `removeCurrency`, `deactivateCurrency`, `pruneExpiredIntents` |
92
+ | Intents | `signalIntent`, `fulfillIntent`, `cancelIntent`, `releaseFundsToPayer`, `getFulfillIntentInputs` |
93
+ | 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 |
94
+ | Payee and quote APIs | `registerPayeeDetails`, `resolvePayeeHash`, `getQuote`, `getTakerTier` |
95
+ | Delegation and hooks | `setDelegate`, `removeDelegate`, `setRateManager`, `clearRateManager`, `setDepositRateManager`, `clearDepositRateManager`, `setDepositPreIntentHook`, `setDepositWhitelistHook` |
96
+ | Vault / DRM | `createRateManager`, `setVaultMinRate`, `setVaultMinRatesBatch`, `setVaultFee`, `setVaultConfig`, `getDepositRateManager`, `getManagerFee`, `getEffectiveRate` |
97
+ | Oracle config | `setOracleRateConfig`, `setOracleRateConfigBatch`, `removeOracleRateConfig`, `updateCurrencyConfigBatch`, `deactivateCurrenciesBatch`, `supportsInlineOracleRateConfig`, `validateOracleFeedsOnChain` |
98
+ | RPC reads | `getDeposits`, `getDeposit`, `getDepositsById`, `getIntents`, `getIntent`, `getPvDepositById`, `getPvDepositsFromIds`, `getPvAccountDeposits`, `getPvAccountIntents`, `getPvIntent` |
99
+ | Indexer | `client.indexer.getDeposits`, `getDepositsWithRelations`, `getDepositById`, `getIntentFulfillmentAmounts`, `getDepositFundActivities`, `getDepositDailySnapshots`, `getRateManagers`, `getRateManagerDetail`, `getManagerDailySnapshots` |
100
+ | React hooks | `@zkp2p/sdk/react` exports hooks for deposits, intents, delegation, vaults, payment methods, and taker tier |
101
+ | Attribution | ERC-8021 helpers like `sendTransactionWithAttribution`, `encodeWithAttribution`, and `txOverrides.referrer` support |
102
+
103
+ ## Create a Deposit
82
104
 
83
105
  ```ts
84
106
  import { Currency } from '@zkp2p/sdk';
85
107
 
86
- await client.createDeposit({
87
- token: '0xUSDC_ADDRESS',
108
+ const result = await client.createDeposit({
109
+ token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
88
110
  amount: 10_000_000n,
89
111
  intentAmountRange: { min: 100_000n, max: 5_000_000n },
90
112
  processorNames: ['wise'],
91
113
  depositData: [{ email: 'maker@example.com' }],
92
114
  conversionRates: [[{ currency: Currency.USD, conversionRate: '1020000000000000000' }]],
93
115
  });
116
+
117
+ console.log(result.hash);
118
+ console.log(result.depositDetails);
94
119
  ```
95
120
 
96
- ### Configure Oracle Spread (EscrowV2)
121
+ 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.
122
+
123
+ ## Payee Registration, Quotes, and Taker Tier
97
124
 
98
125
  ```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
- },
126
+ import { resolvePaymentMethodHash } from '@zkp2p/sdk';
127
+
128
+ const { hashedOnchainIds } = await client.registerPayeeDetails({
129
+ processorNames: ['wise'],
130
+ depositData: [{ email: 'maker@example.com' }],
109
131
  });
110
- ```
111
132
 
112
- ### Validate Oracle Feed Availability
133
+ const quote = await client.getQuote({
134
+ paymentPlatforms: ['wise'],
135
+ fiatCurrency: 'USD',
136
+ user: '0xBuyer',
137
+ recipient: '0xBuyer',
138
+ destinationChainId: 8453,
139
+ destinationToken: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
140
+ amount: '250',
141
+ isExactFiat: true,
142
+ });
113
143
 
114
- ```ts
115
- import { validateOracleFeedsOnChain } from '@zkp2p/sdk';
144
+ const takerTier = await client.getTakerTier({
145
+ owner: '0xBuyer',
146
+ chainId: 8453,
147
+ });
116
148
 
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
149
+ const payeeHash = await client.resolvePayeeHash(
150
+ 42n,
151
+ resolvePaymentMethodHash('wise', { env: 'production' }),
152
+ );
120
153
  ```
121
154
 
122
- ### Signal an Intent with Referral Fees
155
+ `getQuote()` returns available liquidity plus payee details when authenticated. `getTakerTier()` returns limits and cooldown data for taker UX.
156
+
157
+ ## Signal, Fulfill, and Release Intents
123
158
 
124
159
  ```ts
125
- await client.signalIntent({
160
+ const intentHash = await client.signalIntent({
126
161
  depositId: 42n,
127
162
  amount: 250_000n,
128
- to: '0xBuyer',
129
- paymentMethod: 'wise',
163
+ toAddress: '0xBuyer',
164
+ processorName: 'wise',
165
+ payeeDetails: '0xPAYEE_DETAILS_HASH',
130
166
  fiatCurrencyCode: 'USD',
131
- conversionRate: '1020000000000000000',
167
+ conversionRate: 1_020_000_000_000_000_000n,
132
168
  referralFees: [
133
169
  { recipient: '0xPlatformFeeRecipient', fee: 2_500n },
134
170
  { recipient: '0xPartnerFeeRecipient', fee: 1_250n },
135
171
  ],
136
172
  });
173
+
174
+ await client.fulfillIntent({
175
+ intentHash,
176
+ proof: zkTlsProofJson,
177
+ });
178
+
179
+ await client.releaseFundsToPayer({
180
+ intentHash,
181
+ });
137
182
  ```
138
183
 
139
- Legacy `referrer` / `referrerFee` fields are still accepted as a backwards-compatible fallback, but new integrations should send `referralFees[]`.
184
+ For OrchestratorV2 flows, prefer `referralFees[]`. Legacy `referrer` and `referrerFee` fields remain available for compatibility.
185
+
186
+ ## Prepared Transactions
140
187
 
141
- ### Vault / DRM Operations
188
+ 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
189
 
143
190
  ```ts
144
- // Create a vault (rate manager)
145
- await client.createRateManager({
191
+ const prepared = await client.signalIntent.prepare({
192
+ depositId: 42n,
193
+ amount: 250_000n,
194
+ toAddress: '0xBuyer',
195
+ processorName: 'wise',
196
+ payeeDetails: '0xPAYEE_DETAILS_HASH',
197
+ fiatCurrencyCode: 'USD',
198
+ conversionRate: 1_020_000_000_000_000_000n,
199
+ });
200
+
201
+ console.log(prepared);
202
+ // { to, data, value, chainId }
203
+ ```
204
+
205
+ React hooks mirror this where useful. For example, `useSignalIntent()` returns `prepareSignalIntent()` and `prepared`.
206
+
207
+ ## Error Handling
208
+
209
+ The SDK exports a normalized error model:
210
+
211
+ - `ZKP2PError`
212
+ - `ValidationError`
213
+ - `NetworkError`
214
+ - `APIError`
215
+ - `ContractError`
216
+ - `ErrorCode`
217
+
218
+ ```ts
219
+ import { APIError, ErrorCode, ValidationError, ZKP2PError } from '@zkp2p/sdk';
220
+
221
+ try {
222
+ await client.createDeposit({
223
+ token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
224
+ amount: 10_000_000n,
225
+ intentAmountRange: { min: 100_000n, max: 5_000_000n },
226
+ processorNames: ['wise'],
227
+ depositData: [{ email: 'maker@example.com' }],
228
+ conversionRates: [[{ currency: 'USD', conversionRate: '1020000000000000000' }]],
229
+ });
230
+ } catch (error) {
231
+ if (error instanceof ValidationError) {
232
+ console.error('Invalid field:', error.field, error.message);
233
+ } else if (error instanceof APIError) {
234
+ console.error('HTTP status:', error.status, error.message);
235
+ } else if (error instanceof ZKP2PError) {
236
+ console.error('SDK error:', error.code ?? ErrorCode.UNKNOWN, error.details);
237
+ } else {
238
+ console.error('Unknown error:', error);
239
+ }
240
+ }
241
+ ```
242
+
243
+ You should still handle generic `Error` for lower-level transport or wallet failures that originate outside the normalized SDK wrappers.
244
+
245
+ ## Oracle Configuration
246
+
247
+ The SDK exports Chainlink and Pyth adapter helpers, plus a Chainlink-first `getSpreadOracleConfig()` resolver for bundled feed metadata.
248
+
249
+ ```ts
250
+ import {
251
+ getSpreadOracleConfig,
252
+ resolveFiatCurrencyBytes32,
253
+ resolvePaymentMethodHash,
254
+ validateOracleFeedsOnChain,
255
+ } from '@zkp2p/sdk';
256
+
257
+ const paymentMethodHash = resolvePaymentMethodHash('wise', { env: 'production' });
258
+ const currencyHash = resolveFiatCurrencyBytes32('USD');
259
+ const oracle = getSpreadOracleConfig('USD');
260
+
261
+ if (!oracle) throw new Error('No bundled oracle config for USD');
262
+
263
+ await client.setOracleRateConfig({
264
+ depositId: 42n,
265
+ paymentMethodHash,
266
+ currencyHash,
267
+ config: {
268
+ adapter: oracle.adapter,
269
+ adapterConfig: oracle.adapterConfig,
270
+ spreadBps: -50,
271
+ maxStaleness: oracle.maxStaleness,
272
+ },
273
+ });
274
+
275
+ await client.updateCurrencyConfigBatch({
276
+ depositId: 42n,
277
+ paymentMethods: [paymentMethodHash],
278
+ updates: [
279
+ [
280
+ {
281
+ code: currencyHash,
282
+ minConversionRate: 1_020_000_000_000_000_000n,
283
+ updateOracle: true,
284
+ oracleRateConfig: {
285
+ adapter: oracle.adapter,
286
+ adapterConfig: oracle.adapterConfig,
287
+ spreadBps: -50,
288
+ maxStaleness: oracle.maxStaleness,
289
+ },
290
+ },
291
+ ],
292
+ ],
293
+ });
294
+
295
+ const availableFeeds = await validateOracleFeedsOnChain(client.publicClient);
296
+ console.log([...availableFeeds].sort());
297
+ ```
298
+
299
+ Useful helpers and methods in this area:
300
+
301
+ - `CHAINLINK_ORACLE_ADAPTER`
302
+ - `PYTH_ORACLE_ADAPTER`
303
+ - `encodeSpreadOracleAdapterConfig`
304
+ - `encodePythAdapterConfig`
305
+ - `getSpreadOracleConfig`
306
+ - `setOracleRateConfigBatch`
307
+ - `updateCurrencyConfigBatch`
308
+ - `deactivateCurrenciesBatch`
309
+
310
+ ## Delegation and Hooks
311
+
312
+ ```ts
313
+ await client.setDelegate({
314
+ depositId: 42n,
315
+ delegate: '0xDelegate',
316
+ });
317
+
318
+ await client.setRateManager({
319
+ depositId: 42n,
320
+ rateManagerAddress: '0xVaultAddress',
321
+ rateManagerId: '0xVaultId',
322
+ });
323
+
324
+ await client.setDepositPreIntentHook({
325
+ depositId: 42n,
326
+ preIntentHook: '0xHookAddress',
327
+ });
328
+
329
+ await client.setDepositWhitelistHook({
330
+ depositId: 42n,
331
+ whitelistHook: '0xHookAddress',
332
+ });
333
+ ```
334
+
335
+ Use `removeDelegate()` and `clearRateManager()` to unwind delegation. Phase-4 hook methods are available when the target deployment supports them.
336
+
337
+ ## Vault / DRM
338
+
339
+ ```ts
340
+ const createHash = await client.createRateManager({
146
341
  config: {
147
342
  manager: '0xManager',
148
343
  feeRecipient: '0xFeeRecipient',
149
344
  maxFee: 50_000_000_000_000_000n,
150
345
  fee: 10_000_000_000_000_000n,
151
346
  name: 'My Vault',
152
- uri: 'ipfs://...',
347
+ uri: 'ipfs://vault-metadata',
153
348
  },
154
349
  });
155
350
 
156
- // Delegate a deposit to a vault
157
- await client.setRateManager({
158
- depositId: 42n,
159
- rateManagerAddress: '0xVaultAddress',
351
+ await client.setVaultFee({
352
+ rateManagerId: '0xVaultId',
353
+ newFee: 20_000_000_000_000_000n,
354
+ });
355
+
356
+ await client.setVaultMinRate({
160
357
  rateManagerId: '0xVaultId',
358
+ paymentMethodHash: resolvePaymentMethodHash('wise', { env: 'production' }),
359
+ currencyHash: resolveFiatCurrencyBytes32('USD'),
360
+ rate: 1_010_000_000_000_000_000n,
161
361
  });
162
362
 
163
- // Update vault fee and config
164
- await client.setVaultFee({ rateManagerId: '0xVaultId', newFee: 20_000_000_000_000_000n });
165
363
  await client.setVaultConfig({
166
364
  rateManagerId: '0xVaultId',
167
365
  newManager: '0xNewManager',
168
366
  newFeeRecipient: '0xNewFeeRecipient',
169
367
  newName: 'Updated Vault',
170
- newUri: 'ipfs://updated',
368
+ newUri: 'ipfs://updated-vault-metadata',
171
369
  });
172
370
  ```
173
371
 
174
- ### Query Indexer Data
372
+ ## Protocol Viewer (RPC) Reads
373
+
374
+ ProtocolViewer methods bypass indexer lag and are the right default for primary user-facing reads.
375
+
376
+ ```ts
377
+ const deposit = await client.getPvDepositById(42n);
378
+ const deposits = await client.getPvDepositsFromIds([42n, 43n]);
379
+ const makerDeposits = await client.getPvAccountDeposits('0xMaker');
380
+ const takerIntents = await client.getPvAccountIntents('0xTaker');
381
+ const intent = await client.getPvIntent('0xIntentHash');
382
+ ```
383
+
384
+ You can also use the convenience wrappers `getDeposits()`, `getDeposit()`, `getIntents()`, and `getIntent()` for common flows.
385
+
386
+ ## Indexer Queries
387
+
388
+ Use the indexer for filtered queries, pagination, fund activity history, snapshots, and vault analytics.
175
389
 
176
390
  ```ts
177
391
  const deposits = await client.indexer.getDeposits(
178
- { status: 'ACTIVE', depositor: '0xYourAddress' },
179
- { limit: 25 },
392
+ { status: 'ACTIVE', depositor: '0xMaker' },
393
+ { limit: 25, orderBy: 'updatedAt', orderDirection: 'desc' },
180
394
  );
181
395
 
182
- const amounts = await client.indexer.getIntentFulfillmentAmounts('0xIntentHash');
183
- // amounts?.releasedAmount, amounts?.takerAmountNetFees
396
+ const depositWithRelations = await client.indexer.getDepositById('8453_0xEscrowAddress_42', {
397
+ includeIntents: true,
398
+ });
399
+
400
+ const fulfillment = await client.indexer.getIntentFulfillmentAmounts('0xIntentHash');
401
+ const fundActivities = await client.indexer.getDepositFundActivities('8453_0xEscrowAddress_42');
402
+ const snapshots = await client.indexer.getDepositDailySnapshots('8453_0xEscrowAddress_42', 30);
403
+
404
+ const managers = await client.indexer.getRateManagers({
405
+ limit: 10,
406
+ orderBy: 'currentDelegatedBalance',
407
+ orderDirection: 'desc',
408
+ });
409
+
410
+ const managerDetail = await client.indexer.getRateManagerDetail('0xVaultId', {
411
+ rateManagerAddress: '0xVaultAddress',
412
+ });
184
413
  ```
185
414
 
415
+ `managerDetail?.aggregate` gives you current delegated balance and filled volume stats alongside recent snapshots and delegation history.
416
+
186
417
  ## React Hooks
187
418
 
419
+ Install React and import hooks from `@zkp2p/sdk/react`. React is an optional peer dependency of the SDK.
420
+
421
+ 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.
422
+
188
423
  ```tsx
189
424
  import {
190
- // Deposit lifecycle
191
425
  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
426
  useSignalIntent,
210
- useFulfillIntent,
211
- useReleaseFundsToPayer,
212
- usePruneExpiredIntents,
213
-
214
- // Delegation
215
- useSetDelegate,
216
- useRemoveDelegate,
217
-
218
- // Vault / DRM
219
427
  useCreateVault,
220
428
  useVaultDelegation,
221
- useSetVaultFee,
222
- useSetVaultMinRate,
223
- useSetVaultConfig,
224
-
225
- // Taker tier
226
429
  useGetTakerTier,
227
430
  } from '@zkp2p/sdk/react';
431
+
432
+ const createDeposit = useCreateDeposit({ client });
433
+ const signalIntent = useSignalIntent({ client });
434
+ const createVault = useCreateVault({ client, sendTransaction });
435
+ const vaultDelegation = useVaultDelegation({ client, sendTransaction, sendBatch });
436
+ const takerTier = useGetTakerTier({ client, owner, chainId, autoFetch: true });
228
437
  ```
229
438
 
439
+ Hook groups:
440
+
441
+ - Deposit lifecycle: `useCreateDeposit`, `useAddFunds`, `useRemoveFunds`, `useWithdrawDeposit`, `useSetAcceptingIntents`, `useSetIntentRange`, `useSetCurrencyMinRate`, `useSetRetainOnEmpty`
442
+ - Payment and currency management: `useAddPaymentMethods`, `useRemovePaymentMethod`, `useSetPaymentMethodActive`, `useAddCurrencies`, `useRemoveCurrency`, `useDeactivateCurrency`
443
+ - Intent lifecycle: `useSignalIntent`, `useFulfillIntent`, `useReleaseFundsToPayer`, `usePruneExpiredIntents`
444
+ - Delegation: `useSetDelegate`, `useRemoveDelegate`
445
+ - Vault / DRM: `useCreateVault`, `useVaultDelegation`, `useSetVaultFee`, `useSetVaultMinRate`, `useSetVaultConfig`
446
+ - Taker tier: `useGetTakerTier`, plus `getTierDisplayInfo()` and `getNextTierCap()` helpers
447
+
448
+ `useVaultDelegation()` is the batching-oriented hook. It returns `delegateDeposit`, `delegateDeposits`, `clearDelegation`, and `clearDelegations`.
449
+
230
450
  ## Contracts and Catalog Helpers
231
451
 
232
452
  ```ts
233
453
  import {
234
454
  getContracts,
235
- getRateManagerContracts,
236
455
  getPaymentMethodsCatalog,
456
+ getRateManagerContracts,
237
457
  resolveFiatCurrencyBytes32,
238
458
  resolvePaymentMethodHash,
239
459
  } from '@zkp2p/sdk';
240
460
 
241
- const { addresses } = getContracts(8453, 'staging');
242
- const rateManager = getRateManagerContracts(8453, 'staging');
243
- const catalog = getPaymentMethodsCatalog(8453, 'staging');
461
+ const contracts = getContracts(8453, 'production');
462
+ const rateManagerContracts = getRateManagerContracts(8453, 'production');
463
+ const paymentMethods = getPaymentMethodsCatalog(8453, 'production');
464
+ const usdHash = resolveFiatCurrencyBytes32('USD');
465
+ const wiseHash = resolvePaymentMethodHash('wise', { env: 'production' });
244
466
  ```
245
467
 
468
+ ## Supported Currencies
469
+
470
+ The SDK ships currency metadata for 34 fiat currencies:
471
+
472
+ `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`
473
+
246
474
  ## Supported Payment Platforms
247
475
 
248
476
  `wise`, `venmo`, `revolut`, `cashapp`, `mercadopago`, `zelle`, `paypal`, `monzo`, `chime`, `luxon`, `n26`
249
477
 
250
- ## Extension SDK Helpers
478
+ ## Attribution (ERC-8021)
479
+
480
+ The SDK includes builder-code attribution helpers and transaction overrides for partner attribution:
481
+
482
+ ```ts
483
+ const hash = await client.signalIntent({
484
+ depositId: 42n,
485
+ amount: 250_000n,
486
+ toAddress: '0xBuyer',
487
+ processorName: 'wise',
488
+ payeeDetails: '0xPAYEE_DETAILS_HASH',
489
+ fiatCurrencyCode: 'USD',
490
+ conversionRate: 1_020_000_000_000_000_000n,
491
+ txOverrides: {
492
+ referrer: ['my-app', 'campaign-42'],
493
+ },
494
+ });
495
+ ```
496
+
497
+ Lower-level helpers are also exported: `BASE_BUILDER_CODE`, `getAttributionDataSuffix()`, `appendAttributionToCalldata()`, `encodeWithAttribution()`, and `sendTransactionWithAttribution()`.
498
+
499
+ ## TypeDoc API Reference
251
500
 
252
- If you integrate with the Peer extension:
501
+ The package already includes TypeDoc configuration. Generate the full API reference locally with:
502
+
503
+ ```bash
504
+ pnpm --filter @zkp2p/sdk docs
505
+ ```
506
+
507
+ This writes documentation to [`packages/sdk/docs`](./docs) and now includes the React entry point as well as the main SDK and extension surfaces.
508
+
509
+ ## Debug Logging
510
+
511
+ Use `setLogLevel()` when you want verbose SDK logging during local development or integration debugging.
253
512
 
254
513
  ```ts
255
- import { peerExtensionSdk } from '@zkp2p/sdk';
514
+ import { setLogLevel } from '@zkp2p/sdk';
256
515
 
257
- const state = await peerExtensionSdk.getState();
258
- if (state === 'needs_install') peerExtensionSdk.openInstallPage();
516
+ setLogLevel('debug');
259
517
  ```
260
518
 
519
+ Supported log levels: `'error'`, `'info'`, `'debug'`
520
+
261
521
  ## Development
262
522
 
263
523
  ```bash
@@ -266,10 +526,12 @@ pnpm build
266
526
  pnpm test
267
527
  pnpm typecheck
268
528
  pnpm lint
529
+ pnpm docs
269
530
  ```
270
531
 
271
532
  ## Links
272
533
 
273
534
  - NPM: https://www.npmjs.com/package/@zkp2p/sdk
274
- - Monorepo: https://github.com/zkp2p/zkp2p-clients
275
535
  - Docs: https://docs.zkp2p.xyz
536
+ - Monorepo: https://github.com/zkp2p/zkp2p-clients
537
+ - TypeDoc output: [`packages/sdk/docs`](./docs)