@hsuite/smart-engines-cli 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -58
- package/dist/_lib/attestation.d.ts +45 -0
- package/dist/_lib/attestation.d.ts.map +1 -0
- package/dist/_lib/attestation.js +76 -0
- package/dist/_lib/attestation.js.map +1 -0
- package/dist/_lib/baas.d.ts +147 -0
- package/dist/_lib/baas.d.ts.map +1 -0
- package/dist/_lib/baas.js +260 -0
- package/dist/_lib/baas.js.map +1 -0
- package/dist/_lib/cluster.d.ts +6 -6
- package/dist/_lib/cluster.js +6 -6
- package/dist/_lib/deploy-manifest.d.ts +69 -0
- package/dist/_lib/deploy-manifest.d.ts.map +1 -0
- package/dist/_lib/deploy-manifest.js +87 -0
- package/dist/_lib/deploy-manifest.js.map +1 -0
- package/dist/_lib/docker.d.ts +82 -0
- package/dist/_lib/docker.d.ts.map +1 -0
- package/dist/_lib/docker.js +164 -0
- package/dist/_lib/docker.js.map +1 -0
- package/dist/_lib/faucet-client.d.ts +64 -0
- package/dist/_lib/faucet-client.d.ts.map +1 -0
- package/dist/_lib/faucet-client.js +92 -0
- package/dist/_lib/faucet-client.js.map +1 -0
- package/dist/_lib/framework.d.ts +59 -0
- package/dist/_lib/framework.d.ts.map +1 -0
- package/dist/_lib/framework.js +149 -0
- package/dist/_lib/framework.js.map +1 -0
- package/dist/_lib/frontend-guard.d.ts +13 -0
- package/dist/_lib/frontend-guard.d.ts.map +1 -0
- package/dist/_lib/frontend-guard.js +41 -0
- package/dist/_lib/frontend-guard.js.map +1 -0
- package/dist/_lib/registry-fanout.d.ts +114 -0
- package/dist/_lib/registry-fanout.d.ts.map +1 -0
- package/dist/_lib/registry-fanout.js +435 -0
- package/dist/_lib/registry-fanout.js.map +1 -0
- package/dist/_lib/runtime-env.d.ts +126 -0
- package/dist/_lib/runtime-env.d.ts.map +1 -0
- package/dist/_lib/runtime-env.js +172 -0
- package/dist/_lib/runtime-env.js.map +1 -0
- package/dist/_lib/subscription-client.d.ts +129 -18
- package/dist/_lib/subscription-client.d.ts.map +1 -1
- package/dist/_lib/subscription-client.js +268 -40
- package/dist/_lib/subscription-client.js.map +1 -1
- package/dist/_lib/subscription-env.d.ts +35 -0
- package/dist/_lib/subscription-env.d.ts.map +1 -1
- package/dist/_lib/subscription-env.js +46 -2
- package/dist/_lib/subscription-env.js.map +1 -1
- package/dist/commands/app-lifecycle.d.ts +36 -0
- package/dist/commands/app-lifecycle.d.ts.map +1 -0
- package/dist/commands/app-lifecycle.js +145 -0
- package/dist/commands/app-lifecycle.js.map +1 -0
- package/dist/commands/ci.d.ts +45 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +174 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/deploy-manifest.d.ts +11 -0
- package/dist/commands/deploy-manifest.d.ts.map +1 -0
- package/dist/commands/deploy-manifest.js +17 -0
- package/dist/commands/deploy-manifest.js.map +1 -0
- package/dist/commands/deploy.d.ts +70 -11
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +263 -150
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/downgrade.js +1 -1
- package/dist/commands/downgrade.js.map +1 -1
- package/dist/commands/faucet.d.ts +78 -0
- package/dist/commands/faucet.d.ts.map +1 -0
- package/dist/commands/faucet.js +184 -0
- package/dist/commands/faucet.js.map +1 -0
- package/dist/commands/governance.js +1 -1
- package/dist/commands/governance.js.map +1 -1
- package/dist/commands/hist-balance.d.ts +1 -1
- package/dist/commands/hist-balance.js +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/list.d.ts +22 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +81 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/personhood.js +2 -2
- package/dist/commands/personhood.js.map +1 -1
- package/dist/commands/redeploy.d.ts +62 -0
- package/dist/commands/redeploy.d.ts.map +1 -0
- package/dist/commands/redeploy.js +310 -0
- package/dist/commands/redeploy.js.map +1 -0
- package/dist/commands/status.d.ts +51 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +138 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/subscribe.d.ts +94 -17
- package/dist/commands/subscribe.d.ts.map +1 -1
- package/dist/commands/subscribe.js +450 -81
- package/dist/commands/subscribe.js.map +1 -1
- package/dist/commands/transactions.d.ts +60 -0
- package/dist/commands/transactions.d.ts.map +1 -0
- package/dist/commands/transactions.js +101 -0
- package/dist/commands/transactions.js.map +1 -0
- package/dist/commands/update.d.ts +40 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +114 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +10 -19
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +14 -23
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -3
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-env forwarding for `hsuite deploy` / `hsuite redeploy` (issue #1564).
|
|
3
|
+
*
|
|
4
|
+
* THE BUG THIS FIXES
|
|
5
|
+
* ------------------
|
|
6
|
+
* The CLI reads the developer's `.env.local` (`--env`) ONLY for deploy-time auth
|
|
7
|
+
* + build-attestation signing. It never forwarded those runtime vars into the
|
|
8
|
+
* deployed container — the deployed container's env came SOLELY from
|
|
9
|
+
* `manifest.backend.env`. So a subscribed app deployed credential-less: the
|
|
10
|
+
* smart-app's `BaaSAuthService` found no `XRPL_SEED` and silently booted
|
|
11
|
+
* OPEN / in-memory mode (`/baas/status` → `{"mode":"memory","appId":null}`).
|
|
12
|
+
*
|
|
13
|
+
* THE FIX
|
|
14
|
+
* -------
|
|
15
|
+
* On deploy, the runtime-relevant vars from `.env.local` are merged into the
|
|
16
|
+
* customer-env the deployer mirrors into the per-app k8s Secret, so the deployed
|
|
17
|
+
* app runs with the SAME identity + config it runs with locally. The identity is
|
|
18
|
+
* the developer's OWN XRPL wallet (`XRPL_SEED` in `.env.local`, whose address
|
|
19
|
+
* holds the subscription NFT) — there is NO separate app / protocol identity.
|
|
20
|
+
*
|
|
21
|
+
* WHAT COUNTS AS "RUNTIME-RELEVANT"
|
|
22
|
+
* ---------------------------------
|
|
23
|
+
* The source of truth is the smart-app env schema
|
|
24
|
+
* (`apps/showcase/smart-app/src/config/env-validation.ts` in the hsuite-ecosystem
|
|
25
|
+
* repo). {@link RUNTIME_ENV_KEYS} mirrors that key set. Anything not in the set —
|
|
26
|
+
* purely deploy-time / CLI-only knobs the container never reads
|
|
27
|
+
* (`DEPLOYED_APP_ID` book-keeping, `SUBSCRIPTION_NFT_SERIAL`, `VALIDATOR_API_KEY`,
|
|
28
|
+
* docker/build flags, etc.) — is NOT forwarded.
|
|
29
|
+
*
|
|
30
|
+
* The customer-env Secret is PQC-encrypted (kyber-aes-v1) at rest — that is the
|
|
31
|
+
* containment boundary. No secret is ever written into a committed manifest.
|
|
32
|
+
*/
|
|
33
|
+
import type { EnvMap } from './env';
|
|
34
|
+
/**
|
|
35
|
+
* Runtime env keys forwarded from `.env.local` into the deployed customer-env.
|
|
36
|
+
*
|
|
37
|
+
* MIRRORS the smart-app `EnvSchema`
|
|
38
|
+
* (`apps/showcase/smart-app/src/config/env-validation.ts`). Keep this in lockstep
|
|
39
|
+
* with that schema: a key the smart-app reads at runtime but that is absent here
|
|
40
|
+
* would not reach the container (the #1564 class of bug), and a key here that the
|
|
41
|
+
* smart-app never reads is harmless noise in the Secret.
|
|
42
|
+
*
|
|
43
|
+
* Deliberately EXCLUDES purely deploy-time / CLI-only vars that the deployed
|
|
44
|
+
* container never consumes:
|
|
45
|
+
* - `SUBSCRIPTION_NFT_SERIAL` — a `hsuite subscribe` book-keeping value.
|
|
46
|
+
* - `VALIDATOR_API_KEY` / `SMART_HOST_API_KEY` — the in-cluster app authenticates
|
|
47
|
+
* as its wallet (Web3 challenge-response); a raw API key is a deploy-time /
|
|
48
|
+
* local-only convenience, not a container runtime credential, and the deployer
|
|
49
|
+
* injects the mediated `SMART_HOST_URL` / `APP_TOKEN` via the cluster-env
|
|
50
|
+
* Secret. (Forwarding a raw validator key would also widen the tenant's
|
|
51
|
+
* credential surface for no runtime benefit.)
|
|
52
|
+
*/
|
|
53
|
+
export declare const RUNTIME_ENV_KEYS: readonly string[];
|
|
54
|
+
/**
|
|
55
|
+
* Env keys whose presence makes the deployed app boot in cluster (subscribed)
|
|
56
|
+
* mode rather than open / in-memory mode. The smart-app's `BaaSAuthService`
|
|
57
|
+
* builds its signer from `XRPL_SEED` (`createXrplWeb3Signer(seed)`), so a missing
|
|
58
|
+
* `XRPL_SEED` in the container is exactly the #1564 open-mode footgun.
|
|
59
|
+
*/
|
|
60
|
+
export declare const CLUSTER_MODE_REQUIRED_KEYS: readonly string[];
|
|
61
|
+
export interface ResolveRuntimeEnvInput {
|
|
62
|
+
/** The parsed `.env.local` (developer runtime + deploy-time creds). */
|
|
63
|
+
env: EnvMap;
|
|
64
|
+
/** `manifest.backend.env` — explicit, committed, NON-secret overrides. */
|
|
65
|
+
manifestEnv?: Record<string, string>;
|
|
66
|
+
/**
|
|
67
|
+
* Opt-in escape hatch for an intentional OPEN-MODE deploy — e.g. a zero-cred
|
|
68
|
+
* fork demo the developer wants to run unsubscribed/in-memory.
|
|
69
|
+
*
|
|
70
|
+
* When true, the developer's `XRPL_SEED` is DELIBERATELY WITHHELD from the
|
|
71
|
+
* forwarded container env (so the deployed app boots open/in-memory mode), and
|
|
72
|
+
* the fail-loud {@link OpenModeDeployError} is suppressed. The seed still exists
|
|
73
|
+
* in `.env.local` for the local deploy-time work (auth + attestation signing) —
|
|
74
|
+
* it is just not injected into the running container.
|
|
75
|
+
*
|
|
76
|
+
* When false (the default), the developer's runtime creds — including
|
|
77
|
+
* `XRPL_SEED` — are forwarded so the deployed app runs cluster/subscribed mode,
|
|
78
|
+
* and a resolved env with no `XRPL_SEED` throws {@link OpenModeDeployError}
|
|
79
|
+
* rather than silently shipping open mode.
|
|
80
|
+
*/
|
|
81
|
+
allowOpenMode?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Optional sink for non-fatal advisories (e.g. a secret-shaped key found in the
|
|
84
|
+
* committed manifest surface). Injected by the command so warnings surface to
|
|
85
|
+
* the operator; omitted in unit tests that assert the pure merge.
|
|
86
|
+
*/
|
|
87
|
+
warn?: (message: string) => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A subscribed-but-credential-less deploy was blocked. Thrown by
|
|
91
|
+
* {@link resolveRuntimeEnv} when the resolved container env carries no
|
|
92
|
+
* `XRPL_SEED` and `allowOpenMode` is not set — so a deploy never SILENTLY ships
|
|
93
|
+
* an open-mode app (the #1564 invisible failure). The remedy (populate
|
|
94
|
+
* `.env.local` via `hsuite init` + `hsuite subscribe`, or opt in explicitly) is
|
|
95
|
+
* on the message.
|
|
96
|
+
*/
|
|
97
|
+
export declare class OpenModeDeployError extends Error {
|
|
98
|
+
constructor(missing: readonly string[]);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the runtime env the deployed container should receive.
|
|
102
|
+
*
|
|
103
|
+
* Merge + precedence (issue #1564, criterion "define + document the precedence"):
|
|
104
|
+
* 1. Start from the runtime-relevant vars in `.env.local` (secrets like
|
|
105
|
+
* `XRPL_SEED` + app config) — {@link RUNTIME_ENV_KEYS} filtered.
|
|
106
|
+
* 2. Overlay `manifest.backend.env` LAST, so an explicitly-set manifest key
|
|
107
|
+
* WINS. The manifest is the committed, explicit override surface for
|
|
108
|
+
* NON-secret config (ports, feature flags, Discord/AI endpoints); secrets
|
|
109
|
+
* are supplied automatically by `.env.local` and never need to be
|
|
110
|
+
* hand-written into a committed manifest.
|
|
111
|
+
*
|
|
112
|
+
* Rationale for manifest-wins: a value a developer deliberately typed into the
|
|
113
|
+
* manifest is an intentional per-deploy override and must not be silently shadowed
|
|
114
|
+
* by whatever happens to sit in their local `.env.local`. Secrets, by contrast,
|
|
115
|
+
* are NOT expected in the manifest — they flow from `.env.local` — so the two
|
|
116
|
+
* surfaces do not normally collide on secret keys.
|
|
117
|
+
*
|
|
118
|
+
* Fail-loud (criterion "a subscribed-but-credential-less deploy fails loudly"):
|
|
119
|
+
* if the merged result has no `XRPL_SEED` and `allowOpenMode` is not set, throws
|
|
120
|
+
* {@link OpenModeDeployError} rather than shipping a silent open-mode app.
|
|
121
|
+
*
|
|
122
|
+
* @throws {OpenModeDeployError} when the resolved env is credential-less and
|
|
123
|
+
* `allowOpenMode` is not set.
|
|
124
|
+
*/
|
|
125
|
+
export declare function resolveRuntimeEnv(input: ResolveRuntimeEnvInput): Record<string, string>;
|
|
126
|
+
//# sourceMappingURL=runtime-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../../src/_lib/runtime-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EA4C7C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAAkB,CAAC;AAE3E,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAWD;;;;;;;GAOG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,SAAS,MAAM,EAAE;CAYvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiDxB"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenModeDeployError = exports.CLUSTER_MODE_REQUIRED_KEYS = exports.RUNTIME_ENV_KEYS = void 0;
|
|
4
|
+
exports.resolveRuntimeEnv = resolveRuntimeEnv;
|
|
5
|
+
/**
|
|
6
|
+
* Runtime env keys forwarded from `.env.local` into the deployed customer-env.
|
|
7
|
+
*
|
|
8
|
+
* MIRRORS the smart-app `EnvSchema`
|
|
9
|
+
* (`apps/showcase/smart-app/src/config/env-validation.ts`). Keep this in lockstep
|
|
10
|
+
* with that schema: a key the smart-app reads at runtime but that is absent here
|
|
11
|
+
* would not reach the container (the #1564 class of bug), and a key here that the
|
|
12
|
+
* smart-app never reads is harmless noise in the Secret.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately EXCLUDES purely deploy-time / CLI-only vars that the deployed
|
|
15
|
+
* container never consumes:
|
|
16
|
+
* - `SUBSCRIPTION_NFT_SERIAL` — a `hsuite subscribe` book-keeping value.
|
|
17
|
+
* - `VALIDATOR_API_KEY` / `SMART_HOST_API_KEY` — the in-cluster app authenticates
|
|
18
|
+
* as its wallet (Web3 challenge-response); a raw API key is a deploy-time /
|
|
19
|
+
* local-only convenience, not a container runtime credential, and the deployer
|
|
20
|
+
* injects the mediated `SMART_HOST_URL` / `APP_TOKEN` via the cluster-env
|
|
21
|
+
* Secret. (Forwarding a raw validator key would also widen the tenant's
|
|
22
|
+
* credential surface for no runtime benefit.)
|
|
23
|
+
*/
|
|
24
|
+
exports.RUNTIME_ENV_KEYS = [
|
|
25
|
+
// Application
|
|
26
|
+
'NODE_ENV',
|
|
27
|
+
'PORT',
|
|
28
|
+
'APP_ID',
|
|
29
|
+
'APP_NAME',
|
|
30
|
+
'APP_DESCRIPTION',
|
|
31
|
+
// CORS
|
|
32
|
+
'CORS_ORIGINS',
|
|
33
|
+
// XRPL — the developer's own wallet identity (holds the subscription NFT).
|
|
34
|
+
'XRPL_NETWORK',
|
|
35
|
+
'XRPL_ADDRESS',
|
|
36
|
+
'XRPL_SEED',
|
|
37
|
+
'XRPL_PUBLIC_KEY',
|
|
38
|
+
// Subscription binding
|
|
39
|
+
'SUBSCRIPTION_APP_ID',
|
|
40
|
+
'DEPLOYED_APP_ID',
|
|
41
|
+
// Cluster connection (the deployer also injects mediated in-cluster URLs via
|
|
42
|
+
// the cluster-env Secret; a developer override still forwards here).
|
|
43
|
+
'VALIDATOR_URL',
|
|
44
|
+
'SMART_HOST_URL',
|
|
45
|
+
// Agent AI / templates
|
|
46
|
+
'AI_PROVIDER',
|
|
47
|
+
'AI_MODEL',
|
|
48
|
+
'ANTHROPIC_API_KEY',
|
|
49
|
+
'ANTHROPIC_MODEL',
|
|
50
|
+
'OPENAI_API_KEY',
|
|
51
|
+
'GEMINI_API_KEY',
|
|
52
|
+
'AI_BASE_URL',
|
|
53
|
+
'AI_API_KEY',
|
|
54
|
+
'AI_MAX_TOKENS',
|
|
55
|
+
'DISCORD_WEBHOOK_URL',
|
|
56
|
+
'WEATHER_PAYOUT_ADDRESS',
|
|
57
|
+
// Misc runtime
|
|
58
|
+
'REQUEST_TIMEOUT',
|
|
59
|
+
'DEBUG',
|
|
60
|
+
// Subscription behaviour
|
|
61
|
+
'AUTO_SUBSCRIBE',
|
|
62
|
+
'SUBSCRIPTION_TIER',
|
|
63
|
+
// NOTE: `DEV_MODE` / `ALLOW_INSECURE` are deliberately NOT forwarded — they are
|
|
64
|
+
// local-dev safety toggles, and a stale `DEV_MODE=true` / `ALLOW_INSECURE=true`
|
|
65
|
+
// sitting in a developer's `.env.local` must not silently propagate into a live
|
|
66
|
+
// deployment. A deploy that genuinely needs one can set it explicitly (and
|
|
67
|
+
// intentionally) via `manifest.backend.env`.
|
|
68
|
+
];
|
|
69
|
+
/**
|
|
70
|
+
* Env keys whose presence makes the deployed app boot in cluster (subscribed)
|
|
71
|
+
* mode rather than open / in-memory mode. The smart-app's `BaaSAuthService`
|
|
72
|
+
* builds its signer from `XRPL_SEED` (`createXrplWeb3Signer(seed)`), so a missing
|
|
73
|
+
* `XRPL_SEED` in the container is exactly the #1564 open-mode footgun.
|
|
74
|
+
*/
|
|
75
|
+
exports.CLUSTER_MODE_REQUIRED_KEYS = ['XRPL_SEED'];
|
|
76
|
+
/**
|
|
77
|
+
* Heuristic: does a key name look like a secret? Used only to WARN when such a
|
|
78
|
+
* key appears in `manifest.backend.env` — the committed, typically git-tracked
|
|
79
|
+
* surface — since secrets are meant to flow from `.env.local`, not the manifest.
|
|
80
|
+
*/
|
|
81
|
+
function looksLikeSecretKey(key) {
|
|
82
|
+
return /(_SEED|_PRIVATE_KEY|_API_KEY|_SECRET|_TOKEN|_PASSWORD|_MNEMONIC)$/.test(key);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* A subscribed-but-credential-less deploy was blocked. Thrown by
|
|
86
|
+
* {@link resolveRuntimeEnv} when the resolved container env carries no
|
|
87
|
+
* `XRPL_SEED` and `allowOpenMode` is not set — so a deploy never SILENTLY ships
|
|
88
|
+
* an open-mode app (the #1564 invisible failure). The remedy (populate
|
|
89
|
+
* `.env.local` via `hsuite init` + `hsuite subscribe`, or opt in explicitly) is
|
|
90
|
+
* on the message.
|
|
91
|
+
*/
|
|
92
|
+
class OpenModeDeployError extends Error {
|
|
93
|
+
constructor(missing) {
|
|
94
|
+
super(`Refusing to deploy an OPEN-MODE (credential-less) app: the resolved ` +
|
|
95
|
+
`container env is missing ${missing.join(', ')}. The deployed smart-app ` +
|
|
96
|
+
`authenticates as YOUR XRPL wallet (the XRPL_SEED in --env), which holds ` +
|
|
97
|
+
`the subscription NFT; without it the app boots in-memory/unsubscribed ` +
|
|
98
|
+
`and BaaS routes 503. Run \`hsuite init\` + \`hsuite subscribe\` so ` +
|
|
99
|
+
`.env.local carries the creds, or pass --allow-open-mode for an ` +
|
|
100
|
+
`intentional zero-cred fork deploy.`);
|
|
101
|
+
this.name = 'OpenModeDeployError';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.OpenModeDeployError = OpenModeDeployError;
|
|
105
|
+
/**
|
|
106
|
+
* Resolve the runtime env the deployed container should receive.
|
|
107
|
+
*
|
|
108
|
+
* Merge + precedence (issue #1564, criterion "define + document the precedence"):
|
|
109
|
+
* 1. Start from the runtime-relevant vars in `.env.local` (secrets like
|
|
110
|
+
* `XRPL_SEED` + app config) — {@link RUNTIME_ENV_KEYS} filtered.
|
|
111
|
+
* 2. Overlay `manifest.backend.env` LAST, so an explicitly-set manifest key
|
|
112
|
+
* WINS. The manifest is the committed, explicit override surface for
|
|
113
|
+
* NON-secret config (ports, feature flags, Discord/AI endpoints); secrets
|
|
114
|
+
* are supplied automatically by `.env.local` and never need to be
|
|
115
|
+
* hand-written into a committed manifest.
|
|
116
|
+
*
|
|
117
|
+
* Rationale for manifest-wins: a value a developer deliberately typed into the
|
|
118
|
+
* manifest is an intentional per-deploy override and must not be silently shadowed
|
|
119
|
+
* by whatever happens to sit in their local `.env.local`. Secrets, by contrast,
|
|
120
|
+
* are NOT expected in the manifest — they flow from `.env.local` — so the two
|
|
121
|
+
* surfaces do not normally collide on secret keys.
|
|
122
|
+
*
|
|
123
|
+
* Fail-loud (criterion "a subscribed-but-credential-less deploy fails loudly"):
|
|
124
|
+
* if the merged result has no `XRPL_SEED` and `allowOpenMode` is not set, throws
|
|
125
|
+
* {@link OpenModeDeployError} rather than shipping a silent open-mode app.
|
|
126
|
+
*
|
|
127
|
+
* @throws {OpenModeDeployError} when the resolved env is credential-less and
|
|
128
|
+
* `allowOpenMode` is not set.
|
|
129
|
+
*/
|
|
130
|
+
function resolveRuntimeEnv(input) {
|
|
131
|
+
const { env, manifestEnv = {}, allowOpenMode = false, warn } = input;
|
|
132
|
+
const merged = {};
|
|
133
|
+
// 1. Runtime-relevant vars from .env.local (only keys the smart-app reads).
|
|
134
|
+
// Under an explicit open-mode deploy, the cluster-mode secrets (XRPL_SEED)
|
|
135
|
+
// are DELIBERATELY WITHHELD from the container so it boots open/in-memory —
|
|
136
|
+
// the seed still exists locally for attestation, it is just not injected.
|
|
137
|
+
const withhold = allowOpenMode ? new Set(exports.CLUSTER_MODE_REQUIRED_KEYS) : new Set();
|
|
138
|
+
for (const key of exports.RUNTIME_ENV_KEYS) {
|
|
139
|
+
if (withhold.has(key))
|
|
140
|
+
continue;
|
|
141
|
+
const val = env.get(key);
|
|
142
|
+
if (val !== undefined && val !== '') {
|
|
143
|
+
merged[key] = val;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// 2. manifest.backend.env wins (explicit, committed, non-secret overrides).
|
|
147
|
+
// NOTE: manifest keys are NOT bounded by RUNTIME_ENV_KEYS — the manifest is
|
|
148
|
+
// the explicit, developer-authored, committed override surface, so a
|
|
149
|
+
// manifest-only key (e.g. a custom feature flag) passes through verbatim.
|
|
150
|
+
// The allowlist governs only the `.env.local` source (step 1). An empty
|
|
151
|
+
// manifest value is forwarded as-is (an explicit author choice), unlike an
|
|
152
|
+
// empty `.env.local` value which is dropped in step 1.
|
|
153
|
+
for (const [key, val] of Object.entries(manifestEnv)) {
|
|
154
|
+
if (warn && looksLikeSecretKey(key)) {
|
|
155
|
+
warn(`manifest.backend.env sets a secret-shaped key "${key}" — the manifest is ` +
|
|
156
|
+
`typically git-committed. Secrets should live in your --env file ` +
|
|
157
|
+
`(.env.local), which is forwarded automatically; only NON-secret ` +
|
|
158
|
+
`overrides belong in the manifest.`);
|
|
159
|
+
}
|
|
160
|
+
merged[key] = val;
|
|
161
|
+
}
|
|
162
|
+
// 3. Fail loud on a credential-less (open-mode) deploy unless opted in — so a
|
|
163
|
+
// subscribed app never SILENTLY ships open mode (the #1564 invisible bug).
|
|
164
|
+
if (!allowOpenMode) {
|
|
165
|
+
const missing = exports.CLUSTER_MODE_REQUIRED_KEYS.filter((k) => merged[k] === undefined || merged[k] === '');
|
|
166
|
+
if (missing.length > 0) {
|
|
167
|
+
throw new OpenModeDeployError(missing);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return merged;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=runtime-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-env.js","sourceRoot":"","sources":["../../src/_lib/runtime-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,52 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thin HTTP client for the validator-side `/api/v3/subscription/*` surface.
|
|
3
|
-
*
|
|
4
|
-
* Wraps the routes implemented in `apps/smart-validator/src/subscription/
|
|
5
|
-
* subscription.controller.ts`. The endpoints are `@Public()` and live on
|
|
6
|
-
* the same gateway URL the CLI's `init` writes to env as `VALIDATOR_URL`.
|
|
7
|
-
*
|
|
8
|
-
* Kept dependency-free (uses global `fetch`) so the CLI command bodies
|
|
9
|
-
* stay small and easy to unit-test with the standard `jest.fn()` mock
|
|
10
|
-
* pattern. Tests inject a fake `fetch` via the constructor.
|
|
11
|
-
*/
|
|
12
1
|
export type DepositInstructions = {
|
|
13
2
|
walletAddress: string;
|
|
14
3
|
tokenId: string;
|
|
15
4
|
amount: string;
|
|
16
5
|
chain: string;
|
|
17
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* Canonical `ValidatorRules` block — what the validator's mandatory creation
|
|
9
|
+
* gate (`EntityCreationOrchestrator`) parses against `ValidatorRulesSchema`
|
|
10
|
+
* before it will create any entity. Kept as a structural type here so the CLI
|
|
11
|
+
* has no runtime dependency on `@hsuite/smart-engines-shared`.
|
|
12
|
+
*/
|
|
13
|
+
export type ValidatorRules = Record<string, unknown> & {
|
|
14
|
+
version: string;
|
|
15
|
+
type: 'account' | 'token' | 'topic' | 'agent';
|
|
16
|
+
created: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Smart-app create payload — mirrors `CreateSmartAppSchema`
|
|
20
|
+
* (apps/smart-validator/src/smart-app/dto/create-smart-app.dto.ts).
|
|
21
|
+
*/
|
|
22
|
+
export type CreateAppPayload = {
|
|
23
|
+
name: string;
|
|
24
|
+
services: string[];
|
|
25
|
+
config: Record<string, unknown>;
|
|
26
|
+
tier: string;
|
|
27
|
+
networks: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Optional — mirrors `CreateSmartAppSchema.validatorRules` (`.optional()`).
|
|
30
|
+
* When omitted the validator's create factory synthesizes the canonical
|
|
31
|
+
* security-first default (the standard deployment path). `hsuite subscribe`
|
|
32
|
+
* leaves it unset so the default applies.
|
|
33
|
+
*/
|
|
34
|
+
validatorRules?: ValidatorRules;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Response from `POST /api/v3/smart-apps` (SmartAppController.create).
|
|
38
|
+
*/
|
|
39
|
+
export type CreateAppResponse = {
|
|
40
|
+
appId: string;
|
|
41
|
+
name: string;
|
|
42
|
+
status: string;
|
|
43
|
+
services: string[];
|
|
44
|
+
createdAt?: string;
|
|
45
|
+
configCid?: string;
|
|
46
|
+
blsPubKeyHex?: string;
|
|
47
|
+
subscriptionId?: string;
|
|
48
|
+
depositInstructions?: DepositInstructions;
|
|
49
|
+
};
|
|
18
50
|
export type SubscriptionRequestResponse = {
|
|
19
51
|
success: boolean;
|
|
20
52
|
subscriptionId?: string;
|
|
@@ -32,6 +64,20 @@ export type SubscriptionStatusResponse = {
|
|
|
32
64
|
appName?: string;
|
|
33
65
|
status?: string;
|
|
34
66
|
subscriptionNftSerial?: number | string;
|
|
67
|
+
/**
|
|
68
|
+
* Per-chain minted-NFT coordinates exposed by the validator once the
|
|
69
|
+
* subscription NFT is minted. For XRPL this carries the NFTokenID, the
|
|
70
|
+
* issuing account (the cluster SignerList issuer), and the sell-offer tx id —
|
|
71
|
+
* enough for the CLI to resolve + accept the brokered sell offer WITHOUT a
|
|
72
|
+
* manual `--nft-issuer` flag.
|
|
73
|
+
*/
|
|
74
|
+
chainNfts?: {
|
|
75
|
+
xrpl?: {
|
|
76
|
+
nftId?: string;
|
|
77
|
+
issuerAddress?: string;
|
|
78
|
+
offerTxId?: string;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
35
81
|
expiresAt?: string | number;
|
|
36
82
|
remainingBalance?: string;
|
|
37
83
|
createdAt?: string | number;
|
|
@@ -114,17 +160,85 @@ export type FetchLike = (input: string, init?: any) => Promise<{
|
|
|
114
160
|
export type SubscriptionClientOptions = {
|
|
115
161
|
baseUrl: string;
|
|
116
162
|
fetchImpl?: FetchLike;
|
|
163
|
+
/** HTTP request timeout in ms. Defaults to 180_000 (deposit-account creation
|
|
164
|
+
* is a synchronous multi-step on-chain ceremony; the SDK's 30s default is too
|
|
165
|
+
* short on a slow public XRPL endpoint). */
|
|
166
|
+
requestTimeoutMs?: number;
|
|
167
|
+
/**
|
|
168
|
+
* Optional web3-auth creds. When set, `authenticate()` obtains a validator
|
|
169
|
+
* bearer session (the subscription routes are session-guarded since P4d, so
|
|
170
|
+
* `request`/`mint` 401 without it).
|
|
171
|
+
*/
|
|
172
|
+
auth?: {
|
|
173
|
+
chain: string;
|
|
174
|
+
address: string;
|
|
175
|
+
seed: string;
|
|
176
|
+
};
|
|
117
177
|
};
|
|
118
178
|
/**
|
|
119
179
|
* Validator-side subscription HTTP client.
|
|
120
180
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
181
|
+
* Adapter over the SDK's {@link SdkSubscriptionClient} + {@link ValidatorAuthClient}.
|
|
182
|
+
* All HTTP/fetch + auth logic lives in the SDK; this class only adapts method
|
|
183
|
+
* names + base URL, flattens the SDK's `pendingTierChange` envelope onto the
|
|
184
|
+
* flat `effectiveAt`/`depositInstructions` the CLI consumers read, and (for
|
|
185
|
+
* tests) bridges the injectable `fetchImpl` seam onto the SDK transport.
|
|
123
186
|
*/
|
|
124
187
|
export declare class SubscriptionClient {
|
|
125
|
-
|
|
126
|
-
private readonly
|
|
188
|
+
/** Validator origin WITHOUT the /api/v3 prefix (auth routes are un-prefixed). */
|
|
189
|
+
private readonly origin;
|
|
190
|
+
private readonly sdk;
|
|
191
|
+
private readonly http;
|
|
192
|
+
private readonly auth?;
|
|
127
193
|
constructor(opts: SubscriptionClientOptions);
|
|
194
|
+
/**
|
|
195
|
+
* Web3-auth against the validator: challenge → sign → authenticate → bearer.
|
|
196
|
+
* The validator auth controller is mounted WITHOUT the `/api` prefix
|
|
197
|
+
* (`/auth/validator/...`). Call before request/mint; no-op without creds.
|
|
198
|
+
*
|
|
199
|
+
* Delegates to the SDK's {@link ValidatorAuthClient} for the
|
|
200
|
+
* challenge/authenticate round-trip; signing stays here (ripple-keypairs)
|
|
201
|
+
* because it owns the dev wallet seed. The resulting bearer is attached to
|
|
202
|
+
* the shared HTTP client via `setAuthToken`, so subsequent SDK calls carry it.
|
|
203
|
+
*/
|
|
204
|
+
authenticate(): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Run a bearer-authenticated call with transparent re-auth on token expiry.
|
|
207
|
+
*
|
|
208
|
+
* The deposit-account creation behind `POST /subscription/request` is a
|
|
209
|
+
* synchronous multi-step on-chain ceremony (~60-90s on a slow public XRPL
|
|
210
|
+
* endpoint — see the constructor's timeout note). The validator session
|
|
211
|
+
* bearer obtained in {@link authenticate} can expire DURING that window, so
|
|
212
|
+
* the next session-guarded call (`status`/`mint`) comes back 401
|
|
213
|
+
* "Invalid or expired authentication token" and the CLI's post-payment NFT
|
|
214
|
+
* mint/accept steps never run.
|
|
215
|
+
*
|
|
216
|
+
* This wrapper makes every bearer call robust to ANY request duration (not
|
|
217
|
+
* just a fixed-but-longer TTL): on a 401 / expired-token error it re-runs
|
|
218
|
+
* {@link authenticate} (re-signs a fresh challenge → fresh bearer) ONCE and
|
|
219
|
+
* retries the call. A second failure surfaces unchanged. No-op re-auth (no
|
|
220
|
+
* creds configured) is skipped — a retry without a fresh bearer can't help.
|
|
221
|
+
*/
|
|
222
|
+
private withReauth;
|
|
223
|
+
/**
|
|
224
|
+
* Create the canonical smart-app entity via `POST /api/v3/smart-apps`
|
|
225
|
+
* (`SmartAppController.create`) — runs the per-entity DKG ceremony to derive
|
|
226
|
+
* `entityId` AND creates the paid pending-deposit subscription on that id,
|
|
227
|
+
* returning `{ appId: entityId, depositInstructions, subscriptionId }`.
|
|
228
|
+
*
|
|
229
|
+
* The MINT-FIRST entry point for `hsuite subscribe`: the returned `entityId`
|
|
230
|
+
* becomes the subscription appId end-to-end (no throwaway `app-${uuid}`).
|
|
231
|
+
* Auth-gated (developer session) — uses the same validator bearer obtained by
|
|
232
|
+
* {@link authenticate}, and reuses the long request timeout (the synchronous
|
|
233
|
+
* DKG ceremony + on-chain deposit-account funding exceeds the SDK's 30s
|
|
234
|
+
* default). Wrapped in {@link withReauth} so a session expiry during the slow
|
|
235
|
+
* ceremony re-signs + retries once.
|
|
236
|
+
*
|
|
237
|
+
* Posts on the shared `${origin}/api/v3` client (the same base the
|
|
238
|
+
* subscription calls use), so the path is the controller-relative
|
|
239
|
+
* `/smart-apps` and the full URL is `${origin}/api/v3/smart-apps`.
|
|
240
|
+
*/
|
|
241
|
+
createApp(payload: CreateAppPayload): Promise<CreateAppResponse>;
|
|
128
242
|
request(payload: {
|
|
129
243
|
appId: string;
|
|
130
244
|
developerAccountId: string;
|
|
@@ -145,8 +259,5 @@ export declare class SubscriptionClient {
|
|
|
145
259
|
usage(appId: string): Promise<UsageSummaryResponse>;
|
|
146
260
|
usageStatus(appId: string): Promise<UsageStatusResponse>;
|
|
147
261
|
billing(appId: string, limit?: number, offset?: number): Promise<BillingLedgerResponse>;
|
|
148
|
-
private post;
|
|
149
|
-
private get;
|
|
150
|
-
private send;
|
|
151
262
|
}
|
|
152
263
|
//# sourceMappingURL=subscription-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscription-client.d.ts","sourceRoot":"","sources":["../../src/_lib/subscription-client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subscription-client.d.ts","sourceRoot":"","sources":["../../src/_lib/subscription-client.ts"],"names":[],"mappings":"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"}
|