uvd-x402-sdk 2.63.0 → 2.65.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/README.md +89 -0
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/index.mjs.map +1 -1
- package/dist/index.d.mts +44 -2
- package/dist/index.d.ts +44 -2
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -1
- package/dist/index.mjs.map +1 -1
- package/dist/providers/algorand/index.js.map +1 -1
- package/dist/providers/algorand/index.mjs.map +1 -1
- package/dist/providers/evm/index.js.map +1 -1
- package/dist/providers/evm/index.mjs.map +1 -1
- package/dist/providers/near/index.js.map +1 -1
- package/dist/providers/near/index.mjs.map +1 -1
- package/dist/providers/solana/index.js.map +1 -1
- package/dist/providers/solana/index.mjs.map +1 -1
- package/dist/providers/stellar/index.js.map +1 -1
- package/dist/providers/stellar/index.mjs.map +1 -1
- package/dist/providers/sui/index.js.map +1 -1
- package/dist/providers/sui/index.mjs.map +1 -1
- package/dist/providers/xrpl/index.js.map +1 -1
- package/dist/providers/xrpl/index.mjs.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs.map +1 -1
- package/dist/utils/index.d.mts +24 -1
- package/dist/utils/index.d.ts +24 -1
- package/dist/utils/index.js +55 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +55 -1
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/dx402.ts +59 -0
- package/src/index.ts +3 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/x402.ts +101 -0
package/README.md
CHANGED
|
@@ -1280,3 +1280,92 @@ const isHealthy = await client.healthCheck();
|
|
|
1280
1280
|
## License
|
|
1281
1281
|
|
|
1282
1282
|
MIT
|
|
1283
|
+
|
|
1284
|
+
## DX402 — evidence that outlives the session
|
|
1285
|
+
|
|
1286
|
+
x402 settles payment on-chain forever but delivers the resource **once** and
|
|
1287
|
+
keeps nothing. DX402 seals a copy of the response to the payer's own public key
|
|
1288
|
+
— recovered from the payment signature itself — and anchors it. No registration,
|
|
1289
|
+
no extra round trip: paying *is* publishing your encryption key.
|
|
1290
|
+
|
|
1291
|
+
### Seller: one call
|
|
1292
|
+
|
|
1293
|
+
```ts
|
|
1294
|
+
import { anchorEvidence, evidenceHeader } from 'uvd-x402-sdk';
|
|
1295
|
+
|
|
1296
|
+
const result = await anchorEvidence(body, {
|
|
1297
|
+
paymentId, network: 'base', txHash,
|
|
1298
|
+
payer: payerAddr, payee: myAddr, payerKey: payerPubkey,
|
|
1299
|
+
sign: (digest) => myCustodian.sign(digest), // a callable, not a key
|
|
1300
|
+
});
|
|
1301
|
+
res.setHeader('X-Durable-Evidence', evidenceHeader(result));
|
|
1302
|
+
```
|
|
1303
|
+
|
|
1304
|
+
**It never throws.** Every failure resolves to `result.skipped`, because
|
|
1305
|
+
evidence is an addition to the payment path and must never be a gate in front of
|
|
1306
|
+
it. An unreachable facilitator costs the receipt, never the sale.
|
|
1307
|
+
|
|
1308
|
+
`sign` takes a **callable rather than a private key** so a custodian can sign:
|
|
1309
|
+
it receives the 32-byte digest and returns a signature without the seed ever
|
|
1310
|
+
leaving it.
|
|
1311
|
+
|
|
1312
|
+
### Buyer: come back months later
|
|
1313
|
+
|
|
1314
|
+
```ts
|
|
1315
|
+
import { recoverEvidence, evidenceFromHeaders } from 'uvd-x402-sdk';
|
|
1316
|
+
|
|
1317
|
+
const evidence = evidenceFromHeaders(res.headers);
|
|
1318
|
+
const body = await recoverEvidence(evidence, myPrivateKey);
|
|
1319
|
+
```
|
|
1320
|
+
|
|
1321
|
+
This needs permission from nobody. The ciphertext was sealed to the wallet that
|
|
1322
|
+
paid, so recovery is arithmetic rather than an access-control decision anyone
|
|
1323
|
+
could refuse. The `contentHash` check runs automatically and throws
|
|
1324
|
+
`ContentHashMismatch` — it is what catches a seller who anchored something other
|
|
1325
|
+
than what it served.
|
|
1326
|
+
|
|
1327
|
+
### `verified` vs `signed` — read this before you branch on either
|
|
1328
|
+
|
|
1329
|
+
Since facilitator **1.87.0** a signature alone does not make an anchor final:
|
|
1330
|
+
|
|
1331
|
+
| field | means | supersedable by |
|
|
1332
|
+
|---|---|---|
|
|
1333
|
+
| `verified: true` | the **chain** confirmed this address is the payee | nothing — final |
|
|
1334
|
+
| `signed: true` | the claimant controls the address it *declared* | a verified anchor |
|
|
1335
|
+
| neither | anyone could have written it | either of the above |
|
|
1336
|
+
|
|
1337
|
+
To reach `verified` you must send `proofOfPayment`. Without it the facilitator
|
|
1338
|
+
has checked no chain and answers `notVerifiedReason: "dx402_proof_missing"` —
|
|
1339
|
+
your signature was still accepted (`signed: true`), authorship simply was not
|
|
1340
|
+
certified.
|
|
1341
|
+
|
|
1342
|
+
Why the split: `verified` was previously decided against the `payee` field *in
|
|
1343
|
+
the request*, which the caller supplies. Proving "I control the address I typed
|
|
1344
|
+
into my own request" was enough to own a stranger's evidence permanently.
|
|
1345
|
+
|
|
1346
|
+
### Choosing where evidence is stored
|
|
1347
|
+
|
|
1348
|
+
```ts
|
|
1349
|
+
import { availableBackends } from 'uvd-x402-sdk';
|
|
1350
|
+
|
|
1351
|
+
for (const b of await availableBackends()) {
|
|
1352
|
+
console.log(b.id, b.retention, b.revocable ? 'deletable' : 'IRREVERSIBLE');
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
await anchorEvidence(body, { ...opts, storage: 'ipfs-private' });
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
Ask rather than assume: what exists depends on the deployment, and you may be
|
|
1359
|
+
pointed at a facilitator that is not ours. `revocable: false` means the
|
|
1360
|
+
`retentionUntil` in the **signed** receipt cannot be honoured — on public IPFS,
|
|
1361
|
+
unpinning removes the facilitator's copy, not the network's.
|
|
1362
|
+
|
|
1363
|
+
### Limits
|
|
1364
|
+
|
|
1365
|
+
- Inline anchors cap at **64 KiB of request** (~47 KB of plaintext); the SDK
|
|
1366
|
+
returns `skipped: 'too_large'` before touching the network.
|
|
1367
|
+
- Anchoring with `retention: 'permanent'` is **irrevocable**.
|
|
1368
|
+
- On Solana, `verified` is not reachable yet — the on-chain gate cannot read
|
|
1369
|
+
that payment, so `signed: true` is the honest maximum.
|
|
1370
|
+
|
|
1371
|
+
Full guide: [DX402.md](https://github.com/UltravioletaDAO/x402-rs/blob/main/docs/DX402.md)
|