@orbitmem/cli 0.1.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 +152 -0
- package/dist/index.js +820 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# @orbitmem/cli
|
|
2
|
+
|
|
3
|
+
CLI for OrbitMem — manage vaults, discover data, and interact with on-chain registries.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @orbitmem/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Initialize (generate keys, create config)
|
|
15
|
+
orbitmem init --name my-wallet --network base-sepolia
|
|
16
|
+
|
|
17
|
+
# Store data
|
|
18
|
+
orbitmem vault store /notes/hello "Hello, world!"
|
|
19
|
+
|
|
20
|
+
# Read data
|
|
21
|
+
orbitmem vault get /notes/hello
|
|
22
|
+
|
|
23
|
+
# List keys
|
|
24
|
+
orbitmem vault ls
|
|
25
|
+
|
|
26
|
+
# Check status
|
|
27
|
+
orbitmem status
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
### `init`
|
|
33
|
+
|
|
34
|
+
Generate keys and create `~/.orbitmem/config.json`.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
orbitmem init --name <wallet> --network <chain> [--force]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### `status`
|
|
41
|
+
|
|
42
|
+
Show identity, config, and vault info.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
orbitmem status [--relay <url>] [--json]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### `vault store <path> <value>`
|
|
49
|
+
|
|
50
|
+
Store data in vault.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Private (default, AES encrypted)
|
|
54
|
+
orbitmem vault store /secret "sensitive data"
|
|
55
|
+
|
|
56
|
+
# Public (plaintext)
|
|
57
|
+
orbitmem vault store /public/bio "Hello" --public
|
|
58
|
+
|
|
59
|
+
# Shared with Lit access conditions
|
|
60
|
+
orbitmem vault store /shared/data "gated info" \
|
|
61
|
+
--shared --engine lit --allow-address 0x1234...
|
|
62
|
+
|
|
63
|
+
# Require minimum reputation score
|
|
64
|
+
orbitmem vault store /gated/data "quality data" \
|
|
65
|
+
--shared --engine lit --min-score 100
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `vault get <path>`
|
|
69
|
+
|
|
70
|
+
Read data from vault.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
orbitmem vault get /notes/hello [--relay <url>] [--json]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `vault ls [prefix]`
|
|
77
|
+
|
|
78
|
+
List vault keys.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
orbitmem vault ls
|
|
82
|
+
orbitmem vault ls /notes
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `vault update-access <path>`
|
|
86
|
+
|
|
87
|
+
Re-encrypt with new Lit access conditions.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
orbitmem vault update-access /shared/data --allow-address 0xNewAddr...
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `vault price`
|
|
94
|
+
|
|
95
|
+
Manage per-read pricing (micropayments).
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
orbitmem vault price set /data 5.50 # Set price in USDC
|
|
99
|
+
orbitmem vault price set /data 2.00 --currency EUR
|
|
100
|
+
orbitmem vault price get /data # Show price
|
|
101
|
+
orbitmem vault price ls # List priced paths
|
|
102
|
+
orbitmem vault price rm /data # Remove pricing
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `register`
|
|
106
|
+
|
|
107
|
+
Register data on-chain for discovery (ERC-8004).
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
orbitmem register /my/data \
|
|
111
|
+
--name "My Dataset" \
|
|
112
|
+
--description "A useful dataset" \
|
|
113
|
+
--schema json \
|
|
114
|
+
--tags data,public
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### `discover`
|
|
118
|
+
|
|
119
|
+
Search on-chain data registries.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
orbitmem discover json --tags public --min-quality 80
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `snapshot`
|
|
126
|
+
|
|
127
|
+
Archive vault to Filecoin/IPFS via Storacha.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
orbitmem snapshot --label "backup-2026-03"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### `dev`
|
|
134
|
+
|
|
135
|
+
Start local relay server for development.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
orbitmem dev [--port 3000]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Global Options
|
|
142
|
+
|
|
143
|
+
| Flag | Description |
|
|
144
|
+
|------|-------------|
|
|
145
|
+
| `--relay <url>` | Override relay URL |
|
|
146
|
+
| `--chain <name>` | Override blockchain |
|
|
147
|
+
| `--json` | Output as JSON |
|
|
148
|
+
| `--help` | Show help |
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __returnValue = (v) => v;
|
|
5
|
+
function __exportSetter(name, newValue) {
|
|
6
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
7
|
+
}
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
set: __exportSetter.bind(all, name)
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
|
+
|
|
20
|
+
// src/config.ts
|
|
21
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
22
|
+
import { homedir } from "node:os";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
import { getNetwork } from "@orbitmem/sdk/contracts";
|
|
25
|
+
function defaultConfig(network) {
|
|
26
|
+
const net = getNetwork(network);
|
|
27
|
+
return {
|
|
28
|
+
network: network ?? "base-sepolia",
|
|
29
|
+
relay: net.relayUrl,
|
|
30
|
+
chain: net.chain,
|
|
31
|
+
registryAddress: net.dataRegistry,
|
|
32
|
+
reputationAddress: net.feedbackRegistry
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getConfigDir() {
|
|
36
|
+
return process.env.ORBITMEM_HOME ?? join(homedir(), ".orbitmem");
|
|
37
|
+
}
|
|
38
|
+
function ensureDir() {
|
|
39
|
+
const dir = getConfigDir();
|
|
40
|
+
if (!existsSync(dir))
|
|
41
|
+
mkdirSync(dir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
function loadConfig() {
|
|
44
|
+
const configPath = join(getConfigDir(), "config.json");
|
|
45
|
+
const defaults = defaultConfig();
|
|
46
|
+
if (!existsSync(configPath))
|
|
47
|
+
return { walletName: "", ...defaults };
|
|
48
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
49
|
+
const base = raw.network ? defaultConfig(raw.network) : defaults;
|
|
50
|
+
return { walletName: "", ...base, ...raw };
|
|
51
|
+
}
|
|
52
|
+
function toCaip2(network) {
|
|
53
|
+
const map = {
|
|
54
|
+
"base-sepolia": "eip155:84532",
|
|
55
|
+
base: "eip155:8453"
|
|
56
|
+
};
|
|
57
|
+
return map[network] ?? "eip155:84532";
|
|
58
|
+
}
|
|
59
|
+
function saveConfig(config) {
|
|
60
|
+
ensureDir();
|
|
61
|
+
const configPath = join(getConfigDir(), "config.json");
|
|
62
|
+
const existing = loadConfig();
|
|
63
|
+
const merged = { ...existing, ...config };
|
|
64
|
+
writeFileSync(configPath, `${JSON.stringify(merged, null, 2)}
|
|
65
|
+
`);
|
|
66
|
+
}
|
|
67
|
+
var init_config = () => {};
|
|
68
|
+
|
|
69
|
+
// src/utils/output.ts
|
|
70
|
+
function output(data, json) {
|
|
71
|
+
if (json) {
|
|
72
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
73
|
+
`);
|
|
74
|
+
} else if (typeof data === "string") {
|
|
75
|
+
process.stdout.write(`${data}
|
|
76
|
+
`);
|
|
77
|
+
} else if (Array.isArray(data)) {
|
|
78
|
+
printTable(data);
|
|
79
|
+
} else if (typeof data === "object" && data !== null) {
|
|
80
|
+
for (const [key, value] of Object.entries(data)) {
|
|
81
|
+
process.stdout.write(`${key}: ${value}
|
|
82
|
+
`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function printTable(rows) {
|
|
87
|
+
if (rows.length === 0) {
|
|
88
|
+
process.stdout.write(`(empty)
|
|
89
|
+
`);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const keys = Object.keys(rows[0]);
|
|
93
|
+
const widths = keys.map((k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? "").length)));
|
|
94
|
+
const header = keys.map((k, i) => k.padEnd(widths[i])).join(" ");
|
|
95
|
+
const sep = widths.map((w) => "─".repeat(w)).join("──");
|
|
96
|
+
process.stdout.write(`${header}
|
|
97
|
+
${sep}
|
|
98
|
+
`);
|
|
99
|
+
for (const row of rows) {
|
|
100
|
+
const line = keys.map((k, i) => String(row[k] ?? "").padEnd(widths[i])).join(" ");
|
|
101
|
+
process.stdout.write(`${line}
|
|
102
|
+
`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function error(msg) {
|
|
106
|
+
process.stderr.write(`error: ${msg}
|
|
107
|
+
`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/commands/init.ts
|
|
112
|
+
var exports_init = {};
|
|
113
|
+
__export(exports_init, {
|
|
114
|
+
init: () => init
|
|
115
|
+
});
|
|
116
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
117
|
+
import { join as join2 } from "node:path";
|
|
118
|
+
import { createWallet } from "@open-wallet-standard/core";
|
|
119
|
+
import { createOwsAdapter } from "@orbitmem/sdk/identity";
|
|
120
|
+
async function init(_args, flags) {
|
|
121
|
+
const configDir = getConfigDir();
|
|
122
|
+
const configPath = join2(configDir, "config.json");
|
|
123
|
+
if (existsSync2(configPath) && flags.force === undefined) {
|
|
124
|
+
const existing = loadConfig();
|
|
125
|
+
if (existing.walletName) {
|
|
126
|
+
process.stderr.write(`Already initialized at ${configDir}. Use --force to reinitialize.
|
|
127
|
+
`);
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const walletName = flags.name ?? "orbitmem";
|
|
132
|
+
createWallet(walletName);
|
|
133
|
+
const network = flags.network ?? "base-sepolia";
|
|
134
|
+
saveConfig({ walletName, network });
|
|
135
|
+
const config = loadConfig();
|
|
136
|
+
const caip2 = toCaip2(network);
|
|
137
|
+
const adapter = createOwsAdapter(walletName, caip2);
|
|
138
|
+
const address = await adapter.getAddress();
|
|
139
|
+
const info = {
|
|
140
|
+
wallet: walletName,
|
|
141
|
+
address,
|
|
142
|
+
configDir,
|
|
143
|
+
network: config.network,
|
|
144
|
+
relay: config.relay,
|
|
145
|
+
chain: config.chain,
|
|
146
|
+
dataRegistry: config.registryAddress,
|
|
147
|
+
feedbackRegistry: config.reputationAddress
|
|
148
|
+
};
|
|
149
|
+
if (flags.json !== undefined) {
|
|
150
|
+
output(info, true);
|
|
151
|
+
} else {
|
|
152
|
+
process.stdout.write(`
|
|
153
|
+
OrbitMem initialized!
|
|
154
|
+
|
|
155
|
+
`);
|
|
156
|
+
process.stdout.write(` Wallet: ${info.wallet}
|
|
157
|
+
`);
|
|
158
|
+
process.stdout.write(` Config: ${info.configDir}
|
|
159
|
+
`);
|
|
160
|
+
process.stdout.write(` Network: ${info.network}
|
|
161
|
+
`);
|
|
162
|
+
process.stdout.write(` Relay: ${info.relay}
|
|
163
|
+
`);
|
|
164
|
+
process.stdout.write(` Chain: ${info.chain}
|
|
165
|
+
`);
|
|
166
|
+
process.stdout.write(` DataRegistry: ${info.dataRegistry}
|
|
167
|
+
`);
|
|
168
|
+
process.stdout.write(` FeedbackRegistry: ${info.feedbackRegistry}
|
|
169
|
+
|
|
170
|
+
`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
var init_init = __esm(() => {
|
|
174
|
+
init_config();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// src/commands/status.ts
|
|
178
|
+
var exports_status = {};
|
|
179
|
+
__export(exports_status, {
|
|
180
|
+
status: () => status
|
|
181
|
+
});
|
|
182
|
+
import { createOwsAdapter as createOwsAdapter2 } from "@orbitmem/sdk/identity";
|
|
183
|
+
async function status(_args, flags) {
|
|
184
|
+
const config = loadConfig();
|
|
185
|
+
if (!config.walletName) {
|
|
186
|
+
error("Not initialized. Run `orbitmem init` first.");
|
|
187
|
+
}
|
|
188
|
+
const caip2 = toCaip2(config.network);
|
|
189
|
+
const adapter = createOwsAdapter2(config.walletName, caip2);
|
|
190
|
+
const address = await adapter.getAddress();
|
|
191
|
+
const info = {
|
|
192
|
+
wallet: config.walletName,
|
|
193
|
+
address,
|
|
194
|
+
configDir: getConfigDir(),
|
|
195
|
+
relay: flags.relay ?? config.relay,
|
|
196
|
+
chain: flags.chain ?? config.chain,
|
|
197
|
+
registryAddress: config.registryAddress ?? "(not set)",
|
|
198
|
+
reputationAddress: config.reputationAddress ?? "(not set)"
|
|
199
|
+
};
|
|
200
|
+
output(info, flags.json !== undefined);
|
|
201
|
+
}
|
|
202
|
+
var init_status = __esm(() => {
|
|
203
|
+
init_config();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// src/utils/client.ts
|
|
207
|
+
import { createOrbitMem, getNetwork as getNetwork2 } from "@orbitmem/sdk";
|
|
208
|
+
import { createOwsAdapter as createOwsAdapter3 } from "@orbitmem/sdk/identity";
|
|
209
|
+
import { createPublicClient, createWalletClient, http } from "viem";
|
|
210
|
+
import { base, baseSepolia } from "viem/chains";
|
|
211
|
+
async function createClient(config, opts) {
|
|
212
|
+
const network = getNetwork2(config.network);
|
|
213
|
+
const chain = CHAINS[config.network] ?? baseSepolia;
|
|
214
|
+
const transport = http(network.rpcUrl);
|
|
215
|
+
const adapter = createOwsAdapter3(config.walletName, `eip155:${chain.id}`);
|
|
216
|
+
const viemAccount = await adapter.toViemAccount();
|
|
217
|
+
const publicClient = createPublicClient({ chain, transport });
|
|
218
|
+
const walletClient = createWalletClient({ chain, transport, account: viemAccount });
|
|
219
|
+
const encryption = {
|
|
220
|
+
defaultEngine: "aes",
|
|
221
|
+
aes: { kdf: "hkdf-sha256" }
|
|
222
|
+
};
|
|
223
|
+
if (opts?.litNetwork) {
|
|
224
|
+
encryption.lit = { network: opts.litNetwork };
|
|
225
|
+
}
|
|
226
|
+
const client = await createOrbitMem({
|
|
227
|
+
network: config.network,
|
|
228
|
+
identity: { owsWallet: config.walletName },
|
|
229
|
+
vault: { dbName: "orbitmem-cli" },
|
|
230
|
+
encryption,
|
|
231
|
+
persistence: {
|
|
232
|
+
relayUrl: config.relay
|
|
233
|
+
},
|
|
234
|
+
discovery: {
|
|
235
|
+
dataRegistry: network.dataRegistry,
|
|
236
|
+
reputationRegistry: network.feedbackRegistry,
|
|
237
|
+
registryChain: network.chain,
|
|
238
|
+
publicClient,
|
|
239
|
+
walletClient
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
await client.connect({ method: "evm" });
|
|
243
|
+
return client;
|
|
244
|
+
}
|
|
245
|
+
var CHAINS;
|
|
246
|
+
var init_client = __esm(() => {
|
|
247
|
+
CHAINS = {
|
|
248
|
+
"base-sepolia": baseSepolia,
|
|
249
|
+
base
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// src/commands/vault.ts
|
|
254
|
+
var exports_vault = {};
|
|
255
|
+
__export(exports_vault, {
|
|
256
|
+
vault: () => vault
|
|
257
|
+
});
|
|
258
|
+
async function vault(args, flags) {
|
|
259
|
+
const sub = args[0];
|
|
260
|
+
switch (sub) {
|
|
261
|
+
case "store":
|
|
262
|
+
return vaultStore(args.slice(1), flags);
|
|
263
|
+
case "get":
|
|
264
|
+
return vaultGet(args.slice(1), flags);
|
|
265
|
+
case "ls":
|
|
266
|
+
return vaultLs(args.slice(1), flags);
|
|
267
|
+
case "update-access":
|
|
268
|
+
return vaultUpdateAccess(args.slice(1), flags);
|
|
269
|
+
case "price":
|
|
270
|
+
return vaultPrice(args.slice(1), flags);
|
|
271
|
+
default:
|
|
272
|
+
error(`Unknown vault command: ${sub ?? "(none)"}. Use: store, get, ls, update-access, price`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async function vaultStore(args, flags) {
|
|
276
|
+
const [path, ...valueParts] = args;
|
|
277
|
+
const value = valueParts.join(" ");
|
|
278
|
+
if (!path || !value)
|
|
279
|
+
error("Usage: orbitmem vault store <path> <value>");
|
|
280
|
+
const config = loadConfig();
|
|
281
|
+
if (flags.relay)
|
|
282
|
+
config.relay = flags.relay;
|
|
283
|
+
const engine = flags.engine ?? "aes";
|
|
284
|
+
const litNetwork = flags["lit-network"] ?? "cayenne";
|
|
285
|
+
const useLit = engine === "lit";
|
|
286
|
+
const client = await createClient(config, useLit ? { litNetwork } : undefined);
|
|
287
|
+
try {
|
|
288
|
+
let visibility;
|
|
289
|
+
if (flags.public !== undefined) {
|
|
290
|
+
visibility = "public";
|
|
291
|
+
} else if (flags.shared !== undefined || useLit) {
|
|
292
|
+
visibility = "shared";
|
|
293
|
+
} else {
|
|
294
|
+
visibility = "private";
|
|
295
|
+
}
|
|
296
|
+
const putOpts = { visibility };
|
|
297
|
+
if (useLit) {
|
|
298
|
+
putOpts.engine = "lit";
|
|
299
|
+
const accessConditions = [];
|
|
300
|
+
if (flags["allow-address"]) {
|
|
301
|
+
const chain = flags["access-chain"] ?? config.chain ?? "base-sepolia";
|
|
302
|
+
const condition = {
|
|
303
|
+
conditionType: "evmBasic",
|
|
304
|
+
contractAddress: "",
|
|
305
|
+
standardContractType: "",
|
|
306
|
+
chain,
|
|
307
|
+
method: "",
|
|
308
|
+
parameters: [":userAddress"],
|
|
309
|
+
returnValueTest: { comparator: "=", value: flags["allow-address"] }
|
|
310
|
+
};
|
|
311
|
+
accessConditions.push(condition);
|
|
312
|
+
}
|
|
313
|
+
if (flags["min-score"]) {
|
|
314
|
+
const chain = flags["access-chain"] ?? config.chain ?? "base-sepolia";
|
|
315
|
+
const condition = {
|
|
316
|
+
conditionType: "evmContract",
|
|
317
|
+
contractAddress: config.reputationAddress,
|
|
318
|
+
standardContractType: "",
|
|
319
|
+
chain,
|
|
320
|
+
method: "getScore",
|
|
321
|
+
parameters: [":userAddress"],
|
|
322
|
+
returnValueTest: { comparator: ">=", value: flags["min-score"] }
|
|
323
|
+
};
|
|
324
|
+
accessConditions.push(condition);
|
|
325
|
+
}
|
|
326
|
+
if (accessConditions.length === 0) {
|
|
327
|
+
error("Lit encryption requires --allow-address <addr> or --min-score <n>");
|
|
328
|
+
}
|
|
329
|
+
putOpts.accessConditions = accessConditions;
|
|
330
|
+
}
|
|
331
|
+
const entry = await client.vault.put(path, value, putOpts);
|
|
332
|
+
const result = {
|
|
333
|
+
path,
|
|
334
|
+
visibility,
|
|
335
|
+
engine,
|
|
336
|
+
encrypted: entry.encrypted,
|
|
337
|
+
timestamp: entry.timestamp
|
|
338
|
+
};
|
|
339
|
+
if (flags.json !== undefined) {
|
|
340
|
+
output(result, true);
|
|
341
|
+
} else {
|
|
342
|
+
const engineLabel = useLit ? " [lit]" : "";
|
|
343
|
+
process.stdout.write(`Stored "${path}" (${visibility}${engineLabel})
|
|
344
|
+
`);
|
|
345
|
+
}
|
|
346
|
+
} finally {
|
|
347
|
+
await client.destroy();
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async function vaultUpdateAccess(args, flags) {
|
|
351
|
+
const [path] = args;
|
|
352
|
+
if (!path)
|
|
353
|
+
error("Usage: orbitmem vault update-access <path> --allow-address <addr> | --min-score <n>");
|
|
354
|
+
const config = loadConfig();
|
|
355
|
+
if (flags.relay)
|
|
356
|
+
config.relay = flags.relay;
|
|
357
|
+
const litNetwork = flags["lit-network"] ?? "cayenne";
|
|
358
|
+
const client = await createClient(config, { litNetwork });
|
|
359
|
+
try {
|
|
360
|
+
const accessConditions = [];
|
|
361
|
+
const chain = flags["access-chain"] ?? config.chain ?? "base-sepolia";
|
|
362
|
+
if (flags["allow-address"]) {
|
|
363
|
+
const condition = {
|
|
364
|
+
conditionType: "evmBasic",
|
|
365
|
+
contractAddress: "",
|
|
366
|
+
standardContractType: "",
|
|
367
|
+
chain,
|
|
368
|
+
method: "",
|
|
369
|
+
parameters: [":userAddress"],
|
|
370
|
+
returnValueTest: { comparator: "=", value: flags["allow-address"] }
|
|
371
|
+
};
|
|
372
|
+
accessConditions.push(condition);
|
|
373
|
+
}
|
|
374
|
+
if (flags["min-score"]) {
|
|
375
|
+
const condition = {
|
|
376
|
+
conditionType: "evmContract",
|
|
377
|
+
contractAddress: config.reputationAddress,
|
|
378
|
+
standardContractType: "",
|
|
379
|
+
chain,
|
|
380
|
+
method: "getScore",
|
|
381
|
+
parameters: [":userAddress"],
|
|
382
|
+
returnValueTest: { comparator: ">=", value: flags["min-score"] }
|
|
383
|
+
};
|
|
384
|
+
accessConditions.push(condition);
|
|
385
|
+
}
|
|
386
|
+
if (accessConditions.length === 0) {
|
|
387
|
+
error("update-access requires --allow-address <addr> or --min-score <n>");
|
|
388
|
+
}
|
|
389
|
+
const vault2 = client.vault;
|
|
390
|
+
const entry = await vault2.updateAccess(path, accessConditions, { chain });
|
|
391
|
+
if (flags.json !== undefined) {
|
|
392
|
+
output({ path, updated: true, timestamp: entry.timestamp }, true);
|
|
393
|
+
} else {
|
|
394
|
+
process.stdout.write(`Updated access for "${path}"
|
|
395
|
+
`);
|
|
396
|
+
}
|
|
397
|
+
} finally {
|
|
398
|
+
await client.destroy();
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async function vaultGet(args, flags) {
|
|
402
|
+
const [path] = args;
|
|
403
|
+
if (!path)
|
|
404
|
+
error("Usage: orbitmem vault get <path>");
|
|
405
|
+
const config = loadConfig();
|
|
406
|
+
if (flags.relay)
|
|
407
|
+
config.relay = flags.relay;
|
|
408
|
+
const client = await createClient(config);
|
|
409
|
+
try {
|
|
410
|
+
const entry = await client.vault.get(path);
|
|
411
|
+
if (!entry)
|
|
412
|
+
error(`Not found: ${path}`);
|
|
413
|
+
output(flags.json !== undefined ? entry : entry.value, flags.json !== undefined);
|
|
414
|
+
} finally {
|
|
415
|
+
await client.destroy();
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
async function vaultLs(args, flags) {
|
|
419
|
+
const [prefix] = args;
|
|
420
|
+
const config = loadConfig();
|
|
421
|
+
if (flags.relay)
|
|
422
|
+
config.relay = flags.relay;
|
|
423
|
+
const client = await createClient(config);
|
|
424
|
+
try {
|
|
425
|
+
const keys = await client.vault.keys(prefix);
|
|
426
|
+
if (flags.json !== undefined) {
|
|
427
|
+
output(keys, true);
|
|
428
|
+
} else if (keys.length === 0) {
|
|
429
|
+
process.stdout.write(`(no entries)
|
|
430
|
+
`);
|
|
431
|
+
} else {
|
|
432
|
+
for (const key of keys) {
|
|
433
|
+
process.stdout.write(`${key}
|
|
434
|
+
`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
} finally {
|
|
438
|
+
await client.destroy();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async function vaultPrice(args, flags) {
|
|
442
|
+
const action = args[0];
|
|
443
|
+
switch (action) {
|
|
444
|
+
case "set":
|
|
445
|
+
return vaultPriceSet(args.slice(1), flags);
|
|
446
|
+
case "get":
|
|
447
|
+
return vaultPriceGet(args.slice(1), flags);
|
|
448
|
+
case "ls":
|
|
449
|
+
return vaultPriceLs(flags);
|
|
450
|
+
case "rm":
|
|
451
|
+
return vaultPriceRm(args.slice(1), flags);
|
|
452
|
+
default:
|
|
453
|
+
error(`Unknown price command: ${action ?? "(none)"}. Use: set, get, ls, rm`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
async function vaultPriceSet(args, flags) {
|
|
457
|
+
const [path, amount] = args;
|
|
458
|
+
if (!path || !amount)
|
|
459
|
+
error("Usage: orbitmem vault price set <path> <amount>");
|
|
460
|
+
const config = loadConfig();
|
|
461
|
+
if (flags.relay)
|
|
462
|
+
config.relay = flags.relay;
|
|
463
|
+
const client = await createClient(config);
|
|
464
|
+
try {
|
|
465
|
+
const currency = flags.currency ?? "USDC";
|
|
466
|
+
await client.pricing.setPrice(path, { amount, currency });
|
|
467
|
+
if (flags.json !== undefined) {
|
|
468
|
+
output({ path, amount, currency }, true);
|
|
469
|
+
} else {
|
|
470
|
+
process.stdout.write(`Set price for "${path}": ${amount} ${currency} per read
|
|
471
|
+
`);
|
|
472
|
+
}
|
|
473
|
+
} finally {
|
|
474
|
+
await client.destroy();
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async function vaultPriceGet(args, flags) {
|
|
478
|
+
const [path] = args;
|
|
479
|
+
if (!path)
|
|
480
|
+
error("Usage: orbitmem vault price get <path>");
|
|
481
|
+
const config = loadConfig();
|
|
482
|
+
if (flags.relay)
|
|
483
|
+
config.relay = flags.relay;
|
|
484
|
+
const client = await createClient(config);
|
|
485
|
+
try {
|
|
486
|
+
const price = await client.pricing.getPrice(path);
|
|
487
|
+
if (!price) {
|
|
488
|
+
if (flags.json !== undefined) {
|
|
489
|
+
output(null, true);
|
|
490
|
+
} else {
|
|
491
|
+
process.stdout.write(`"${path}" is free (no pricing set)
|
|
492
|
+
`);
|
|
493
|
+
}
|
|
494
|
+
} else if (flags.json !== undefined) {
|
|
495
|
+
output({ path, ...price }, true);
|
|
496
|
+
} else {
|
|
497
|
+
process.stdout.write(`${price.amount} ${price.currency}
|
|
498
|
+
`);
|
|
499
|
+
}
|
|
500
|
+
} finally {
|
|
501
|
+
await client.destroy();
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
async function vaultPriceLs(flags) {
|
|
505
|
+
const config = loadConfig();
|
|
506
|
+
if (flags.relay)
|
|
507
|
+
config.relay = flags.relay;
|
|
508
|
+
const client = await createClient(config);
|
|
509
|
+
try {
|
|
510
|
+
const prices = await client.pricing.listPrices();
|
|
511
|
+
if (flags.json !== undefined) {
|
|
512
|
+
output(prices, true);
|
|
513
|
+
} else if (prices.length === 0) {
|
|
514
|
+
process.stdout.write(`(no priced paths)
|
|
515
|
+
`);
|
|
516
|
+
} else {
|
|
517
|
+
for (const p of prices) {
|
|
518
|
+
process.stdout.write(`${p.path} ${p.amount} ${p.currency}
|
|
519
|
+
`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
} finally {
|
|
523
|
+
await client.destroy();
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
async function vaultPriceRm(args, flags) {
|
|
527
|
+
const [path] = args;
|
|
528
|
+
if (!path)
|
|
529
|
+
error("Usage: orbitmem vault price rm <path>");
|
|
530
|
+
const config = loadConfig();
|
|
531
|
+
if (flags.relay)
|
|
532
|
+
config.relay = flags.relay;
|
|
533
|
+
const client = await createClient(config);
|
|
534
|
+
try {
|
|
535
|
+
await client.pricing.removePrice(path);
|
|
536
|
+
if (flags.json !== undefined) {
|
|
537
|
+
output({ path, removed: true }, true);
|
|
538
|
+
} else {
|
|
539
|
+
process.stdout.write(`Removed pricing for "${path}"
|
|
540
|
+
`);
|
|
541
|
+
}
|
|
542
|
+
} finally {
|
|
543
|
+
await client.destroy();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
var init_vault = __esm(() => {
|
|
547
|
+
init_config();
|
|
548
|
+
init_client();
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// src/commands/register.ts
|
|
552
|
+
var exports_register = {};
|
|
553
|
+
__export(exports_register, {
|
|
554
|
+
register: () => register
|
|
555
|
+
});
|
|
556
|
+
async function register(args, flags) {
|
|
557
|
+
const [path] = args;
|
|
558
|
+
if (!path)
|
|
559
|
+
error("Usage: orbitmem register <path>");
|
|
560
|
+
const config = loadConfig();
|
|
561
|
+
if (flags.relay)
|
|
562
|
+
config.relay = flags.relay;
|
|
563
|
+
if (!config.registryAddress)
|
|
564
|
+
error("No registry address configured. Set registryAddress in ~/.orbitmem/config.json");
|
|
565
|
+
const client = await createClient(config);
|
|
566
|
+
try {
|
|
567
|
+
const entry = await client.vault.get(path);
|
|
568
|
+
if (!entry)
|
|
569
|
+
error(`Vault entry not found: ${path}`);
|
|
570
|
+
const result = await client.discovery.registerData({
|
|
571
|
+
key: path,
|
|
572
|
+
name: flags.name ?? path,
|
|
573
|
+
description: flags.description ?? "",
|
|
574
|
+
schema: flags.schema,
|
|
575
|
+
tags: flags.tags ? flags.tags.split(",") : []
|
|
576
|
+
});
|
|
577
|
+
if (flags.json !== undefined) {
|
|
578
|
+
output(result, true);
|
|
579
|
+
} else {
|
|
580
|
+
process.stdout.write(`Registered "${path}" on-chain
|
|
581
|
+
`);
|
|
582
|
+
process.stdout.write(` Data ID: ${result.dataId}
|
|
583
|
+
`);
|
|
584
|
+
}
|
|
585
|
+
} finally {
|
|
586
|
+
await client.destroy();
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
var init_register = __esm(() => {
|
|
590
|
+
init_config();
|
|
591
|
+
init_client();
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
// src/commands/discover.ts
|
|
595
|
+
var exports_discover = {};
|
|
596
|
+
__export(exports_discover, {
|
|
597
|
+
discover: () => discover
|
|
598
|
+
});
|
|
599
|
+
async function discover(args, flags) {
|
|
600
|
+
const config = loadConfig();
|
|
601
|
+
if (flags.relay)
|
|
602
|
+
config.relay = flags.relay;
|
|
603
|
+
if (!config.registryAddress)
|
|
604
|
+
error("No registry address configured. Set registryAddress in ~/.orbitmem/config.json");
|
|
605
|
+
const client = await createClient(config);
|
|
606
|
+
try {
|
|
607
|
+
const query = {};
|
|
608
|
+
if (args[0])
|
|
609
|
+
query.schema = args[0];
|
|
610
|
+
if (flags.tags)
|
|
611
|
+
query.tags = flags.tags.split(",");
|
|
612
|
+
if (flags["min-quality"])
|
|
613
|
+
query.minQuality = Number(flags["min-quality"]);
|
|
614
|
+
const results = await client.discovery.findData(query);
|
|
615
|
+
if (flags.json !== undefined) {
|
|
616
|
+
output(results, true);
|
|
617
|
+
} else if (results.length === 0) {
|
|
618
|
+
process.stdout.write(`No data found
|
|
619
|
+
`);
|
|
620
|
+
} else {
|
|
621
|
+
const rows = results.map((r) => ({
|
|
622
|
+
id: r.dataId,
|
|
623
|
+
name: r.name,
|
|
624
|
+
quality: r.quality,
|
|
625
|
+
vault: `${String(r.vaultAddress ?? "").slice(0, 10)}...`
|
|
626
|
+
}));
|
|
627
|
+
output(rows, false);
|
|
628
|
+
}
|
|
629
|
+
} finally {
|
|
630
|
+
await client.destroy();
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
var init_discover = __esm(() => {
|
|
634
|
+
init_config();
|
|
635
|
+
init_client();
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
// src/commands/snapshot.ts
|
|
639
|
+
var exports_snapshot = {};
|
|
640
|
+
__export(exports_snapshot, {
|
|
641
|
+
snapshot: () => snapshot
|
|
642
|
+
});
|
|
643
|
+
async function snapshot(_args, flags) {
|
|
644
|
+
const config = loadConfig();
|
|
645
|
+
if (flags.relay)
|
|
646
|
+
config.relay = flags.relay;
|
|
647
|
+
const client = await createClient(config);
|
|
648
|
+
try {
|
|
649
|
+
const result = await client.persistence.archive({
|
|
650
|
+
label: flags.label
|
|
651
|
+
});
|
|
652
|
+
if (flags.json !== undefined) {
|
|
653
|
+
output(result, true);
|
|
654
|
+
} else {
|
|
655
|
+
process.stdout.write(`Snapshot archived!
|
|
656
|
+
`);
|
|
657
|
+
process.stdout.write(` CID: ${result.cid}
|
|
658
|
+
`);
|
|
659
|
+
process.stdout.write(` Size: ${result.size} bytes
|
|
660
|
+
`);
|
|
661
|
+
process.stdout.write(` Entries: ${result.entryCount}
|
|
662
|
+
`);
|
|
663
|
+
}
|
|
664
|
+
} finally {
|
|
665
|
+
await client.destroy();
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
var init_snapshot = __esm(() => {
|
|
669
|
+
init_config();
|
|
670
|
+
init_client();
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
// src/commands/dev.ts
|
|
674
|
+
var exports_dev = {};
|
|
675
|
+
__export(exports_dev, {
|
|
676
|
+
dev: () => dev
|
|
677
|
+
});
|
|
678
|
+
async function dev(_args, flags) {
|
|
679
|
+
const port = flags.port ? Number(flags.port) : 3000;
|
|
680
|
+
process.stdout.write(`Starting OrbitMem relay on http://localhost:${port}...
|
|
681
|
+
`);
|
|
682
|
+
const { buildApp } = await import("@orbitmem/relay/app");
|
|
683
|
+
const { createMockServices } = await import("@orbitmem/relay/services");
|
|
684
|
+
const { serve } = await import("@hono/node-server");
|
|
685
|
+
const services = createMockServices();
|
|
686
|
+
const app = buildApp(services);
|
|
687
|
+
const server = serve({
|
|
688
|
+
fetch: app.fetch,
|
|
689
|
+
port
|
|
690
|
+
});
|
|
691
|
+
process.stdout.write(`Relay running at http://localhost:${port}
|
|
692
|
+
`);
|
|
693
|
+
process.stdout.write(`Press Ctrl+C to stop
|
|
694
|
+
|
|
695
|
+
`);
|
|
696
|
+
process.on("SIGINT", () => {
|
|
697
|
+
process.stdout.write(`
|
|
698
|
+
Shutting down...
|
|
699
|
+
`);
|
|
700
|
+
server.close();
|
|
701
|
+
process.exit(0);
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// src/index.ts
|
|
706
|
+
function parseArgs(argv) {
|
|
707
|
+
const raw = argv.slice(2);
|
|
708
|
+
const flags = {};
|
|
709
|
+
const positional = [];
|
|
710
|
+
for (let i = 0;i < raw.length; i++) {
|
|
711
|
+
if (raw[i].startsWith("--")) {
|
|
712
|
+
const key = raw[i].slice(2);
|
|
713
|
+
const next = raw[i + 1];
|
|
714
|
+
if (next && !next.startsWith("--")) {
|
|
715
|
+
flags[key] = next;
|
|
716
|
+
i++;
|
|
717
|
+
} else {
|
|
718
|
+
flags[key] = "";
|
|
719
|
+
}
|
|
720
|
+
} else {
|
|
721
|
+
positional.push(raw[i]);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return {
|
|
725
|
+
command: positional[0] ?? "help",
|
|
726
|
+
args: positional.slice(1),
|
|
727
|
+
flags
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
function printUsage() {
|
|
731
|
+
process.stdout.write(`
|
|
732
|
+
Usage: orbitmem <command> [options]
|
|
733
|
+
|
|
734
|
+
Commands:
|
|
735
|
+
init Generate keys and create config
|
|
736
|
+
status Show identity, config, and vault info
|
|
737
|
+
vault store <path> <value> Store data in vault
|
|
738
|
+
vault get <path> Read data from vault
|
|
739
|
+
vault ls [prefix] List vault keys
|
|
740
|
+
vault update-access <path> Re-encrypt with new Lit access conditions
|
|
741
|
+
vault price set <path> <amount> Set per-read price (USDC)
|
|
742
|
+
vault price get <path> Show price for path
|
|
743
|
+
vault price ls List all priced paths
|
|
744
|
+
vault price rm <path> Remove pricing (free)
|
|
745
|
+
register <path> Register data on-chain (ERC-8004)
|
|
746
|
+
discover [query] Search on-chain registries
|
|
747
|
+
snapshot Persist vault to Storacha
|
|
748
|
+
dev Start local relay server
|
|
749
|
+
|
|
750
|
+
Options:
|
|
751
|
+
--relay <url> Override relay URL
|
|
752
|
+
--chain <name> Override chain
|
|
753
|
+
--json Output as JSON
|
|
754
|
+
--help Show this help
|
|
755
|
+
|
|
756
|
+
Vault store options:
|
|
757
|
+
--public Store as public (unencrypted)
|
|
758
|
+
--shared Store as shared (encrypted, condition-gated)
|
|
759
|
+
--engine <aes|lit> Encryption engine (default: aes)
|
|
760
|
+
--lit-network <name> Lit network: cayenne | manzano | habanero (default: cayenne)
|
|
761
|
+
--allow-address <addr> Lit: allow this address to decrypt
|
|
762
|
+
--min-score <n> Lit: require minimum reputation score to decrypt
|
|
763
|
+
--access-chain <chain> Lit: chain for access conditions (default: base-sepolia)
|
|
764
|
+
|
|
765
|
+
`);
|
|
766
|
+
}
|
|
767
|
+
async function main() {
|
|
768
|
+
const { command, args, flags } = parseArgs(process.argv);
|
|
769
|
+
if (flags.help !== undefined || command === "help") {
|
|
770
|
+
printUsage();
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
switch (command) {
|
|
774
|
+
case "init": {
|
|
775
|
+
const { init: init2 } = await Promise.resolve().then(() => (init_init(), exports_init));
|
|
776
|
+
await init2(args, flags);
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
case "status": {
|
|
780
|
+
const { status: status2 } = await Promise.resolve().then(() => (init_status(), exports_status));
|
|
781
|
+
await status2(args, flags);
|
|
782
|
+
break;
|
|
783
|
+
}
|
|
784
|
+
case "vault": {
|
|
785
|
+
const { vault: vault2 } = await Promise.resolve().then(() => (init_vault(), exports_vault));
|
|
786
|
+
await vault2(args, flags);
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
789
|
+
case "register": {
|
|
790
|
+
const { register: register2 } = await Promise.resolve().then(() => (init_register(), exports_register));
|
|
791
|
+
await register2(args, flags);
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
case "discover": {
|
|
795
|
+
const { discover: discover2 } = await Promise.resolve().then(() => (init_discover(), exports_discover));
|
|
796
|
+
await discover2(args, flags);
|
|
797
|
+
break;
|
|
798
|
+
}
|
|
799
|
+
case "snapshot": {
|
|
800
|
+
const { snapshot: snapshot2 } = await Promise.resolve().then(() => (init_snapshot(), exports_snapshot));
|
|
801
|
+
await snapshot2(args, flags);
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
case "dev": {
|
|
805
|
+
const { dev: dev2 } = await Promise.resolve().then(() => exports_dev);
|
|
806
|
+
await dev2(args, flags);
|
|
807
|
+
break;
|
|
808
|
+
}
|
|
809
|
+
default:
|
|
810
|
+
process.stderr.write(`Unknown command: ${command}
|
|
811
|
+
`);
|
|
812
|
+
printUsage();
|
|
813
|
+
process.exit(1);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
main().catch((err) => {
|
|
817
|
+
process.stderr.write(`error: ${err.message}
|
|
818
|
+
`);
|
|
819
|
+
process.exit(1);
|
|
820
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@orbitmem/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for OrbitMem — manage vaults, discover data, and interact with on-chain registries",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agents",
|
|
7
|
+
"ai",
|
|
8
|
+
"cli",
|
|
9
|
+
"data",
|
|
10
|
+
"orbitmem",
|
|
11
|
+
"vault",
|
|
12
|
+
"web3"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/oboroxyz/orbitmem/tree/main/packages/cli",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Oboro Inc. <dev@oboro.xyz> (https://oboro.xyz)",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/oboroxyz/orbitmem",
|
|
20
|
+
"directory": "packages/cli"
|
|
21
|
+
},
|
|
22
|
+
"bin": {
|
|
23
|
+
"orbitmem": "./dist/index.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target node --packages external",
|
|
32
|
+
"test": "bun test",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"prepublishOnly": "bun run build"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@hono/node-server": "^1.13.0",
|
|
38
|
+
"@open-wallet-standard/core": "^1.1.0",
|
|
39
|
+
"@orbitmem/relay": "^0.1.0",
|
|
40
|
+
"@orbitmem/sdk": "^0.1.0",
|
|
41
|
+
"viem": "^2.0.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^25.4.0",
|
|
45
|
+
"bun-types": "latest",
|
|
46
|
+
"typescript": "^5.5.0"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|