@zkp2p/zkp2p-attestation 1.5.1 → 1.6.2
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 +13 -0
- package/README.md +18 -4
- package/dist/cli/verify.js +29 -3
- 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 +42 -5
- package/dist/index.d.ts +42 -5
- 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,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.2
|
|
4
|
+
|
|
5
|
+
- Default the production environment to `https://attestation-service.zkp2p.xyz` and bundle a production PCR8 pin for that hostname. The historical `attestation-service-preprod.zkp2p.xyz` hostname remains pinned to the same production PCR8.
|
|
6
|
+
- Retry transient network-layer `GET /attestation` failures before surfacing `ATTESTATION_FETCH_FAILED`; HTTP errors, invalid responses, and timeouts still fail immediately.
|
|
7
|
+
|
|
8
|
+
## 1.6.1
|
|
9
|
+
|
|
10
|
+
- Add Cash App identity request typing for `register_cashapp`. Cash App identity session material requires `sessionCookie` and `requestPayload`, accepts optional `requestHeaders`, and uses `{}` public params.
|
|
11
|
+
|
|
12
|
+
## 1.6.0
|
|
13
|
+
|
|
14
|
+
- Add generic buyer TEE Zelle typing for `platform: "zelle"` and bank-specific action types `transfer_zelle_bofa`, `transfer_zelle_chase`, and `transfer_zelle_citi`; direct bank-specific Zelle routes and method hashes remain legacy drain-only.
|
|
15
|
+
|
|
3
16
|
## 1.5.1
|
|
4
17
|
|
|
5
18
|
- Change Venmo identity registration to derive the stories URL from `params.SENDER_ID`. Venmo identity session material now requires only `Cookie`, while the service verifies the authenticated account id before replaying the derived stories request.
|
package/README.md
CHANGED
|
@@ -29,9 +29,9 @@ Environment defaults:
|
|
|
29
29
|
| Environment | Service URL | PCR8 source |
|
|
30
30
|
|---|---|---|
|
|
31
31
|
| `staging` | `https://attestation-service-staging.zkp2p.xyz` | bundled staging pin |
|
|
32
|
-
| `production` | `https://attestation-service
|
|
32
|
+
| `production` | `https://attestation-service.zkp2p.xyz` | bundled production pin |
|
|
33
33
|
|
|
34
|
-
Callers can still pass `attestationServiceUrl` and `trust.expectedPcr8Hex` directly. Explicit trust pins always win.
|
|
34
|
+
Callers can still pass `attestationServiceUrl` and `trust.expectedPcr8Hex` directly. Explicit trust pins always win. The historical `https://attestation-service-preprod.zkp2p.xyz` hostname remains pinned to the same production PCR8 while it continues to serve the Nitro prod deployment.
|
|
35
35
|
|
|
36
36
|
## Fast Path
|
|
37
37
|
|
|
@@ -75,7 +75,7 @@ const verifiedCredentialBundle = verifySellerCredentialBundle(credentialBundle,
|
|
|
75
75
|
});
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
Venmo, Cash App, and
|
|
78
|
+
Venmo, Cash App, PayPal, and Zelle still require a top-level `payeeId`; existing callers can keep using the same call shape:
|
|
79
79
|
|
|
80
80
|
```ts
|
|
81
81
|
const encryptedUpload = await nitro.createEncryptedSellerCredentialUpload({
|
|
@@ -88,6 +88,8 @@ Venmo seller uploads can use either the existing session material or Google OAut
|
|
|
88
88
|
|
|
89
89
|
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
90
|
|
|
91
|
+
Zelle seller uploads use the same Gmail OAuth shape with `platform: "zelle"` and a top-level `payeeId` for the seller's Zelle recipient identifier. The service validates the OAuth mailbox by finding at least one DKIM-verified incoming Zelle receipt from a supported bank/Zelle sender, then later resolves `/seller/verify/zelle` by matching `txId` against the received receipt's transaction, confirmation, reference, or payment id. Seller Zelle attestations use the generic on-chain payment method `keccak256("zelle")`; receipt providers such as Chase, Citi, and Bank of America are metadata only.
|
|
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`.
|
|
@@ -152,8 +154,15 @@ Buyer TEE platform matrix:
|
|
|
152
154
|
| `chime` | `transfer_chime` | `Cookie`, `body` | `{}` |
|
|
153
155
|
| `chase` | `transfer_zelle` | `Cookie`, `x-jpmc-channel`, `x-jpmc-csrf-token`, `Referer`, `Origin` | `index` |
|
|
154
156
|
| `bankofamerica` | `transfer_zelle` | `Cookie` | `index` |
|
|
157
|
+
| `zelle` | `transfer_zelle_bofa` | `Cookie` | `index` |
|
|
158
|
+
| `zelle` | `transfer_zelle_chase` | `Cookie`, `x-jpmc-channel`, `x-jpmc-csrf-token`, `Referer`, `Origin` | `index` |
|
|
159
|
+
| `zelle` | `transfer_zelle_citi` | `Cookie` | `index` |
|
|
155
160
|
| `paypal` | `transfer_paypal` | `Cookie` | `PAYMENT_ID` |
|
|
156
161
|
|
|
162
|
+
The generic Zelle buyer routes use bank-specific action types and attest `intent.paymentMethod = hashUtf8("zelle")`.
|
|
163
|
+
New Zelle deposits and intents should use generic `zelle`. Direct bank-specific routes remain available only for
|
|
164
|
+
legacy drain support with `hashUtf8("zelle-citi")`, `hashUtf8("zelle-chase")`, or `hashUtf8("zelle-bofa")`.
|
|
165
|
+
|
|
157
166
|
Per-platform session-material types require these headers using the canonical names shown above while still allowing
|
|
158
167
|
additional captured headers. Captured request bodies are session material because they can contain sensitive data and
|
|
159
168
|
are encrypted before being sent to the service.
|
|
@@ -194,14 +203,19 @@ Identity platform matrix:
|
|
|
194
203
|
| `venmo` | `register_venmo` | `Cookie` | `SENDER_ID` |
|
|
195
204
|
| `paypal` | `register_paypal` | `Cookie` | `{}` |
|
|
196
205
|
| `wise` | `register_wise` | `Cookie`, `X-Access-Token` | `PROFILE_ID` |
|
|
206
|
+
| `cashapp` | `register_cashapp` | `sessionCookie`, `requestPayload`, optional `requestHeaders` | `{}` |
|
|
197
207
|
|
|
198
208
|
For Venmo identity, pass `SENDER_ID` in public params and include a replayable `Cookie` header in encrypted session
|
|
199
209
|
material. The service verifies the authenticated account id, derives the stories URL from `SENDER_ID`, and requires
|
|
200
210
|
Venmo to return a valid stories response with an explicit `stories` array.
|
|
201
211
|
|
|
212
|
+
For Cash App identity, pass the replayable Cash App session cookie as `sessionMaterial.sessionCookie` and the canonical
|
|
213
|
+
`MY_ACTIVITY_WEB_V2` activity request body as `sessionMaterial.requestPayload`. Include captured replayable headers in
|
|
214
|
+
`sessionMaterial.requestHeaders` when needed; the service ignores public params for this flow.
|
|
215
|
+
|
|
202
216
|
Buyer TEE and identity expose discriminated unions keyed by `platform` and `actionType`, including per-platform
|
|
203
217
|
`params`, so invalid pairings fail during TypeScript compilation. Seller credential upload keeps its existing
|
|
204
|
-
platform narrowing (`wise` derives payee id from the credential; Venmo, Cash App, and
|
|
218
|
+
platform narrowing (`wise` derives payee id from the credential; Venmo, Cash App, PayPal, and Zelle require `payeeId`) but
|
|
205
219
|
does not add exhaustive `sessionMaterial` typing: each seller platform can accept multiple credential sources, such as
|
|
206
220
|
cookie headers or Google OAuth with optional partner OAuth client material, and encoding all combinations would make
|
|
207
221
|
the SDK brittle without improving the wire contract.
|
package/dist/cli/verify.js
CHANGED
|
@@ -4267,6 +4267,8 @@ function parseAdvertisedPcr8(value, label) {
|
|
|
4267
4267
|
|
|
4268
4268
|
// src/attestation/fetch.ts
|
|
4269
4269
|
var MAX_ATTESTATION_RESPONSE_BYTES = 256 * 1024;
|
|
4270
|
+
var NETWORK_LAYER_FETCH_ATTEMPTS = 3;
|
|
4271
|
+
var NETWORK_LAYER_RETRY_DELAY_MS = 150;
|
|
4270
4272
|
var ETH_ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;
|
|
4271
4273
|
function buildAttestationUrl(attestationServiceUrl, nonceHex) {
|
|
4272
4274
|
const url = new URL(attestationServiceUrl);
|
|
@@ -4278,7 +4280,7 @@ function buildAttestationUrl(attestationServiceUrl, nonceHex) {
|
|
|
4278
4280
|
}
|
|
4279
4281
|
async function fetchAttestationEnvelope(params) {
|
|
4280
4282
|
const url = buildAttestationUrl(params.attestationServiceUrl, params.nonceHex);
|
|
4281
|
-
const response = await
|
|
4283
|
+
const response = await fetchWithNetworkRetry(url.toString(), params.fetch, params.timeoutMs);
|
|
4282
4284
|
const responseText = await readResponseText(response);
|
|
4283
4285
|
if (!response.ok) {
|
|
4284
4286
|
fail("ATTESTATION_FETCH_FAILED", `GET /attestation failed with HTTP ${response.status}`, {
|
|
@@ -4372,6 +4374,20 @@ function parseOptionalAdvertisedPcr8(value, label) {
|
|
|
4372
4374
|
fail("ATTESTATION_RESPONSE_INVALID", `${label} must be a 96-character lowercase hex string`, { cause });
|
|
4373
4375
|
}
|
|
4374
4376
|
}
|
|
4377
|
+
async function fetchWithNetworkRetry(url, fetcher, timeoutMs) {
|
|
4378
|
+
let attempt = 1;
|
|
4379
|
+
while (true) {
|
|
4380
|
+
try {
|
|
4381
|
+
return await fetchWithTimeout(url, fetcher, timeoutMs);
|
|
4382
|
+
} catch (cause) {
|
|
4383
|
+
if (!isNetworkLayerFetchFailure(cause) || attempt >= NETWORK_LAYER_FETCH_ATTEMPTS) {
|
|
4384
|
+
throw cause;
|
|
4385
|
+
}
|
|
4386
|
+
await sleep(NETWORK_LAYER_RETRY_DELAY_MS * attempt);
|
|
4387
|
+
attempt += 1;
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
}
|
|
4375
4391
|
async function fetchWithTimeout(url, fetcher, timeoutMs) {
|
|
4376
4392
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
4377
4393
|
let timeoutHandle;
|
|
@@ -4400,9 +4416,18 @@ async function fetchWithTimeout(url, fetcher, timeoutMs) {
|
|
|
4400
4416
|
if (cause instanceof Error && (cause.name === "AbortError" || cause.message === "timeout")) {
|
|
4401
4417
|
fail("TIMEOUT", `GET /attestation timed out after ${timeoutMs}ms`, { cause });
|
|
4402
4418
|
}
|
|
4403
|
-
fail("ATTESTATION_FETCH_FAILED", "GET /attestation failed at the network layer", {
|
|
4419
|
+
fail("ATTESTATION_FETCH_FAILED", "GET /attestation failed at the network layer", {
|
|
4420
|
+
cause,
|
|
4421
|
+
details: { layer: "network" }
|
|
4422
|
+
});
|
|
4404
4423
|
}
|
|
4405
4424
|
}
|
|
4425
|
+
function isNetworkLayerFetchFailure(cause) {
|
|
4426
|
+
return cause instanceof NitroAttestationError && cause.code === "ATTESTATION_FETCH_FAILED" && cause.details?.layer === "network";
|
|
4427
|
+
}
|
|
4428
|
+
function sleep(ms) {
|
|
4429
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
4430
|
+
}
|
|
4406
4431
|
function isRecord(value) {
|
|
4407
4432
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4408
4433
|
}
|
|
@@ -4482,7 +4507,8 @@ var STAGING_PCR8 = "5636e3bd96f847cf12cfd9de7faa8cad0e6fa00962ce16ba185f8e5ea571
|
|
|
4482
4507
|
var PRODUCTION_PCR8 = "41a4ae0b9b96752cab5addb7d22689b3070e564e29f90a54316fa33fa38ea51387a6e887ea4f5a4b0cc34f69cea3f40e";
|
|
4483
4508
|
var DEFAULT_EXPECTED_PCR8_BY_HOST = {
|
|
4484
4509
|
"attestation-service-staging.zkp2p.xyz": normalizePcr8Pin(STAGING_PCR8, "bundled staging PCR8"),
|
|
4485
|
-
"attestation-service-preprod.zkp2p.xyz": normalizePcr8Pin(PRODUCTION_PCR8, "bundled production PCR8")
|
|
4510
|
+
"attestation-service-preprod.zkp2p.xyz": normalizePcr8Pin(PRODUCTION_PCR8, "bundled production PCR8"),
|
|
4511
|
+
"attestation-service.zkp2p.xyz": normalizePcr8Pin(PRODUCTION_PCR8, "bundled production PCR8")
|
|
4486
4512
|
};
|
|
4487
4513
|
|
|
4488
4514
|
// src/trust/resolveExpectedPcr8.ts
|