This repo houses the JSON providers used in ZKP2P PeerAuth Extension and ZKP2P React Native SDK. ZKP2P is live in production at zkp2p.xyz. PeerAuth is a browser extension that allows you to authenticate internet data in a privacy preserving way using web proofs / zkTLS
This package is data-only. Consumers import the JSON templates directly via deep import paths, or read the included manifest.
Install:
npm install @zkp2p/providers
# or
yarn add @zkp2p/providers
CommonJS (Node):
const zelle = require('@zkp2p/providers/citi/transfer_zelle.json');
console.log(zelle.actionType);
ESM (Node with import assertions):
import zelle from '@zkp2p/providers/citi/transfer_zelle.json' assert { type: 'json' };
console.log(zelle.actionType);
Manifest (providers.json):
// CJS
const manifest = require('@zkp2p/providers/providers.json');
for (const p of manifest.providers) console.log(p.id, p.files);
// ESM
import manifest from '@zkp2p/providers/providers.json' assert { type: 'json' };
Notes:
- No runtime code is shipped; only JSON and docs.
- Deep imports like
@zkp2p/providers/<provider>/<file>.json
are stable entry points. - Bundlers (Webpack/Vite) support JSON imports by default.
Note: The npm package is data-only. The local dev server described here is for development/testing in this repo and is not included in the published package. To get started building a new provider, you will need to setup a local version of
- Clone the repo
- Run
yarn install
andyarn start
. App is hosted on http://localhost:8080 - Install the PeerAuth extension in your browser
- Create a new directory and JSON file and add the necessary provider data for your integration
- Test your integration by going to developer.zkp2p.xyz
- Click on Open Settings on the page and set Base URL to
http://localhost:8080/
. Any changes to your JSON will now be reflected in the extension and developer app. - Update the inputs with the right path to your integration
localhost:8080/{platform_name}/{provider_name}.json
- Click Authenticate to extract metadata
- If successful, proceed to Prove a specific transaction
This guide explains how to create and configure provider templates for the ZKP2P PeerAuth extension. Provider configurations define how to extract and verify data from various platforms.
- Getting Started
- Configuration Structure
- Field Descriptions
- Parameter Extraction
- Best Practices
- Common Issues
- Inspect network tab in Dev Tools after logging into your payment website. Or turn on Intercepted Requests in ZKP2P sidebar
- Find a request that contains amount, timestamp / date, recipient ID at a minimum. Look for additional params such as status (to see if payment finalized), currency (if platform supports more than 1 currency)
- A tip is to look for where the transactions page is. Sometimes the transactions are expandable so you can log those too
- Based on the request, populate the template.
{
"actionType": "transfer_venmo",
"authLink": "https://account.venmo.com/?feed=mine",
"url": "https://account.venmo.com/api/stories?feedType=me&externalId={{SENDER_ID}}",
"method": "GET",
"skipRequestHeaders": [],
"body": "",
"metadata": {
"platform": "venmo",
"urlRegex": "https://account.venmo.com/api/stories\\?feedType=me&externalId=\\S+",
"method": "GET",
"shouldSkipCloseTab": false,
"transactionsExtraction": {
"transactionJsonPathListSelector": "$.stories"
}
},
"paramNames": ["SENDER_ID"],
"paramSelectors": [{
"type": "jsonPath",
"value": "$.stories[{{INDEX}}].title.sender.id",
"source": "responseBody"
}],
"secretHeaders": ["Cookie"],
"responseMatches": [{
"type": "regex",
"value": "\"amount\":\"-\\$(?<amount>[^\"]+)\""
}],
"responseRedactions": [{
"jsonPath": "$.stories[{{INDEX}}].amount",
"xPath": ""
}],
"mobile": {
"includeAdditionalCookieDomains": [],
"useExternalAction": true,
"external": {
"actionLink": "venmo://paycharge?txn=pay&recipients={{RECEIVER_ID}}¬e=cash&amount={{AMOUNT}}",
"appStoreLink": "https://apps.apple.com/us/app/venmo/id351727428",
"playStoreLink": "https://play.google.com/store/apps/details?id=com.venmo"
}
}
}
- Type:
string
- Description: Identifier for the action type (e.g., "transfer_venmo", "receive_payment")
- Example:
"transfer_venmo"
- Type:
string
- Description: URL for user authentication/login page
- Example:
"https://venmo.com/login"
- Type:
string
- Description: API endpoint URL for the main request
- Example:
"https://api.venmo.com/v1/payments"
- Type:
string
- Description: HTTP method for the request
- Values:
"GET"
,"POST"
,"PUT"
,"PATCH"
- Example:
"POST"
- Type:
string[]
- Description: Headers to exclude from the notarized request.
- Example:
["User-Agent", "Accept-Language"]
- Type:
string
- Description: Request body template (for POST/PUT requests)
- Example:
"{\"amount\": \"{{AMOUNT}}\", \"recipient\": \"{{RECIPIENT}}\"}""
- Type:
object
- Description: Configuration for request matching and transaction extraction
"metadata": {
"shouldReplayRequestInPage": false,
"shouldSkipCloseTab": false,
"platform": "venmo",
"urlRegex": "https://api\\.venmo\\.com/v1/payments/\\d+",
"method": "GET",
"fallbackUrlRegex": "https://api\\.venmo\\.com/v1/transactions",
"fallbackMethod": "GET",
"preprocessRegex": "window\\.__data\\s*=\\s*({.*?});",
"transactionsExtraction": {
"transactionJsonPathListSelector": "$.data.transactions",
"transactionRegexSelectors": {
"paymentId": "js_transactionItem-([A-Z0-9]+)"
},
"transactionJsonPathSelectors": {
"recipient": "$.target.username",
"amount": "$.amount",
"date": "$.created_time",
"paymentId": "$.id",
"currency": "$.currency"
}
},
"proofMetadataSelectors": [
{
"type": "jsonPath",
"value": "$.data.user.id"
}
]
}
- Type:
boolean
- Default:
false
- Description: When set to
true
, prevents the extension from automatically closing the authentication tab after successful authentication - Use case: Useful when you need the user to stay on the page to perform additional actions or when the authentication flow requires multiple steps
- Example:
"shouldSkipCloseTab": true
- Type:
boolean
- Default:
false
- Description: When set to
true
, replays the request in the page context instead of making it from the extension - Use case: Useful for requests that require page-specific context or when CORS policies prevent extension requests
- Type:
string[]
- Description: Names of parameters to extract
- Example:
["transactionId", "amount", "recipient"]
- Type:
ParamSelector[]
- Description: Selectors for extracting parameter values
interface ParamSelector {
type: 'jsonPath' | 'regex';
value: string;
source?: 'url' | 'responseBody' | 'responseHeaders' | 'requestHeaders' | 'requestBody';
}
The source
field in paramSelectors
specifies where to extract the parameter from:
- Description: Extract from the response body
- Example:
{
"type": "jsonPath",
"value": "$.data.transactionId",
"source": "responseBody"
}
- Description: Extract from the request URL
- Example:
{
"type": "regex",
"value": "userId=([^&]+)",
"source": "url"
}
- Description: Extract from response headers
- Example:
{
"type": "regex",
"value": "X-Transaction-Id: (.+)",
"source": "responseHeaders"
}
- Description: Extract from request headers
- Example:
{
"type": "regex",
"value": "Authorization: Bearer (.+)",
"source": "requestHeaders"
}
- Description: Extract from the request body (for POST/PUT requests)
- Example:
{
"type": "jsonPath",
"value": "$.payment.amount",
"source": "requestBody"
}
- Type:
string[]
- Description: Headers containing sensitive data (e.g., auth tokens)
- Example:
["Authorization", "Cookie"]
- Type:
ResponseMatch[]
- Description: Patterns to verify in the response
"responseMatches": [
{
"type": "jsonPath",
"value": "$.data.transactions[{{INDEX}}].id",
"hash": false
},
{
"type": "regex",
"value": "\"status\":\\s*\"completed\"",
"hash": true
}
]
- Type:
ResponseRedaction[]
- Description: Data to redact from the response for privacy
"responseRedactions": [
{
"jsonPath": "$.data.user.email",
"xPath": ""
},
{
"jsonPath": "$.data.ssn",
"xPath": ""
}
]
- Type:
object
- Description: Special configurations for the ZKP2P mobile SDK. The mobile configuration supports both internal (WebView) and external (native app) actions.
"mobile": {
"includeAdditionalCookieDomains": ["additional-domain.com"],
"useExternalAction": true,
"userAgent": {
"android": "Mozilla/5.0 (Linux; Android 13; Pixel 6) ...",
"ios": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) ..."
},
"external": {
"actionLink": "venmo://paycharge?txn=pay&recipients={{RECEIVER_ID}}¬e=cash&amount={{AMOUNT}}",
"appStoreLink": "https://apps.apple.com/us/app/venmo/id351727428",
"playStoreLink": "https://play.google.com/store/apps/details?id=com.venmo"
},
"internal": {
"actionLink": "https://app.provider.com/send",
"actionCompletedUrlRegex": "https://app.provider.com/confirmation/\\S+",
"injectedJavaScript": "/* JavaScript to interact with the webpage */",
"injectedJavaScriptParamNames": ["RECIPIENT_ID", "AMOUNT"]
}
}
Top-level Fields:
includeAdditionalCookieDomains
: Array of additional cookie domains to includeuseExternalAction
: Boolean to prefer external action whentrue
, otherwise prefer internal actionuserAgent
(optional): Custom user agent strings for Android and iOS WebViews
External Action Fields (external
):
actionLink
: Deep link URL for the native mobile app with placeholders for dynamic valuesappStoreLink
: iOS App Store URL for the appplayStoreLink
: Google Play Store URL for the app
Internal Action Fields (internal
):
actionLink
: Web URL to open in WebView for the actionactionCompletedUrlRegex
(optional): Regex pattern to detect when the action is completedinjectedJavaScript
(optional): JavaScript code to inject into the WebView to assist with form filling or interactioninjectedJavaScriptParamNames
(optional): Array of parameter names used in the injected JavaScript
Action Flow: The mobile SDK will attempt actions based on the configuration:
- If
useExternalAction
istrue
, it will try the external action first (native app), then fall back to internal (WebView) - If
useExternalAction
isfalse
or omitted, it will try the internal action first (WebView), then fall back to external (native app) - Both
internal
andexternal
sections can be provided for maximum flexibility
- Type:
object
- Description: Extra client configuration options (not commonly used)
"additionalClientOptions": {
"cipherSuites": ["TLS_AES_128_GCM_SHA256"]
}
- Type:
AdditionalProof[]
- Description: Configuration for generating multiple proofs from different endpoints (not commonly used)
{
"paramNames": ["userId"],
"paramSelectors": [{
"type": "regex",
"value": "/user/([^/]+)/transactions",
"source": "url"
}]
}
{
"paramNames": ["sessionId"],
"paramSelectors": [{
"type": "regex",
"value": "X-Session-Id: ([a-zA-Z0-9]+)",
"source": "responseHeaders"
}]
}
{
"paramNames": ["userId", "transactionId", "amount"],
"paramSelectors": [
{
"type": "regex",
"value": "userId=([^&]+)",
"source": "url"
},
{
"type": "jsonPath",
"value": "$.data.transactions[{{INDEX}}].id",
"source": "responseBody"
},
{
"type": "regex",
"value": "X-Transaction-Amount: ([0-9.]+)",
"source": "responseHeaders"
}
]
}
Use JSONPath expressions for structured data:
{
"type": "jsonPath",
"value": "$.data.transactions[{{INDEX}}].amount"
}
Special features:
{{INDEX}}
placeholder for array indexing- Supports nested paths:
$.user.profile.email
- Array filters:
$.items[?(@.status=='active')]
Use regular expressions for pattern matching:
{
"type": "regex",
"value": "transactionId\":\\s*\"([^\"]+)\""
}
Notes:
- First capture group
()
is used as the extracted value - Escape special characters:
\\.
for dots - Use
\\s*
for flexible whitespace matching
- Escape special characters:
\\.
for dots - Use specific patterns to avoid false matches
- Test regex patterns thoroughly
- Use JSONPath for structured JSON data
- Use regex for HTML, text responses, or complex patterns
- Always specify capture groups
()
for regex extraction - Specify
source
when extracting from non-default locations (not responseBody) - Test extraction with various response formats
- List all sensitive headers in
secretHeaders
- Use
responseRedactions
to remove PII - Never expose authentication tokens in
responseMatches
- Type:
object
- Description: Regular expression patterns to extract transaction data from HTML/text responses
- Use case: Use this when transactions are embedded in HTML or when the response is not structured JSON
- Example:
{
"transactionsExtraction": {
"transactionRegexSelectors": {
"amount": "<td class=\"amount\">\\$([\\d,\\.]+)</td>",
"recipient": "<td class=\"recipient\">([^<]+)</td>",
"date": "<td class=\"date\">(\\d{2}/\\d{2}/\\d{4})</td>",
"paymentId": "data-payment-id=\"(\\d+)\""
}
}
}
Note: Use either transactionJsonPathListSelector
(for JSON responses) or transactionRegexSelectors
(for HTML/text responses), not both.
- Provide fallback URLs when primary endpoints might fail
- Use preprocessing regex for embedded JSON data
- Test extraction selectors with various response formats
- Minimize the number of
responseMatches
for faster verification - Use specific JSONPath expressions instead of wildcards
- Consider response size when designing redactions
- Set
shouldSkipCloseTab: true
for flows where when closing the tab results in ending the session token, thus preventing us from replaying the request successfully. - Use default behavior (auto-close) for simple authentication flows
- Consider user experience when deciding tab behavior
- Authenticate does not open desired auth link: Check the Base URL you have set in the extension. Ensure you are running the server which is hosted in port 8080
- Authenticated into your payment platform but not redirected back to developer.zkp2p.xyz: There is an issue with the urlRegex for metadata extraction. Double check your regex is correct
- Metadata returned to app, but Prove fails: There is an issue with the response redactions or headers for the server call. If error is JSON path not found or regex not found then check your response redactions parameters. If it returns a error that is not 200, the server has rejected your request, so there is an issue with your headers, request body.
- Parameters not extracted correctly: Check the
source
field in yourparamSelectors
. By default, parameters are extracted from responseBody. If your parameter is in the URL, headers, or request body, you must specify the correct source.
We want to make this the largest open source repository of provider templates for global payment platforms. Please open a PR when you have created and tested your template