solforge 0.2.11 → 0.2.13

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 (175) hide show
  1. package/package.json +4 -8
  2. package/docs/API.md +0 -379
  3. package/docs/CONFIGURATION.md +0 -407
  4. package/docs/bun-single-file-executable.md +0 -585
  5. package/docs/cli-plan.md +0 -154
  6. package/docs/data-indexing-plan.md +0 -214
  7. package/docs/gui-roadmap.md +0 -202
  8. package/scripts/decode-b58.ts +0 -10
  9. package/scripts/install.sh +0 -112
  10. package/server/index.ts +0 -5
  11. package/server/lib/base58.ts +0 -33
  12. package/server/lib/faucet.ts +0 -110
  13. package/server/lib/instruction-parser.ts +0 -328
  14. package/server/lib/parsers/spl-associated-token-account.ts +0 -50
  15. package/server/lib/parsers/spl-token.ts +0 -340
  16. package/server/lib/spl-token.ts +0 -57
  17. package/server/methods/TEMPLATE.md +0 -117
  18. package/server/methods/account/get-account-info.ts +0 -86
  19. package/server/methods/account/get-balance.ts +0 -23
  20. package/server/methods/account/get-multiple-accounts.ts +0 -84
  21. package/server/methods/account/get-parsed-account-info.ts +0 -17
  22. package/server/methods/account/index.ts +0 -12
  23. package/server/methods/account/parsers/index.ts +0 -52
  24. package/server/methods/account/parsers/loader-upgradeable.ts +0 -79
  25. package/server/methods/account/parsers/spl-token.ts +0 -256
  26. package/server/methods/account/parsers/system.ts +0 -4
  27. package/server/methods/account/request-airdrop.ts +0 -271
  28. package/server/methods/admin/adopt-mint-authority.ts +0 -94
  29. package/server/methods/admin/clone-program-accounts.ts +0 -55
  30. package/server/methods/admin/clone-program.ts +0 -152
  31. package/server/methods/admin/clone-token-accounts.ts +0 -117
  32. package/server/methods/admin/clone-token-mint.ts +0 -82
  33. package/server/methods/admin/create-mint.ts +0 -114
  34. package/server/methods/admin/create-token-account.ts +0 -137
  35. package/server/methods/admin/helpers.ts +0 -70
  36. package/server/methods/admin/index.ts +0 -10
  37. package/server/methods/admin/list-mints.ts +0 -21
  38. package/server/methods/admin/load-program.ts +0 -52
  39. package/server/methods/admin/mint-to.ts +0 -266
  40. package/server/methods/block/get-block-height.ts +0 -5
  41. package/server/methods/block/get-block.ts +0 -31
  42. package/server/methods/block/get-blocks-with-limit.ts +0 -19
  43. package/server/methods/block/get-latest-blockhash.ts +0 -12
  44. package/server/methods/block/get-slot.ts +0 -5
  45. package/server/methods/block/index.ts +0 -6
  46. package/server/methods/block/is-blockhash-valid.ts +0 -19
  47. package/server/methods/epoch/get-cluster-nodes.ts +0 -17
  48. package/server/methods/epoch/get-epoch-info.ts +0 -16
  49. package/server/methods/epoch/get-epoch-schedule.ts +0 -15
  50. package/server/methods/epoch/get-highest-snapshot-slot.ts +0 -9
  51. package/server/methods/epoch/get-leader-schedule.ts +0 -8
  52. package/server/methods/epoch/get-max-retransmit-slot.ts +0 -9
  53. package/server/methods/epoch/get-max-shred-insert-slot.ts +0 -9
  54. package/server/methods/epoch/get-slot-leader.ts +0 -6
  55. package/server/methods/epoch/get-slot-leaders.ts +0 -9
  56. package/server/methods/epoch/get-stake-activation.ts +0 -9
  57. package/server/methods/epoch/get-stake-minimum-delegation.ts +0 -9
  58. package/server/methods/epoch/get-vote-accounts.ts +0 -19
  59. package/server/methods/epoch/index.ts +0 -13
  60. package/server/methods/epoch/minimum-ledger-slot.ts +0 -5
  61. package/server/methods/fee/get-fee-calculator-for-blockhash.ts +0 -12
  62. package/server/methods/fee/get-fee-for-message.ts +0 -8
  63. package/server/methods/fee/get-fee-rate-governor.ts +0 -16
  64. package/server/methods/fee/get-fees.ts +0 -14
  65. package/server/methods/fee/get-recent-prioritization-fees.ts +0 -22
  66. package/server/methods/fee/index.ts +0 -5
  67. package/server/methods/get-address-lookup-table.ts +0 -27
  68. package/server/methods/index.ts +0 -265
  69. package/server/methods/performance/get-recent-performance-samples.ts +0 -25
  70. package/server/methods/performance/get-transaction-count.ts +0 -5
  71. package/server/methods/performance/index.ts +0 -2
  72. package/server/methods/program/get-block-commitment.ts +0 -9
  73. package/server/methods/program/get-block-production.ts +0 -14
  74. package/server/methods/program/get-block-time.ts +0 -21
  75. package/server/methods/program/get-blocks.ts +0 -11
  76. package/server/methods/program/get-first-available-block.ts +0 -9
  77. package/server/methods/program/get-genesis-hash.ts +0 -6
  78. package/server/methods/program/get-identity.ts +0 -6
  79. package/server/methods/program/get-inflation-governor.ts +0 -15
  80. package/server/methods/program/get-inflation-rate.ts +0 -10
  81. package/server/methods/program/get-inflation-reward.ts +0 -12
  82. package/server/methods/program/get-largest-accounts.ts +0 -8
  83. package/server/methods/program/get-parsed-program-accounts.ts +0 -12
  84. package/server/methods/program/get-parsed-token-accounts-by-delegate.ts +0 -12
  85. package/server/methods/program/get-parsed-token-accounts-by-owner.ts +0 -12
  86. package/server/methods/program/get-program-accounts.ts +0 -221
  87. package/server/methods/program/get-supply.ts +0 -13
  88. package/server/methods/program/get-token-account-balance.ts +0 -60
  89. package/server/methods/program/get-token-accounts-by-delegate.ts +0 -82
  90. package/server/methods/program/get-token-accounts-by-owner.ts +0 -416
  91. package/server/methods/program/get-token-largest-accounts.ts +0 -81
  92. package/server/methods/program/get-token-supply.ts +0 -39
  93. package/server/methods/program/index.ts +0 -21
  94. package/server/methods/solforge/index.ts +0 -158
  95. package/server/methods/system/get-health.ts +0 -5
  96. package/server/methods/system/get-minimum-balance-for-rent-exemption.ts +0 -13
  97. package/server/methods/system/get-version.ts +0 -9
  98. package/server/methods/system/index.ts +0 -3
  99. package/server/methods/transaction/get-confirmed-transaction.ts +0 -11
  100. package/server/methods/transaction/get-parsed-transaction.ts +0 -17
  101. package/server/methods/transaction/get-signature-statuses.ts +0 -79
  102. package/server/methods/transaction/get-signatures-for-address.ts +0 -41
  103. package/server/methods/transaction/get-transaction.ts +0 -639
  104. package/server/methods/transaction/index.ts +0 -7
  105. package/server/methods/transaction/inner-instructions.test.ts +0 -104
  106. package/server/methods/transaction/send-transaction.ts +0 -469
  107. package/server/methods/transaction/simulate-transaction.ts +0 -57
  108. package/server/rpc-server.ts +0 -521
  109. package/server/types.ts +0 -109
  110. package/server/ws-server.ts +0 -178
  111. package/src/api-server-entry.ts +0 -109
  112. package/src/cli/bootstrap.ts +0 -67
  113. package/src/cli/commands/airdrop.ts +0 -37
  114. package/src/cli/commands/config.ts +0 -39
  115. package/src/cli/commands/mint.ts +0 -187
  116. package/src/cli/commands/program-clone.ts +0 -122
  117. package/src/cli/commands/program-load.ts +0 -64
  118. package/src/cli/commands/rpc-start.ts +0 -49
  119. package/src/cli/commands/token-adopt-authority.ts +0 -37
  120. package/src/cli/commands/token-clone.ts +0 -112
  121. package/src/cli/commands/token-create.ts +0 -81
  122. package/src/cli/main.ts +0 -152
  123. package/src/cli/run-solforge.ts +0 -112
  124. package/src/cli/setup-utils.ts +0 -54
  125. package/src/cli/setup-wizard.ts +0 -258
  126. package/src/cli/utils/args.ts +0 -15
  127. package/src/commands/add-program.ts +0 -333
  128. package/src/commands/init.ts +0 -122
  129. package/src/commands/list.ts +0 -136
  130. package/src/commands/mint.ts +0 -287
  131. package/src/commands/start.ts +0 -881
  132. package/src/commands/status.ts +0 -99
  133. package/src/commands/stop.ts +0 -405
  134. package/src/config/index.ts +0 -146
  135. package/src/config/manager.ts +0 -157
  136. package/src/db/index.ts +0 -83
  137. package/src/db/schema/accounts.ts +0 -23
  138. package/src/db/schema/address-signatures.ts +0 -31
  139. package/src/db/schema/index.ts +0 -6
  140. package/src/db/schema/meta-kv.ts +0 -9
  141. package/src/db/schema/transactions.ts +0 -36
  142. package/src/db/schema/tx-account-states.ts +0 -23
  143. package/src/db/schema/tx-accounts.ts +0 -33
  144. package/src/db/tx-store.ts +0 -264
  145. package/src/gui/public/app.css +0 -1556
  146. package/src/gui/public/build/main.css +0 -1569
  147. package/src/gui/public/build/main.js +0 -303
  148. package/src/gui/public/build/main.js.txt +0 -231
  149. package/src/gui/public/index.html +0 -19
  150. package/src/gui/server.ts +0 -296
  151. package/src/gui/src/api.ts +0 -127
  152. package/src/gui/src/app.tsx +0 -441
  153. package/src/gui/src/components/airdrop-mint-form.tsx +0 -246
  154. package/src/gui/src/components/clone-program-modal.tsx +0 -202
  155. package/src/gui/src/components/clone-token-modal.tsx +0 -230
  156. package/src/gui/src/components/modal.tsx +0 -134
  157. package/src/gui/src/components/programs-panel.tsx +0 -124
  158. package/src/gui/src/components/status-panel.tsx +0 -136
  159. package/src/gui/src/components/tokens-panel.tsx +0 -122
  160. package/src/gui/src/hooks/use-interval.ts +0 -17
  161. package/src/gui/src/index.css +0 -557
  162. package/src/gui/src/main.tsx +0 -17
  163. package/src/index.ts +0 -216
  164. package/src/migrations-bundled.ts +0 -23
  165. package/src/rpc/start.ts +0 -44
  166. package/src/services/api-server.ts +0 -504
  167. package/src/services/port-manager.ts +0 -174
  168. package/src/services/process-registry.ts +0 -153
  169. package/src/services/program-cloner.ts +0 -317
  170. package/src/services/token-cloner.ts +0 -811
  171. package/src/services/validator.ts +0 -293
  172. package/src/types/config.ts +0 -110
  173. package/src/utils/shell.ts +0 -110
  174. package/src/utils/token-loader.ts +0 -115
  175. /package/{start.js → start.cjs} +0 -0
@@ -1,94 +0,0 @@
1
- import { MINT_SIZE, MintLayout } from "@solana/spl-token";
2
- import { PublicKey } from "@solana/web3.js";
3
- import type { RpcMethodHandler } from "../../types";
4
-
5
- // Adopt faucet as mint authority for a given mint (LiteSVM-only, overwrites account data)
6
- export const solforgeAdoptMintAuthority: RpcMethodHandler = async (
7
- id,
8
- params,
9
- context,
10
- ) => {
11
- try {
12
- const [mintStr] = params as [string];
13
- if (!mintStr)
14
- return context.createErrorResponse(
15
- id,
16
- -32602,
17
- "Invalid params: mint required",
18
- );
19
- const mint = new PublicKey(mintStr);
20
- const acct = context.svm.getAccount(mint);
21
- if (!acct)
22
- return context.createErrorResponse(
23
- id,
24
- -32004,
25
- "Mint not found in LiteSVM",
26
- );
27
- if (!acct.data || acct.data.length < MINT_SIZE)
28
- return context.createErrorResponse(
29
- id,
30
- -32000,
31
- "Account not a valid mint",
32
- );
33
-
34
- const faucet = context.getFaucet();
35
- const buf = Buffer.from(acct.data);
36
- type MintStruct = Parameters<typeof MintLayout.encode>[0];
37
- const mintDecoded = MintLayout.decode(
38
- buf.slice(0, MINT_SIZE),
39
- ) as unknown as MintStruct;
40
- // Update authority fields
41
- (
42
- mintDecoded as unknown as { mintAuthorityOption: number }
43
- ).mintAuthorityOption = 1;
44
- (mintDecoded as unknown as { mintAuthority: PublicKey }).mintAuthority =
45
- faucet.publicKey;
46
- const out = Buffer.from(buf); // preserve any extensions beyond MintLayout
47
- MintLayout.encode(mintDecoded as MintStruct, out);
48
-
49
- const ownerBase58 =
50
- typeof acct.owner === "string"
51
- ? new PublicKey(acct.owner).toBase58()
52
- : (acct.owner as PublicKey).toBase58();
53
- const ownerPk = new PublicKey(ownerBase58);
54
-
55
- context.svm.setAccount(mint, {
56
- lamports: Number(acct.lamports || 0n),
57
- data: new Uint8Array(out),
58
- owner: ownerPk,
59
- executable: false,
60
- rentEpoch: 0,
61
- });
62
- try {
63
- context.registerMint?.(mint);
64
- } catch {}
65
- try {
66
- await context.store?.upsertAccounts([
67
- {
68
- address: mint.toBase58(),
69
- lamports: Number(acct.lamports || 0n),
70
- ownerProgram: ownerBase58,
71
- executable: false,
72
- rentEpoch: 0,
73
- dataLen: out.length,
74
- dataBase64: undefined,
75
- lastSlot: Number(context.slot),
76
- },
77
- ]);
78
- } catch {}
79
- return context.createSuccessResponse(id, {
80
- ok: true,
81
- mint: mintStr,
82
- authority: faucet.publicKey.toBase58(),
83
- });
84
- } catch (e) {
85
- return context.createErrorResponse(
86
- id,
87
- -32603,
88
- "Adopt mint authority failed",
89
- (e as Error)?.message || String(e),
90
- );
91
- }
92
- };
93
-
94
- export type { RpcMethodHandler } from "../../types";
@@ -1,55 +0,0 @@
1
- import { Connection, PublicKey } from "@solana/web3.js";
2
- import type { RpcMethodHandler } from "../../types";
3
-
4
- export const solforgeAdminCloneProgramAccounts: RpcMethodHandler = async (
5
- id,
6
- params,
7
- context,
8
- ) => {
9
- const [programId, options] = params as [
10
- string,
11
- { endpoint?: string; limit?: number; filters?: unknown[] }?,
12
- ];
13
- if (!programId)
14
- return context.createErrorResponse(
15
- id,
16
- -32602,
17
- "Invalid params: programId required",
18
- );
19
- const endpoint = options?.endpoint || "https://api.mainnet-beta.solana.com";
20
- const limit = options?.limit
21
- ? Math.max(1, Math.min(10000, options.limit))
22
- : undefined;
23
- try {
24
- const conn = new Connection(endpoint, "confirmed");
25
- const pid = new PublicKey(programId);
26
- const list = await conn.getProgramAccounts(pid, {
27
- commitment: "confirmed",
28
- // @ts-expect-error: filters type is loose
29
- filters: Array.isArray(options?.filters) ? options?.filters : undefined,
30
- });
31
- let count = 0;
32
- for (const { pubkey, account } of list.slice(0, limit ?? list.length)) {
33
- try {
34
- context.svm.setAccount(pubkey, {
35
- data: new Uint8Array(account.data as Buffer),
36
- executable: account.executable,
37
- lamports: Number(account.lamports),
38
- owner: account.owner,
39
- rentEpoch: 0,
40
- });
41
- count++;
42
- } catch {}
43
- }
44
- return context.createSuccessResponse(id, { ok: true, count });
45
- } catch (e) {
46
- return context.createErrorResponse(
47
- id,
48
- -32603,
49
- "Clone program accounts failed",
50
- (e as Error)?.message || String(e),
51
- );
52
- }
53
- };
54
-
55
- export type { RpcMethodHandler } from "../../types";
@@ -1,152 +0,0 @@
1
- import { Connection, PublicKey } from "@solana/web3.js";
2
- import type { RpcMethodHandler } from "../../types";
3
- import { parseUpgradeableLoader } from "../account/parsers/loader-upgradeable";
4
-
5
- export const solforgeAdminCloneProgram: RpcMethodHandler = async (
6
- id,
7
- params,
8
- context,
9
- ) => {
10
- const [programId, options] = params as [
11
- string,
12
- { endpoint?: string; withAccounts?: boolean; accountsLimit?: number }?,
13
- ];
14
- if (!programId)
15
- return context.createErrorResponse(
16
- id,
17
- -32602,
18
- "Invalid params: programId required",
19
- );
20
- const endpoint = options?.endpoint || "https://api.mainnet-beta.solana.com";
21
- try {
22
- const conn = new Connection(endpoint, "confirmed");
23
- const pid = new PublicKey(programId);
24
- const info = await conn.getAccountInfo(pid, "confirmed");
25
- if (!info)
26
- return context.createErrorResponse(
27
- id,
28
- -32004,
29
- "Program account not found on endpoint",
30
- { programId, endpoint },
31
- );
32
-
33
- console.log("[admin] clone program start", {
34
- programId: pid.toBase58(),
35
- owner: info.owner.toBase58(),
36
- exec: info.executable,
37
- dataLen: info.data?.length ?? 0,
38
- });
39
- const ownerStr = info.owner.toBase58();
40
- let addSource: "programData" | "program" | null = null;
41
-
42
- // If upgradeable loader: fetch program data, extract ELF and addProgram
43
- const parsed = parseUpgradeableLoader(
44
- ownerStr,
45
- new Uint8Array(info.data),
46
- context,
47
- );
48
- if (parsed?.parsed?.type === "program") {
49
- const programDataAddr = parsed.parsed.info?.programData as
50
- | string
51
- | undefined;
52
- if (programDataAddr) {
53
- const pda = new PublicKey(programDataAddr);
54
- const pinfo = await conn.getAccountInfo(pda, "confirmed");
55
- if (pinfo) {
56
- const pdataParsed = parseUpgradeableLoader(
57
- ownerStr,
58
- new Uint8Array(pinfo.data),
59
- context,
60
- );
61
- const base64 = pdataParsed?.parsed?.info?.data?.[0] as
62
- | string
63
- | undefined;
64
- if (base64) {
65
- const bytes = Uint8Array.from(Buffer.from(base64, "base64"));
66
- try {
67
- context.svm.addProgram(pid, bytes);
68
- addSource = "programData";
69
- } catch (e) {
70
- console.warn("[admin] addProgram failed (programData bytes)", e);
71
- return context.createErrorResponse(
72
- id,
73
- -32603,
74
- "Clone program failed",
75
- {
76
- message: String(e),
77
- programId,
78
- endpoint,
79
- source: "programData",
80
- },
81
- );
82
- }
83
- } else {
84
- console.warn("[admin] programData bytes missing");
85
- return context.createErrorResponse(
86
- id,
87
- -32603,
88
- "Clone program failed",
89
- {
90
- message: "ProgramData bytes missing",
91
- programId,
92
- endpoint,
93
- },
94
- );
95
- }
96
- }
97
- }
98
- } else {
99
- // Legacy loaders keep ELF in the program account directly
100
- try {
101
- context.svm.addProgram(pid, new Uint8Array(info.data));
102
- addSource = "program";
103
- } catch (e) {
104
- console.warn("[admin] addProgram failed (program account data)", e);
105
- return context.createErrorResponse(id, -32603, "Clone program failed", {
106
- message: String(e),
107
- programId,
108
- endpoint,
109
- source: "program",
110
- });
111
- }
112
- }
113
-
114
- // Optionally clone owned accounts
115
- if (options?.withAccounts) {
116
- const { solforgeAdminCloneProgramAccounts } = await import(
117
- "./clone-program-accounts"
118
- );
119
- const res = await solforgeAdminCloneProgramAccounts(
120
- id,
121
- [programId, { endpoint, limit: options.accountsLimit }],
122
- context,
123
- );
124
- void res;
125
- }
126
-
127
- console.log("[admin] clone program done", {
128
- programId: pid.toBase58(),
129
- added: true,
130
- source: addSource,
131
- });
132
- try {
133
- context.registerProgram?.(pid);
134
- } catch {}
135
- return context.createSuccessResponse(id, {
136
- ok: true,
137
- programId,
138
- added: true,
139
- source: addSource,
140
- });
141
- } catch (e) {
142
- console.error("[admin] clone program error", e);
143
- return context.createErrorResponse(id, -32603, "Clone program failed", {
144
- message: (e as Error)?.message || String(e),
145
- stack: (e as Error)?.stack,
146
- programId,
147
- endpoint,
148
- });
149
- }
150
- };
151
-
152
- export type { RpcMethodHandler } from "../../types";
@@ -1,117 +0,0 @@
1
- import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
2
- import { Connection, PublicKey } from "@solana/web3.js";
3
- import type { RpcMethodHandler } from "../../types";
4
-
5
- export const solforgeAdminCloneTokenAccounts: RpcMethodHandler = async (
6
- id,
7
- params,
8
- context,
9
- ) => {
10
- const [mint, options] = params as [
11
- string,
12
- { endpoint?: string; holders?: number; allAccounts?: boolean }?,
13
- ];
14
- if (!mint)
15
- return context.createErrorResponse(
16
- id,
17
- -32602,
18
- "Invalid params: mint required",
19
- );
20
- const endpoint = options?.endpoint || "https://api.mainnet-beta.solana.com";
21
- const limit =
22
- options?.holders && !options?.allAccounts
23
- ? Math.max(1, Math.min(10000, options.holders))
24
- : undefined;
25
- try {
26
- const conn = new Connection(endpoint, "confirmed");
27
- const mintPk = new PublicKey(mint);
28
- let accounts: Array<{
29
- pubkey: PublicKey;
30
- data: Buffer;
31
- lamports: number;
32
- owner: PublicKey;
33
- executable: boolean;
34
- rentEpoch: number;
35
- }>;
36
- if (options?.allAccounts) {
37
- const list = await conn.getProgramAccounts(TOKEN_PROGRAM_ID, {
38
- commitment: "confirmed",
39
- filters: [
40
- { dataSize: 165 },
41
- { memcmp: { offset: 0, bytes: mintPk.toBase58() } },
42
- ],
43
- });
44
- accounts = list.map(({ pubkey, account }) => ({
45
- pubkey,
46
- data: account.data as Buffer,
47
- lamports: account.lamports,
48
- owner: account.owner,
49
- executable: account.executable,
50
- rentEpoch: account.rentEpoch,
51
- }));
52
- } else if (typeof limit === "number") {
53
- const largest = await conn.getTokenLargestAccounts(mintPk, "confirmed");
54
- const addrs = largest.value.slice(0, limit).map((x) => x.address);
55
- const multi = await conn.getMultipleAccountsInfo(addrs, {
56
- commitment: "confirmed",
57
- });
58
- accounts = [];
59
- for (let i = 0; i < addrs.length; i++) {
60
- const info = multi[i];
61
- const pk = addrs[i];
62
- if (!info || !pk) continue;
63
- accounts.push({
64
- pubkey: pk,
65
- data: info.data as Buffer,
66
- lamports: info.lamports,
67
- owner: info.owner,
68
- executable: info.executable,
69
- rentEpoch: info.rentEpoch,
70
- });
71
- }
72
- } else {
73
- const largest = await conn.getTokenLargestAccounts(mintPk, "confirmed");
74
- const addrs = largest.value.slice(0, 100).map((x) => x.address);
75
- const multi = await conn.getMultipleAccountsInfo(addrs, {
76
- commitment: "confirmed",
77
- });
78
- accounts = [];
79
- for (let i = 0; i < addrs.length; i++) {
80
- const info = multi[i];
81
- const pk = addrs[i];
82
- if (!info || !pk) continue;
83
- accounts.push({
84
- pubkey: pk,
85
- data: info.data as Buffer,
86
- lamports: info.lamports,
87
- owner: info.owner,
88
- executable: info.executable,
89
- rentEpoch: info.rentEpoch,
90
- });
91
- }
92
- }
93
- let count = 0;
94
- for (const a of accounts) {
95
- try {
96
- context.svm.setAccount(a.pubkey, {
97
- data: new Uint8Array(a.data),
98
- executable: a.executable,
99
- lamports: Number(a.lamports),
100
- owner: a.owner,
101
- rentEpoch: 0,
102
- });
103
- count++;
104
- } catch {}
105
- }
106
- return context.createSuccessResponse(id, { ok: true, count });
107
- } catch (e) {
108
- return context.createErrorResponse(
109
- id,
110
- -32603,
111
- "Clone token accounts failed",
112
- (e as Error)?.message || String(e),
113
- );
114
- }
115
- };
116
-
117
- export type { RpcMethodHandler } from "../../types";
@@ -1,82 +0,0 @@
1
- import { MINT_SIZE, MintLayout } from "@solana/spl-token";
2
- import type { AccountInfo } from "@solana/web3.js";
3
- import { Connection, PublicKey } from "@solana/web3.js";
4
- import type { RpcMethodHandler } from "../../types";
5
- import { cloneMintExtensionAccounts } from "./helpers";
6
-
7
- export const solforgeAdminCloneTokenMint: RpcMethodHandler = async (
8
- id,
9
- params,
10
- context,
11
- ) => {
12
- const [mint, options] = params as [string, { endpoint?: string }?];
13
- if (!mint)
14
- return context.createErrorResponse(
15
- id,
16
- -32602,
17
- "Invalid params: mint required",
18
- );
19
- const endpoint = options?.endpoint || "https://api.mainnet-beta.solana.com";
20
- try {
21
- const conn = new Connection(endpoint, "confirmed");
22
- const mintPk = new PublicKey(mint);
23
- console.log(`[admin] clone mint start`, {
24
- mint: mintPk.toBase58(),
25
- endpoint,
26
- });
27
- const info = await conn.getAccountInfo(mintPk, "confirmed");
28
- if (!info) {
29
- console.warn(`[admin] clone mint: account not found`, {
30
- mint: mintPk.toBase58(),
31
- endpoint,
32
- });
33
- return context.createErrorResponse(
34
- id,
35
- -32004,
36
- "Mint account not found on endpoint",
37
- { endpoint, mint },
38
- );
39
- }
40
- try {
41
- const dec = MintLayout.decode(
42
- (info.data as Buffer).slice(0, MINT_SIZE),
43
- ).decimals;
44
- console.log(`[admin] clone mint fetched`, {
45
- owner: info.owner.toBase58(),
46
- dataLen: info.data.length,
47
- decimals: dec,
48
- lamports: info.lamports,
49
- });
50
- } catch {}
51
- // Write raw account into LiteSVM
52
- context.svm.setAccount(mintPk, {
53
- data: new Uint8Array(info.data),
54
- executable: info.executable,
55
- lamports: Number(info.lamports),
56
- owner: info.owner,
57
- rentEpoch: 0,
58
- });
59
-
60
- await cloneMintExtensionAccounts(
61
- conn,
62
- context,
63
- mintPk,
64
- info as AccountInfo<Buffer>,
65
- );
66
- try {
67
- context.registerMint?.(mintPk);
68
- } catch {}
69
- console.log(`[admin] clone mint done`, { mint: mintPk.toBase58() });
70
- return context.createSuccessResponse(id, { ok: true, address: mint });
71
- } catch (e) {
72
- console.error(`[admin] clone mint error`, e);
73
- return context.createErrorResponse(id, -32603, "Clone mint failed", {
74
- message: (e as Error)?.message || String(e),
75
- stack: (e as Error)?.stack,
76
- endpoint,
77
- mint,
78
- });
79
- }
80
- };
81
-
82
- export type { RpcMethodHandler } from "../../types";
@@ -1,114 +0,0 @@
1
- import { MINT_SIZE, MintLayout, TOKEN_PROGRAM_ID } from "@solana/spl-token";
2
- import { PublicKey } from "@solana/web3.js";
3
- import type { RpcMethodHandler } from "../../types";
4
-
5
- // Create a new SPL Mint locally with given decimals and mint authority
6
- export const solforgeCreateMint: RpcMethodHandler = async (
7
- id,
8
- params,
9
- context,
10
- ) => {
11
- try {
12
- const [mintStr, decimals, authorityStr] = params as [
13
- string | null | undefined,
14
- number,
15
- string | null | undefined,
16
- ];
17
- if (typeof decimals !== "number" || decimals < 0 || decimals > 18)
18
- return context.createErrorResponse(
19
- id,
20
- -32602,
21
- "Invalid params: decimals required (0-18)",
22
- );
23
- const authority = authorityStr
24
- ? new PublicKey(authorityStr)
25
- : context.getFaucet().publicKey;
26
- const mintPk = mintStr ? new PublicKey(mintStr) : PublicKey.unique();
27
-
28
- const buf = Buffer.alloc(MINT_SIZE);
29
- type MintStruct = Parameters<typeof MintLayout.encode>[0];
30
- const initialMint = {
31
- mintAuthorityOption: 1,
32
- mintAuthority: authority,
33
- supply: 0n,
34
- decimals,
35
- isInitialized: true,
36
- freezeAuthorityOption: 0,
37
- freezeAuthority: PublicKey.default,
38
- } satisfies Partial<MintStruct> as MintStruct;
39
- MintLayout.encode(initialMint, buf);
40
-
41
- const rentLamports = Number(
42
- context.svm.minimumBalanceForRentExemption(BigInt(MINT_SIZE)),
43
- );
44
- context.svm.setAccount(mintPk, {
45
- lamports: rentLamports,
46
- data: new Uint8Array(buf),
47
- owner: TOKEN_PROGRAM_ID,
48
- executable: false,
49
- rentEpoch: 0,
50
- });
51
- try {
52
- context.registerMint?.(mintPk);
53
- } catch {}
54
- try {
55
- await context.store?.upsertAccounts([
56
- {
57
- address: mintPk.toBase58(),
58
- lamports: rentLamports,
59
- ownerProgram: TOKEN_PROGRAM_ID.toBase58(),
60
- executable: false,
61
- rentEpoch: 0,
62
- dataLen: MINT_SIZE,
63
- dataBase64: undefined,
64
- lastSlot: Number(context.slot),
65
- },
66
- ]);
67
- } catch {}
68
- // Synthetic transaction for explorers
69
- try {
70
- const sig = `admin:create-mint:${mintPk.toBase58()}:${Date.now()}`;
71
- await context.store?.insertTransactionBundle({
72
- signature: sig,
73
- slot: Number(context.slot),
74
- blockTime: Math.floor(Date.now() / 1000),
75
- version: "legacy",
76
- fee: 0,
77
- err: null,
78
- rawBase64: "",
79
- preBalances: [],
80
- postBalances: [],
81
- logs: ["admin create mint"],
82
- accounts: [
83
- {
84
- address: mintPk.toBase58(),
85
- index: 0,
86
- signer: false,
87
- writable: true,
88
- },
89
- {
90
- address: authority.toBase58(),
91
- index: 1,
92
- signer: false,
93
- writable: false,
94
- },
95
- ],
96
- });
97
- } catch {}
98
- return context.createSuccessResponse(id, {
99
- ok: true,
100
- mint: mintPk.toBase58(),
101
- decimals,
102
- authority: authority.toBase58(),
103
- });
104
- } catch (e) {
105
- return context.createErrorResponse(
106
- id,
107
- -32603,
108
- "Create mint failed",
109
- (e as Error)?.message || String(e),
110
- );
111
- }
112
- };
113
-
114
- export type { RpcMethodHandler } from "../../types";