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
@@ -0,0 +1,113 @@
1
+ /**
2
+ * `vana app register` - idempotent builder registration at the gateway.
3
+ *
4
+ * Resolves the app key (generating one on first use), checks the gateway
5
+ * first and exits 0 when the app is already registered, otherwise signs the
6
+ * EIP-712 BuilderRegistration and posts it. Safe at the top of any script.
7
+ */
8
+ import { BUILDER_REGISTRATION_TYPES, createGatewayClient, } from "@opendatalabs/vana-sdk";
9
+ import { privateKeyToAccount } from "viem/accounts";
10
+ import { resolveAppKey, InvalidAppKeyError, } from "../../core/app-key.js";
11
+ import { UnknownNetworkError, resolveNetwork, } from "../../core/network.js";
12
+ import { emitAppOutcome } from "./outcome.js";
13
+ const EIP712_DOMAIN_NAME = "Vana Data Portability";
14
+ const EIP712_DOMAIN_VERSION = "1";
15
+ export function builderRegistrationDomainFor(network) {
16
+ return {
17
+ name: EIP712_DOMAIN_NAME,
18
+ version: EIP712_DOMAIN_VERSION,
19
+ chainId: BigInt(network.chainId),
20
+ verifyingContract: network.granteesContract,
21
+ };
22
+ }
23
+ export async function signBuilderRegistration(key, network, appUrl) {
24
+ const account = privateKeyToAccount(key.privateKey);
25
+ const message = {
26
+ ownerAddress: key.address,
27
+ granteeAddress: key.address,
28
+ publicKey: key.publicKey,
29
+ appUrl,
30
+ };
31
+ const signature = await account.signTypedData({
32
+ domain: builderRegistrationDomainFor(network),
33
+ types: BUILDER_REGISTRATION_TYPES,
34
+ primaryType: "BuilderRegistration",
35
+ message,
36
+ });
37
+ return { ...message, signature };
38
+ }
39
+ export async function runAppRegister(options, deps = {}) {
40
+ let network;
41
+ try {
42
+ network = resolveNetwork(options.network);
43
+ }
44
+ catch (error) {
45
+ if (error instanceof UnknownNetworkError) {
46
+ return emitAppOutcome(options, {
47
+ status: "failed",
48
+ code: "bad_usage",
49
+ message: error.message,
50
+ });
51
+ }
52
+ throw error;
53
+ }
54
+ let key;
55
+ try {
56
+ key = (deps.resolveKey ?? resolveAppKey)({ allowGenerate: true });
57
+ }
58
+ catch (error) {
59
+ if (error instanceof InvalidAppKeyError) {
60
+ return emitAppOutcome(options, {
61
+ status: "failed",
62
+ code: "bad_usage",
63
+ message: error.message,
64
+ network: network.name,
65
+ });
66
+ }
67
+ throw error;
68
+ }
69
+ const client = (deps.createClient ?? createGatewayClient)(network.gatewayUrl);
70
+ try {
71
+ if (await client.isRegisteredBuilder(key.address)) {
72
+ return emitAppOutcome(options, {
73
+ status: "done",
74
+ code: "ok",
75
+ message: "Already registered.",
76
+ network: network.name,
77
+ data: {
78
+ address: key.address,
79
+ keySource: key.source,
80
+ alreadyRegistered: true,
81
+ },
82
+ });
83
+ }
84
+ const params = await signBuilderRegistration(key, network, options.appUrl ?? "");
85
+ const result = await client.registerBuilder(params);
86
+ return emitAppOutcome(options, {
87
+ status: "done",
88
+ code: "ok",
89
+ message: result.alreadyRegistered
90
+ ? "Already registered."
91
+ : "Builder registered.",
92
+ network: network.name,
93
+ data: {
94
+ address: key.address,
95
+ keySource: key.source,
96
+ builderId: result.builderId ?? null,
97
+ alreadyRegistered: result.alreadyRegistered,
98
+ },
99
+ });
100
+ }
101
+ catch (error) {
102
+ const message = error instanceof Error ? error.message : "Gateway request failed.";
103
+ return emitAppOutcome(options, {
104
+ status: "failed",
105
+ code: "gateway_unreachable",
106
+ message: `Builder registration failed: ${message}`,
107
+ remedy: "check connectivity to " + network.gatewayUrl + " and retry",
108
+ network: network.name,
109
+ data: { address: key.address },
110
+ });
111
+ }
112
+ }
113
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/cli/app/register.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,GAEpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,aAAa,EACb,kBAAkB,GAEnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,cAAc,GAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAA0B,MAAM,cAAc,CAAC;AAYtE,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AACnD,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAElC,MAAM,UAAU,4BAA4B,CAAC,OAAwB;IACnE,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,qBAAqB;QAC9B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAChC,iBAAiB,EAAE,OAAO,CAAC,gBAAiC;KACpD,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,GAAmB,EACnB,OAAwB,EACxB,MAAc;IAQd,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG;QACd,YAAY,EAAE,GAAG,CAAC,OAAO;QACzB,cAAc,EAAE,GAAG,CAAC,OAAO;QAC3B,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,MAAM;KACP,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC;QAC5C,MAAM,EAAE,4BAA4B,CAAC,OAAO,CAAC;QAC7C,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE,qBAAqB;QAClC,OAAO;KACR,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAA+B,EAC/B,OAAqB,EAAE;IAEvB,IAAI,OAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;YACzC,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,GAAmB,CAAC;IACxB,IAAI,CAAC;QACH,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,aAAa,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;YACxC,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,OAAO,CAAC,IAAI;aACtB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE9E,IAAI,CAAC;QACH,IAAI,MAAM,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EAAE,OAAO,CAAC,IAAI;gBACrB,IAAI,EAAE;oBACJ,OAAO,EAAE,GAAG,CAAC,OAAO;oBACpB,SAAS,EAAE,GAAG,CAAC,MAAM;oBACrB,iBAAiB,EAAE,IAAI;iBACxB;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,GAAG,EACH,OAAO,EACP,OAAO,CAAC,MAAM,IAAI,EAAE,CACrB,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACpD,OAAO,cAAc,CAAC,OAAO,EAAE;YAC7B,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,MAAM,CAAC,iBAAiB;gBAC/B,CAAC,CAAC,qBAAqB;gBACvB,CAAC,CAAC,qBAAqB;YACzB,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,IAAI,EAAE;gBACJ,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,SAAS,EAAE,GAAG,CAAC,MAAM;gBACrB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI;gBACnC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;aAC5C;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;QACrE,OAAO,cAAc,CAAC,OAAO,EAAE;YAC7B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,gCAAgC,OAAO,EAAE;YAClD,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,UAAU,GAAG,YAAY;YACpE,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;SAC/B,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `vana app request` - ask a person for access and get the grant back.
3
+ *
4
+ * The half of the loop that cannot be driven headlessly: the CLI creates
5
+ * the access request, prints the approval URL, and polls until the person
6
+ * approves, denies, or it expires. With `--no-input` it prints the URL and
7
+ * exits 7, so an agent can hand the link to a human and come back later
8
+ * with `vana app requests show <id>`.
9
+ *
10
+ * The request is persisted the moment it is created, before any approval,
11
+ * so a `--no-input` run is findable afterwards.
12
+ */
13
+ import { createDirectDataController } from "@opendatalabs/vana-sdk/server";
14
+ import { resolveAppKey } from "../../core/app-key.js";
15
+ import { type RequestsStore } from "../../core/requests-store.js";
16
+ import { type AppCommandOptions } from "./outcome.js";
17
+ export interface RequestCommandOptions extends AppCommandOptions {
18
+ scopes?: string;
19
+ /** Derivative question text, requires --derived and --sources. */
20
+ question?: string;
21
+ derived?: string;
22
+ sources?: string;
23
+ /** Where the approval UI returns the person after they decide. */
24
+ returnUrl?: string;
25
+ /** Seconds to poll before giving up. */
26
+ timeout?: string;
27
+ appId?: string;
28
+ appName?: string;
29
+ appUrl?: string;
30
+ }
31
+ export interface RequestDeps {
32
+ resolveKey?: typeof resolveAppKey;
33
+ createController?: typeof createDirectDataController;
34
+ requests?: RequestsStore;
35
+ sleep?: (ms: number) => Promise<void>;
36
+ now?: () => number;
37
+ }
38
+ /**
39
+ * The connector source shown on the approval screen.
40
+ *
41
+ * It has to come from a scope the person actually connected, not from the
42
+ * first entry in the list: with a derivative question the derived scope can
43
+ * come first, and a request for `coach.weekly,spotify.history` would ask
44
+ * the person to "Connect coach", a source that does not exist. Source
45
+ * scopes win, then any non-derived scope, and `write:` prefixes never count
46
+ * as a source name.
47
+ */
48
+ export declare function resolveSourceKey(scopes: string[], derived: string | undefined, sourceScopes: string[]): string;
49
+ export declare function runAppRequest(options: RequestCommandOptions, deps?: RequestDeps): Promise<number>;
50
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../../src/cli/app/request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAEL,aAAa,EAEd,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAEL,KAAK,aAAa,EAGnB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtE,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,OAAO,aAAa,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,0BAA0B,CAAC;IACrD,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAaD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,YAAY,EAAE,MAAM,EAAE,GACrB,MAAM,CAQR;AASD,wBAAsB,aAAa,CACjC,OAAO,EAAE,qBAAqB,EAC9B,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,CAwNjB"}
@@ -0,0 +1,252 @@
1
+ /**
2
+ * `vana app request` - ask a person for access and get the grant back.
3
+ *
4
+ * The half of the loop that cannot be driven headlessly: the CLI creates
5
+ * the access request, prints the approval URL, and polls until the person
6
+ * approves, denies, or it expires. With `--no-input` it prints the URL and
7
+ * exits 7, so an agent can hand the link to a human and come back later
8
+ * with `vana app requests show <id>`.
9
+ *
10
+ * The request is persisted the moment it is created, before any approval,
11
+ * so a `--no-input` run is findable afterwards.
12
+ */
13
+ import { createDirectDataController } from "@opendatalabs/vana-sdk/server";
14
+ import { AppKeyMissingError, resolveAppKey, } from "../../core/app-key.js";
15
+ import { UnknownNetworkError, resolveNetwork, } from "../../core/network.js";
16
+ import { createRequestsStore, } from "../../core/requests-store.js";
17
+ import { emitAppOutcome } from "./outcome.js";
18
+ const POLL_INTERVAL_MS = 3_000;
19
+ const DEFAULT_TIMEOUT_SECONDS = 600;
20
+ /** Statuses that end the poll loop. */
21
+ const TERMINAL = new Set([
22
+ "approved",
23
+ "ready_for_read",
24
+ "completed",
25
+ "denied",
26
+ "expired",
27
+ ]);
28
+ /**
29
+ * The connector source shown on the approval screen.
30
+ *
31
+ * It has to come from a scope the person actually connected, not from the
32
+ * first entry in the list: with a derivative question the derived scope can
33
+ * come first, and a request for `coach.weekly,spotify.history` would ask
34
+ * the person to "Connect coach", a source that does not exist. Source
35
+ * scopes win, then any non-derived scope, and `write:` prefixes never count
36
+ * as a source name.
37
+ */
38
+ export function resolveSourceKey(scopes, derived, sourceScopes) {
39
+ const namespace = (scope) => scope.replace(/^write:/, "").split(".")[0];
40
+ if (sourceScopes.length > 0) {
41
+ return namespace(sourceScopes[0]);
42
+ }
43
+ const plain = scopes.filter((scope) => scope !== derived);
44
+ return namespace((plain[0] ?? scopes[0]));
45
+ }
46
+ function splitList(value) {
47
+ return (value ?? "")
48
+ .split(",")
49
+ .map((entry) => entry.trim())
50
+ .filter(Boolean);
51
+ }
52
+ export async function runAppRequest(options, deps = {}) {
53
+ let network;
54
+ try {
55
+ network = resolveNetwork(options.network);
56
+ }
57
+ catch (error) {
58
+ if (error instanceof UnknownNetworkError) {
59
+ return emitAppOutcome(options, {
60
+ status: "failed",
61
+ code: "bad_usage",
62
+ message: error.message,
63
+ });
64
+ }
65
+ throw error;
66
+ }
67
+ const scopes = splitList(options.scopes);
68
+ if (scopes.length === 0) {
69
+ return emitAppOutcome(options, {
70
+ status: "failed",
71
+ code: "bad_usage",
72
+ message: "At least one scope is required.",
73
+ remedy: "vana app request --scopes github.repositories",
74
+ network: network.name,
75
+ });
76
+ }
77
+ // A question needs its derived scope granted as a plain read too, which
78
+ // the SDK validates eagerly; check it here so the error names the fix.
79
+ const sourceScopes = splitList(options.sources);
80
+ if (options.question || options.derived || sourceScopes.length > 0) {
81
+ if (!options.question || !options.derived || sourceScopes.length === 0) {
82
+ return emitAppOutcome(options, {
83
+ status: "failed",
84
+ code: "bad_usage",
85
+ message: "A derivative question needs --question, --derived and --sources together.",
86
+ network: network.name,
87
+ });
88
+ }
89
+ if (!scopes.includes(options.derived)) {
90
+ return emitAppOutcome(options, {
91
+ status: "failed",
92
+ code: "bad_usage",
93
+ message: `The derived scope ${options.derived} must also appear in --scopes as a plain read.`,
94
+ remedy: `vana app request --scopes ${[...scopes, options.derived].join(",")} ...`,
95
+ network: network.name,
96
+ });
97
+ }
98
+ }
99
+ let key;
100
+ try {
101
+ key = (deps.resolveKey ?? resolveAppKey)({});
102
+ }
103
+ catch (error) {
104
+ if (error instanceof AppKeyMissingError) {
105
+ return emitAppOutcome(options, {
106
+ status: "failed",
107
+ code: "bad_usage",
108
+ message: "No app key on this machine yet.",
109
+ remedy: "vana app register",
110
+ network: network.name,
111
+ });
112
+ }
113
+ throw error;
114
+ }
115
+ const controller = (deps.createController ?? createDirectDataController)({
116
+ // The dev host set serves moksha; production serves both networks.
117
+ env: network.env === "dev" ? "dev" : "production",
118
+ network: network.name,
119
+ appPrivateKey: key.privateKey,
120
+ app: {
121
+ id: options.appId ?? "vana-cli",
122
+ name: options.appName ?? "Vana CLI",
123
+ homepageUrl: options.appUrl ?? "https://github.com/vana-com/vana-cli",
124
+ },
125
+ source: resolveSourceKey(scopes, options.derived, sourceScopes),
126
+ scopes,
127
+ });
128
+ const requests = deps.requests ?? createRequestsStore();
129
+ let created;
130
+ try {
131
+ created = await controller.createAccessRequest({
132
+ returnUrl: options.returnUrl ?? "https://github.com/vana-com/vana-cli",
133
+ ...(options.question && options.derived
134
+ ? {
135
+ questions: [
136
+ {
137
+ derivedScope: options.derived,
138
+ sourceScopes,
139
+ question: options.question,
140
+ },
141
+ ],
142
+ }
143
+ : {}),
144
+ });
145
+ }
146
+ catch (error) {
147
+ return emitAppOutcome(options, {
148
+ status: "failed",
149
+ code: "gateway_unreachable",
150
+ message: `Could not create the access request: ${error instanceof Error ? error.message : String(error)}`,
151
+ network: network.name,
152
+ });
153
+ }
154
+ // Persist before anything can go wrong, so --no-input runs are findable.
155
+ const stored = {
156
+ requestId: created.requestId,
157
+ appAddress: key.address,
158
+ network: network.name,
159
+ gatewayUrl: network.gatewayUrl,
160
+ scopes,
161
+ approvalUrl: created.approvalUrl,
162
+ createdAt: new Date().toISOString(),
163
+ status: "pending",
164
+ updatedAt: new Date().toISOString(),
165
+ ...(created.expiresAt ? { expiresAt: created.expiresAt } : {}),
166
+ ...(options.question && options.derived
167
+ ? { questions: [{ derivedScope: options.derived, sourceScopes }] }
168
+ : {}),
169
+ };
170
+ requests.save(stored);
171
+ if (options.noInput) {
172
+ return emitAppOutcome(options, {
173
+ status: "failed",
174
+ code: "confirmation_required",
175
+ message: "A person has to approve this request.",
176
+ remedy: `send them ${created.approvalUrl}, then: vana app requests show ${created.requestId}`,
177
+ network: network.name,
178
+ data: {
179
+ requestId: created.requestId,
180
+ approvalUrl: created.approvalUrl,
181
+ scopes,
182
+ expiresAt: created.expiresAt ?? null,
183
+ },
184
+ });
185
+ }
186
+ if (!options.json && !options.quiet) {
187
+ process.stderr.write(`\n Approve at ${created.approvalUrl}\n Request ${created.requestId}\n Waiting for approval...\n\n`);
188
+ }
189
+ const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
190
+ const now = deps.now ?? (() => Date.now());
191
+ const deadline = now() + Number(options.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1000;
192
+ while (now() < deadline) {
193
+ let status;
194
+ try {
195
+ status = await controller.getAccessRequestStatus(created.requestId);
196
+ }
197
+ catch {
198
+ await sleep(POLL_INTERVAL_MS);
199
+ continue;
200
+ }
201
+ if (TERMINAL.has(status.status)) {
202
+ requests.update(created.requestId, {
203
+ status: status.status,
204
+ ...(status.grantId ? { grantId: status.grantId } : {}),
205
+ ...(status.scopes ? { approvedScopes: status.scopes } : {}),
206
+ ...(status.delivery ? { delivery: status.delivery } : {}),
207
+ ...(status.personalServerUrl
208
+ ? { personalServerUrl: status.personalServerUrl }
209
+ : {}),
210
+ });
211
+ if (status.status === "denied" || status.status === "expired") {
212
+ return emitAppOutcome(options, {
213
+ status: "failed",
214
+ code: "grant_invalid",
215
+ message: `The request was ${status.status}.`,
216
+ network: network.name,
217
+ data: { requestId: created.requestId },
218
+ });
219
+ }
220
+ const approvedScopes = status.scopes ?? scopes;
221
+ return emitAppOutcome(options, {
222
+ status: "done",
223
+ code: "ok",
224
+ message: `Approved. Grant ${status.grantId ?? "(pending id)"}.`,
225
+ remedy: status.grantId
226
+ ? `vana app read ${approvedScopes[0]} --grant ${status.grantId}`
227
+ : undefined,
228
+ network: network.name,
229
+ data: {
230
+ requestId: created.requestId,
231
+ grantId: status.grantId ?? null,
232
+ scopes: approvedScopes,
233
+ delivery: status.delivery ?? "personal_server",
234
+ personalServerUrl: status.personalServerUrl ?? null,
235
+ },
236
+ });
237
+ }
238
+ await sleep(POLL_INTERVAL_MS);
239
+ }
240
+ return emitAppOutcome(options, {
241
+ status: "failed",
242
+ code: "not_ready",
243
+ message: "Nobody approved the request in time; it is still open.",
244
+ remedy: `vana app requests show ${created.requestId}`,
245
+ network: network.name,
246
+ data: {
247
+ requestId: created.requestId,
248
+ approvalUrl: created.approvalUrl,
249
+ },
250
+ });
251
+ }
252
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../../src/cli/app/request.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,aAAa,GAEd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,cAAc,GAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,GAIpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAA0B,MAAM,cAAc,CAAC;AAyBtE,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAC/B,MAAM,uBAAuB,GAAG,GAAG,CAAC;AACpC,uCAAuC;AACvC,MAAM,QAAQ,GAAwB,IAAI,GAAG,CAAC;IAC5C,UAAU;IACV,gBAAgB;IAChB,WAAW;IACX,QAAQ;IACR,SAAS;CACV,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAgB,EAChB,OAA2B,EAC3B,YAAsB;IAEtB,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,EAAE,CAClC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;IAC1D,OAAO,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAW,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,SAAS,CAAC,KAAyB;IAC1C,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA8B,EAC9B,OAAoB,EAAE;IAEtB,IAAI,OAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;YACzC,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,cAAc,CAAC,OAAO,EAAE;YAC7B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,iCAAiC;YAC1C,MAAM,EAAE,+CAA+C;YACvD,OAAO,EAAE,OAAO,CAAC,IAAI;SACtB,CAAC,CAAC;IACL,CAAC;IAED,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvE,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,WAAW;gBACjB,OAAO,EACL,2EAA2E;gBAC7E,OAAO,EAAE,OAAO,CAAC,IAAI;aACtB,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,qBAAqB,OAAO,CAAC,OAAO,gDAAgD;gBAC7F,MAAM,EAAE,6BAA6B,CAAC,GAAG,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;gBACjF,OAAO,EAAE,OAAO,CAAC,IAAI;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,IAAI,GAAmB,CAAC;IACxB,IAAI,CAAC;QACH,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;YACxC,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,iCAAiC;gBAC1C,MAAM,EAAE,mBAAmB;gBAC3B,OAAO,EAAE,OAAO,CAAC,IAAI;aACtB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,CAAC;QACvE,mEAAmE;QACnE,GAAG,EAAE,OAAO,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY;QACjD,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,aAAa,EAAE,GAAG,CAAC,UAAU;QAC7B,GAAG,EAAE;YACH,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,UAAU;YAC/B,IAAI,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU;YACnC,WAAW,EAAE,OAAO,CAAC,MAAM,IAAI,sCAAsC;SACtE;QACD,MAAM,EAAE,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC;QAC/D,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,mBAAmB,EAAE,CAAC;IACxD,IAAI,OAAO,CAAC;IACZ,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,UAAU,CAAC,mBAAmB,CAAC;YAC7C,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,sCAAsC;YACtE,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO;gBACrC,CAAC,CAAC;oBACE,SAAS,EAAE;wBACT;4BACE,YAAY,EAAE,OAAO,CAAC,OAAO;4BAC7B,YAAY;4BACZ,QAAQ,EAAE,OAAO,CAAC,QAAQ;yBAClB;qBACX;iBACF;gBACH,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,cAAc,CAAC,OAAO,EAAE;YAC7B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,wCACP,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE;YACF,OAAO,EAAE,OAAO,CAAC,IAAI;SACtB,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,MAAM,MAAM,GAAkB;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,UAAU,EAAE,GAAG,CAAC,OAAO;QACvB,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,MAAM;QACN,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO;YACrC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE;YAClE,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEtB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,cAAc,CAAC,OAAO,EAAE;YAC7B,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,uCAAuC;YAChD,MAAM,EAAE,aAAa,OAAO,CAAC,WAAW,kCAAkC,OAAO,CAAC,SAAS,EAAE;YAC7F,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,IAAI,EAAE;gBACJ,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,MAAM;gBACN,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI;aACrC;SACF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mBAAmB,OAAO,CAAC,WAAW,mBAAmB,OAAO,CAAC,SAAS,iCAAiC,CAC5G,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GACT,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,MAAM,QAAQ,GACZ,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,uBAAuB,CAAC,GAAG,IAAI,CAAC;IAEpE,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QACxB,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,UAAU,CAAC,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE;gBACjC,MAAM,EAAE,MAAM,CAAC,MAA6B;gBAC5C,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3D,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,GAAG,CAAC,MAAM,CAAC,iBAAiB;oBAC1B,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,EAAE;oBACjD,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,cAAc,CAAC,OAAO,EAAE;oBAC7B,MAAM,EAAE,QAAQ;oBAChB,IAAI,EAAE,eAAe;oBACrB,OAAO,EAAE,mBAAmB,MAAM,CAAC,MAAM,GAAG;oBAC5C,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE;iBACvC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;YAC/C,OAAO,cAAc,CAAC,OAAO,EAAE;gBAC7B,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,mBAAmB,MAAM,CAAC,OAAO,IAAI,cAAc,GAAG;gBAC/D,MAAM,EAAE,MAAM,CAAC,OAAO;oBACpB,CAAC,CAAC,iBAAiB,cAAc,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,OAAO,EAAE;oBAChE,CAAC,CAAC,SAAS;gBACb,OAAO,EAAE,OAAO,CAAC,IAAI;gBACrB,IAAI,EAAE;oBACJ,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;oBAC/B,MAAM,EAAE,cAAc;oBACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,iBAAiB;oBAC9C,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,IAAI;iBACpD;aACF,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,cAAc,CAAC,OAAO,EAAE;QAC7B,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,wDAAwD;QACjE,MAAM,EAAE,0BAA0B,OAAO,CAAC,SAAS,EAAE;QACrD,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,IAAI,EAAE;YACJ,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `vana app requests list|show <id>` - what this machine asked for, and
3
+ * what came back.
4
+ *
5
+ * `list` reads the local index alone, so it works offline and is the way an
6
+ * agent recovers a request id it did not keep. `show` merges the local
7
+ * entry with the live status and writes back what changed, which is how a
8
+ * `--no-input` request eventually learns its grant id.
9
+ */
10
+ import { createDirectDataController } from "@opendatalabs/vana-sdk/server";
11
+ import { resolveAppKey } from "../../core/app-key.js";
12
+ import { type RequestsStore } from "../../core/requests-store.js";
13
+ import { type AppCommandOptions } from "./outcome.js";
14
+ export interface RequestsDeps {
15
+ resolveKey?: typeof resolveAppKey;
16
+ createController?: typeof createDirectDataController;
17
+ requests?: RequestsStore;
18
+ }
19
+ export declare function runAppRequestsList(options: AppCommandOptions, deps?: RequestsDeps): Promise<number>;
20
+ export declare function runAppRequestsShow(requestId: string, options: AppCommandOptions, deps?: RequestsDeps): Promise<number>;
21
+ //# sourceMappingURL=requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../../src/cli/app/requests.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,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;AAGtE,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,OAAO,aAAa,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,0BAA0B,CAAC;IACrD,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAsBD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CA4CjB;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,MAAM,CAAC,CAoGjB"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * `vana app requests list|show <id>` - what this machine asked for, and
3
+ * what came back.
4
+ *
5
+ * `list` reads the local index alone, so it works offline and is the way an
6
+ * agent recovers a request id it did not keep. `show` merges the local
7
+ * entry with the live status and writes back what changed, which is how a
8
+ * `--no-input` request eventually learns its grant id.
9
+ */
10
+ import { createDirectDataController } from "@opendatalabs/vana-sdk/server";
11
+ import { AppKeyMissingError, resolveAppKey, } from "../../core/app-key.js";
12
+ import { UnknownNetworkError, resolveNetwork, } from "../../core/network.js";
13
+ import { createRequestsStore, } from "../../core/requests-store.js";
14
+ import { emitAppOutcome } from "./outcome.js";
15
+ import { resolveSourceKey } from "./request.js";
16
+ function resolveNetworkOrFail(options) {
17
+ try {
18
+ return { ok: true, network: resolveNetwork(options.network) };
19
+ }
20
+ catch (error) {
21
+ if (error instanceof UnknownNetworkError) {
22
+ return {
23
+ ok: false,
24
+ exitCode: emitAppOutcome(options, {
25
+ status: "failed",
26
+ code: "bad_usage",
27
+ message: error.message,
28
+ }),
29
+ };
30
+ }
31
+ throw error;
32
+ }
33
+ }
34
+ export async function runAppRequestsList(options, deps = {}) {
35
+ const resolved = resolveNetworkOrFail(options);
36
+ if (!resolved.ok) {
37
+ return resolved.exitCode;
38
+ }
39
+ const { network } = resolved;
40
+ // Scoped to this app when a key exists; without one, show everything the
41
+ // machine has rather than nothing.
42
+ let appAddress;
43
+ try {
44
+ appAddress = (deps.resolveKey ?? resolveAppKey)({}).address;
45
+ }
46
+ catch (error) {
47
+ if (!(error instanceof AppKeyMissingError)) {
48
+ throw error;
49
+ }
50
+ }
51
+ const entries = (deps.requests ?? createRequestsStore()).list({
52
+ appAddress,
53
+ network: network.name,
54
+ });
55
+ return emitAppOutcome(options, {
56
+ status: "done",
57
+ code: "ok",
58
+ message: entries.length === 0
59
+ ? "No access requests from this machine yet."
60
+ : `${entries.length} access request${entries.length === 1 ? "" : "s"}.`,
61
+ remedy: entries.length === 0 ? "vana app request --scopes <scope>" : undefined,
62
+ network: network.name,
63
+ data: {
64
+ count: entries.length,
65
+ requests: entries.map((entry) => ({
66
+ requestId: entry.requestId,
67
+ status: entry.status,
68
+ scopes: entry.scopes,
69
+ grantId: entry.grantId ?? null,
70
+ createdAt: entry.createdAt,
71
+ })),
72
+ },
73
+ });
74
+ }
75
+ export async function runAppRequestsShow(requestId, options, deps = {}) {
76
+ const resolved = resolveNetworkOrFail(options);
77
+ if (!resolved.ok) {
78
+ return resolved.exitCode;
79
+ }
80
+ const { network } = resolved;
81
+ const requests = deps.requests ?? createRequestsStore();
82
+ const stored = requests.get(requestId);
83
+ if (!stored) {
84
+ return emitAppOutcome(options, {
85
+ status: "failed",
86
+ code: "bad_usage",
87
+ message: `No local record of ${requestId}.`,
88
+ remedy: "vana app requests list",
89
+ network: network.name,
90
+ });
91
+ }
92
+ let key = null;
93
+ try {
94
+ key = (deps.resolveKey ?? resolveAppKey)({});
95
+ }
96
+ catch (error) {
97
+ if (!(error instanceof AppKeyMissingError)) {
98
+ throw error;
99
+ }
100
+ }
101
+ // Refresh from the service when we can sign; offline or keyless, report
102
+ // what the local index knows rather than failing.
103
+ let live = null;
104
+ if (key) {
105
+ try {
106
+ const controller = (deps.createController ?? createDirectDataController)({
107
+ env: network.env === "dev" ? "dev" : "production",
108
+ network: network.name,
109
+ appPrivateKey: key.privateKey,
110
+ app: {
111
+ id: "vana-cli",
112
+ name: "Vana CLI",
113
+ homepageUrl: "https://github.com/vana-com/vana-cli",
114
+ },
115
+ source: resolveSourceKey(stored.scopes, stored.questions?.[0]?.derivedScope, stored.questions?.[0]?.sourceScopes ?? []),
116
+ scopes: stored.scopes,
117
+ });
118
+ live = await controller.getAccessRequestStatus(requestId);
119
+ }
120
+ catch {
121
+ live = null;
122
+ }
123
+ }
124
+ if (live) {
125
+ requests.update(requestId, {
126
+ status: live.status,
127
+ ...(live.grantId ? { grantId: live.grantId } : {}),
128
+ ...(live.scopes ? { approvedScopes: live.scopes } : {}),
129
+ ...(live.delivery ? { delivery: live.delivery } : {}),
130
+ ...(live.personalServerUrl
131
+ ? { personalServerUrl: live.personalServerUrl }
132
+ : {}),
133
+ });
134
+ }
135
+ const status = live?.status ?? stored.status;
136
+ const grantId = live?.grantId ?? stored.grantId ?? null;
137
+ const scopes = live?.scopes ?? stored.approvedScopes ?? stored.scopes;
138
+ return emitAppOutcome(options, {
139
+ status: "done",
140
+ code: "ok",
141
+ message: `${requestId}: ${status}${live ? "" : " (local record, service not reached)"}.`,
142
+ remedy: grantId
143
+ ? `vana app read ${scopes[0]} --grant ${grantId}`
144
+ : status === "pending"
145
+ ? `still waiting; approve at ${stored.approvalUrl}`
146
+ : undefined,
147
+ network: network.name,
148
+ data: {
149
+ requestId,
150
+ status,
151
+ live: Boolean(live),
152
+ scopes,
153
+ requestedScopes: stored.scopes,
154
+ grantId,
155
+ delivery: live?.delivery ?? stored.delivery ?? null,
156
+ personalServerUrl: live?.personalServerUrl ?? stored.personalServerUrl ?? null,
157
+ approvalUrl: stored.approvalUrl,
158
+ createdAt: stored.createdAt,
159
+ expiresAt: stored.expiresAt ?? null,
160
+ },
161
+ });
162
+ }
163
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/cli/app/requests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `vana app whoami` - the app identity at a glance: address, where the key
3
+ * came from, network, registration state. Never creates a key.
4
+ */
5
+ import { type GatewayClient } from "@opendatalabs/vana-sdk";
6
+ import { resolveAppKey } from "../../core/app-key.js";
7
+ import { type AppCommandOptions } from "./outcome.js";
8
+ export interface WhoamiDeps {
9
+ createClient?: (gatewayUrl: string) => GatewayClient;
10
+ resolveKey?: typeof resolveAppKey;
11
+ }
12
+ export declare function runAppWhoami(options: AppCommandOptions, deps?: WhoamiDeps): Promise<number>;
13
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/cli/app/whoami.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAGL,aAAa,EACd,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAkB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtE,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,aAAa,CAAC;IACrD,UAAU,CAAC,EAAE,OAAO,aAAa,CAAC;CACnC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,MAAM,CAAC,CA6DjB"}