npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zkp2p/zkp2p-react-native-sdk

v0.4.3

Published

React Native SDK for ZKP2P

Readme

zkp2p-react-native-sdk

React Native SDK for ZKP2P - A peer-to-peer fiat-to-crypto on/off-ramp powered by zero-knowledge proofs.

Installation

bun add @zkp2p/zkp2p-react-native-sdk @react-native-async-storage/async-storage @preeternal/react-native-cookie-manager react-native-webview viem

iOS Setup

cd ios && pod install

Quick Start

The SDK supports two modes:

  • Full Mode: Access all features including blockchain operations (requires wallet & API key)
  • Proof-Only Mode: Generate proofs without wallet or API key

Full Mode Setup

import { Zkp2pProvider, useZkp2p } from '@zkp2p/zkp2p-react-native-sdk';
import { createWalletClient, custom } from 'viem';

// 1. Setup wallet client
const walletClient = createWalletClient({
  chain: base,
  transport: custom(window.ethereum),
});

// 2. Wrap your app with Zkp2pProvider
function App() {
  return (
    <Zkp2pProvider
      walletClient={walletClient}
      apiKey="your-api-key"
      chainId={8453} // Base
      rpcUrl="https://base-mainnet.g.alchemy.com/v2/your-key" // explicit RPC (recommended)
    >
      <YourApp />
    </Zkp2pProvider>
  );
}

Proof-Only Mode Setup

// No wallet or API key required!
function App() {
  return (
    <Zkp2pProvider
      chainId={8453} // Base
      // rpcUrl is optional here too if you want to pin to a specific endpoint
      // rpcUrl="https://base-sepolia.g.alchemy.com/v2/your-key"
    >
      <YourApp />
    </Zkp2pProvider>
  );
}

// 3. Use the SDK in your components
function PaymentFlow() {
  const {
    flowState,
    initiate,
    authenticate,
    prepareBuyerTeeProof,
    zkp2pClient, // null in proof-only mode
    proofData,
    metadataList,
    proofStatus,
  } = useZkp2p();

  // Check mode
  const isProofOnlyMode = !zkp2pClient;
  const isProofRunning = proofStatus.phase === 'running';

  // Your component logic
}

API Reference

Provider Props

| Prop | Type | Default | Description | | -------------------- | --------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | walletClient | WalletClient | Optional | Viem wallet client for blockchain interactions (required for full mode) | | apiKey | string | Optional | Your ZKP2P API key (required for full mode) | | chainId | number | 8453 | Blockchain chain ID (8453 for Base, 31337 for Hardhat) | | environment | 'production' \| 'staging' | 'production' | Environment (production or staging) | | preferV2ByDefault | boolean | false | Contract routing default. false keeps onramp/offramp on legacy V1 contracts until V2 rollout is enabled. | | baseApiUrl | string | 'https://api.zkp2p.xyz' | ZKP2P API base URL (versioned paths are appended by the SDK) | | rpcUrl | string | Optional | HTTP RPC endpoint for the selected chain (e.g., Alchemy/Infura/Base). If omitted, viem uses the chain default. | | configBaseUrl | string | 'https://raw.githubusercontent.com/zkp2p/providers/main/' | Provider configuration base URL | | storage | Storage | Optional | App-provided secure storage instance (e.g., SecureStore). Required to persist credentials/consent. | | renderProofStatus | (props) => ReactNode | Optional | If provided, SDK calls this renderer with proof visibility/status/cancel props. By default, the SDK renders no proof UI. | | renderConsentSheet | (props) => ReactNode | Optional | If provided, SDK renders this after visible login when consent is unset. Your component must call onAccept / onSkip / onDeny. |

Core Flow Functions

1. signalIntent(args)

Signal your intent to buy/sell crypto. This must be called before initiating the payment flow.

const { zkp2pClient } = useZkp2p();

const signalArgs = {
  depositId: '123', // The deposit ID you want to fulfill
  amount: '100', // Amount in USD
  // ... other contract parameters
};

const tx = await zkp2pClient.signalIntent(signalArgs);

2. initiate(platform, actionType, options?)

Start the payment proof generation flow. Opens payment provider authentication.

const { initiate } = useZkp2p();

const provider = await initiate('venmo', 'transfer_venmo', {
  // Optional: Auto-start with payment action
  initialAction: {
    enabled: true,
    paymentDetails: {
      RECIPIENT_ID: 'john-doe-123',
      AMOUNT: '100',
    },
  },
});

3. prepareBuyerTeeProof(provider, payload, selectedMetadata)

Prepare a buyer TEE payment proof from encrypted session material and the selected metadata row params.

const {
  authenticate,
  prepareBuyerTeeProof,
  provider,
  interceptedPayload,
  metadataList,
  zkp2pClient,
} = useZkp2p();

try {
  const proof = await prepareBuyerTeeProof(
    provider,
    interceptedPayload,
    metadataList[0] // selected display row; params are read directly from this row
  );

  await zkp2pClient.fulfillIntent({
    intentHash: '0x...',
    proof,
  });
} catch (error) {
  console.error('Payment verification failed:', error);
  // Fallback to manual authentication
  await authenticate('venmo', 'transfer_venmo');
}

Buyer-TEE is the only payment proof mechanism exposed by the provider.

4. authenticate(platform, actionType, options?)

Start the authentication flow for a specific provider. Useful for manual flows or when you want to drive the UI yourself.

const { authenticate } = useZkp2p();

await authenticate('venmo', 'transfer_venmo');

Note: Both `initiate(...)` and `authenticate(...)` start a new session and clear `proofData`, `metadataList`, and `interceptedPayload` to ensure no stale state carries into the new flow.

#### 4.1 `isSessionActive(platform, actionType, options?)`
Quickly check if a session is still valid before showing UI. This performs a read‑only network check using previously captured cookies. It does not mutate state or open any WebViews.

```ts
const { isSessionActive } = useZkp2p();

// Optionally pass a provider config you already have
const ok = await isSessionActive('venmo', 'transfer_venmo', {
  existingProviderConfig: providerConfig, // optional
});

if (ok) {
  // You can proceed directly to auto‑proof, or skip visible auth
} else {
  // Ask the user to authenticate()
}

Behavior:

  • Replays a read‑only request (same‑origin) with stored cookies. Mirrors the same replay + extraction path as the restore flow, including the XPath HTML Accept fallback. Returns true whenever the replay succeeds (i.e., session cookies are valid), regardless of whether any metadata items are extracted.

Notes:

  • Requires that a prior authentication captured an intercepted payload for the provider; if none is present, it returns false.
  • No UI side effects, no state changes — safe to call at app startup or before rendering auth screens.

Tip:

  • To check for the presence of metadata items, do not rely on isSessionActive. Instead, run your normal metadata fetch/restore flow and assert the resulting list length is greater than zero (e.g., metadataList.length > 0).

4.2 isInternalAction(platform, actionType, options?)

Returns a boolean indicating whether the initial payment action should route to the in‑app WebView (internal) as the primary path, mirroring the same decision logic as _handleInitialAction.

const { isInternalAction } = useZkp2p();

// With just platform/actionType (reads config)
const useInternal = await isInternalAction('venmo', 'transfer_venmo');

// Or pass an override to simulate runtime behavior
const useInternalWithOverride = await isInternalAction(
  'venmo',
  'transfer_venmo',
  {
    initialAction: { useExternalActionOverride: false },
  }
);

Decision rules:

  • If useExternalAction is true in provider config (or override is set to true), prefer external when available; otherwise fall back to internal if present.
  • Otherwise prefer internal when available; else external if present.
  • Returns false when neither action link is present.

Passing a custom RPC without the Provider

If you instantiate the client directly, pass rpcUrl on the options:

import { Zkp2pClient } from '@zkp2p/zkp2p-react-native-sdk';
import { base } from 'viem/chains';

const client = new Zkp2pClient({
  chainId: base.id,
  apiKey: 'your-api-key',
  rpcUrl: 'https://base-mainnet.g.alchemy.com/v2/your-key',
});

Credential Storage & Consent (SDK-managed)

The SDK can store credentials (username/password) per provider/action when the user consents. You supply:

  • storage: a Storage implementation (e.g., backed by SecureStore or AsyncStorage) via Zkp2pProvider.
  • renderConsentSheet: an app-owned bottom sheet or modal. The SDK will call it after a successful visible login when consent is unset. You call back:
    • onAccept → SDK stores credentials and writes provider consent.
    • onSkip → SDK does not store; consent remains unset (prompt again next time).
    • onDeny → SDK writes provider consent = 'denied' (no further prompts). Keys used internally (no need to manage these directly):
  • Credentials: zkp2p_cred_{keccak256(platform:actionType:url)}
  • Consent: zkp2p_consent_{keccak256(platform:actionType:url)}

Provider config must include login selectors. Optionally set a reveal timeout for invisible autofill flows:

{
  "mobile": {
    "login": {
      "usernameSelector": "#email, input[name=\"email\"]",
      "passwordSelector": "#password, input[name=\"password\"][type=\"password\"]",
      "submitSelector": "button[type=\"submit\"]",
      "revealTimeoutMs": 3000, // how long to keep the WebView minimized after submit before revealing
    },
  },
}

Exposing helpers (optional):

import { useZkp2p } from '@zkp2p/zkp2p-react-native-sdk';
import type { ProviderSettings } from '@zkp2p/zkp2p-react-native-sdk';

const ExampleComponent = ({ providerCfg }: { providerCfg: ProviderSettings }) => {
  const {
    clearAllCredentials,
    clearAllConsents,
    clearProviderCredentials,
    clearProviderConsent,
    getProviderConsent,
  } = useZkp2p();

  const handleClear = async () => {
    await clearAllCredentials();
    await clearAllConsents();
    await clearProviderCredentials(providerCfg);
    await clearProviderConsent(providerCfg);
    const consent = await getProviderConsent(providerCfg);
    console.log('Current consent', consent);
  };

  // ...
};

#### 5. `fulfillIntent(params)`
Complete the transaction by first posting your proof to the attestation service and then submitting the attestation on-chain.

Required params:
- `platform: string`, `actionType: string`
- `intentHash: Hash`
- `proof: BuyerTeePaymentProofInput`
- `amount: string`, `timestampMs: string`
- `fiatCurrency: Hex`, `conversionRate: string`
- `payeeDetails: Hex`, `timestampBufferMs: string`

```typescript
const { zkp2pClient } = useZkp2p();

await zkp2pClient.fulfillIntent({
  platform: 'revolut',
  actionType: 'transfer_revolut',
  intentHash: '0x…',
  proof,
  amount: '1000000',
  timestampMs: String(Date.now()),
  fiatCurrency: currencyInfo.USD.currencyCodeHash as Hex,
  conversionRate: '1000000000000000000',
  payeeDetails: '0x…' as Hex,
  timestampBufferMs: '10000000',
});

Notes:

  • SDK encodes paymentProof from the service responseObject and sets verificationData = abi.encode(['address'], [signer]).
  • No metadata is used from the service for on-chain verification.
  • ERROR_MESSAGE_MAP and toUserFriendlyError are re-exported from the package root for apps that want the SDK’s fulfill-simulation error copy.

Migration Reference: Updated Interfaces (0.1.0)

Use these as the “after” source of truth when upgrading.

// FulfillIntentParams
type FulfillIntentParams = {
  intentHash: Hash;
  proof: BuyerTeePaymentProofInput;
  platform: string;
  actionType: string;
  amount: string;
  timestampMs: string;
  fiatCurrency: Hex; // bytes32
  conversionRate: string; // 1e18 scaled
  payeeDetails: Hex; // bytes32
  timestampBufferMs: string;
  onSuccess?: ActionCallback;
  onError?: (error: Error) => void;
  onMined?: ActionCallback;
  txOverrides?: SafeTxOverrides;
};

// SignalIntentParams
type SignalIntentParams = {
  processorName: string;
  depositId: string;
  amount: string; // replaces tokenAmount
  payeeDetails: string;
  toAddress: Address; // was string
  paymentMethodHash?: Hex; // optional override
  currencyHash?: Hex; // replaces currency by code
  conversionRate: string | bigint;
  referrer?: Address;
  referrerFee?: string | bigint;
  escrowAddress?: Address; // optional routing override for V1 vs V2 deposits
  onSuccess?: ActionCallback;
  onError?: (error: Error) => void;
  onMined?: ActionCallback;
  txOverrides?: SafeTxOverrides;
};

// IntentSignalRequest (SDK → API)
type IntentSignalRequest = {
  processorName: string;
  payeeDetails: string;
  depositId: string;
  amount: string;
  toAddress: Address;
  paymentMethod: Hex;
  fiatCurrency: Hex;
  conversionRate: string;
  chainId: string;
  orchestratorAddress: Address;
  escrowAddress: Address;
};

// signalIntent(...) return value
type SignalIntentResult = {
  txHash: Hash;
};

// CreateDeposit
type CreateDepositConversionRate = {
  currency: CurrencyType; // e.g., Currency.USD
  conversionRate: string;
};

type CreateDepositParams = {
  token: Address;
  amount: bigint;
  intentAmountRange: { min: bigint; max: bigint };
  conversionRates: CreateDepositConversionRate[][]; // per payment method
  processorNames: string[];
  depositData: Record<string, string>[];
  // new optionals
  delegate?: Address;
  intentGuardian?: Address;
  referrer?: Address;
  referrerFee?: string | bigint;
  onSuccess?: ActionCallback;
  onError?: (error: Error) => void;
  onMined?: ActionCallback;
  txOverrides?: SafeTxOverrides;
};

// Auto-generate proof callback
type AutoGenerateProofOptions = {
  intentHash?: string;
  itemIndex?: number;
  onProofGenerated?: (proofData: ProofData | ProofData[]) => void;
  onProofError?: (error: Error) => void;
};

// AttestationResponse (service output used by encoders)
type AttestationResponse = {
  success: boolean;
  message: string;
  responseObject: {
    signature: Hex;
    signer: Address;
    typedDataSpec: {
      primaryType: string;
      types: Record<string, { type: string; name: string }[]>;
    };
    typedDataValue: { intentHash: Hex; releaseAmount: string; dataHash: Hex };
    encodedPaymentDetails: Hex;
    metadata: Hex;
  };
  statusCode: number;
};

Base API URL (versionless)

  • Set baseApiUrl to the root (e.g., https://api.zkp2p.xyz). Do not append /v1 or /v2; the SDK appends versioned paths internally.
  • Signal intent → /v2/verify/intent; quotes → /v1/quote/(exact-fiat|exact-token); makers → /v1/makers/create.

Hook Return Values

const {
  // State
  flowState, // Current flow state: 'idle' | 'authenticating' | 'authenticated' | 'actionStarted' | 'proofGenerating' | 'proofGeneratedSuccess' | 'proofGeneratedFailure'
  provider, // Current provider configuration
  proofData, // Generated proof data (ProofData[])
  metadataList, // List of transactions from authentication
  authError, // Authentication error if any
  proofError, // Proof generation error if any
  interceptedPayload, // Network event data from authentication
  authWebViewProps, // Props for the authentication WebView

  // Methods
  initiate, // Start the flow
  authenticate, // Manual authentication
  prepareBuyerTeeProof, // Prepare buyer TEE proof from selected metadata params
  closeAuthWebView, // Close authentication modal
  clearSession, // Clear cookies/storage for a fresh login
  resetState, // Reset in-memory SDK state and cancel background work

  // Client
  zkp2pClient, // Direct access to contract methods (null in proof-only mode)
} = useZkp2p();

Complete Flow Example

function BuyCrypto() {
  const {
    flowState,
    initiate,
    authenticate,
    prepareBuyerTeeProof,
    zkp2pClient,
    metadataList,
    provider,
    interceptedPayload
  } = useZkp2p();

  const handleBuy = async () => {
    try {
      const signalTx = await zkp2pClient.signalIntent({
        processorName: 'venmo',
        depositId: '123',
        tokenAmount: '100',
        payeeDetails: '0x1234567890123456789012345678901234567890',
        toAddress: '0x0000000000000000000000000000000000000000',
        currency: 'USD',
      });

      const intentHash = signalTx.responseObject.signedIntent;

      await initiate('venmo', 'transfer_venmo', {
        initialAction: {
          enabled: true,
          paymentDetails: {
            venmoUsername: 'crypto-seller',
            note: 'Cash',
            amount: '100.00'
          }
        },
      });

      await authenticate('venmo', 'transfer_venmo');

      if (!provider || !interceptedPayload || !metadataList[0]) return;
      const proof = await prepareBuyerTeeProof(
        provider,
        interceptedPayload,
        metadataList[0]
      );
      const fulfillTx = await zkp2pClient.fulfillIntent({
        proof,
        intentHash,
        onSuccess: (tx) => console.log('Transaction complete:', tx.hash),
        onError: (error) => console.error('Fulfillment failed:', error),
      });
      console.log('Transaction complete:', fulfillTx.hash);

    } catch (error) {
      console.error('Buy flow failed:', error);
    }
  };

  return (
    <View>
      <Button onPress={handleBuy} title="Buy Crypto" />
      <Text>Status: {flowState}</Text>
    </View>
  );
}

Flow States

  • idle - No active operation
  • actionStarted - Payment action initiated (Venmo/CashApp/etc opened)
  • authenticating - User authenticating with payment provider
  • authenticated - Authentication complete, transactions available
  • proofGenerating - Generating zero-knowledge proof
  • proofGeneratedSuccess - Proof successfully generated
  • proofGeneratedFailure - Proof generation failed

Custom Proof UI

The provider is headless by default for TEE proof flows. To show proof progress, either pass renderProofStatus or read the live status from context:

<Zkp2pProvider
  renderProofStatus={({ visible, proofStatus, onCancel }) =>
    visible ? (
      <YourProofSheet
        progress={proofStatus.progress}
        message={proofStatus.meta}
        status={proofStatus.phase}
        error={proofStatus.error}
        onCancel={onCancel}
      />
    ) : null
  }
>
  <App />
</Zkp2pProvider>
function App() {
  return (
    <Zkp2pProvider>
      <HeadlessProofScreen />
    </Zkp2pProvider>
  );
}

function HeadlessProofScreen() {
  const { proofStatus, cancelProof } = useZkp2p();

  if (proofStatus.phase === 'idle') return null;

  return (
    <YourCustomIndicator
      progress={proofStatus.progress}
      message={proofStatus.meta}
      status={proofStatus.phase}
      error={proofStatus.error}
      onCancel={cancelProof}
    />
  );
}

proofStatus updates as the proof lifecycle progresses:

  • phase: 'idle' | 'running' | 'success' | 'failure'
  • progress: normalized value from 0 to 1
  • meta: human-readable status message
  • error: latest proof error (if any)

Call cancelProof() from your UI to stop active proof work. Re-running prepareBuyerTeeProof(...) after a failure reinitializes proof state. For a full reset, call resetState().

Supported Platforms and Actions

| Platform | Action Types | Description | | -------- | ------------------ | ------------------- | | Venmo | transfer_venmo | Venmo P2P transfers | | Cash App | transfer_cashapp | Cash App transfers | | Revolut | transfer_revolut | Revolut transfers | | Wise | transfer_wise | Wise transfers | | Zelle | transfer_zelle | Zelle transfers | | Chime | transfer_chime | Chime transfers | | PayPal | transfer_paypal | PayPal transfers | | Monzo | transfer_monzo | Monzo transfers |

Error Handling

// Check authentication errors
const { authError } = useZkp2p();
if (authError) {
  console.error('Auth failed:', authError.message);
}

// Handle proof generation errors
try {
  await prepareBuyerTeeProof(provider, interceptedPayload, selectedMetadata);
} catch (error) {
  console.error('Proof generation failed:', error);
}

Advanced Configuration

Custom User Agent

The SDK allows configuring custom user agents per provider in the provider configuration:

provider.mobile?.userAgent = {
  ios: 'Custom iOS User Agent',
  android: 'Custom Android User Agent',
};

Resetting SDK State

  • resetState() — Resets internal SDK state and cancels background work:

    • Aborts pending RPC requests and remounts the RPC bridge
    • Clears proofData, metadataList, interceptedPayload
    • Closes/minimizes auth webview and resets flow to idle
  • clearSession(options?) — Clears persisted cookies/storage used for web auth. Use this to force fresh logins. It does not cancel native tasks by itself.

Client Methods

Contract Interactions

const { zkp2pClient } = useZkp2p();

// Available methods:
zkp2pClient.signalIntent(params); // Signal buy/sell intent
zkp2pClient.fulfillIntent(params); // Complete transaction with proof
zkp2pClient.createDeposit(params); // Create new deposit
zkp2pClient.withdrawDeposit(params); // Withdraw deposit
zkp2pClient.cancelIntent(params); // Cancel pending intent
zkp2pClient.releaseFundsToPayer(params); // Release escrowed funds

// Query methods:
zkp2pClient.getQuote(params); // Get price quotes
zkp2pClient.getPayeeDetails(params); // Get payee information
zkp2pClient.getAccountDeposits(address); // Get user's deposits
zkp2pClient.getAccountIntents(address); // Get user's intents (array)

// Utility methods:
zkp2pClient.getUsdcAddress(); // Get USDC contract address
zkp2pClient.getDeployedAddresses(); // Get all contract addresses

Quote Params

Required

  • paymentPlatforms: string[]
  • fiatCurrency: string
  • user: string — taker address
  • recipient: string — on-chain recipient
  • destinationChainId: number
  • destinationToken: string
  • amount: string — use isExactFiat to indicate fiat vs token units

Optional

  • isExactFiat?: boolean — defaults to true
  • quotesToReturn?: number — API limits server-side
  • referrer?: string, useMultihop?: boolean
  • escrowAddresses?: string[] — override the escrow(s) used for quoting; defaults to the SDK's selected default escrow for the active network (legacy V1 by default)
  • minDepositSuccessRateBps?: number — minimum acceptable historical completion rate; defaults to 0 (no filter)

Quote Responses

getQuote(params) returns { success, message, responseObject, statusCode } where responseObject contains:

  • fiat: { currencyCode, currencyName, currencySymbol, countryCode }
  • token: { token, decimals, name, symbol, chainId }
  • quotes: array of quotes with fields:
    • fiatAmount, fiatAmountFormatted
    • tokenAmount, tokenAmountFormatted
    • paymentMethod, payeeAddress, conversionRate
    • intent: { depositId, amount, processorName, toAddress, payeeDetails, fiatCurrencyCode, chainId, escrowAddress? }
    • depositSuccessRateBps?: historical completion rate for the source deposit, in basis points (0–10000)
    • depositIntentStats?: { totalIntents, signaledIntents, fulfilledIntents, prunedIntents }

Example quote item

{
  "fiatAmount": "1000000",
  "fiatAmountFormatted": "1.00 USD",
  "tokenAmount": "990099",
  "tokenAmountFormatted": "0.99 USDC",
  "paymentMethod": "venmo",
  "payeeAddress": "0x...",
  "conversionRate": "1010000000000000000",
  "depositSuccessRateBps": 4166,
  "depositIntentStats": {
    "totalIntents": 12,
    "signaledIntents": 12,
    "fulfilledIntents": 5,
    "prunedIntents": 7
  },
  "intent": {
    "depositId": "1910",
    "amount": "985221",
    "processorName": "venmo",
    "toAddress": "0x...",
    "payeeDetails": "0x...",
    "fiatCurrencyCode": "0x...",
    "chainId": "8453",
    "escrowAddress": "0x..."
  }
}

On-chain Views Enrichment

  • When calling getAccountDeposits(address) and getAccountIntents(address), the SDK parses on-chain views.
  • Enrichment adds two fields:
    • paymentMethod: platform key derived from the verifier address (e.g., venmo, cashapp, revolut, wise). Always set when the verifier is a supported platform.
    • paymentData: opaque key-value details fetched from the API, available only when an apiKey is provided.

Where the data appears

  • Per-verifier: EscrowDepositView.verifiers[i].verificationData.paymentMethod and ...verificationData.paymentData.
  • Top-level intent: EscrowIntent.paymentMethod and EscrowIntent.paymentData (copied from the verifier matching paymentVerifier).

Example

const intentViews = await zkp2pClient.getAccountIntents('0xYourAddress');
if (intentView) {
  // Top-level enrichment
  console.log(intentView.intent.paymentMethod); // e.g. 'venmo'
  console.log(intentView.intent.paymentData); // e.g. { username: 'alice', contact: '...' }

  // Per-verifier enrichment
  for (const v of intentView.deposit.verifiers) {
    console.log(v.verificationData.paymentMethod);
    console.log(v.verificationData.paymentData);
  }
}

const deposits = await zkp2pClient.getAccountDeposits('0xYourAddress');
for (const d of deposits) {
  for (const v of d.verifiers) {
    console.log(v.verificationData.paymentMethod);
    console.log(v.verificationData.paymentData);
  }
}

Notes

  • Enrichment is best-effort; failures are logged and do not throw.
  • paymentData requires a valid apiKey. paymentMethod does not.

Platform Configuration

  • Supported payment platforms are defined once in ENABLED_PLATFORMS (src/utils/constants.ts).
  • Contract addresses use a typed ContractSet that maps those platforms to verifier addresses, keeping config and types in sync.
  • Helpers:
    • platformFromVerifierAddress(addresses, verifierAddress) resolves the platform key from a verifier contract address.
    • getPlatformAddressMap(addresses) returns { [platform]: address } restricted to enabled platforms.

Type Definitions

Core Types

// Proof data structure
interface ProofData {
  proofType: 'buyerTee';
  encryptedSessionMaterial: string;
  params: Record<string, string | number | boolean>;
  actionType?: string;
  actionPlatform?: string;
}

// Flow states
type FlowState =
  | 'idle'
  | 'authenticating'
  | 'authenticated'
  | 'actionStarted'
  | 'proofGenerating'
  | 'proofGeneratedSuccess'
  | 'proofGeneratedFailure';

// Initiate options
interface InitiateOptions {
  authOverrides?: AuthWVOverrides;
  existingProviderConfig?: ProviderSettings;
  initialAction?: {
    enabled?: boolean;
    paymentDetails?: Record<string, string>; // For URL/JS injection
    useExternalActionOverride?: boolean; // Override internal vs external action
  };
}

// Authenticate options
interface AuthenticateOptions {
  authOverrides?: AuthWVOverrides;
  existingProviderConfig?: ProviderSettings;
}

// Fulfill intent params (subset)
interface FulfillIntentParams {
  proof: ProofData;
  intentHash: string;
}

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT


Made with create-react-native-library