@opendatalabs/vana-sdk 3.1.0 → 3.2.0-canary.255a8bf
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 +2 -1
- package/dist/account/personal-server-lite-owner-binding.cjs +81 -0
- package/dist/account/personal-server-lite-owner-binding.cjs.map +1 -0
- package/dist/account/personal-server-lite-owner-binding.d.ts +30 -0
- package/dist/account/personal-server-lite-owner-binding.js +59 -0
- package/dist/account/personal-server-lite-owner-binding.js.map +1 -0
- package/dist/account/personal-server-lite-owner-binding.test.d.ts +1 -0
- package/dist/account/personal-server-registration.cjs +263 -0
- package/dist/account/personal-server-registration.cjs.map +1 -0
- package/dist/account/personal-server-registration.d.ts +66 -0
- package/dist/account/personal-server-registration.js +240 -0
- package/dist/account/personal-server-registration.js.map +1 -0
- package/dist/account/personal-server-registration.test.d.ts +1 -0
- package/dist/auth/errors.js +1 -1
- package/dist/auth/oauth-client.js +2 -2
- package/dist/auth/web3-signed-builder.js +1 -1
- package/dist/auth/web3-signed.js +3 -3
- package/dist/browser.js +1 -1
- package/dist/chains/definitions.js +1 -1
- package/dist/chains/index.js +1 -1
- package/dist/chains.browser.js +1 -1
- package/dist/chains.js +1 -1
- package/dist/chains.node.js +1 -1
- package/dist/contracts/contractController.js +4 -4
- package/dist/core/client.js +1 -1
- package/dist/crypto/ecies/base.js +3 -3
- package/dist/crypto/ecies/browser.js +1 -1
- package/dist/crypto/ecies/index.js +1 -1
- package/dist/crypto/ecies/interface.js +1 -1
- package/dist/crypto/ecies/node.js +1 -1
- package/dist/crypto/services/WalletKeyEncryptionService.js +1 -1
- package/dist/generated/abi/index.js +26 -26
- package/dist/index.browser.d.ts +9 -3
- package/dist/index.browser.js +768 -72
- package/dist/index.browser.js.map +4 -4
- package/dist/index.node.cjs +798 -73
- package/dist/index.node.cjs.map +4 -4
- package/dist/index.node.d.ts +9 -3
- package/dist/index.node.js +768 -72
- package/dist/index.node.js.map +4 -4
- package/dist/node.js +1 -1
- package/dist/platform/browser-only.js +1 -1
- package/dist/platform/browser-safe.js +1 -1
- package/dist/platform/browser.js +6 -6
- package/dist/platform/index.js +4 -4
- package/dist/platform/node.js +8 -8
- package/dist/platform/utils.js +2 -2
- package/dist/platform.browser.js +3 -3
- package/dist/platform.js +4 -4
- package/dist/platform.node.js +4 -4
- package/dist/protocol/eip712.cjs +58 -3
- package/dist/protocol/eip712.cjs.map +1 -1
- package/dist/protocol/eip712.d.ts +99 -7
- package/dist/protocol/eip712.js +52 -3
- 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 +89 -0
- package/dist/protocol/fee-registry.cjs.map +1 -0
- package/dist/protocol/fee-registry.d.ts +105 -0
- package/dist/protocol/fee-registry.js +63 -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 +124 -3
- package/dist/protocol/gateway.cjs.map +1 -1
- package/dist/protocol/gateway.d.ts +196 -16
- package/dist/protocol/gateway.js +124 -3
- package/dist/protocol/gateway.js.map +1 -1
- package/dist/protocol/grants.cjs +24 -64
- package/dist/protocol/grants.cjs.map +1 -1
- package/dist/protocol/grants.d.ts +6 -13
- package/dist/protocol/grants.js +25 -64
- package/dist/protocol/grants.js.map +1 -1
- 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/protocol/personal-server-registration.cjs +122 -0
- package/dist/protocol/personal-server-registration.cjs.map +1 -0
- package/dist/protocol/personal-server-registration.d.ts +62 -0
- package/dist/protocol/personal-server-registration.js +97 -0
- package/dist/protocol/personal-server-registration.js.map +1 -0
- package/dist/protocol/personal-server-registration.test.d.ts +1 -0
- package/dist/storage/default.js +1 -1
- package/dist/storage/index.js +10 -10
- package/dist/storage/manager.js +1 -1
- package/dist/storage/providers/callback-storage.js +1 -1
- package/dist/storage/providers/dropbox.js +1 -1
- package/dist/storage/providers/google-drive.js +1 -1
- package/dist/storage/providers/ipfs.js +2 -2
- package/dist/storage/providers/pinata.js +1 -1
- package/dist/storage/providers/r2.js +1 -1
- package/dist/storage/providers/vana-storage.js +2 -2
- package/dist/types/index.js +2 -2
- package/dist/types.js +1 -1
- package/package.json +6 -3
|
@@ -0,0 +1,89 @@
|
|
|
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_deposit_exports = {};
|
|
20
|
+
__export(escrow_deposit_exports, {
|
|
21
|
+
ESCROW_DEPOSIT_ABI: () => ESCROW_DEPOSIT_ABI,
|
|
22
|
+
buildDepositNativeRequest: () => buildDepositNativeRequest,
|
|
23
|
+
buildDepositTokenRequest: () => buildDepositTokenRequest,
|
|
24
|
+
encodeDepositNativeData: () => encodeDepositNativeData,
|
|
25
|
+
encodeDepositTokenData: () => encodeDepositTokenData,
|
|
26
|
+
escrowContractAddress: () => escrowContractAddress
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(escrow_deposit_exports);
|
|
29
|
+
var import_viem = require("viem");
|
|
30
|
+
const ESCROW_DEPOSIT_ABI = [
|
|
31
|
+
{
|
|
32
|
+
type: "function",
|
|
33
|
+
name: "depositNative",
|
|
34
|
+
stateMutability: "payable",
|
|
35
|
+
inputs: [{ name: "account", type: "address" }],
|
|
36
|
+
outputs: []
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
type: "function",
|
|
40
|
+
name: "depositToken",
|
|
41
|
+
stateMutability: "nonpayable",
|
|
42
|
+
inputs: [
|
|
43
|
+
{ name: "account", type: "address" },
|
|
44
|
+
{ name: "token", type: "address" },
|
|
45
|
+
{ name: "amount", type: "uint256" }
|
|
46
|
+
],
|
|
47
|
+
outputs: []
|
|
48
|
+
}
|
|
49
|
+
];
|
|
50
|
+
function escrowContractAddress(config) {
|
|
51
|
+
return config.contracts.dataPortabilityEscrow;
|
|
52
|
+
}
|
|
53
|
+
function encodeDepositNativeData(input) {
|
|
54
|
+
return (0, import_viem.encodeFunctionData)({
|
|
55
|
+
abi: ESCROW_DEPOSIT_ABI,
|
|
56
|
+
functionName: "depositNative",
|
|
57
|
+
args: [input.account]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function encodeDepositTokenData(input) {
|
|
61
|
+
return (0, import_viem.encodeFunctionData)({
|
|
62
|
+
abi: ESCROW_DEPOSIT_ABI,
|
|
63
|
+
functionName: "depositToken",
|
|
64
|
+
args: [input.account, input.token, input.amount]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function buildDepositNativeRequest(config, input) {
|
|
68
|
+
return {
|
|
69
|
+
to: escrowContractAddress(config),
|
|
70
|
+
data: encodeDepositNativeData({ account: input.account }),
|
|
71
|
+
value: input.amount
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function buildDepositTokenRequest(config, input) {
|
|
75
|
+
return {
|
|
76
|
+
to: escrowContractAddress(config),
|
|
77
|
+
data: encodeDepositTokenData(input)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
81
|
+
0 && (module.exports = {
|
|
82
|
+
ESCROW_DEPOSIT_ABI,
|
|
83
|
+
buildDepositNativeRequest,
|
|
84
|
+
buildDepositTokenRequest,
|
|
85
|
+
encodeDepositNativeData,
|
|
86
|
+
encodeDepositTokenData,
|
|
87
|
+
escrowContractAddress
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=escrow-deposit.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/protocol/escrow-deposit.ts"],"sourcesContent":["/**\n * On-chain deposit primitives for the DataPortabilityEscrow contract.\n *\n * The escrow holds the finalized balance that `/v1/escrow/pay` debits against.\n * A payer credits their balance by sending one of two function calls to the\n * escrow contract — depositNative (native VANA, amount via `msg.value`) or\n * depositToken (ERC-20, caller must `approve` the escrow first). The credited\n * `account` need not equal `msg.sender`, so a third party can fund someone\n * else's escrow.\n *\n * Once the on-chain tx lands, call `GatewayClient.submitEscrowDeposit({txHash})`\n * to announce it; the gateway reconciles it into the balance and surfaces it\n * under `getEscrowBalance(account).deposits.finalized`.\n *\n * These helpers are signer/transport-agnostic — they return the raw\n * `{to, data, value?}` request object so callers can feed it to any wallet\n * stack (viem `sendTransaction`/`writeContract`, ethers, wallet-rpc, MPC,\n * Safe transactions, etc.).\n *\n * @category Protocol\n */\nimport { encodeFunctionData } from \"viem\";\nimport type { DataPortabilityGatewayConfig } from \"./eip712\";\n\n// ABI for the two deposit entry points on DataPortabilityEscrow. Same shape\n// the gateway uses to decode pending/mined tx calldata at\n// /v1/escrow/deposit time (data-gateway/lib/escrow.ts:39).\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\nexport function escrowContractAddress(\n config: DataPortabilityGatewayConfig,\n): `0x${string}` {\n return config.contracts.dataPortabilityEscrow as `0x${string}`;\n}\n\nexport interface DepositNativeInput {\n // Address credited inside the escrow. Often the same as the wallet sending\n // the tx, but third-party funding is supported.\n account: `0x${string}`;\n amount: bigint;\n}\n\nexport interface DepositTokenInput {\n account: `0x${string}`;\n // ERC-20 contract address.\n token: `0x${string}`;\n amount: bigint;\n}\n\n// Shape compatible with viem's `sendTransaction` / `writeContract` request\n// objects. `value` is omitted on the ERC-20 path because the amount lives in\n// the token contract, not `msg.value`.\nexport interface DepositTransactionRequest {\n to: `0x${string}`;\n data: `0x${string}`;\n value?: bigint;\n}\n\nexport function encodeDepositNativeData(input: {\n account: `0x${string}`;\n}): `0x${string}` {\n return encodeFunctionData({\n abi: ESCROW_DEPOSIT_ABI,\n functionName: \"depositNative\",\n args: [input.account],\n });\n}\n\nexport function encodeDepositTokenData(\n input: DepositTokenInput,\n): `0x${string}` {\n return encodeFunctionData({\n abi: ESCROW_DEPOSIT_ABI,\n functionName: \"depositToken\",\n args: [input.account, input.token, input.amount],\n });\n}\n\n// Build the full tx request for a native-VANA deposit. Feed it straight to\n// `walletClient.sendTransaction({...req, account, chain})`. ERC-20 needs a\n// prior `approve(escrow, amount)` on the token — use viem's built-in\n// `erc20Abi` for that; the SDK doesn't bundle one to avoid the import surface.\nexport function buildDepositNativeRequest(\n config: DataPortabilityGatewayConfig,\n input: DepositNativeInput,\n): DepositTransactionRequest {\n return {\n to: escrowContractAddress(config),\n data: encodeDepositNativeData({ account: input.account }),\n value: input.amount,\n };\n}\n\nexport function buildDepositTokenRequest(\n config: DataPortabilityGatewayConfig,\n input: DepositTokenInput,\n): DepositTransactionRequest {\n return {\n to: escrowContractAddress(config),\n data: encodeDepositTokenData(input),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBA,kBAAmC;AAM5B,MAAM,qBAAqB;AAAA,EAChC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,MACjC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AACF;AAEO,SAAS,sBACd,QACe;AACf,SAAO,OAAO,UAAU;AAC1B;AAyBO,SAAS,wBAAwB,OAEtB;AAChB,aAAO,gCAAmB;AAAA,IACxB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,OAAO;AAAA,EACtB,CAAC;AACH;AAEO,SAAS,uBACd,OACe;AACf,aAAO,gCAAmB;AAAA,IACxB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,SAAS,MAAM,OAAO,MAAM,MAAM;AAAA,EACjD,CAAC;AACH;AAMO,SAAS,0BACd,QACA,OAC2B;AAC3B,SAAO;AAAA,IACL,IAAI,sBAAsB,MAAM;AAAA,IAChC,MAAM,wBAAwB,EAAE,SAAS,MAAM,QAAQ,CAAC;AAAA,IACxD,OAAO,MAAM;AAAA,EACf;AACF;AAEO,SAAS,yBACd,QACA,OAC2B;AAC3B,SAAO;AAAA,IACL,IAAI,sBAAsB,MAAM;AAAA,IAChC,MAAM,uBAAuB,KAAK;AAAA,EACpC;AACF;","names":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { DataPortabilityGatewayConfig } from "./eip712";
|
|
2
|
+
export declare const ESCROW_DEPOSIT_ABI: readonly [{
|
|
3
|
+
readonly type: "function";
|
|
4
|
+
readonly name: "depositNative";
|
|
5
|
+
readonly stateMutability: "payable";
|
|
6
|
+
readonly inputs: readonly [{
|
|
7
|
+
readonly name: "account";
|
|
8
|
+
readonly type: "address";
|
|
9
|
+
}];
|
|
10
|
+
readonly outputs: readonly [];
|
|
11
|
+
}, {
|
|
12
|
+
readonly type: "function";
|
|
13
|
+
readonly name: "depositToken";
|
|
14
|
+
readonly stateMutability: "nonpayable";
|
|
15
|
+
readonly inputs: readonly [{
|
|
16
|
+
readonly name: "account";
|
|
17
|
+
readonly type: "address";
|
|
18
|
+
}, {
|
|
19
|
+
readonly name: "token";
|
|
20
|
+
readonly type: "address";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "amount";
|
|
23
|
+
readonly type: "uint256";
|
|
24
|
+
}];
|
|
25
|
+
readonly outputs: readonly [];
|
|
26
|
+
}];
|
|
27
|
+
export declare function escrowContractAddress(config: DataPortabilityGatewayConfig): `0x${string}`;
|
|
28
|
+
export interface DepositNativeInput {
|
|
29
|
+
account: `0x${string}`;
|
|
30
|
+
amount: bigint;
|
|
31
|
+
}
|
|
32
|
+
export interface DepositTokenInput {
|
|
33
|
+
account: `0x${string}`;
|
|
34
|
+
token: `0x${string}`;
|
|
35
|
+
amount: bigint;
|
|
36
|
+
}
|
|
37
|
+
export interface DepositTransactionRequest {
|
|
38
|
+
to: `0x${string}`;
|
|
39
|
+
data: `0x${string}`;
|
|
40
|
+
value?: bigint;
|
|
41
|
+
}
|
|
42
|
+
export declare function encodeDepositNativeData(input: {
|
|
43
|
+
account: `0x${string}`;
|
|
44
|
+
}): `0x${string}`;
|
|
45
|
+
export declare function encodeDepositTokenData(input: DepositTokenInput): `0x${string}`;
|
|
46
|
+
export declare function buildDepositNativeRequest(config: DataPortabilityGatewayConfig, input: DepositNativeInput): DepositTransactionRequest;
|
|
47
|
+
export declare function buildDepositTokenRequest(config: DataPortabilityGatewayConfig, input: DepositTokenInput): DepositTransactionRequest;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { encodeFunctionData } from "viem";
|
|
2
|
+
const ESCROW_DEPOSIT_ABI = [
|
|
3
|
+
{
|
|
4
|
+
type: "function",
|
|
5
|
+
name: "depositNative",
|
|
6
|
+
stateMutability: "payable",
|
|
7
|
+
inputs: [{ name: "account", type: "address" }],
|
|
8
|
+
outputs: []
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
type: "function",
|
|
12
|
+
name: "depositToken",
|
|
13
|
+
stateMutability: "nonpayable",
|
|
14
|
+
inputs: [
|
|
15
|
+
{ name: "account", type: "address" },
|
|
16
|
+
{ name: "token", type: "address" },
|
|
17
|
+
{ name: "amount", type: "uint256" }
|
|
18
|
+
],
|
|
19
|
+
outputs: []
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
function escrowContractAddress(config) {
|
|
23
|
+
return config.contracts.dataPortabilityEscrow;
|
|
24
|
+
}
|
|
25
|
+
function encodeDepositNativeData(input) {
|
|
26
|
+
return encodeFunctionData({
|
|
27
|
+
abi: ESCROW_DEPOSIT_ABI,
|
|
28
|
+
functionName: "depositNative",
|
|
29
|
+
args: [input.account]
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function encodeDepositTokenData(input) {
|
|
33
|
+
return encodeFunctionData({
|
|
34
|
+
abi: ESCROW_DEPOSIT_ABI,
|
|
35
|
+
functionName: "depositToken",
|
|
36
|
+
args: [input.account, input.token, input.amount]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function buildDepositNativeRequest(config, input) {
|
|
40
|
+
return {
|
|
41
|
+
to: escrowContractAddress(config),
|
|
42
|
+
data: encodeDepositNativeData({ account: input.account }),
|
|
43
|
+
value: input.amount
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function buildDepositTokenRequest(config, input) {
|
|
47
|
+
return {
|
|
48
|
+
to: escrowContractAddress(config),
|
|
49
|
+
data: encodeDepositTokenData(input)
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
ESCROW_DEPOSIT_ABI,
|
|
54
|
+
buildDepositNativeRequest,
|
|
55
|
+
buildDepositTokenRequest,
|
|
56
|
+
encodeDepositNativeData,
|
|
57
|
+
encodeDepositTokenData,
|
|
58
|
+
escrowContractAddress
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=escrow-deposit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/protocol/escrow-deposit.ts"],"sourcesContent":["/**\n * On-chain deposit primitives for the DataPortabilityEscrow contract.\n *\n * The escrow holds the finalized balance that `/v1/escrow/pay` debits against.\n * A payer credits their balance by sending one of two function calls to the\n * escrow contract — depositNative (native VANA, amount via `msg.value`) or\n * depositToken (ERC-20, caller must `approve` the escrow first). The credited\n * `account` need not equal `msg.sender`, so a third party can fund someone\n * else's escrow.\n *\n * Once the on-chain tx lands, call `GatewayClient.submitEscrowDeposit({txHash})`\n * to announce it; the gateway reconciles it into the balance and surfaces it\n * under `getEscrowBalance(account).deposits.finalized`.\n *\n * These helpers are signer/transport-agnostic — they return the raw\n * `{to, data, value?}` request object so callers can feed it to any wallet\n * stack (viem `sendTransaction`/`writeContract`, ethers, wallet-rpc, MPC,\n * Safe transactions, etc.).\n *\n * @category Protocol\n */\nimport { encodeFunctionData } from \"viem\";\nimport type { DataPortabilityGatewayConfig } from \"./eip712\";\n\n// ABI for the two deposit entry points on DataPortabilityEscrow. Same shape\n// the gateway uses to decode pending/mined tx calldata at\n// /v1/escrow/deposit time (data-gateway/lib/escrow.ts:39).\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\nexport function escrowContractAddress(\n config: DataPortabilityGatewayConfig,\n): `0x${string}` {\n return config.contracts.dataPortabilityEscrow as `0x${string}`;\n}\n\nexport interface DepositNativeInput {\n // Address credited inside the escrow. Often the same as the wallet sending\n // the tx, but third-party funding is supported.\n account: `0x${string}`;\n amount: bigint;\n}\n\nexport interface DepositTokenInput {\n account: `0x${string}`;\n // ERC-20 contract address.\n token: `0x${string}`;\n amount: bigint;\n}\n\n// Shape compatible with viem's `sendTransaction` / `writeContract` request\n// objects. `value` is omitted on the ERC-20 path because the amount lives in\n// the token contract, not `msg.value`.\nexport interface DepositTransactionRequest {\n to: `0x${string}`;\n data: `0x${string}`;\n value?: bigint;\n}\n\nexport function encodeDepositNativeData(input: {\n account: `0x${string}`;\n}): `0x${string}` {\n return encodeFunctionData({\n abi: ESCROW_DEPOSIT_ABI,\n functionName: \"depositNative\",\n args: [input.account],\n });\n}\n\nexport function encodeDepositTokenData(\n input: DepositTokenInput,\n): `0x${string}` {\n return encodeFunctionData({\n abi: ESCROW_DEPOSIT_ABI,\n functionName: \"depositToken\",\n args: [input.account, input.token, input.amount],\n });\n}\n\n// Build the full tx request for a native-VANA deposit. Feed it straight to\n// `walletClient.sendTransaction({...req, account, chain})`. ERC-20 needs a\n// prior `approve(escrow, amount)` on the token — use viem's built-in\n// `erc20Abi` for that; the SDK doesn't bundle one to avoid the import surface.\nexport function buildDepositNativeRequest(\n config: DataPortabilityGatewayConfig,\n input: DepositNativeInput,\n): DepositTransactionRequest {\n return {\n to: escrowContractAddress(config),\n data: encodeDepositNativeData({ account: input.account }),\n value: input.amount,\n };\n}\n\nexport function buildDepositTokenRequest(\n config: DataPortabilityGatewayConfig,\n input: DepositTokenInput,\n): DepositTransactionRequest {\n return {\n to: escrowContractAddress(config),\n data: encodeDepositTokenData(input),\n };\n}\n"],"mappings":"AAqBA,SAAS,0BAA0B;AAM5B,MAAM,qBAAqB;AAAA,EAChC;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ,CAAC,EAAE,MAAM,WAAW,MAAM,UAAU,CAAC;AAAA,IAC7C,SAAS,CAAC;AAAA,EACZ;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,iBAAiB;AAAA,IACjB,QAAQ;AAAA,MACN,EAAE,MAAM,WAAW,MAAM,UAAU;AAAA,MACnC,EAAE,MAAM,SAAS,MAAM,UAAU;AAAA,MACjC,EAAE,MAAM,UAAU,MAAM,UAAU;AAAA,IACpC;AAAA,IACA,SAAS,CAAC;AAAA,EACZ;AACF;AAEO,SAAS,sBACd,QACe;AACf,SAAO,OAAO,UAAU;AAC1B;AAyBO,SAAS,wBAAwB,OAEtB;AAChB,SAAO,mBAAmB;AAAA,IACxB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,OAAO;AAAA,EACtB,CAAC;AACH;AAEO,SAAS,uBACd,OACe;AACf,SAAO,mBAAmB;AAAA,IACxB,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM,SAAS,MAAM,OAAO,MAAM,MAAM;AAAA,EACjD,CAAC;AACH;AAMO,SAAS,0BACd,QACA,OAC2B;AAC3B,SAAO;AAAA,IACL,IAAI,sBAAsB,MAAM;AAAA,IAChC,MAAM,wBAAwB,EAAE,SAAS,MAAM,QAAQ,CAAC;AAAA,IACxD,OAAO,MAAM;AAAA,EACf;AACF;AAEO,SAAS,yBACd,QACA,OAC2B;AAC3B,SAAO;AAAA,IACL,IAAI,sBAAsB,MAAM;AAAA,IAChC,MAAM,uBAAuB,KAAK;AAAA,EACpC;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end test of the deposit + payment flow.
|
|
3
|
+
*
|
|
4
|
+
* The SDK is signer- and transport-agnostic. To prove the helpers compose
|
|
5
|
+
* correctly we wire them through:
|
|
6
|
+
*
|
|
7
|
+
* - A real viem `WalletClient` against an in-memory L1 (a custom RPC
|
|
8
|
+
* transport routes JSON-RPC calls to a Map-backed chain). The wallet
|
|
9
|
+
* genuinely signs an EIP-1559 transaction with the depositNative
|
|
10
|
+
* calldata produced by buildDepositNativeRequest.
|
|
11
|
+
*
|
|
12
|
+
* - A fetch-mocked gateway that decodes that same calldata via
|
|
13
|
+
* ESCROW_DEPOSIT_ABI, credits a balance, and later recovers the
|
|
14
|
+
* GenericPayment EIP-712 signer with viem's recoverTypedDataAddress —
|
|
15
|
+
* same cryptographic checks the real gateway runs.
|
|
16
|
+
*
|
|
17
|
+
* Anything weaker than this (hand-rolled sendTx, hand-rolled sig recovery)
|
|
18
|
+
* would let the SDK's encoder or domain helpers drift silently. Going through
|
|
19
|
+
* viem's real wallet + sign paths is what makes this a useful e2e.
|
|
20
|
+
*/
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
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 fee_registry_exports = {};
|
|
20
|
+
__export(fee_registry_exports, {
|
|
21
|
+
FEE_REGISTRY_ABI: () => FEE_REGISTRY_ABI,
|
|
22
|
+
getFee: () => getFee,
|
|
23
|
+
getOpFee: () => getOpFee
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(fee_registry_exports);
|
|
26
|
+
var import_viem = require("viem");
|
|
27
|
+
const FEE_REGISTRY_ABI = (0, import_viem.parseAbi)([
|
|
28
|
+
"struct Fee { uint256 amount; address asset; address payee; bool enabled; }",
|
|
29
|
+
"function fees(bytes32 operation) view returns (Fee)",
|
|
30
|
+
"function operationKey(string name) pure returns (bytes32)"
|
|
31
|
+
]);
|
|
32
|
+
function operationNameFor(kind, opts) {
|
|
33
|
+
if (kind === "registration") {
|
|
34
|
+
return opts?.registrationOpName ?? "registration";
|
|
35
|
+
}
|
|
36
|
+
return opts?.dataAccessOpName ?? "data_access";
|
|
37
|
+
}
|
|
38
|
+
async function getFee(client, config, kind, opts) {
|
|
39
|
+
const address = config.contracts.feeRegistry;
|
|
40
|
+
const opName = operationNameFor(kind, opts);
|
|
41
|
+
const opKey = await client.readContract({
|
|
42
|
+
address,
|
|
43
|
+
abi: FEE_REGISTRY_ABI,
|
|
44
|
+
functionName: "operationKey",
|
|
45
|
+
args: [opName]
|
|
46
|
+
});
|
|
47
|
+
const fee = await client.readContract({
|
|
48
|
+
address,
|
|
49
|
+
abi: FEE_REGISTRY_ABI,
|
|
50
|
+
functionName: "fees",
|
|
51
|
+
args: [opKey]
|
|
52
|
+
});
|
|
53
|
+
if (!fee.enabled) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`FeeRegistry: operation "${opName}" (kind=${kind}) is not enabled \u2014 operator must call setFeeByName before payments will validate`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (fee.payee === "0x0000000000000000000000000000000000000000") {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`FeeRegistry: operation "${opName}" has zero-address payee \u2014 contract pre-flight rejects payouts to 0x0`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return fee;
|
|
64
|
+
}
|
|
65
|
+
async function getOpFee(client, config, opts) {
|
|
66
|
+
const [registration, dataAccess] = await Promise.all([
|
|
67
|
+
getFee(client, config, "registration", opts),
|
|
68
|
+
getFee(client, config, "data_access", opts)
|
|
69
|
+
]);
|
|
70
|
+
if (registration.asset.toLowerCase() !== dataAccess.asset.toLowerCase()) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`FeeRegistry asset mismatch: registration=${registration.asset} vs data_access=${dataAccess.asset}. The gateway requires both fees to settle in the same asset.`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
asset: registration.asset,
|
|
77
|
+
registrationFee: registration.amount,
|
|
78
|
+
dataAccessFee: dataAccess.amount,
|
|
79
|
+
registrationPayee: registration.payee,
|
|
80
|
+
dataAccessPayee: dataAccess.payee
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
84
|
+
0 && (module.exports = {
|
|
85
|
+
FEE_REGISTRY_ABI,
|
|
86
|
+
getFee,
|
|
87
|
+
getOpFee
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=fee-registry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/protocol/fee-registry.ts"],"sourcesContent":["/**\n * Adapter for the on-chain FeeRegistry contract — the source of truth the\n * gateway re-reads on every /v1/escrow/pay to size the payment amount.\n *\n * The registry stores per-operation `{amount, asset, payee, enabled}`\n * records keyed on `keccak256(name)`. SDK consumers (builders sizing\n * payments) MUST read fees from this contract rather than hardcoding\n * them, or the signed `amount` won't match the gateway's expected total\n * and /v1/escrow/pay returns 400.\n *\n * Two operation names are wired up today:\n * - 'registration' — one-time fee charged the first time a payment\n * lands for a grant in 'pending' payment_status.\n * - 'data_access' — per-access fee charged every accepted payment.\n *\n * Deployers can override the on-chain operation names via the gateway's\n * FEE_REGISTRY_REGISTRATION_OP / FEE_REGISTRY_DATA_ACCESS_OP env vars;\n * the matching SDK escape hatch is the `opts.registrationOpName` /\n * `opts.dataAccessOpName` arguments.\n *\n * This module is signer/transport-agnostic — callers pass in their own\n * `PublicClient` for the contract reads. No caching here; a long-running\n * service consumer should wrap with their own TTL. Mirrors\n * data-gateway/lib/fee-registry.ts byte-for-byte.\n *\n * @category Protocol\n */\nimport { parseAbi, type Address, type Hex, type PublicClient } from \"viem\";\nimport type { DataPortabilityGatewayConfig } from \"./eip712\";\n\nexport const FEE_REGISTRY_ABI = parseAbi([\n \"struct Fee { uint256 amount; address asset; address payee; bool enabled; }\",\n \"function fees(bytes32 operation) view returns (Fee)\",\n \"function operationKey(string name) pure returns (bytes32)\",\n]);\n\nexport type FeeKind = \"registration\" | \"data_access\";\n\nexport interface FeeEntry {\n amount: bigint;\n // Asset the fee is denominated in. 0x0000…0000 = native VANA;\n // anything else is an ERC-20 contract address.\n asset: Address;\n // The recipient the on-chain settle pass routes the fee to.\n payee: Address;\n enabled: boolean;\n}\n\n// Combined view that mirrors data-gateway/lib/op-fees.ts. Throws if the two\n// kinds disagree on `asset` because the pay handler accepts a single\n// `asset` on the payment payload — both fees must settle in the same one.\n// Payees can differ (registration → one treasury, data-access → another).\nexport interface OpFee {\n asset: Address;\n registrationFee: bigint;\n dataAccessFee: bigint;\n registrationPayee: Address;\n dataAccessPayee: Address;\n}\n\nexport interface FeeRegistryOptions {\n registrationOpName?: string;\n dataAccessOpName?: string;\n}\n\nfunction operationNameFor(\n kind: FeeKind,\n opts: FeeRegistryOptions | undefined,\n): string {\n if (kind === \"registration\") {\n return opts?.registrationOpName ?? \"registration\";\n }\n return opts?.dataAccessOpName ?? \"data_access\";\n}\n\n/**\n * Reads one fee kind from the FeeRegistry. Calls the contract's\n * `operationKey(name)` first to derive the bytes32 key — matches the\n * gateway's approach exactly (could compute locally via keccak256, but\n * going through the contract eliminates any chance of encoding drift).\n *\n * Throws when:\n * - the fee record's `enabled` flag is false (operator hasn't set it),\n * - or the `payee` is the zero address (the contract's settle pre-flight\n * rejects payouts to 0x0; surfacing it early gives a better error).\n */\nexport async function getFee(\n client: PublicClient,\n config: DataPortabilityGatewayConfig,\n kind: FeeKind,\n opts?: FeeRegistryOptions,\n): Promise<FeeEntry> {\n const address = config.contracts.feeRegistry as Address;\n const opName = operationNameFor(kind, opts);\n\n const opKey = (await client.readContract({\n address,\n abi: FEE_REGISTRY_ABI,\n functionName: \"operationKey\",\n args: [opName],\n })) as Hex;\n\n const fee = (await client.readContract({\n address,\n abi: FEE_REGISTRY_ABI,\n functionName: \"fees\",\n args: [opKey],\n })) as FeeEntry;\n\n if (!fee.enabled) {\n throw new Error(\n `FeeRegistry: operation \"${opName}\" (kind=${kind}) is not enabled — operator must call setFeeByName before payments will validate`,\n );\n }\n if (fee.payee === \"0x0000000000000000000000000000000000000000\") {\n throw new Error(\n `FeeRegistry: operation \"${opName}\" has zero-address payee — contract pre-flight rejects payouts to 0x0`,\n );\n }\n\n return fee;\n}\n\n/**\n * Convenience: read both fee kinds and combine into the shape the pay\n * handler validates against. Throws if the two kinds disagree on asset\n * (the gateway requires both to settle in the same one).\n *\n * Builders use this at startup, then sign `amount = registrationFee +\n * dataAccessFee` for the first grant payment and `amount = dataAccessFee`\n * for subsequent ones.\n */\nexport async function getOpFee(\n client: PublicClient,\n config: DataPortabilityGatewayConfig,\n opts?: FeeRegistryOptions,\n): Promise<OpFee> {\n const [registration, dataAccess] = await Promise.all([\n getFee(client, config, \"registration\", opts),\n getFee(client, config, \"data_access\", opts),\n ]);\n if (registration.asset.toLowerCase() !== dataAccess.asset.toLowerCase()) {\n throw new Error(\n `FeeRegistry asset mismatch: registration=${registration.asset} vs data_access=${dataAccess.asset}. The gateway requires both fees to settle in the same asset.`,\n );\n }\n return {\n asset: registration.asset,\n registrationFee: registration.amount,\n dataAccessFee: dataAccess.amount,\n registrationPayee: registration.payee,\n dataAccessPayee: dataAccess.payee,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,kBAAoE;AAG7D,MAAM,uBAAmB,sBAAS;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA+BD,SAAS,iBACP,MACA,MACQ;AACR,MAAI,SAAS,gBAAgB;AAC3B,WAAO,MAAM,sBAAsB;AAAA,EACrC;AACA,SAAO,MAAM,oBAAoB;AACnC;AAaA,eAAsB,OACpB,QACA,QACA,MACA,MACmB;AACnB,QAAM,UAAU,OAAO,UAAU;AACjC,QAAM,SAAS,iBAAiB,MAAM,IAAI;AAE1C,QAAM,QAAS,MAAM,OAAO,aAAa;AAAA,IACvC;AAAA,IACA,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM;AAAA,EACf,CAAC;AAED,QAAM,MAAO,MAAM,OAAO,aAAa;AAAA,IACrC;AAAA,IACA,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,KAAK;AAAA,EACd,CAAC;AAED,MAAI,CAAC,IAAI,SAAS;AAChB,UAAM,IAAI;AAAA,MACR,2BAA2B,MAAM,WAAW,IAAI;AAAA,IAClD;AAAA,EACF;AACA,MAAI,IAAI,UAAU,8CAA8C;AAC9D,UAAM,IAAI;AAAA,MACR,2BAA2B,MAAM;AAAA,IACnC;AAAA,EACF;AAEA,SAAO;AACT;AAWA,eAAsB,SACpB,QACA,QACA,MACgB;AAChB,QAAM,CAAC,cAAc,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,IACnD,OAAO,QAAQ,QAAQ,gBAAgB,IAAI;AAAA,IAC3C,OAAO,QAAQ,QAAQ,eAAe,IAAI;AAAA,EAC5C,CAAC;AACD,MAAI,aAAa,MAAM,YAAY,MAAM,WAAW,MAAM,YAAY,GAAG;AACvE,UAAM,IAAI;AAAA,MACR,4CAA4C,aAAa,KAAK,mBAAmB,WAAW,KAAK;AAAA,IACnG;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,aAAa;AAAA,IACpB,iBAAiB,aAAa;AAAA,IAC9B,eAAe,WAAW;AAAA,IAC1B,mBAAmB,aAAa;AAAA,IAChC,iBAAiB,WAAW;AAAA,EAC9B;AACF;","names":[]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter for the on-chain FeeRegistry contract — the source of truth the
|
|
3
|
+
* gateway re-reads on every /v1/escrow/pay to size the payment amount.
|
|
4
|
+
*
|
|
5
|
+
* The registry stores per-operation `{amount, asset, payee, enabled}`
|
|
6
|
+
* records keyed on `keccak256(name)`. SDK consumers (builders sizing
|
|
7
|
+
* payments) MUST read fees from this contract rather than hardcoding
|
|
8
|
+
* them, or the signed `amount` won't match the gateway's expected total
|
|
9
|
+
* and /v1/escrow/pay returns 400.
|
|
10
|
+
*
|
|
11
|
+
* Two operation names are wired up today:
|
|
12
|
+
* - 'registration' — one-time fee charged the first time a payment
|
|
13
|
+
* lands for a grant in 'pending' payment_status.
|
|
14
|
+
* - 'data_access' — per-access fee charged every accepted payment.
|
|
15
|
+
*
|
|
16
|
+
* Deployers can override the on-chain operation names via the gateway's
|
|
17
|
+
* FEE_REGISTRY_REGISTRATION_OP / FEE_REGISTRY_DATA_ACCESS_OP env vars;
|
|
18
|
+
* the matching SDK escape hatch is the `opts.registrationOpName` /
|
|
19
|
+
* `opts.dataAccessOpName` arguments.
|
|
20
|
+
*
|
|
21
|
+
* This module is signer/transport-agnostic — callers pass in their own
|
|
22
|
+
* `PublicClient` for the contract reads. No caching here; a long-running
|
|
23
|
+
* service consumer should wrap with their own TTL. Mirrors
|
|
24
|
+
* data-gateway/lib/fee-registry.ts byte-for-byte.
|
|
25
|
+
*
|
|
26
|
+
* @category Protocol
|
|
27
|
+
*/
|
|
28
|
+
import { type Address, type PublicClient } from "viem";
|
|
29
|
+
import type { DataPortabilityGatewayConfig } from "./eip712";
|
|
30
|
+
export declare const FEE_REGISTRY_ABI: readonly [{
|
|
31
|
+
readonly name: "fees";
|
|
32
|
+
readonly type: "function";
|
|
33
|
+
readonly stateMutability: "view";
|
|
34
|
+
readonly inputs: readonly [{
|
|
35
|
+
readonly type: "bytes32";
|
|
36
|
+
readonly name: "operation";
|
|
37
|
+
}];
|
|
38
|
+
readonly outputs: readonly [{
|
|
39
|
+
readonly type: "tuple";
|
|
40
|
+
readonly components: readonly [{
|
|
41
|
+
readonly type: "uint256";
|
|
42
|
+
readonly name: "amount";
|
|
43
|
+
}, {
|
|
44
|
+
readonly type: "address";
|
|
45
|
+
readonly name: "asset";
|
|
46
|
+
}, {
|
|
47
|
+
readonly type: "address";
|
|
48
|
+
readonly name: "payee";
|
|
49
|
+
}, {
|
|
50
|
+
readonly type: "bool";
|
|
51
|
+
readonly name: "enabled";
|
|
52
|
+
}];
|
|
53
|
+
}];
|
|
54
|
+
}, {
|
|
55
|
+
readonly name: "operationKey";
|
|
56
|
+
readonly type: "function";
|
|
57
|
+
readonly stateMutability: "pure";
|
|
58
|
+
readonly inputs: readonly [{
|
|
59
|
+
readonly type: "string";
|
|
60
|
+
readonly name: "name";
|
|
61
|
+
}];
|
|
62
|
+
readonly outputs: readonly [{
|
|
63
|
+
readonly type: "bytes32";
|
|
64
|
+
}];
|
|
65
|
+
}];
|
|
66
|
+
export type FeeKind = "registration" | "data_access";
|
|
67
|
+
export interface FeeEntry {
|
|
68
|
+
amount: bigint;
|
|
69
|
+
asset: Address;
|
|
70
|
+
payee: Address;
|
|
71
|
+
enabled: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface OpFee {
|
|
74
|
+
asset: Address;
|
|
75
|
+
registrationFee: bigint;
|
|
76
|
+
dataAccessFee: bigint;
|
|
77
|
+
registrationPayee: Address;
|
|
78
|
+
dataAccessPayee: Address;
|
|
79
|
+
}
|
|
80
|
+
export interface FeeRegistryOptions {
|
|
81
|
+
registrationOpName?: string;
|
|
82
|
+
dataAccessOpName?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Reads one fee kind from the FeeRegistry. Calls the contract's
|
|
86
|
+
* `operationKey(name)` first to derive the bytes32 key — matches the
|
|
87
|
+
* gateway's approach exactly (could compute locally via keccak256, but
|
|
88
|
+
* going through the contract eliminates any chance of encoding drift).
|
|
89
|
+
*
|
|
90
|
+
* Throws when:
|
|
91
|
+
* - the fee record's `enabled` flag is false (operator hasn't set it),
|
|
92
|
+
* - or the `payee` is the zero address (the contract's settle pre-flight
|
|
93
|
+
* rejects payouts to 0x0; surfacing it early gives a better error).
|
|
94
|
+
*/
|
|
95
|
+
export declare function getFee(client: PublicClient, config: DataPortabilityGatewayConfig, kind: FeeKind, opts?: FeeRegistryOptions): Promise<FeeEntry>;
|
|
96
|
+
/**
|
|
97
|
+
* Convenience: read both fee kinds and combine into the shape the pay
|
|
98
|
+
* handler validates against. Throws if the two kinds disagree on asset
|
|
99
|
+
* (the gateway requires both to settle in the same one).
|
|
100
|
+
*
|
|
101
|
+
* Builders use this at startup, then sign `amount = registrationFee +
|
|
102
|
+
* dataAccessFee` for the first grant payment and `amount = dataAccessFee`
|
|
103
|
+
* for subsequent ones.
|
|
104
|
+
*/
|
|
105
|
+
export declare function getOpFee(client: PublicClient, config: DataPortabilityGatewayConfig, opts?: FeeRegistryOptions): Promise<OpFee>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { parseAbi } from "viem";
|
|
2
|
+
const FEE_REGISTRY_ABI = parseAbi([
|
|
3
|
+
"struct Fee { uint256 amount; address asset; address payee; bool enabled; }",
|
|
4
|
+
"function fees(bytes32 operation) view returns (Fee)",
|
|
5
|
+
"function operationKey(string name) pure returns (bytes32)"
|
|
6
|
+
]);
|
|
7
|
+
function operationNameFor(kind, opts) {
|
|
8
|
+
if (kind === "registration") {
|
|
9
|
+
return opts?.registrationOpName ?? "registration";
|
|
10
|
+
}
|
|
11
|
+
return opts?.dataAccessOpName ?? "data_access";
|
|
12
|
+
}
|
|
13
|
+
async function getFee(client, config, kind, opts) {
|
|
14
|
+
const address = config.contracts.feeRegistry;
|
|
15
|
+
const opName = operationNameFor(kind, opts);
|
|
16
|
+
const opKey = await client.readContract({
|
|
17
|
+
address,
|
|
18
|
+
abi: FEE_REGISTRY_ABI,
|
|
19
|
+
functionName: "operationKey",
|
|
20
|
+
args: [opName]
|
|
21
|
+
});
|
|
22
|
+
const fee = await client.readContract({
|
|
23
|
+
address,
|
|
24
|
+
abi: FEE_REGISTRY_ABI,
|
|
25
|
+
functionName: "fees",
|
|
26
|
+
args: [opKey]
|
|
27
|
+
});
|
|
28
|
+
if (!fee.enabled) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`FeeRegistry: operation "${opName}" (kind=${kind}) is not enabled \u2014 operator must call setFeeByName before payments will validate`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
if (fee.payee === "0x0000000000000000000000000000000000000000") {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`FeeRegistry: operation "${opName}" has zero-address payee \u2014 contract pre-flight rejects payouts to 0x0`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return fee;
|
|
39
|
+
}
|
|
40
|
+
async function getOpFee(client, config, opts) {
|
|
41
|
+
const [registration, dataAccess] = await Promise.all([
|
|
42
|
+
getFee(client, config, "registration", opts),
|
|
43
|
+
getFee(client, config, "data_access", opts)
|
|
44
|
+
]);
|
|
45
|
+
if (registration.asset.toLowerCase() !== dataAccess.asset.toLowerCase()) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`FeeRegistry asset mismatch: registration=${registration.asset} vs data_access=${dataAccess.asset}. The gateway requires both fees to settle in the same asset.`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
asset: registration.asset,
|
|
52
|
+
registrationFee: registration.amount,
|
|
53
|
+
dataAccessFee: dataAccess.amount,
|
|
54
|
+
registrationPayee: registration.payee,
|
|
55
|
+
dataAccessPayee: dataAccess.payee
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
FEE_REGISTRY_ABI,
|
|
60
|
+
getFee,
|
|
61
|
+
getOpFee
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=fee-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/protocol/fee-registry.ts"],"sourcesContent":["/**\n * Adapter for the on-chain FeeRegistry contract — the source of truth the\n * gateway re-reads on every /v1/escrow/pay to size the payment amount.\n *\n * The registry stores per-operation `{amount, asset, payee, enabled}`\n * records keyed on `keccak256(name)`. SDK consumers (builders sizing\n * payments) MUST read fees from this contract rather than hardcoding\n * them, or the signed `amount` won't match the gateway's expected total\n * and /v1/escrow/pay returns 400.\n *\n * Two operation names are wired up today:\n * - 'registration' — one-time fee charged the first time a payment\n * lands for a grant in 'pending' payment_status.\n * - 'data_access' — per-access fee charged every accepted payment.\n *\n * Deployers can override the on-chain operation names via the gateway's\n * FEE_REGISTRY_REGISTRATION_OP / FEE_REGISTRY_DATA_ACCESS_OP env vars;\n * the matching SDK escape hatch is the `opts.registrationOpName` /\n * `opts.dataAccessOpName` arguments.\n *\n * This module is signer/transport-agnostic — callers pass in their own\n * `PublicClient` for the contract reads. No caching here; a long-running\n * service consumer should wrap with their own TTL. Mirrors\n * data-gateway/lib/fee-registry.ts byte-for-byte.\n *\n * @category Protocol\n */\nimport { parseAbi, type Address, type Hex, type PublicClient } from \"viem\";\nimport type { DataPortabilityGatewayConfig } from \"./eip712\";\n\nexport const FEE_REGISTRY_ABI = parseAbi([\n \"struct Fee { uint256 amount; address asset; address payee; bool enabled; }\",\n \"function fees(bytes32 operation) view returns (Fee)\",\n \"function operationKey(string name) pure returns (bytes32)\",\n]);\n\nexport type FeeKind = \"registration\" | \"data_access\";\n\nexport interface FeeEntry {\n amount: bigint;\n // Asset the fee is denominated in. 0x0000…0000 = native VANA;\n // anything else is an ERC-20 contract address.\n asset: Address;\n // The recipient the on-chain settle pass routes the fee to.\n payee: Address;\n enabled: boolean;\n}\n\n// Combined view that mirrors data-gateway/lib/op-fees.ts. Throws if the two\n// kinds disagree on `asset` because the pay handler accepts a single\n// `asset` on the payment payload — both fees must settle in the same one.\n// Payees can differ (registration → one treasury, data-access → another).\nexport interface OpFee {\n asset: Address;\n registrationFee: bigint;\n dataAccessFee: bigint;\n registrationPayee: Address;\n dataAccessPayee: Address;\n}\n\nexport interface FeeRegistryOptions {\n registrationOpName?: string;\n dataAccessOpName?: string;\n}\n\nfunction operationNameFor(\n kind: FeeKind,\n opts: FeeRegistryOptions | undefined,\n): string {\n if (kind === \"registration\") {\n return opts?.registrationOpName ?? \"registration\";\n }\n return opts?.dataAccessOpName ?? \"data_access\";\n}\n\n/**\n * Reads one fee kind from the FeeRegistry. Calls the contract's\n * `operationKey(name)` first to derive the bytes32 key — matches the\n * gateway's approach exactly (could compute locally via keccak256, but\n * going through the contract eliminates any chance of encoding drift).\n *\n * Throws when:\n * - the fee record's `enabled` flag is false (operator hasn't set it),\n * - or the `payee` is the zero address (the contract's settle pre-flight\n * rejects payouts to 0x0; surfacing it early gives a better error).\n */\nexport async function getFee(\n client: PublicClient,\n config: DataPortabilityGatewayConfig,\n kind: FeeKind,\n opts?: FeeRegistryOptions,\n): Promise<FeeEntry> {\n const address = config.contracts.feeRegistry as Address;\n const opName = operationNameFor(kind, opts);\n\n const opKey = (await client.readContract({\n address,\n abi: FEE_REGISTRY_ABI,\n functionName: \"operationKey\",\n args: [opName],\n })) as Hex;\n\n const fee = (await client.readContract({\n address,\n abi: FEE_REGISTRY_ABI,\n functionName: \"fees\",\n args: [opKey],\n })) as FeeEntry;\n\n if (!fee.enabled) {\n throw new Error(\n `FeeRegistry: operation \"${opName}\" (kind=${kind}) is not enabled — operator must call setFeeByName before payments will validate`,\n );\n }\n if (fee.payee === \"0x0000000000000000000000000000000000000000\") {\n throw new Error(\n `FeeRegistry: operation \"${opName}\" has zero-address payee — contract pre-flight rejects payouts to 0x0`,\n );\n }\n\n return fee;\n}\n\n/**\n * Convenience: read both fee kinds and combine into the shape the pay\n * handler validates against. Throws if the two kinds disagree on asset\n * (the gateway requires both to settle in the same one).\n *\n * Builders use this at startup, then sign `amount = registrationFee +\n * dataAccessFee` for the first grant payment and `amount = dataAccessFee`\n * for subsequent ones.\n */\nexport async function getOpFee(\n client: PublicClient,\n config: DataPortabilityGatewayConfig,\n opts?: FeeRegistryOptions,\n): Promise<OpFee> {\n const [registration, dataAccess] = await Promise.all([\n getFee(client, config, \"registration\", opts),\n getFee(client, config, \"data_access\", opts),\n ]);\n if (registration.asset.toLowerCase() !== dataAccess.asset.toLowerCase()) {\n throw new Error(\n `FeeRegistry asset mismatch: registration=${registration.asset} vs data_access=${dataAccess.asset}. The gateway requires both fees to settle in the same asset.`,\n );\n }\n return {\n asset: registration.asset,\n registrationFee: registration.amount,\n dataAccessFee: dataAccess.amount,\n registrationPayee: registration.payee,\n dataAccessPayee: dataAccess.payee,\n };\n}\n"],"mappings":"AA2BA,SAAS,gBAA2D;AAG7D,MAAM,mBAAmB,SAAS;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA+BD,SAAS,iBACP,MACA,MACQ;AACR,MAAI,SAAS,gBAAgB;AAC3B,WAAO,MAAM,sBAAsB;AAAA,EACrC;AACA,SAAO,MAAM,oBAAoB;AACnC;AAaA,eAAsB,OACpB,QACA,QACA,MACA,MACmB;AACnB,QAAM,UAAU,OAAO,UAAU;AACjC,QAAM,SAAS,iBAAiB,MAAM,IAAI;AAE1C,QAAM,QAAS,MAAM,OAAO,aAAa;AAAA,IACvC;AAAA,IACA,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,MAAM;AAAA,EACf,CAAC;AAED,QAAM,MAAO,MAAM,OAAO,aAAa;AAAA,IACrC;AAAA,IACA,KAAK;AAAA,IACL,cAAc;AAAA,IACd,MAAM,CAAC,KAAK;AAAA,EACd,CAAC;AAED,MAAI,CAAC,IAAI,SAAS;AAChB,UAAM,IAAI;AAAA,MACR,2BAA2B,MAAM,WAAW,IAAI;AAAA,IAClD;AAAA,EACF;AACA,MAAI,IAAI,UAAU,8CAA8C;AAC9D,UAAM,IAAI;AAAA,MACR,2BAA2B,MAAM;AAAA,IACnC;AAAA,EACF;AAEA,SAAO;AACT;AAWA,eAAsB,SACpB,QACA,QACA,MACgB;AAChB,QAAM,CAAC,cAAc,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,IACnD,OAAO,QAAQ,QAAQ,gBAAgB,IAAI;AAAA,IAC3C,OAAO,QAAQ,QAAQ,eAAe,IAAI;AAAA,EAC5C,CAAC;AACD,MAAI,aAAa,MAAM,YAAY,MAAM,WAAW,MAAM,YAAY,GAAG;AACvE,UAAM,IAAI;AAAA,MACR,4CAA4C,aAAa,KAAK,mBAAmB,WAAW,KAAK;AAAA,IACnG;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,aAAa;AAAA,IACpB,iBAAiB,aAAa;AAAA,IAC9B,eAAe,WAAW;AAAA,IAC1B,mBAAmB,aAAa;AAAA,IAChC,iBAAiB,WAAW;AAAA,EAC9B;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|