vana-cli 0.15.1 → 0.23.4

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 (93) hide show
  1. package/README.md +73 -15
  2. package/dist/cli/app/ask.d.ts +38 -0
  3. package/dist/cli/app/ask.d.ts.map +1 -0
  4. package/dist/cli/app/ask.js +110 -0
  5. package/dist/cli/app/ask.js.map +1 -0
  6. package/dist/cli/app/derivatives.d.ts +41 -0
  7. package/dist/cli/app/derivatives.d.ts.map +1 -0
  8. package/dist/cli/app/derivatives.js +227 -0
  9. package/dist/cli/app/derivatives.js.map +1 -0
  10. package/dist/cli/app/escrow.d.ts +44 -0
  11. package/dist/cli/app/escrow.d.ts.map +1 -0
  12. package/dist/cli/app/escrow.js +275 -0
  13. package/dist/cli/app/escrow.js.map +1 -0
  14. package/dist/cli/app/index.d.ts +11 -0
  15. package/dist/cli/app/index.d.ts.map +1 -0
  16. package/dist/cli/app/index.js +151 -0
  17. package/dist/cli/app/index.js.map +1 -0
  18. package/dist/cli/app/onchain.d.ts +14 -0
  19. package/dist/cli/app/onchain.d.ts.map +1 -0
  20. package/dist/cli/app/onchain.js +84 -0
  21. package/dist/cli/app/onchain.js.map +1 -0
  22. package/dist/cli/app/outcome.d.ts +45 -0
  23. package/dist/cli/app/outcome.d.ts.map +1 -0
  24. package/dist/cli/app/outcome.js +55 -0
  25. package/dist/cli/app/outcome.js.map +1 -0
  26. package/dist/cli/app/read.d.ts +43 -0
  27. package/dist/cli/app/read.d.ts.map +1 -0
  28. package/dist/cli/app/read.js +429 -0
  29. package/dist/cli/app/read.js.map +1 -0
  30. package/dist/cli/app/register.d.ts +34 -0
  31. package/dist/cli/app/register.d.ts.map +1 -0
  32. package/dist/cli/app/register.js +113 -0
  33. package/dist/cli/app/register.js.map +1 -0
  34. package/dist/cli/app/request.d.ts +50 -0
  35. package/dist/cli/app/request.d.ts.map +1 -0
  36. package/dist/cli/app/request.js +252 -0
  37. package/dist/cli/app/request.js.map +1 -0
  38. package/dist/cli/app/requests.d.ts +21 -0
  39. package/dist/cli/app/requests.d.ts.map +1 -0
  40. package/dist/cli/app/requests.js +163 -0
  41. package/dist/cli/app/requests.js.map +1 -0
  42. package/dist/cli/app/whoami.d.ts +13 -0
  43. package/dist/cli/app/whoami.d.ts.map +1 -0
  44. package/dist/cli/app/whoami.js +71 -0
  45. package/dist/cli/app/whoami.js.map +1 -0
  46. package/dist/cli/auth.d.ts +18 -0
  47. package/dist/cli/auth.d.ts.map +1 -1
  48. package/dist/cli/auth.js +82 -4
  49. package/dist/cli/auth.js.map +1 -1
  50. package/dist/cli/index.d.ts +2 -2
  51. package/dist/cli/index.d.ts.map +1 -1
  52. package/dist/cli/index.js +304 -54
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/cli/mcp-server.d.ts.map +1 -1
  55. package/dist/cli/mcp-server.js +32 -3
  56. package/dist/cli/mcp-server.js.map +1 -1
  57. package/dist/core/app-key.d.ts +50 -0
  58. package/dist/core/app-key.d.ts.map +1 -0
  59. package/dist/core/app-key.js +171 -0
  60. package/dist/core/app-key.js.map +1 -0
  61. package/dist/core/assets.d.ts +33 -0
  62. package/dist/core/assets.d.ts.map +1 -0
  63. package/dist/core/assets.js +87 -0
  64. package/dist/core/assets.js.map +1 -0
  65. package/dist/core/cli-types.d.ts +30 -0
  66. package/dist/core/cli-types.d.ts.map +1 -1
  67. package/dist/core/cli-types.js +16 -0
  68. package/dist/core/cli-types.js.map +1 -1
  69. package/dist/core/exit-codes.d.ts +48 -0
  70. package/dist/core/exit-codes.d.ts.map +1 -0
  71. package/dist/core/exit-codes.js +96 -0
  72. package/dist/core/exit-codes.js.map +1 -0
  73. package/dist/core/network.d.ts +52 -0
  74. package/dist/core/network.d.ts.map +1 -0
  75. package/dist/core/network.js +83 -0
  76. package/dist/core/network.js.map +1 -0
  77. package/dist/core/paths.d.ts +4 -2
  78. package/dist/core/paths.d.ts.map +1 -1
  79. package/dist/core/paths.js +8 -6
  80. package/dist/core/paths.js.map +1 -1
  81. package/dist/core/receipts.d.ts +37 -0
  82. package/dist/core/receipts.d.ts.map +1 -0
  83. package/dist/core/receipts.js +72 -0
  84. package/dist/core/receipts.js.map +1 -0
  85. package/dist/core/requests-store.d.ts +54 -0
  86. package/dist/core/requests-store.d.ts.map +1 -0
  87. package/dist/core/requests-store.js +83 -0
  88. package/dist/core/requests-store.js.map +1 -0
  89. package/dist/personal-server/registered.d.ts +25 -0
  90. package/dist/personal-server/registered.d.ts.map +1 -0
  91. package/dist/personal-server/registered.js +49 -0
  92. package/dist/personal-server/registered.js.map +1 -0
  93. package/package.json +2 -2
package/README.md CHANGED
@@ -1,37 +1,95 @@
1
- # OpenDataLabs Context Gateway JavaScript SDK
1
+ # Vana CLI
2
2
 
3
- `vana-cli` is the JavaScript client SDK for
4
- [OpenDataLabs Context Gateway](https://www.opendatalabs.com/context-gateway).
5
- Use it to let users connect their own data to your app.
3
+ `vana` is the command line for Vana: it collects a person's own data into
4
+ their Personal Server, and it drives the builder side of the protocol so an
5
+ app or an agent can ask for that data, read it, and pay for it from a
6
+ terminal.
6
7
 
7
- ## CLI
8
+ This repository also ships the JavaScript SDK the CLI is built on, which is
9
+ documented further down.
8
10
 
9
- The `vana` CLI collects your personal data from any platform. See the **[CLI README](./cli/README.md)**.
11
+ ## Install
10
12
 
11
- Install on macOS with Homebrew:
13
+ Run it without installing anything:
12
14
 
13
15
  ```bash
14
- brew tap vana-com/tap
15
- brew install vana
16
- vana status
16
+ npx vana-cli status
17
17
  ```
18
18
 
19
- Or use the hosted prerelease installer on macOS/Linux:
19
+ Or install the standalone binary, which is signed and notarized on macOS:
20
20
 
21
21
  ```bash
22
22
  curl -fsSL https://raw.githubusercontent.com/vana-com/vana-cli/main/install/install.sh | sh
23
+ vana status
23
24
  ```
24
25
 
25
- Branch prerelease:
26
+ Windows uses `install/install.ps1`. Homebrew (`brew tap vana-com/tap && brew
27
+ install vana`) is still published but lags the installer.
28
+
29
+ The npm route runs under your own Node, which some endpoint security
30
+ products prefer over an unknown executable; the installer gives you a
31
+ single self-contained binary with no Node required. Both are the same CLI.
26
32
 
27
- - `https://github.com/vana-com/vana-cli/releases/tag/canary-feat-connect-cli-v1`
33
+ ## Two halves
28
34
 
29
- Once installed:
35
+ **Owner side** collects your own data and keeps it in your Personal Server:
30
36
 
31
37
  ```bash
32
- vana connect linkedin
38
+ vana login # Vana account, or --server <url> for a self-hosted PS
39
+ vana connect github # managed browser, collects, syncs to your server
40
+ vana data show github # what was collected
41
+ vana server status # your server, local and registered URLs
33
42
  ```
34
43
 
44
+ **Builder side** is what an app or an agent uses to work with someone
45
+ else's data, with their consent:
46
+
47
+ ```bash
48
+ vana app register # once per machine
49
+ vana app request --scopes github.repositories # prints an approval URL, waits
50
+ vana app read github.repositories --grant <id> # signed read
51
+ ```
52
+
53
+ `request` returns the grant id once the person approves. `read` stops at
54
+ exit 4 with the exact price before spending anything; add `--pay` to settle
55
+ it from escrow and `--max-fee` to cap it. The rest of the group:
56
+
57
+ | Command | What it does |
58
+ | ---------------------------------------------------- | ------------------------------------------------------------------------------- |
59
+ | `vana app ask "<q>" --sources a,b --derived <scope>` | ask a question computed on the person's own server, without reading the sources |
60
+ | `vana app status <derived-scope>` | is the answer coming, and when |
61
+ | `vana app lineage <scope>` | what an answer was computed from, redacted where it must be |
62
+ | `vana app whoami` | app address, key source, network, registration state |
63
+ | `vana app requests list\|show <id>` | what was asked, what was approved |
64
+ | `vana app escrow balance\|fund` | what the app can spend, and funding it |
65
+ | `vana app onchain <scope> --owner <addr>` | data point version, hashes, deletion state |
66
+
67
+ Everything defaults to **moksha**, the testnet; `--network mainnet` spends
68
+ real money and is never implied.
69
+
70
+ ## For agents
71
+
72
+ Every command takes `--json` and `--no-input`, and exits with a code an
73
+ agent can branch on: `0` done, `1` failed, `2` bad usage, `3` no grant,
74
+ `4` payment required, `5` no server answered, `6` not ready yet, `7` a
75
+ person has to act. The full contract is in
76
+ [docs/CLI-EXIT-CODE-MATRIX.md](./docs/CLI-EXIT-CODE-MATRIX.md).
77
+
78
+ Install the skills that teach an agent each half:
79
+
80
+ ```bash
81
+ vana skills install builder # ask for access, read, pay
82
+ vana skills install connect-data # collect your own data
83
+ ```
84
+
85
+ There is also an MCP server over stdio for clients that prefer tools:
86
+
87
+ ```bash
88
+ claude mcp add vana -- vana mcp
89
+ ```
90
+
91
+ ## The SDK
92
+
35
93
  ## What problem this solves
36
94
 
37
95
  Your users already have rich personal data — ChatGPT conversations, Instagram activity, Gmail, purchase history — but it's locked inside the platforms that collected it. As a builder, you can't easily use that data to personalize onboarding, tailor recommendations, or skip lengthy signup forms.
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `vana app ask "<question>" --sources a,b --derived <scope>`
3
+ *
4
+ * The consent path by default: the question travels inside an access
5
+ * request, so the person approves the question itself and the app ends up
6
+ * holding a grant on the answer rather than on the sources it was computed
7
+ * from. `--registered` switches to the builder-registered path, which needs
8
+ * a read grant on every source scope and says so.
9
+ *
10
+ * This composes commands that already exist rather than reimplementing
11
+ * them: it creates the request, waits for the answer to settle, and reads
12
+ * the derived scope through the same escrow path, gates and receipts as any
13
+ * other read. Costs are reported separately (see derivatives.ts).
14
+ */
15
+ import { type AppCommandOptions } from "./outcome.js";
16
+ import { runAppRead } from "./read.js";
17
+ import { runAppRequest } from "./request.js";
18
+ import { runAppStatus } from "./derivatives.js";
19
+ export interface AskCommandOptions extends AppCommandOptions {
20
+ sources?: string;
21
+ derived?: string;
22
+ /** Settle the derived-scope read from escrow. */
23
+ pay?: boolean;
24
+ maxFee?: string;
25
+ timeout?: string;
26
+ /**
27
+ * Register the question as a builder instead of carrying it through
28
+ * consent. Needs a read grant on every source scope.
29
+ */
30
+ registered?: boolean;
31
+ }
32
+ export interface AskDeps {
33
+ request?: typeof runAppRequest;
34
+ status?: typeof runAppStatus;
35
+ read?: typeof runAppRead;
36
+ }
37
+ export declare function runAppAsk(question: string, options: AskCommandOptions, deps?: AskDeps): Promise<number>;
38
+ //# sourceMappingURL=ask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../../src/cli/app/ask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,UAAU,EAA2B,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,aAAa,EAA8B,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgBhD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,EAAE,OAAO,aAAa,CAAC;IAC/B,MAAM,CAAC,EAAE,OAAO,YAAY,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,UAAU,CAAC;CAC1B;AAED,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,OAAY,GACjB,OAAO,CAAC,MAAM,CAAC,CA0FjB"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * `vana app ask "<question>" --sources a,b --derived <scope>`
3
+ *
4
+ * The consent path by default: the question travels inside an access
5
+ * request, so the person approves the question itself and the app ends up
6
+ * holding a grant on the answer rather than on the sources it was computed
7
+ * from. `--registered` switches to the builder-registered path, which needs
8
+ * a read grant on every source scope and says so.
9
+ *
10
+ * This composes commands that already exist rather than reimplementing
11
+ * them: it creates the request, waits for the answer to settle, and reads
12
+ * the derived scope through the same escrow path, gates and receipts as any
13
+ * other read. Costs are reported separately (see derivatives.ts).
14
+ */
15
+ import { UnknownNetworkError, resolveNetwork, } from "../../core/network.js";
16
+ import { emitAppOutcome } from "./outcome.js";
17
+ import { runAppRead } from "./read.js";
18
+ import { runAppRequest } from "./request.js";
19
+ import { runAppStatus } from "./derivatives.js";
20
+ import { createRequestsStore } from "../../core/requests-store.js";
21
+ /** Newest approved grant covering a scope, from the local request index. */
22
+ function findGrantForScope(scope, network) {
23
+ return (createRequestsStore()
24
+ .list({ network })
25
+ .find((entry) => Boolean(entry.grantId) &&
26
+ (entry.approvedScopes ?? entry.scopes).includes(scope))?.grantId ?? null);
27
+ }
28
+ export async function runAppAsk(question, options, deps = {}) {
29
+ let network;
30
+ try {
31
+ network = resolveNetwork(options.network);
32
+ }
33
+ catch (error) {
34
+ if (error instanceof UnknownNetworkError) {
35
+ return emitAppOutcome(options, {
36
+ status: "failed",
37
+ code: "bad_usage",
38
+ message: error.message,
39
+ });
40
+ }
41
+ throw error;
42
+ }
43
+ const sources = (options.sources ?? "")
44
+ .split(",")
45
+ .map((entry) => entry.trim())
46
+ .filter(Boolean);
47
+ if (!question.trim() || sources.length === 0 || !options.derived) {
48
+ return emitAppOutcome(options, {
49
+ status: "failed",
50
+ code: "bad_usage",
51
+ message: "ask needs a question, --sources and --derived.",
52
+ remedy: `vana app ask "..." --sources spotify.history --derived myapp.summary`,
53
+ network: network.name,
54
+ });
55
+ }
56
+ if (options.registered) {
57
+ // Honest refusal rather than a half-path: registering a question as the
58
+ // builder requires a read grant on every source scope, which is exactly
59
+ // the access the consent path is designed to avoid. Until someone needs
60
+ // it, say so instead of pretending.
61
+ return emitAppOutcome(options, {
62
+ status: "failed",
63
+ code: "bad_usage",
64
+ message: "--registered is not wired yet. It needs a read grant on every source scope, which the consent path deliberately avoids.",
65
+ remedy: `drop --registered to ask through consent`,
66
+ network: network.name,
67
+ });
68
+ }
69
+ // 1. Ask the person. The derived scope must also be granted as a plain
70
+ // read so the answer can be read back; request validates that.
71
+ const requestOptions = {
72
+ ...options,
73
+ scopes: [...sources, options.derived].join(","),
74
+ question,
75
+ derived: options.derived,
76
+ sources: options.sources,
77
+ };
78
+ const requestExit = await (deps.request ?? runAppRequest)(requestOptions);
79
+ if (requestExit !== 0) {
80
+ // request already emitted a precise outcome (7 when a person must act,
81
+ // 3 on denial, 6 on timeout); nothing to add.
82
+ return requestExit;
83
+ }
84
+ // 2. Wait for the answer to settle on the owner's server.
85
+ const statusExit = await (deps.status ?? runAppStatus)(options.derived, options);
86
+ if (statusExit !== 0) {
87
+ return statusExit;
88
+ }
89
+ // 3. Read the answer, through the ordinary billable read path. The grant
90
+ // comes from the request just approved; read resolves the owner and the
91
+ // server from it.
92
+ const grantId = findGrantForScope(options.derived, network.name);
93
+ if (!grantId) {
94
+ return emitAppOutcome(options, {
95
+ status: "failed",
96
+ code: "grant_invalid",
97
+ message: "The request was approved but no grant id was recorded.",
98
+ remedy: "vana app requests list",
99
+ network: network.name,
100
+ });
101
+ }
102
+ const readOptions = {
103
+ ...options,
104
+ grant: grantId,
105
+ pay: options.pay,
106
+ maxFee: options.maxFee,
107
+ };
108
+ return (deps.read ?? runAppRead)(options.derived, readOptions);
109
+ }
110
+ //# sourceMappingURL=ask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/cli/app/ask.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * `vana app ask | status | lineage` - questions over a person's data.
3
+ *
4
+ * A question is computed on the owner's own Personal Server over source
5
+ * scopes the app never reads, and the answer is written into a derived
6
+ * scope the app does read. That is why `ask` goes through consent: the
7
+ * question travels inside the access request, so the app holds a grant on
8
+ * the answer rather than on the sources.
9
+ *
10
+ * Pricing note. Two separate costs live here and the CLI reports them
11
+ * separately rather than folding them into one number, because only one of
12
+ * them exists today and the other is an open decision:
13
+ *
14
+ * - the compute itself emits no fee event today, so it is reported as
15
+ * `computeCost: null` rather than as free; when a price appears it is a
16
+ * number in a field that already exists
17
+ * - reading the derived scope afterwards is an ordinary billable read and
18
+ * goes through the same escrow path, gates and receipts as any other
19
+ *
20
+ * No price is hardcoded anywhere: every amount comes from what the
21
+ * protocol quotes.
22
+ */
23
+ import { getDerivativeStatus, getLineage } from "@opendatalabs/vana-sdk";
24
+ import { resolveAppKey } from "../../core/app-key.js";
25
+ import { type RequestsStore } from "../../core/requests-store.js";
26
+ import { type AppCommandOptions } from "./outcome.js";
27
+ export interface DerivativeCommandOptions extends AppCommandOptions {
28
+ /** Grant covering the derived scope; resolved from the store when absent. */
29
+ grant?: string;
30
+ /** Personal Server URL; resolved from the stored request when absent. */
31
+ server?: string;
32
+ }
33
+ export interface DerivativeDeps {
34
+ resolveKey?: typeof resolveAppKey;
35
+ requests?: RequestsStore;
36
+ status?: typeof getDerivativeStatus;
37
+ lineage?: typeof getLineage;
38
+ }
39
+ export declare function runAppStatus(derivedScope: string, options: DerivativeCommandOptions, deps?: DerivativeDeps): Promise<number>;
40
+ export declare function runAppLineage(scope: string, options: DerivativeCommandOptions, deps?: DerivativeDeps): Promise<number>;
41
+ //# sourceMappingURL=derivatives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivatives.d.ts","sourceRoot":"","sources":["../../../src/cli/app/derivatives.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,mBAAmB,EACnB,UAAU,EAEX,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAEL,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtE,MAAM,WAAW,wBAAyB,SAAQ,iBAAiB;IACjE,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,OAAO,aAAa,CAAC;IAClC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC;CAC7B;AAwHD,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,wBAAwB,EACjC,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CA6DjB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,wBAAwB,EACjC,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * `vana app ask | status | lineage` - questions over a person's data.
3
+ *
4
+ * A question is computed on the owner's own Personal Server over source
5
+ * scopes the app never reads, and the answer is written into a derived
6
+ * scope the app does read. That is why `ask` goes through consent: the
7
+ * question travels inside the access request, so the app holds a grant on
8
+ * the answer rather than on the sources.
9
+ *
10
+ * Pricing note. Two separate costs live here and the CLI reports them
11
+ * separately rather than folding them into one number, because only one of
12
+ * them exists today and the other is an open decision:
13
+ *
14
+ * - the compute itself emits no fee event today, so it is reported as
15
+ * `computeCost: null` rather than as free; when a price appears it is a
16
+ * number in a field that already exists
17
+ * - reading the derived scope afterwards is an ordinary billable read and
18
+ * goes through the same escrow path, gates and receipts as any other
19
+ *
20
+ * No price is hardcoded anywhere: every amount comes from what the
21
+ * protocol quotes.
22
+ */
23
+ import { getDerivativeStatus, getLineage, isDerivativeStatusSettled, } from "@opendatalabs/vana-sdk";
24
+ import { privateKeyToAccount } from "viem/accounts";
25
+ import { AppKeyMissingError, resolveAppKey, } from "../../core/app-key.js";
26
+ import { UnknownNetworkError, resolveNetwork, } from "../../core/network.js";
27
+ import { createRequestsStore, } from "../../core/requests-store.js";
28
+ import { emitAppOutcome } from "./outcome.js";
29
+ /**
30
+ * Resolve what a derivative call needs: the network, the app key, a grant
31
+ * covering the derived scope and the server that holds it. Explicit flags
32
+ * win; otherwise the newest approved request that covers the scope answers
33
+ * both, which is how `ask` hands off to `status` without the caller
34
+ * carrying ids around.
35
+ */
36
+ function resolveContext(derivedScope, options, deps) {
37
+ let network;
38
+ try {
39
+ network = resolveNetwork(options.network);
40
+ }
41
+ catch (error) {
42
+ if (error instanceof UnknownNetworkError) {
43
+ return {
44
+ ok: false,
45
+ exitCode: emitAppOutcome(options, {
46
+ status: "failed",
47
+ code: "bad_usage",
48
+ message: error.message,
49
+ }),
50
+ };
51
+ }
52
+ throw error;
53
+ }
54
+ let key;
55
+ try {
56
+ key = (deps.resolveKey ?? resolveAppKey)({});
57
+ }
58
+ catch (error) {
59
+ if (error instanceof AppKeyMissingError) {
60
+ return {
61
+ ok: false,
62
+ exitCode: emitAppOutcome(options, {
63
+ status: "failed",
64
+ code: "bad_usage",
65
+ message: "No app key on this machine yet.",
66
+ remedy: "vana app register",
67
+ network: network.name,
68
+ }),
69
+ };
70
+ }
71
+ throw error;
72
+ }
73
+ let grantId = options.grant;
74
+ let personalServerUrl = options.server;
75
+ if (!grantId || !personalServerUrl) {
76
+ const match = findApprovedRequest(derivedScope, network.name, key.address, deps.requests ?? createRequestsStore());
77
+ grantId ??= match?.grantId;
78
+ personalServerUrl ??= match?.personalServerUrl;
79
+ }
80
+ if (!grantId) {
81
+ return {
82
+ ok: false,
83
+ exitCode: emitAppOutcome(options, {
84
+ status: "failed",
85
+ code: "grant_invalid",
86
+ message: `No approved grant covering ${derivedScope}.`,
87
+ remedy: `vana app request --scopes ${derivedScope} --question "..." --derived ${derivedScope} --sources <scopes>`,
88
+ network: network.name,
89
+ }),
90
+ };
91
+ }
92
+ if (!personalServerUrl) {
93
+ return {
94
+ ok: false,
95
+ exitCode: emitAppOutcome(options, {
96
+ status: "failed",
97
+ code: "owner_not_ready",
98
+ message: "No Personal Server URL for this grant; the owner may serve through the enclave path, which derivatives do not use yet.",
99
+ remedy: "pass --server explicitly if you know the URL",
100
+ network: network.name,
101
+ }),
102
+ };
103
+ }
104
+ return {
105
+ ok: true,
106
+ context: { network, key, grantId, personalServerUrl },
107
+ };
108
+ }
109
+ function findApprovedRequest(derivedScope, network, appAddress, requests) {
110
+ return (requests
111
+ .list({ network, appAddress })
112
+ .find((entry) => Boolean(entry.grantId) &&
113
+ (entry.approvedScopes ?? entry.scopes).includes(derivedScope)) ?? null);
114
+ }
115
+ export async function runAppStatus(derivedScope, options, deps = {}) {
116
+ const resolved = resolveContext(derivedScope, options, deps);
117
+ if (!resolved.ok) {
118
+ return resolved.exitCode;
119
+ }
120
+ const { network, key, grantId, personalServerUrl } = resolved.context;
121
+ if (!options.quiet && !options.json) {
122
+ // The route is free to the caller and triggers a recompute, so a loop
123
+ // here spends the inference budget without reading anything.
124
+ process.stderr.write("Note: this route can trigger a recompute. Poll on the interval the server names, not faster.\n");
125
+ }
126
+ try {
127
+ const status = await (deps.status ?? getDerivativeStatus)({
128
+ personalServerUrl,
129
+ derivedScope,
130
+ grantId,
131
+ signer: privateKeyToAccount(key.privateKey),
132
+ });
133
+ const settled = isDerivativeStatusSettled(status);
134
+ const ready = status.status === "ready";
135
+ return emitAppOutcome(options, {
136
+ status: ready || settled ? "done" : "failed",
137
+ code: ready
138
+ ? "ok"
139
+ : status.status === "failed"
140
+ ? mapDerivativeError(status.errorCode)
141
+ : "not_ready",
142
+ message: derivativeMessage(status),
143
+ remedy: ready
144
+ ? `vana app read ${derivedScope} --grant ${grantId}`
145
+ : status.retryAfterSeconds
146
+ ? `retry in ${status.retryAfterSeconds}s`
147
+ : undefined,
148
+ network: network.name,
149
+ data: {
150
+ derivedScope,
151
+ state: status.status,
152
+ version: status.derivedVersion,
153
+ lastComputedAt: status.lastComputedAt,
154
+ errorCode: status.errorCode,
155
+ retryAfterSeconds: status.retryAfterSeconds,
156
+ // Compute emits no fee event today; null says "unknown/unpriced",
157
+ // not "free". A price lands here as a number without a shape change.
158
+ computeCost: null,
159
+ },
160
+ });
161
+ }
162
+ catch (error) {
163
+ return emitAppOutcome(options, {
164
+ status: "failed",
165
+ code: "server_unavailable",
166
+ message: `Could not read the derivative status: ${error instanceof Error ? error.message : String(error)}`,
167
+ network: network.name,
168
+ });
169
+ }
170
+ }
171
+ export async function runAppLineage(scope, options, deps = {}) {
172
+ const resolved = resolveContext(scope, options, deps);
173
+ if (!resolved.ok) {
174
+ return resolved.exitCode;
175
+ }
176
+ const { network, key, grantId, personalServerUrl } = resolved.context;
177
+ try {
178
+ const result = await (deps.lineage ?? getLineage)({
179
+ personalServerUrl,
180
+ scope,
181
+ grantId,
182
+ signer: privateKeyToAccount(key.privateKey),
183
+ });
184
+ return emitAppOutcome(options, {
185
+ status: "done",
186
+ code: "ok",
187
+ message: `Lineage for ${scope}.`,
188
+ network: network.name,
189
+ data: { scope, lineage: result },
190
+ });
191
+ }
192
+ catch (error) {
193
+ return emitAppOutcome(options, {
194
+ status: "failed",
195
+ code: "server_unavailable",
196
+ message: `Could not read the lineage: ${error instanceof Error ? error.message : String(error)}`,
197
+ network: network.name,
198
+ });
199
+ }
200
+ }
201
+ function mapDerivativeError(code) {
202
+ switch (code) {
203
+ case "grant_invalid":
204
+ return "grant_invalid";
205
+ case "source_missing":
206
+ return "scope_not_found";
207
+ case "inference_unavailable":
208
+ return "not_ready";
209
+ default:
210
+ return "internal";
211
+ }
212
+ }
213
+ function derivativeMessage(status) {
214
+ switch (status.status) {
215
+ case "ready":
216
+ return `Answer is ready (version ${status.derivedVersion ?? "?"}).`;
217
+ case "pending":
218
+ return "The answer is being computed.";
219
+ case "stale":
220
+ return "A source changed; the answer is being recomputed.";
221
+ case "failed":
222
+ return `The computation failed: ${status.errorCode ?? "unknown"}.`;
223
+ default:
224
+ return `State: ${status.status}.`;
225
+ }
226
+ }
227
+ //# sourceMappingURL=derivatives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivatives.js","sourceRoot":"","sources":["../../../src/cli/app/derivatives.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `vana app escrow balance|fund` - what the app can spend, and funding it.
3
+ *
4
+ * Funding is deliberately one command for both halves: the on-chain
5
+ * `depositNative(account)` transaction and the gateway deposit
6
+ * registration. Either half alone produces a contract that looks funded
7
+ * while every read still answers 402.
8
+ */
9
+ import { type GatewayClient } from "@opendatalabs/vana-sdk";
10
+ import { resolveAppKey, type ResolvedAppKey } from "../../core/app-key.js";
11
+ import { type ResolvedNetwork } from "../../core/network.js";
12
+ import { type AppCommandOptions } from "./outcome.js";
13
+ export interface EscrowFundOptions extends AppCommandOptions {
14
+ /** Amount to deposit, decimal, in units of the chosen asset. */
15
+ amount?: string;
16
+ /**
17
+ * ERC20 to deposit instead of native VANA. Reads are priced in USDC.e on
18
+ * mainnet, so funding native alone leaves every read answering 402.
19
+ */
20
+ asset?: string;
21
+ }
22
+ export interface EscrowDeps {
23
+ createClient?: (gatewayUrl: string) => GatewayClient;
24
+ resolveKey?: typeof resolveAppKey;
25
+ /** Injectable chain senders for tests. */
26
+ sendDeposit?: (params: {
27
+ network: ResolvedNetwork;
28
+ key: ResolvedAppKey;
29
+ escrowContract: `0x${string}`;
30
+ amountWei: bigint;
31
+ asset?: string;
32
+ }) => Promise<{
33
+ txHash: `0x${string}`;
34
+ }>;
35
+ }
36
+ export declare function runAppEscrowBalance(options: AppCommandOptions, deps?: EscrowDeps): Promise<number>;
37
+ export declare class InsufficientFundsError extends Error {
38
+ readonly balanceWei: bigint;
39
+ readonly neededWei: bigint;
40
+ readonly asset?: string | undefined;
41
+ constructor(balanceWei: bigint, neededWei: bigint, asset?: string | undefined);
42
+ }
43
+ export declare function runAppEscrowFund(options: EscrowFundOptions, deps?: EscrowDeps): Promise<number>;
44
+ //# sourceMappingURL=escrow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escrow.d.ts","sourceRoot":"","sources":["../../../src/cli/app/escrow.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAiBhC,OAAO,EAEL,aAAa,EACb,KAAK,cAAc,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtE,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,aAAa,CAAC;IACrD,UAAU,CAAC,EAAE,OAAO,aAAa,CAAC;IAClC,0CAA0C;IAC1C,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE;QACrB,OAAO,EAAE,eAAe,CAAC;QACzB,GAAG,EAAE,cAAc,CAAC;QACpB,cAAc,EAAE,KAAK,MAAM,EAAE,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC1C;AA4CD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,MAAM,CAAC,CA0CjB;AA2ED,qBAAa,sBAAuB,SAAQ,KAAK;aAE7B,UAAU,EAAE,MAAM;aAClB,SAAS,EAAE,MAAM;aACjB,KAAK,CAAC,EAAE,MAAM;gBAFd,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,YAAA;CASjC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,MAAM,CAAC,CAkHjB"}