solforge 0.2.12 → 0.2.14

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 +1 -5
  2. package/start.cjs +19 -23
  3. package/docs/API.md +0 -379
  4. package/docs/CONFIGURATION.md +0 -407
  5. package/docs/bun-single-file-executable.md +0 -585
  6. package/docs/cli-plan.md +0 -154
  7. package/docs/data-indexing-plan.md +0 -214
  8. package/docs/gui-roadmap.md +0 -202
  9. package/scripts/decode-b58.ts +0 -10
  10. package/scripts/install.sh +0 -112
  11. package/server/index.ts +0 -5
  12. package/server/lib/base58.ts +0 -33
  13. package/server/lib/faucet.ts +0 -110
  14. package/server/lib/instruction-parser.ts +0 -328
  15. package/server/lib/parsers/spl-associated-token-account.ts +0 -50
  16. package/server/lib/parsers/spl-token.ts +0 -340
  17. package/server/lib/spl-token.ts +0 -57
  18. package/server/methods/TEMPLATE.md +0 -117
  19. package/server/methods/account/get-account-info.ts +0 -86
  20. package/server/methods/account/get-balance.ts +0 -23
  21. package/server/methods/account/get-multiple-accounts.ts +0 -84
  22. package/server/methods/account/get-parsed-account-info.ts +0 -17
  23. package/server/methods/account/index.ts +0 -12
  24. package/server/methods/account/parsers/index.ts +0 -52
  25. package/server/methods/account/parsers/loader-upgradeable.ts +0 -79
  26. package/server/methods/account/parsers/spl-token.ts +0 -256
  27. package/server/methods/account/parsers/system.ts +0 -4
  28. package/server/methods/account/request-airdrop.ts +0 -271
  29. package/server/methods/admin/adopt-mint-authority.ts +0 -94
  30. package/server/methods/admin/clone-program-accounts.ts +0 -55
  31. package/server/methods/admin/clone-program.ts +0 -152
  32. package/server/methods/admin/clone-token-accounts.ts +0 -117
  33. package/server/methods/admin/clone-token-mint.ts +0 -82
  34. package/server/methods/admin/create-mint.ts +0 -114
  35. package/server/methods/admin/create-token-account.ts +0 -137
  36. package/server/methods/admin/helpers.ts +0 -70
  37. package/server/methods/admin/index.ts +0 -10
  38. package/server/methods/admin/list-mints.ts +0 -21
  39. package/server/methods/admin/load-program.ts +0 -52
  40. package/server/methods/admin/mint-to.ts +0 -266
  41. package/server/methods/block/get-block-height.ts +0 -5
  42. package/server/methods/block/get-block.ts +0 -31
  43. package/server/methods/block/get-blocks-with-limit.ts +0 -19
  44. package/server/methods/block/get-latest-blockhash.ts +0 -12
  45. package/server/methods/block/get-slot.ts +0 -5
  46. package/server/methods/block/index.ts +0 -6
  47. package/server/methods/block/is-blockhash-valid.ts +0 -19
  48. package/server/methods/epoch/get-cluster-nodes.ts +0 -17
  49. package/server/methods/epoch/get-epoch-info.ts +0 -16
  50. package/server/methods/epoch/get-epoch-schedule.ts +0 -15
  51. package/server/methods/epoch/get-highest-snapshot-slot.ts +0 -9
  52. package/server/methods/epoch/get-leader-schedule.ts +0 -8
  53. package/server/methods/epoch/get-max-retransmit-slot.ts +0 -9
  54. package/server/methods/epoch/get-max-shred-insert-slot.ts +0 -9
  55. package/server/methods/epoch/get-slot-leader.ts +0 -6
  56. package/server/methods/epoch/get-slot-leaders.ts +0 -9
  57. package/server/methods/epoch/get-stake-activation.ts +0 -9
  58. package/server/methods/epoch/get-stake-minimum-delegation.ts +0 -9
  59. package/server/methods/epoch/get-vote-accounts.ts +0 -19
  60. package/server/methods/epoch/index.ts +0 -13
  61. package/server/methods/epoch/minimum-ledger-slot.ts +0 -5
  62. package/server/methods/fee/get-fee-calculator-for-blockhash.ts +0 -12
  63. package/server/methods/fee/get-fee-for-message.ts +0 -8
  64. package/server/methods/fee/get-fee-rate-governor.ts +0 -16
  65. package/server/methods/fee/get-fees.ts +0 -14
  66. package/server/methods/fee/get-recent-prioritization-fees.ts +0 -22
  67. package/server/methods/fee/index.ts +0 -5
  68. package/server/methods/get-address-lookup-table.ts +0 -27
  69. package/server/methods/index.ts +0 -265
  70. package/server/methods/performance/get-recent-performance-samples.ts +0 -25
  71. package/server/methods/performance/get-transaction-count.ts +0 -5
  72. package/server/methods/performance/index.ts +0 -2
  73. package/server/methods/program/get-block-commitment.ts +0 -9
  74. package/server/methods/program/get-block-production.ts +0 -14
  75. package/server/methods/program/get-block-time.ts +0 -21
  76. package/server/methods/program/get-blocks.ts +0 -11
  77. package/server/methods/program/get-first-available-block.ts +0 -9
  78. package/server/methods/program/get-genesis-hash.ts +0 -6
  79. package/server/methods/program/get-identity.ts +0 -6
  80. package/server/methods/program/get-inflation-governor.ts +0 -15
  81. package/server/methods/program/get-inflation-rate.ts +0 -10
  82. package/server/methods/program/get-inflation-reward.ts +0 -12
  83. package/server/methods/program/get-largest-accounts.ts +0 -8
  84. package/server/methods/program/get-parsed-program-accounts.ts +0 -12
  85. package/server/methods/program/get-parsed-token-accounts-by-delegate.ts +0 -12
  86. package/server/methods/program/get-parsed-token-accounts-by-owner.ts +0 -12
  87. package/server/methods/program/get-program-accounts.ts +0 -221
  88. package/server/methods/program/get-supply.ts +0 -13
  89. package/server/methods/program/get-token-account-balance.ts +0 -60
  90. package/server/methods/program/get-token-accounts-by-delegate.ts +0 -82
  91. package/server/methods/program/get-token-accounts-by-owner.ts +0 -416
  92. package/server/methods/program/get-token-largest-accounts.ts +0 -81
  93. package/server/methods/program/get-token-supply.ts +0 -39
  94. package/server/methods/program/index.ts +0 -21
  95. package/server/methods/solforge/index.ts +0 -158
  96. package/server/methods/system/get-health.ts +0 -5
  97. package/server/methods/system/get-minimum-balance-for-rent-exemption.ts +0 -13
  98. package/server/methods/system/get-version.ts +0 -9
  99. package/server/methods/system/index.ts +0 -3
  100. package/server/methods/transaction/get-confirmed-transaction.ts +0 -11
  101. package/server/methods/transaction/get-parsed-transaction.ts +0 -17
  102. package/server/methods/transaction/get-signature-statuses.ts +0 -79
  103. package/server/methods/transaction/get-signatures-for-address.ts +0 -41
  104. package/server/methods/transaction/get-transaction.ts +0 -639
  105. package/server/methods/transaction/index.ts +0 -7
  106. package/server/methods/transaction/inner-instructions.test.ts +0 -104
  107. package/server/methods/transaction/send-transaction.ts +0 -469
  108. package/server/methods/transaction/simulate-transaction.ts +0 -57
  109. package/server/rpc-server.ts +0 -521
  110. package/server/types.ts +0 -109
  111. package/server/ws-server.ts +0 -178
  112. package/src/api-server-entry.ts +0 -109
  113. package/src/cli/bootstrap.ts +0 -67
  114. package/src/cli/commands/airdrop.ts +0 -37
  115. package/src/cli/commands/config.ts +0 -39
  116. package/src/cli/commands/mint.ts +0 -187
  117. package/src/cli/commands/program-clone.ts +0 -122
  118. package/src/cli/commands/program-load.ts +0 -64
  119. package/src/cli/commands/rpc-start.ts +0 -49
  120. package/src/cli/commands/token-adopt-authority.ts +0 -37
  121. package/src/cli/commands/token-clone.ts +0 -112
  122. package/src/cli/commands/token-create.ts +0 -81
  123. package/src/cli/main.ts +0 -158
  124. package/src/cli/run-solforge.ts +0 -112
  125. package/src/cli/setup-utils.ts +0 -54
  126. package/src/cli/setup-wizard.ts +0 -258
  127. package/src/cli/utils/args.ts +0 -15
  128. package/src/commands/add-program.ts +0 -333
  129. package/src/commands/init.ts +0 -122
  130. package/src/commands/list.ts +0 -136
  131. package/src/commands/mint.ts +0 -287
  132. package/src/commands/start.ts +0 -881
  133. package/src/commands/status.ts +0 -99
  134. package/src/commands/stop.ts +0 -405
  135. package/src/config/index.ts +0 -146
  136. package/src/config/manager.ts +0 -157
  137. package/src/db/index.ts +0 -83
  138. package/src/db/schema/accounts.ts +0 -23
  139. package/src/db/schema/address-signatures.ts +0 -31
  140. package/src/db/schema/index.ts +0 -6
  141. package/src/db/schema/meta-kv.ts +0 -9
  142. package/src/db/schema/transactions.ts +0 -36
  143. package/src/db/schema/tx-account-states.ts +0 -23
  144. package/src/db/schema/tx-accounts.ts +0 -33
  145. package/src/db/tx-store.ts +0 -264
  146. package/src/gui/public/app.css +0 -1556
  147. package/src/gui/public/build/main.css +0 -1569
  148. package/src/gui/public/build/main.js +0 -303
  149. package/src/gui/public/build/main.js.txt +0 -231
  150. package/src/gui/public/index.html +0 -19
  151. package/src/gui/server.ts +0 -296
  152. package/src/gui/src/api.ts +0 -127
  153. package/src/gui/src/app.tsx +0 -441
  154. package/src/gui/src/components/airdrop-mint-form.tsx +0 -246
  155. package/src/gui/src/components/clone-program-modal.tsx +0 -202
  156. package/src/gui/src/components/clone-token-modal.tsx +0 -230
  157. package/src/gui/src/components/modal.tsx +0 -134
  158. package/src/gui/src/components/programs-panel.tsx +0 -124
  159. package/src/gui/src/components/status-panel.tsx +0 -136
  160. package/src/gui/src/components/tokens-panel.tsx +0 -122
  161. package/src/gui/src/hooks/use-interval.ts +0 -17
  162. package/src/gui/src/index.css +0 -557
  163. package/src/gui/src/main.tsx +0 -17
  164. package/src/index.ts +0 -216
  165. package/src/migrations-bundled.ts +0 -23
  166. package/src/rpc/start.ts +0 -44
  167. package/src/services/api-server.ts +0 -504
  168. package/src/services/port-manager.ts +0 -174
  169. package/src/services/process-registry.ts +0 -153
  170. package/src/services/program-cloner.ts +0 -317
  171. package/src/services/token-cloner.ts +0 -811
  172. package/src/services/validator.ts +0 -293
  173. package/src/types/config.ts +0 -110
  174. package/src/utils/shell.ts +0 -110
  175. package/src/utils/token-loader.ts +0 -115
@@ -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";