Skip to content

zkp2p/zkp2p-react-native-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

yarn add @zkp2p/zkp2p-react-native-sdk @react-native-async-storage/async-storage @react-native-cookies/cookies react-native-webview @zkp2p/webview-intercept viem react-native-svg react-native-device-info

iOS Setup

cd ios && pod install

Additional Dependencies

  • react-native-device-info: Used for dynamic memory management in proof generation
  • react-native-svg: Required for animated UI components

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
      prover="reclaim_gnark" // or "reclaim_snarkjs"
      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
      prover="reclaim_gnark"
      // 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,
    generateProof,
    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)
prover 'reclaim_snarkjs' | 'reclaim_gnark' 'reclaim_gnark' Proof generation method
witnessUrl string 'https://witness-proxy.zkp2p.xyz' Witness server URL
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.
rpcTimeout number 30000 RPC timeout in milliseconds
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.
hideDefaultProofUI boolean false When true, the SDK does not render its proof progress sheet. Use this for headless/custom proof animations.
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. generateProof(provider, payload, intentHash, itemIndex?)

Generate zero-knowledge proof(s) for a specific transaction. Always returns an array of ProofData.

const { generateProof, provider, interceptedPayload } = useZkp2p();

try {
  const proofs = await generateProof(
    provider,
    interceptedPayload,
    '0x...', // Intent hash from signalIntent
    0 // Transaction index to prove
  );
  
  console.log('Proofs generated:', proofs);
} catch (error) {
  console.error('Proof generation failed:', error);
  // Fallback to manual authentication
  await authenticate('venmo', 'transfer_venmo');
}

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();

// Simple authentication without auto-proof
await authenticate('venmo', 'transfer_venmo');

// Or with auto-proof generation
await authenticate('venmo', 'transfer_venmo', {
  autoGenerateProof: {
    intentHash: '0x...',
    itemIndex: 0,
    onProofGenerated: (proofData) => {
      // Handle generated proof
    },
    onProofError: (err) => console.error(err),
  },
});

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.

### Passing a custom RPC without the Provider

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

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

const client = new Zkp2pClient({
  prover: 'reclaim_gnark',
  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`
- `zkTlsProof: string` (stringified proof JSON)
- `amount: string`, `timestampMs: string`
- `fiatCurrency: Hex`, `conversionRate: string`
- `payeeDetails: Hex`, `timestampBufferMs: string`
- `verifyingContract?: Address` (UnifiedPaymentVerifier)

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

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

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.

Migration Reference: Updated Interfaces (0.1.0)

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

// FulfillIntentParams
type FulfillIntentParams = {
  intentHash: Hash;
  zkTlsProof: string;            // stringified proof JSON
  platform: string;
  actionType: string;
  amount: string;
  timestampMs: string;
  fiatCurrency: Hex;             // bytes32
  conversionRate: string;        // 1e18 scaled
  payeeDetails: Hex;             // bytes32
  timestampBufferMs: string;
  verifyingContract?: Address;   // UnifiedPaymentVerifier
  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;
  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;
};

// SignalIntentResponse.responseObject.intentData
type IntentData = {
  orchestratorAddress: Address;
  escrowAddress: Address;
  depositId: string;
  amount: string;
  recipientAddress: Address;
  paymentMethod: Hex;
  fiatCurrency: Hex;
  conversionRate: string;
  signatureExpiration: string;
  chainId: string;
  gatingServiceSignature: Hex;
};

// 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
  generateProof,       // Generate proof(s) for transaction (returns ProofData[])
  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();

Performance: Lazy Circuit Loading

  • Circuits are now loaded lazily per algorithm (e.g., aes-256-ctr, aes-128-ctr, chacha20) instead of at SDK mount. This significantly reduces app startup time.
  • The SDK extracts the cipher from the witness and begins preloading that specific circuit just before proof generation. Only one circuit is initialized at a time, on demand.
  • If you want to explicitly warm up a circuit even earlier, you may call the native preload via GnarkBridge.preloadAlgorithm(algorithm) when you have enough context, though this is optional — the bridge also ensures lazy initialization on first use.

Complete Flow Example

function BuyCrypto() {
  const { 
    flowState, 
    initiate, 
    generateProof,
    zkp2pClient,
    proofData,
    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'
          }
        },
        // Optional: After authenticate step, you can auto-generate proof
        // (Recommended to pass autoGenerateProof in authenticate instead.)
      });
      
      // Example: Manually authenticate and auto-generate proof
      await authenticate('venmo', 'transfer_venmo', {
        autoGenerateProof: {
          intentHash,
          itemIndex: 0,
          onProofGenerated: async (_singleProof) => {
            // For multiple-proof configs, read the array from the hook state
            const proofsToUse = proofData && proofData.length > 0 ? proofData : [];
            if (proofsToUse.length === 0) return;
            const fulfillTx = await zkp2pClient.fulfillIntent({
              paymentProofs: proofsToUse,
              intentHash,
              onSuccess: (tx) => console.log('Transaction complete:', tx.hash),
              onError: (error) => console.error('Fulfillment failed:', error),
            });
            console.log('Transaction complete:', fulfillTx.hash);
          },
          onProofError: async (error) => {
            console.error('Auto-proof failed, trying manual:', error);
            if (provider && interceptedPayload) {
              const proofs = await generateProof(
                provider,
                interceptedPayload,
                intentHash,
                0
              );
              await zkp2pClient.fulfillIntent({ paymentProofs: proofs, intentHash });
            }
          },
        },
      });

    } 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 renders a default progress sheet. To supply your own UI, opt out and read the live status from context:

function App() {
  return (
    <Zkp2pProvider hideDefaultProofUI>
      <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() to stop the active proof and close the default sheet. Re-running generateProof(...) after a failure automatically reinitializes the RPC bridge. 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
MercadoPago transfer_mercadopago MercadoPago transfers
Zelle transfer_zelle Zelle transfers

Error Handling

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

// Handle proof generation errors
try {
  await generateProof(provider, interceptedPayload, intentHash, 0);
} 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'
};

Multiple Proof Generation

The SDK supports generating multiple proofs for different transaction data:

const proofs = await generateProof(
  provider,
  interceptedPayload,
  intentHash,
  0 // itemIndex
);
// Returns ProofData[] - array of proofs if multiple configured

Dynamic Memory Management

The SDK automatically adjusts proof generation concurrency based on device memory:

  • Devices with 8GB+ RAM: Up to 6 concurrent proofs
  • Devices with 6GB+ RAM: Up to 4 concurrent proofs
  • Devices with 4GB+ RAM: Up to 3 concurrent proofs
  • Devices with less than 4GB: Up to 2 concurrent proofs

Resetting SDK State

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

    • Cancels all active native gnark proofs and cleans up memory
    • 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.

UI Components

Authentication WebView

The SDK provides a built-in WebView component for authentication:

  • Slide-up animation from bottom
  • Minimizable to 48px height
  • Tap header to minimize/expand
  • Clean circular close button
  • No backdrop overlay - allows interaction with main app

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 [zkp2pClient.getDeployedAddresses().escrow]
  • minDepositSuccessRateBps?: number — minimum acceptable historical completion rate; defaults to 3000 (30%)

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? }
    • payeeData?: populated by the SDK when apiKey is provided
    • 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: 'reclaim';
  proof: ReclaimProof;
}

// 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;
  autoGenerateProof?: {
    intentHash?: string;
    itemIndex?: number;
    onProofGenerated?: (proofData: ProofData) => void;
    onProofError?: (error: Error) => void;
  };
}

// Fulfill intent params (subset)
interface FulfillIntentParams {
  paymentProofs: 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

About

React Native Mobile SDK for ZKP2P

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •