@opendatalabs/vana-sdk 3.12.0 → 3.13.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.
package/README.md CHANGED
@@ -108,41 +108,33 @@ const result = await storage.upload(myBlob, "report.json");
108
108
  console.log(result.url);
109
109
  ```
110
110
 
111
- ### Scope Vana storage to a protocol network
111
+ ### Scope Vana storage by network
112
112
 
113
- `VanaStorage` has two independent axes. `endpoint` is the **product host**
114
- (e.g. `https://storage.vana.org` for production, `https://storage-dev.vana.org`
115
- for internal staging). `network` is the **protocol network** (`mainnet` or
116
- `moksha`) that scopes the blob path. They are not synonyms — `storage-dev` is a
117
- staging host, not a stand-in for Moksha.
113
+ Set `network` when writing to Vana Storage for a specific Vana network. The SDK
114
+ resolves the network to its chain ID and uploads through chain-scoped routes
115
+ (`/v1/chains/{chainId}/blobs/...`) so data for different chains never collides.
118
116
 
119
117
  ```typescript
120
118
  import { createVanaStorageProvider } from "@opendatalabs/vana-sdk/node";
121
119
 
122
120
  const storage = createVanaStorageProvider({
123
- endpoint: "https://storage.vana.org", // product host
124
- network: "moksha", // protocol namespace within that host
121
+ endpoint: "https://storage.vana.org",
122
+ network: "moksha",
125
123
  signer: {
126
124
  address: account.address,
127
125
  signMessage: (msg) => account.signMessage({ message: msg }),
128
126
  },
129
127
  });
130
128
 
131
- // Uploads to /v1/networks/moksha/blobs/{owner}/{scope}/{collectedAt}
132
129
  const result = await storage.upload(
133
130
  myBlob,
134
131
  "instagram.profile/2026-05-08T20:00:00.000Z",
135
132
  );
136
133
  ```
137
134
 
138
- When `network` is omitted, `VanaStorage` uses the legacy `/v1/blobs/...` routes,
139
- preserving backward compatibility. The Web3Signed audience is always the
140
- endpoint origin, never the network.
141
-
142
- A network-configured provider still accepts legacy same-endpoint
143
- `/v1/blobs/...` URLs so it can read or delete objects written before the opt-in,
144
- but it rejects URLs scoped to a _different_ explicit network — a Moksha provider
145
- won't act on a `mainnet`-scoped URL, and vice versa.
135
+ Network-configured providers reject legacy blob URLs and URLs scoped to a
136
+ different chain. If you need a custom or future protocol network that this SDK
137
+ does not know yet, pass `chainId` explicitly.
146
138
 
147
139
  ## Build a Vana app
148
140
 
@@ -25,6 +25,7 @@ __export(endpoints_exports, {
25
25
  getDirectNetworkChainId: () => getDirectNetworkChainId
26
26
  });
27
27
  module.exports = __toCommonJS(endpoints_exports);
28
+ var import_networks = require("../protocol/networks");
28
29
  const PRODUCTION_ENDPOINTS = {
29
30
  chainId: 1480,
30
31
  accessRequestBaseUrl: "https://app.vana.org",
@@ -47,7 +48,7 @@ function getDirectDefaultNetwork(env) {
47
48
  return env === "dev" ? "moksha" : "mainnet";
48
49
  }
49
50
  function getDirectNetworkChainId(network) {
50
- return network === "moksha" ? 14800 : 1480;
51
+ return (0, import_networks.getProtocolNetworkChainId)(network);
51
52
  }
52
53
  // Annotate the CommonJS export names for ESM import in node:
53
54
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/direct/endpoints.ts"],"sourcesContent":["/**\n * Per-environment service URLs for the Direct Data Controller.\n *\n * @remarks\n * The SDK ships production defaults; pass `env: \"dev\"` only when testing\n * against Vana's internal dev stack. Use the controller `network` option for\n * chain selection without changing deployment URLs.\n *\n * @category Direct\n * @module direct/endpoints\n */\n\nimport type { DirectEnv, DirectNetwork, DirectServiceEndpoints } from \"./types\";\n\n/** Production (mainnet) service URLs. */\nexport const PRODUCTION_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 1480,\n accessRequestBaseUrl: \"https://app.vana.org\",\n approvalAppBaseUrl: \"https://app.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc.vana.org\",\n} as const;\n\n/** Internal dev stack service URLs. */\nexport const DEV_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 14800,\n accessRequestBaseUrl: \"https://app-dev.vana.org\",\n approvalAppBaseUrl: \"https://app-dev.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc-dev.vana.org\",\n} as const;\n\n/**\n * Resolve the default {@link DirectServiceEndpoints} for an environment.\n *\n * @param env - Target environment.\n * @returns The default endpoints for that environment.\n */\nexport function getDirectEndpoints(env: DirectEnv): DirectServiceEndpoints {\n if (env === \"dev\") {\n return DEV_ENDPOINTS;\n }\n\n return PRODUCTION_ENDPOINTS;\n}\n\n/**\n * Resolve the default network for a deployment environment.\n *\n * @param env - Target deployment environment.\n * @returns The network historically paired with that deployment.\n */\nexport function getDirectDefaultNetwork(env: DirectEnv): DirectNetwork {\n return env === \"dev\" ? \"moksha\" : \"mainnet\";\n}\n\n/**\n * Resolve the Vana chain id for a network.\n *\n * @param network - Target Vana network.\n * @returns The network chain id.\n */\nexport function getDirectNetworkChainId(network: DirectNetwork): number {\n return network === \"moksha\" ? 14800 : 1480;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeO,MAAM,uBAA+C;AAAA,EAC1D,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAGO,MAAM,gBAAwC;AAAA,EACnD,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAQO,SAAS,mBAAmB,KAAwC;AACzE,MAAI,QAAQ,OAAO;AACjB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAQO,SAAS,wBAAwB,KAA+B;AACrE,SAAO,QAAQ,QAAQ,WAAW;AACpC;AAQO,SAAS,wBAAwB,SAAgC;AACtE,SAAO,YAAY,WAAW,QAAQ;AACxC;","names":[]}
1
+ {"version":3,"sources":["../../src/direct/endpoints.ts"],"sourcesContent":["/**\n * Per-environment service URLs for the Direct Data Controller.\n *\n * @remarks\n * The SDK ships production defaults; pass `env: \"dev\"` only when testing\n * against Vana's internal dev stack. Use the controller `network` option for\n * chain selection without changing deployment URLs.\n *\n * @category Direct\n * @module direct/endpoints\n */\n\nimport type { DirectEnv, DirectNetwork, DirectServiceEndpoints } from \"./types\";\nimport { getProtocolNetworkChainId } from \"../protocol/networks\";\n\n/** Production (mainnet) service URLs. */\nexport const PRODUCTION_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 1480,\n accessRequestBaseUrl: \"https://app.vana.org\",\n approvalAppBaseUrl: \"https://app.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc.vana.org\",\n} as const;\n\n/** Internal dev stack service URLs. */\nexport const DEV_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 14800,\n accessRequestBaseUrl: \"https://app-dev.vana.org\",\n approvalAppBaseUrl: \"https://app-dev.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc-dev.vana.org\",\n} as const;\n\n/**\n * Resolve the default {@link DirectServiceEndpoints} for an environment.\n *\n * @param env - Target environment.\n * @returns The default endpoints for that environment.\n */\nexport function getDirectEndpoints(env: DirectEnv): DirectServiceEndpoints {\n if (env === \"dev\") {\n return DEV_ENDPOINTS;\n }\n\n return PRODUCTION_ENDPOINTS;\n}\n\n/**\n * Resolve the default network for a deployment environment.\n *\n * @param env - Target deployment environment.\n * @returns The network historically paired with that deployment.\n */\nexport function getDirectDefaultNetwork(env: DirectEnv): DirectNetwork {\n return env === \"dev\" ? \"moksha\" : \"mainnet\";\n}\n\n/**\n * Resolve the Vana chain id for a network.\n *\n * @param network - Target Vana network.\n * @returns The network chain id.\n */\nexport function getDirectNetworkChainId(network: DirectNetwork): number {\n return getProtocolNetworkChainId(network);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,sBAA0C;AAGnC,MAAM,uBAA+C;AAAA,EAC1D,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAGO,MAAM,gBAAwC;AAAA,EACnD,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAQO,SAAS,mBAAmB,KAAwC;AACzE,MAAI,QAAQ,OAAO;AACjB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAQO,SAAS,wBAAwB,KAA+B;AACrE,SAAO,QAAQ,QAAQ,WAAW;AACpC;AAQO,SAAS,wBAAwB,SAAgC;AACtE,aAAO,2CAA0B,OAAO;AAC1C;","names":[]}
@@ -1,3 +1,4 @@
1
+ import { getProtocolNetworkChainId } from "../protocol/networks.js";
1
2
  const PRODUCTION_ENDPOINTS = {
2
3
  chainId: 1480,
3
4
  accessRequestBaseUrl: "https://app.vana.org",
@@ -20,7 +21,7 @@ function getDirectDefaultNetwork(env) {
20
21
  return env === "dev" ? "moksha" : "mainnet";
21
22
  }
22
23
  function getDirectNetworkChainId(network) {
23
- return network === "moksha" ? 14800 : 1480;
24
+ return getProtocolNetworkChainId(network);
24
25
  }
25
26
  export {
26
27
  DEV_ENDPOINTS,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/direct/endpoints.ts"],"sourcesContent":["/**\n * Per-environment service URLs for the Direct Data Controller.\n *\n * @remarks\n * The SDK ships production defaults; pass `env: \"dev\"` only when testing\n * against Vana's internal dev stack. Use the controller `network` option for\n * chain selection without changing deployment URLs.\n *\n * @category Direct\n * @module direct/endpoints\n */\n\nimport type { DirectEnv, DirectNetwork, DirectServiceEndpoints } from \"./types\";\n\n/** Production (mainnet) service URLs. */\nexport const PRODUCTION_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 1480,\n accessRequestBaseUrl: \"https://app.vana.org\",\n approvalAppBaseUrl: \"https://app.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc.vana.org\",\n} as const;\n\n/** Internal dev stack service URLs. */\nexport const DEV_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 14800,\n accessRequestBaseUrl: \"https://app-dev.vana.org\",\n approvalAppBaseUrl: \"https://app-dev.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc-dev.vana.org\",\n} as const;\n\n/**\n * Resolve the default {@link DirectServiceEndpoints} for an environment.\n *\n * @param env - Target environment.\n * @returns The default endpoints for that environment.\n */\nexport function getDirectEndpoints(env: DirectEnv): DirectServiceEndpoints {\n if (env === \"dev\") {\n return DEV_ENDPOINTS;\n }\n\n return PRODUCTION_ENDPOINTS;\n}\n\n/**\n * Resolve the default network for a deployment environment.\n *\n * @param env - Target deployment environment.\n * @returns The network historically paired with that deployment.\n */\nexport function getDirectDefaultNetwork(env: DirectEnv): DirectNetwork {\n return env === \"dev\" ? \"moksha\" : \"mainnet\";\n}\n\n/**\n * Resolve the Vana chain id for a network.\n *\n * @param network - Target Vana network.\n * @returns The network chain id.\n */\nexport function getDirectNetworkChainId(network: DirectNetwork): number {\n return network === \"moksha\" ? 14800 : 1480;\n}\n"],"mappings":"AAeO,MAAM,uBAA+C;AAAA,EAC1D,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAGO,MAAM,gBAAwC;AAAA,EACnD,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAQO,SAAS,mBAAmB,KAAwC;AACzE,MAAI,QAAQ,OAAO;AACjB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAQO,SAAS,wBAAwB,KAA+B;AACrE,SAAO,QAAQ,QAAQ,WAAW;AACpC;AAQO,SAAS,wBAAwB,SAAgC;AACtE,SAAO,YAAY,WAAW,QAAQ;AACxC;","names":[]}
1
+ {"version":3,"sources":["../../src/direct/endpoints.ts"],"sourcesContent":["/**\n * Per-environment service URLs for the Direct Data Controller.\n *\n * @remarks\n * The SDK ships production defaults; pass `env: \"dev\"` only when testing\n * against Vana's internal dev stack. Use the controller `network` option for\n * chain selection without changing deployment URLs.\n *\n * @category Direct\n * @module direct/endpoints\n */\n\nimport type { DirectEnv, DirectNetwork, DirectServiceEndpoints } from \"./types\";\nimport { getProtocolNetworkChainId } from \"../protocol/networks\";\n\n/** Production (mainnet) service URLs. */\nexport const PRODUCTION_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 1480,\n accessRequestBaseUrl: \"https://app.vana.org\",\n approvalAppBaseUrl: \"https://app.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc.vana.org\",\n} as const;\n\n/** Internal dev stack service URLs. */\nexport const DEV_ENDPOINTS: DirectServiceEndpoints = {\n chainId: 14800,\n accessRequestBaseUrl: \"https://app-dev.vana.org\",\n approvalAppBaseUrl: \"https://app-dev.vana.org\",\n escrowGatewayUrl: \"https://dp-rpc-dev.vana.org\",\n} as const;\n\n/**\n * Resolve the default {@link DirectServiceEndpoints} for an environment.\n *\n * @param env - Target environment.\n * @returns The default endpoints for that environment.\n */\nexport function getDirectEndpoints(env: DirectEnv): DirectServiceEndpoints {\n if (env === \"dev\") {\n return DEV_ENDPOINTS;\n }\n\n return PRODUCTION_ENDPOINTS;\n}\n\n/**\n * Resolve the default network for a deployment environment.\n *\n * @param env - Target deployment environment.\n * @returns The network historically paired with that deployment.\n */\nexport function getDirectDefaultNetwork(env: DirectEnv): DirectNetwork {\n return env === \"dev\" ? \"moksha\" : \"mainnet\";\n}\n\n/**\n * Resolve the Vana chain id for a network.\n *\n * @param network - Target Vana network.\n * @returns The network chain id.\n */\nexport function getDirectNetworkChainId(network: DirectNetwork): number {\n return getProtocolNetworkChainId(network);\n}\n"],"mappings":"AAaA,SAAS,iCAAiC;AAGnC,MAAM,uBAA+C;AAAA,EAC1D,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAGO,MAAM,gBAAwC;AAAA,EACnD,SAAS;AAAA,EACT,sBAAsB;AAAA,EACtB,oBAAoB;AAAA,EACpB,kBAAkB;AACpB;AAQO,SAAS,mBAAmB,KAAwC;AACzE,MAAI,QAAQ,OAAO;AACjB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAQO,SAAS,wBAAwB,KAA+B;AACrE,SAAO,QAAQ,QAAQ,WAAW;AACpC;AAQO,SAAS,wBAAwB,SAAgC;AACtE,SAAO,0BAA0B,OAAO;AAC1C;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/direct/types.ts"],"sourcesContent":["import type { EscrowAccessRecord } from \"../protocol/escrow\";\n\n/**\n * Shared types for the Direct Data Controller and the browser connect helper.\n *\n * @remarks\n * These types describe the \"two-tab\" Data Portability flow documented in the\n * builder guide: a backend controller creates an access request, the browser\n * opens Vana for user approval, and the backend reads the approved data from\n * the user's Personal Server (handling 402 Payment Required).\n *\n * @category Direct\n * @module direct/types\n */\n\n/**\n * Target environment for a {@link DirectDataController}.\n *\n * - `\"production\"` — Vana mainnet stack (default service URLs).\n * - `\"dev\"` — Vana internal dev stack. Use only when testing against\n * Vana's dev infrastructure.\n */\nexport type DirectEnv = \"dev\" | \"production\";\n\n/**\n * Vana network used for chain-aware Direct defaults.\n *\n * - `\"mainnet\"` — Vana mainnet (`chainId` 1480).\n * - `\"moksha\"` — Moksha testnet (`chainId` 14800).\n */\nexport type DirectNetwork = \"mainnet\" | \"moksha\";\n\n/**\n * App identity advertised to users during approval and attributed in Builder\n * League activity reports.\n */\nexport interface DirectAppConfig {\n /** Stable, human-readable app id (e.g. `\"notes-lens\"`). */\n id: string;\n /** Display name shown to the user in the Vana approval UI. */\n name: string;\n /** Public homepage URL for the app. */\n homepageUrl: string;\n}\n\n/**\n * Resolved app identity: the configured {@link DirectAppConfig} plus the app's\n * derived on-chain address (the address to fund and inspect).\n */\nexport interface AppIdentity extends DirectAppConfig {\n /** The app's `0x`-prefixed on-chain address (derived from `appPrivateKey`). */\n address: string;\n}\n\n/**\n * Resolved service URLs and chain id for a given {@link DirectEnv}.\n *\n * @remarks\n * Centralizes the per-environment base URLs the controller talks to. Each can\n * be overridden via {@link DirectDataControllerConfig.endpoints} when pointing\n * at a non-standard deployment.\n */\nexport interface DirectServiceEndpoints {\n /** Vana chain id for this environment (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** Base URL of the Vana Account access-request API that issues `dcr_*` ids. */\n accessRequestBaseUrl: string;\n /** Base URL users are sent to for approval (the Vana app). */\n approvalAppBaseUrl: string;\n /** Base URL of the DP RPC escrow gateway used to settle `402 Payment Required`. */\n escrowGatewayUrl: string;\n}\n\n/** Result of {@link DirectDataController.createAccessRequest}. */\nexport interface AccessRequest {\n /** Opaque request id (e.g. `\"dcr_123\"`). */\n requestId: string;\n /** URL the browser opens so the user can approve the requested scopes. */\n approvalUrl: string;\n /** On-chain address of the (registered or reused) app. */\n appAddress: string;\n}\n\n/** Lifecycle status of an access request. */\nexport type AccessRequestStatusValue =\n | \"pending\"\n | \"approved\"\n | \"ready_for_read\"\n | \"denied\"\n | \"expired\";\n\n/** Result of {@link DirectDataController.getAccessRequestStatus}. */\nexport interface AccessRequestStatus {\n /** Current lifecycle status of the request. */\n status: AccessRequestStatusValue;\n /** Personal Server base URL — present once data is ready to read. */\n personalServerUrl?: string;\n /** Grant id covering the approved scope — present once data is ready to read. */\n grantId?: string;\n /** The approved scope — present once data is ready to read. */\n scope?: string;\n}\n\n/** Result of {@link DirectDataController.readApprovedData}. */\nexport interface ApprovedDataResult<T = unknown> {\n /** The scope the data was read for. */\n scope: string;\n /** The decoded payload returned by the Personal Server. */\n data: T;\n /**\n * Payment receipt — present only when this read required (and settled) a\n * payment. Lets builders inspect the amount, asset, and fee breakdown without\n * digging into the underlying 402/escrow exchange. Reads served from a paid-up\n * grant omit this field.\n */\n payment?: DirectPaymentReceipt;\n}\n\n/**\n * Client for the Vana Account access-request API — the service that turns a\n * registered app + scopes into a `dcr_*` id and approval URL.\n *\n * @remarks\n * The controller uses a default client against the Vana Account endpoints. You\n * can inject your own implementation to point at a custom deployment or to\n * supply a test double.\n */\nexport interface AccessRequestClient {\n /**\n * Create an access request for the given app + scopes.\n *\n * @param input - App identity, source, scopes, network, and the post-approval return URL.\n * @returns The created {@link AccessRequest}.\n */\n createAccessRequest(input: {\n appAddress: string;\n app: DirectAppConfig;\n source: string;\n scopes: string[];\n returnUrl: string;\n /** Vana protocol network for this request (`\"mainnet\"` or `\"moksha\"`). */\n network: DirectNetwork;\n }): Promise<AccessRequest>;\n\n /**\n * Fetch the current status of a previously created access request.\n *\n * @param requestId - The `dcr_*` id returned by {@link AccessRequestClient.createAccessRequest}.\n * @returns The current {@link AccessRequestStatus}.\n */\n getAccessRequestStatus(requestId: string): Promise<AccessRequestStatus>;\n\n /**\n * Acknowledge that the app successfully read the approved data.\n *\n * @remarks\n * Direct Vana Web DCRs remain in `ready_for_read` while the browser Personal\n * Server is serving the app. After a successful Personal Server read, the\n * controller calls this hook so Vana Web can mark the request completed and\n * close/redirect the approval tab.\n *\n * Optional so injected clients from older SDK integrations keep compiling;\n * the default HTTP client implements it.\n */\n acknowledgeRead?(requestId: string): Promise<void>;\n}\n\n/**\n * Op-type vocabulary used by the DPv2 escrow payment surface.\n *\n * @remarks\n * These are the operations the gateway prices and settles via\n * `POST /v1/escrow/pay` (`opType` field of the `GenericPayment` message). A\n * direct data read settles the {@link DirectOpType.DataAccess} op for the\n * approved grant; the other op types are listed here for completeness and to\n * give builders a typed vocabulary when inspecting fee breakdowns.\n *\n * Note: the escrow `GenericPayment` `opType` is currently `\"grant\"` on the wire\n * for grant lifecycle payments; this enum names the higher-level fee categories\n * the gateway reports in a {@link PaymentBreakdown}.\n */\nexport const DirectOpType = {\n GrantRegistration: \"grant_registration\",\n DataAccess: \"data_access\",\n DataRegistration: \"data_registration\",\n ServerRegistration: \"server_registration\",\n BuilderRegistration: \"builder_registration\",\n} as const;\n\n/** A direct-flow op type (see {@link DirectOpType}). */\nexport type DirectOpTypeValue =\n (typeof DirectOpType)[keyof typeof DirectOpType];\n\n/**\n * What a Personal Server `402 Payment Required` tells the controller is owed for\n * a data read.\n *\n * @remarks\n * The PS read 402 body identifies the grant to settle and the amount/asset. The\n * controller settles it via the DPv2 escrow gateway (`/v1/escrow/pay`). The full\n * unmodified body is preserved under {@link PersonalServerPaymentRequired.raw}.\n */\nexport interface PersonalServerPaymentRequired {\n /** Grant id to settle (the escrow `opId`). Defaults to the read's grantId. */\n grantId: string;\n /** X402 network advertised by the Personal Server challenge. */\n network?: string;\n /** Payment nonce requested by the 402 challenge. */\n paymentNonce?: string;\n /** Server-signed data access receipt requested by the 402 challenge. */\n accessRecord?: EscrowAccessRecord;\n /** Asset address owed (zero address = native VANA). */\n asset: string;\n /** Amount owed, as a decimal base-unit string (preserves uint256 precision). */\n amount: string;\n /** The full, unmodified 402 response body. */\n raw: unknown;\n}\n\n/**\n * Structured payment metadata attached to a successful paid read.\n *\n * @remarks\n * Derived from the gateway's {@link EscrowPayResult}. Lets builders debug the\n * amount, asset, and per-op fee breakdown without re-deriving anything from the\n * raw 402/payment exchange.\n */\nexport interface DirectPaymentReceipt {\n /** Op type settled (the gateway `opType`, e.g. `\"grant\"`). */\n opType: string;\n /** Op id settled (the grant id). */\n opId: string;\n /** Asset paid in (zero address = native VANA). */\n asset: string;\n /** Total amount paid, as a decimal base-unit string. */\n amount: string;\n /** Payment nonce used for this settlement. */\n paymentNonce: string;\n /** Fee breakdown reported by the gateway (registration vs data-access fee). */\n breakdown: DirectFeeBreakdown;\n /** ISO timestamp the gateway recorded the payment. */\n paidAt: string;\n}\n\n/**\n * Per-op fee breakdown reported by the gateway.\n *\n * @remarks\n * Mirrors the escrow {@link PaymentBreakdown}: a one-time registration fee plus\n * the per-read data-access fee, and whether this settlement covered the\n * registration fee.\n */\nexport interface DirectFeeBreakdown {\n /** One-time registration fee for the op, as a decimal base-unit string. */\n registrationFee: string;\n /** Per-read data-access fee, as a decimal base-unit string. */\n dataAccessFee: string;\n /** True when this settlement paid the registration fee. */\n registrationPaid: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqLO,MAAM,eAAe;AAAA,EAC1B,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;","names":[]}
1
+ {"version":3,"sources":["../../src/direct/types.ts"],"sourcesContent":["import type { EscrowAccessRecord } from \"../protocol/escrow\";\nimport type { ProtocolNetwork } from \"../protocol/networks\";\n\n/**\n * Shared types for the Direct Data Controller and the browser connect helper.\n *\n * @remarks\n * These types describe the \"two-tab\" Data Portability flow documented in the\n * builder guide: a backend controller creates an access request, the browser\n * opens Vana for user approval, and the backend reads the approved data from\n * the user's Personal Server (handling 402 Payment Required).\n *\n * @category Direct\n * @module direct/types\n */\n\n/**\n * Target environment for a {@link DirectDataController}.\n *\n * - `\"production\"` — Vana mainnet stack (default service URLs).\n * - `\"dev\"` — Vana internal dev stack. Use only when testing against\n * Vana's dev infrastructure.\n */\nexport type DirectEnv = \"dev\" | \"production\";\n\n/**\n * Vana network used for chain-aware Direct defaults.\n *\n * - `\"mainnet\"` — Vana mainnet (`chainId` 1480).\n * - `\"moksha\"` — Moksha testnet (`chainId` 14800).\n */\nexport type DirectNetwork = ProtocolNetwork;\n\n/**\n * App identity advertised to users during approval and attributed in Builder\n * League activity reports.\n */\nexport interface DirectAppConfig {\n /** Stable, human-readable app id (e.g. `\"notes-lens\"`). */\n id: string;\n /** Display name shown to the user in the Vana approval UI. */\n name: string;\n /** Public homepage URL for the app. */\n homepageUrl: string;\n}\n\n/**\n * Resolved app identity: the configured {@link DirectAppConfig} plus the app's\n * derived on-chain address (the address to fund and inspect).\n */\nexport interface AppIdentity extends DirectAppConfig {\n /** The app's `0x`-prefixed on-chain address (derived from `appPrivateKey`). */\n address: string;\n}\n\n/**\n * Resolved service URLs and chain id for a given {@link DirectEnv}.\n *\n * @remarks\n * Centralizes the per-environment base URLs the controller talks to. Each can\n * be overridden via {@link DirectDataControllerConfig.endpoints} when pointing\n * at a non-standard deployment.\n */\nexport interface DirectServiceEndpoints {\n /** Vana chain id for this environment (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** Base URL of the Vana Account access-request API that issues `dcr_*` ids. */\n accessRequestBaseUrl: string;\n /** Base URL users are sent to for approval (the Vana app). */\n approvalAppBaseUrl: string;\n /** Base URL of the DP RPC escrow gateway used to settle `402 Payment Required`. */\n escrowGatewayUrl: string;\n}\n\n/** Result of {@link DirectDataController.createAccessRequest}. */\nexport interface AccessRequest {\n /** Opaque request id (e.g. `\"dcr_123\"`). */\n requestId: string;\n /** URL the browser opens so the user can approve the requested scopes. */\n approvalUrl: string;\n /** On-chain address of the (registered or reused) app. */\n appAddress: string;\n}\n\n/** Lifecycle status of an access request. */\nexport type AccessRequestStatusValue =\n | \"pending\"\n | \"approved\"\n | \"ready_for_read\"\n | \"denied\"\n | \"expired\";\n\n/** Result of {@link DirectDataController.getAccessRequestStatus}. */\nexport interface AccessRequestStatus {\n /** Current lifecycle status of the request. */\n status: AccessRequestStatusValue;\n /** Personal Server base URL — present once data is ready to read. */\n personalServerUrl?: string;\n /** Grant id covering the approved scope — present once data is ready to read. */\n grantId?: string;\n /** The approved scope — present once data is ready to read. */\n scope?: string;\n}\n\n/** Result of {@link DirectDataController.readApprovedData}. */\nexport interface ApprovedDataResult<T = unknown> {\n /** The scope the data was read for. */\n scope: string;\n /** The decoded payload returned by the Personal Server. */\n data: T;\n /**\n * Payment receipt — present only when this read required (and settled) a\n * payment. Lets builders inspect the amount, asset, and fee breakdown without\n * digging into the underlying 402/escrow exchange. Reads served from a paid-up\n * grant omit this field.\n */\n payment?: DirectPaymentReceipt;\n}\n\n/**\n * Client for the Vana Account access-request API — the service that turns a\n * registered app + scopes into a `dcr_*` id and approval URL.\n *\n * @remarks\n * The controller uses a default client against the Vana Account endpoints. You\n * can inject your own implementation to point at a custom deployment or to\n * supply a test double.\n */\nexport interface AccessRequestClient {\n /**\n * Create an access request for the given app + scopes.\n *\n * @param input - App identity, source, scopes, network, and the post-approval return URL.\n * @returns The created {@link AccessRequest}.\n */\n createAccessRequest(input: {\n appAddress: string;\n app: DirectAppConfig;\n source: string;\n scopes: string[];\n returnUrl: string;\n /** Vana protocol network for this request (`\"mainnet\"` or `\"moksha\"`). */\n network: DirectNetwork;\n }): Promise<AccessRequest>;\n\n /**\n * Fetch the current status of a previously created access request.\n *\n * @param requestId - The `dcr_*` id returned by {@link AccessRequestClient.createAccessRequest}.\n * @returns The current {@link AccessRequestStatus}.\n */\n getAccessRequestStatus(requestId: string): Promise<AccessRequestStatus>;\n\n /**\n * Acknowledge that the app successfully read the approved data.\n *\n * @remarks\n * Direct Vana Web DCRs remain in `ready_for_read` while the browser Personal\n * Server is serving the app. After a successful Personal Server read, the\n * controller calls this hook so Vana Web can mark the request completed and\n * close/redirect the approval tab.\n *\n * Optional so injected clients from older SDK integrations keep compiling;\n * the default HTTP client implements it.\n */\n acknowledgeRead?(requestId: string): Promise<void>;\n}\n\n/**\n * Op-type vocabulary used by the DPv2 escrow payment surface.\n *\n * @remarks\n * These are the operations the gateway prices and settles via\n * `POST /v1/escrow/pay` (`opType` field of the `GenericPayment` message). A\n * direct data read settles the {@link DirectOpType.DataAccess} op for the\n * approved grant; the other op types are listed here for completeness and to\n * give builders a typed vocabulary when inspecting fee breakdowns.\n *\n * Note: the escrow `GenericPayment` `opType` is currently `\"grant\"` on the wire\n * for grant lifecycle payments; this enum names the higher-level fee categories\n * the gateway reports in a {@link PaymentBreakdown}.\n */\nexport const DirectOpType = {\n GrantRegistration: \"grant_registration\",\n DataAccess: \"data_access\",\n DataRegistration: \"data_registration\",\n ServerRegistration: \"server_registration\",\n BuilderRegistration: \"builder_registration\",\n} as const;\n\n/** A direct-flow op type (see {@link DirectOpType}). */\nexport type DirectOpTypeValue =\n (typeof DirectOpType)[keyof typeof DirectOpType];\n\n/**\n * What a Personal Server `402 Payment Required` tells the controller is owed for\n * a data read.\n *\n * @remarks\n * The PS read 402 body identifies the grant to settle and the amount/asset. The\n * controller settles it via the DPv2 escrow gateway (`/v1/escrow/pay`). The full\n * unmodified body is preserved under {@link PersonalServerPaymentRequired.raw}.\n */\nexport interface PersonalServerPaymentRequired {\n /** Grant id to settle (the escrow `opId`). Defaults to the read's grantId. */\n grantId: string;\n /** X402 network advertised by the Personal Server challenge. */\n network?: string;\n /** Payment nonce requested by the 402 challenge. */\n paymentNonce?: string;\n /** Server-signed data access receipt requested by the 402 challenge. */\n accessRecord?: EscrowAccessRecord;\n /** Asset address owed (zero address = native VANA). */\n asset: string;\n /** Amount owed, as a decimal base-unit string (preserves uint256 precision). */\n amount: string;\n /** The full, unmodified 402 response body. */\n raw: unknown;\n}\n\n/**\n * Structured payment metadata attached to a successful paid read.\n *\n * @remarks\n * Derived from the gateway's {@link EscrowPayResult}. Lets builders debug the\n * amount, asset, and per-op fee breakdown without re-deriving anything from the\n * raw 402/payment exchange.\n */\nexport interface DirectPaymentReceipt {\n /** Op type settled (the gateway `opType`, e.g. `\"grant\"`). */\n opType: string;\n /** Op id settled (the grant id). */\n opId: string;\n /** Asset paid in (zero address = native VANA). */\n asset: string;\n /** Total amount paid, as a decimal base-unit string. */\n amount: string;\n /** Payment nonce used for this settlement. */\n paymentNonce: string;\n /** Fee breakdown reported by the gateway (registration vs data-access fee). */\n breakdown: DirectFeeBreakdown;\n /** ISO timestamp the gateway recorded the payment. */\n paidAt: string;\n}\n\n/**\n * Per-op fee breakdown reported by the gateway.\n *\n * @remarks\n * Mirrors the escrow {@link PaymentBreakdown}: a one-time registration fee plus\n * the per-read data-access fee, and whether this settlement covered the\n * registration fee.\n */\nexport interface DirectFeeBreakdown {\n /** One-time registration fee for the op, as a decimal base-unit string. */\n registrationFee: string;\n /** Per-read data-access fee, as a decimal base-unit string. */\n dataAccessFee: string;\n /** True when this settlement paid the registration fee. */\n registrationPaid: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsLO,MAAM,eAAe;AAAA,EAC1B,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;","names":[]}
@@ -1,4 +1,5 @@
1
1
  import type { EscrowAccessRecord } from "../protocol/escrow";
2
+ import type { ProtocolNetwork } from "../protocol/networks";
2
3
  /**
3
4
  * Shared types for the Direct Data Controller and the browser connect helper.
4
5
  *
@@ -25,7 +26,7 @@ export type DirectEnv = "dev" | "production";
25
26
  * - `"mainnet"` — Vana mainnet (`chainId` 1480).
26
27
  * - `"moksha"` — Moksha testnet (`chainId` 14800).
27
28
  */
28
- export type DirectNetwork = "mainnet" | "moksha";
29
+ export type DirectNetwork = ProtocolNetwork;
29
30
  /**
30
31
  * App identity advertised to users during approval and attributed in Builder
31
32
  * League activity reports.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/direct/types.ts"],"sourcesContent":["import type { EscrowAccessRecord } from \"../protocol/escrow\";\n\n/**\n * Shared types for the Direct Data Controller and the browser connect helper.\n *\n * @remarks\n * These types describe the \"two-tab\" Data Portability flow documented in the\n * builder guide: a backend controller creates an access request, the browser\n * opens Vana for user approval, and the backend reads the approved data from\n * the user's Personal Server (handling 402 Payment Required).\n *\n * @category Direct\n * @module direct/types\n */\n\n/**\n * Target environment for a {@link DirectDataController}.\n *\n * - `\"production\"` — Vana mainnet stack (default service URLs).\n * - `\"dev\"` — Vana internal dev stack. Use only when testing against\n * Vana's dev infrastructure.\n */\nexport type DirectEnv = \"dev\" | \"production\";\n\n/**\n * Vana network used for chain-aware Direct defaults.\n *\n * - `\"mainnet\"` — Vana mainnet (`chainId` 1480).\n * - `\"moksha\"` — Moksha testnet (`chainId` 14800).\n */\nexport type DirectNetwork = \"mainnet\" | \"moksha\";\n\n/**\n * App identity advertised to users during approval and attributed in Builder\n * League activity reports.\n */\nexport interface DirectAppConfig {\n /** Stable, human-readable app id (e.g. `\"notes-lens\"`). */\n id: string;\n /** Display name shown to the user in the Vana approval UI. */\n name: string;\n /** Public homepage URL for the app. */\n homepageUrl: string;\n}\n\n/**\n * Resolved app identity: the configured {@link DirectAppConfig} plus the app's\n * derived on-chain address (the address to fund and inspect).\n */\nexport interface AppIdentity extends DirectAppConfig {\n /** The app's `0x`-prefixed on-chain address (derived from `appPrivateKey`). */\n address: string;\n}\n\n/**\n * Resolved service URLs and chain id for a given {@link DirectEnv}.\n *\n * @remarks\n * Centralizes the per-environment base URLs the controller talks to. Each can\n * be overridden via {@link DirectDataControllerConfig.endpoints} when pointing\n * at a non-standard deployment.\n */\nexport interface DirectServiceEndpoints {\n /** Vana chain id for this environment (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** Base URL of the Vana Account access-request API that issues `dcr_*` ids. */\n accessRequestBaseUrl: string;\n /** Base URL users are sent to for approval (the Vana app). */\n approvalAppBaseUrl: string;\n /** Base URL of the DP RPC escrow gateway used to settle `402 Payment Required`. */\n escrowGatewayUrl: string;\n}\n\n/** Result of {@link DirectDataController.createAccessRequest}. */\nexport interface AccessRequest {\n /** Opaque request id (e.g. `\"dcr_123\"`). */\n requestId: string;\n /** URL the browser opens so the user can approve the requested scopes. */\n approvalUrl: string;\n /** On-chain address of the (registered or reused) app. */\n appAddress: string;\n}\n\n/** Lifecycle status of an access request. */\nexport type AccessRequestStatusValue =\n | \"pending\"\n | \"approved\"\n | \"ready_for_read\"\n | \"denied\"\n | \"expired\";\n\n/** Result of {@link DirectDataController.getAccessRequestStatus}. */\nexport interface AccessRequestStatus {\n /** Current lifecycle status of the request. */\n status: AccessRequestStatusValue;\n /** Personal Server base URL — present once data is ready to read. */\n personalServerUrl?: string;\n /** Grant id covering the approved scope — present once data is ready to read. */\n grantId?: string;\n /** The approved scope — present once data is ready to read. */\n scope?: string;\n}\n\n/** Result of {@link DirectDataController.readApprovedData}. */\nexport interface ApprovedDataResult<T = unknown> {\n /** The scope the data was read for. */\n scope: string;\n /** The decoded payload returned by the Personal Server. */\n data: T;\n /**\n * Payment receipt — present only when this read required (and settled) a\n * payment. Lets builders inspect the amount, asset, and fee breakdown without\n * digging into the underlying 402/escrow exchange. Reads served from a paid-up\n * grant omit this field.\n */\n payment?: DirectPaymentReceipt;\n}\n\n/**\n * Client for the Vana Account access-request API — the service that turns a\n * registered app + scopes into a `dcr_*` id and approval URL.\n *\n * @remarks\n * The controller uses a default client against the Vana Account endpoints. You\n * can inject your own implementation to point at a custom deployment or to\n * supply a test double.\n */\nexport interface AccessRequestClient {\n /**\n * Create an access request for the given app + scopes.\n *\n * @param input - App identity, source, scopes, network, and the post-approval return URL.\n * @returns The created {@link AccessRequest}.\n */\n createAccessRequest(input: {\n appAddress: string;\n app: DirectAppConfig;\n source: string;\n scopes: string[];\n returnUrl: string;\n /** Vana protocol network for this request (`\"mainnet\"` or `\"moksha\"`). */\n network: DirectNetwork;\n }): Promise<AccessRequest>;\n\n /**\n * Fetch the current status of a previously created access request.\n *\n * @param requestId - The `dcr_*` id returned by {@link AccessRequestClient.createAccessRequest}.\n * @returns The current {@link AccessRequestStatus}.\n */\n getAccessRequestStatus(requestId: string): Promise<AccessRequestStatus>;\n\n /**\n * Acknowledge that the app successfully read the approved data.\n *\n * @remarks\n * Direct Vana Web DCRs remain in `ready_for_read` while the browser Personal\n * Server is serving the app. After a successful Personal Server read, the\n * controller calls this hook so Vana Web can mark the request completed and\n * close/redirect the approval tab.\n *\n * Optional so injected clients from older SDK integrations keep compiling;\n * the default HTTP client implements it.\n */\n acknowledgeRead?(requestId: string): Promise<void>;\n}\n\n/**\n * Op-type vocabulary used by the DPv2 escrow payment surface.\n *\n * @remarks\n * These are the operations the gateway prices and settles via\n * `POST /v1/escrow/pay` (`opType` field of the `GenericPayment` message). A\n * direct data read settles the {@link DirectOpType.DataAccess} op for the\n * approved grant; the other op types are listed here for completeness and to\n * give builders a typed vocabulary when inspecting fee breakdowns.\n *\n * Note: the escrow `GenericPayment` `opType` is currently `\"grant\"` on the wire\n * for grant lifecycle payments; this enum names the higher-level fee categories\n * the gateway reports in a {@link PaymentBreakdown}.\n */\nexport const DirectOpType = {\n GrantRegistration: \"grant_registration\",\n DataAccess: \"data_access\",\n DataRegistration: \"data_registration\",\n ServerRegistration: \"server_registration\",\n BuilderRegistration: \"builder_registration\",\n} as const;\n\n/** A direct-flow op type (see {@link DirectOpType}). */\nexport type DirectOpTypeValue =\n (typeof DirectOpType)[keyof typeof DirectOpType];\n\n/**\n * What a Personal Server `402 Payment Required` tells the controller is owed for\n * a data read.\n *\n * @remarks\n * The PS read 402 body identifies the grant to settle and the amount/asset. The\n * controller settles it via the DPv2 escrow gateway (`/v1/escrow/pay`). The full\n * unmodified body is preserved under {@link PersonalServerPaymentRequired.raw}.\n */\nexport interface PersonalServerPaymentRequired {\n /** Grant id to settle (the escrow `opId`). Defaults to the read's grantId. */\n grantId: string;\n /** X402 network advertised by the Personal Server challenge. */\n network?: string;\n /** Payment nonce requested by the 402 challenge. */\n paymentNonce?: string;\n /** Server-signed data access receipt requested by the 402 challenge. */\n accessRecord?: EscrowAccessRecord;\n /** Asset address owed (zero address = native VANA). */\n asset: string;\n /** Amount owed, as a decimal base-unit string (preserves uint256 precision). */\n amount: string;\n /** The full, unmodified 402 response body. */\n raw: unknown;\n}\n\n/**\n * Structured payment metadata attached to a successful paid read.\n *\n * @remarks\n * Derived from the gateway's {@link EscrowPayResult}. Lets builders debug the\n * amount, asset, and per-op fee breakdown without re-deriving anything from the\n * raw 402/payment exchange.\n */\nexport interface DirectPaymentReceipt {\n /** Op type settled (the gateway `opType`, e.g. `\"grant\"`). */\n opType: string;\n /** Op id settled (the grant id). */\n opId: string;\n /** Asset paid in (zero address = native VANA). */\n asset: string;\n /** Total amount paid, as a decimal base-unit string. */\n amount: string;\n /** Payment nonce used for this settlement. */\n paymentNonce: string;\n /** Fee breakdown reported by the gateway (registration vs data-access fee). */\n breakdown: DirectFeeBreakdown;\n /** ISO timestamp the gateway recorded the payment. */\n paidAt: string;\n}\n\n/**\n * Per-op fee breakdown reported by the gateway.\n *\n * @remarks\n * Mirrors the escrow {@link PaymentBreakdown}: a one-time registration fee plus\n * the per-read data-access fee, and whether this settlement covered the\n * registration fee.\n */\nexport interface DirectFeeBreakdown {\n /** One-time registration fee for the op, as a decimal base-unit string. */\n registrationFee: string;\n /** Per-read data-access fee, as a decimal base-unit string. */\n dataAccessFee: string;\n /** True when this settlement paid the registration fee. */\n registrationPaid: boolean;\n}\n"],"mappings":"AAqLO,MAAM,eAAe;AAAA,EAC1B,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;","names":[]}
1
+ {"version":3,"sources":["../../src/direct/types.ts"],"sourcesContent":["import type { EscrowAccessRecord } from \"../protocol/escrow\";\nimport type { ProtocolNetwork } from \"../protocol/networks\";\n\n/**\n * Shared types for the Direct Data Controller and the browser connect helper.\n *\n * @remarks\n * These types describe the \"two-tab\" Data Portability flow documented in the\n * builder guide: a backend controller creates an access request, the browser\n * opens Vana for user approval, and the backend reads the approved data from\n * the user's Personal Server (handling 402 Payment Required).\n *\n * @category Direct\n * @module direct/types\n */\n\n/**\n * Target environment for a {@link DirectDataController}.\n *\n * - `\"production\"` — Vana mainnet stack (default service URLs).\n * - `\"dev\"` — Vana internal dev stack. Use only when testing against\n * Vana's dev infrastructure.\n */\nexport type DirectEnv = \"dev\" | \"production\";\n\n/**\n * Vana network used for chain-aware Direct defaults.\n *\n * - `\"mainnet\"` — Vana mainnet (`chainId` 1480).\n * - `\"moksha\"` — Moksha testnet (`chainId` 14800).\n */\nexport type DirectNetwork = ProtocolNetwork;\n\n/**\n * App identity advertised to users during approval and attributed in Builder\n * League activity reports.\n */\nexport interface DirectAppConfig {\n /** Stable, human-readable app id (e.g. `\"notes-lens\"`). */\n id: string;\n /** Display name shown to the user in the Vana approval UI. */\n name: string;\n /** Public homepage URL for the app. */\n homepageUrl: string;\n}\n\n/**\n * Resolved app identity: the configured {@link DirectAppConfig} plus the app's\n * derived on-chain address (the address to fund and inspect).\n */\nexport interface AppIdentity extends DirectAppConfig {\n /** The app's `0x`-prefixed on-chain address (derived from `appPrivateKey`). */\n address: string;\n}\n\n/**\n * Resolved service URLs and chain id for a given {@link DirectEnv}.\n *\n * @remarks\n * Centralizes the per-environment base URLs the controller talks to. Each can\n * be overridden via {@link DirectDataControllerConfig.endpoints} when pointing\n * at a non-standard deployment.\n */\nexport interface DirectServiceEndpoints {\n /** Vana chain id for this environment (1480 mainnet, 14800 moksha). */\n chainId: number;\n /** Base URL of the Vana Account access-request API that issues `dcr_*` ids. */\n accessRequestBaseUrl: string;\n /** Base URL users are sent to for approval (the Vana app). */\n approvalAppBaseUrl: string;\n /** Base URL of the DP RPC escrow gateway used to settle `402 Payment Required`. */\n escrowGatewayUrl: string;\n}\n\n/** Result of {@link DirectDataController.createAccessRequest}. */\nexport interface AccessRequest {\n /** Opaque request id (e.g. `\"dcr_123\"`). */\n requestId: string;\n /** URL the browser opens so the user can approve the requested scopes. */\n approvalUrl: string;\n /** On-chain address of the (registered or reused) app. */\n appAddress: string;\n}\n\n/** Lifecycle status of an access request. */\nexport type AccessRequestStatusValue =\n | \"pending\"\n | \"approved\"\n | \"ready_for_read\"\n | \"denied\"\n | \"expired\";\n\n/** Result of {@link DirectDataController.getAccessRequestStatus}. */\nexport interface AccessRequestStatus {\n /** Current lifecycle status of the request. */\n status: AccessRequestStatusValue;\n /** Personal Server base URL — present once data is ready to read. */\n personalServerUrl?: string;\n /** Grant id covering the approved scope — present once data is ready to read. */\n grantId?: string;\n /** The approved scope — present once data is ready to read. */\n scope?: string;\n}\n\n/** Result of {@link DirectDataController.readApprovedData}. */\nexport interface ApprovedDataResult<T = unknown> {\n /** The scope the data was read for. */\n scope: string;\n /** The decoded payload returned by the Personal Server. */\n data: T;\n /**\n * Payment receipt — present only when this read required (and settled) a\n * payment. Lets builders inspect the amount, asset, and fee breakdown without\n * digging into the underlying 402/escrow exchange. Reads served from a paid-up\n * grant omit this field.\n */\n payment?: DirectPaymentReceipt;\n}\n\n/**\n * Client for the Vana Account access-request API — the service that turns a\n * registered app + scopes into a `dcr_*` id and approval URL.\n *\n * @remarks\n * The controller uses a default client against the Vana Account endpoints. You\n * can inject your own implementation to point at a custom deployment or to\n * supply a test double.\n */\nexport interface AccessRequestClient {\n /**\n * Create an access request for the given app + scopes.\n *\n * @param input - App identity, source, scopes, network, and the post-approval return URL.\n * @returns The created {@link AccessRequest}.\n */\n createAccessRequest(input: {\n appAddress: string;\n app: DirectAppConfig;\n source: string;\n scopes: string[];\n returnUrl: string;\n /** Vana protocol network for this request (`\"mainnet\"` or `\"moksha\"`). */\n network: DirectNetwork;\n }): Promise<AccessRequest>;\n\n /**\n * Fetch the current status of a previously created access request.\n *\n * @param requestId - The `dcr_*` id returned by {@link AccessRequestClient.createAccessRequest}.\n * @returns The current {@link AccessRequestStatus}.\n */\n getAccessRequestStatus(requestId: string): Promise<AccessRequestStatus>;\n\n /**\n * Acknowledge that the app successfully read the approved data.\n *\n * @remarks\n * Direct Vana Web DCRs remain in `ready_for_read` while the browser Personal\n * Server is serving the app. After a successful Personal Server read, the\n * controller calls this hook so Vana Web can mark the request completed and\n * close/redirect the approval tab.\n *\n * Optional so injected clients from older SDK integrations keep compiling;\n * the default HTTP client implements it.\n */\n acknowledgeRead?(requestId: string): Promise<void>;\n}\n\n/**\n * Op-type vocabulary used by the DPv2 escrow payment surface.\n *\n * @remarks\n * These are the operations the gateway prices and settles via\n * `POST /v1/escrow/pay` (`opType` field of the `GenericPayment` message). A\n * direct data read settles the {@link DirectOpType.DataAccess} op for the\n * approved grant; the other op types are listed here for completeness and to\n * give builders a typed vocabulary when inspecting fee breakdowns.\n *\n * Note: the escrow `GenericPayment` `opType` is currently `\"grant\"` on the wire\n * for grant lifecycle payments; this enum names the higher-level fee categories\n * the gateway reports in a {@link PaymentBreakdown}.\n */\nexport const DirectOpType = {\n GrantRegistration: \"grant_registration\",\n DataAccess: \"data_access\",\n DataRegistration: \"data_registration\",\n ServerRegistration: \"server_registration\",\n BuilderRegistration: \"builder_registration\",\n} as const;\n\n/** A direct-flow op type (see {@link DirectOpType}). */\nexport type DirectOpTypeValue =\n (typeof DirectOpType)[keyof typeof DirectOpType];\n\n/**\n * What a Personal Server `402 Payment Required` tells the controller is owed for\n * a data read.\n *\n * @remarks\n * The PS read 402 body identifies the grant to settle and the amount/asset. The\n * controller settles it via the DPv2 escrow gateway (`/v1/escrow/pay`). The full\n * unmodified body is preserved under {@link PersonalServerPaymentRequired.raw}.\n */\nexport interface PersonalServerPaymentRequired {\n /** Grant id to settle (the escrow `opId`). Defaults to the read's grantId. */\n grantId: string;\n /** X402 network advertised by the Personal Server challenge. */\n network?: string;\n /** Payment nonce requested by the 402 challenge. */\n paymentNonce?: string;\n /** Server-signed data access receipt requested by the 402 challenge. */\n accessRecord?: EscrowAccessRecord;\n /** Asset address owed (zero address = native VANA). */\n asset: string;\n /** Amount owed, as a decimal base-unit string (preserves uint256 precision). */\n amount: string;\n /** The full, unmodified 402 response body. */\n raw: unknown;\n}\n\n/**\n * Structured payment metadata attached to a successful paid read.\n *\n * @remarks\n * Derived from the gateway's {@link EscrowPayResult}. Lets builders debug the\n * amount, asset, and per-op fee breakdown without re-deriving anything from the\n * raw 402/payment exchange.\n */\nexport interface DirectPaymentReceipt {\n /** Op type settled (the gateway `opType`, e.g. `\"grant\"`). */\n opType: string;\n /** Op id settled (the grant id). */\n opId: string;\n /** Asset paid in (zero address = native VANA). */\n asset: string;\n /** Total amount paid, as a decimal base-unit string. */\n amount: string;\n /** Payment nonce used for this settlement. */\n paymentNonce: string;\n /** Fee breakdown reported by the gateway (registration vs data-access fee). */\n breakdown: DirectFeeBreakdown;\n /** ISO timestamp the gateway recorded the payment. */\n paidAt: string;\n}\n\n/**\n * Per-op fee breakdown reported by the gateway.\n *\n * @remarks\n * Mirrors the escrow {@link PaymentBreakdown}: a one-time registration fee plus\n * the per-read data-access fee, and whether this settlement covered the\n * registration fee.\n */\nexport interface DirectFeeBreakdown {\n /** One-time registration fee for the op, as a decimal base-unit string. */\n registrationFee: string;\n /** Per-read data-access fee, as a decimal base-unit string. */\n dataAccessFee: string;\n /** True when this settlement paid the registration fee. */\n registrationPaid: boolean;\n}\n"],"mappings":"AAsLO,MAAM,eAAe;AAAA,EAC1B,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;","names":[]}
@@ -29026,6 +29026,21 @@ async function buildWeb3SignedHeader(params) {
29026
29026
  return `Web3Signed ${payloadBase64}.${signature}`;
29027
29027
  }
29028
29028
 
29029
+ // src/protocol/networks.ts
29030
+ var PROTOCOL_NETWORK_CHAIN_IDS = {
29031
+ mainnet: 1480,
29032
+ moksha: 14800
29033
+ };
29034
+ function isProtocolNetwork(value) {
29035
+ return typeof value === "string" && Object.hasOwn(PROTOCOL_NETWORK_CHAIN_IDS, value);
29036
+ }
29037
+ function getProtocolNetworkChainId(network) {
29038
+ if (!isProtocolNetwork(network)) {
29039
+ throw new Error(`Unsupported Vana protocol network: ${String(network)}`);
29040
+ }
29041
+ return PROTOCOL_NETWORK_CHAIN_IDS[network];
29042
+ }
29043
+
29029
29044
  // src/storage/providers/vana-storage.ts
29030
29045
  var DEFAULT_ENDPOINT = "https://storage.vana.org";
29031
29046
  var LEGACY_BLOB_PATH_PREFIX = "/v1/blobs";
@@ -29035,6 +29050,7 @@ var MAX_RATE_LIMIT_DELAY_MS = 3e4;
29035
29050
  var VanaStorage = class {
29036
29051
  endpoint;
29037
29052
  network;
29053
+ chainId;
29038
29054
  blobPathPrefix;
29039
29055
  signer;
29040
29056
  ownerAddress;
@@ -29048,15 +29064,10 @@ var VanaStorage = class {
29048
29064
  );
29049
29065
  }
29050
29066
  this.endpoint = (config.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "");
29051
- if (config.network !== void 0 && !isProtocolNetwork(config.network)) {
29052
- throw new StorageError(
29053
- `Unsupported vana-storage network '${String(config.network)}'`,
29054
- "INVALID_NETWORK",
29055
- "vana-storage"
29056
- );
29057
- }
29058
- this.network = config.network;
29059
- this.blobPathPrefix = this.network ? `/v1/networks/${this.network}/blobs` : LEGACY_BLOB_PATH_PREFIX;
29067
+ const resolved = resolveStorageNamespace(config);
29068
+ this.network = resolved.network;
29069
+ this.chainId = resolved.chainId;
29070
+ this.blobPathPrefix = this.chainId !== void 0 ? `/v1/chains/${this.chainId}/blobs` : LEGACY_BLOB_PATH_PREFIX;
29060
29071
  this.signer = config.signer;
29061
29072
  this.ownerAddress = (config.ownerAddress ?? config.signer.address).toLowerCase();
29062
29073
  this.fetchImpl = config.fetchImpl ?? globalThis.fetch.bind(globalThis);
@@ -29253,20 +29264,52 @@ var VanaStorage = class {
29253
29264
  "vana-storage"
29254
29265
  );
29255
29266
  }
29256
- const crossNetwork = this.network ? route.network !== void 0 && route.network !== this.network : route.network !== void 0;
29257
- if (crossNetwork) {
29267
+ if (route.chainId !== this.chainId) {
29258
29268
  throw new StorageError(
29259
- `URL network '${route.network ?? "legacy"}' does not match provider network '${this.network ?? "legacy"}'`,
29269
+ `URL chainId '${route.chainId ?? "legacy"}' does not match provider namespace '${this.namespaceDescription()}'`,
29260
29270
  "INVALID_URL",
29261
29271
  "vana-storage"
29262
29272
  );
29263
29273
  }
29264
29274
  return parsed.pathname;
29265
29275
  }
29276
+ namespaceDescription() {
29277
+ if (this.network !== void 0) {
29278
+ return `${this.network} (${this.chainId})`;
29279
+ }
29280
+ return this.chainId === void 0 ? "legacy" : String(this.chainId);
29281
+ }
29266
29282
  };
29267
- var PROTOCOL_NETWORKS = ["mainnet", "moksha"];
29268
- function isProtocolNetwork(value) {
29269
- return typeof value === "string" && PROTOCOL_NETWORKS.includes(value);
29283
+ function isValidChainId(value) {
29284
+ return typeof value === "number" && Number.isInteger(value) && value > 0;
29285
+ }
29286
+ function resolveStorageNamespace(config) {
29287
+ if (config.network !== void 0 && !isProtocolNetwork(config.network)) {
29288
+ throw new StorageError(
29289
+ `Unsupported vana-storage network '${String(config.network)}'`,
29290
+ "INVALID_NETWORK",
29291
+ "vana-storage"
29292
+ );
29293
+ }
29294
+ if (config.chainId !== void 0 && !isValidChainId(config.chainId)) {
29295
+ throw new StorageError(
29296
+ `Unsupported vana-storage chainId '${String(config.chainId)}'`,
29297
+ "INVALID_CHAIN_ID",
29298
+ "vana-storage"
29299
+ );
29300
+ }
29301
+ if (config.network === void 0) {
29302
+ return { chainId: config.chainId };
29303
+ }
29304
+ const networkChainId = getProtocolNetworkChainId(config.network);
29305
+ if (config.chainId !== void 0 && config.chainId !== networkChainId) {
29306
+ throw new StorageError(
29307
+ `vana-storage network '${config.network}' resolves to chainId '${networkChainId}', not '${config.chainId}'`,
29308
+ "INVALID_CHAIN_ID",
29309
+ "vana-storage"
29310
+ );
29311
+ }
29312
+ return { chainId: networkChainId, network: config.network };
29270
29313
  }
29271
29314
  function parseBlobPath(pathname) {
29272
29315
  const segments = pathname.split("/").filter((s) => s.length > 0);
@@ -29276,11 +29319,13 @@ function parseBlobPath(pathname) {
29276
29319
  if (isTraversal(scope) || isTraversal(collectedAt)) return null;
29277
29320
  return { owner, scope, collectedAt };
29278
29321
  }
29279
- if (segments.length === 7 && segments[0] === "v1" && segments[1] === "networks" && segments[3] === "blobs") {
29280
- const [, , network, , owner, scope, collectedAt] = segments;
29281
- if (!isProtocolNetwork(network)) return null;
29322
+ if (segments.length === 7 && segments[0] === "v1" && segments[1] === "chains" && segments[3] === "blobs") {
29323
+ const [, , chainIdSegment, , owner, scope, collectedAt] = segments;
29324
+ if (!/^[0-9]+$/.test(chainIdSegment)) return null;
29325
+ const chainId = Number(chainIdSegment);
29326
+ if (!isValidChainId(chainId)) return null;
29282
29327
  if (isTraversal(scope) || isTraversal(collectedAt)) return null;
29283
- return { network, owner, scope, collectedAt };
29328
+ return { chainId, owner, scope, collectedAt };
29284
29329
  }
29285
29330
  return null;
29286
29331
  }