@ariestools/cli 0.1.8 → 0.1.9
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 +32 -0
- package/dist/bin/aries.mjs +608 -185
- package/dist/bin/daemons/chain-server.mjs +152 -0
- package/dist/bin/daemons/dapp-server.mjs +970 -0
- package/dist/bin/daemons/datalake-dev.mjs +111520 -0
- package/dist/node/datalake.d.ts +100 -0
- package/dist/node/datalake.mjs +475 -0
- package/package.json +19 -11
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import S3rver from "s3rver";
|
|
7
|
+
//#region src/ChainBacking.ts
|
|
8
|
+
const CHAIN_BACKINGS = ["memory"];
|
|
9
|
+
function isChainBackingKind(value) {
|
|
10
|
+
return CHAIN_BACKINGS.includes(value);
|
|
11
|
+
}
|
|
12
|
+
function createMemoryBacking() {
|
|
13
|
+
let dir;
|
|
14
|
+
return {
|
|
15
|
+
description: "memory (ephemeral temp directory)",
|
|
16
|
+
get directory() {
|
|
17
|
+
if (dir === void 0) throw new Error("Memory backing not prepared");
|
|
18
|
+
return dir;
|
|
19
|
+
},
|
|
20
|
+
async prepare() {
|
|
21
|
+
dir ??= await mkdtemp(path.join(tmpdir(), "aries-chain-"));
|
|
22
|
+
},
|
|
23
|
+
async cleanup() {
|
|
24
|
+
if (dir !== void 0) await rm(dir, {
|
|
25
|
+
recursive: true,
|
|
26
|
+
force: true
|
|
27
|
+
});
|
|
28
|
+
dir = void 0;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function resolveBacking(kind) {
|
|
33
|
+
switch (kind) {
|
|
34
|
+
case "memory": return createMemoryBacking();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/startChainServer.ts
|
|
39
|
+
/**
|
|
40
|
+
* The bucket-per-role split of the published chain layout. Path-style
|
|
41
|
+
* addressing turns each bucket into a subfolder of the one origin —
|
|
42
|
+
* `/blocks`, `/state`, `/indexes` — replacing the production sub-domains.
|
|
43
|
+
*/
|
|
44
|
+
const CHAIN_BUCKETS = [
|
|
45
|
+
"blocks",
|
|
46
|
+
"state",
|
|
47
|
+
"indexes"
|
|
48
|
+
];
|
|
49
|
+
const DEFAULT_HOST = "127.0.0.1";
|
|
50
|
+
const DEFAULT_PORT = 8791;
|
|
51
|
+
/** Allow browser RestBlockViewer clients to read the layout cross-origin. */
|
|
52
|
+
const CORS_ALLOW_READS = `<CORSConfiguration>
|
|
53
|
+
<CORSRule>
|
|
54
|
+
<AllowedOrigin>*</AllowedOrigin>
|
|
55
|
+
<AllowedMethod>GET</AllowedMethod>
|
|
56
|
+
<AllowedMethod>HEAD</AllowedMethod>
|
|
57
|
+
<AllowedHeader>*</AllowedHeader>
|
|
58
|
+
</CORSRule>
|
|
59
|
+
</CORSConfiguration>`;
|
|
60
|
+
/**
|
|
61
|
+
* Boots an S3-compatible server (s3rver) pre-configured with the three chain
|
|
62
|
+
* layout buckets. Writers use the S3 API (any credentials are accepted);
|
|
63
|
+
* readers fetch `/{bucket}/{layout-path}` over HTTP or optional TLS.
|
|
64
|
+
*
|
|
65
|
+
* DEV ONLY — this server is a local development fixture, not a production
|
|
66
|
+
* chain host. It intentionally skips the production concerns the datalake
|
|
67
|
+
* and signing-pool planes carry (auth, metrics, durable multi-instance
|
|
68
|
+
* storage): any S3 credentials are accepted and the only backing is an
|
|
69
|
+
* ephemeral temp directory. Production chains stay on the real sub-domain
|
|
70
|
+
* layout (blocks/state/indexes origins backed by S3/R2).
|
|
71
|
+
*/
|
|
72
|
+
async function startChainServer(options) {
|
|
73
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
74
|
+
const publicHost = options.publicHost ?? host;
|
|
75
|
+
await options.backing.prepare();
|
|
76
|
+
const server = new S3rver({
|
|
77
|
+
address: host,
|
|
78
|
+
allowMismatchedSignatures: true,
|
|
79
|
+
cert: options.tls?.cert,
|
|
80
|
+
configureBuckets: CHAIN_BUCKETS.map((name) => ({
|
|
81
|
+
name,
|
|
82
|
+
configs: [CORS_ALLOW_READS]
|
|
83
|
+
})),
|
|
84
|
+
directory: options.backing.directory,
|
|
85
|
+
key: options.tls?.key,
|
|
86
|
+
port: options.port ?? DEFAULT_PORT,
|
|
87
|
+
silent: options.silent ?? false,
|
|
88
|
+
vhostBuckets: false
|
|
89
|
+
});
|
|
90
|
+
try {
|
|
91
|
+
const { port } = await server.run();
|
|
92
|
+
return {
|
|
93
|
+
baseUrl: `${options.tls === void 0 ? "http" : "https"}://${publicHost}:${port}`,
|
|
94
|
+
port,
|
|
95
|
+
close: async () => {
|
|
96
|
+
await server.close();
|
|
97
|
+
await options.backing.cleanup();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
} catch (error) {
|
|
101
|
+
await options.backing.cleanup();
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/bin/chainServer.ts
|
|
107
|
+
/**
|
|
108
|
+
* Chain REST server daemon: serves an XL1/XYO published-chain layout from a
|
|
109
|
+
* single origin using subfolders (/blocks, /state, /indexes) instead of the
|
|
110
|
+
* production sub-domains. The subfolders are S3 buckets on an embedded
|
|
111
|
+
* S3-compatible server, so the existing `xyo s3 ...` publish commands write
|
|
112
|
+
* into it unchanged while readers (RestBlockViewer, curl) fetch the same
|
|
113
|
+
* layout paths over HTTP or optional TLS.
|
|
114
|
+
*/
|
|
115
|
+
const PORT = Number(process.env.CHAIN_PORT ?? 8791);
|
|
116
|
+
const HOST = process.env.HOST ?? "127.0.0.1";
|
|
117
|
+
const BACKING = process.env.CHAIN_BACKING ?? "memory";
|
|
118
|
+
const PUBLIC_HOST = process.env.CHAIN_PUBLIC_HOST;
|
|
119
|
+
const TLS_CERT_PATH = process.env.CHAIN_TLS_CERT;
|
|
120
|
+
const TLS_KEY_PATH = process.env.CHAIN_TLS_KEY;
|
|
121
|
+
async function main() {
|
|
122
|
+
if (!isChainBackingKind(BACKING)) throw new Error(`Unsupported CHAIN_BACKING '${BACKING}' (supported: ${CHAIN_BACKINGS.join(", ")})`);
|
|
123
|
+
const backing = resolveBacking(BACKING);
|
|
124
|
+
if (TLS_CERT_PATH === void 0 !== (TLS_KEY_PATH === void 0)) throw new Error("CHAIN_TLS_CERT and CHAIN_TLS_KEY must be provided together");
|
|
125
|
+
const server = await startChainServer({
|
|
126
|
+
backing,
|
|
127
|
+
host: HOST,
|
|
128
|
+
port: PORT,
|
|
129
|
+
publicHost: PUBLIC_HOST,
|
|
130
|
+
tls: TLS_CERT_PATH === void 0 || TLS_KEY_PATH === void 0 ? void 0 : {
|
|
131
|
+
cert: readFileSync(TLS_CERT_PATH),
|
|
132
|
+
key: readFileSync(TLS_KEY_PATH)
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
console.log(`chain server listening at ${server.baseUrl}\n` + CHAIN_BUCKETS.map((bucket) => ` /${bucket.padEnd(7)} ${server.baseUrl}/${bucket}`).join("\n") + `\nbacking: ${backing.description} — ${backing.directory}`);
|
|
136
|
+
const shutdown = async () => {
|
|
137
|
+
await server.close();
|
|
138
|
+
process.exit(0);
|
|
139
|
+
};
|
|
140
|
+
process.on("SIGINT", () => {
|
|
141
|
+
shutdown();
|
|
142
|
+
});
|
|
143
|
+
process.on("SIGTERM", () => {
|
|
144
|
+
shutdown();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
main().catch((error) => {
|
|
148
|
+
console.error(error);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
});
|
|
151
|
+
//#endregion
|
|
152
|
+
export {};
|