@zkp2p/providers 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +546 -0
- package/bankofamerica/transfer_zelle.json +113 -0
- package/cashapp/transfer_cashapp.json +136 -0
- package/chase/transfer_zelle.json +148 -0
- package/citi/transfer_zelle.json +117 -0
- package/idfc/transfer_idfc.json +109 -0
- package/luxon/transfer_luxon.json +118 -0
- package/mercadopago/transfer_mercado_pago.json +121 -0
- package/mercadopago/transfer_mercadopago.json +121 -0
- package/monzo/transfer_monzo.json +110 -0
- package/package.json +22 -0
- package/paypal/transfer_paypal.json +101 -0
- package/providers.json +22 -0
- package/revolut/transfer_revolut.json +126 -0
- package/royalbankcanada/transfer_interac.json +89 -0
- package/usbank/transfer_zelle.json +126 -0
- package/venmo/transfer_venmo.json +110 -0
- package/wise/transfer_wise.json +133 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ZKP2P
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
# ZKP2P Provider Templates
|
|
2
|
+
|
|
3
|
+
This repo houses the JSON providers used in ZKP2P PeerAuth Extension and ZKP2P React Native SDK. ZKP2P is live in production at [zkp2p.xyz](https://zkp2p.xyz/). PeerAuth is a browser extension that allows you to authenticate internet data in a privacy preserving way using web proofs / zkTLS
|
|
4
|
+
|
|
5
|
+
## Package Usage (npm)
|
|
6
|
+
|
|
7
|
+
This package is data-only. Consumers import the JSON templates directly via deep import paths, or read the included manifest.
|
|
8
|
+
|
|
9
|
+
Install:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @zkp2p/providers
|
|
13
|
+
# or
|
|
14
|
+
yarn add @zkp2p/providers
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
CommonJS (Node):
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
const zelle = require('@zkp2p/providers/citi/transfer_zelle.json');
|
|
21
|
+
console.log(zelle.actionType);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
ESM (Node with import assertions):
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import zelle from '@zkp2p/providers/citi/transfer_zelle.json' assert { type: 'json' };
|
|
28
|
+
console.log(zelle.actionType);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Manifest (providers.json):
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
// CJS
|
|
35
|
+
const manifest = require('@zkp2p/providers/providers.json');
|
|
36
|
+
for (const p of manifest.providers) console.log(p.id, p.files);
|
|
37
|
+
|
|
38
|
+
// ESM
|
|
39
|
+
import manifest from '@zkp2p/providers/providers.json' assert { type: 'json' };
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Notes:
|
|
43
|
+
- No runtime code is shipped; only JSON and docs.
|
|
44
|
+
- Deep imports like `@zkp2p/providers/<provider>/<file>.json` are stable entry points.
|
|
45
|
+
- Bundlers (Webpack/Vite) support JSON imports by default.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Developer Quickstart
|
|
49
|
+
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.
|
|
50
|
+
To get started building a new provider, you will need to setup a local version of
|
|
51
|
+
1. Clone the repo
|
|
52
|
+
2. Run `yarn install` and `yarn start`. App is hosted on [http://localhost:8080](http://localhost:8080)
|
|
53
|
+
3. Install the [PeerAuth extension](https://chromewebstore.google.com/detail/peerauth-authenticate-and/ijpgccednehjpeclfcllnjjcmiohdjih) in your browser
|
|
54
|
+
3. Create a new directory and JSON file and add the necessary provider data for your integration
|
|
55
|
+
4. Test your integration by going to [developer.zkp2p.xyz](https://developer.zkp2p.xyz/)
|
|
56
|
+
5. 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.
|
|
57
|
+
6. Update the inputs with the right path to your integration `localhost:8080/{platform_name}/{provider_name}.json`
|
|
58
|
+
7. Click Authenticate to extract metadata
|
|
59
|
+
8. If successful, proceed to Prove a specific transaction
|
|
60
|
+
|
|
61
|
+
## Provider Configuration Guide
|
|
62
|
+
|
|
63
|
+
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.
|
|
64
|
+
|
|
65
|
+
### Table of Contents
|
|
66
|
+
- [Getting Started](#getting-started)
|
|
67
|
+
- [Configuration Structure](#configuration-structure)
|
|
68
|
+
- [Field Descriptions](#field-descriptions)
|
|
69
|
+
- [Parameter Extraction](#parameter-extraction)
|
|
70
|
+
- [Best Practices](#best-practices)
|
|
71
|
+
- [Common Issues](#common-issues)
|
|
72
|
+
|
|
73
|
+
### Getting Started
|
|
74
|
+
1. Inspect network tab in Dev Tools after logging into your payment website. Or turn on Intercepted Requests in ZKP2P sidebar
|
|
75
|
+
2. 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)
|
|
76
|
+
3. A tip is to look for where the transactions page is. Sometimes the transactions are expandable so you can log those too
|
|
77
|
+
4. Based on the request, populate the template.
|
|
78
|
+
|
|
79
|
+
### Configuration Structure
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"actionType": "transfer_venmo",
|
|
84
|
+
"authLink": "https://account.venmo.com/?feed=mine",
|
|
85
|
+
"url": "https://account.venmo.com/api/stories?feedType=me&externalId={{SENDER_ID}}",
|
|
86
|
+
"method": "GET",
|
|
87
|
+
"skipRequestHeaders": [],
|
|
88
|
+
"body": "",
|
|
89
|
+
"metadata": {
|
|
90
|
+
"platform": "venmo",
|
|
91
|
+
"urlRegex": "https://account.venmo.com/api/stories\\?feedType=me&externalId=\\S+",
|
|
92
|
+
"method": "GET",
|
|
93
|
+
"shouldSkipCloseTab": false,
|
|
94
|
+
"transactionsExtraction": {
|
|
95
|
+
"transactionJsonPathListSelector": "$.stories"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"paramNames": ["SENDER_ID"],
|
|
99
|
+
"paramSelectors": [{
|
|
100
|
+
"type": "jsonPath",
|
|
101
|
+
"value": "$.stories[{{INDEX}}].title.sender.id",
|
|
102
|
+
"source": "responseBody"
|
|
103
|
+
}],
|
|
104
|
+
"secretHeaders": ["Cookie"],
|
|
105
|
+
"responseMatches": [{
|
|
106
|
+
"type": "regex",
|
|
107
|
+
"value": "\"amount\":\"-\\$(?<amount>[^\"]+)\""
|
|
108
|
+
}],
|
|
109
|
+
"responseRedactions": [{
|
|
110
|
+
"jsonPath": "$.stories[{{INDEX}}].amount",
|
|
111
|
+
"xPath": ""
|
|
112
|
+
}],
|
|
113
|
+
"mobile": {
|
|
114
|
+
"includeAdditionalCookieDomains": [],
|
|
115
|
+
"useExternalAction": true,
|
|
116
|
+
"external": {
|
|
117
|
+
"actionLink": "venmo://paycharge?txn=pay&recipients={{RECEIVER_ID}}¬e=cash&amount={{AMOUNT}}",
|
|
118
|
+
"appStoreLink": "https://apps.apple.com/us/app/venmo/id351727428",
|
|
119
|
+
"playStoreLink": "https://play.google.com/store/apps/details?id=com.venmo"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Field Descriptions
|
|
126
|
+
|
|
127
|
+
#### Basic Configuration
|
|
128
|
+
|
|
129
|
+
#### `actionType` (required)
|
|
130
|
+
- **Type**: `string`
|
|
131
|
+
- **Description**: Identifier for the action type (e.g., "transfer_venmo", "receive_payment")
|
|
132
|
+
- **Example**: `"transfer_venmo"`
|
|
133
|
+
|
|
134
|
+
#### `authLink` (required)
|
|
135
|
+
- **Type**: `string`
|
|
136
|
+
- **Description**: URL for user authentication/login page
|
|
137
|
+
- **Example**: `"https://venmo.com/login"`
|
|
138
|
+
|
|
139
|
+
#### `url` (required)
|
|
140
|
+
- **Type**: `string`
|
|
141
|
+
- **Description**: API endpoint URL for the main request
|
|
142
|
+
- **Example**: `"https://api.venmo.com/v1/payments"`
|
|
143
|
+
|
|
144
|
+
#### `method` (required)
|
|
145
|
+
- **Type**: `string`
|
|
146
|
+
- **Description**: HTTP method for the request
|
|
147
|
+
- **Values**: `"GET"`, `"POST"`, `"PUT"`, `"PATCH"`
|
|
148
|
+
- **Example**: `"POST"`
|
|
149
|
+
|
|
150
|
+
#### `skipRequestHeaders` (optional)
|
|
151
|
+
- **Type**: `string[]`
|
|
152
|
+
- **Description**: Headers to exclude from the notarized request.
|
|
153
|
+
- **Example**: `["User-Agent", "Accept-Language"]`
|
|
154
|
+
|
|
155
|
+
#### `body` (optional)
|
|
156
|
+
- **Type**: `string`
|
|
157
|
+
- **Description**: Request body template (for POST/PUT requests)
|
|
158
|
+
- **Example**: `"{\"amount\": \"{{AMOUNT}}\", \"recipient\": \"{{RECIPIENT}}\"}""`
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
#### Metadata Configuration
|
|
162
|
+
|
|
163
|
+
#### `metadata` (required)
|
|
164
|
+
- **Type**: `object`
|
|
165
|
+
- **Description**: Configuration for request matching and transaction extraction
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
"metadata": {
|
|
169
|
+
"shouldReplayRequestInPage": false,
|
|
170
|
+
"shouldSkipCloseTab": false,
|
|
171
|
+
"platform": "venmo",
|
|
172
|
+
"urlRegex": "https://api\\.venmo\\.com/v1/payments/\\d+",
|
|
173
|
+
"method": "GET",
|
|
174
|
+
"fallbackUrlRegex": "https://api\\.venmo\\.com/v1/transactions",
|
|
175
|
+
"fallbackMethod": "GET",
|
|
176
|
+
"preprocessRegex": "window\\.__data\\s*=\\s*({.*?});",
|
|
177
|
+
"transactionsExtraction": {
|
|
178
|
+
"transactionJsonPathListSelector": "$.data.transactions",
|
|
179
|
+
"transactionRegexSelectors": {
|
|
180
|
+
"paymentId": "js_transactionItem-([A-Z0-9]+)"
|
|
181
|
+
},
|
|
182
|
+
"transactionJsonPathSelectors": {
|
|
183
|
+
"recipient": "$.target.username",
|
|
184
|
+
"amount": "$.amount",
|
|
185
|
+
"date": "$.created_time",
|
|
186
|
+
"paymentId": "$.id",
|
|
187
|
+
"currency": "$.currency"
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"proofMetadataSelectors": [
|
|
191
|
+
{
|
|
192
|
+
"type": "jsonPath",
|
|
193
|
+
"value": "$.data.user.id"
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
##### Metadata Fields
|
|
200
|
+
|
|
201
|
+
###### `shouldSkipCloseTab` (optional)
|
|
202
|
+
- **Type**: `boolean`
|
|
203
|
+
- **Default**: `false`
|
|
204
|
+
- **Description**: When set to `true`, prevents the extension from automatically closing the authentication tab after successful authentication
|
|
205
|
+
- **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
|
|
206
|
+
- **Example**: `"shouldSkipCloseTab": true`
|
|
207
|
+
|
|
208
|
+
###### `shouldReplayRequestInPage` (optional)
|
|
209
|
+
- **Type**: `boolean`
|
|
210
|
+
- **Default**: `false`
|
|
211
|
+
- **Description**: When set to `true`, replays the request in the page context instead of making it from the extension
|
|
212
|
+
- **Use case**: Useful for requests that require page-specific context or when CORS policies prevent extension requests
|
|
213
|
+
|
|
214
|
+
#### Parameter Extraction
|
|
215
|
+
|
|
216
|
+
#### `paramNames` (required)
|
|
217
|
+
- **Type**: `string[]`
|
|
218
|
+
- **Description**: Names of parameters to extract
|
|
219
|
+
- **Example**: `["transactionId", "amount", "recipient"]`
|
|
220
|
+
|
|
221
|
+
#### `paramSelectors` (required)
|
|
222
|
+
- **Type**: `ParamSelector[]`
|
|
223
|
+
- **Description**: Selectors for extracting parameter values
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
interface ParamSelector {
|
|
227
|
+
type: 'jsonPath' | 'regex';
|
|
228
|
+
value: string;
|
|
229
|
+
source?: 'url' | 'responseBody' | 'responseHeaders' | 'requestHeaders' | 'requestBody';
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
##### Parameter Source Options
|
|
234
|
+
|
|
235
|
+
The `source` field in `paramSelectors` specifies where to extract the parameter from:
|
|
236
|
+
|
|
237
|
+
###### `responseBody` (default)
|
|
238
|
+
- **Description**: Extract from the response body
|
|
239
|
+
- **Example**:
|
|
240
|
+
```json
|
|
241
|
+
{
|
|
242
|
+
"type": "jsonPath",
|
|
243
|
+
"value": "$.data.transactionId",
|
|
244
|
+
"source": "responseBody"
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
###### `url`
|
|
249
|
+
- **Description**: Extract from the request URL
|
|
250
|
+
- **Example**:
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"type": "regex",
|
|
254
|
+
"value": "userId=([^&]+)",
|
|
255
|
+
"source": "url"
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
###### `responseHeaders`
|
|
260
|
+
- **Description**: Extract from response headers
|
|
261
|
+
- **Example**:
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"type": "regex",
|
|
265
|
+
"value": "X-Transaction-Id: (.+)",
|
|
266
|
+
"source": "responseHeaders"
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
###### `requestHeaders`
|
|
271
|
+
- **Description**: Extract from request headers
|
|
272
|
+
- **Example**:
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"type": "regex",
|
|
276
|
+
"value": "Authorization: Bearer (.+)",
|
|
277
|
+
"source": "requestHeaders"
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
###### `requestBody`
|
|
282
|
+
- **Description**: Extract from the request body (for POST/PUT requests)
|
|
283
|
+
- **Example**:
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"type": "jsonPath",
|
|
287
|
+
"value": "$.payment.amount",
|
|
288
|
+
"source": "requestBody"
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
#### Security Configuration
|
|
293
|
+
|
|
294
|
+
#### `secretHeaders` (optional)
|
|
295
|
+
- **Type**: `string[]`
|
|
296
|
+
- **Description**: Headers containing sensitive data (e.g., auth tokens)
|
|
297
|
+
- **Example**: `["Authorization", "Cookie"]`
|
|
298
|
+
|
|
299
|
+
#### Response Verification
|
|
300
|
+
|
|
301
|
+
#### `responseMatches` (required)
|
|
302
|
+
- **Type**: `ResponseMatch[]`
|
|
303
|
+
- **Description**: Patterns to verify in the response
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
"responseMatches": [
|
|
307
|
+
{
|
|
308
|
+
"type": "jsonPath",
|
|
309
|
+
"value": "$.data.transactions[{{INDEX}}].id",
|
|
310
|
+
"hash": false
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"type": "regex",
|
|
314
|
+
"value": "\"status\":\\s*\"completed\"",
|
|
315
|
+
"hash": true
|
|
316
|
+
}
|
|
317
|
+
]
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
#### `responseRedactions` (optional)
|
|
321
|
+
- **Type**: `ResponseRedaction[]`
|
|
322
|
+
- **Description**: Data to redact from the response for privacy
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
"responseRedactions": [
|
|
326
|
+
{
|
|
327
|
+
"jsonPath": "$.data.user.email",
|
|
328
|
+
"xPath": ""
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
"jsonPath": "$.data.ssn",
|
|
332
|
+
"xPath": ""
|
|
333
|
+
}
|
|
334
|
+
]
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### Additional Options
|
|
338
|
+
|
|
339
|
+
#### `mobile` (optional)
|
|
340
|
+
- **Type**: `object`
|
|
341
|
+
- **Description**: Special configurations for the ZKP2P mobile SDK. The mobile configuration supports both internal (WebView) and external (native app) actions.
|
|
342
|
+
|
|
343
|
+
```json
|
|
344
|
+
"mobile": {
|
|
345
|
+
"includeAdditionalCookieDomains": ["additional-domain.com"],
|
|
346
|
+
"useExternalAction": true,
|
|
347
|
+
"userAgent": {
|
|
348
|
+
"android": "Mozilla/5.0 (Linux; Android 13; Pixel 6) ...",
|
|
349
|
+
"ios": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) ..."
|
|
350
|
+
},
|
|
351
|
+
"external": {
|
|
352
|
+
"actionLink": "venmo://paycharge?txn=pay&recipients={{RECEIVER_ID}}¬e=cash&amount={{AMOUNT}}",
|
|
353
|
+
"appStoreLink": "https://apps.apple.com/us/app/venmo/id351727428",
|
|
354
|
+
"playStoreLink": "https://play.google.com/store/apps/details?id=com.venmo"
|
|
355
|
+
},
|
|
356
|
+
"internal": {
|
|
357
|
+
"actionLink": "https://app.provider.com/send",
|
|
358
|
+
"actionCompletedUrlRegex": "https://app.provider.com/confirmation/\\S+",
|
|
359
|
+
"injectedJavaScript": "/* JavaScript to interact with the webpage */",
|
|
360
|
+
"injectedJavaScriptParamNames": ["RECIPIENT_ID", "AMOUNT"]
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**Top-level Fields:**
|
|
366
|
+
- `includeAdditionalCookieDomains`: Array of additional cookie domains to include
|
|
367
|
+
- `useExternalAction`: Boolean to prefer external action when `true`, otherwise prefer internal action
|
|
368
|
+
- `userAgent` (optional): Custom user agent strings for Android and iOS WebViews
|
|
369
|
+
|
|
370
|
+
**External Action Fields (`external`):**
|
|
371
|
+
- `actionLink`: Deep link URL for the native mobile app with placeholders for dynamic values
|
|
372
|
+
- `appStoreLink`: iOS App Store URL for the app
|
|
373
|
+
- `playStoreLink`: Google Play Store URL for the app
|
|
374
|
+
|
|
375
|
+
**Internal Action Fields (`internal`):**
|
|
376
|
+
- `actionLink`: Web URL to open in WebView for the action
|
|
377
|
+
- `actionCompletedUrlRegex` (optional): Regex pattern to detect when the action is completed
|
|
378
|
+
- `injectedJavaScript` (optional): JavaScript code to inject into the WebView to assist with form filling or interaction
|
|
379
|
+
- `injectedJavaScriptParamNames` (optional): Array of parameter names used in the injected JavaScript
|
|
380
|
+
|
|
381
|
+
**Action Flow:**
|
|
382
|
+
The mobile SDK will attempt actions based on the configuration:
|
|
383
|
+
- If `useExternalAction` is `true`, it will try the external action first (native app), then fall back to internal (WebView)
|
|
384
|
+
- If `useExternalAction` is `false` or omitted, it will try the internal action first (WebView), then fall back to external (native app)
|
|
385
|
+
- Both `internal` and `external` sections can be provided for maximum flexibility
|
|
386
|
+
|
|
387
|
+
#### `additionalClientOptions` (optional)
|
|
388
|
+
- **Type**: `object`
|
|
389
|
+
- **Description**: Extra client configuration options (not commonly used)
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
"additionalClientOptions": {
|
|
393
|
+
"cipherSuites": ["TLS_AES_128_GCM_SHA256"]
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
#### `additionalProofs` (optional)
|
|
398
|
+
- **Type**: `AdditionalProof[]`
|
|
399
|
+
- **Description**: Configuration for generating multiple proofs from different endpoints (not commonly used)
|
|
400
|
+
|
|
401
|
+
### Parameter Extraction Examples
|
|
402
|
+
|
|
403
|
+
##### Example 1: Extract from URL
|
|
404
|
+
```json
|
|
405
|
+
{
|
|
406
|
+
"paramNames": ["userId"],
|
|
407
|
+
"paramSelectors": [{
|
|
408
|
+
"type": "regex",
|
|
409
|
+
"value": "/user/([^/]+)/transactions",
|
|
410
|
+
"source": "url"
|
|
411
|
+
}]
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
##### Example 2: Extract from Response Headers
|
|
416
|
+
```json
|
|
417
|
+
{
|
|
418
|
+
"paramNames": ["sessionId"],
|
|
419
|
+
"paramSelectors": [{
|
|
420
|
+
"type": "regex",
|
|
421
|
+
"value": "X-Session-Id: ([a-zA-Z0-9]+)",
|
|
422
|
+
"source": "responseHeaders"
|
|
423
|
+
}]
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
##### Example 3: Mixed Sources
|
|
428
|
+
```json
|
|
429
|
+
{
|
|
430
|
+
"paramNames": ["userId", "transactionId", "amount"],
|
|
431
|
+
"paramSelectors": [
|
|
432
|
+
{
|
|
433
|
+
"type": "regex",
|
|
434
|
+
"value": "userId=([^&]+)",
|
|
435
|
+
"source": "url"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
"type": "jsonPath",
|
|
439
|
+
"value": "$.data.transactions[{{INDEX}}].id",
|
|
440
|
+
"source": "responseBody"
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
"type": "regex",
|
|
444
|
+
"value": "X-Transaction-Amount: ([0-9.]+)",
|
|
445
|
+
"source": "responseHeaders"
|
|
446
|
+
}
|
|
447
|
+
]
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Extraction Types
|
|
452
|
+
|
|
453
|
+
##### JSONPath
|
|
454
|
+
Use JSONPath expressions for structured data:
|
|
455
|
+
```json
|
|
456
|
+
{
|
|
457
|
+
"type": "jsonPath",
|
|
458
|
+
"value": "$.data.transactions[{{INDEX}}].amount"
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Special features:**
|
|
463
|
+
- `{{INDEX}}` placeholder for array indexing
|
|
464
|
+
- Supports nested paths: `$.user.profile.email`
|
|
465
|
+
- Array filters: `$.items[?(@.status=='active')]`
|
|
466
|
+
|
|
467
|
+
##### Regex
|
|
468
|
+
Use regular expressions for pattern matching:
|
|
469
|
+
```json
|
|
470
|
+
{
|
|
471
|
+
"type": "regex",
|
|
472
|
+
"value": "transactionId\":\\s*\"([^\"]+)\""
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**Notes:**
|
|
477
|
+
- First capture group `()` is used as the extracted value
|
|
478
|
+
- Escape special characters: `\\.` for dots
|
|
479
|
+
- Use `\\s*` for flexible whitespace matching
|
|
480
|
+
|
|
481
|
+
### Best Practices
|
|
482
|
+
|
|
483
|
+
#### 1. URL Regex Patterns
|
|
484
|
+
- Escape special characters: `\\.` for dots
|
|
485
|
+
- Use specific patterns to avoid false matches
|
|
486
|
+
- Test regex patterns thoroughly
|
|
487
|
+
|
|
488
|
+
#### 2. Parameter Extraction
|
|
489
|
+
- Use JSONPath for structured JSON data
|
|
490
|
+
- Use regex for HTML, text responses, or complex patterns
|
|
491
|
+
- Always specify capture groups `()` for regex extraction
|
|
492
|
+
- Specify `source` when extracting from non-default locations (not responseBody)
|
|
493
|
+
- Test extraction with various response formats
|
|
494
|
+
|
|
495
|
+
#### 3. Security
|
|
496
|
+
- List all sensitive headers in `secretHeaders`
|
|
497
|
+
- Use `responseRedactions` to remove PII
|
|
498
|
+
- Never expose authentication tokens in `responseMatches`
|
|
499
|
+
|
|
500
|
+
#### 4. Transaction Extraction
|
|
501
|
+
|
|
502
|
+
##### `transactionRegexSelectors` (optional)
|
|
503
|
+
- **Type**: `object`
|
|
504
|
+
- **Description**: Regular expression patterns to extract transaction data from HTML/text responses
|
|
505
|
+
- **Use case**: Use this when transactions are embedded in HTML or when the response is not structured JSON
|
|
506
|
+
- **Example**:
|
|
507
|
+
```json
|
|
508
|
+
{
|
|
509
|
+
"transactionsExtraction": {
|
|
510
|
+
"transactionRegexSelectors": {
|
|
511
|
+
"amount": "<td class=\"amount\">\\$([\\d,\\.]+)</td>",
|
|
512
|
+
"recipient": "<td class=\"recipient\">([^<]+)</td>",
|
|
513
|
+
"date": "<td class=\"date\">(\\d{2}/\\d{2}/\\d{4})</td>",
|
|
514
|
+
"paymentId": "data-payment-id=\"(\\d+)\""
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
**Note**: Use either `transactionJsonPathListSelector` (for JSON responses) or `transactionRegexSelectors` (for HTML/text responses), not both.
|
|
521
|
+
|
|
522
|
+
#### 5. Error Handling
|
|
523
|
+
- Provide fallback URLs when primary endpoints might fail
|
|
524
|
+
- Use preprocessing regex for embedded JSON data
|
|
525
|
+
- Test extraction selectors with various response formats
|
|
526
|
+
|
|
527
|
+
#### 6. Performance
|
|
528
|
+
- Minimize the number of `responseMatches` for faster verification
|
|
529
|
+
- Use specific JSONPath expressions instead of wildcards
|
|
530
|
+
- Consider response size when designing redactions
|
|
531
|
+
|
|
532
|
+
#### 7. Tab Management
|
|
533
|
+
- Set `shouldSkipCloseTab: true` for flows where when closing the tab results in ending the session token, thus preventing us from replaying the request successfully.
|
|
534
|
+
- Use default behavior (auto-close) for simple authentication flows
|
|
535
|
+
- Consider user experience when deciding tab behavior
|
|
536
|
+
|
|
537
|
+
### Common Issues
|
|
538
|
+
- **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
|
|
539
|
+
- **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
|
|
540
|
+
- **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.
|
|
541
|
+
- **Parameters not extracted correctly**: Check the `source` field in your `paramSelectors`. By default, parameters are extracted from responseBody. If your parameter is in the URL, headers, or request body, you must specify the correct source.
|
|
542
|
+
|
|
543
|
+
## Contributing
|
|
544
|
+
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
|
|
545
|
+
|
|
546
|
+

|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"actionType": "transfer_zelle",
|
|
3
|
+
"authLink": "https://secure.bankofamerica.com/pay-transfer-pay-portal/?request_locale=en-us&returnSiteIndicator=GAIMW&target=paymentactivity#/",
|
|
4
|
+
"url": "https://secure.bankofamerica.com/ogateway/payment-activity/api/v4/activity",
|
|
5
|
+
"method": "POST",
|
|
6
|
+
"body": "{\"filterV1\":{\"dateFilter\":{\"timeframeForHistory\":\"DEFAULTDAYS\"}},\"sortCriteriaV1\":{\"fieldName\":\"DATE\",\"order\":\"DESCENDING\"},\"pageInfo\":{\"pageNum\":1,\"pageSize\":\"\"}}",
|
|
7
|
+
"metadata": {
|
|
8
|
+
"shouldReplayRequestInPage": true,
|
|
9
|
+
"platform": "zelle",
|
|
10
|
+
"urlRegex": "https://secure.bankofamerica.com/ogateway/payment-activity/api/v4/activity",
|
|
11
|
+
"method": "POST",
|
|
12
|
+
"fallbackUrlRegex": "https://secure.bankofamerica.com/myaccounts/omni/rest/CommunicationBarkerCount",
|
|
13
|
+
"fallbackMethod": "GET",
|
|
14
|
+
"preprocessRegex": "",
|
|
15
|
+
"transactionsExtraction": {
|
|
16
|
+
"transactionJsonPathListSelector": "$.completedTransactions",
|
|
17
|
+
"transactionJsonPathSelectors": {
|
|
18
|
+
"recipient": "$.targetAccount.displayName",
|
|
19
|
+
"amount": "$.amount",
|
|
20
|
+
"date": "$.transactionDate",
|
|
21
|
+
"paymentId": "$.confirmationNumber"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"proofMetadataSelectors": [
|
|
25
|
+
{
|
|
26
|
+
"type": "jsonPath",
|
|
27
|
+
"value": "$.completedTransactions[{{INDEX}}].confirmationNumber"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"type": "jsonPath",
|
|
31
|
+
"value": "$.completedTransactions[{{INDEX}}].targetAccount.displayName"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"type": "jsonPath",
|
|
35
|
+
"value": "$.completedTransactions[{{INDEX}}].amount"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "jsonPath",
|
|
39
|
+
"value": "$.completedTransactions[{{INDEX}}].transactionDate"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
"paramNames": [],
|
|
44
|
+
"paramSelectors": [],
|
|
45
|
+
"skipRequestHeaders": [
|
|
46
|
+
"Cookie",
|
|
47
|
+
"Accept-Encoding"
|
|
48
|
+
],
|
|
49
|
+
"secretHeaders": [
|
|
50
|
+
"Cookie"
|
|
51
|
+
],
|
|
52
|
+
"responseMatches": [
|
|
53
|
+
{
|
|
54
|
+
"type": "regex",
|
|
55
|
+
"value": "\"confirmationNumber\":\"(?<confirmationNumber>[^\"]+)\""
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "regex",
|
|
59
|
+
"value": "\"status\":\"(?<status>[^\"]+)\""
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"type": "regex",
|
|
63
|
+
"value": "\"transactionDate\":\"(?<transactionDate>[^\"]+)\""
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"type": "regex",
|
|
67
|
+
"value": "\"amount\":(?<amount>[0-9\\.]+)"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"type": "regex",
|
|
71
|
+
"value": "\"aliasToken\":\"(?<aliasToken>[^\"]+)\"",
|
|
72
|
+
"hash": true
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"responseRedactions": [
|
|
76
|
+
{
|
|
77
|
+
"jsonPath": "$.completedTransactions[{{INDEX}}].confirmationNumber",
|
|
78
|
+
"xPath": ""
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"jsonPath": "$.completedTransactions[{{INDEX}}].status",
|
|
82
|
+
"xPath": ""
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"jsonPath": "$.completedTransactions[{{INDEX}}].transactionDate",
|
|
86
|
+
"xPath": ""
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"jsonPath": "$.completedTransactions[{{INDEX}}].amount",
|
|
90
|
+
"xPath": ""
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"jsonPath": "$.completedTransactions[{{INDEX}}].targetAccount.aliasToken",
|
|
94
|
+
"xPath": ""
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"additionalClientOptions": {
|
|
98
|
+
"cipherSuites": [
|
|
99
|
+
"TLS_CHACHA20_POLY1305_SHA256",
|
|
100
|
+
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
101
|
+
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"mobile": {
|
|
105
|
+
"includeAdditionalCookieDomains": [],
|
|
106
|
+
"useExternalAction": true,
|
|
107
|
+
"external": {
|
|
108
|
+
"actionLink": "bofa://movemoney",
|
|
109
|
+
"appStoreLink": "https://apps.apple.com/us/app/bank-of-america-mobile-banking/id284847138",
|
|
110
|
+
"playStoreLink": "https://play.google.com/store/apps/details?id=com.infonow.bofa"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|