Skip to main content

Client Reference

What this does​

This page documents the published Zkp2pClient API surface for @zkp2p/sdk. Use it as the reference layer for custom integrations after you have read the higher-level walkthroughs:

Release channels

This reference tracks @zkp2p/sdk@latest, including the Curator v3, OrchestratorV3, StakeVault, and DisputeProtectionPolicy surfaces.

Constructor​

Create a client with new Zkp2pClient(opts).

FieldRequiredDescription
walletClientYesviem WalletClient with an attached account for signing
chainIdYesChain ID used for contract and API routing
rpcUrlNoOptional RPC override; otherwise the SDK uses the wallet client's chain transport
rpcTransportNoviem Transport override for RPC reads
runtimeEnvNoRuntime environment: production, preproduction, or staging. Defaults to production
indexerUrlNoOverride for the indexer GraphQL endpoint
baseApiUrlNoOverride for ZKP2P service APIs
apiKeyNoInternal curator API key sent as x-api-key; only verifySellerPayment() uses it. Public endpoints such as quotes, maker reads, and POST /v3/sign ignore it, and quote responses carry payeeData.offchainId for every caller
authorizationTokenNoOptional bearer token for hybrid authentication
getAuthorizationTokenNoAsync token provider for long-lived clients
indexerApiKeyNoOptional x-api-key header for indexer proxy authentication
apiHeadersNoExtra headers sent on curator quote, orderbook, and /v3/sign requests, such as x-pp-key for service callers
timeouts.apiNoAPI timeout in milliseconds
import { Zkp2pClient } from "@zkp2p/sdk";

const client = new Zkp2pClient({
walletClient,
chainId: 8453,
});
No API key required

Most public SDK methods work without apiKey or authorizationToken. Auth credentials are optional for normal deposit, quote, and intent flows and mostly affect response richness. signalIntent() fetches a missing gating signature through POST /v3/sign when baseApiUrl is configured; it does not require an API key for that request. Set baseApiUrl to the correct Curator root, or supply both gatingServiceSignature and signatureExpiration yourself.

Service roots

Set baseApiUrl to the service root, for example https://api.zkp2p.xyz. Do not append /v1, /v2, or /v3; the SDK appends the current versioned paths internally.

Runtime requirements

@zkp2p/sdk@latest declares node >= 22 for Node runtimes and viem ^2.37.3 as a peer dependency. Its package metadata pins the compatible contracts, indexer schema, and attestation dependencies; do not override those versions independently. Install stable releases through the latest dist-tag.

Prepared transactions​

Most write methods are "prepareable":

  • Calling the method directly sends the transaction and returns a hash
  • Calling .prepare() on the same method returns a PreparedTransaction with { to, data, value, chainId }
const prepared = await client.signalIntent.prepare({
depositId: 42n,
amount: 100_000000n,
toAddress: "0xYourRecipientAddress",
processorName: "wise",
payeeDetails:
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
fiatCurrencyCode: "USD",
conversionRate: 1_020000000000000000n,
});

await relayer.submit({
to: prepared.to,
data: prepared.data,
value: prepared.value,
});

createDeposit() is the main exception because it may also post curator data. Use prepareCreateDeposit() when you need calldata without sending:

const { depositDetails, prepared } = await client.prepareCreateDeposit({
token: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
amount: 1_000_000000n,
intentAmountRange: { min: 10_000000n, max: 500_000000n },
processorNames: ["wise"],
payeeData: [{ offchainId: "maker@example.com" }],
conversionRates: [
[{ currency: "USD", conversionRate: "1020000000000000000" }],
],
});

When intentGuardian is omitted, createDeposit() and prepareCreateDeposit() use the paid guardian deployed for the client's environment. Production and preproduction use 0x83671606454fA72ba1e2831E18C5090D25629414; staging uses 0x3355bb8CEFA54509d244384CFA7f2A71fdb1FDD6. This lets a payer purchase more time for a live intent through the intent-lifetime extension methods. Pass intentGuardian explicitly when using a custom guardian.

Payee registration​

Use registerPayeeDetails() when you want to register payment details first and reuse the returned hashes in a later createDeposit() call.

ParameterTypeDescription
processorNamesstring[]Payment platforms such as wise, revolut, or venmo
payeeDataCuratorPayeeDataInput[]One entry per processor, in the same order as processorNames. offchainId is required; telegramUsername, metadata, and identityAttestation are optional
depositDataCuratorPayeeDataInput[]Deprecated alias for payeeData

registerPayeeDetails() posts each payee identity to curator POST /v2/makers/create with { processorName, offchainId, telegramUsername?, metadata? }. Curator returns the hashedOnchainId used by deposits, quotes, intents, seller credential status, and seller credential uploads. This endpoint does not accept legacy proof JSON or encrypted session material. Request identity attestations separately through the attestation helpers below, then pass the result as payeeData[].identityAttestation; the SDK forwards it as metadata.identityAttestation.

const { hashedOnchainIds } = await client.registerPayeeDetails({
processorNames: ["wise", "revolut"],
payeeData: [{ offchainId: "maker@example.com" }, { offchainId: "maker" }],
});

await client.createDeposit({
token: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
amount: 1_000_000000n,
intentAmountRange: { min: 10_000000n, max: 500_000000n },
processorNames: ["wise", "revolut"],
payeeData: [{ offchainId: "maker@example.com" }, { offchainId: "maker" }],
conversionRates: [
[{ currency: "USD", conversionRate: "1020000000000000000" }],
[{ currency: "EUR", conversionRate: "950000000000000000" }],
],
payeeDetailsHashes: hashedOnchainIds,
});

Identity attestation​

Identity registration is a separate Attestation Service flow for platforms that need a live account identity before curator registration. The SDK exposes it through the Nitro attestation client re-export and through the lower-level apiRequestIdentityAttestation() helper.

Current identity platform/action pairs:

PlatformAction typeEncrypted session materialPublic params
venmoregister_venmoCookie{ SENDER_ID }
paypalregister_paypalCookie{}
wiseregister_wiseCookie, X-Access-Token{ PROFILE_ID }
cashappregister_cashappsessionCookie, requestPayload, optional requestHeaders{}
alipayregister_alipayCookie{}

Typed maker registration through payeeData[].identityAttestation accepts the MakerIdentityPlatform union: paypal, wise, and alipay.

Venmo session material

Do not send a captured Venmo stories URL in encrypted session material. The Venmo identity request sends only a replayable Cookie header plus public params.SENDER_ID. The Attestation Service derives https://account.venmo.com/api/stories?feedType=me&externalId={SENDER_ID}, verifies the authenticated account id, and requires Venmo to return a valid stories array.

import { createNitroAttestationClient } from "@zkp2p/sdk";

const nitro = createNitroAttestationClient({
environment: "production",
attestationServiceUrl: "https://attestation-service.zkp2p.xyz",
});

const identity = await nitro.requestIdentityAttestation({
platform: "venmo",
actionType: "register_venmo",
callerAddress: "0x0000000000000000000000000000000000000002",
sessionMaterial: {
Cookie: "venmo-session-cookie-header",
},
params: {
SENDER_ID: "123456789",
},
});

console.log(identity.identity.payeeIdHash);

If you already encrypted session material outside the Nitro client, call the raw endpoint helper:

import { apiRequestIdentityAttestation } from "@zkp2p/sdk";

const response = await apiRequestIdentityAttestation(
{
callerAddress: "0x0000000000000000000000000000000000000002",
encryptedSessionMaterial,
params: { SENDER_ID: "123456789" },
},
"https://attestation-service.zkp2p.xyz",
"venmo",
"register_venmo",
);

callerAddress is required and is signed into the returned IdentityAttestation. Public maker registration does not authenticate or compare it to a linked wallet; verification still checks platform, action type, payee hash, canonical identity dataHash, signature, and validity window.

Intent operations​

signalIntent() / signalIntent.prepare()​

Signals a taker-side intent and reserves liquidity from a deposit.

ParameterRequiredDescription
depositIdYesDeposit ID to use
amountYesToken amount in base units
toAddressYesRecipient address for the on-chain asset
processorNameYesPayment platform name
payeeDetailsYesHashed payee details for the deposit/payment method
fiatCurrencyCodeYesFiat currency such as USD or EUR
conversionRateYesAgreed conversion rate with 18 decimals
referralFeesNoMulti-recipient referral fee list
referrer / referrerFeeNoDeprecated legacy single-referrer fields
referrerFeeConfigNoOnramp-friendly referrer fee configuration
postIntentHookNoPost-intent hook contract address
preIntentHookDataNoData for a pre-intent hook
dataNoArbitrary bytes passed into hook-enabled flows
escrowAddressNoEscrow override when you want explicit routing
orchestratorAddressNoOrchestrator override
gatingServiceSignatureNoPre-obtained signature if you do not want SDK auto-fetching
signatureExpirationNoSignature expiration timestamp
txOverridesNoviem transaction overrides plus optional referrer code(s)

cancelIntent() / cancelIntent.prepare()​

Cancels a signaled intent before fulfillment.

ParameterRequiredDescription
intentHashYes0x-prefixed 32-byte intent hash
orchestratorAddressNoExplicit orchestrator override
txOverridesNoviem transaction overrides

fulfillIntent() / fulfillIntent.prepare()​

Fulfills a signaled intent with a payment proof. The SDK handles attestation encoding for you.

ParameterRequiredDescription
intentHashYes0x-prefixed 32-byte intent hash
proofYesBuyer TEE proof input: { proofType: 'buyerTee', encryptedSessionMaterial, params }. Legacy zkTLS proof objects and JSON strings are rejected
timestampBufferMsNoAllowed timestamp variance in milliseconds
attestationServiceUrlNoOverride for the attestation service
attestationServiceFallbackUrlsNoAlternate attestation-service origins tried after network failures; omit for the default proxy, pass [] to disable fallback
orchestratorAddressNoExplicit orchestrator override
postIntentHookDataNoHook payload passed to the orchestrator
txOverridesNoviem transaction overrides
callbacksNoUI lifecycle callbacks such as onAttestationStart, onAttestationComplete, onTxSent, and onTxMined
precomputedAttestationNoPre-encoded attestation data for advanced flows

releaseFundsToPayer() / releaseFundsToPayer.prepare()​

Manual release path for returning reserved funds to the deposit owner when an intent should not be fulfilled.

ParameterRequiredDescription
intentHashYes0x-prefixed 32-byte intent hash
orchestratorAddressNoExplicit orchestrator override
txOverridesNoviem transaction overrides

Intent lifetime extension​

The standalone IntentGuardian lets any payer buy more time for a live intent. Use hasIntentGuardian() to gate the feature, then read getIntentGuardianPolicy() and call quoteIntentExtension() immediately before signing. The fee is owner-governed, so pass the fresh quote through the required maxCost ceiling.

MethodPurpose
hasIntentGuardian()Non-throwing deployment capability check
getIntentGuardianPolicy()Read the current fee and lifetime limits
quoteIntentExtension()Read the authoritative on-chain cost
getIntentGuardianPayerFunding()Read payer token balance and allowance
extendIntentLifetime() / .prepare()Pay for and submit the lifetime extension

extendIntentLifetime() requires escrow, depositId, intentHash, additionalTime in seconds, and maxCost. The guardian charges the target deposit's token, pays the deposit owner, and does not refund extension payments.

Deposit hook controls​

OrchestratorV3 has one generic pre-intent hook slot per deposit. The whitelist-hook methods in the SDK target OrchestratorV2 and remain available for existing V2 integrations.

MethodDescriptionKey parameters
setDepositPreIntentHook() / .prepare()Set the hook called before an intent is accepteddepositId, preIntentHook, escrowAddress?, orchestratorAddress?
getDepositPreIntentHook()Read the configured pre-intent hookdepositId, escrowAddress?, orchestratorAddress?
setDepositWhitelistHook() / .prepare()Set the legacy V2 whitelist hookdepositId, whitelistHook, escrowAddress?, orchestratorAddress?
getDepositWhitelistHook()Read the legacy V2 whitelist hookdepositId, escrowAddress?, orchestratorAddress?
cleanupOrphanedIntents() / .prepare()Permissionless cleanup for orphaned V2 or V3 intentsintentHashes, escrowAddress?, orchestratorAddress?

Deposit access policy​

client.accessPolicy wraps the environment's WhitelistPolicy and AddressGroupRegistry. Check client.accessPolicy.isSupported before reading or preparing unwind transactions; unsupported deployments fail closed with AccessPolicyUnsupportedError. Reads include isEnabled, getAllowedGroups, isWhitelisted, maxGroupsPerDepositPaymentMethod, groupExists, and isMember.

These methods remain available for integrations that must inspect or unwind policies written before Groups were retired. Existing deposits continue to enforce their stored policy until they are closed. Historical-policy writes are limited to prepareDisable, prepareRemoveAllowedGroups, and prepareRemoveWhitelistedAddresses.

New sell-deposit flows may call prepareConfigurePeerPayMerchantDeposit({ escrow, depositId, paymentMethod }) as part of the same atomic creation batch. It always selects the protocol-owned Peer Pay merchant group for the client's runtime environment; callers cannot supply another group ID. General-purpose additive policy planners and writes remain removed.

Vault and rate-manager operations​

At the client layer, vaults are exposed as rate managers. These flows are most relevant when you are delegating deposits or managing shared pricing.

note

New intents route through EscrowV2 and OrchestratorV3. Existing intent reads, cancellation, and fulfillment resolve the V2 or V3 orchestrator that owns the intent. Pass an explicit escrowAddress or orchestratorAddress only when targeting a configured deployment.

Create a vault​

Use createRateManager() to create a new vault.

FieldRequiredDescription
config.managerYesManager address
config.feeRecipientYesAddress that receives manager fees
config.maxFeeYesMaximum allowed fee
config.feeYesCurrent fee
config.depositHookNoOptional deposit hook contract
config.minLiquidityNoMinimum USDC liquidity required for delegation
config.nameYesHuman-readable name
config.uriYesMetadata URI
txOverridesNoviem transaction overrides

Delegation methods​

Use one of the delegation paths below depending on how the deposit is routed.

MethodUse it whenKey parameters
setDepositRateManager()Delegating through the controller/registry pathescrow, depositId, registry, rateManagerId
clearDepositRateManager()Clearing controller-based delegationescrow, depositId
setRateManager()Writing directly to EscrowV2depositId, rateManagerAddress, rateManagerId, escrowAddress?
clearRateManager()Clearing direct EscrowV2 delegationdepositId, escrowAddress?

Vault configuration​

MethodDescriptionKey parameters
setVaultFee()Update vault manager feerateManagerId, newFee
setVaultMinRate()Set floor rate for one payment method/currency pairrateManagerId, paymentMethodHash, currencyHash, rate
setVaultMinRatesBatch()Batch version of setVaultMinRate()rateManagerId, paymentMethods, currencies, rates
setVaultConfig()Update manager, fee recipient, hook, name, or URIrateManagerId, newManager, newFeeRecipient, newHook?, newName, newUri

Payment method management​

MethodDescriptionKey parameters
addPaymentMethods()Add new payment platforms to an existing depositdepositId, paymentMethods, paymentMethodData, currencies
setPaymentMethodActive()Activate or deactivate a payment methoddepositId, paymentMethod, isActive
removePaymentMethod()Convenience alias for deactivating a payment methoddepositId, paymentMethod

Currency management​

MethodDescriptionKey parameters
addCurrencies()Add currencies to an existing payment methoddepositId, paymentMethod, currencies
deactivateCurrency()Disable a currency for a payment methoddepositId, paymentMethod, currencyCode
removeCurrency()Alias for deactivateCurrency()depositId, paymentMethod, currencyCode

Rate-manager reads​

MethodReturnsNotes
getDepositRateManager(escrow, depositId){ registry, rateManagerId }Reads current delegation state
getManagerFee(escrow, depositId)bigintReads the effective manager fee
getEffectiveRate({ escrow, depositId, paymentMethod, fiatCurrency })bigintReads effective EscrowV2 rate after manager logic

For EscrowV2 pricing flows, the client also exposes setOracleRateConfig(), removeOracleRateConfig(), setOracleRateConfigBatch(), updateCurrencyConfigBatch(), and deactivateCurrenciesBatch().

Taker staking and dispute-protection risk​

StakeVault collateral belongs to an effective stake owner. A taker may use self-stake or select an owner that has explicitly authorized that taker. Always read stakeOwnerOf(taker) immediately before attributing capacity; an expired or revoked selection falls back to the taker's own stake on-chain.

Stake and policy reads​

MethodReturns or purpose
getStakeBalance(stakeOwner)Total stake owned
getLockedStake(stakeOwner)Stake locked behind live chargeback windows
getFreeStake(stakeOwner)Stake available for new chargebackable intents or withdrawal
getClaimable(beneficiary)USDC already released into the beneficiary's claim balance
getStakeOwner(taker)Effective owner after authorization checks
getSelectedStakeOwner(taker)Raw selected owner; zero address means no selection
getTakerAuthorization(stakeOwner, taker)Whether the owner currently sponsors the taker
getStakeVaultState({ staker, taker? })Combined stake, ownership, authorization, and admissions snapshot
getAdmissionsPaused()Whether new chargebackable admissions are paused
getRiskWindow(paymentMethodHash)Minimum collateral lock window in seconds
isDisputeProtectionEnabled(escrow, depositId, paymentMethod)Whether that deposit payment method uses chargeback coverage

Stake and keeper writes​

MethodSigner and behavior
ensureStakeAllowance({ amount })Approves the StakeVault token allowance when needed
depositStake({ amount })Deposits caller-owned USDC stake
withdrawStake({ amount })Withdraws immediately, bounded by current free stake
claim()Withdraws the caller's complete claimable balance
setTakerAuthorization({ taker, authorized })Lets a stake owner add or revoke a sponsored taker
selectStakeOwner({ stakeOwner })Lets a taker select an owner that currently authorizes it
clearStakeOwner()Returns the taker to self-stake
setDisputeProtectionEnabled({ escrow, depositId, paymentMethod, enabled })Depositor opt-in or opt-out; supports direct and .prepare() use
releaseMaturedDisputeProtectionIntent() / releaseMaturedDisputeProtectionIntents()Permissionless keeper release with a caller-pinned policy address

StakeVault, dispute-protection, and keeper writes have direct and .prepare() forms; ensureStakeAllowance() is a plain async call. There is no withdrawal request, cooldown, or exit queue: withdrawStake() is limited by the current freeStake value.

Indexed state and risk helpers​

client.indexer.getStakingState() accepts chainId, environment (base or base_staging), vaultAddress, disputeProtectionPolicyAddress, taker, and a freshly read stakeOwner. It returns indexed ownership, balances, claims, authorizations, risk windows, and row-level freshness. If indexed ownership has not caught up with the supplied on-chain owner, it returns zero capacity instead of attributing another account's stake.

The package also exports pure admission helpers:

HelperContract-equivalent result
calculateRequiredCoverage(amount, disputeProtected)Full intent amount for protected methods, otherwise zero
calculateStakeBackedCapacity(freeStake)Maximum protected amount supportable by current free stake
selectRiskMode(amount, freeStake, disputeProtected)UNBONDED, STAKE_BACKED, or an insufficient-stake error

Deployment readiness​

getDisputeProtectionReadiness({ verifyPassiveSuccessor? }) pins all RPC reads to one block and verifies the packaged deployment identity before returning one of these states:

StateMeaning
active_successor_verifiedThe exact successor hook and full policy/vault stack are active
recognized_predecessorThe exact predecessor hook remains active
passive_successorThe predecessor remains active and the explicitly requested successor proof passed
verified_no_hookOrchestratorV3 has the zero lifecycle hook
mismatchBuild identity, runtime code, wiring, or RPC verification failed

An active_successor_verified result reports orchestratorPaused, allowMultipleIntents, and policyAdmissionsPaused separately. readyForDisputeProtection is true only when those operational gates allow new protected traffic. This preserves exact deployment identity during an admissions pause so settlement and matured-lock release can continue. Passive verification is opt-in so known predecessor and zero-hook deployments do not query an inactive successor by default. Local source builds carry a deterministic, non-distributable development identity and therefore return mismatch before RPC. Trusted package artifacts also expose their immutable identity as SDK_BUILD_METADATA and @zkp2p/sdk/build-metadata.json.

Quote API​

Both quote methods use Curator v3 and accept eligibility and payment-verification preferences in the first argument (req). The optional second argument (opts) only overrides transport settings.

getQuote(req, opts?)​

Fetch available liquidity for selected payment platforms. The SDK calls POST /v3/quote/exact-fiat by default, or POST /v3/quote/exact-token when isExactFiat: false.

Request fieldTypeRequiredDescription
paymentPlatformsstring[]YesPlatforms to search, such as ['wise', 'revolut']
fiatCurrencystringYesFiat currency code, such as USD
userstringYesTaker EVM address; eligibility and available stake are evaluated for this user
recipientstringYesAsset recipient EVM address
destinationChainIdnumberYesDestination chain ID; current v3 quotes support Base (8453)
destinationTokenstringYesDestination token EVM address
amountstringYesPositive integer string in base units. Both modes use the destination token's decimals. With USDC (6 decimals), '100000000' means 100 USD in exact-fiat mode or 100 USDC in exact-token mode
isExactFiatbooleanNotrue (default): fix fiat input and quote token output. false: fix token output and quote required fiat input
modeQuoteVisibilityModeNoEligibility mode; defaults to eligible. See modes
quotePreferenceQuotePreferenceNoSAR / Buyer TEE pool selection and fallback. See preferences
referrerstringNoReferrer attribution
referrerFeeConfigReferrerFeeConfigNoSingle fee { recipient, feeBps }; converted to a one-entry referralFees array when that array is omitted
referralFeesReferrerFeeConfig[]NoUp to five { recipient, feeBps } entries. Takes precedence over referrerFeeConfig in the API request, including when empty. Use one representation per request
useMultihopbooleanNoPresent in the SDK type, but current Curator v3 rejects true with Multihop not supported; omit or use false
quotesToReturnnumberNoPositive integer quote limit, sent as a query parameter; Curator caps it at 20
escrowAddressesstring[]NoLimit search to these escrows. Omitted or empty arrays use the client's configured escrow
excludedPayToValuesstring[]NoPayee identifiers to exclude, for example a maker already tried for this order; maximum 100 values
includeNearbyQuotesbooleanNoInclude suggestions at other amounts when no exact match exists; defaults to false
nearbySearchRangenumberNoMaximum percentage deviation, 1-100 (10 = plus/minus 10%). Omit for no percentage limit
nearbyQuotesCountnumberNoSuggestions per direction, 1-10; defaults to 3
Migrating older quote requests

includePrivateOrderbooks and intentGatingService are no longer fields in the published quote request types. Use mode for eligibility; whitelist access is evaluated for user. all is an orderbook browsing mode and is rejected by quote endpoints.

Quote modes​

These values apply to both quote methods. mode controls which deposits the taker may access; it is independent of quotePreference.

modeBehavior
eligibleDefault. Direct-route quotes: public deposits without disputes, plus whitelist-enabled deposits where user is whitelisted. A whitelisted taker can use the direct route without locking dispute stake
eligible_with_chargebackAlso includes dispute-route quotes, even when the user has insufficient free stake. Stake must be available to lock when signaling such an intent
eligible_with_chargeback_stakedAlso includes dispute-route quotes, but only when the user's current free stake covers the required signal amount

eligible_with_chargeback_staked is a subset of eligible_with_chargeback. Eligibility and free stake can change between quoting and signaling; a quote does not reserve either liquidity or stake.

Quote preferences​

Use the singular field name quotePreference. SAR means Seller Automated Release; Buyer TEE means buyer-provided payment verification.

quotePreferenceSearch behavior
OmittedBuyer TEE / non-SAR pool only, with no SAR fallback
EXCLUSIVE_SARSAR pool only
PREFER_SARSAR first, then Buyer TEE / non-SAR fallback
PREFER_BUYER_TEEBuyer TEE / non-SAR first, then SAR fallback
EXCLUSIVE_BUYER_TEEBuyer TEE / non-SAR pool only

For getQuote, a preferred pass with exact matches ends the search; fallback is not used to fill the requested count with another pool. For getQuotesBestByPlatform, fallback fills platforms missing a best quote while preserving the primary pass's available quotes. SAR availability is evaluated from live seller credentials, not just whether the platform supports automation.

Per-call options​

Both methods accept these fields in the second argument:

OptionTypeDescription
baseApiUrlstringOverride the service root for this call; omit version suffixes. Defaults to the client's configured API root
timeoutMsnumberOverride the API timeout in milliseconds. Defaults to the client's timeouts.api
import type { QuoteRequest } from "@zkp2p/sdk";

const request = {
paymentPlatforms: ["wise"],
fiatCurrency: "USD",
user: "0x0000000000000000000000000000000000000001",
recipient: "0x0000000000000000000000000000000000000002",
destinationChainId: 8453,
destinationToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
amount: "100000000", // 100 USD, in 6-decimal units
isExactFiat: true,
mode: "eligible",
quotePreference: "PREFER_SAR",
quotesToReturn: 3,
includeNearbyQuotes: true,
nearbySearchRange: 10,
nearbyQuotesCount: 3,
} satisfies QuoteRequest;

const quote = await client.getQuote(request, { timeoutMs: 15_000 });

for (const match of quote.responseObject.quotes) {
console.log(match.payeeData.offchainId, match.tokenAmountFormatted);
}

Quote responses​

getQuote() returns GetQuoteResponse, with { success, message, statusCode, responseObject }. The response object includes:

FieldDescription
quotesArray of matched quotes
nearbySuggestionsOptional { below, above } arrays when nearby discovery is enabled and no exact match exists. Each entry contains a quote and suggested amount / percentage difference fields
fiat, token, feesCurrency, token metadata (including decimals), and aggregate fee information
quoteExpiresAtQuote expiration timestamp
orchestratorAddressOrchestrator used for routing
modeEffective eligibility mode

Each quote includes:

  • fiatAmount, tokenAmount, and their Formatted variants; conversionRate and optional takerConversionRate use 18-decimal precision.
  • intent, including depositId, escrowAddress, optional orchestratorAddress, processorName, payeeDetails, amount, and recipient/currency data.
  • maker.offchainId and SDK-derived payeeData.offchainId. The SDK drops quotes with missing maker identity; payeeData is no longer a rich metadata lookup gated on API-key authentication.
  • Optional signalIntentAmount (gross token base units to pass to signalIntent()), fee amount/display fields, and serviceFeeBps / takerReferralFeeBps. Keep the referral fees used for signaling consistent with the quote request.
  • whitelistEnabled, allowedGroupIds, disputeProtectionOptedOut, and disputeProtectionRequiresStake for access and stake UX.
  • Optional sellerAutomatedReleaseAvailable, indicating live, fresh seller automation credentials for this quote.

The SDK adds the compatibility fields referrerFeeAmount, referrerFeeAmountFormatted, and referrerFeeBps when referrerFeeConfig is supplied. Do not assume these SDK-derived display fields are populated for referralFees-only requests.

getQuotesBestByPlatform(req, opts?)​

Fetch one best quote per supported platform. The SDK calls POST /v3/quote/best-by-platform by default, or POST /v3/quote/best-by-platform-exact-token when isExactFiat: false.

Request fieldTypeRequiredDescription
fiatCurrencystringYesFiat currency code
userstringYesTaker EVM address used for eligibility and stake checks
recipientstringYesAsset recipient EVM address
destinationChainIdnumberYesDestination chain ID; currently Base (8453)
destinationTokenstringYesDestination token EVM address
amountstringYesSame positive integer base-unit encoding as getQuote
isExactFiatbooleanNoDefaults to true
modeQuoteVisibilityModeNoSame modes; defaults to eligible
quotePreferenceQuotePreferenceNoSame preferences, with fallback per missing platform
referrerstringNoReferrer attribution
referrerFeeConfigReferrerFeeConfigNoSingle referral fee configuration
referralFeesReferrerFeeConfig[]NoReferral fee list; same limit and precedence as getQuote
escrowAddressesstring[]NoLimit to specific escrows; omitted or empty uses the client's configured escrow
excludedPayToValuesstring[]NoPayee identifiers to exclude; maximum 100
minDepositSuccessRateBpsnumberNoMinimum maker success rate, 0-10000 basis points
supportBusinessAccountsbooleanNoAllow business-account quotes; defaults to false

This request searches all supported platforms: it has no paymentPlatforms, quotesToReturn, useMultihop, or nearby-search options. Although Curator's exact-quote API accepts additional filters, the SDK only exposes minDepositSuccessRateBps and supportBusinessAccounts on QuotesBestByPlatformRequest.

The result is GetBestByPlatformResponse. Its responseObject has the same metadata, expiry, orchestrator, and mode fields as getQuote, with platformQuotes instead of quotes. Each entry contains { platform, supported, available, bestQuote? }; check availability before using bestQuote. Best quotes have the same SDK-derived payee identity and fee display behavior as getQuote.

const best = await client.getQuotesBestByPlatform(
{
fiatCurrency: "USD",
user: "0x0000000000000000000000000000000000000001",
recipient: "0x0000000000000000000000000000000000000002",
destinationChainId: 8453,
destinationToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
amount: "100000000", // Receive exactly 100 USDC (6 decimals)
isExactFiat: false,
mode: "eligible_with_chargeback_staked",
quotePreference: "PREFER_BUYER_TEE",
supportBusinessAccounts: false,
},
{ timeoutMs: 15_000 },
);

for (const { platform, available, bestQuote } of best.responseObject
.platformQuotes) {
if (!available || !bestQuote) continue;
console.log(
platform,
bestQuote.intent.depositId,
bestQuote.payeeData.offchainId,
);
}

Referral account APIs​

Use these methods when your app needs to create, redeem, rename, or read Peer referral codes. Referral identity is keyed by wallet address. Privy bearer tokens are still supported for Peer-account flows, but external integrations can use wallet signatures without creating Privy users.

Public reads do not send auth headers and can be called from any browser origin:

MethodCurator pathDescription
getReferralDashboard({ address })GET /v2/referral?address=0x...Read a referrer's code, redemption state, reward rates, referee counts, and lifetime fees
getReferralEarnings({ address })GET /v2/referral/earnings?address=0x...Read the earnings breakdown for a referrer wallet
lookupReferralCode(code)GET /v2/referral/code/{code}Resolve a code to { code, referrerWalletAddress, isActive }

Bearer-authenticated writes use authorizationToken or getAuthorizationToken from the client or per-call options:

MethodCurator pathDescription
createReferralCode(opts?)POST /v2/referral/codeCreate or fetch the caller's own code
redeemReferralCode(code, opts?)POST /v2/referral/redeemRedeem another user's code for the authenticated wallet
updateReferralCode(code, opts?)PATCH /v2/referral/codeRename the authenticated wallet's code

Signature-authenticated writes use the configured viem walletClient and require no Privy account:

MethodRequired optionsDescription
createReferralCodeWithSignature(opts?)NoneSigns and posts the CreateCode payload
redeemReferralCodeWithSignature(code, opts?)Optional referrerWalletAddressSigns RedeemCode; if referrerWalletAddress is omitted, the SDK first calls lookupReferralCode(code)
updateReferralCodeWithSignature(code, opts)oldCodeSigns RenameCode; oldCode prevents stale rename replay
import { Zkp2pClient } from "@zkp2p/sdk";

const client = new Zkp2pClient({
walletClient,
chainId: 8453,
});

const dashboard = await client.getReferralDashboard({
address: "0x1111111111111111111111111111111111111111",
});

const lookup = await client.lookupReferralCode("PEER42");

const { code: myCode } = await client.createReferralCodeWithSignature();

await client.redeemReferralCodeWithSignature("PEER42", {
referrerWalletAddress: lookup.referrerWalletAddress,
});

await client.updateReferralCodeWithSignature("MYCODE", {
oldCode: myCode,
});

The signature domain is:

{ name: 'ZKP2PReferral', version: '1' }

The SDK signs issuedAt as Unix seconds and defaults production signatures to audience base_production. Override audience when using a non-production API environment. Server-side freshness is 10 minutes, with a small future clock-skew allowance. Do not combine a bearer token and signature body on the same write; curator requires exactly one auth mode.

Rate limits are per minute: public dashboard and earnings reads are 30 per IP, code lookup is 60 per IP, and writes are limited to 20 per IP plus 10 per IP-wallet pair.

Seller Autopilot​

Use these methods to upload seller credentials, inspect credential status, and verify seller payments for Seller Autopilot flows. Supported seller platforms are venmo, cashapp, wise, and paypal.

Seller credential upload and identity attestation are different flows. Identity attestation proves an account identity for registration. Seller Autopilot stores an encrypted credential bundle that lets the enclave verify future seller-side payments. New Venmo and PayPal connections use the Google OAuth helper. The low-level encrypted-bundle API still supports backend Venmo cookie credentials, including already-stored credentials; cookie capture is not a client onboarding option. Curator status is keyed by { processorName, payeeDetails }, not maker id.

uploadSellerCredential()​

Use uploadSellerCredential(params, opts?) to create a signed credential bundle through the attestation service and store the public credential status in curator. Returns CuratorSellerCredentialUploadResponse.

For Cash App, pass the seller identity plus platform-specific session material:

FieldRequiredDescription
platformYescashapp
offchainIdYesStable seller identity used for payee registration
payeeIdYesPlatform payee identifier
telegramUsernameNoOptional seller Telegram username
metadataNoOptional curator metadata
sessionMaterialYesPlatform-specific session material
callerAddressNoOptional caller wallet address forwarded to the attestation service with the bundle request

For Wise, pass only the platform and Wise session material. The enclave derives the payee hash from the submitted token:

FieldRequiredDescription
platformYeswise
sessionMaterial.apiTokenYesWise Personal API Token
sessionMaterial.profileIdNoWise profile identifier. If omitted and multiple profiles exist, handle the profile-selection response
callerAddressNoOptional caller wallet address forwarded to the attestation service with the bundle request

Optional opts fields:

FieldRequiredDescription
baseApiUrlNoOverride for the curator base API URL
attestationServiceUrlNoOverride for the attestation service used to sign the credential bundle
attestationServiceFallbackUrlsNoAlternate attestation-service origins tried after network failures; pass [] to disable fallback
timeoutMsNoRequest timeout in milliseconds
attestationRuntimeNoRuntime overrides for fetch, subtle, or getRandomValues

CashAppSessionMaterial

FieldRequiredDescription
recipientCashtagYesCash App cashtag that receives the seller payment
customerIdYesCash App customer identifier
sessionCookieYesAuthenticated Cash App session cookie
requestHeadersNoOptional request headers captured from the authenticated session
requestPayloadYesCaptured Cash App request payload used during verification

WiseSessionMaterial

FieldRequiredDescription
apiTokenYesWise API token
profileIdNoWise profile identifier
import { Zkp2pClient } from "@zkp2p/sdk";

const client = new Zkp2pClient({
walletClient,
chainId: 8453,
});

const response = await client.uploadSellerCredential(
{
platform: "cashapp",
offchainId: "peer-seller",
payeeId: "123456789",
sessionMaterial: {
recipientCashtag: "peer-seller",
customerId: "123456789",
requestPayload: capturedRequestBody,
sessionCookie: "session_cookie",
requestHeaders: {
"user-agent": "Mozilla/5.0",
},
},
},
{ timeoutMs: 10_000 },
);

uploadSellerCredentialBundle()​

Use uploadSellerCredentialBundle(params, opts?) when the encrypted credential bundle was already created elsewhere — typically inside a capture extension via apiCreateSellerCredentialBundle() — and you only need to register the payee and store the bundle with curator. This is the page-side half of the extension Seller Autopilot capture flow.

For registered payee platforms (venmo and cashapp):

FieldRequiredDescription
platformYesvenmo or cashapp
offchainIdYesStable seller identity used for payee registration
bundleYesEncrypted SellerCredentialBundle returned by the capture
telegramUsernameNoOptional seller Telegram username
metadataNoOptional curator metadata

For Wise, pass only platform: 'wise' and the bundle. Optional opts fields are baseApiUrl and timeoutMs. The client forwards its resolved authorization token to curator when one is configured.

For registered payee platforms, this helper:

  1. Calls curator POST /v2/makers/create with the supplied offchainId, optional telegramUsername, optional metadata, and processorName.
  2. Verifies the returned hashedOnchainId equals bundle.payeeIdHash.
  3. Stores the bundle with curator POST /v2/makers/{platform}/{hashedOnchainId}/seller-credential.

The hash check is required. It prevents a tampered capture from binding an encrypted credential bundle to different public payee details.

const response = await client.uploadSellerCredentialBundle({
platform: "cashapp",
offchainId: capture.offchainId,
bundle: capture.credentialBundle,
});

Hosted Venmo receipt linking​

For partner cash-out onboarding, use stable @zkp2p/cash@0.6.1 and its optional receipt-linking methods. Cash handles registration and environment selection. Linking never gates cashout() or prepare().

Direct @zkp2p/sdk@0.14.2 consumers can call the top-level getVenmoGmailConnectUrl({ payeeDetails, peerOrigin }) or openVenmoGmailConnect({ payeeDetails, peerOrigin }) for an already-registered Venmo payee hash. Call the popup helper directly from a click handler. It resolves { payeeDetails } and rejects with VenmoGmailConnectError, preserving codes such as venmo_google_oauth_receipt_not_found. Google-hosted school and custom domains are verified by receipts, not rejected by email suffix.

The Peer-hosted page owns Google consent and code upload; partners receive no Google codes, tokens, or email contents. Use the matching Peer/Curator environment and read getSellerCredentialStatus() after returning or an ambiguous popup closure. Only active plus google_oauth means linked. Native/redirect hosts can open the generated URL and read status on return. See the flow specification.

uploadGoogleOAuthSellerCredential()​

Use uploadGoogleOAuthSellerCredential(params, opts?) when curator owns the Google OAuth encryption hop for PayPal or Venmo credentials. This is the lower-level code-upload API used by the hosted flow; partner apps should use the hosted linking helpers above.

FieldRequiredDescription
platformYespaypal or venmo
authorizationCodeYesOne-time Google OAuth code
payeeDetailsYesHashed payee details
redirectUriYesOAuth redirect URI used to obtain the code
payeeEmailPayPal onlyPayPal seller email

This helper posts to curator POST /v2/makers/{platform}/{payeeDetails}/seller-credential/google-oauth. The payeeDetails value is the registered maker hash returned by /v2/makers/create. For Venmo, Curator resolves the numeric account ID from the registered username and verifies the identity hash before exchanging the Google code; do not send an account ID. All Venmo connect and reconnect UI uses this Gmail flow. Existing stored cookie credentials remain usable; the backend dual-credential wire API is separate from client onboarding.

getSellerCredentialStatus()​

Use getSellerCredentialStatus(params, opts?) to fetch public seller credential status from curator. Returns CuratorSellerCredentialStatusResponse.

FieldRequiredDescription
processorNameYesSeller payment platform: venmo, cashapp, wise, or paypal
payeeDetailsYesHashed payee details bytes32

Optional opts fields:

FieldRequiredDescription
baseApiUrlNoOverride for the curator base API URL
timeoutMsNoRequest timeout in milliseconds

The SDK calls curator GET /v2/makers/{processorName}/{payeeDetails}/seller-credential/status. The public status DTO is { platform, payeeIdHash, status, credentialType }; maker row ids are intentionally not returned.

import { Zkp2pClient } from "@zkp2p/sdk";

const client = new Zkp2pClient({
walletClient,
chainId: 8453,
});

const response = await client.getSellerCredentialStatus(
{
processorName: "paypal",
payeeDetails:
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
},
{ timeoutMs: 10_000 },
);

verifySellerPayment()​

Use verifySellerPayment(params, opts?) to verify a seller payment through curator's seller-credential proxy. Returns CuratorSellerVerifyResponse.

Internal-only authentication

verifySellerPayment() requires curator's internal x-api-key, not standard SDK consumer keys. It returns 410 GONE when the seller credential is inactive or fails a re-probe.

FieldRequiredDescription
platformYesSeller payment platform: venmo, cashapp, wise, or paypal
txIdYesPayment transaction identifier to verify
chainIdYesChain ID associated with the verification request
intentYesSellerVerifyIntentDetails payload for the seller payment verification
metadataNoOptional metadata object forwarded to the curator proxy

Optional opts fields:

FieldRequiredDescription
baseApiUrlNoOverride for the curator base API URL
timeoutMsNoRequest timeout in milliseconds
import { Zkp2pClient, type SellerVerifyIntentDetails } from "@zkp2p/sdk";

declare const sellerVerifyIntentDetails: SellerVerifyIntentDetails;

const client = new Zkp2pClient({
walletClient,
chainId: 8453,
});

const response = await client.verifySellerPayment(
{
platform: "wise",
txId: "transfer_123",
chainId: 8453,
intent: sellerVerifyIntentDetails,
},
{ timeoutMs: 10_000 },
);

Standalone API and attestation helpers​

The package also exports low-level helpers for integrations that call service APIs directly instead of going through Zkp2pClient.

HelperPurpose
apiGetOrderbook(params, opts)Fetch orderbook entries for a fiat currency, optional platform, sort, limit, chain, and token
apiGetOrderbookTable(params, opts)Fetch aggregated orderbook table rows from /v3/orderbook/table with the same params as apiGetOrderbook()
apiGetDepositBundle(params, opts)Fetch one deposit with related intents, events, profit snapshots, fund activities, and daily snapshots
apiValidatePayeeDetails(req, baseApiUrl, timeoutMs?)Validate a payee identity before registration
apiGetPayeeDetails(req, baseApiUrl, timeoutMs?)Resolve curator payee details from a hashed on-chain ID
apiGetOwnerDeposits(req, apiKey, baseApiUrl, authToken?, timeoutMs?)Fetch owner deposits from the service API
apiGetReferralDashboard(opts)Low-level referral dashboard read; pass address for public mode or authorizationToken for caller mode
apiGetReferralEarnings(opts)Low-level referral earnings read; pass address for public mode or authorizationToken for caller mode
apiLookupReferralCode(code, opts)Resolve a referral code to its owner wallet and active status
apiCreateReferralCode(req, opts)Create or fetch a referral code with bearer auth or a signature body
apiRedeemReferralCode(req, opts)Redeem a referral code with bearer auth or a signature body
apiUpdateReferralCode(req, opts)Rename a referral code with bearer auth or a signature body
createNitroAttestationClient(opts)Verify the Nitro enclave and request typed identity attestations, Buyer TEE attestations, or seller credential bundles through @zkp2p/zkp2p-attestation
apiRequestIdentityAttestation(payload, attestationServiceUrl, platform, actionType, options?)Request an identity attestation from POST /identity after session material has already been encrypted
createEncryptedBuyerTeeSessionMaterial(input)Encrypt buyer TEE session material for a buyer-payment proof
apiCreateSellerCredentialBundle(payload, attestationServiceUrl, platform, timeoutMs?, runtime?, options?)Create a signed seller credential bundle directly through attestation service
apiUploadSellerCredentialBundle(params, baseApiUrl?, timeoutMs?, authorizationToken?)Register payee details if needed, verify the bundle payee hash, and store an encrypted seller credential bundle with curator

apiGetOrderbook() accepts { currency, paymentPlatform?, mode?, takerAddress?, sortBy?, sortDirection?, sellerAutomatedRelease?, limit?, offset?, amount?, showSmallOrders?, hideExtremeSpread?, chainId?, token? }. mode takes the OrderbookVisibilityMode values all, eligible, or eligible_with_chargeback. sellerAutomatedRelease takes 'include' | 'exclude' | 'only' to control how Seller Autopilot liquidity appears in results. apiGetDepositBundle() accepts { depositId, escrowAddress, dailySnapshotLimit? }.

Querying on-chain data​

For common read flows, start with the RPC-first methods:

  • getDeposits()
  • getAccountDeposits(owner)
  • getDeposit(depositId)
  • getDepositsById(ids)
  • getIntents()
  • getAccountIntents(owner)
  • getIntent(intentHash)
  • getPvDepositById(depositId)
  • getPvDepositsFromIds(ids)
  • getPvAccountDeposits(owner)
  • getPvAccountIntents(owner)
  • getPvIntent(intentHash)
  • resolvePayeeHash(depositId, paymentMethodHash)
  • getFulfillIntentInputs(intentHash)
  • getDepositPreIntentHook(depositId, options?)
  • getDepositWhitelistHook(depositId, options?)
  • getDeployedAddresses()
  • getUsdcAddress()

For copy-paste examples around deposits and intents, see Offramp Integration.

Indexer​

Use client.indexer when you need historical data, richer filtering, or pagination across all deposits and intents. All methods live on a flat namespace.

The stable SDK uses @zkp2p/indexer-schema@0.22.0. Its default GraphQL endpoints are https://indexer.zkp2p.xyz/v1/graphql for production, https://indexer-preprod.zkp2p.xyz/v1/graphql for preproduction, and https://indexer-staging.zkp2p.xyz/v1/graphql for staging. Use indexerUrl only for an explicit override. Indexer history can lag a confirmed transaction; use the receipt and on-chain reads to establish confirmation.

Deposit queries​

  • getDeposits(filter?, pagination?)
  • getDepositsWithRelations(filter?, pagination?, options?)
  • getDepositById(compositeId, options?)
  • getDepositsByIds(ids)
  • getDepositsByIdsWithRelations(ids, options?)
  • getDepositsByPayeeHash(payeeHash, options?)

Intent queries​

  • getIntentsForDeposits(depositIds, statuses?)
  • getOwnerIntents(owner, statuses?)
  • getIntentsByRateManager(rateManagerId, statuses?)
  • getIntentByHash(intentHash)
  • getExpiredIntents({ now, depositIds, limit? })
  • getFulfilledIntentEvents(intentHashes) — fulfillment events, including takerAmountNetFees
  • getIntentFulfillmentAmounts(intentHash) — includes takerAmountNetFees, the net USDC the taker received after fees
  • getFulfillmentAndPayment(intentHash)

Fund activity and snapshots​

  • getDepositFundActivities(depositId)
  • getMakerFundActivities(depositor, limit?)
  • getDepositDailySnapshots(depositId, limit?)
  • getProfitSnapshotsByDeposits(depositIds)

Rate manager (vault) queries​

  • getRateManagers(pagination?, filter?)
  • getRateManagerDetail(managerId, options?)
  • getRateManagerDelegations(managerId, pagination?)
  • getDelegationForDeposit(depositId, options?)
  • getManagerDailySnapshots(managerId, options?)
  • getManualRateUpdates(managerId, options?)
  • getOracleConfigUpdates(managerId, options?)

Staking query​

  • getStakingState({ chainId, environment, vaultAddress, disputeProtectionPolicyAddress, taker, stakeOwner })
  • getStakeLocks({ chainId, vaultAddress, stakeOwner, status?, limit?, cursor? })
  • getTakerStakeAuthorizations({ chainId, vaultAddress, stakeOwner | taker, authorized?, limit?, cursor? }) pages one side of the authorization graph: the takers a stake owner has authorized, or the stake owners that have authorized a taker
  • getStakeActivity({ chainId, vaultAddress, merchant, kind?, limit?, cursor? })
  • getDisputeProtectionIntents({ chainId, policyAddress, throughBlockNumber, limit?, cursor? })

The page methods return { items, nextCursor, asOf }. Pass opaque cursors back unchanged. Limits are integers from 1 through 100 and numeric fields are unsigned decimal strings. asOf is the latest row observed in that page, not an indexer-head or strong-consistency watermark.

throughBlockNumber is required for finalized disputes and applies an exact inclusive upper bound to disputedAtBlockNumber. Choose the finalized cutoff in application code and reuse it for every cursor in one ingestion pass. The dispute page also returns endCursor, the opaque cursor of its last item even when nextCursor is null; it is null only for an empty page. Follow nextCursor within a pass, then persist the terminal endCursor with the committed block/log position for the next poll.

Raw access​

  • query<T>({ query, variables? }) — raw GraphQL
  • client — raw IndexerClient instance

The package also exports IndexerRateManagerService and the standalone helper fetchIndexerFulfillmentAndPayment(client.indexer.client, intentHash).

Indexer converters​

The SDK exports converter helpers for turning indexer payloads into the same EscrowDepositView shape produced by RPC reads.

HelperPurpose
convertIndexerDepositToEscrowView(deposit, chainId, escrowAddress)Converts a single indexer deposit (with relations) into an EscrowDepositView
convertDepositsForLiquidity(deposits, chainId, escrowAddress, options?)Filters and converts indexer deposits into the active liquidity set used by takers. Pass { includePrivateOrderbooks: true } to also include deposits gated by a non-zero whitelist hook (defaults to false, public orderbooks only)
convertIndexerIntentsToEscrowViews(intents, depositViewsById)Converts indexer intents into EscrowIntentView[]

Oracle helpers​

The SDK exports helper constants and encoders for oracle-backed ARM spread pricing.

HelperPurpose
getSpreadOracleConfig(currency, adapters?)Resolve the bundled Chainlink oracle config for a fiat currency
encodeSpreadOracleAdapterConfig(config)Encode Chainlink adapter config
encodePythAdapterConfig(config)Deprecated compatibility encoder for custom Pyth configs
validateOracleFeedsOnChain(publicClient, pythContract?)Return currencies whose bundled feeds are available on-chain
supportsInlineOracleRateConfig({ escrowAddress? })Client method that reports whether the target Escrow ABI accepts inline oracle configs

Useful constants include CHAINLINK_ORACLE_ADAPTER, DEFAULT_ORACLE_MAX_STALENESS_SECONDS, CHAINLINK_ORACLE_FEEDS, and its deprecated alias SPREAD_ORACLE_FEEDS. PYTH_ORACLE_ADAPTER, PYTH_ORACLE_FEEDS, and encodePythAdapterConfig() remain compatibility exports; the bundled Pyth feed map is empty and is not an automatic fallback.

Referrer fees​

Use these helpers when you want to validate or normalize referrer fee settings before calling getQuote() or signalIntent().

HelperPurpose
assertValidReferrerFeeConfig(config, context)Throws if the config is invalid for getQuote, getQuotesBestByPlatform, or signalIntent
isValidReferrerFeeRecipient(value)Checks whether a referrer fee recipient is a valid address
isValidReferrerFeeBps(value)Checks whether a BPS value is allowed
parseReferrerFeeConfig(recipient, feeBpsValue)Builds a ReferrerFeeConfig from loosely typed input
referrerFeeConfigToPreciseUnits(config)Converts the fee config into precise units for on-chain use

Attribution​

The SDK includes ERC-8021 helpers for Base builder attribution.

HelperPurpose
getAttributionDataSuffix(referrer?)Builds the attribution suffix
appendAttributionToCalldata(calldata, referrer?)Appends attribution to existing calldata
encodeWithAttribution(request, referrer?)Encodes calldata and appends attribution in one step
sendTransactionWithAttribution(walletClient, request, referrer?, overrides?)Sends a transaction with appended attribution

Useful constants:

  • BASE_BUILDER_CODE
  • ZKP2P_IOS_REFERRER
  • ZKP2P_ANDROID_REFERRER

Contract helpers​

HelperDescription
getContracts(chainId, env?)Returns deployed addresses and ABIs for escrow, orchestrator, verifier, ProtocolViewer, USDC, and related contracts
getRateManagerContracts(chainId, env?)Returns rate-manager registry/controller addresses and ABIs
getStakeVaultContract(chainId, env?)Returns the StakeVault address and ABI
getDisputeProtectionPolicyContract(chainId, env?)Returns the DisputeProtectionPolicy address and ABI
getOrchestratorV3Contract(chainId, env?)Returns the current OrchestratorV3 address and ABI
getPaymentMethodsCatalog(chainId, env?)Returns the platform-to-hash catalog used for payment-method resolution
getGatingServiceAddress(chainId, env?)Returns the signer used for intent gating

A constructed client also exposes client.getStakeVaultContract(), client.getOrchestratorV3Contract(), and client.getDisputeProtectionPolicyContract(), which return the coordinates already resolved for its chain and runtime environment.

Common companion helpers:

  • currencyInfo
  • getCurrencyInfoFromHash()
  • getCurrencyInfoFromCountryCode()
  • resolveFiatCurrencyBytes32()
  • resolvePaymentMethodHash()
  • resolvePaymentMethodHashFromCatalog()
  • resolvePaymentMethodNameFromHash()

Error handling​

SDK-specific errors extend ZKP2PError, except AccessPolicyUnsupportedError, which extends Error and is thrown by client.accessPolicy when WhitelistPolicy or AddressGroupRegistry is not deployed for the environment.

ClassCodeExtra fieldsUse it for
ZKP2PErrorAny ErrorCodedetails?, field?Shared base class
ValidationErrorVALIDATIONfield?, details?Invalid input
NetworkErrorNETWORKdetails?RPC or network failures
APIErrorAPIstatus?, details?Failed API requests
ContractErrorCONTRACTdetails?Contract call or simulation failures

Available error codes: VALIDATION, NETWORK, API, CONTRACT, UNKNOWN.

import {
APIError,
ContractError,
ValidationError,
ZKP2PError,
} from "@zkp2p/sdk";

try {
await client.createDeposit({
/* ... */
});
} catch (error) {
if (error instanceof ValidationError) {
console.error(error.field, error.message);
} else if (error instanceof APIError) {
console.error(error.status, error.message);
} else if (error instanceof ContractError) {
console.error(error.details);
} else if (error instanceof ZKP2PError) {
console.error(error.code, error.message);
}
}

Logging​

Use setLogLevel() to adjust SDK logging.

import { setLogLevel } from "@zkp2p/sdk";

setLogLevel("debug"); // 'debug' | 'info' | 'error'

Help?​

If you run into issues, join our Discord.