@opendatalabs/vana-sdk 3.4.1 → 3.5.1-pr.159.12a6f39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +116 -0
  2. package/dist/account/personal-server-lite-owner-binding.cjs +3 -3
  3. package/dist/account/personal-server-lite-owner-binding.cjs.map +1 -1
  4. package/dist/account/personal-server-lite-owner-binding.d.ts +2 -2
  5. package/dist/account/personal-server-lite-owner-binding.js +1 -1
  6. package/dist/account/personal-server-lite-owner-binding.js.map +1 -1
  7. package/dist/direct/access-request-client.cjs +104 -0
  8. package/dist/direct/access-request-client.cjs.map +1 -0
  9. package/dist/direct/access-request-client.d.ts +51 -0
  10. package/dist/direct/access-request-client.js +79 -0
  11. package/dist/direct/access-request-client.js.map +1 -0
  12. package/dist/direct/access-request-client.test.d.ts +1 -0
  13. package/dist/direct/connect-flow.cjs +152 -0
  14. package/dist/direct/connect-flow.cjs.map +1 -0
  15. package/dist/direct/connect-flow.d.ts +85 -0
  16. package/dist/direct/connect-flow.js +128 -0
  17. package/dist/direct/connect-flow.js.map +1 -0
  18. package/dist/direct/connect-flow.test.d.ts +1 -0
  19. package/dist/direct/controller.cjs +129 -0
  20. package/dist/direct/controller.cjs.map +1 -0
  21. package/dist/direct/controller.d.ts +152 -0
  22. package/dist/direct/controller.js +109 -0
  23. package/dist/direct/controller.js.map +1 -0
  24. package/dist/direct/controller.test.d.ts +1 -0
  25. package/dist/direct/endpoints.cjs +45 -0
  26. package/dist/direct/endpoints.cjs.map +1 -0
  27. package/dist/direct/endpoints.d.ts +22 -0
  28. package/dist/direct/endpoints.js +19 -0
  29. package/dist/direct/endpoints.js.map +1 -0
  30. package/dist/direct/errors.cjs +65 -0
  31. package/dist/direct/errors.cjs.map +1 -0
  32. package/dist/direct/errors.d.ts +44 -0
  33. package/dist/direct/errors.js +38 -0
  34. package/dist/direct/errors.js.map +1 -0
  35. package/dist/direct/escrow-payment.cjs +96 -0
  36. package/dist/direct/escrow-payment.cjs.map +1 -0
  37. package/dist/direct/escrow-payment.d.ts +81 -0
  38. package/dist/direct/escrow-payment.js +72 -0
  39. package/dist/direct/escrow-payment.js.map +1 -0
  40. package/dist/direct/escrow-payment.test.d.ts +1 -0
  41. package/dist/direct/personal-server-read.cjs +149 -0
  42. package/dist/direct/personal-server-read.cjs.map +1 -0
  43. package/dist/direct/personal-server-read.d.ts +103 -0
  44. package/dist/direct/personal-server-read.js +124 -0
  45. package/dist/direct/personal-server-read.js.map +1 -0
  46. package/dist/direct/personal-server-read.test.d.ts +1 -0
  47. package/dist/direct/types.cjs +35 -0
  48. package/dist/direct/types.cjs.map +1 -0
  49. package/dist/direct/types.d.ts +205 -0
  50. package/dist/direct/types.js +11 -0
  51. package/dist/direct/types.js.map +1 -0
  52. package/dist/direct/use-direct-vana-connect.cjs +68 -0
  53. package/dist/direct/use-direct-vana-connect.cjs.map +1 -0
  54. package/dist/direct/use-direct-vana-connect.d.ts +45 -0
  55. package/dist/direct/use-direct-vana-connect.js +46 -0
  56. package/dist/direct/use-direct-vana-connect.js.map +1 -0
  57. package/dist/index.browser.d.ts +9 -4
  58. package/dist/index.browser.js +644 -178
  59. package/dist/index.browser.js.map +4 -4
  60. package/dist/index.node.cjs +672 -183
  61. package/dist/index.node.cjs.map +4 -4
  62. package/dist/index.node.d.ts +9 -4
  63. package/dist/index.node.js +644 -178
  64. package/dist/index.node.js.map +4 -4
  65. package/dist/personal-server-lite/owner-binding.cjs +93 -0
  66. package/dist/personal-server-lite/owner-binding.cjs.map +1 -0
  67. package/dist/personal-server-lite/owner-binding.d.ts +44 -0
  68. package/dist/personal-server-lite/owner-binding.js +65 -0
  69. package/dist/personal-server-lite/owner-binding.js.map +1 -0
  70. package/dist/personal-server-lite/owner-binding.test.d.ts +1 -0
  71. package/dist/protocol/data-point-status.cjs +80 -0
  72. package/dist/protocol/data-point-status.cjs.map +1 -0
  73. package/dist/protocol/data-point-status.d.ts +34 -0
  74. package/dist/protocol/data-point-status.js +51 -0
  75. package/dist/protocol/data-point-status.js.map +1 -0
  76. package/dist/protocol/data-point-status.test.d.ts +1 -0
  77. package/dist/protocol/eip712.cjs +53 -31
  78. package/dist/protocol/eip712.cjs.map +1 -1
  79. package/dist/protocol/eip712.d.ts +98 -43
  80. package/dist/protocol/eip712.js +47 -27
  81. package/dist/protocol/eip712.js.map +1 -1
  82. package/dist/protocol/escrow-deposit.cjs +89 -0
  83. package/dist/protocol/escrow-deposit.cjs.map +1 -0
  84. package/dist/protocol/escrow-deposit.d.ts +47 -0
  85. package/dist/protocol/escrow-deposit.js +60 -0
  86. package/dist/protocol/escrow-deposit.js.map +1 -0
  87. package/dist/protocol/escrow-deposit.test.d.ts +1 -0
  88. package/dist/protocol/escrow-flow.test.d.ts +21 -0
  89. package/dist/protocol/escrow.cjs +146 -0
  90. package/dist/protocol/escrow.cjs.map +1 -0
  91. package/dist/protocol/escrow.d.ts +336 -0
  92. package/dist/protocol/escrow.js +118 -0
  93. package/dist/protocol/escrow.js.map +1 -0
  94. package/dist/protocol/escrow.test.d.ts +1 -0
  95. package/dist/protocol/fee-registry.cjs +116 -0
  96. package/dist/protocol/fee-registry.cjs.map +1 -0
  97. package/dist/protocol/fee-registry.d.ts +151 -0
  98. package/dist/protocol/fee-registry.js +89 -0
  99. package/dist/protocol/fee-registry.js.map +1 -0
  100. package/dist/protocol/fee-registry.test.d.ts +1 -0
  101. package/dist/protocol/gateway.cjs +107 -37
  102. package/dist/protocol/gateway.cjs.map +1 -1
  103. package/dist/protocol/gateway.d.ts +223 -57
  104. package/dist/protocol/gateway.js +107 -37
  105. package/dist/protocol/gateway.js.map +1 -1
  106. package/dist/protocol/grants.cjs +27 -64
  107. package/dist/protocol/grants.cjs.map +1 -1
  108. package/dist/protocol/grants.d.ts +6 -13
  109. package/dist/protocol/grants.js +27 -63
  110. package/dist/protocol/grants.js.map +1 -1
  111. package/dist/protocol/personal-server-data.cjs +71 -0
  112. package/dist/protocol/personal-server-data.cjs.map +1 -0
  113. package/dist/protocol/personal-server-data.d.ts +16 -0
  114. package/dist/protocol/personal-server-data.js +47 -0
  115. package/dist/protocol/personal-server-data.js.map +1 -0
  116. package/dist/protocol/personal-server-data.test.d.ts +1 -0
  117. package/dist/protocol/personal-server-registration.cjs +16 -4
  118. package/dist/protocol/personal-server-registration.cjs.map +1 -1
  119. package/dist/protocol/personal-server-registration.d.ts +5 -2
  120. package/dist/protocol/personal-server-registration.js +16 -4
  121. package/dist/protocol/personal-server-registration.js.map +1 -1
  122. package/dist/react.cjs +32 -0
  123. package/dist/react.cjs.map +1 -0
  124. package/dist/react.d.ts +33 -0
  125. package/dist/react.js +11 -0
  126. package/dist/react.js.map +1 -0
  127. package/dist/server.cjs +73 -0
  128. package/dist/server.cjs.map +1 -0
  129. package/dist/server.d.ts +32 -0
  130. package/dist/server.js +55 -0
  131. package/dist/server.js.map +1 -0
  132. package/dist/storage/providers/vana-storage.cjs +75 -17
  133. package/dist/storage/providers/vana-storage.cjs.map +1 -1
  134. package/dist/storage/providers/vana-storage.js +75 -17
  135. package/dist/storage/providers/vana-storage.js.map +1 -1
  136. package/package.json +20 -1
@@ -0,0 +1,146 @@
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 escrow_exports = {};
20
+ __export(escrow_exports, {
21
+ ESCROW_DEPOSIT_ABI: () => ESCROW_DEPOSIT_ABI,
22
+ GENERIC_PAYMENT_TYPES: () => GENERIC_PAYMENT_TYPES,
23
+ NATIVE_ASSET_ADDRESS: () => NATIVE_ASSET_ADDRESS,
24
+ createEscrowGatewayClient: () => createEscrowGatewayClient,
25
+ genericPaymentDomain: () => genericPaymentDomain
26
+ });
27
+ module.exports = __toCommonJS(escrow_exports);
28
+ const GENERIC_PAYMENT_TYPES = {
29
+ GenericPayment: [
30
+ { name: "payerAddress", type: "address" },
31
+ { name: "opType", type: "string" },
32
+ { name: "opId", type: "bytes32" },
33
+ { name: "asset", type: "address" },
34
+ { name: "amount", type: "uint256" },
35
+ { name: "paymentNonce", type: "uint256" }
36
+ ]
37
+ };
38
+ function genericPaymentDomain(chainId, escrowContract) {
39
+ return {
40
+ name: "Vana Data Portability",
41
+ version: "1",
42
+ chainId,
43
+ verifyingContract: escrowContract
44
+ };
45
+ }
46
+ const ESCROW_DEPOSIT_ABI = [
47
+ {
48
+ type: "function",
49
+ name: "depositNative",
50
+ stateMutability: "payable",
51
+ inputs: [{ name: "account", type: "address" }],
52
+ outputs: []
53
+ },
54
+ {
55
+ type: "function",
56
+ name: "depositToken",
57
+ stateMutability: "nonpayable",
58
+ inputs: [
59
+ { name: "account", type: "address" },
60
+ { name: "token", type: "address" },
61
+ { name: "amount", type: "uint256" }
62
+ ],
63
+ outputs: []
64
+ }
65
+ ];
66
+ const NATIVE_ASSET_ADDRESS = "0x0000000000000000000000000000000000000000";
67
+ function createEscrowGatewayClient(baseUrl) {
68
+ const base = baseUrl.replace(/\/+$/, "");
69
+ async function throwOnError(res, context) {
70
+ if (!res.ok) {
71
+ let detail = "";
72
+ try {
73
+ const body = await res.json();
74
+ if (body.error) detail = `: ${body.error}`;
75
+ } catch {
76
+ }
77
+ throw new Error(
78
+ `Escrow gateway error (${context}): ${res.status} ${res.statusText}${detail}`
79
+ );
80
+ }
81
+ }
82
+ return {
83
+ async submitDeposit({ txHash }) {
84
+ const res = await fetch(`${base}/v1/escrow/deposit`, {
85
+ method: "POST",
86
+ headers: { "Content-Type": "application/json" },
87
+ body: JSON.stringify({ txHash })
88
+ });
89
+ if (res.status !== 200 && res.status !== 202) {
90
+ await throwOnError(res, "POST /v1/escrow/deposit");
91
+ }
92
+ return res.json();
93
+ },
94
+ async getEscrowBalance(account) {
95
+ const res = await fetch(
96
+ `${base}/v1/escrow/balance?account=${encodeURIComponent(account)}`
97
+ );
98
+ await throwOnError(res, "GET /v1/escrow/balance");
99
+ return res.json();
100
+ },
101
+ async syncEscrowBalance(account) {
102
+ const res = await fetch(
103
+ `${base}/v1/escrow/balance/sync?account=${encodeURIComponent(account)}`,
104
+ { method: "POST" }
105
+ );
106
+ await throwOnError(res, "POST /v1/escrow/balance/sync");
107
+ return res.json();
108
+ },
109
+ async payForOp({
110
+ payerAddress,
111
+ opType,
112
+ opId,
113
+ asset,
114
+ amount,
115
+ paymentNonce,
116
+ signature
117
+ }) {
118
+ const res = await fetch(`${base}/v1/escrow/pay`, {
119
+ method: "POST",
120
+ headers: {
121
+ "Content-Type": "application/json",
122
+ Authorization: `Web3Signed ${signature}`
123
+ },
124
+ body: JSON.stringify({
125
+ payerAddress,
126
+ opType,
127
+ opId,
128
+ asset,
129
+ amount,
130
+ paymentNonce
131
+ })
132
+ });
133
+ await throwOnError(res, "POST /v1/escrow/pay");
134
+ return res.json();
135
+ }
136
+ };
137
+ }
138
+ // Annotate the CommonJS export names for ESM import in node:
139
+ 0 && (module.exports = {
140
+ ESCROW_DEPOSIT_ABI,
141
+ GENERIC_PAYMENT_TYPES,
142
+ NATIVE_ASSET_ADDRESS,
143
+ createEscrowGatewayClient,
144
+ genericPaymentDomain
145
+ });
146
+ //# sourceMappingURL=escrow.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/protocol/escrow.ts"],"sourcesContent":["/**\n * DPv2 escrow payment helpers.\n *\n * Covers the three-phase flow used by builders to pay for data access:\n *\n * 1. **Deposit** — call `depositNative` or `depositToken` on the\n * DataPortabilityEscrow contract, then notify the gateway.\n * 2. **Balance** — read or force-sync the gateway's off-chain credit view.\n * 3. **Pay** — sign a `GenericPayment` EIP-712 message and POST it to the\n * gateway's `/v1/escrow/pay` endpoint.\n *\n * The gateway is the authority on balances; the on-chain contract is the\n * authority on what has been settled. Nothing in this module touches the\n * chain directly — signing is done by the caller's wallet.\n *\n * @category Protocol\n * @module escrow\n */\n\nimport type { TypedDataDomain } from \"viem\";\n\n// ---------------------------------------------------------------------------\n// EIP-712 — GenericPayment\n// ---------------------------------------------------------------------------\n\n/**\n * EIP-712 typed-data types for a generic op payment.\n *\n * The gateway verifies that the recovered signer == `payerAddress` and that\n * the (payer, paymentNonce) pair has not been seen before. Use a\n * monotonically-increasing nonce; the first payment for any payer should\n * start at 1.\n */\nexport const GENERIC_PAYMENT_TYPES = {\n GenericPayment: [\n { name: \"payerAddress\", type: \"address\" },\n { name: \"opType\", type: \"string\" },\n { name: \"opId\", type: \"bytes32\" },\n { name: \"asset\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n { name: \"paymentNonce\", type: \"uint256\" },\n ],\n} as const;\n\n/**\n * EIP-712 message payload for a generic op payment.\n *\n * - `opType` is currently `\"grant\"`. Additional types (file, builder, schema)\n * may be added in future protocol versions.\n * - `opId` is the bytes32 id of the operation being paid for (e.g. `grantId`).\n * - `asset` is the ERC-20 token address, or the zero address for native VANA.\n * - `amount` is the total amount in base units (wei for VANA). Must match the\n * sum the gateway expects for the current lifecycle of the op.\n * - `paymentNonce` must be a positive integer unique per `payerAddress`. Use 1\n * for the first payment; increment by at least 1 for each subsequent call.\n */\nexport interface GenericPaymentMessage {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: bigint;\n paymentNonce: bigint;\n}\n\n/**\n * Returns the EIP-712 domain for signing a `GenericPayment` message.\n *\n * The verifying contract is the `DataPortabilityEscrow` contract; all gateway\n * deployments share the same domain name and version.\n *\n * @param chainId - Chain ID of the Vana network (e.g. 1480 mainnet, 14800 testnet).\n * @param escrowContract - Deployed address of DataPortabilityEscrow.\n */\nexport function genericPaymentDomain(\n chainId: number,\n escrowContract: `0x${string}`,\n): TypedDataDomain {\n return {\n name: \"Vana Data Portability\",\n version: \"1\",\n chainId,\n verifyingContract: escrowContract,\n };\n}\n\n// ---------------------------------------------------------------------------\n// On-chain deposit ABI fragments\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal ABI for the two deposit entry points on `DataPortabilityEscrow`.\n *\n * - `depositNative(address account)` payable — credits native VANA.\n * - `depositToken(address account, address token, uint256 amount)` — credits\n * an ERC-20 token (caller must have pre-approved the escrow contract).\n *\n * Pass this to viem's `writeContract` or encode it manually.\n */\nexport const ESCROW_DEPOSIT_ABI = [\n {\n type: \"function\",\n name: \"depositNative\",\n stateMutability: \"payable\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"depositToken\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"account\", type: \"address\" },\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [],\n },\n] as const;\n\n/**\n * The zero address used by the DataPortabilityEscrow contract to represent\n * native VANA in `asset` fields of events and balance responses.\n */\nexport const NATIVE_ASSET_ADDRESS =\n \"0x0000000000000000000000000000000000000000\" as const;\n\n// ---------------------------------------------------------------------------\n// Gateway API client\n// ---------------------------------------------------------------------------\n\n/**\n * Per-asset balance entry returned by the gateway's escrow balance endpoints.\n *\n * - `balance` — gross finalized credit (deposits credited so far).\n * - `pendingAmount` — sum of submitted deposits not yet confirmed.\n * - `authorizedAmount` — sum of all in-flight payments authorized by\n * `/v1/escrow/pay` (soft-lock). May include payments not yet settled\n * on-chain.\n * - `availableAmount` — `max(balance − authorizedAmount, 0)`. This is what\n * the payer can authorize before the gateway rejects with 402.\n */\nexport interface EscrowBalanceEntry {\n asset: string;\n balance: string;\n pendingAmount: string;\n authorizedAmount: string;\n availableAmount: string;\n updatedAt: string | null;\n}\n\nexport interface SubmittedDepositEntry {\n txHash: string;\n submittedAt: string;\n claimedAsset: string;\n claimedAmount: string;\n}\n\nexport interface FinalizedDepositEntry {\n txHash: string;\n finalizedAt: string | null;\n blockNumber: string | null;\n claimedAsset: string;\n claimedAmount: string;\n}\n\nexport interface FailedDepositEntry {\n txHash: string;\n submittedAt: string;\n claimedAsset: string;\n claimedAmount: string;\n lastError: string | null;\n}\n\n/** Full balance read response from `GET /v1/escrow/balance`. */\nexport interface EscrowBalanceResult {\n account: string;\n balances: EscrowBalanceEntry[];\n deposits: {\n submitted: SubmittedDepositEntry[];\n finalized: FinalizedDepositEntry[];\n failed: FailedDepositEntry[];\n };\n}\n\n/**\n * Response from `POST /v1/escrow/balance/sync`.\n *\n * Extends {@link EscrowBalanceResult} with a `sync` summary of what the\n * lazy-confirmation pass did.\n */\nexport interface EscrowBalanceSyncResult extends EscrowBalanceResult {\n sync:\n | { scanned: number; finalized: number; stillPending: number; failed: number }\n | { skipped: true };\n}\n\n/** Response from `POST /v1/escrow/deposit`. */\nexport interface DepositSubmissionResult {\n success: true;\n txHash: string;\n account: string;\n status: \"submitted\" | \"finalized\" | \"failed\";\n blockNumber?: string | null;\n submittedAt: string;\n finalizedAt?: string | null;\n lastError?: string | null;\n}\n\n/** Breakdown returned by a successful `POST /v1/escrow/pay`. */\nexport interface PaymentBreakdown {\n registrationFee: string;\n dataAccessFee: string;\n /** True when this call settled the registration fee for the op. */\n registrationPaid: boolean;\n}\n\n/** Response from `POST /v1/escrow/pay`. */\nexport interface EscrowPayResult {\n success: true;\n opType: string;\n opId: string;\n payerAddress: string;\n asset: string;\n amount: string;\n breakdown: PaymentBreakdown;\n paymentNonce: string;\n paidAt: string;\n}\n\n/**\n * Parameters for submitting a deposit tx hash to the gateway.\n *\n * The gateway will decode the `account` from the tx's calldata and\n * credit the identified account once the tx reaches the configured\n * confirmation depth.\n */\nexport interface SubmitDepositParams {\n /** 0x-prefixed 32-byte transaction hash. */\n txHash: `0x${string}`;\n}\n\n/**\n * Parameters for the generic op payment endpoint (`POST /v1/escrow/pay`).\n *\n * The `signature` is an EIP-712 signature over a `GenericPayment` message\n * (see {@link GENERIC_PAYMENT_TYPES} and {@link genericPaymentDomain}).\n * Build and sign the typed data with your wallet before calling\n * {@link EscrowGatewayClient.payForOp}.\n */\nexport interface PayForOpParams {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n /** Decimal string representation of the uint256 amount. */\n amount: string;\n /** Decimal string representation of the uint256 nonce. */\n paymentNonce: string;\n /** 0x-prefixed 65-byte EIP-712 signature hex string. */\n signature: `0x${string}`;\n}\n\n/**\n * Minimal client for the gateway's escrow endpoints.\n *\n * Construct with {@link createEscrowGatewayClient}.\n */\nexport interface EscrowGatewayClient {\n /**\n * Notify the gateway of a submitted deposit transaction.\n *\n * The gateway decodes the credited account from the on-chain tx calldata\n * and starts tracking the deposit. Call this immediately after your\n * `depositNative` or `depositToken` tx is broadcast (it accepts pending\n * mempool txs). Returns `202` while the tx awaits confirmation.\n */\n submitDeposit(params: SubmitDepositParams): Promise<DepositSubmissionResult>;\n\n /**\n * Read the current escrow balance for an account.\n *\n * Pure read — no chain calls. To force a reconciliation pass first,\n * use {@link syncEscrowBalance}.\n */\n getEscrowBalance(account: `0x${string}`): Promise<EscrowBalanceResult>;\n\n /**\n * Force a reconciliation pass then return the updated balance.\n *\n * Triggers the gateway's lazy-confirmation worker for the account — any\n * submitted deposits that have reached the configured confirmation level\n * are credited before the balance is returned. Prefer this over\n * {@link getEscrowBalance} when you need a fresh view after a deposit.\n */\n syncEscrowBalance(account: `0x${string}`): Promise<EscrowBalanceSyncResult>;\n\n /**\n * Authorize a payment against the payer's escrow balance.\n *\n * The caller must:\n * 1. Assemble a {@link GenericPaymentMessage}.\n * 2. Sign it with `signTypedData` using {@link GENERIC_PAYMENT_TYPES} and\n * the domain from {@link genericPaymentDomain}.\n * 3. Pass the message fields + signature here.\n *\n * The gateway verifies the signature, checks the soft-lock balance, and\n * records the payment. Returns 402 if the payer has insufficient balance.\n */\n payForOp(params: PayForOpParams): Promise<EscrowPayResult>;\n}\n\n/**\n * Creates a client for the gateway escrow endpoints.\n *\n * @param baseUrl - Base URL of the DP RPC gateway\n * (e.g. `\"https://dp.vana.org\"`). Trailing slashes are trimmed.\n *\n * @example\n * ```typescript\n * import {\n * createEscrowGatewayClient,\n * genericPaymentDomain,\n * GENERIC_PAYMENT_TYPES,\n * } from \"@opendatalabs/vana-sdk/node\";\n *\n * const escrow = createEscrowGatewayClient(\"https://dp.vana.org\");\n *\n * // 1. Submit your deposit tx hash after broadcasting depositNative on-chain\n * const deposit = await escrow.submitDeposit({ txHash: \"0xabc…\" });\n *\n * // 2. Force-sync and read the updated balance\n * const { balances } = await escrow.syncEscrowBalance(\"0xpayerAddress\");\n *\n * // 3. Sign and authorize a grant payment\n * const sig = await walletClient.signTypedData({\n * domain: genericPaymentDomain(1480, \"0xEscrowContract\"),\n * types: GENERIC_PAYMENT_TYPES,\n * primaryType: \"GenericPayment\",\n * message: {\n * payerAddress: \"0xpayerAddress\",\n * opType: \"grant\",\n * opId: \"0xgrantId\",\n * asset: \"0x0000000000000000000000000000000000000000\",\n * amount: 1000000000000000000n,\n * paymentNonce: 1n,\n * },\n * });\n * const result = await escrow.payForOp({\n * payerAddress: \"0xpayerAddress\",\n * opType: \"grant\",\n * opId: \"0xgrantId\",\n * asset: \"0x0000000000000000000000000000000000000000\",\n * amount: \"1000000000000000000\",\n * paymentNonce: \"1\",\n * signature: sig,\n * });\n * ```\n */\nexport function createEscrowGatewayClient(\n baseUrl: string,\n): EscrowGatewayClient {\n const base = baseUrl.replace(/\\/+$/, \"\");\n\n async function throwOnError(res: Response, context: string): Promise<void> {\n if (!res.ok) {\n let detail = \"\";\n try {\n const body = (await res.json()) as { error?: string };\n if (body.error) detail = `: ${body.error}`;\n } catch {\n // Ignore JSON parse errors; use status text only.\n }\n throw new Error(\n `Escrow gateway error (${context}): ${res.status} ${res.statusText}${detail}`,\n );\n }\n }\n\n return {\n async submitDeposit({ txHash }) {\n const res = await fetch(`${base}/v1/escrow/deposit`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ txHash }),\n });\n // 202 Accepted and 200 OK are both success states for deposit submission.\n if (res.status !== 200 && res.status !== 202) {\n await throwOnError(res, \"POST /v1/escrow/deposit\");\n }\n return res.json() as Promise<DepositSubmissionResult>;\n },\n\n async getEscrowBalance(account) {\n const res = await fetch(\n `${base}/v1/escrow/balance?account=${encodeURIComponent(account)}`,\n );\n await throwOnError(res, \"GET /v1/escrow/balance\");\n return res.json() as Promise<EscrowBalanceResult>;\n },\n\n async syncEscrowBalance(account) {\n const res = await fetch(\n `${base}/v1/escrow/balance/sync?account=${encodeURIComponent(account)}`,\n { method: \"POST\" },\n );\n await throwOnError(res, \"POST /v1/escrow/balance/sync\");\n return res.json() as Promise<EscrowBalanceSyncResult>;\n },\n\n async payForOp({\n payerAddress,\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n signature,\n }) {\n const res = await fetch(`${base}/v1/escrow/pay`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${signature}`,\n },\n body: JSON.stringify({\n payerAddress,\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n }),\n });\n await throwOnError(res, \"POST /v1/escrow/pay\");\n return res.json() as Promise<EscrowPayResult>;\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,336 @@
1
+ /**
2
+ * DPv2 escrow payment helpers.
3
+ *
4
+ * Covers the three-phase flow used by builders to pay for data access:
5
+ *
6
+ * 1. **Deposit** — call `depositNative` or `depositToken` on the
7
+ * DataPortabilityEscrow contract, then notify the gateway.
8
+ * 2. **Balance** — read or force-sync the gateway's off-chain credit view.
9
+ * 3. **Pay** — sign a `GenericPayment` EIP-712 message and POST it to the
10
+ * gateway's `/v1/escrow/pay` endpoint.
11
+ *
12
+ * The gateway is the authority on balances; the on-chain contract is the
13
+ * authority on what has been settled. Nothing in this module touches the
14
+ * chain directly — signing is done by the caller's wallet.
15
+ *
16
+ * @category Protocol
17
+ * @module escrow
18
+ */
19
+ import type { TypedDataDomain } from "viem";
20
+ /**
21
+ * EIP-712 typed-data types for a generic op payment.
22
+ *
23
+ * The gateway verifies that the recovered signer == `payerAddress` and that
24
+ * the (payer, paymentNonce) pair has not been seen before. Use a
25
+ * monotonically-increasing nonce; the first payment for any payer should
26
+ * start at 1.
27
+ */
28
+ export declare const GENERIC_PAYMENT_TYPES: {
29
+ readonly GenericPayment: readonly [{
30
+ readonly name: "payerAddress";
31
+ readonly type: "address";
32
+ }, {
33
+ readonly name: "opType";
34
+ readonly type: "string";
35
+ }, {
36
+ readonly name: "opId";
37
+ readonly type: "bytes32";
38
+ }, {
39
+ readonly name: "asset";
40
+ readonly type: "address";
41
+ }, {
42
+ readonly name: "amount";
43
+ readonly type: "uint256";
44
+ }, {
45
+ readonly name: "paymentNonce";
46
+ readonly type: "uint256";
47
+ }];
48
+ };
49
+ /**
50
+ * EIP-712 message payload for a generic op payment.
51
+ *
52
+ * - `opType` is currently `"grant"`. Additional types (file, builder, schema)
53
+ * may be added in future protocol versions.
54
+ * - `opId` is the bytes32 id of the operation being paid for (e.g. `grantId`).
55
+ * - `asset` is the ERC-20 token address, or the zero address for native VANA.
56
+ * - `amount` is the total amount in base units (wei for VANA). Must match the
57
+ * sum the gateway expects for the current lifecycle of the op.
58
+ * - `paymentNonce` must be a positive integer unique per `payerAddress`. Use 1
59
+ * for the first payment; increment by at least 1 for each subsequent call.
60
+ */
61
+ export interface GenericPaymentMessage {
62
+ payerAddress: `0x${string}`;
63
+ opType: string;
64
+ opId: `0x${string}`;
65
+ asset: `0x${string}`;
66
+ amount: bigint;
67
+ paymentNonce: bigint;
68
+ }
69
+ /**
70
+ * Returns the EIP-712 domain for signing a `GenericPayment` message.
71
+ *
72
+ * The verifying contract is the `DataPortabilityEscrow` contract; all gateway
73
+ * deployments share the same domain name and version.
74
+ *
75
+ * @param chainId - Chain ID of the Vana network (e.g. 1480 mainnet, 14800 testnet).
76
+ * @param escrowContract - Deployed address of DataPortabilityEscrow.
77
+ */
78
+ export declare function genericPaymentDomain(chainId: number, escrowContract: `0x${string}`): TypedDataDomain;
79
+ /**
80
+ * Minimal ABI for the two deposit entry points on `DataPortabilityEscrow`.
81
+ *
82
+ * - `depositNative(address account)` payable — credits native VANA.
83
+ * - `depositToken(address account, address token, uint256 amount)` — credits
84
+ * an ERC-20 token (caller must have pre-approved the escrow contract).
85
+ *
86
+ * Pass this to viem's `writeContract` or encode it manually.
87
+ */
88
+ export declare const ESCROW_DEPOSIT_ABI: readonly [{
89
+ readonly type: "function";
90
+ readonly name: "depositNative";
91
+ readonly stateMutability: "payable";
92
+ readonly inputs: readonly [{
93
+ readonly name: "account";
94
+ readonly type: "address";
95
+ }];
96
+ readonly outputs: readonly [];
97
+ }, {
98
+ readonly type: "function";
99
+ readonly name: "depositToken";
100
+ readonly stateMutability: "nonpayable";
101
+ readonly inputs: readonly [{
102
+ readonly name: "account";
103
+ readonly type: "address";
104
+ }, {
105
+ readonly name: "token";
106
+ readonly type: "address";
107
+ }, {
108
+ readonly name: "amount";
109
+ readonly type: "uint256";
110
+ }];
111
+ readonly outputs: readonly [];
112
+ }];
113
+ /**
114
+ * The zero address used by the DataPortabilityEscrow contract to represent
115
+ * native VANA in `asset` fields of events and balance responses.
116
+ */
117
+ export declare const NATIVE_ASSET_ADDRESS: "0x0000000000000000000000000000000000000000";
118
+ /**
119
+ * Per-asset balance entry returned by the gateway's escrow balance endpoints.
120
+ *
121
+ * - `balance` — gross finalized credit (deposits credited so far).
122
+ * - `pendingAmount` — sum of submitted deposits not yet confirmed.
123
+ * - `authorizedAmount` — sum of all in-flight payments authorized by
124
+ * `/v1/escrow/pay` (soft-lock). May include payments not yet settled
125
+ * on-chain.
126
+ * - `availableAmount` — `max(balance − authorizedAmount, 0)`. This is what
127
+ * the payer can authorize before the gateway rejects with 402.
128
+ */
129
+ export interface EscrowBalanceEntry {
130
+ asset: string;
131
+ balance: string;
132
+ pendingAmount: string;
133
+ authorizedAmount: string;
134
+ availableAmount: string;
135
+ updatedAt: string | null;
136
+ }
137
+ export interface SubmittedDepositEntry {
138
+ txHash: string;
139
+ submittedAt: string;
140
+ claimedAsset: string;
141
+ claimedAmount: string;
142
+ }
143
+ export interface FinalizedDepositEntry {
144
+ txHash: string;
145
+ finalizedAt: string | null;
146
+ blockNumber: string | null;
147
+ claimedAsset: string;
148
+ claimedAmount: string;
149
+ }
150
+ export interface FailedDepositEntry {
151
+ txHash: string;
152
+ submittedAt: string;
153
+ claimedAsset: string;
154
+ claimedAmount: string;
155
+ lastError: string | null;
156
+ }
157
+ /** Full balance read response from `GET /v1/escrow/balance`. */
158
+ export interface EscrowBalanceResult {
159
+ account: string;
160
+ balances: EscrowBalanceEntry[];
161
+ deposits: {
162
+ submitted: SubmittedDepositEntry[];
163
+ finalized: FinalizedDepositEntry[];
164
+ failed: FailedDepositEntry[];
165
+ };
166
+ }
167
+ /**
168
+ * Response from `POST /v1/escrow/balance/sync`.
169
+ *
170
+ * Extends {@link EscrowBalanceResult} with a `sync` summary of what the
171
+ * lazy-confirmation pass did.
172
+ */
173
+ export interface EscrowBalanceSyncResult extends EscrowBalanceResult {
174
+ sync: {
175
+ scanned: number;
176
+ finalized: number;
177
+ stillPending: number;
178
+ failed: number;
179
+ } | {
180
+ skipped: true;
181
+ };
182
+ }
183
+ /** Response from `POST /v1/escrow/deposit`. */
184
+ export interface DepositSubmissionResult {
185
+ success: true;
186
+ txHash: string;
187
+ account: string;
188
+ status: "submitted" | "finalized" | "failed";
189
+ blockNumber?: string | null;
190
+ submittedAt: string;
191
+ finalizedAt?: string | null;
192
+ lastError?: string | null;
193
+ }
194
+ /** Breakdown returned by a successful `POST /v1/escrow/pay`. */
195
+ export interface PaymentBreakdown {
196
+ registrationFee: string;
197
+ dataAccessFee: string;
198
+ /** True when this call settled the registration fee for the op. */
199
+ registrationPaid: boolean;
200
+ }
201
+ /** Response from `POST /v1/escrow/pay`. */
202
+ export interface EscrowPayResult {
203
+ success: true;
204
+ opType: string;
205
+ opId: string;
206
+ payerAddress: string;
207
+ asset: string;
208
+ amount: string;
209
+ breakdown: PaymentBreakdown;
210
+ paymentNonce: string;
211
+ paidAt: string;
212
+ }
213
+ /**
214
+ * Parameters for submitting a deposit tx hash to the gateway.
215
+ *
216
+ * The gateway will decode the `account` from the tx's calldata and
217
+ * credit the identified account once the tx reaches the configured
218
+ * confirmation depth.
219
+ */
220
+ export interface SubmitDepositParams {
221
+ /** 0x-prefixed 32-byte transaction hash. */
222
+ txHash: `0x${string}`;
223
+ }
224
+ /**
225
+ * Parameters for the generic op payment endpoint (`POST /v1/escrow/pay`).
226
+ *
227
+ * The `signature` is an EIP-712 signature over a `GenericPayment` message
228
+ * (see {@link GENERIC_PAYMENT_TYPES} and {@link genericPaymentDomain}).
229
+ * Build and sign the typed data with your wallet before calling
230
+ * {@link EscrowGatewayClient.payForOp}.
231
+ */
232
+ export interface PayForOpParams {
233
+ payerAddress: `0x${string}`;
234
+ opType: string;
235
+ opId: `0x${string}`;
236
+ asset: `0x${string}`;
237
+ /** Decimal string representation of the uint256 amount. */
238
+ amount: string;
239
+ /** Decimal string representation of the uint256 nonce. */
240
+ paymentNonce: string;
241
+ /** 0x-prefixed 65-byte EIP-712 signature hex string. */
242
+ signature: `0x${string}`;
243
+ }
244
+ /**
245
+ * Minimal client for the gateway's escrow endpoints.
246
+ *
247
+ * Construct with {@link createEscrowGatewayClient}.
248
+ */
249
+ export interface EscrowGatewayClient {
250
+ /**
251
+ * Notify the gateway of a submitted deposit transaction.
252
+ *
253
+ * The gateway decodes the credited account from the on-chain tx calldata
254
+ * and starts tracking the deposit. Call this immediately after your
255
+ * `depositNative` or `depositToken` tx is broadcast (it accepts pending
256
+ * mempool txs). Returns `202` while the tx awaits confirmation.
257
+ */
258
+ submitDeposit(params: SubmitDepositParams): Promise<DepositSubmissionResult>;
259
+ /**
260
+ * Read the current escrow balance for an account.
261
+ *
262
+ * Pure read — no chain calls. To force a reconciliation pass first,
263
+ * use {@link syncEscrowBalance}.
264
+ */
265
+ getEscrowBalance(account: `0x${string}`): Promise<EscrowBalanceResult>;
266
+ /**
267
+ * Force a reconciliation pass then return the updated balance.
268
+ *
269
+ * Triggers the gateway's lazy-confirmation worker for the account — any
270
+ * submitted deposits that have reached the configured confirmation level
271
+ * are credited before the balance is returned. Prefer this over
272
+ * {@link getEscrowBalance} when you need a fresh view after a deposit.
273
+ */
274
+ syncEscrowBalance(account: `0x${string}`): Promise<EscrowBalanceSyncResult>;
275
+ /**
276
+ * Authorize a payment against the payer's escrow balance.
277
+ *
278
+ * The caller must:
279
+ * 1. Assemble a {@link GenericPaymentMessage}.
280
+ * 2. Sign it with `signTypedData` using {@link GENERIC_PAYMENT_TYPES} and
281
+ * the domain from {@link genericPaymentDomain}.
282
+ * 3. Pass the message fields + signature here.
283
+ *
284
+ * The gateway verifies the signature, checks the soft-lock balance, and
285
+ * records the payment. Returns 402 if the payer has insufficient balance.
286
+ */
287
+ payForOp(params: PayForOpParams): Promise<EscrowPayResult>;
288
+ }
289
+ /**
290
+ * Creates a client for the gateway escrow endpoints.
291
+ *
292
+ * @param baseUrl - Base URL of the DP RPC gateway
293
+ * (e.g. `"https://dp.vana.org"`). Trailing slashes are trimmed.
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * import {
298
+ * createEscrowGatewayClient,
299
+ * genericPaymentDomain,
300
+ * GENERIC_PAYMENT_TYPES,
301
+ * } from "@opendatalabs/vana-sdk/node";
302
+ *
303
+ * const escrow = createEscrowGatewayClient("https://dp.vana.org");
304
+ *
305
+ * // 1. Submit your deposit tx hash after broadcasting depositNative on-chain
306
+ * const deposit = await escrow.submitDeposit({ txHash: "0xabc…" });
307
+ *
308
+ * // 2. Force-sync and read the updated balance
309
+ * const { balances } = await escrow.syncEscrowBalance("0xpayerAddress");
310
+ *
311
+ * // 3. Sign and authorize a grant payment
312
+ * const sig = await walletClient.signTypedData({
313
+ * domain: genericPaymentDomain(1480, "0xEscrowContract"),
314
+ * types: GENERIC_PAYMENT_TYPES,
315
+ * primaryType: "GenericPayment",
316
+ * message: {
317
+ * payerAddress: "0xpayerAddress",
318
+ * opType: "grant",
319
+ * opId: "0xgrantId",
320
+ * asset: "0x0000000000000000000000000000000000000000",
321
+ * amount: 1000000000000000000n,
322
+ * paymentNonce: 1n,
323
+ * },
324
+ * });
325
+ * const result = await escrow.payForOp({
326
+ * payerAddress: "0xpayerAddress",
327
+ * opType: "grant",
328
+ * opId: "0xgrantId",
329
+ * asset: "0x0000000000000000000000000000000000000000",
330
+ * amount: "1000000000000000000",
331
+ * paymentNonce: "1",
332
+ * signature: sig,
333
+ * });
334
+ * ```
335
+ */
336
+ export declare function createEscrowGatewayClient(baseUrl: string): EscrowGatewayClient;
@@ -0,0 +1,118 @@
1
+ const GENERIC_PAYMENT_TYPES = {
2
+ GenericPayment: [
3
+ { name: "payerAddress", type: "address" },
4
+ { name: "opType", type: "string" },
5
+ { name: "opId", type: "bytes32" },
6
+ { name: "asset", type: "address" },
7
+ { name: "amount", type: "uint256" },
8
+ { name: "paymentNonce", type: "uint256" }
9
+ ]
10
+ };
11
+ function genericPaymentDomain(chainId, escrowContract) {
12
+ return {
13
+ name: "Vana Data Portability",
14
+ version: "1",
15
+ chainId,
16
+ verifyingContract: escrowContract
17
+ };
18
+ }
19
+ const ESCROW_DEPOSIT_ABI = [
20
+ {
21
+ type: "function",
22
+ name: "depositNative",
23
+ stateMutability: "payable",
24
+ inputs: [{ name: "account", type: "address" }],
25
+ outputs: []
26
+ },
27
+ {
28
+ type: "function",
29
+ name: "depositToken",
30
+ stateMutability: "nonpayable",
31
+ inputs: [
32
+ { name: "account", type: "address" },
33
+ { name: "token", type: "address" },
34
+ { name: "amount", type: "uint256" }
35
+ ],
36
+ outputs: []
37
+ }
38
+ ];
39
+ const NATIVE_ASSET_ADDRESS = "0x0000000000000000000000000000000000000000";
40
+ function createEscrowGatewayClient(baseUrl) {
41
+ const base = baseUrl.replace(/\/+$/, "");
42
+ async function throwOnError(res, context) {
43
+ if (!res.ok) {
44
+ let detail = "";
45
+ try {
46
+ const body = await res.json();
47
+ if (body.error) detail = `: ${body.error}`;
48
+ } catch {
49
+ }
50
+ throw new Error(
51
+ `Escrow gateway error (${context}): ${res.status} ${res.statusText}${detail}`
52
+ );
53
+ }
54
+ }
55
+ return {
56
+ async submitDeposit({ txHash }) {
57
+ const res = await fetch(`${base}/v1/escrow/deposit`, {
58
+ method: "POST",
59
+ headers: { "Content-Type": "application/json" },
60
+ body: JSON.stringify({ txHash })
61
+ });
62
+ if (res.status !== 200 && res.status !== 202) {
63
+ await throwOnError(res, "POST /v1/escrow/deposit");
64
+ }
65
+ return res.json();
66
+ },
67
+ async getEscrowBalance(account) {
68
+ const res = await fetch(
69
+ `${base}/v1/escrow/balance?account=${encodeURIComponent(account)}`
70
+ );
71
+ await throwOnError(res, "GET /v1/escrow/balance");
72
+ return res.json();
73
+ },
74
+ async syncEscrowBalance(account) {
75
+ const res = await fetch(
76
+ `${base}/v1/escrow/balance/sync?account=${encodeURIComponent(account)}`,
77
+ { method: "POST" }
78
+ );
79
+ await throwOnError(res, "POST /v1/escrow/balance/sync");
80
+ return res.json();
81
+ },
82
+ async payForOp({
83
+ payerAddress,
84
+ opType,
85
+ opId,
86
+ asset,
87
+ amount,
88
+ paymentNonce,
89
+ signature
90
+ }) {
91
+ const res = await fetch(`${base}/v1/escrow/pay`, {
92
+ method: "POST",
93
+ headers: {
94
+ "Content-Type": "application/json",
95
+ Authorization: `Web3Signed ${signature}`
96
+ },
97
+ body: JSON.stringify({
98
+ payerAddress,
99
+ opType,
100
+ opId,
101
+ asset,
102
+ amount,
103
+ paymentNonce
104
+ })
105
+ });
106
+ await throwOnError(res, "POST /v1/escrow/pay");
107
+ return res.json();
108
+ }
109
+ };
110
+ }
111
+ export {
112
+ ESCROW_DEPOSIT_ABI,
113
+ GENERIC_PAYMENT_TYPES,
114
+ NATIVE_ASSET_ADDRESS,
115
+ createEscrowGatewayClient,
116
+ genericPaymentDomain
117
+ };
118
+ //# sourceMappingURL=escrow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/protocol/escrow.ts"],"sourcesContent":["/**\n * DPv2 escrow payment helpers.\n *\n * Covers the three-phase flow used by builders to pay for data access:\n *\n * 1. **Deposit** — call `depositNative` or `depositToken` on the\n * DataPortabilityEscrow contract, then notify the gateway.\n * 2. **Balance** — read or force-sync the gateway's off-chain credit view.\n * 3. **Pay** — sign a `GenericPayment` EIP-712 message and POST it to the\n * gateway's `/v1/escrow/pay` endpoint.\n *\n * The gateway is the authority on balances; the on-chain contract is the\n * authority on what has been settled. Nothing in this module touches the\n * chain directly — signing is done by the caller's wallet.\n *\n * @category Protocol\n * @module escrow\n */\n\nimport type { TypedDataDomain } from \"viem\";\n\n// ---------------------------------------------------------------------------\n// EIP-712 — GenericPayment\n// ---------------------------------------------------------------------------\n\n/**\n * EIP-712 typed-data types for a generic op payment.\n *\n * The gateway verifies that the recovered signer == `payerAddress` and that\n * the (payer, paymentNonce) pair has not been seen before. Use a\n * monotonically-increasing nonce; the first payment for any payer should\n * start at 1.\n */\nexport const GENERIC_PAYMENT_TYPES = {\n GenericPayment: [\n { name: \"payerAddress\", type: \"address\" },\n { name: \"opType\", type: \"string\" },\n { name: \"opId\", type: \"bytes32\" },\n { name: \"asset\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n { name: \"paymentNonce\", type: \"uint256\" },\n ],\n} as const;\n\n/**\n * EIP-712 message payload for a generic op payment.\n *\n * - `opType` is currently `\"grant\"`. Additional types (file, builder, schema)\n * may be added in future protocol versions.\n * - `opId` is the bytes32 id of the operation being paid for (e.g. `grantId`).\n * - `asset` is the ERC-20 token address, or the zero address for native VANA.\n * - `amount` is the total amount in base units (wei for VANA). Must match the\n * sum the gateway expects for the current lifecycle of the op.\n * - `paymentNonce` must be a positive integer unique per `payerAddress`. Use 1\n * for the first payment; increment by at least 1 for each subsequent call.\n */\nexport interface GenericPaymentMessage {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n amount: bigint;\n paymentNonce: bigint;\n}\n\n/**\n * Returns the EIP-712 domain for signing a `GenericPayment` message.\n *\n * The verifying contract is the `DataPortabilityEscrow` contract; all gateway\n * deployments share the same domain name and version.\n *\n * @param chainId - Chain ID of the Vana network (e.g. 1480 mainnet, 14800 testnet).\n * @param escrowContract - Deployed address of DataPortabilityEscrow.\n */\nexport function genericPaymentDomain(\n chainId: number,\n escrowContract: `0x${string}`,\n): TypedDataDomain {\n return {\n name: \"Vana Data Portability\",\n version: \"1\",\n chainId,\n verifyingContract: escrowContract,\n };\n}\n\n// ---------------------------------------------------------------------------\n// On-chain deposit ABI fragments\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal ABI for the two deposit entry points on `DataPortabilityEscrow`.\n *\n * - `depositNative(address account)` payable — credits native VANA.\n * - `depositToken(address account, address token, uint256 amount)` — credits\n * an ERC-20 token (caller must have pre-approved the escrow contract).\n *\n * Pass this to viem's `writeContract` or encode it manually.\n */\nexport const ESCROW_DEPOSIT_ABI = [\n {\n type: \"function\",\n name: \"depositNative\",\n stateMutability: \"payable\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"depositToken\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"account\", type: \"address\" },\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [],\n },\n] as const;\n\n/**\n * The zero address used by the DataPortabilityEscrow contract to represent\n * native VANA in `asset` fields of events and balance responses.\n */\nexport const NATIVE_ASSET_ADDRESS =\n \"0x0000000000000000000000000000000000000000\" as const;\n\n// ---------------------------------------------------------------------------\n// Gateway API client\n// ---------------------------------------------------------------------------\n\n/**\n * Per-asset balance entry returned by the gateway's escrow balance endpoints.\n *\n * - `balance` — gross finalized credit (deposits credited so far).\n * - `pendingAmount` — sum of submitted deposits not yet confirmed.\n * - `authorizedAmount` — sum of all in-flight payments authorized by\n * `/v1/escrow/pay` (soft-lock). May include payments not yet settled\n * on-chain.\n * - `availableAmount` — `max(balance − authorizedAmount, 0)`. This is what\n * the payer can authorize before the gateway rejects with 402.\n */\nexport interface EscrowBalanceEntry {\n asset: string;\n balance: string;\n pendingAmount: string;\n authorizedAmount: string;\n availableAmount: string;\n updatedAt: string | null;\n}\n\nexport interface SubmittedDepositEntry {\n txHash: string;\n submittedAt: string;\n claimedAsset: string;\n claimedAmount: string;\n}\n\nexport interface FinalizedDepositEntry {\n txHash: string;\n finalizedAt: string | null;\n blockNumber: string | null;\n claimedAsset: string;\n claimedAmount: string;\n}\n\nexport interface FailedDepositEntry {\n txHash: string;\n submittedAt: string;\n claimedAsset: string;\n claimedAmount: string;\n lastError: string | null;\n}\n\n/** Full balance read response from `GET /v1/escrow/balance`. */\nexport interface EscrowBalanceResult {\n account: string;\n balances: EscrowBalanceEntry[];\n deposits: {\n submitted: SubmittedDepositEntry[];\n finalized: FinalizedDepositEntry[];\n failed: FailedDepositEntry[];\n };\n}\n\n/**\n * Response from `POST /v1/escrow/balance/sync`.\n *\n * Extends {@link EscrowBalanceResult} with a `sync` summary of what the\n * lazy-confirmation pass did.\n */\nexport interface EscrowBalanceSyncResult extends EscrowBalanceResult {\n sync:\n | { scanned: number; finalized: number; stillPending: number; failed: number }\n | { skipped: true };\n}\n\n/** Response from `POST /v1/escrow/deposit`. */\nexport interface DepositSubmissionResult {\n success: true;\n txHash: string;\n account: string;\n status: \"submitted\" | \"finalized\" | \"failed\";\n blockNumber?: string | null;\n submittedAt: string;\n finalizedAt?: string | null;\n lastError?: string | null;\n}\n\n/** Breakdown returned by a successful `POST /v1/escrow/pay`. */\nexport interface PaymentBreakdown {\n registrationFee: string;\n dataAccessFee: string;\n /** True when this call settled the registration fee for the op. */\n registrationPaid: boolean;\n}\n\n/** Response from `POST /v1/escrow/pay`. */\nexport interface EscrowPayResult {\n success: true;\n opType: string;\n opId: string;\n payerAddress: string;\n asset: string;\n amount: string;\n breakdown: PaymentBreakdown;\n paymentNonce: string;\n paidAt: string;\n}\n\n/**\n * Parameters for submitting a deposit tx hash to the gateway.\n *\n * The gateway will decode the `account` from the tx's calldata and\n * credit the identified account once the tx reaches the configured\n * confirmation depth.\n */\nexport interface SubmitDepositParams {\n /** 0x-prefixed 32-byte transaction hash. */\n txHash: `0x${string}`;\n}\n\n/**\n * Parameters for the generic op payment endpoint (`POST /v1/escrow/pay`).\n *\n * The `signature` is an EIP-712 signature over a `GenericPayment` message\n * (see {@link GENERIC_PAYMENT_TYPES} and {@link genericPaymentDomain}).\n * Build and sign the typed data with your wallet before calling\n * {@link EscrowGatewayClient.payForOp}.\n */\nexport interface PayForOpParams {\n payerAddress: `0x${string}`;\n opType: string;\n opId: `0x${string}`;\n asset: `0x${string}`;\n /** Decimal string representation of the uint256 amount. */\n amount: string;\n /** Decimal string representation of the uint256 nonce. */\n paymentNonce: string;\n /** 0x-prefixed 65-byte EIP-712 signature hex string. */\n signature: `0x${string}`;\n}\n\n/**\n * Minimal client for the gateway's escrow endpoints.\n *\n * Construct with {@link createEscrowGatewayClient}.\n */\nexport interface EscrowGatewayClient {\n /**\n * Notify the gateway of a submitted deposit transaction.\n *\n * The gateway decodes the credited account from the on-chain tx calldata\n * and starts tracking the deposit. Call this immediately after your\n * `depositNative` or `depositToken` tx is broadcast (it accepts pending\n * mempool txs). Returns `202` while the tx awaits confirmation.\n */\n submitDeposit(params: SubmitDepositParams): Promise<DepositSubmissionResult>;\n\n /**\n * Read the current escrow balance for an account.\n *\n * Pure read — no chain calls. To force a reconciliation pass first,\n * use {@link syncEscrowBalance}.\n */\n getEscrowBalance(account: `0x${string}`): Promise<EscrowBalanceResult>;\n\n /**\n * Force a reconciliation pass then return the updated balance.\n *\n * Triggers the gateway's lazy-confirmation worker for the account — any\n * submitted deposits that have reached the configured confirmation level\n * are credited before the balance is returned. Prefer this over\n * {@link getEscrowBalance} when you need a fresh view after a deposit.\n */\n syncEscrowBalance(account: `0x${string}`): Promise<EscrowBalanceSyncResult>;\n\n /**\n * Authorize a payment against the payer's escrow balance.\n *\n * The caller must:\n * 1. Assemble a {@link GenericPaymentMessage}.\n * 2. Sign it with `signTypedData` using {@link GENERIC_PAYMENT_TYPES} and\n * the domain from {@link genericPaymentDomain}.\n * 3. Pass the message fields + signature here.\n *\n * The gateway verifies the signature, checks the soft-lock balance, and\n * records the payment. Returns 402 if the payer has insufficient balance.\n */\n payForOp(params: PayForOpParams): Promise<EscrowPayResult>;\n}\n\n/**\n * Creates a client for the gateway escrow endpoints.\n *\n * @param baseUrl - Base URL of the DP RPC gateway\n * (e.g. `\"https://dp.vana.org\"`). Trailing slashes are trimmed.\n *\n * @example\n * ```typescript\n * import {\n * createEscrowGatewayClient,\n * genericPaymentDomain,\n * GENERIC_PAYMENT_TYPES,\n * } from \"@opendatalabs/vana-sdk/node\";\n *\n * const escrow = createEscrowGatewayClient(\"https://dp.vana.org\");\n *\n * // 1. Submit your deposit tx hash after broadcasting depositNative on-chain\n * const deposit = await escrow.submitDeposit({ txHash: \"0xabc…\" });\n *\n * // 2. Force-sync and read the updated balance\n * const { balances } = await escrow.syncEscrowBalance(\"0xpayerAddress\");\n *\n * // 3. Sign and authorize a grant payment\n * const sig = await walletClient.signTypedData({\n * domain: genericPaymentDomain(1480, \"0xEscrowContract\"),\n * types: GENERIC_PAYMENT_TYPES,\n * primaryType: \"GenericPayment\",\n * message: {\n * payerAddress: \"0xpayerAddress\",\n * opType: \"grant\",\n * opId: \"0xgrantId\",\n * asset: \"0x0000000000000000000000000000000000000000\",\n * amount: 1000000000000000000n,\n * paymentNonce: 1n,\n * },\n * });\n * const result = await escrow.payForOp({\n * payerAddress: \"0xpayerAddress\",\n * opType: \"grant\",\n * opId: \"0xgrantId\",\n * asset: \"0x0000000000000000000000000000000000000000\",\n * amount: \"1000000000000000000\",\n * paymentNonce: \"1\",\n * signature: sig,\n * });\n * ```\n */\nexport function createEscrowGatewayClient(\n baseUrl: string,\n): EscrowGatewayClient {\n const base = baseUrl.replace(/\\/+$/, \"\");\n\n async function throwOnError(res: Response, context: string): Promise<void> {\n if (!res.ok) {\n let detail = \"\";\n try {\n const body = (await res.json()) as { error?: string };\n if (body.error) detail = `: ${body.error}`;\n } catch {\n // Ignore JSON parse errors; use status text only.\n }\n throw new Error(\n `Escrow gateway error (${context}): ${res.status} ${res.statusText}${detail}`,\n );\n }\n }\n\n return {\n async submitDeposit({ txHash }) {\n const res = await fetch(`${base}/v1/escrow/deposit`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ txHash }),\n });\n // 202 Accepted and 200 OK are both success states for deposit submission.\n if (res.status !== 200 && res.status !== 202) {\n await throwOnError(res, \"POST /v1/escrow/deposit\");\n }\n return res.json() as Promise<DepositSubmissionResult>;\n },\n\n async getEscrowBalance(account) {\n const res = await fetch(\n `${base}/v1/escrow/balance?account=${encodeURIComponent(account)}`,\n );\n await throwOnError(res, \"GET /v1/escrow/balance\");\n return res.json() as Promise<EscrowBalanceResult>;\n },\n\n async syncEscrowBalance(account) {\n const res = await fetch(\n `${base}/v1/escrow/balance/sync?account=${encodeURIComponent(account)}`,\n { method: \"POST\" },\n );\n await throwOnError(res, \"POST /v1/escrow/balance/sync\");\n return res.json() as Promise<EscrowBalanceSyncResult>;\n },\n\n async payForOp({\n payerAddress,\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n signature,\n }) {\n const res = await fetch(`${base}/v1/escrow/pay`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${signature}`,\n },\n body: JSON.stringify({\n payerAddress,\n opType,\n opId,\n asset,\n amount,\n paymentNonce,\n }),\n });\n await throwOnError(res, \"POST /v1/escrow/pay\");\n return res.json() as Promise<EscrowPayResult>;\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1 @@
1
+ export {};