@opendatalabs/vana-sdk 3.5.1 → 3.6.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 +116 -0
- package/dist/direct/access-request-client.cjs +104 -0
- package/dist/direct/access-request-client.cjs.map +1 -0
- package/dist/direct/access-request-client.d.ts +51 -0
- package/dist/direct/access-request-client.js +79 -0
- package/dist/direct/access-request-client.js.map +1 -0
- package/dist/direct/access-request-client.test.d.ts +1 -0
- package/dist/direct/connect-flow.cjs +152 -0
- package/dist/direct/connect-flow.cjs.map +1 -0
- package/dist/direct/connect-flow.d.ts +85 -0
- package/dist/direct/connect-flow.js +128 -0
- package/dist/direct/connect-flow.js.map +1 -0
- package/dist/direct/connect-flow.test.d.ts +1 -0
- package/dist/direct/controller.cjs +129 -0
- package/dist/direct/controller.cjs.map +1 -0
- package/dist/direct/controller.d.ts +152 -0
- package/dist/direct/controller.js +109 -0
- package/dist/direct/controller.js.map +1 -0
- package/dist/direct/controller.test.d.ts +1 -0
- package/dist/direct/endpoints.cjs +45 -0
- package/dist/direct/endpoints.cjs.map +1 -0
- package/dist/direct/endpoints.d.ts +22 -0
- package/dist/direct/endpoints.js +19 -0
- package/dist/direct/endpoints.js.map +1 -0
- package/dist/direct/errors.cjs +65 -0
- package/dist/direct/errors.cjs.map +1 -0
- package/dist/direct/errors.d.ts +44 -0
- package/dist/direct/errors.js +38 -0
- package/dist/direct/errors.js.map +1 -0
- package/dist/direct/escrow-payment.cjs +96 -0
- package/dist/direct/escrow-payment.cjs.map +1 -0
- package/dist/direct/escrow-payment.d.ts +81 -0
- package/dist/direct/escrow-payment.js +72 -0
- package/dist/direct/escrow-payment.js.map +1 -0
- package/dist/direct/escrow-payment.test.d.ts +1 -0
- package/dist/direct/personal-server-read.cjs +149 -0
- package/dist/direct/personal-server-read.cjs.map +1 -0
- package/dist/direct/personal-server-read.d.ts +103 -0
- package/dist/direct/personal-server-read.js +124 -0
- package/dist/direct/personal-server-read.js.map +1 -0
- package/dist/direct/personal-server-read.test.d.ts +1 -0
- package/dist/direct/types.cjs +35 -0
- package/dist/direct/types.cjs.map +1 -0
- package/dist/direct/types.d.ts +205 -0
- package/dist/direct/types.js +11 -0
- package/dist/direct/types.js.map +1 -0
- package/dist/direct/use-direct-vana-connect.cjs +68 -0
- package/dist/direct/use-direct-vana-connect.cjs.map +1 -0
- package/dist/direct/use-direct-vana-connect.d.ts +45 -0
- package/dist/direct/use-direct-vana-connect.js +46 -0
- package/dist/direct/use-direct-vana-connect.js.map +1 -0
- package/dist/index.browser.d.ts +7 -3
- package/dist/index.browser.js +438 -157
- package/dist/index.browser.js.map +4 -4
- package/dist/index.node.cjs +461 -162
- package/dist/index.node.cjs.map +4 -4
- package/dist/index.node.d.ts +7 -3
- package/dist/index.node.js +438 -157
- package/dist/index.node.js.map +4 -4
- package/dist/protocol/data-point-status.cjs +80 -0
- package/dist/protocol/data-point-status.cjs.map +1 -0
- package/dist/protocol/data-point-status.d.ts +34 -0
- package/dist/protocol/data-point-status.js +51 -0
- package/dist/protocol/data-point-status.js.map +1 -0
- package/dist/protocol/data-point-status.test.d.ts +1 -0
- package/dist/protocol/eip712.cjs +53 -31
- package/dist/protocol/eip712.cjs.map +1 -1
- package/dist/protocol/eip712.d.ts +98 -43
- package/dist/protocol/eip712.js +47 -27
- package/dist/protocol/eip712.js.map +1 -1
- package/dist/protocol/escrow-deposit.cjs +89 -0
- package/dist/protocol/escrow-deposit.cjs.map +1 -0
- package/dist/protocol/escrow-deposit.d.ts +47 -0
- package/dist/protocol/escrow-deposit.js +60 -0
- package/dist/protocol/escrow-deposit.js.map +1 -0
- package/dist/protocol/escrow-deposit.test.d.ts +1 -0
- package/dist/protocol/escrow-flow.test.d.ts +21 -0
- package/dist/protocol/fee-registry.cjs +116 -0
- package/dist/protocol/fee-registry.cjs.map +1 -0
- package/dist/protocol/fee-registry.d.ts +151 -0
- package/dist/protocol/fee-registry.js +89 -0
- package/dist/protocol/fee-registry.js.map +1 -0
- package/dist/protocol/fee-registry.test.d.ts +1 -0
- package/dist/protocol/gateway.cjs +107 -37
- package/dist/protocol/gateway.cjs.map +1 -1
- package/dist/protocol/gateway.d.ts +223 -57
- package/dist/protocol/gateway.js +107 -37
- package/dist/protocol/gateway.js.map +1 -1
- package/dist/protocol/grants.cjs +27 -64
- package/dist/protocol/grants.cjs.map +1 -1
- package/dist/protocol/grants.d.ts +6 -13
- package/dist/protocol/grants.js +27 -63
- package/dist/protocol/grants.js.map +1 -1
- package/dist/protocol/personal-server-data.cjs +71 -0
- package/dist/protocol/personal-server-data.cjs.map +1 -0
- package/dist/protocol/personal-server-data.d.ts +16 -0
- package/dist/protocol/personal-server-data.js +47 -0
- package/dist/protocol/personal-server-data.js.map +1 -0
- package/dist/protocol/personal-server-data.test.d.ts +1 -0
- package/dist/protocol/personal-server-lite-owner-binding.cjs +93 -0
- package/dist/protocol/personal-server-lite-owner-binding.cjs.map +1 -0
- package/dist/protocol/personal-server-lite-owner-binding.d.ts +44 -0
- package/dist/protocol/personal-server-lite-owner-binding.js +65 -0
- package/dist/protocol/personal-server-lite-owner-binding.js.map +1 -0
- package/dist/protocol/personal-server-lite-owner-binding.test.d.ts +1 -0
- package/dist/react.cjs +32 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.ts +33 -0
- package/dist/react.js +11 -0
- package/dist/react.js.map +1 -0
- package/dist/server.cjs +73 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.ts +32 -0
- package/dist/server.js +55 -0
- package/dist/server.js.map +1 -0
- package/package.json +20 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/direct/personal-server-read.ts"],"sourcesContent":["/**\n * Personal Server data-read request builder and the 402 -> escrow-pay -> retry loop.\n *\n * @remarks\n * The read targets the Personal Server data path (`/v1/data/{scope}`),\n * authenticates with a Web3Signed header (built on {@link buildWeb3SignedHeader}),\n * and — on `402 Payment Required` — settles the grant's data-access fee through\n * the DPv2 escrow gateway and retries once.\n *\n * The 402 body is parsed into a {@link PersonalServerPaymentRequired} (grant id,\n * asset, and amount owed), which drives the escrow settlement.\n *\n * @category Direct\n * @module direct/personal-server-read\n */\n\nimport { buildWeb3SignedHeader } from \"../auth/web3-signed-builder\";\nimport type { Web3SignedSignFn } from \"../auth/web3-signed-builder\";\nimport { NATIVE_ASSET_ADDRESS } from \"../protocol/escrow\";\nimport {\n authorizeGrantPayment,\n type EscrowPaymentConfig,\n} from \"./escrow-payment\";\nimport { PaymentRequiredError, PersonalServerReadError } from \"./errors\";\nimport type {\n DirectPaymentReceipt,\n PersonalServerPaymentRequired,\n} from \"./types\";\n\n/** Minimal `Response`-like shape so the read loop is testable without a DOM. */\nexport interface FetchResponseLike {\n ok: boolean;\n status: number;\n statusText: string;\n headers: { get(name: string): string | null };\n json(): Promise<unknown>;\n text(): Promise<string>;\n}\n\n/** Minimal `fetch` signature accepted by {@link readPersonalServerData}. */\nexport type PersonalServerFetch = (\n input: string,\n init: {\n method: string;\n headers: Record<string, string>;\n },\n) => Promise<FetchResponseLike>;\n\n/** A built, ready-to-send Personal Server data read request. */\nexport interface PersonalServerDataReadRequest {\n /** Absolute URL of the read endpoint. */\n url: string;\n /** HTTP method (always `\"GET\"`). */\n method: \"GET\";\n /** Request path used in the Web3Signed `uri` claim (e.g. `/v1/data/{scope}`). */\n path: string;\n /** Headers including the Web3Signed `Authorization` value. */\n headers: Record<string, string>;\n}\n\n/** Outcome of {@link readPersonalServerData}: the payload plus optional receipt. */\nexport interface PersonalServerReadResult {\n /** The decoded JSON payload returned by the Personal Server. */\n data: unknown;\n /** Present only when this read required (and settled) a payment. */\n payment?: DirectPaymentReceipt;\n}\n\nfunction stripTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\n/** Compute the data path for a scope (`/v1/data/{scope}`). */\nexport function dataPathForScope(scope: string): string {\n return `/v1/data/${encodeURIComponent(scope)}`;\n}\n\n/**\n * Build a Web3Signed-authenticated Personal Server data read request.\n *\n * @param params - Personal Server URL, scope, grant id, and an EIP-191 signer.\n * @returns The request URL, method, path, and headers (including `Authorization`).\n */\nexport async function buildPersonalServerDataReadRequest(params: {\n /** Base URL of the user's Personal Server. */\n personalServerUrl: string;\n /** Scope to read (e.g. `\"icloud_notes.notes\"`). */\n scope: string;\n /** Grant id authorizing the read. */\n grantId: string;\n /** EIP-191 signer for the Web3Signed header (the app key). */\n signMessage: Web3SignedSignFn;\n}): Promise<PersonalServerDataReadRequest> {\n const base = stripTrailingSlash(params.personalServerUrl);\n const path = dataPathForScope(params.scope);\n const authorization = await buildWeb3SignedHeader({\n signMessage: params.signMessage,\n aud: base,\n method: \"GET\",\n uri: path,\n grantId: params.grantId,\n });\n const headers: Record<string, string> = {\n Authorization: authorization,\n Accept: \"application/json\",\n };\n return { url: `${base}${path}`, method: \"GET\", path, headers };\n}\n\n/**\n * Parse a `402 Payment Required` body into a {@link PersonalServerPaymentRequired}.\n *\n * @remarks\n * Accepts a few field spellings and falls back to the read's own grantId and the\n * native asset when a field is absent.\n *\n * @param res - The 402 response.\n * @param grantId - The grant id of the read (default `opId`).\n * @returns The parsed payment requirement.\n */\nexport async function parsePersonalServerPaymentRequired(\n res: FetchResponseLike,\n grantId: string,\n): Promise<PersonalServerPaymentRequired> {\n let raw: unknown = undefined;\n try {\n raw = await res.json();\n } catch {\n raw = undefined;\n }\n const body = (raw ?? {}) as {\n grantId?: unknown;\n opId?: unknown;\n asset?: unknown;\n amount?: unknown;\n maxAmountRequired?: unknown;\n };\n const resolvedGrantId =\n typeof body.grantId === \"string\"\n ? body.grantId\n : typeof body.opId === \"string\"\n ? body.opId\n : grantId;\n const amountValue =\n typeof body.amount === \"string\"\n ? body.amount\n : typeof body.maxAmountRequired === \"string\"\n ? body.maxAmountRequired\n : \"0\";\n return {\n grantId: resolvedGrantId,\n asset: typeof body.asset === \"string\" ? body.asset : NATIVE_ASSET_ADDRESS,\n amount: amountValue,\n raw,\n };\n}\n\n/**\n * Read approved data from a Personal Server, settling a 402 via escrow.\n *\n * @remarks\n * Sends a Web3Signed-authenticated `GET /v1/data/{scope}`. On `402`, parses what\n * is owed, authorizes an escrow payment for the grant via `escrow`, and retries\n * once. If escrow is not configured, throws {@link PaymentRequiredError} carrying\n * the parsed requirement so callers can debug amount/asset.\n *\n * @param params - Connection details, app signer, optional escrow config and fetch.\n * @returns `{ data, payment? }`.\n */\nexport async function readPersonalServerData(params: {\n personalServerUrl: string;\n scope: string;\n grantId: string;\n payerAddress: `0x${string}`;\n signMessage: Web3SignedSignFn;\n escrow?: EscrowPaymentConfig;\n fetchFn?: PersonalServerFetch;\n}): Promise<PersonalServerReadResult> {\n const fetchFn =\n params.fetchFn ?? (globalThis.fetch as unknown as PersonalServerFetch);\n if (!fetchFn) {\n throw new PersonalServerReadError(\n \"No fetch implementation available for Personal Server read\",\n );\n }\n\n const initial = await buildPersonalServerDataReadRequest({\n personalServerUrl: params.personalServerUrl,\n scope: params.scope,\n grantId: params.grantId,\n signMessage: params.signMessage,\n });\n\n let res = await fetchFn(initial.url, {\n method: initial.method,\n headers: initial.headers,\n });\n\n let payment: DirectPaymentReceipt | undefined;\n\n if (res.status === 402) {\n const required = await parsePersonalServerPaymentRequired(\n res,\n params.grantId,\n );\n if (!params.escrow) {\n throw new PaymentRequiredError(\n \"Personal Server requires payment but no escrow config is set\",\n {\n scope: params.scope,\n grantId: required.grantId,\n asset: required.asset,\n amount: required.amount,\n },\n );\n }\n\n payment = await authorizeGrantPayment({\n payerAddress: params.payerAddress,\n required,\n config: params.escrow,\n });\n\n // Re-sign and retry — the settled payment unlocks the read.\n const retry = await buildPersonalServerDataReadRequest({\n personalServerUrl: params.personalServerUrl,\n scope: params.scope,\n grantId: params.grantId,\n signMessage: params.signMessage,\n });\n res = await fetchFn(retry.url, {\n method: retry.method,\n headers: retry.headers,\n });\n\n if (res.status === 402) {\n throw new PaymentRequiredError(\n \"Personal Server still requires payment after escrow settlement\",\n {\n scope: params.scope,\n grantId: required.grantId,\n asset: required.asset,\n amount: required.amount,\n payment,\n },\n );\n }\n }\n\n if (!res.ok) {\n const detail = await res.text().catch(() => \"\");\n throw new PersonalServerReadError(\n `Personal Server read failed: ${res.status} ${res.statusText}`,\n res.status,\n { scope: params.scope, body: detail.slice(0, 500) },\n );\n }\n\n return { data: await res.json(), payment };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Personal Server data-read request builder and the 402 -> escrow-pay -> retry loop.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* The read targets the Personal Server data path (`/v1/data/{scope}`),
|
|
6
|
+
* authenticates with a Web3Signed header (built on {@link buildWeb3SignedHeader}),
|
|
7
|
+
* and — on `402 Payment Required` — settles the grant's data-access fee through
|
|
8
|
+
* the DPv2 escrow gateway and retries once.
|
|
9
|
+
*
|
|
10
|
+
* The 402 body is parsed into a {@link PersonalServerPaymentRequired} (grant id,
|
|
11
|
+
* asset, and amount owed), which drives the escrow settlement.
|
|
12
|
+
*
|
|
13
|
+
* @category Direct
|
|
14
|
+
* @module direct/personal-server-read
|
|
15
|
+
*/
|
|
16
|
+
import type { Web3SignedSignFn } from "../auth/web3-signed-builder";
|
|
17
|
+
import { type EscrowPaymentConfig } from "./escrow-payment";
|
|
18
|
+
import type { DirectPaymentReceipt, PersonalServerPaymentRequired } from "./types";
|
|
19
|
+
/** Minimal `Response`-like shape so the read loop is testable without a DOM. */
|
|
20
|
+
export interface FetchResponseLike {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
status: number;
|
|
23
|
+
statusText: string;
|
|
24
|
+
headers: {
|
|
25
|
+
get(name: string): string | null;
|
|
26
|
+
};
|
|
27
|
+
json(): Promise<unknown>;
|
|
28
|
+
text(): Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
/** Minimal `fetch` signature accepted by {@link readPersonalServerData}. */
|
|
31
|
+
export type PersonalServerFetch = (input: string, init: {
|
|
32
|
+
method: string;
|
|
33
|
+
headers: Record<string, string>;
|
|
34
|
+
}) => Promise<FetchResponseLike>;
|
|
35
|
+
/** A built, ready-to-send Personal Server data read request. */
|
|
36
|
+
export interface PersonalServerDataReadRequest {
|
|
37
|
+
/** Absolute URL of the read endpoint. */
|
|
38
|
+
url: string;
|
|
39
|
+
/** HTTP method (always `"GET"`). */
|
|
40
|
+
method: "GET";
|
|
41
|
+
/** Request path used in the Web3Signed `uri` claim (e.g. `/v1/data/{scope}`). */
|
|
42
|
+
path: string;
|
|
43
|
+
/** Headers including the Web3Signed `Authorization` value. */
|
|
44
|
+
headers: Record<string, string>;
|
|
45
|
+
}
|
|
46
|
+
/** Outcome of {@link readPersonalServerData}: the payload plus optional receipt. */
|
|
47
|
+
export interface PersonalServerReadResult {
|
|
48
|
+
/** The decoded JSON payload returned by the Personal Server. */
|
|
49
|
+
data: unknown;
|
|
50
|
+
/** Present only when this read required (and settled) a payment. */
|
|
51
|
+
payment?: DirectPaymentReceipt;
|
|
52
|
+
}
|
|
53
|
+
/** Compute the data path for a scope (`/v1/data/{scope}`). */
|
|
54
|
+
export declare function dataPathForScope(scope: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Build a Web3Signed-authenticated Personal Server data read request.
|
|
57
|
+
*
|
|
58
|
+
* @param params - Personal Server URL, scope, grant id, and an EIP-191 signer.
|
|
59
|
+
* @returns The request URL, method, path, and headers (including `Authorization`).
|
|
60
|
+
*/
|
|
61
|
+
export declare function buildPersonalServerDataReadRequest(params: {
|
|
62
|
+
/** Base URL of the user's Personal Server. */
|
|
63
|
+
personalServerUrl: string;
|
|
64
|
+
/** Scope to read (e.g. `"icloud_notes.notes"`). */
|
|
65
|
+
scope: string;
|
|
66
|
+
/** Grant id authorizing the read. */
|
|
67
|
+
grantId: string;
|
|
68
|
+
/** EIP-191 signer for the Web3Signed header (the app key). */
|
|
69
|
+
signMessage: Web3SignedSignFn;
|
|
70
|
+
}): Promise<PersonalServerDataReadRequest>;
|
|
71
|
+
/**
|
|
72
|
+
* Parse a `402 Payment Required` body into a {@link PersonalServerPaymentRequired}.
|
|
73
|
+
*
|
|
74
|
+
* @remarks
|
|
75
|
+
* Accepts a few field spellings and falls back to the read's own grantId and the
|
|
76
|
+
* native asset when a field is absent.
|
|
77
|
+
*
|
|
78
|
+
* @param res - The 402 response.
|
|
79
|
+
* @param grantId - The grant id of the read (default `opId`).
|
|
80
|
+
* @returns The parsed payment requirement.
|
|
81
|
+
*/
|
|
82
|
+
export declare function parsePersonalServerPaymentRequired(res: FetchResponseLike, grantId: string): Promise<PersonalServerPaymentRequired>;
|
|
83
|
+
/**
|
|
84
|
+
* Read approved data from a Personal Server, settling a 402 via escrow.
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* Sends a Web3Signed-authenticated `GET /v1/data/{scope}`. On `402`, parses what
|
|
88
|
+
* is owed, authorizes an escrow payment for the grant via `escrow`, and retries
|
|
89
|
+
* once. If escrow is not configured, throws {@link PaymentRequiredError} carrying
|
|
90
|
+
* the parsed requirement so callers can debug amount/asset.
|
|
91
|
+
*
|
|
92
|
+
* @param params - Connection details, app signer, optional escrow config and fetch.
|
|
93
|
+
* @returns `{ data, payment? }`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function readPersonalServerData(params: {
|
|
96
|
+
personalServerUrl: string;
|
|
97
|
+
scope: string;
|
|
98
|
+
grantId: string;
|
|
99
|
+
payerAddress: `0x${string}`;
|
|
100
|
+
signMessage: Web3SignedSignFn;
|
|
101
|
+
escrow?: EscrowPaymentConfig;
|
|
102
|
+
fetchFn?: PersonalServerFetch;
|
|
103
|
+
}): Promise<PersonalServerReadResult>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { buildWeb3SignedHeader } from "../auth/web3-signed-builder.js";
|
|
2
|
+
import { NATIVE_ASSET_ADDRESS } from "../protocol/escrow.js";
|
|
3
|
+
import {
|
|
4
|
+
authorizeGrantPayment
|
|
5
|
+
} from "./escrow-payment.js";
|
|
6
|
+
import { PaymentRequiredError, PersonalServerReadError } from "./errors.js";
|
|
7
|
+
function stripTrailingSlash(url) {
|
|
8
|
+
return url.replace(/\/+$/, "");
|
|
9
|
+
}
|
|
10
|
+
function dataPathForScope(scope) {
|
|
11
|
+
return `/v1/data/${encodeURIComponent(scope)}`;
|
|
12
|
+
}
|
|
13
|
+
async function buildPersonalServerDataReadRequest(params) {
|
|
14
|
+
const base = stripTrailingSlash(params.personalServerUrl);
|
|
15
|
+
const path = dataPathForScope(params.scope);
|
|
16
|
+
const authorization = await buildWeb3SignedHeader({
|
|
17
|
+
signMessage: params.signMessage,
|
|
18
|
+
aud: base,
|
|
19
|
+
method: "GET",
|
|
20
|
+
uri: path,
|
|
21
|
+
grantId: params.grantId
|
|
22
|
+
});
|
|
23
|
+
const headers = {
|
|
24
|
+
Authorization: authorization,
|
|
25
|
+
Accept: "application/json"
|
|
26
|
+
};
|
|
27
|
+
return { url: `${base}${path}`, method: "GET", path, headers };
|
|
28
|
+
}
|
|
29
|
+
async function parsePersonalServerPaymentRequired(res, grantId) {
|
|
30
|
+
let raw = void 0;
|
|
31
|
+
try {
|
|
32
|
+
raw = await res.json();
|
|
33
|
+
} catch {
|
|
34
|
+
raw = void 0;
|
|
35
|
+
}
|
|
36
|
+
const body = raw ?? {};
|
|
37
|
+
const resolvedGrantId = typeof body.grantId === "string" ? body.grantId : typeof body.opId === "string" ? body.opId : grantId;
|
|
38
|
+
const amountValue = typeof body.amount === "string" ? body.amount : typeof body.maxAmountRequired === "string" ? body.maxAmountRequired : "0";
|
|
39
|
+
return {
|
|
40
|
+
grantId: resolvedGrantId,
|
|
41
|
+
asset: typeof body.asset === "string" ? body.asset : NATIVE_ASSET_ADDRESS,
|
|
42
|
+
amount: amountValue,
|
|
43
|
+
raw
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function readPersonalServerData(params) {
|
|
47
|
+
const fetchFn = params.fetchFn ?? globalThis.fetch;
|
|
48
|
+
if (!fetchFn) {
|
|
49
|
+
throw new PersonalServerReadError(
|
|
50
|
+
"No fetch implementation available for Personal Server read"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const initial = await buildPersonalServerDataReadRequest({
|
|
54
|
+
personalServerUrl: params.personalServerUrl,
|
|
55
|
+
scope: params.scope,
|
|
56
|
+
grantId: params.grantId,
|
|
57
|
+
signMessage: params.signMessage
|
|
58
|
+
});
|
|
59
|
+
let res = await fetchFn(initial.url, {
|
|
60
|
+
method: initial.method,
|
|
61
|
+
headers: initial.headers
|
|
62
|
+
});
|
|
63
|
+
let payment;
|
|
64
|
+
if (res.status === 402) {
|
|
65
|
+
const required = await parsePersonalServerPaymentRequired(
|
|
66
|
+
res,
|
|
67
|
+
params.grantId
|
|
68
|
+
);
|
|
69
|
+
if (!params.escrow) {
|
|
70
|
+
throw new PaymentRequiredError(
|
|
71
|
+
"Personal Server requires payment but no escrow config is set",
|
|
72
|
+
{
|
|
73
|
+
scope: params.scope,
|
|
74
|
+
grantId: required.grantId,
|
|
75
|
+
asset: required.asset,
|
|
76
|
+
amount: required.amount
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
payment = await authorizeGrantPayment({
|
|
81
|
+
payerAddress: params.payerAddress,
|
|
82
|
+
required,
|
|
83
|
+
config: params.escrow
|
|
84
|
+
});
|
|
85
|
+
const retry = await buildPersonalServerDataReadRequest({
|
|
86
|
+
personalServerUrl: params.personalServerUrl,
|
|
87
|
+
scope: params.scope,
|
|
88
|
+
grantId: params.grantId,
|
|
89
|
+
signMessage: params.signMessage
|
|
90
|
+
});
|
|
91
|
+
res = await fetchFn(retry.url, {
|
|
92
|
+
method: retry.method,
|
|
93
|
+
headers: retry.headers
|
|
94
|
+
});
|
|
95
|
+
if (res.status === 402) {
|
|
96
|
+
throw new PaymentRequiredError(
|
|
97
|
+
"Personal Server still requires payment after escrow settlement",
|
|
98
|
+
{
|
|
99
|
+
scope: params.scope,
|
|
100
|
+
grantId: required.grantId,
|
|
101
|
+
asset: required.asset,
|
|
102
|
+
amount: required.amount,
|
|
103
|
+
payment
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (!res.ok) {
|
|
109
|
+
const detail = await res.text().catch(() => "");
|
|
110
|
+
throw new PersonalServerReadError(
|
|
111
|
+
`Personal Server read failed: ${res.status} ${res.statusText}`,
|
|
112
|
+
res.status,
|
|
113
|
+
{ scope: params.scope, body: detail.slice(0, 500) }
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
return { data: await res.json(), payment };
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
buildPersonalServerDataReadRequest,
|
|
120
|
+
dataPathForScope,
|
|
121
|
+
parsePersonalServerPaymentRequired,
|
|
122
|
+
readPersonalServerData
|
|
123
|
+
};
|
|
124
|
+
//# sourceMappingURL=personal-server-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/direct/personal-server-read.ts"],"sourcesContent":["/**\n * Personal Server data-read request builder and the 402 -> escrow-pay -> retry loop.\n *\n * @remarks\n * The read targets the Personal Server data path (`/v1/data/{scope}`),\n * authenticates with a Web3Signed header (built on {@link buildWeb3SignedHeader}),\n * and — on `402 Payment Required` — settles the grant's data-access fee through\n * the DPv2 escrow gateway and retries once.\n *\n * The 402 body is parsed into a {@link PersonalServerPaymentRequired} (grant id,\n * asset, and amount owed), which drives the escrow settlement.\n *\n * @category Direct\n * @module direct/personal-server-read\n */\n\nimport { buildWeb3SignedHeader } from \"../auth/web3-signed-builder\";\nimport type { Web3SignedSignFn } from \"../auth/web3-signed-builder\";\nimport { NATIVE_ASSET_ADDRESS } from \"../protocol/escrow\";\nimport {\n authorizeGrantPayment,\n type EscrowPaymentConfig,\n} from \"./escrow-payment\";\nimport { PaymentRequiredError, PersonalServerReadError } from \"./errors\";\nimport type {\n DirectPaymentReceipt,\n PersonalServerPaymentRequired,\n} from \"./types\";\n\n/** Minimal `Response`-like shape so the read loop is testable without a DOM. */\nexport interface FetchResponseLike {\n ok: boolean;\n status: number;\n statusText: string;\n headers: { get(name: string): string | null };\n json(): Promise<unknown>;\n text(): Promise<string>;\n}\n\n/** Minimal `fetch` signature accepted by {@link readPersonalServerData}. */\nexport type PersonalServerFetch = (\n input: string,\n init: {\n method: string;\n headers: Record<string, string>;\n },\n) => Promise<FetchResponseLike>;\n\n/** A built, ready-to-send Personal Server data read request. */\nexport interface PersonalServerDataReadRequest {\n /** Absolute URL of the read endpoint. */\n url: string;\n /** HTTP method (always `\"GET\"`). */\n method: \"GET\";\n /** Request path used in the Web3Signed `uri` claim (e.g. `/v1/data/{scope}`). */\n path: string;\n /** Headers including the Web3Signed `Authorization` value. */\n headers: Record<string, string>;\n}\n\n/** Outcome of {@link readPersonalServerData}: the payload plus optional receipt. */\nexport interface PersonalServerReadResult {\n /** The decoded JSON payload returned by the Personal Server. */\n data: unknown;\n /** Present only when this read required (and settled) a payment. */\n payment?: DirectPaymentReceipt;\n}\n\nfunction stripTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\n/** Compute the data path for a scope (`/v1/data/{scope}`). */\nexport function dataPathForScope(scope: string): string {\n return `/v1/data/${encodeURIComponent(scope)}`;\n}\n\n/**\n * Build a Web3Signed-authenticated Personal Server data read request.\n *\n * @param params - Personal Server URL, scope, grant id, and an EIP-191 signer.\n * @returns The request URL, method, path, and headers (including `Authorization`).\n */\nexport async function buildPersonalServerDataReadRequest(params: {\n /** Base URL of the user's Personal Server. */\n personalServerUrl: string;\n /** Scope to read (e.g. `\"icloud_notes.notes\"`). */\n scope: string;\n /** Grant id authorizing the read. */\n grantId: string;\n /** EIP-191 signer for the Web3Signed header (the app key). */\n signMessage: Web3SignedSignFn;\n}): Promise<PersonalServerDataReadRequest> {\n const base = stripTrailingSlash(params.personalServerUrl);\n const path = dataPathForScope(params.scope);\n const authorization = await buildWeb3SignedHeader({\n signMessage: params.signMessage,\n aud: base,\n method: \"GET\",\n uri: path,\n grantId: params.grantId,\n });\n const headers: Record<string, string> = {\n Authorization: authorization,\n Accept: \"application/json\",\n };\n return { url: `${base}${path}`, method: \"GET\", path, headers };\n}\n\n/**\n * Parse a `402 Payment Required` body into a {@link PersonalServerPaymentRequired}.\n *\n * @remarks\n * Accepts a few field spellings and falls back to the read's own grantId and the\n * native asset when a field is absent.\n *\n * @param res - The 402 response.\n * @param grantId - The grant id of the read (default `opId`).\n * @returns The parsed payment requirement.\n */\nexport async function parsePersonalServerPaymentRequired(\n res: FetchResponseLike,\n grantId: string,\n): Promise<PersonalServerPaymentRequired> {\n let raw: unknown = undefined;\n try {\n raw = await res.json();\n } catch {\n raw = undefined;\n }\n const body = (raw ?? {}) as {\n grantId?: unknown;\n opId?: unknown;\n asset?: unknown;\n amount?: unknown;\n maxAmountRequired?: unknown;\n };\n const resolvedGrantId =\n typeof body.grantId === \"string\"\n ? body.grantId\n : typeof body.opId === \"string\"\n ? body.opId\n : grantId;\n const amountValue =\n typeof body.amount === \"string\"\n ? body.amount\n : typeof body.maxAmountRequired === \"string\"\n ? body.maxAmountRequired\n : \"0\";\n return {\n grantId: resolvedGrantId,\n asset: typeof body.asset === \"string\" ? body.asset : NATIVE_ASSET_ADDRESS,\n amount: amountValue,\n raw,\n };\n}\n\n/**\n * Read approved data from a Personal Server, settling a 402 via escrow.\n *\n * @remarks\n * Sends a Web3Signed-authenticated `GET /v1/data/{scope}`. On `402`, parses what\n * is owed, authorizes an escrow payment for the grant via `escrow`, and retries\n * once. If escrow is not configured, throws {@link PaymentRequiredError} carrying\n * the parsed requirement so callers can debug amount/asset.\n *\n * @param params - Connection details, app signer, optional escrow config and fetch.\n * @returns `{ data, payment? }`.\n */\nexport async function readPersonalServerData(params: {\n personalServerUrl: string;\n scope: string;\n grantId: string;\n payerAddress: `0x${string}`;\n signMessage: Web3SignedSignFn;\n escrow?: EscrowPaymentConfig;\n fetchFn?: PersonalServerFetch;\n}): Promise<PersonalServerReadResult> {\n const fetchFn =\n params.fetchFn ?? (globalThis.fetch as unknown as PersonalServerFetch);\n if (!fetchFn) {\n throw new PersonalServerReadError(\n \"No fetch implementation available for Personal Server read\",\n );\n }\n\n const initial = await buildPersonalServerDataReadRequest({\n personalServerUrl: params.personalServerUrl,\n scope: params.scope,\n grantId: params.grantId,\n signMessage: params.signMessage,\n });\n\n let res = await fetchFn(initial.url, {\n method: initial.method,\n headers: initial.headers,\n });\n\n let payment: DirectPaymentReceipt | undefined;\n\n if (res.status === 402) {\n const required = await parsePersonalServerPaymentRequired(\n res,\n params.grantId,\n );\n if (!params.escrow) {\n throw new PaymentRequiredError(\n \"Personal Server requires payment but no escrow config is set\",\n {\n scope: params.scope,\n grantId: required.grantId,\n asset: required.asset,\n amount: required.amount,\n },\n );\n }\n\n payment = await authorizeGrantPayment({\n payerAddress: params.payerAddress,\n required,\n config: params.escrow,\n });\n\n // Re-sign and retry — the settled payment unlocks the read.\n const retry = await buildPersonalServerDataReadRequest({\n personalServerUrl: params.personalServerUrl,\n scope: params.scope,\n grantId: params.grantId,\n signMessage: params.signMessage,\n });\n res = await fetchFn(retry.url, {\n method: retry.method,\n headers: retry.headers,\n });\n\n if (res.status === 402) {\n throw new PaymentRequiredError(\n \"Personal Server still requires payment after escrow settlement\",\n {\n scope: params.scope,\n grantId: required.grantId,\n asset: required.asset,\n amount: required.amount,\n payment,\n },\n );\n }\n }\n\n if (!res.ok) {\n const detail = await res.text().catch(() => \"\");\n throw new PersonalServerReadError(\n `Personal Server read failed: ${res.status} ${res.statusText}`,\n res.status,\n { scope: params.scope, body: detail.slice(0, 500) },\n );\n }\n\n return { data: await res.json(), payment };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var types_exports = {};
|
|
20
|
+
__export(types_exports, {
|
|
21
|
+
DirectOpType: () => DirectOpType
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(types_exports);
|
|
24
|
+
const DirectOpType = {
|
|
25
|
+
GrantRegistration: "grant_registration",
|
|
26
|
+
DataAccess: "data_access",
|
|
27
|
+
DataRegistration: "data_registration",
|
|
28
|
+
ServerRegistration: "server_registration",
|
|
29
|
+
BuilderRegistration: "builder_registration"
|
|
30
|
+
};
|
|
31
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
32
|
+
0 && (module.exports = {
|
|
33
|
+
DirectOpType
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=types.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/direct/types.ts"],"sourcesContent":["/**\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/testnet stack. Use only when testing against\n * Vana's dev infrastructure.\n */\nexport type DirectEnv = \"dev\" | \"production\";\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 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}\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 | \"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 `status === \"approved\"`. */\n personalServerUrl?: string;\n /** Grant id covering the approved scope — present once approved. */\n grantId?: string;\n /** The approved scope — present once approved. */\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, 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 }): 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/**\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 /** 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;AAwJO,MAAM,eAAe;AAAA,EAC1B,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;","names":[]}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the Direct Data Controller and the browser connect helper.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* These types describe the "two-tab" Data Portability flow documented in the
|
|
6
|
+
* builder guide: a backend controller creates an access request, the browser
|
|
7
|
+
* opens Vana for user approval, and the backend reads the approved data from
|
|
8
|
+
* the user's Personal Server (handling 402 Payment Required).
|
|
9
|
+
*
|
|
10
|
+
* @category Direct
|
|
11
|
+
* @module direct/types
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Target environment for a {@link DirectDataController}.
|
|
15
|
+
*
|
|
16
|
+
* - `"production"` — Vana mainnet stack (default service URLs).
|
|
17
|
+
* - `"dev"` — Vana internal dev/testnet stack. Use only when testing against
|
|
18
|
+
* Vana's dev infrastructure.
|
|
19
|
+
*/
|
|
20
|
+
export type DirectEnv = "dev" | "production";
|
|
21
|
+
/**
|
|
22
|
+
* App identity advertised to users during approval and attributed in Builder
|
|
23
|
+
* League activity reports.
|
|
24
|
+
*/
|
|
25
|
+
export interface DirectAppConfig {
|
|
26
|
+
/** Stable, human-readable app id (e.g. `"notes-lens"`). */
|
|
27
|
+
id: string;
|
|
28
|
+
/** Display name shown to the user in the Vana approval UI. */
|
|
29
|
+
name: string;
|
|
30
|
+
/** Public homepage URL for the app. */
|
|
31
|
+
homepageUrl: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolved app identity: the configured {@link DirectAppConfig} plus the app's
|
|
35
|
+
* derived on-chain address (the address to fund and inspect).
|
|
36
|
+
*/
|
|
37
|
+
export interface AppIdentity extends DirectAppConfig {
|
|
38
|
+
/** The app's `0x`-prefixed on-chain address (derived from `appPrivateKey`). */
|
|
39
|
+
address: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolved service URLs for a given {@link DirectEnv}.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Centralizes the per-environment base URLs the controller talks to. Each can
|
|
46
|
+
* be overridden via {@link DirectDataControllerConfig.endpoints} when pointing
|
|
47
|
+
* at a non-standard deployment.
|
|
48
|
+
*/
|
|
49
|
+
export interface DirectServiceEndpoints {
|
|
50
|
+
/** Vana chain id for this environment (1480 mainnet, 14800 moksha). */
|
|
51
|
+
chainId: number;
|
|
52
|
+
/** Base URL of the Vana Account access-request API that issues `dcr_*` ids. */
|
|
53
|
+
accessRequestBaseUrl: string;
|
|
54
|
+
/** Base URL users are sent to for approval (the Vana app). */
|
|
55
|
+
approvalAppBaseUrl: string;
|
|
56
|
+
}
|
|
57
|
+
/** Result of {@link DirectDataController.createAccessRequest}. */
|
|
58
|
+
export interface AccessRequest {
|
|
59
|
+
/** Opaque request id (e.g. `"dcr_123"`). */
|
|
60
|
+
requestId: string;
|
|
61
|
+
/** URL the browser opens so the user can approve the requested scopes. */
|
|
62
|
+
approvalUrl: string;
|
|
63
|
+
/** On-chain address of the (registered or reused) app. */
|
|
64
|
+
appAddress: string;
|
|
65
|
+
}
|
|
66
|
+
/** Lifecycle status of an access request. */
|
|
67
|
+
export type AccessRequestStatusValue = "pending" | "approved" | "denied" | "expired";
|
|
68
|
+
/** Result of {@link DirectDataController.getAccessRequestStatus}. */
|
|
69
|
+
export interface AccessRequestStatus {
|
|
70
|
+
/** Current lifecycle status of the request. */
|
|
71
|
+
status: AccessRequestStatusValue;
|
|
72
|
+
/** Personal Server base URL — present once `status === "approved"`. */
|
|
73
|
+
personalServerUrl?: string;
|
|
74
|
+
/** Grant id covering the approved scope — present once approved. */
|
|
75
|
+
grantId?: string;
|
|
76
|
+
/** The approved scope — present once approved. */
|
|
77
|
+
scope?: string;
|
|
78
|
+
}
|
|
79
|
+
/** Result of {@link DirectDataController.readApprovedData}. */
|
|
80
|
+
export interface ApprovedDataResult<T = unknown> {
|
|
81
|
+
/** The scope the data was read for. */
|
|
82
|
+
scope: string;
|
|
83
|
+
/** The decoded payload returned by the Personal Server. */
|
|
84
|
+
data: T;
|
|
85
|
+
/**
|
|
86
|
+
* Payment receipt — present only when this read required (and settled) a
|
|
87
|
+
* payment. Lets builders inspect the amount, asset, and fee breakdown without
|
|
88
|
+
* digging into the underlying 402/escrow exchange. Reads served from a paid-up
|
|
89
|
+
* grant omit this field.
|
|
90
|
+
*/
|
|
91
|
+
payment?: DirectPaymentReceipt;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Client for the Vana Account access-request API — the service that turns a
|
|
95
|
+
* registered app + scopes into a `dcr_*` id and approval URL.
|
|
96
|
+
*
|
|
97
|
+
* @remarks
|
|
98
|
+
* The controller uses a default client against the Vana Account endpoints. You
|
|
99
|
+
* can inject your own implementation to point at a custom deployment or to
|
|
100
|
+
* supply a test double.
|
|
101
|
+
*/
|
|
102
|
+
export interface AccessRequestClient {
|
|
103
|
+
/**
|
|
104
|
+
* Create an access request for the given app + scopes.
|
|
105
|
+
*
|
|
106
|
+
* @param input - App identity, source, scopes, and the post-approval return URL.
|
|
107
|
+
* @returns The created {@link AccessRequest}.
|
|
108
|
+
*/
|
|
109
|
+
createAccessRequest(input: {
|
|
110
|
+
appAddress: string;
|
|
111
|
+
app: DirectAppConfig;
|
|
112
|
+
source: string;
|
|
113
|
+
scopes: string[];
|
|
114
|
+
returnUrl: string;
|
|
115
|
+
}): Promise<AccessRequest>;
|
|
116
|
+
/**
|
|
117
|
+
* Fetch the current status of a previously created access request.
|
|
118
|
+
*
|
|
119
|
+
* @param requestId - The `dcr_*` id returned by {@link AccessRequestClient.createAccessRequest}.
|
|
120
|
+
* @returns The current {@link AccessRequestStatus}.
|
|
121
|
+
*/
|
|
122
|
+
getAccessRequestStatus(requestId: string): Promise<AccessRequestStatus>;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Op-type vocabulary used by the DPv2 escrow payment surface.
|
|
126
|
+
*
|
|
127
|
+
* @remarks
|
|
128
|
+
* These are the operations the gateway prices and settles via
|
|
129
|
+
* `POST /v1/escrow/pay` (`opType` field of the `GenericPayment` message). A
|
|
130
|
+
* direct data read settles the {@link DirectOpType.DataAccess} op for the
|
|
131
|
+
* approved grant; the other op types are listed here for completeness and to
|
|
132
|
+
* give builders a typed vocabulary when inspecting fee breakdowns.
|
|
133
|
+
*
|
|
134
|
+
* Note: the escrow `GenericPayment` `opType` is currently `"grant"` on the wire
|
|
135
|
+
* for grant lifecycle payments; this enum names the higher-level fee categories
|
|
136
|
+
* the gateway reports in a {@link PaymentBreakdown}.
|
|
137
|
+
*/
|
|
138
|
+
export declare const DirectOpType: {
|
|
139
|
+
readonly GrantRegistration: "grant_registration";
|
|
140
|
+
readonly DataAccess: "data_access";
|
|
141
|
+
readonly DataRegistration: "data_registration";
|
|
142
|
+
readonly ServerRegistration: "server_registration";
|
|
143
|
+
readonly BuilderRegistration: "builder_registration";
|
|
144
|
+
};
|
|
145
|
+
/** A direct-flow op type (see {@link DirectOpType}). */
|
|
146
|
+
export type DirectOpTypeValue = (typeof DirectOpType)[keyof typeof DirectOpType];
|
|
147
|
+
/**
|
|
148
|
+
* What a Personal Server `402 Payment Required` tells the controller is owed for
|
|
149
|
+
* a data read.
|
|
150
|
+
*
|
|
151
|
+
* @remarks
|
|
152
|
+
* The PS read 402 body identifies the grant to settle and the amount/asset. The
|
|
153
|
+
* controller settles it via the DPv2 escrow gateway (`/v1/escrow/pay`). The full
|
|
154
|
+
* unmodified body is preserved under {@link PersonalServerPaymentRequired.raw}.
|
|
155
|
+
*/
|
|
156
|
+
export interface PersonalServerPaymentRequired {
|
|
157
|
+
/** Grant id to settle (the escrow `opId`). Defaults to the read's grantId. */
|
|
158
|
+
grantId: string;
|
|
159
|
+
/** Asset address owed (zero address = native VANA). */
|
|
160
|
+
asset: string;
|
|
161
|
+
/** Amount owed, as a decimal base-unit string (preserves uint256 precision). */
|
|
162
|
+
amount: string;
|
|
163
|
+
/** The full, unmodified 402 response body. */
|
|
164
|
+
raw: unknown;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Structured payment metadata attached to a successful paid read.
|
|
168
|
+
*
|
|
169
|
+
* @remarks
|
|
170
|
+
* Derived from the gateway's {@link EscrowPayResult}. Lets builders debug the
|
|
171
|
+
* amount, asset, and per-op fee breakdown without re-deriving anything from the
|
|
172
|
+
* raw 402/payment exchange.
|
|
173
|
+
*/
|
|
174
|
+
export interface DirectPaymentReceipt {
|
|
175
|
+
/** Op type settled (the gateway `opType`, e.g. `"grant"`). */
|
|
176
|
+
opType: string;
|
|
177
|
+
/** Op id settled (the grant id). */
|
|
178
|
+
opId: string;
|
|
179
|
+
/** Asset paid in (zero address = native VANA). */
|
|
180
|
+
asset: string;
|
|
181
|
+
/** Total amount paid, as a decimal base-unit string. */
|
|
182
|
+
amount: string;
|
|
183
|
+
/** Payment nonce used for this settlement. */
|
|
184
|
+
paymentNonce: string;
|
|
185
|
+
/** Fee breakdown reported by the gateway (registration vs data-access fee). */
|
|
186
|
+
breakdown: DirectFeeBreakdown;
|
|
187
|
+
/** ISO timestamp the gateway recorded the payment. */
|
|
188
|
+
paidAt: string;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Per-op fee breakdown reported by the gateway.
|
|
192
|
+
*
|
|
193
|
+
* @remarks
|
|
194
|
+
* Mirrors the escrow {@link PaymentBreakdown}: a one-time registration fee plus
|
|
195
|
+
* the per-read data-access fee, and whether this settlement covered the
|
|
196
|
+
* registration fee.
|
|
197
|
+
*/
|
|
198
|
+
export interface DirectFeeBreakdown {
|
|
199
|
+
/** One-time registration fee for the op, as a decimal base-unit string. */
|
|
200
|
+
registrationFee: string;
|
|
201
|
+
/** Per-read data-access fee, as a decimal base-unit string. */
|
|
202
|
+
dataAccessFee: string;
|
|
203
|
+
/** True when this settlement paid the registration fee. */
|
|
204
|
+
registrationPaid: boolean;
|
|
205
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const DirectOpType = {
|
|
2
|
+
GrantRegistration: "grant_registration",
|
|
3
|
+
DataAccess: "data_access",
|
|
4
|
+
DataRegistration: "data_registration",
|
|
5
|
+
ServerRegistration: "server_registration",
|
|
6
|
+
BuilderRegistration: "builder_registration"
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
DirectOpType
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/direct/types.ts"],"sourcesContent":["/**\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/testnet stack. Use only when testing against\n * Vana's dev infrastructure.\n */\nexport type DirectEnv = \"dev\" | \"production\";\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 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}\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 | \"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 `status === \"approved\"`. */\n personalServerUrl?: string;\n /** Grant id covering the approved scope — present once approved. */\n grantId?: string;\n /** The approved scope — present once approved. */\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, 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 }): 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/**\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 /** 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":"AAwJO,MAAM,eAAe;AAAA,EAC1B,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,qBAAqB;AACvB;","names":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var use_direct_vana_connect_exports = {};
|
|
20
|
+
__export(use_direct_vana_connect_exports, {
|
|
21
|
+
useDirectVanaConnect: () => useDirectVanaConnect
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(use_direct_vana_connect_exports);
|
|
24
|
+
var import_react = require("react");
|
|
25
|
+
var import_connect_flow = require("./connect-flow");
|
|
26
|
+
function useDirectVanaConnect(options) {
|
|
27
|
+
const optionsRef = (0, import_react.useRef)(options);
|
|
28
|
+
optionsRef.current = options;
|
|
29
|
+
const flow = (0, import_react.useMemo)(
|
|
30
|
+
() => (0, import_connect_flow.createDirectConnectFlow)(
|
|
31
|
+
{
|
|
32
|
+
createRequest: () => optionsRef.current.createRequest(),
|
|
33
|
+
getStatus: (id) => optionsRef.current.getStatus(id),
|
|
34
|
+
readResult: (id) => optionsRef.current.readResult(id)
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
get pollIntervalMs() {
|
|
38
|
+
return optionsRef.current.pollIntervalMs;
|
|
39
|
+
},
|
|
40
|
+
get timeoutMs() {
|
|
41
|
+
return optionsRef.current.timeoutMs;
|
|
42
|
+
},
|
|
43
|
+
get openWindow() {
|
|
44
|
+
return optionsRef.current.openWindow;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
),
|
|
48
|
+
// Created once per component instance; callbacks are read via optionsRef.
|
|
49
|
+
[]
|
|
50
|
+
);
|
|
51
|
+
const state = (0, import_react.useSyncExternalStore)(
|
|
52
|
+
flow.subscribe,
|
|
53
|
+
flow.getState,
|
|
54
|
+
flow.getState
|
|
55
|
+
);
|
|
56
|
+
const start = (0, import_react.useCallback)(() => {
|
|
57
|
+
void flow.start();
|
|
58
|
+
}, [flow]);
|
|
59
|
+
const reset = (0, import_react.useCallback)(() => {
|
|
60
|
+
flow.reset();
|
|
61
|
+
}, [flow]);
|
|
62
|
+
return { state, start, reset };
|
|
63
|
+
}
|
|
64
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
65
|
+
0 && (module.exports = {
|
|
66
|
+
useDirectVanaConnect
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=use-direct-vana-connect.cjs.map
|