@zkp2p/zkp2p-attestation 3.0.1 → 4.0.0-rc.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/CHANGELOG.md +16 -0
- package/README.md +88 -11
- package/dist/cli/verify.js +0 -2
- package/dist/cli/verify.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -37
- package/dist/index.d.ts +178 -37
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.0-rc.0
|
|
4
|
+
|
|
5
|
+
- Add X Money seller credential uploads and receipt-gated `register_xmoney` seller identity types. Mailbox credentials support Google OAuth, Microsoft OAuth, and iCloud Mail; standalone X Money identity requests remain unavailable.
|
|
6
|
+
|
|
7
|
+
- BREAKING: Monobank buyer TEE now uses entrepreneur business portal `gatewayState`/`browserId` credentials and `CLIENT_ID`/`TRANSACTION_ID` params. Retire the buyer Open API token shape; enforce settled UAH transfers and a service-owned 14-day timestamp buffer.
|
|
8
|
+
|
|
9
|
+
- Add typed X Money Buyer TEE requests with encrypted captured `url` and headers, and no public params. Replay the captured GraphQL operation ID and derive the transaction ID from the URL instead of accepting duplicate input.
|
|
10
|
+
|
|
11
|
+
- BREAKING: remove the retired HDFC Gmail buyer proof types and action. Amazon
|
|
12
|
+
Pay is the supported UPI buyer and seller verification path.
|
|
13
|
+
|
|
14
|
+
## 3.1.0
|
|
15
|
+
|
|
16
|
+
- Remove the retired preproduction hostname and PCR8 from bundled trust pins.
|
|
17
|
+
- Add typed Venmo and PayPal dispute helpers for attested session encryption, `POST /dispute/verify`, and local `DisputeAttestation` verification. The helpers use the `ZKP2P DisputeVerifier` EIP-712 domain and `DisputeDetails` wire fields while keeping all extracted identifiers out of public params.
|
|
18
|
+
|
|
3
19
|
## 3.0.1
|
|
4
20
|
|
|
5
21
|
- Restore the generic Buyer TEE compact JWE for standalone identity capture while retaining the Alipay types added in 3.0.0. `callerAddress` remains required on `POST /identity` and in the signed typed data, but is no longer required by identity encryption helpers or nested inside encrypted session material.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zkp2p/zkp2p-attestation
|
|
2
2
|
|
|
3
|
-
Client-side verifier and encryptor for ZKP2P Nitro
|
|
3
|
+
Client-side verifier and encryptor for ZKP2P Nitro payment, dispute, identity, and seller-credential flows.
|
|
4
4
|
|
|
5
5
|
The package runs in Chrome MV3 service workers, browser DOM contexts, React Native with a Web Crypto polyfill, and Node >= 20. Library entrypoints use `fetch`, `SubtleCrypto`, `crypto.getRandomValues`, and `Uint8Array`; they do not import `node:*` modules or use `Buffer`.
|
|
6
6
|
|
|
@@ -33,7 +33,7 @@ Environment defaults:
|
|
|
33
33
|
| `staging` | `https://attestation-service-staging.zkp2p.xyz` | bundled staging pin |
|
|
34
34
|
| `production` | `https://attestation-service.zkp2p.xyz` | bundled production pin |
|
|
35
35
|
|
|
36
|
-
Callers can still pass `attestationServiceUrl` and `trust.expectedPcr8Hex` directly. Explicit trust pins always win.
|
|
36
|
+
Callers can still pass `attestationServiceUrl` and `trust.expectedPcr8Hex` directly. Explicit trust pins always win. Bundled trust is limited to the canonical staging and production hostnames.
|
|
37
37
|
|
|
38
38
|
## Fast Path
|
|
39
39
|
|
|
@@ -86,15 +86,17 @@ const encryptedUpload = await nitro.createEncryptedSellerCredentialUpload({
|
|
|
86
86
|
});
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
Venmo Gmail OAuth uploads use the same encryption helper with numeric Venmo account id as `payeeId` and `sessionMaterial: { credentialSource: "google_oauth", authorizationCode, redirectUri, oauthClient? }`. The service binds a DKIM-verified receipt recipient to that account through Venmo's public profile API. The optional partner app secret and refresh token remain inside the encrypted seller bundle. Existing Venmo session-cookie uploads remain an independently supported credential type.
|
|
90
|
+
|
|
89
91
|
PayPal Gmail OAuth seller uploads use the same app-selection model. Pass the seller PayPal email as `payeeId` and use `sessionMaterial: { credentialSource: "google_oauth", authorizationCode, redirectUri }`; the service validates Gmail access against paypal.com DKIM-signed payment receipts. To onboard through a partner-owned Google OAuth app, include `oauthClient: { clientId, clientSecret }` inside the encrypted `sessionMaterial`. The PayPal partner client secret is handled as seller credential material: it rides only in the compact JWE upload plaintext, is sealed with the Gmail refresh token in the KMS-envelope seller credential bundle, and is reused only to refresh that seller's Gmail access token.
|
|
90
92
|
|
|
91
93
|
Buyer TEE requests use the same attested upload key and compact JWE envelope. The typed helper encrypts the captured
|
|
92
94
|
session material, posts `{ encryptedSessionMaterial, params, chainId, intent }` to
|
|
93
95
|
`POST /buyer/verify/:platform/:actionType`, unwraps the service envelope, and returns a typed `AttestationOutput`.
|
|
94
|
-
The service does not enforce capture-age or one-use replay limits for
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
The service does not enforce capture-age or one-use replay limits for reusable
|
|
97
|
+
buyer TEE session material; verification depends on the upstream session still
|
|
98
|
+
being active. Treat any accidental JWE disclosure as equivalent to leaking its
|
|
99
|
+
underlying private evidence.
|
|
98
100
|
|
|
99
101
|
```ts
|
|
100
102
|
const attestation = await nitro.verifyBuyerTeePayment({
|
|
@@ -153,19 +155,76 @@ Buyer TEE platform matrix:
|
|
|
153
155
|
| `zelle` | `transfer_zelle_chase` | `Cookie`, `x-jpmc-channel`, `x-jpmc-csrf-token`, `Referer`, `Origin` | `index` |
|
|
154
156
|
| `zelle` | `transfer_zelle_citi` | `Cookie` | `index` |
|
|
155
157
|
| `paypal` | `transfer_paypal` | `Cookie` | `PAYMENT_ID` |
|
|
158
|
+
| `monobank` | `transfer_monobank` | `gatewayState`, `browserId` | `CLIENT_ID`, `TRANSACTION_ID` |
|
|
156
159
|
| `alipay` | `transfer_alipay` | `Cookie` | `TRADE_NO` |
|
|
160
|
+
| `upi` | `transfer_upi_amazonpay` | `Cookie`, `User-Agent`, `body` | `TRANSACTION_URL` |
|
|
161
|
+
| `xmoney` | `transfer_xmoney` | `url`, `Cookie` and other captured session headers | `{}` |
|
|
162
|
+
|
|
163
|
+
Monobank buyer verification uses the entrepreneur business portal session. Capture
|
|
164
|
+
`localStorage.gateway` as `gatewayState`, and encode the raw P-256 public key from
|
|
165
|
+
`localStorage.browserId.publicKey` as unpadded base64url `browserId`. Encrypt both
|
|
166
|
+
inside the normal buyer JWE. `CLIENT_ID` selects the business profile and
|
|
167
|
+
`TRANSACTION_ID` selects its payment detail. The attestor constructs and encrypts
|
|
168
|
+
the bank request itself; caller-supplied payment JSON or encrypted request bodies
|
|
169
|
+
are rejected. It accepts settled outgoing UAH transfers (bank currency code 980),
|
|
170
|
+
hashes the recipient IBAN and bank payment ID, and signs a service-owned 14-day
|
|
171
|
+
buffer. The previous buyer Open API token shape is no longer accepted.
|
|
172
|
+
|
|
173
|
+
X Money replays the captured `url`, including X's current GraphQL operation ID,
|
|
174
|
+
just as Chime replays its captured `body`. Both stay inside encrypted session
|
|
175
|
+
material. The attestor owns endpoint and operation validation; X Money remains
|
|
176
|
+
GET-only on `https://x.com`, derives the transaction ID from the captured URL,
|
|
177
|
+
and requires the response ID to match. Ship the X Money extension capture and attestor changes
|
|
178
|
+
together; captures without `url` are rejected. Chime's contract is unchanged.
|
|
157
179
|
|
|
158
180
|
Zelle buyer verification uses only `platform: "zelle"` with bank-specific action types. Every Zelle action attests
|
|
159
181
|
`intent.paymentMethod = hashUtf8("zelle")`; direct bank-specific platforms are unsupported.
|
|
160
182
|
|
|
183
|
+
Amazon Pay uses `platform: "upi"` and `actionType: "transfer_upi_amazonpay"`.
|
|
184
|
+
Capture the `getTransactionHistory` GraphQL request after signing into Amazon
|
|
185
|
+
Pay and applying a transaction-history filter. Send its headers and exact request
|
|
186
|
+
body as encrypted session material, with only the selected history row's
|
|
187
|
+
`transactionDetailPageURL` as `params.TRANSACTION_URL`. The service rebuilds the
|
|
188
|
+
history query, confirms the selected outgoing payment, and fetches its receipt;
|
|
189
|
+
receipt URL labels alone do not establish payment direction. Both UPI actions use
|
|
190
|
+
the same `upi:<UPI reference>` payment-id preimage. Amazon session cookies remain
|
|
191
|
+
subject to server-side expiry or revocation; the package does not refresh them.
|
|
192
|
+
|
|
161
193
|
Per-platform session-material types require these headers using the canonical names shown above while still allowing
|
|
162
194
|
additional captured headers. Captured request bodies are session material because they can contain sensitive data and
|
|
163
195
|
are encrypted before being sent to the service.
|
|
164
196
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
197
|
+
Dispute verification uses the same attested key and compact JWE shape. The complete raw email stays encrypted, and all
|
|
198
|
+
payment, dispute, and amount fields come from its authenticated contents rather than public params.
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
const dispute = await nitro.verifyDispute({
|
|
202
|
+
platform: "venmo",
|
|
203
|
+
actionType: "dispute_venmo",
|
|
204
|
+
sessionMaterial: { rawEmail: completeRfc5322Email },
|
|
205
|
+
params: {},
|
|
206
|
+
chainId,
|
|
207
|
+
intentHash,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const verifiedDispute = verifyDisputeAttestation(dispute, {
|
|
211
|
+
trustedSigners,
|
|
212
|
+
expectedPlatform: "venmo",
|
|
213
|
+
expectedActionType: "dispute_venmo",
|
|
214
|
+
expectedDomain: { chainId, verifyingContract: disputeVerifier },
|
|
215
|
+
expectedIntentHash: intentHash,
|
|
216
|
+
});
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Venmo uses `dispute_venmo`; PayPal uses `dispute_paypal`. Both accept only `{ rawEmail }` encrypted session material
|
|
220
|
+
and `{}` public params. `verifyDisputeAttestation` checks the DisputeVerifier EIP-712 domain, the same trusted
|
|
221
|
+
attestation-service witnesses used by payment and identity, the request intent, the signed data hash, and exact parity
|
|
222
|
+
between `disputeDetails` and `encodedDisputeDetails`.
|
|
223
|
+
|
|
224
|
+
Identity requests use the same attested upload key and compact JWE plaintext shape as buyer TEE, but with a narrower
|
|
225
|
+
platform/action matrix. The typed helper encrypts captured session material, posts
|
|
226
|
+
`{ platform, actionType, callerAddress, encryptedSessionMaterial, params }` to `POST /identity`, unwraps the service response, and
|
|
227
|
+
returns an `IdentityAttestationOutput`. `verifyIdentityAttestation` checks the EIP-712 signature, trusted signer,
|
|
169
228
|
platform/action binding, expected caller address, expected payee hash, canonical identity `dataHash`, and `validUntil`,
|
|
170
229
|
then returns normalized identity details.
|
|
171
230
|
|
|
@@ -215,7 +274,9 @@ For Cash App identity, pass the replayable Cash App session cookie as `sessionMa
|
|
|
215
274
|
|
|
216
275
|
For Alipay identity, pass a replayable `Cookie` header. The service fetches the authenticated account page and signs
|
|
217
276
|
the historical transfer-recipient preimage: normalized recipient name concatenated directly with the redacted,
|
|
218
|
-
lowercased email.
|
|
277
|
+
lowercased email. CJK names use their final CJK character to match Alipay's masked transfer detail; non-CJK names keep
|
|
278
|
+
the existing token normalization. The normalized full email remains `identity.username`; the authenticated account's
|
|
279
|
+
16-digit PID is returned as `identity.metadata.alipayPid` for payment routing.
|
|
219
280
|
|
|
220
281
|
Buyer TEE and identity expose discriminated unions keyed by `platform` and `actionType`, including per-platform
|
|
221
282
|
`params`, so invalid pairings fail during TypeScript compilation. Seller credential upload keeps its existing
|
|
@@ -268,6 +329,17 @@ Identity helpers emit `{ platform, actionType, sessionMaterial, boundPubKeySha25
|
|
|
268
329
|
like buyer TEE capture. The outer `callerAddress` is required by `POST /identity` and included in the signed typed data,
|
|
269
330
|
but is not encrypted into or authenticated by the session envelope.
|
|
270
331
|
|
|
332
|
+
For dispute flows with a cached attestation:
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
const encryptedSessionMaterial = await nitro.encryptDisputeSessionMaterial({
|
|
336
|
+
key: verified.attestedSellerUploadKey,
|
|
337
|
+
platform: "paypal",
|
|
338
|
+
actionType: "dispute_paypal",
|
|
339
|
+
sessionMaterial: { rawEmail: completeRfc5322Email },
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
271
343
|
The attested SPKI is stable within one enclave process. If the enclave restarts, cached keys become stale and upload decrypt will fail; fetch a fresh attestation for a new session.
|
|
272
344
|
|
|
273
345
|
## React Native Wiring
|
|
@@ -290,18 +362,23 @@ Any conforming `SubtleCrypto` works. The package does not require `Buffer`.
|
|
|
290
362
|
```ts
|
|
291
363
|
import {
|
|
292
364
|
createEncryptedBuyerTeeSessionMaterial,
|
|
365
|
+
createEncryptedDisputeSessionMaterial,
|
|
293
366
|
createEncryptedIdentitySessionMaterial,
|
|
294
367
|
createEncryptedSellerCredentialUpload,
|
|
295
368
|
encryptBuyerTeeSessionMaterial,
|
|
369
|
+
encryptDisputeSessionMaterial,
|
|
296
370
|
encryptIdentitySessionMaterial,
|
|
297
371
|
encryptSellerCredentialUpload,
|
|
298
372
|
fetchAndVerifyAttestation,
|
|
299
373
|
getUnifiedPaymentVerifierDomainSeparator,
|
|
374
|
+
getDisputeVerifierDomainSeparator,
|
|
300
375
|
hashUtf8,
|
|
301
376
|
requestIdentityAttestation,
|
|
302
377
|
uploadSellerCredential,
|
|
303
378
|
verifyBuyerTeePaymentAttestation,
|
|
304
379
|
verifyBuyerTeePayment,
|
|
380
|
+
verifyDispute,
|
|
381
|
+
verifyDisputeAttestation,
|
|
305
382
|
verifyIdentityAttestation,
|
|
306
383
|
verifySellerCredentialBundle,
|
|
307
384
|
} from "@zkp2p/zkp2p-attestation";
|
package/dist/cli/verify.js
CHANGED
|
@@ -4510,10 +4510,8 @@ var DEFAULT_TIMEOUT_MS = 1e4;
|
|
|
4510
4510
|
// src/trust/pins.ts
|
|
4511
4511
|
var STAGING_PCR8 = "5636e3bd96f847cf12cfd9de7faa8cad0e6fa00962ce16ba185f8e5ea57105abb3cc9cc34f1e1e4de3444ceabcca7485";
|
|
4512
4512
|
var PRODUCTION_PCR8 = "41a4ae0b9b96752cab5addb7d22689b3070e564e29f90a54316fa33fa38ea51387a6e887ea4f5a4b0cc34f69cea3f40e";
|
|
4513
|
-
var PREPROD_PCR8 = "5453c5bfb7d040285be5ba9af142f4fbdd9685d082f244b66c62bf7b22d8d02a638fa2e02b9a6fe8877953a9429209e0";
|
|
4514
4513
|
var DEFAULT_EXPECTED_PCR8_BY_HOST = {
|
|
4515
4514
|
"attestation-service-staging.zkp2p.xyz": normalizePcr8Pin(STAGING_PCR8, "bundled staging PCR8"),
|
|
4516
|
-
"attestation-service-preprod.zkp2p.xyz": normalizePcr8Pin(PREPROD_PCR8, "bundled preprod PCR8"),
|
|
4517
4515
|
"attestation-service.zkp2p.xyz": normalizePcr8Pin(PRODUCTION_PCR8, "bundled production PCR8")
|
|
4518
4516
|
};
|
|
4519
4517
|
|