uvd-x402-sdk 2.63.0 → 2.64.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uvd-x402-sdk",
3
- "version": "2.63.0",
3
+ "version": "2.64.0",
4
4
  "description": "x402 Payment SDK - Gasless crypto payments across 25 blockchains via Ultravioleta facilitator. Supports EVM (including Scroll, SKALE Base, Robinhood Chain), Solana, Fogo, Stellar, NEAR, Algorand, Sui, and XRP Ledger. Features: ERC-8004 Trustless Agents, Escrow/Refunds, multi-stablecoin (USDC, EURC, AUSD, PYUSD, USDT, USDG).",
5
5
  "author": "Ultravioleta DAO <ultravioletadao@gmail.com>",
6
6
  "license": "MIT",
package/src/dx402.ts CHANGED
@@ -836,6 +836,17 @@ export interface AnchorOptions {
836
836
  * proves more may supersede it.
837
837
  */
838
838
  proofOfPayment?: Record<string, unknown>;
839
+ /**
840
+ * Which backend to anchor to (`"s3"`, `"ipfs-private"`, `"ipfs-public"`).
841
+ * Omit to take the facilitator's default.
842
+ *
843
+ * Ask {@link availableBackends} what a given facilitator offers rather than
844
+ * assuming — it depends on the deployment, and you may be pointed at one that
845
+ * is not ours. **`ipfs-public` is irreversible**: the bytes become permanently
846
+ * resolvable by anyone, and nobody, the facilitator included, can take them
847
+ * down.
848
+ */
849
+ storage?: string;
839
850
  /**
840
851
  * `(digest) => "0x..."`. A callable rather than a private key is what lets a
841
852
  * custodian sign: it receives the digest and returns the signature without the
@@ -969,6 +980,10 @@ export async function anchorEvidence(
969
980
  payload.proofOfPayment = opts.proofOfPayment;
970
981
  }
971
982
 
983
+ if (opts.storage) {
984
+ payload.storage = opts.storage;
985
+ }
986
+
972
987
  if (opts.sign) {
973
988
  const digest = sellerDigestFor(opts.paymentId, hash, opts.payee, opts.network);
974
989
  if (digest === undefined) {
@@ -1020,6 +1035,50 @@ export async function anchorEvidence(
1020
1035
  }
1021
1036
  }
1022
1037
 
1038
+ /** One storage option a facilitator offers, from `GET /dx402/stats`. */
1039
+ export interface BackendOffer {
1040
+ id: string;
1041
+ retention: string;
1042
+ /**
1043
+ * Whether the bytes can actually be removed when retention expires.
1044
+ *
1045
+ * `false` means the `retentionUntil` in the signed receipt **cannot be
1046
+ * honoured**: on public IPFS, unpinning removes the facilitator's copy, not
1047
+ * the network's.
1048
+ */
1049
+ revocable: boolean;
1050
+ /** Whether anyone resolves the bytes without going through the facilitator. */
1051
+ public: boolean;
1052
+ enabled: boolean;
1053
+ disabledReason?: string;
1054
+ }
1055
+
1056
+ /**
1057
+ * Ask a facilitator which storage backends it actually offers.
1058
+ *
1059
+ * Ask instead of assuming. What exists depends on the deployment — one without
1060
+ * a Pinata credential offers only `s3` — and an integrator may be pointed at a
1061
+ * facilitator that is not ours. A hardcoded list in your code is a promise
1062
+ * somebody else has to keep.
1063
+ *
1064
+ * Resolves to `[]` rather than rejecting when the facilitator is unreachable or
1065
+ * does not run DX402 — same discipline as {@link anchorEvidence}.
1066
+ */
1067
+ export async function availableBackends(
1068
+ facilitator = 'https://facilitator.ultravioletadao.xyz',
1069
+ opts: { fetch?: typeof fetch } = {},
1070
+ ): Promise<BackendOffer[]> {
1071
+ try {
1072
+ const doFetch = opts.fetch ?? fetch;
1073
+ const res = await doFetch(`${facilitator.replace(/\/+$/, '')}/dx402/stats`);
1074
+ if (!res.ok) return [];
1075
+ const body = (await res.json()) as { backends?: BackendOffer[] };
1076
+ return body.backends ?? [];
1077
+ } catch {
1078
+ return [];
1079
+ }
1080
+ }
1081
+
1023
1082
  /** Encode an anchor result for the `X-Durable-Evidence` response header. */
1024
1083
  export function evidenceHeader(evidence: unknown): string {
1025
1084
  // Encode to UTF-8 first. `btoa` takes a *binary* string: any code point above
package/src/index.ts CHANGED
@@ -144,6 +144,8 @@ export {
144
144
  sealEvidenceTo,
145
145
  payerKeyFromSolanaAddress,
146
146
  anchorEvidence,
147
+ availableBackends,
148
+ type BackendOffer,
147
149
  // Reachable only via a deep import before this: the helper that exists so
148
150
  // nobody hand-builds a digest was the one you had to already know about.
149
151
  sellerDigestFor,