insumer-verify 1.2.1 → 1.3.1

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.
Files changed (2) hide show
  1. package/README.md +38 -1
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -105,6 +105,41 @@ The attestation response you're verifying looks like this:
105
105
 
106
106
  No balances. No amounts. Just a signed true/false per condition.
107
107
 
108
+ ### Handling `rpc_failure` errors
109
+
110
+ If the API cannot reach one or more data sources (RPC nodes, Helius, XRPL, Covalent) after retries, it returns `ok: false` with error code `rpc_failure` instead of issuing an attestation. **No signature, no JWT, no credits charged.** This is a retryable error — retry the same request after a short delay (2-5 seconds).
111
+
112
+ ```json
113
+ {
114
+ "ok": false,
115
+ "error": {
116
+ "code": "rpc_failure",
117
+ "message": "Unable to verify all conditions — data source unavailable after retries",
118
+ "failedConditions": [
119
+ { "source": "rpcBalanceOf", "chainId": "43114", "message": "Timeout" }
120
+ ]
121
+ },
122
+ "meta": { "version": "1.0", "timestamp": "..." }
123
+ }
124
+ ```
125
+
126
+ **Important:** `rpc_failure` is NOT a verification failure. It means the API could not check the condition at all. Do not treat it as `pass: false`. Check for `ok: false` with `error.code === "rpc_failure"` and retry:
127
+
128
+ ```typescript
129
+ const res = await fetch("https://api.insumermodel.com/v1/attest", { ... });
130
+ const data = await res.json();
131
+
132
+ if (!data.ok && data.error?.code === "rpc_failure") {
133
+ // Retryable — data source temporarily unavailable
134
+ // Wait 2-5 seconds and retry the same request
135
+ console.log("RPC failure, retrying...", data.error.failedConditions);
136
+ return;
137
+ }
138
+
139
+ // Only verify if we got an actual attestation
140
+ const result = await verifyAttestation(data, { maxAge: 120 });
141
+ ```
142
+
108
143
  ### Browser
109
144
 
110
145
  ```html
@@ -148,7 +183,9 @@ When `jwksUrl` is set, the library fetches the JWKS, matches the key by `kid` fr
148
183
 
149
184
  | Parameter | Type | Description |
150
185
  |-----------|------|-------------|
151
- | `response` | `unknown` | Full InsumerAPI response (must contain `data.attestation` and `data.sig`) |
186
+ | `response` | `unknown` | Full InsumerAPI response envelope (must contain `data.attestation` and `data.sig`) |
187
+
188
+ > **Common mistake:** Pass the **full API response** (`await res.json()`), not `response.data` or `response.data.attestation`. The function expects the outer envelope `{ok, data: {attestation, sig, kid}, meta}`. Passing the inner `data` object will throw `"Invalid response: missing data object"`.
152
189
  | `options.maxAge` | `number` | Optional max age in seconds for block freshness check |
153
190
  | `options.jwksUrl` | `string` | Optional JWKS URL for dynamic key discovery (e.g. `https://insumermodel.com/.well-known/jwks.json`) |
154
191
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insumer-verify",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "description": "Client-side verifier for InsumerAPI attestations. ECDSA P-256 signatures, condition hashes, block freshness, expiry. Zero dependencies. Used by DJD Agent Score (Coinbase x402).",
5
5
  "type": "module",
6
6
  "main": "build/index.js",