@zkp2p/sdk 0.2.3 → 0.3.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 +70 -24
- package/dist/index.cjs +223 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +11 -6
- package/dist/index.d.ts +11 -6
- package/dist/index.mjs +222 -43
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/{vaultUtils-DiAumiXp.d.mts → vaultUtils-sodi4Xx-.d.mts} +86 -7
- package/dist/{vaultUtils-DiAumiXp.d.ts → vaultUtils-sodi4Xx-.d.ts} +86 -7
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
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.
|
|
8
8
|
|
|
9
|
-
Current version: `0.
|
|
9
|
+
Current version: `0.2.3`
|
|
10
10
|
|
|
11
11
|
## Why This SDK
|
|
12
12
|
|
|
@@ -29,7 +29,7 @@ Current version: `0.1.0`
|
|
|
29
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
30
|
- Indexer for history and filtering: use `client.indexer.*` for pagination, historical volumes, fund activities, daily snapshots, and vault analytics.
|
|
31
31
|
- Current-stack routing: the client resolves against the upgraded escrow and orchestrator contracts, with historical escrow lookups available for reads and legacy deposits.
|
|
32
|
-
- Modular internals:
|
|
32
|
+
- Modular internals: intent, vault, and ProtocolViewer logic are extracted into `IntentOperations`, `VaultOperations`, and `ProtocolViewerReader`, keeping `Zkp2pClient` focused on orchestration.
|
|
33
33
|
- App-level rollout control: the SDK is capability-based. Product gating and phase flags belong in your app layer, not inside transaction helpers.
|
|
34
34
|
|
|
35
35
|
## Installation
|
|
@@ -72,10 +72,14 @@ const client = new Zkp2pClient({
|
|
|
72
72
|
|
|
73
73
|
- Supported runtime environments: `'production'`, `'preproduction'`, `'staging'`
|
|
74
74
|
- `runtimeEnv` default: `'production'`
|
|
75
|
-
- `
|
|
75
|
+
- `rpcUrl`: optional RPC URL override (defaults to wallet's chain RPC)
|
|
76
|
+
- `apiKey`: optional curator-issued API key — used when the SDK auto-fetches `signalIntent()` gating signatures and enables richer authenticated `getQuote()` responses with maker `depositData`; curator may also attach `skipTierEnforce` to trusted keys on hybrid intent-signing endpoints
|
|
76
77
|
- `authorizationToken` / `getAuthorizationToken`: optional bearer auth for hybrid client and indexer flows
|
|
77
78
|
- `indexerApiKey`: optional `x-api-key` for indexer proxy auth
|
|
78
79
|
- `indexerUrl` and `baseApiUrl`: override defaults when you are targeting custom deployments
|
|
80
|
+
- `timeouts`: `{ api?: number }` — API timeout in milliseconds (default 15000)
|
|
81
|
+
|
|
82
|
+
**No API key is required to get started.** `createDeposit`, `registerPayeeDetails`, `getQuote`, `getTakerTier`, and the rest of the SDK work without `apiKey` or `authorizationToken`. The main tradeoff is that `signalIntent()` only auto-fetches a gating service signature from curator `/v3/intent` when `apiKey` or `authorizationToken` is available; otherwise provide both `gatingServiceSignature` and `signatureExpiration` manually if your integration needs one. Authenticated quotes also include richer maker `depositData`, and curator-issued API keys may carry `skipTierEnforce` on hybrid intent-signing endpoints.
|
|
79
83
|
|
|
80
84
|
Indexer defaults by environment:
|
|
81
85
|
|
|
@@ -85,20 +89,20 @@ Indexer defaults by environment:
|
|
|
85
89
|
|
|
86
90
|
## Core Capabilities
|
|
87
91
|
|
|
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
|
|
92
|
+
| Area | Stable surface |
|
|
93
|
+
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
94
|
+
| Deposits | `createDeposit`, `addFunds`, `removeFunds`, `withdrawDeposit`, `ensureAllowance`, `setAcceptingIntents`, `setIntentRange`, `setCurrencyMinRate`, `setRetainOnEmpty` |
|
|
95
|
+
| Payment methods and currencies | `addPaymentMethods`, `removePaymentMethod`, `setPaymentMethodActive`, `addCurrencies`, `removeCurrency`, `deactivateCurrency`, `pruneExpiredIntents` |
|
|
96
|
+
| Intents | `signalIntent`, `fulfillIntent`, `cancelIntent`, `releaseFundsToPayer`, `getFulfillIntentInputs` |
|
|
97
|
+
| 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 |
|
|
98
|
+
| Payee and quote APIs | `registerPayeeDetails`, `resolvePayeeHash`, `getQuote`, `getTakerTier` |
|
|
99
|
+
| Delegation and hooks | `setDelegate`, `removeDelegate`, `setRateManager`, `clearRateManager`, `setDepositRateManager`, `clearDepositRateManager`, `setDepositPreIntentHook`, `setDepositWhitelistHook` |
|
|
100
|
+
| Vault / DRM | `createRateManager`, `setVaultMinRate`, `setVaultMinRatesBatch`, `setVaultFee`, `setVaultConfig`, `getDepositRateManager`, `getManagerFee`, `getEffectiveRate` |
|
|
101
|
+
| Oracle config | `setOracleRateConfig`, `setOracleRateConfigBatch`, `removeOracleRateConfig`, `updateCurrencyConfigBatch`, `deactivateCurrenciesBatch`, `supportsInlineOracleRateConfig`, `validateOracleFeedsOnChain` |
|
|
102
|
+
| RPC reads | `getDeposits`, `getDeposit`, `getDepositsById`, `getIntents`, `getIntent`, `getPvDepositById`, `getPvDepositsFromIds`, `getPvAccountDeposits`, `getPvAccountIntents`, `getPvIntent` |
|
|
103
|
+
| Indexer | `client.indexer.getDeposits`, `getDepositsWithRelations`, `getDepositById`, `getDepositsByIds`, `getDepositsByIdsWithRelations`, `getDepositsByPayeeHash`, `getIntentsForDeposits`, `getOwnerIntents`, `getIntentsByRateManager`, `getIntentByHash`, `getExpiredIntents`, `getFulfilledIntentEvents`, `getIntentFulfillmentAmounts`, `getFulfillmentAndPayment`, `getDepositFundActivities`, `getMakerFundActivities`, `getDepositDailySnapshots`, `getProfitSnapshotsByDeposits`, `getRateManagers`, `getRateManagerDetail`, `getRateManagerDelegations`, `getDelegationForDeposit`, `getManagerDailySnapshots`, `getManualRateUpdates`, `getOracleConfigUpdates`, `query` |
|
|
104
|
+
| React hooks | `@zkp2p/sdk/react` exports hooks for deposits, intents, delegation, vaults, payment methods, and taker tier |
|
|
105
|
+
| Attribution | ERC-8021 helpers like `sendTransactionWithAttribution`, `encodeWithAttribution`, and `txOverrides.referrer` support |
|
|
102
106
|
|
|
103
107
|
## Create a Deposit
|
|
104
108
|
|
|
@@ -385,35 +389,77 @@ You can also use the convenience wrappers `getDeposits()`, `getDeposit()`, `getI
|
|
|
385
389
|
|
|
386
390
|
## Indexer Queries
|
|
387
391
|
|
|
388
|
-
Use the indexer for filtered queries, pagination, fund activity history, snapshots, and vault analytics.
|
|
392
|
+
Use the indexer for filtered queries, pagination, fund activity history, snapshots, and vault analytics. All methods live on the flat `client.indexer.*` namespace.
|
|
389
393
|
|
|
390
394
|
```ts
|
|
395
|
+
// Deposit queries
|
|
391
396
|
const deposits = await client.indexer.getDeposits(
|
|
392
397
|
{ status: 'ACTIVE', depositor: '0xMaker' },
|
|
393
398
|
{ limit: 25, orderBy: 'updatedAt', orderDirection: 'desc' },
|
|
394
399
|
);
|
|
395
|
-
|
|
396
|
-
|
|
400
|
+
const depositsWithRelations = await client.indexer.getDepositsWithRelations(
|
|
401
|
+
{ status: 'ACTIVE' },
|
|
402
|
+
{ limit: 10 },
|
|
403
|
+
{ includeIntents: true },
|
|
404
|
+
);
|
|
405
|
+
const deposit = await client.indexer.getDepositById('8453_0xEscrowAddress_42', {
|
|
406
|
+
includeIntents: true,
|
|
407
|
+
});
|
|
408
|
+
const depositsByIds = await client.indexer.getDepositsByIds(['8453_0xEscrow_42']);
|
|
409
|
+
const depositsByIdsWithRelations = await client.indexer.getDepositsByIdsWithRelations(
|
|
410
|
+
['8453_0xEscrow_42'],
|
|
411
|
+
{ includeIntents: true },
|
|
412
|
+
);
|
|
413
|
+
const depositsByPayee = await client.indexer.getDepositsByPayeeHash('0xPayeeHash', {
|
|
414
|
+
paymentMethodHash: '0x...',
|
|
415
|
+
limit: 10,
|
|
397
416
|
includeIntents: true,
|
|
398
417
|
});
|
|
399
418
|
|
|
419
|
+
// Intent queries
|
|
420
|
+
const intentsForDeposits = await client.indexer.getIntentsForDeposits(
|
|
421
|
+
['8453_0xEscrow_42'],
|
|
422
|
+
['SIGNALED'],
|
|
423
|
+
);
|
|
424
|
+
const ownerIntents = await client.indexer.getOwnerIntents('0xTaker', ['SIGNALED', 'FULFILLED']);
|
|
425
|
+
const intentsByVault = await client.indexer.getIntentsByRateManager('0xVaultId');
|
|
426
|
+
const intent = await client.indexer.getIntentByHash('0xIntentHash');
|
|
427
|
+
const expiredIntents = await client.indexer.getExpiredIntents({
|
|
428
|
+
now: BigInt(Math.floor(Date.now() / 1000)),
|
|
429
|
+
depositIds: ['8453_0xEscrow_42'],
|
|
430
|
+
});
|
|
431
|
+
const fulfilledEvents = await client.indexer.getFulfilledIntentEvents(['0xIntentHash']);
|
|
400
432
|
const fulfillment = await client.indexer.getIntentFulfillmentAmounts('0xIntentHash');
|
|
433
|
+
const fulfillmentAndPayment = await client.indexer.getFulfillmentAndPayment('0xIntentHash');
|
|
434
|
+
|
|
435
|
+
// Fund activity and snapshots
|
|
401
436
|
const fundActivities = await client.indexer.getDepositFundActivities('8453_0xEscrowAddress_42');
|
|
437
|
+
const makerActivities = await client.indexer.getMakerFundActivities('0xMaker', 50);
|
|
402
438
|
const snapshots = await client.indexer.getDepositDailySnapshots('8453_0xEscrowAddress_42', 30);
|
|
439
|
+
const profitSnapshots = await client.indexer.getProfitSnapshotsByDeposits(['8453_0xEscrow_42']);
|
|
403
440
|
|
|
441
|
+
// Rate manager (vault) queries
|
|
404
442
|
const managers = await client.indexer.getRateManagers({
|
|
405
443
|
limit: 10,
|
|
406
444
|
orderBy: 'currentDelegatedBalance',
|
|
407
445
|
orderDirection: 'desc',
|
|
408
446
|
});
|
|
409
|
-
|
|
410
447
|
const managerDetail = await client.indexer.getRateManagerDetail('0xVaultId', {
|
|
411
448
|
rateManagerAddress: '0xVaultAddress',
|
|
449
|
+
statsLimit: 30,
|
|
450
|
+
});
|
|
451
|
+
const delegations = await client.indexer.getRateManagerDelegations('0xVaultId');
|
|
452
|
+
const delegation = await client.indexer.getDelegationForDeposit('8453_0xEscrow_42');
|
|
453
|
+
const managerSnapshots = await client.indexer.getManagerDailySnapshots('0xVaultId');
|
|
454
|
+
const manualRates = await client.indexer.getManualRateUpdates('0xVaultId');
|
|
455
|
+
const oracleUpdates = await client.indexer.getOracleConfigUpdates('0xVaultId');
|
|
456
|
+
|
|
457
|
+
// Raw GraphQL
|
|
458
|
+
const custom = await client.indexer.query<MyType>({
|
|
459
|
+
query: '{ deposits(limit: 5) { id } }',
|
|
412
460
|
});
|
|
413
461
|
```
|
|
414
462
|
|
|
415
|
-
`managerDetail?.aggregate` gives you current delegated balance and filled volume stats alongside recent snapshots and delegation history.
|
|
416
|
-
|
|
417
463
|
## React Hooks
|
|
418
464
|
|
|
419
465
|
Install React and import hooks from `@zkp2p/sdk/react`. React is an optional peer dependency of the SDK.
|
|
@@ -494,7 +540,7 @@ const hash = await client.signalIntent({
|
|
|
494
540
|
});
|
|
495
541
|
```
|
|
496
542
|
|
|
497
|
-
Lower-level helpers are also exported: `BASE_BUILDER_CODE`, `getAttributionDataSuffix()`, `appendAttributionToCalldata()`, `encodeWithAttribution()`, and `sendTransactionWithAttribution()`.
|
|
543
|
+
Lower-level helpers are also exported: `BASE_BUILDER_CODE`, `ZKP2P_IOS_REFERRER`, `ZKP2P_ANDROID_REFERRER`, `getAttributionDataSuffix()`, `appendAttributionToCalldata()`, `encodeWithAttribution()`, and `sendTransactionWithAttribution()`.
|
|
498
544
|
|
|
499
545
|
## TypeDoc API Reference
|
|
500
546
|
|
package/dist/index.cjs
CHANGED
|
@@ -1099,15 +1099,9 @@ var init_protocolViewerParsers = __esm({
|
|
|
1099
1099
|
|
|
1100
1100
|
// src/client/clientUtils.ts
|
|
1101
1101
|
init_bigint();
|
|
1102
|
+
|
|
1103
|
+
// src/utils/address.ts
|
|
1102
1104
|
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
1103
|
-
var MIN_ORACLE_SPREAD_BPS = -32768;
|
|
1104
|
-
var MAX_ORACLE_SPREAD_BPS = 32767;
|
|
1105
|
-
var EMPTY_ORACLE_RATE_CONFIG = {
|
|
1106
|
-
adapter: ZERO_ADDRESS,
|
|
1107
|
-
adapterConfig: "0x",
|
|
1108
|
-
spreadBps: 0,
|
|
1109
|
-
maxStaleness: 0
|
|
1110
|
-
};
|
|
1111
1105
|
var isValidHexAddress = (addr) => {
|
|
1112
1106
|
if (typeof addr !== "string") return false;
|
|
1113
1107
|
return /^0x[0-9a-fA-F]{40}$/.test(addr);
|
|
@@ -1116,6 +1110,16 @@ var normalizeAddress = (addr) => {
|
|
|
1116
1110
|
if (!isValidHexAddress(addr)) return void 0;
|
|
1117
1111
|
return addr;
|
|
1118
1112
|
};
|
|
1113
|
+
|
|
1114
|
+
// src/client/clientUtils.ts
|
|
1115
|
+
var MIN_ORACLE_SPREAD_BPS = -32768;
|
|
1116
|
+
var MAX_ORACLE_SPREAD_BPS = 32767;
|
|
1117
|
+
var EMPTY_ORACLE_RATE_CONFIG = {
|
|
1118
|
+
adapter: ZERO_ADDRESS,
|
|
1119
|
+
adapterConfig: "0x",
|
|
1120
|
+
spreadBps: 0,
|
|
1121
|
+
maxStaleness: 0
|
|
1122
|
+
};
|
|
1119
1123
|
var parseEscrowAddressFromCompositeDepositId = (depositId) => {
|
|
1120
1124
|
if (typeof depositId !== "string") return void 0;
|
|
1121
1125
|
const parts = depositId.split("_");
|
|
@@ -1422,9 +1426,6 @@ function parseAPIError(response, responseText) {
|
|
|
1422
1426
|
} catch {
|
|
1423
1427
|
if (responseText && responseText.length < 200) message = responseText;
|
|
1424
1428
|
}
|
|
1425
|
-
if (response.status === 429) {
|
|
1426
|
-
message = "Too many requests. Please try again later.";
|
|
1427
|
-
}
|
|
1428
1429
|
return new exports.APIError(message, response.status, { url: response.url });
|
|
1429
1430
|
}
|
|
1430
1431
|
async function withRetry(fn, maxRetries = 3, delayMs = 1e3, timeoutMs) {
|
|
@@ -1488,11 +1489,13 @@ async function apiSignIntentV3(request, opts) {
|
|
|
1488
1489
|
const sig = json?.responseObject?.signedIntent;
|
|
1489
1490
|
const expStr = json?.responseObject?.intentData?.signatureExpiration ?? json?.responseObject?.signatureExpiration;
|
|
1490
1491
|
const preIntentHookData = json?.responseObject?.intentData?.preIntentHookData ?? json?.responseObject?.preIntentHookData;
|
|
1492
|
+
const referralFees = json?.responseObject?.intentData?.referralFees ?? json?.responseObject?.referralFees;
|
|
1491
1493
|
if (!sig || !expStr) throw new Error("v3/intent missing signature or expiration");
|
|
1492
1494
|
return {
|
|
1493
1495
|
signature: sig,
|
|
1494
1496
|
signatureExpiration: BigInt(expStr),
|
|
1495
|
-
preIntentHookData
|
|
1497
|
+
preIntentHookData,
|
|
1498
|
+
referralFees
|
|
1496
1499
|
};
|
|
1497
1500
|
}
|
|
1498
1501
|
|
|
@@ -1919,7 +1922,7 @@ var IntentOperations = class {
|
|
|
1919
1922
|
const depositId = parseRawDepositId(params.depositId);
|
|
1920
1923
|
const amount = typeof params.amount === "bigint" ? params.amount : BigInt(params.amount);
|
|
1921
1924
|
const conversionRate = typeof params.conversionRate === "bigint" ? params.conversionRate : BigInt(params.conversionRate);
|
|
1922
|
-
|
|
1925
|
+
let referralFees = referrerFeeConfig !== void 0 ? [
|
|
1923
1926
|
{
|
|
1924
1927
|
recipient: referrerFeeConfig.recipient,
|
|
1925
1928
|
fee: referrerFeeConfigToPreciseUnits(referrerFeeConfig)
|
|
@@ -1961,6 +1964,23 @@ var IntentOperations = class {
|
|
|
1961
1964
|
gatingServiceSignature = response.signature;
|
|
1962
1965
|
signatureExpiration = response.signatureExpiration;
|
|
1963
1966
|
preIntentHookData = response.preIntentHookData ?? preIntentHookData;
|
|
1967
|
+
if (response.referralFees !== void 0) {
|
|
1968
|
+
referralFees = response.referralFees.map((referralFee) => {
|
|
1969
|
+
if (!isValidReferrerFeeRecipient(referralFee.recipient)) {
|
|
1970
|
+
throw new Error("v3/intent returned invalid referral fee recipient");
|
|
1971
|
+
}
|
|
1972
|
+
let fee;
|
|
1973
|
+
try {
|
|
1974
|
+
fee = BigInt(referralFee.fee);
|
|
1975
|
+
} catch {
|
|
1976
|
+
throw new Error("v3/intent returned non-integer referral fee value");
|
|
1977
|
+
}
|
|
1978
|
+
return {
|
|
1979
|
+
recipient: referralFee.recipient,
|
|
1980
|
+
fee
|
|
1981
|
+
};
|
|
1982
|
+
});
|
|
1983
|
+
}
|
|
1964
1984
|
}
|
|
1965
1985
|
if (!gatingServiceSignature || !signatureExpiration) {
|
|
1966
1986
|
throw new Error("Missing gatingServiceSignature/signatureExpiration");
|
|
@@ -3461,6 +3481,7 @@ var DEPOSIT_FIELDS = `
|
|
|
3461
3481
|
timestamp
|
|
3462
3482
|
txHash
|
|
3463
3483
|
updatedAt
|
|
3484
|
+
whitelistHookAddress
|
|
3464
3485
|
`;
|
|
3465
3486
|
var LEGACY_DEPOSIT_FIELDS = `
|
|
3466
3487
|
id
|
|
@@ -4451,6 +4472,35 @@ var DEPOSIT_DAILY_SNAPSHOTS_QUERY = (
|
|
|
4451
4472
|
}
|
|
4452
4473
|
`
|
|
4453
4474
|
);
|
|
4475
|
+
var PROFIT_SNAPSHOTS_BY_DEPOSITS_QUERY = (
|
|
4476
|
+
/* GraphQL */
|
|
4477
|
+
`
|
|
4478
|
+
query GetProfitSnapshotsByDeposits($depositIds: [String!]) {
|
|
4479
|
+
profitSnapshots: MakerProfitSnapshot(
|
|
4480
|
+
where: { depositId: { _in: $depositIds } }
|
|
4481
|
+
order_by: { createdAt: desc }
|
|
4482
|
+
) {
|
|
4483
|
+
id
|
|
4484
|
+
chainId
|
|
4485
|
+
maker
|
|
4486
|
+
intentId
|
|
4487
|
+
depositId
|
|
4488
|
+
fiatCurrency
|
|
4489
|
+
quoteConversionRate
|
|
4490
|
+
oracleRate
|
|
4491
|
+
spreadBps
|
|
4492
|
+
amount
|
|
4493
|
+
notionalFiatUsdCents
|
|
4494
|
+
feeUsd
|
|
4495
|
+
realizedProfitUsdCents
|
|
4496
|
+
priceSnapshotId
|
|
4497
|
+
status
|
|
4498
|
+
createdAt
|
|
4499
|
+
updatedAt
|
|
4500
|
+
}
|
|
4501
|
+
}
|
|
4502
|
+
`
|
|
4503
|
+
);
|
|
4454
4504
|
var FULFILLMENT_AND_PAYMENT_QUERY = (
|
|
4455
4505
|
/* GraphQL */
|
|
4456
4506
|
`
|
|
@@ -4560,9 +4610,10 @@ function convertIndexerDepositToEscrowView(deposit, _chainId, _escrowAddress) {
|
|
|
4560
4610
|
verifiers
|
|
4561
4611
|
};
|
|
4562
4612
|
}
|
|
4563
|
-
function convertDepositsForLiquidity(deposits, chainId, escrowAddress) {
|
|
4613
|
+
function convertDepositsForLiquidity(deposits, chainId, escrowAddress, options = {}) {
|
|
4614
|
+
const { includePrivateOrderbooks = false } = options;
|
|
4564
4615
|
return deposits.filter(
|
|
4565
|
-
(d) => d.depositor && d.depositor.toLowerCase() !== ZERO && d.acceptingIntents && toBigInt(d.remainingDeposits) > 0n && d.status === "ACTIVE"
|
|
4616
|
+
(d) => d.depositor && d.depositor.toLowerCase() !== ZERO && (includePrivateOrderbooks || normalizeAddress2(d.whitelistHookAddress).toLowerCase() === ZERO) && d.acceptingIntents && toBigInt(d.remainingDeposits) > 0n && d.status === "ACTIVE"
|
|
4566
4617
|
).map((d) => convertIndexerDepositToEscrowView(d));
|
|
4567
4618
|
}
|
|
4568
4619
|
function convertIndexerIntentsToEscrowViews(intents, depositViewsById) {
|
|
@@ -4678,14 +4729,16 @@ var IndexerDepositService = class {
|
|
|
4678
4729
|
const where = {};
|
|
4679
4730
|
if (params.depositIds?.length) where.depositId = { _in: params.depositIds };
|
|
4680
4731
|
if (params.owner) where.owner = { _ilike: params.owner };
|
|
4732
|
+
if (params.rateManagerId) where.rateManagerId = { _ilike: params.rateManagerId };
|
|
4681
4733
|
if (params.statuses?.length) where.status = { _in: params.statuses };
|
|
4682
4734
|
if (!Object.keys(where).length) return [];
|
|
4735
|
+
const orderByField = params.orderByField ?? "signalTimestamp";
|
|
4683
4736
|
const result = await this.queryWithLegacyFallback({
|
|
4684
4737
|
query: INTENTS_QUERY,
|
|
4685
4738
|
legacyQuery: LEGACY_INTENTS_QUERY,
|
|
4686
4739
|
variables: {
|
|
4687
4740
|
where,
|
|
4688
|
-
order_by: [{
|
|
4741
|
+
order_by: [{ [orderByField]: "desc" }],
|
|
4689
4742
|
limit: params.limit,
|
|
4690
4743
|
offset: params.offset
|
|
4691
4744
|
}
|
|
@@ -4748,6 +4801,16 @@ var IndexerDepositService = class {
|
|
|
4748
4801
|
if (!owner) return [];
|
|
4749
4802
|
return this.fetchIntents({ owner, statuses });
|
|
4750
4803
|
}
|
|
4804
|
+
async fetchIntentsByRateManager(rateManagerId, statuses) {
|
|
4805
|
+
const normalizedRateManagerId = rateManagerId?.trim();
|
|
4806
|
+
if (!normalizedRateManagerId) return [];
|
|
4807
|
+
return this.fetchIntents({
|
|
4808
|
+
rateManagerId: normalizedRateManagerId,
|
|
4809
|
+
statuses,
|
|
4810
|
+
limit: 500,
|
|
4811
|
+
orderByField: "fulfillTimestamp"
|
|
4812
|
+
});
|
|
4813
|
+
}
|
|
4751
4814
|
async fetchIntentByHash(intentHash) {
|
|
4752
4815
|
if (!intentHash) return null;
|
|
4753
4816
|
const result = await this.queryWithLegacyFallback({
|
|
@@ -4969,6 +5032,26 @@ var IndexerDepositService = class {
|
|
|
4969
5032
|
return [];
|
|
4970
5033
|
}
|
|
4971
5034
|
}
|
|
5035
|
+
async fetchProfitSnapshotsByDeposits(depositIds) {
|
|
5036
|
+
const normalizedDepositIds = Array.from(
|
|
5037
|
+
new Set(
|
|
5038
|
+
depositIds.map((depositId) => depositId?.trim()).filter((depositId) => Boolean(depositId))
|
|
5039
|
+
)
|
|
5040
|
+
);
|
|
5041
|
+
if (!normalizedDepositIds.length) return [];
|
|
5042
|
+
try {
|
|
5043
|
+
const result = await this.client.query({
|
|
5044
|
+
query: PROFIT_SNAPSHOTS_BY_DEPOSITS_QUERY,
|
|
5045
|
+
variables: { depositIds: normalizedDepositIds }
|
|
5046
|
+
});
|
|
5047
|
+
return result.profitSnapshots ?? result.MakerProfitSnapshot ?? [];
|
|
5048
|
+
} catch (error) {
|
|
5049
|
+
if (!isSchemaCompatibilityError(error)) {
|
|
5050
|
+
throw error;
|
|
5051
|
+
}
|
|
5052
|
+
return [];
|
|
5053
|
+
}
|
|
5054
|
+
}
|
|
4972
5055
|
};
|
|
4973
5056
|
|
|
4974
5057
|
// src/indexer/rateManagerService.ts
|
|
@@ -5865,13 +5948,11 @@ function convertIndexerDepositToLegacyApiDeposit(deposit) {
|
|
|
5865
5948
|
verifiers
|
|
5866
5949
|
};
|
|
5867
5950
|
}
|
|
5868
|
-
async function apiPostDepositDetails(req, baseApiUrl, timeoutMs,
|
|
5951
|
+
async function apiPostDepositDetails(req, baseApiUrl, timeoutMs, _apiKey, _authToken) {
|
|
5869
5952
|
return apiFetch({
|
|
5870
5953
|
url: `${withApiBase(baseApiUrl)}/v1/makers/create`,
|
|
5871
5954
|
method: "POST",
|
|
5872
5955
|
body: req,
|
|
5873
|
-
apiKey,
|
|
5874
|
-
authToken,
|
|
5875
5956
|
timeoutMs
|
|
5876
5957
|
});
|
|
5877
5958
|
}
|
|
@@ -5881,13 +5962,25 @@ async function apiGetQuote(req, baseApiUrl, timeoutMs, apiKey, authToken) {
|
|
|
5881
5962
|
throw new exports.ValidationError("quotesToReturn must be a positive integer", "quotesToReturn");
|
|
5882
5963
|
}
|
|
5883
5964
|
}
|
|
5965
|
+
if (!isValidHexAddress(req.user)) {
|
|
5966
|
+
throw new exports.ValidationError("user must be a valid Ethereum address", "user");
|
|
5967
|
+
}
|
|
5968
|
+
if (!isValidHexAddress(req.recipient)) {
|
|
5969
|
+
throw new exports.ValidationError("recipient must be a valid Ethereum address", "recipient");
|
|
5970
|
+
}
|
|
5971
|
+
if (!isValidHexAddress(req.destinationToken)) {
|
|
5972
|
+
throw new exports.ValidationError(
|
|
5973
|
+
"destinationToken must be a valid Ethereum address",
|
|
5974
|
+
"destinationToken"
|
|
5975
|
+
);
|
|
5976
|
+
}
|
|
5884
5977
|
const isExactFiat = req.isExactFiat !== false;
|
|
5885
5978
|
const endpoint = isExactFiat ? "exact-fiat" : "exact-token";
|
|
5886
5979
|
let url = `${withApiBase(baseApiUrl)}/v2/quote/${endpoint}`;
|
|
5887
5980
|
if (req.quotesToReturn) url += `?quotesToReturn=${req.quotesToReturn}`;
|
|
5888
5981
|
const requestBody = {
|
|
5889
5982
|
...req,
|
|
5890
|
-
[isExactFiat ? "exactFiatAmount" : "exactTokenAmount"]: req.amount,
|
|
5983
|
+
[isExactFiat ? "exactFiatAmount" : "exactTokenAmount"]: String(req.amount),
|
|
5891
5984
|
amount: void 0,
|
|
5892
5985
|
isExactFiat: void 0,
|
|
5893
5986
|
quotesToReturn: void 0
|
|
@@ -5902,6 +5995,29 @@ async function apiGetQuote(req, baseApiUrl, timeoutMs, apiKey, authToken) {
|
|
|
5902
5995
|
timeoutMs
|
|
5903
5996
|
});
|
|
5904
5997
|
}
|
|
5998
|
+
async function apiGetQuotesBestByPlatform(req, baseApiUrl, timeoutMs, apiKey, authToken) {
|
|
5999
|
+
const isExactFiat = req.isExactFiat !== false;
|
|
6000
|
+
const endpoint = isExactFiat ? "best-by-platform" : "best-by-platform-exact-token";
|
|
6001
|
+
const url = `${withApiBase(baseApiUrl)}/v2/quote/${endpoint}`;
|
|
6002
|
+
const requestBody = {
|
|
6003
|
+
...req,
|
|
6004
|
+
[isExactFiat ? "exactFiatAmount" : "exactTokenAmount"]: String(req.amount),
|
|
6005
|
+
amount: void 0,
|
|
6006
|
+
isExactFiat: void 0,
|
|
6007
|
+
referrerFeeConfig: void 0
|
|
6008
|
+
};
|
|
6009
|
+
Object.keys(requestBody).forEach(
|
|
6010
|
+
(key) => requestBody[key] === void 0 && delete requestBody[key]
|
|
6011
|
+
);
|
|
6012
|
+
return apiFetch({
|
|
6013
|
+
url,
|
|
6014
|
+
method: "POST",
|
|
6015
|
+
body: requestBody,
|
|
6016
|
+
apiKey,
|
|
6017
|
+
authToken,
|
|
6018
|
+
timeoutMs
|
|
6019
|
+
});
|
|
6020
|
+
}
|
|
5905
6021
|
async function apiGetPayeeDetails(req, apiKey, baseApiUrl, authToken, timeoutMs) {
|
|
5906
6022
|
return apiFetch({
|
|
5907
6023
|
url: `${baseApiUrl.replace(/\/$/, "")}/v1/makers/${req.processorName}/${req.hashedOnchainId}`,
|
|
@@ -5968,7 +6084,6 @@ async function apiGetTakerTier(req, apiKey, baseApiUrl, timeoutMs) {
|
|
|
5968
6084
|
return apiFetch({
|
|
5969
6085
|
url: `${withApiBase(baseApiUrl)}${endpoint}`,
|
|
5970
6086
|
method: "GET",
|
|
5971
|
-
apiKey,
|
|
5972
6087
|
timeoutMs
|
|
5973
6088
|
});
|
|
5974
6089
|
}
|
|
@@ -6070,6 +6185,23 @@ var appendReferrerFeeDisplayFields = (quoteResponse, referrerFeeConfig) => {
|
|
|
6070
6185
|
}
|
|
6071
6186
|
};
|
|
6072
6187
|
};
|
|
6188
|
+
var appendReferrerFeeDisplayFieldsToBestByPlatform = (quoteResponse, referrerFeeConfig) => {
|
|
6189
|
+
if (!referrerFeeConfig) {
|
|
6190
|
+
return quoteResponse;
|
|
6191
|
+
}
|
|
6192
|
+
const decimals = quoteResponse.responseObject?.token?.decimals ?? 6;
|
|
6193
|
+
const enrichedPlatformQuotes = (quoteResponse.responseObject?.platformQuotes ?? []).map((platformQuote) => ({
|
|
6194
|
+
...platformQuote,
|
|
6195
|
+
bestQuote: platformQuote.available && platformQuote.bestQuote ? applyReferrerFeeDisplayFieldsToQuote(platformQuote.bestQuote, referrerFeeConfig, decimals) : platformQuote.bestQuote
|
|
6196
|
+
}));
|
|
6197
|
+
return {
|
|
6198
|
+
...quoteResponse,
|
|
6199
|
+
responseObject: {
|
|
6200
|
+
...quoteResponse.responseObject,
|
|
6201
|
+
platformQuotes: enrichedPlatformQuotes
|
|
6202
|
+
}
|
|
6203
|
+
};
|
|
6204
|
+
};
|
|
6073
6205
|
|
|
6074
6206
|
// src/utils/erc20.ts
|
|
6075
6207
|
var ERC20_ABI = [
|
|
@@ -6642,7 +6774,9 @@ var Zkp2pClient = class {
|
|
|
6642
6774
|
* sending fiat payment to the deposit's payee.
|
|
6643
6775
|
*
|
|
6644
6776
|
* If `gatingServiceSignature` is not provided, the SDK will automatically
|
|
6645
|
-
* fetch one from
|
|
6777
|
+
* fetch one from curator `/v3/intent` when `apiKey` or `authorizationToken`
|
|
6778
|
+
* is available. Otherwise you must provide `gatingServiceSignature` and
|
|
6779
|
+
* `signatureExpiration` yourself.
|
|
6646
6780
|
*
|
|
6647
6781
|
* **Prepare Mode**: Use `.prepare()` to get the transaction calldata without sending:
|
|
6648
6782
|
* ```typescript
|
|
@@ -7766,6 +7900,12 @@ var Zkp2pClient = class {
|
|
|
7766
7900
|
getOwnerIntents: (owner, statuses) => {
|
|
7767
7901
|
return service.fetchIntentsByOwner(owner, statuses);
|
|
7768
7902
|
},
|
|
7903
|
+
/**
|
|
7904
|
+
* Fetches fulfilled intents for a vault by rate manager ID.
|
|
7905
|
+
*/
|
|
7906
|
+
getIntentsByRateManager: (rateManagerId, statuses) => {
|
|
7907
|
+
return service.fetchIntentsByRateManager(rateManagerId, statuses);
|
|
7908
|
+
},
|
|
7769
7909
|
/**
|
|
7770
7910
|
* Fetches a single intent by hash.
|
|
7771
7911
|
*/
|
|
@@ -7816,6 +7956,12 @@ var Zkp2pClient = class {
|
|
|
7816
7956
|
getDepositsByIdsWithRelations: (ids, options) => {
|
|
7817
7957
|
return service.fetchDepositsByIdsWithRelations(ids, options);
|
|
7818
7958
|
},
|
|
7959
|
+
/**
|
|
7960
|
+
* Fetches maker profit snapshots for the provided deposits.
|
|
7961
|
+
*/
|
|
7962
|
+
getProfitSnapshotsByDeposits: (depositIds) => {
|
|
7963
|
+
return service.fetchProfitSnapshotsByDeposits(depositIds);
|
|
7964
|
+
},
|
|
7819
7965
|
/**
|
|
7820
7966
|
* Fetches rate managers (vaults) with aggregate stats.
|
|
7821
7967
|
*/
|
|
@@ -7969,15 +8115,7 @@ var Zkp2pClient = class {
|
|
|
7969
8115
|
})
|
|
7970
8116
|
);
|
|
7971
8117
|
const apiResponses = await Promise.all(
|
|
7972
|
-
depositDetails.map(
|
|
7973
|
-
(req) => apiPostDepositDetails(
|
|
7974
|
-
req,
|
|
7975
|
-
baseApiUrl,
|
|
7976
|
-
this.apiTimeoutMs,
|
|
7977
|
-
this.apiKey,
|
|
7978
|
-
this.authorizationToken
|
|
7979
|
-
)
|
|
7980
|
-
)
|
|
8118
|
+
depositDetails.map((req) => apiPostDepositDetails(req, baseApiUrl, this.apiTimeoutMs))
|
|
7981
8119
|
);
|
|
7982
8120
|
if (!apiResponses.every((r) => r?.success)) {
|
|
7983
8121
|
const failed = apiResponses.find((r) => !r?.success);
|
|
@@ -8104,15 +8242,7 @@ var Zkp2pClient = class {
|
|
|
8104
8242
|
} else {
|
|
8105
8243
|
const baseApiUrl = (this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(/\/$/, "");
|
|
8106
8244
|
const apiResponses = await Promise.all(
|
|
8107
|
-
depositDetails.map(
|
|
8108
|
-
(req) => apiPostDepositDetails(
|
|
8109
|
-
req,
|
|
8110
|
-
baseApiUrl,
|
|
8111
|
-
this.apiTimeoutMs,
|
|
8112
|
-
this.apiKey,
|
|
8113
|
-
this.authorizationToken
|
|
8114
|
-
)
|
|
8115
|
-
)
|
|
8245
|
+
depositDetails.map((req) => apiPostDepositDetails(req, baseApiUrl, this.apiTimeoutMs))
|
|
8116
8246
|
);
|
|
8117
8247
|
if (!apiResponses.every((r) => r?.success)) {
|
|
8118
8248
|
const failed = apiResponses.find((r) => !r?.success);
|
|
@@ -8315,6 +8445,57 @@ var Zkp2pClient = class {
|
|
|
8315
8445
|
}
|
|
8316
8446
|
return appendReferrerFeeDisplayFields(quote, referrerFeeConfig);
|
|
8317
8447
|
}
|
|
8448
|
+
/**
|
|
8449
|
+
* **Supporting Method** - Fetches the best available quote per supported payment platform.
|
|
8450
|
+
*
|
|
8451
|
+
* Returns one quote per platform when available. When authenticated, the API
|
|
8452
|
+
* returns payee details in each platform's best quote.
|
|
8453
|
+
*
|
|
8454
|
+
* @param req - Best-by-platform quote request parameters
|
|
8455
|
+
* @param opts - Optional overrides for API URL and timeout
|
|
8456
|
+
* @returns Best-by-platform quote response
|
|
8457
|
+
*/
|
|
8458
|
+
async getQuotesBestByPlatform(req, opts) {
|
|
8459
|
+
const referrerFeeConfig = assertValidReferrerFeeConfig(
|
|
8460
|
+
req.referrerFeeConfig,
|
|
8461
|
+
"getQuotesBestByPlatform"
|
|
8462
|
+
);
|
|
8463
|
+
const baseApiUrl = (opts?.baseApiUrl ?? this.baseApiUrl ?? "https://api.zkp2p.xyz").replace(
|
|
8464
|
+
/\/$/,
|
|
8465
|
+
""
|
|
8466
|
+
);
|
|
8467
|
+
const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
|
|
8468
|
+
const reqWithEscrow = { ...req };
|
|
8469
|
+
if (!reqWithEscrow.escrowAddresses || reqWithEscrow.escrowAddresses.length === 0) {
|
|
8470
|
+
const configuredEscrows = this.escrowAddresses.length > 0 ? [...this.escrowAddresses] : this.escrowAddress ? [this.escrowAddress] : [];
|
|
8471
|
+
if (configuredEscrows.length > 0) {
|
|
8472
|
+
reqWithEscrow.escrowAddresses = configuredEscrows;
|
|
8473
|
+
}
|
|
8474
|
+
}
|
|
8475
|
+
const quote = await apiGetQuotesBestByPlatform(
|
|
8476
|
+
reqWithEscrow,
|
|
8477
|
+
baseApiUrl,
|
|
8478
|
+
timeoutMs,
|
|
8479
|
+
this.apiKey,
|
|
8480
|
+
this.authorizationToken
|
|
8481
|
+
);
|
|
8482
|
+
const enrichedQuote = quote ? {
|
|
8483
|
+
...quote,
|
|
8484
|
+
responseObject: {
|
|
8485
|
+
...quote.responseObject,
|
|
8486
|
+
platformQuotes: (quote.responseObject?.platformQuotes ?? []).map((platformQuote) => {
|
|
8487
|
+
const bestQuote = platformQuote?.bestQuote;
|
|
8488
|
+
const makerDepositData = bestQuote?.maker?.depositData;
|
|
8489
|
+
if (!bestQuote || !makerDepositData) return platformQuote;
|
|
8490
|
+
return {
|
|
8491
|
+
...platformQuote,
|
|
8492
|
+
bestQuote: { ...bestQuote, payeeData: makerDepositData }
|
|
8493
|
+
};
|
|
8494
|
+
})
|
|
8495
|
+
}
|
|
8496
|
+
} : quote;
|
|
8497
|
+
return appendReferrerFeeDisplayFieldsToBestByPlatform(enrichedQuote, referrerFeeConfig);
|
|
8498
|
+
}
|
|
8318
8499
|
// ───────────────────────────────────────────────────────────────────────────
|
|
8319
8500
|
// SUPPORTING: TAKER TIER
|
|
8320
8501
|
// (Used by frontends to display taker limits)
|
|
@@ -8334,7 +8515,7 @@ var Zkp2pClient = class {
|
|
|
8334
8515
|
""
|
|
8335
8516
|
);
|
|
8336
8517
|
const timeoutMs = opts?.timeoutMs ?? this.apiTimeoutMs;
|
|
8337
|
-
return apiGetTakerTier(req,
|
|
8518
|
+
return apiGetTakerTier(req, void 0, baseApiUrl, timeoutMs);
|
|
8338
8519
|
}
|
|
8339
8520
|
// ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
8340
8521
|
// ║ CORE: ON-CHAIN DEPOSIT VIEWS ║
|
|
@@ -8764,6 +8945,7 @@ exports.ZKP2P_IOS_REFERRER = ZKP2P_IOS_REFERRER;
|
|
|
8764
8945
|
exports.Zkp2pClient = Zkp2pClient;
|
|
8765
8946
|
exports.apiGetOwnerDeposits = apiGetOwnerDeposits;
|
|
8766
8947
|
exports.apiGetPayeeDetails = apiGetPayeeDetails;
|
|
8948
|
+
exports.apiGetQuotesBestByPlatform = apiGetQuotesBestByPlatform;
|
|
8767
8949
|
exports.apiGetTakerTier = apiGetTakerTier;
|
|
8768
8950
|
exports.apiPostDepositDetails = apiPostDepositDetails;
|
|
8769
8951
|
exports.apiValidatePayeeDetails = apiValidatePayeeDetails;
|