solforge 0.2.4 → 0.2.6
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 +471 -79
- package/cli.cjs +106 -78
- package/package.json +1 -1
- package/scripts/install.sh +1 -1
- package/scripts/postinstall.cjs +69 -61
- package/server/lib/base58.ts +1 -1
- package/server/methods/account/get-account-info.ts +3 -7
- package/server/methods/account/get-balance.ts +3 -7
- package/server/methods/account/get-multiple-accounts.ts +2 -1
- package/server/methods/account/get-parsed-account-info.ts +3 -7
- package/server/methods/account/parsers/index.ts +2 -2
- package/server/methods/account/parsers/loader-upgradeable.ts +14 -1
- package/server/methods/account/parsers/spl-token.ts +29 -10
- package/server/methods/account/request-airdrop.ts +44 -31
- package/server/methods/block/get-block.ts +3 -7
- package/server/methods/block/get-blocks-with-limit.ts +3 -7
- package/server/methods/block/is-blockhash-valid.ts +3 -7
- package/server/methods/get-address-lookup-table.ts +3 -7
- package/server/methods/program/get-program-accounts.ts +9 -9
- package/server/methods/program/get-token-account-balance.ts +3 -7
- package/server/methods/program/get-token-accounts-by-delegate.ts +4 -3
- package/server/methods/program/get-token-accounts-by-owner.ts +61 -35
- package/server/methods/program/get-token-largest-accounts.ts +3 -2
- package/server/methods/program/get-token-supply.ts +3 -2
- package/server/methods/solforge/index.ts +9 -6
- package/server/methods/transaction/get-parsed-transaction.ts +3 -7
- package/server/methods/transaction/get-signature-statuses.ts +14 -7
- package/server/methods/transaction/get-signatures-for-address.ts +3 -7
- package/server/methods/transaction/get-transaction.ts +167 -81
- package/server/methods/transaction/send-transaction.ts +29 -16
- package/server/methods/transaction/simulate-transaction.ts +3 -2
- package/server/rpc-server.ts +47 -34
- package/server/types.ts +9 -6
- package/server/ws-server.ts +15 -8
- package/src/api-server-entry.ts +91 -91
- package/src/cli/commands/airdrop.ts +2 -2
- package/src/cli/commands/config.ts +2 -2
- package/src/cli/commands/mint.ts +3 -3
- package/src/cli/commands/program-clone.ts +9 -11
- package/src/cli/commands/program-load.ts +3 -3
- package/src/cli/commands/rpc-start.ts +8 -5
- package/src/cli/commands/token-adopt-authority.ts +1 -1
- package/src/cli/commands/token-clone.ts +5 -6
- package/src/cli/commands/token-create.ts +5 -5
- package/src/cli/main.ts +38 -37
- package/src/cli/run-solforge.ts +20 -6
- package/src/cli/setup-wizard.ts +8 -6
- package/src/commands/add-program.ts +324 -328
- package/src/commands/init.ts +106 -106
- package/src/commands/list.ts +125 -125
- package/src/commands/mint.ts +247 -248
- package/src/commands/start.ts +837 -833
- package/src/commands/status.ts +80 -80
- package/src/commands/stop.ts +381 -382
- package/src/config/index.ts +33 -17
- package/src/config/manager.ts +150 -150
- package/src/db/index.ts +2 -2
- package/src/db/tx-store.ts +12 -8
- package/src/gui/public/app.css +1556 -1
- package/src/gui/public/build/main.css +1569 -1
- package/src/gui/server.ts +21 -22
- package/src/gui/src/api.ts +1 -1
- package/src/gui/src/app.tsx +96 -45
- package/src/gui/src/components/airdrop-mint-form.tsx +49 -19
- package/src/gui/src/components/clone-program-modal.tsx +31 -12
- package/src/gui/src/components/clone-token-modal.tsx +32 -13
- package/src/gui/src/components/modal.tsx +18 -11
- package/src/gui/src/components/programs-panel.tsx +27 -15
- package/src/gui/src/components/status-panel.tsx +32 -18
- package/src/gui/src/components/tokens-panel.tsx +25 -19
- package/src/gui/src/index.css +491 -463
- package/src/index.ts +177 -149
- package/src/rpc/start.ts +1 -1
- package/src/services/api-server.ts +494 -475
- package/src/services/port-manager.ts +164 -167
- package/src/services/process-registry.ts +144 -145
- package/src/services/program-cloner.ts +312 -312
- package/src/services/token-cloner.ts +799 -797
- package/src/services/validator.ts +288 -290
- package/src/types/config.ts +72 -72
- package/src/utils/shell.ts +75 -75
- package/src/utils/token-loader.ts +78 -78
|
@@ -8,7 +8,7 @@ import { parseFlags } from "../utils/args";
|
|
|
8
8
|
// solforge token clone <mint> --to <owner> --ui-amount <num> --decimals <d>
|
|
9
9
|
export async function tokenCloneCommand(args: string[]) {
|
|
10
10
|
const { flags, rest } = parseFlags(args);
|
|
11
|
-
const mint = ((rest[0] as string) || (flags
|
|
11
|
+
const mint = ((rest[0] as string) || (flags.mint as string) || "").trim();
|
|
12
12
|
if (!mint) {
|
|
13
13
|
p.log.error(
|
|
14
14
|
"Usage: solforge token clone <mint> [--amount <baseUnits> | --ui-amount <num>] [--endpoint URL]",
|
|
@@ -16,10 +16,10 @@ export async function tokenCloneCommand(args: string[]) {
|
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
const configPath = flags
|
|
19
|
+
const _owner = flags.to as string | undefined; // optional; defaults to faucet on server
|
|
20
|
+
const configPath = flags.config as string | undefined;
|
|
21
21
|
const cfg = await readConfig(configPath);
|
|
22
|
-
const endpoint = (flags
|
|
22
|
+
const endpoint = (flags.endpoint as string) || cfg.clone.endpoint;
|
|
23
23
|
const url = `http://localhost:${cfg.server.rpcPort}`;
|
|
24
24
|
const s = p.spinner();
|
|
25
25
|
s.start("Cloning mint into LiteSVM...");
|
|
@@ -75,7 +75,7 @@ export async function tokenCloneCommand(args: string[]) {
|
|
|
75
75
|
),
|
|
76
76
|
);
|
|
77
77
|
return;
|
|
78
|
-
} catch (adoptErr:
|
|
78
|
+
} catch (adoptErr: unknown) {
|
|
79
79
|
p.log.warn(
|
|
80
80
|
`Adopt authority failed: ${adoptErr?.message || String(adoptErr)}`,
|
|
81
81
|
);
|
|
@@ -85,7 +85,6 @@ export async function tokenCloneCommand(args: string[]) {
|
|
|
85
85
|
);
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
-
return;
|
|
89
88
|
} catch (e) {
|
|
90
89
|
s.stop("Clone failed");
|
|
91
90
|
p.log.error(String(e));
|
|
@@ -8,13 +8,13 @@ import { parseFlags } from "../utils/args";
|
|
|
8
8
|
// solforge token create --decimals <d> --owner <pubkey> [--mint <pubkey>] [--amount <baseUnits> | --ui-amount <num>]
|
|
9
9
|
export async function tokenCreateCommand(args: string[]) {
|
|
10
10
|
const { flags } = parseFlags(args);
|
|
11
|
-
const decimals = flags
|
|
12
|
-
const owner = flags
|
|
13
|
-
const mint = flags
|
|
14
|
-
const amountBase = flags
|
|
11
|
+
const decimals = flags.decimals ? Number(flags.decimals) : NaN;
|
|
12
|
+
const owner = flags.owner as string | undefined;
|
|
13
|
+
const mint = flags.mint as string | undefined;
|
|
14
|
+
const amountBase = flags.amount as string | undefined;
|
|
15
15
|
const uiAmount = flags["ui-amount"] as string | undefined;
|
|
16
16
|
|
|
17
|
-
if (!isFinite(decimals)) {
|
|
17
|
+
if (!Number.isFinite(decimals)) {
|
|
18
18
|
p.log.error("--decimals is required (0-18)");
|
|
19
19
|
return;
|
|
20
20
|
}
|
package/src/cli/main.ts
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
// Minimal, fast CLI router with @clack/prompts for UX
|
|
2
2
|
import * as p from "@clack/prompts";
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import pkg from "../../package.json" assert { type: "json" };
|
|
3
|
+
// CLI version string; keep in sync with package.json if possible
|
|
4
|
+
const VERSION = "0.2.4";
|
|
6
5
|
|
|
7
6
|
// Robust arg parsing for both bun script and compiled binary
|
|
8
7
|
const known = new Set([
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
"help",
|
|
9
|
+
"-h",
|
|
10
|
+
"--help",
|
|
11
|
+
"version",
|
|
12
|
+
"-v",
|
|
13
|
+
"--version",
|
|
14
|
+
"rpc",
|
|
15
|
+
"start",
|
|
16
|
+
"config",
|
|
17
|
+
"airdrop",
|
|
18
|
+
"mint",
|
|
19
|
+
"token",
|
|
20
|
+
"program",
|
|
22
21
|
]);
|
|
23
22
|
const raw = Bun.argv.slice(1);
|
|
24
23
|
const firstIdx = raw.findIndex((a) => known.has(String(a)));
|
|
@@ -27,26 +26,28 @@ const argv = firstIdx >= 0 ? raw.slice(firstIdx) : [];
|
|
|
27
26
|
async function main() {
|
|
28
27
|
const [cmd, sub, ...rest] = argv;
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
if (!cmd) {
|
|
30
|
+
const { runSolforge } = await import("./run-solforge");
|
|
31
|
+
// Pass through any flags provided when no explicit command was given
|
|
32
|
+
await runSolforge(raw);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
if (cmd === "help" || cmd === "-h" || cmd === "--help") {
|
|
37
|
+
printHelp();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
if (cmd === "version" || cmd === "-v" || cmd === "--version") {
|
|
42
|
+
printVersion();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
45
|
|
|
46
46
|
// Alias: solforge start -> solforge rpc start
|
|
47
47
|
if (cmd === "start") {
|
|
48
|
-
|
|
49
|
-
await
|
|
48
|
+
// Run the full Solforge flow (config ensure + bootstrap + servers)
|
|
49
|
+
const { runSolforge } = await import("./run-solforge");
|
|
50
|
+
await runSolforge(rest);
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -115,7 +116,7 @@ async function main() {
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
function printHelp() {
|
|
118
|
-
|
|
119
|
+
console.log(`
|
|
119
120
|
solforge <command>
|
|
120
121
|
|
|
121
122
|
Commands:
|
|
@@ -134,18 +135,18 @@ Commands:
|
|
|
134
135
|
Options:
|
|
135
136
|
-h, --help Show help
|
|
136
137
|
-v, --version Show version
|
|
138
|
+
--network Bind servers to 0.0.0.0 (LAN access)
|
|
139
|
+
-y, --ci Non-interactive; auto-accept prompts (use existing config)
|
|
137
140
|
`);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
async function unknownCommand(parts: (string | undefined)[]) {
|
|
141
|
-
|
|
142
|
-
|
|
144
|
+
p.log.error(`Unknown command: ${parts.filter(Boolean).join(" ")}`);
|
|
145
|
+
printHelp();
|
|
143
146
|
}
|
|
144
147
|
|
|
145
148
|
function printVersion() {
|
|
146
|
-
|
|
147
|
-
const v = (pkg as any)?.version ?? "";
|
|
148
|
-
console.log(String(v));
|
|
149
|
+
console.log(String(VERSION));
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
main();
|
package/src/cli/run-solforge.ts
CHANGED
|
@@ -9,17 +9,25 @@ import { startRpcServers } from "../rpc/start";
|
|
|
9
9
|
import { bootstrapEnvironment } from "./bootstrap";
|
|
10
10
|
import { cancelSetup } from "./setup-utils";
|
|
11
11
|
import { runSetupWizard } from "./setup-wizard";
|
|
12
|
+
import { parseFlags } from "./utils/args";
|
|
12
13
|
|
|
13
14
|
const CONFIG_PATH = "sf.config.json";
|
|
14
15
|
|
|
15
|
-
export async function runSolforge() {
|
|
16
|
-
const
|
|
17
|
-
|
|
16
|
+
export async function runSolforge(args: string[] = []) {
|
|
17
|
+
const { flags } = parseFlags(args);
|
|
18
|
+
const ci = flags.ci === true || flags.y === true;
|
|
19
|
+
const config = await ensureConfig(ci);
|
|
20
|
+
await startWithConfig(config, args);
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
async function ensureConfig(): Promise<SolforgeConfig> {
|
|
23
|
+
async function ensureConfig(ci = false): Promise<SolforgeConfig> {
|
|
21
24
|
const exists = await Bun.file(CONFIG_PATH).exists();
|
|
22
25
|
if (!exists) {
|
|
26
|
+
if (ci) {
|
|
27
|
+
// Non-interactive: write defaults and continue
|
|
28
|
+
await saveConfig(defaultConfig);
|
|
29
|
+
return defaultConfig;
|
|
30
|
+
}
|
|
23
31
|
p.intro("Solforge setup");
|
|
24
32
|
const config = await runSetupWizard();
|
|
25
33
|
await saveConfig(config);
|
|
@@ -28,6 +36,7 @@ async function ensureConfig(): Promise<SolforgeConfig> {
|
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
const current = await readConfig(CONFIG_PATH);
|
|
39
|
+
if (ci) return current; // Non-interactive: always reuse existing config
|
|
31
40
|
const reuse = await p.confirm({
|
|
32
41
|
message: `Use existing config at ${CONFIG_PATH}?`,
|
|
33
42
|
initialValue: true,
|
|
@@ -41,8 +50,13 @@ async function ensureConfig(): Promise<SolforgeConfig> {
|
|
|
41
50
|
return updated;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
async function startWithConfig(config: SolforgeConfig) {
|
|
45
|
-
const
|
|
53
|
+
async function startWithConfig(config: SolforgeConfig, args: string[] = []) {
|
|
54
|
+
const { flags } = parseFlags(args);
|
|
55
|
+
const host = String(
|
|
56
|
+
flags.network === true
|
|
57
|
+
? "0.0.0.0"
|
|
58
|
+
: ((flags.host as string) ?? process.env.RPC_HOST ?? "127.0.0.1"),
|
|
59
|
+
);
|
|
46
60
|
const rpcPort = Number(config.server.rpcPort || defaultConfig.server.rpcPort);
|
|
47
61
|
const wsPort = Number(config.server.wsPort || rpcPort + 1);
|
|
48
62
|
const guiEnabled = config.gui?.enabled !== false;
|
package/src/cli/setup-wizard.ts
CHANGED
|
@@ -170,9 +170,10 @@ async function resolveTokens(selections: string[], existing: string[] = []) {
|
|
|
170
170
|
const set = new Set(existing);
|
|
171
171
|
for (const selection of selections) {
|
|
172
172
|
if (selection === "__custom__") {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
{
|
|
174
|
+
const values = await collectCustomEntries("token mint address");
|
|
175
|
+
for (const value of values) set.add(value);
|
|
176
|
+
}
|
|
176
177
|
continue;
|
|
177
178
|
}
|
|
178
179
|
const preset = TOKEN_PRESETS.find((token) => token.value === selection);
|
|
@@ -193,9 +194,10 @@ async function resolvePrograms(selections: string[], existing: string[] = []) {
|
|
|
193
194
|
const set = new Set(existing);
|
|
194
195
|
for (const selection of selections) {
|
|
195
196
|
if (selection === "__custom__") {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
{
|
|
198
|
+
const values = await collectCustomEntries("program id");
|
|
199
|
+
for (const value of values) set.add(value);
|
|
200
|
+
}
|
|
199
201
|
continue;
|
|
200
202
|
}
|
|
201
203
|
const preset = PROGRAM_PRESETS.find(
|