
Security News
Package Maintainers Call for Improvements to GitHub’s New npm Security Plan
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
@zkp2p/client-sdk
Advanced tools
Browser-first TypeScript SDK for ZKP2P with peerauth extension integration
Browser-first TypeScript SDK for integrating ZKP2P into web apps. Built on the proven core from the React Native SDK and extended with peerauth browser extension integration.
npm install @zkp2p/client-sdk viem
import { Zkp2pClient } from '@zkp2p/client-sdk';
const client = new Zkp2pClient({
walletClient, // viem wallet client
apiKey: 'YOUR_API_KEY',
chainId: 8453, // Base mainnet
});
// Fetch quotes
const quotes = await client.getQuote({
paymentPlatforms: ['wise'],
fiatCurrency: 'USD',
user: '0xYourAddress',
recipient: '0xPayeeAddress',
destinationChainId: 8453,
destinationToken: client.getUsdcAddress(),
amount: '100', // exact fiat by default
});
// Use the extension (optional)
import { PeerauthExtension } from '@zkp2p/client-sdk/extension';
const ext = new PeerauthExtension({ onVersion: v => console.log('Extension version', v) });
ext.fetchVersion();
// After generating proof via extension, fulfill intent (see Extension Flow section)
// await client.fulfillIntent({ intentHash, paymentProofs: [{ proof }], paymentMethod: 1 });
@zkp2p/client-sdk/extension
.wise
, venmo
, revolut
, cashapp
, mercadopago
, zelle
, paypal
, monzo
.examples/
folder for:
examples/node-scripts/get-quote.ts
)examples/e2e-browser/index.html
)This demo simulates the peerauth extension with a small in-page mock so you can see the end-to-end flow.
Steps:
npm run build
npx http-server -p 5174 .
or npx serve .
http://localhost:5174/examples/e2e-browser/
in your browser.What it shows:
postMessage
ReclaimProof
with parseExtensionProof
fulfillIntent
with the proofYou can pass any viem
WalletClient
(from wagmi or raw viem). Example with injected wallet on Base:
import { createWalletClient, custom } from 'viem'
import { base } from 'viem/chains'
const walletClient = createWalletClient({
chain: base,
transport: typeof window !== 'undefined' ? custom((window as any).ethereum) : undefined,
});
const client = new Zkp2pClient({ walletClient, apiKey: 'YOUR_API_KEY', chainId: base.id });
Override RPC URL if desired by passing rpcUrl
to the constructor.
const client = new Zkp2pClient({ walletClient, apiKey, chainId: base.id, rpcUrl: 'https://base-mainnet.g.alchemy.com/v2/<key>' });
Supported chains match DEPLOYED_ADDRESSES
. Use client.getDeployedAddresses()
and client.getUsdcAddress()
when needed.
Best practice: pass values into the SDK at initialization. The SDK does not read env directly.
VITE_ZKP2P_API_KEY=your_public_key
VITE_ZKP2P_RPC_URL=https://base-mainnet.g.alchemy.com/v2/xxx
Code:
const apiKey = import.meta.env.VITE_ZKP2P_API_KEY;
if (!apiKey) throw new Error('Missing VITE_ZKP2P_API_KEY');
const client = new Zkp2pClient({
walletClient,
apiKey,
chainId: 8453,
rpcUrl: import.meta.env.VITE_ZKP2P_RPC_URL,
// Optional overrides:
// baseApiUrl: import.meta.env.VITE_ZKP2P_BASE_API_URL,
// witnessUrl: import.meta.env.VITE_ZKP2P_WITNESS_URL,
});
NEXT_PUBLIC_ZKP2P_API_KEY=your_public_key
NEXT_PUBLIC_ZKP2P_RPC_URL=https://base-mainnet.g.alchemy.com/v2/xxx
Code:
const apiKey = process.env.NEXT_PUBLIC_ZKP2P_API_KEY;
if (!apiKey) throw new Error('Missing NEXT_PUBLIC_ZKP2P_API_KEY');
const client = new Zkp2pClient({
walletClient,
apiKey,
chainId: 8453,
rpcUrl: process.env.NEXT_PUBLIC_ZKP2P_RPC_URL,
});
Security: only use public runtime env vars in the browser (VITE_/NEXT_PUBLIC_). If keys must remain private, proxy via your server.
PAYMENT_PLATFORMS
is an exported as const
array and PaymentPlatformType
is the corresponding string union. Use it for extension calls to get autocomplete and type-safety.import { PAYMENT_PLATFORMS, type PaymentPlatformType } from '@zkp2p/client-sdk';
const platform: PaymentPlatformType = 'wise'; // from PAYMENT_PLATFORMS
CurrencyType
is the ISO-like currency code union (e.g., 'USD' | 'EUR' | …'
). Use it in signalIntent
.import { type CurrencyType } from '@zkp2p/client-sdk';
await client.signalIntent({
processorName: 'wise',
depositId: '1',
tokenAmount: '1000000',
payeeDetails: '{"email":"alice@example.com"}',
toAddress: '0xRecipient',
currency: 'USD' as CurrencyType,
});
The typical browser flow is:
intentHash
ReclaimProof
formatfulfillIntent
with the encoded proofimport { Zkp2pClient, assembleProofBytes } from '@zkp2p/client-sdk';
import { PeerauthExtension, parseExtensionProof, ExtensionProofFlow } from '@zkp2p/client-sdk/extension';
// 1) Initialize the client
const client = new Zkp2pClient({ walletClient, apiKey, chainId: 8453 });
// 2) Set up the extension with callbacks
let cachedProofId: string | null = null;
const ext = new PeerauthExtension({
onVersion: (v) => console.log('extension version:', v),
onProofId: (id) => {
cachedProofId = id;
if (cachedProofId) ext.fetchProofById(); // 3) Request proof details once we have the id
},
onProof: async (notaryRequest) => {
if (!notaryRequest) return;
// 4) Convert extension proof → ReclaimProof shape expected by the contracts
const reclaimProof = parseExtensionProof(notaryRequest.proof);
// Submit proof on-chain
await client.fulfillIntent({
intentHash,
paymentProofs: [{ proof: reclaimProof }],
// optionally include a paymentMethod identifier (uint8) if needed by verifier
// paymentMethod: 1,
});
},
onError: (e) => console.error('extension error:', e),
});
// Kick off version check and proof generation
ext.fetchVersion();
ext.generateProof(
'wise', // platform identifier (e.g. 'wise', 'venmo', 'revolut', 'paypal', 'monzo', ...)
intentHash, // `0x…` intent hash to fulfill
0 // originalIndex for the selected transaction/metadata
);
// Helper: Convert extension proof payload → ReclaimProof
const reclaimProof = parseExtensionProof(notaryRequest.proof);
If a platform requires two proofs, or you want a single helper to handle polling/timeout and parsing, use ExtensionProofFlow
and assembleProofBytes
:
const flow = new ExtensionProofFlow();
try {
const proofs = await flow.generateProofs(
'wise', // platform
BigInt(intentHash).toString(), // decimal string expected by extension
0, // originalIndex from extension metadata
{ requiredProofs: 1, pollIntervalMs: 3000, timeoutMs: 60000 },
(p) => console.log('progress', p)
);
// Option A: assemble bytes and submit manually
const bytes = assembleProofBytes(proofs, { paymentMethod: 1 });
// ... submit via your own viem client if desired
// Option B: submit via SDK using the raw proofs
await client.fulfillIntent({
intentHash,
paymentProofs: proofs.map((proof) => ({ proof })),
paymentMethod: 1,
});
} finally {
flow.dispose();
}
encodeProofAsBytes(proof)
encodeTwoProofs(proof1, proof2)
encodeManyProofs([proofs])
encodeProofAndPaymentMethodAsBytes(bytes, method)
assembleProofBytes(proofs, { paymentMethod? })
parseExtensionProof(payload)
createDeposit(params): creates a deposit on-chain and stores deposit details via API
{ token, amount, intentAmountRange, conversionRates, processorNames, depositData, onSuccess, onMined, onError }
{ depositDetails, hash }
signalIntent(params): verifies intent via API and emits on-chain signalIntent
{ processorName, depositId, tokenAmount, payeeDetails, toAddress, currency, onSuccess, onMined, onError }
SignalIntentResponse & { txHash?: Hash }
fulfillIntent({ intentHash, paymentProofs, paymentMethod? }): submits proof bytes to fulfill an intent
withdrawDeposit({ depositId }): withdraws a deposit
cancelIntent({ intentHash }): cancels a pending intent
releaseFundsToPayer({ intentHash }): releases escrowed funds back to payer
getQuote(req): retrieves quotes from API (exact-fiat by default)
getPayeeDetails({ platform, hashedOnchainId })
getAccountDeposits(address): reads deposit views from chain
getAccountIntent(address): reads current intent view from chain
See TypeScript types exported from the package for full shapes.
@zkp2p/client-sdk/extension
is browser-only. In SSR environments (Next.js), use dynamic import or guards to avoid referencing window
during server rendering.Callbacks (optional and per-method):
onSuccess({ hash })
: emitted after the transaction is broadcastonMined({ hash })
: emitted after transaction is confirmedonError(error)
: emitted when any step failsError classes:
ZKP2PError
(base), NetworkError
, APIError
, ContractError
, ValidationError
, ProofGenerationError
window
.@zkp2p/client-sdk/extension
is browser-only. In SSR, import it dynamically or guard with typeof window !== 'undefined'
.await client.createDeposit({
token: client.getUsdcAddress(),
amount: 1000000n, // 1 USDC with 6 decimals
intentAmountRange: { min: 500000n, max: 2000000n },
processorNames: ['wise'],
conversionRates: [[{ currency: 'USD', conversionRate: '1000000' }]],
depositData: [{ /* payee details per processor */ }],
});
await client.signalIntent({
processorName: 'wise',
depositId: '1',
tokenAmount: '1000000',
payeeDetails: '{"email":"alice@example.com"}',
toAddress: '0xRecipient',
currency: 'USD',
});
// ext.generateProof(...)
// const proof = parseExtensionProof(...)
await client.fulfillIntent({ intentHash, paymentProofs: [{ proof }] });
Two common flows: Development (dev tag) and Stable (latest).
Dev release (manual, recommended while iterating)
@zkp2p
org: npm whoami
cd packages/client-sdk
npm pkg set name=@zkp2p/client-sdk
npm pkg set version=0.1.0
(or bump as needed)dev
dist-tag so it won’t affect latest
:
npm ci && npm run build
npm publish --access public --tag dev --no-provenance --otp <CODE>
npm publish --access public --tag dev --no-provenance
npm view @zkp2p/client-sdk dist-tags
npm i @zkp2p/client-sdk@dev
Stable release (promote to latest
)
0.1.1
).npm publish --access public --no-provenance
(provenance requires a public repo)npm view @zkp2p/client-sdk dist-tags
Notes
--tag dev
for non-production builds so integrators can test without moving latest
.--no-provenance
is required when publishing from a private repository. Use provenance only from public CI.MIT
FAQs
Browser-first TypeScript SDK for ZKP2P with React hooks, unified authentication, and peerauth extension integration
The npm package @zkp2p/client-sdk receives a total of 5 weekly downloads. As such, @zkp2p/client-sdk popularity was classified as not popular.
We found that @zkp2p/client-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.