@vtx-labs/solana-explain 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/LICENSE +21 -0
- package/README.md +328 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.js +3317 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.js +3130 -0
- package/dist/index.js.map +1 -0
- package/dist/programs.d.ts +42 -0
- package/dist/programs.js +919 -0
- package/dist/programs.js.map +1 -0
- package/dist/render.d.ts +59 -0
- package/dist/render.js +300 -0
- package/dist/render.js.map +1 -0
- package/dist/types-MSKEy1VA.d.ts +482 -0
- package/package.json +83 -0
package/dist/programs.js
ADDED
|
@@ -0,0 +1,919 @@
|
|
|
1
|
+
import bs58 from 'bs58';
|
|
2
|
+
|
|
3
|
+
// src/decode/known-programs.ts
|
|
4
|
+
var SYSTEM_PROGRAM_ID = "11111111111111111111111111111111";
|
|
5
|
+
var TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
6
|
+
var TOKEN_2022_PROGRAM_ID = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
7
|
+
var ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
8
|
+
var MEMO_PROGRAM_ID = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
|
|
9
|
+
var MEMO_V1_PROGRAM_ID = "Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo";
|
|
10
|
+
var COMPUTE_BUDGET_PROGRAM_ID = "ComputeBudget111111111111111111111111111111";
|
|
11
|
+
var KNOWN_PROGRAMS = Object.freeze({
|
|
12
|
+
// Core / decoded
|
|
13
|
+
[SYSTEM_PROGRAM_ID]: { name: "System", kind: "system" },
|
|
14
|
+
[TOKEN_PROGRAM_ID]: { name: "SPL Token", kind: "token" },
|
|
15
|
+
[TOKEN_2022_PROGRAM_ID]: { name: "Token-2022", kind: "token-2022" },
|
|
16
|
+
[ASSOCIATED_TOKEN_PROGRAM_ID]: { name: "Associated Token Account", kind: "ata" },
|
|
17
|
+
[MEMO_PROGRAM_ID]: { name: "Memo", kind: "memo" },
|
|
18
|
+
[MEMO_V1_PROGRAM_ID]: { name: "Memo (v1)", kind: "memo" },
|
|
19
|
+
[COMPUTE_BUDGET_PROGRAM_ID]: { name: "Compute Budget", kind: "compute-budget" },
|
|
20
|
+
// Native
|
|
21
|
+
Stake11111111111111111111111111111111111111: { name: "Stake", kind: "stake" },
|
|
22
|
+
Vote111111111111111111111111111111111111111: { name: "Vote", kind: "vote" },
|
|
23
|
+
BPFLoaderUpgradeab1e11111111111111111111111: { name: "BPF Upgradeable Loader", kind: "loader" },
|
|
24
|
+
BPFLoader2111111111111111111111111111111111: { name: "BPF Loader 2", kind: "loader" },
|
|
25
|
+
AddressLookupTab1e1111111111111111111111111: {
|
|
26
|
+
name: "Address Lookup Table",
|
|
27
|
+
kind: "other"
|
|
28
|
+
},
|
|
29
|
+
// Metaplex
|
|
30
|
+
metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s: {
|
|
31
|
+
name: "Metaplex Token Metadata",
|
|
32
|
+
kind: "nft"
|
|
33
|
+
},
|
|
34
|
+
BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY: {
|
|
35
|
+
name: "Metaplex Bubblegum",
|
|
36
|
+
kind: "nft"
|
|
37
|
+
},
|
|
38
|
+
cndy3Z4yxLzowg4ZTHTHJYjBmtkk3vd6yMJ4r8x7q3o: {
|
|
39
|
+
name: "Metaplex Candy Machine",
|
|
40
|
+
kind: "nft"
|
|
41
|
+
},
|
|
42
|
+
// Aggregators / DEX
|
|
43
|
+
JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4: { name: "Jupiter v6", kind: "aggregator" },
|
|
44
|
+
JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WconZX: { name: "Jupiter v4", kind: "aggregator" },
|
|
45
|
+
"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8": { name: "Raydium AMM v4", kind: "amm" },
|
|
46
|
+
CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK: { name: "Raydium CLMM", kind: "amm" },
|
|
47
|
+
whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc: { name: "Orca Whirlpool", kind: "amm" },
|
|
48
|
+
"9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP": { name: "Orca v2", kind: "amm" },
|
|
49
|
+
PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY: { name: "Phoenix", kind: "amm" },
|
|
50
|
+
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo: { name: "Meteora DLMM", kind: "amm" }
|
|
51
|
+
});
|
|
52
|
+
function knownProgram(programId) {
|
|
53
|
+
return KNOWN_PROGRAMS[programId];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/errors.ts
|
|
57
|
+
var SolanaExplainError = class extends Error {
|
|
58
|
+
code;
|
|
59
|
+
cause;
|
|
60
|
+
/** Optional, CLI-friendly remediation hint. */
|
|
61
|
+
hint;
|
|
62
|
+
constructor(code, message, options = {}) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = new.target.name;
|
|
65
|
+
this.code = code;
|
|
66
|
+
if (options.cause !== void 0) this.cause = options.cause;
|
|
67
|
+
if (options.hint !== void 0) this.hint = options.hint;
|
|
68
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var DecodeError = class extends SolanaExplainError {
|
|
72
|
+
};
|
|
73
|
+
function encodeBase58(bytes) {
|
|
74
|
+
return bs58.encode(bytes);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/decode/reader.ts
|
|
78
|
+
var Reader = class {
|
|
79
|
+
view;
|
|
80
|
+
bytes;
|
|
81
|
+
offset = 0;
|
|
82
|
+
constructor(bytes) {
|
|
83
|
+
this.bytes = bytes;
|
|
84
|
+
this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
85
|
+
}
|
|
86
|
+
get remaining() {
|
|
87
|
+
return this.bytes.length - this.offset;
|
|
88
|
+
}
|
|
89
|
+
ensure(n, field) {
|
|
90
|
+
if (this.offset + n > this.bytes.length) {
|
|
91
|
+
throw new DecodeError(
|
|
92
|
+
"DECODE_FAILED",
|
|
93
|
+
`unexpected end while reading ${field} (need ${n} bytes at offset ${this.offset}, have ${this.remaining})`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
u8(field = "u8") {
|
|
98
|
+
this.ensure(1, field);
|
|
99
|
+
const v = this.view.getUint8(this.offset);
|
|
100
|
+
this.offset += 1;
|
|
101
|
+
return v;
|
|
102
|
+
}
|
|
103
|
+
u16(field = "u16") {
|
|
104
|
+
this.ensure(2, field);
|
|
105
|
+
const v = this.view.getUint16(this.offset, true);
|
|
106
|
+
this.offset += 2;
|
|
107
|
+
return v;
|
|
108
|
+
}
|
|
109
|
+
u32(field = "u32") {
|
|
110
|
+
this.ensure(4, field);
|
|
111
|
+
const v = this.view.getUint32(this.offset, true);
|
|
112
|
+
this.offset += 4;
|
|
113
|
+
return v;
|
|
114
|
+
}
|
|
115
|
+
u64(field = "u64") {
|
|
116
|
+
this.ensure(8, field);
|
|
117
|
+
const v = this.view.getBigUint64(this.offset, true);
|
|
118
|
+
this.offset += 8;
|
|
119
|
+
return v;
|
|
120
|
+
}
|
|
121
|
+
i64(field = "i64") {
|
|
122
|
+
this.ensure(8, field);
|
|
123
|
+
const v = this.view.getBigInt64(this.offset, true);
|
|
124
|
+
this.offset += 8;
|
|
125
|
+
return v;
|
|
126
|
+
}
|
|
127
|
+
bytes_(n, field = "bytes") {
|
|
128
|
+
this.ensure(n, field);
|
|
129
|
+
const out = this.bytes.subarray(this.offset, this.offset + n);
|
|
130
|
+
this.offset += n;
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
/** Read a 32-byte pubkey and return base58. */
|
|
134
|
+
pubkey(field = "pubkey") {
|
|
135
|
+
return encodeBase58(this.bytes_(32, field));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Solana compact-u16 (a.k.a. ShortVec) length prefix. 1–3 bytes, 7 bits each.
|
|
139
|
+
*/
|
|
140
|
+
compactU16(field = "compact-u16") {
|
|
141
|
+
let value = 0;
|
|
142
|
+
let shift = 0;
|
|
143
|
+
for (let i = 0; i < 3; i++) {
|
|
144
|
+
const byte = this.u8(`${field} length byte`);
|
|
145
|
+
value |= (byte & 127) << shift;
|
|
146
|
+
if ((byte & 128) === 0) return value >>> 0;
|
|
147
|
+
shift += 7;
|
|
148
|
+
}
|
|
149
|
+
return value >>> 0;
|
|
150
|
+
}
|
|
151
|
+
/** Remaining bytes (no copy). */
|
|
152
|
+
rest() {
|
|
153
|
+
const out = this.bytes.subarray(this.offset);
|
|
154
|
+
this.offset = this.bytes.length;
|
|
155
|
+
return out;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// src/decode/programs/system.ts
|
|
160
|
+
function acc(ix, i) {
|
|
161
|
+
return ix.accounts[i]?.pubkey;
|
|
162
|
+
}
|
|
163
|
+
function decodeSystem(ix) {
|
|
164
|
+
if (ix.data.length < 4) {
|
|
165
|
+
return { decoded: false, program: "System", warning: "instruction data too short" };
|
|
166
|
+
}
|
|
167
|
+
const r = new Reader(ix.data);
|
|
168
|
+
const disc = r.u32("discriminator");
|
|
169
|
+
try {
|
|
170
|
+
switch (disc) {
|
|
171
|
+
case 0: {
|
|
172
|
+
const lamports = r.u64("lamports");
|
|
173
|
+
const space = r.u64("space");
|
|
174
|
+
const owner = r.pubkey("owner");
|
|
175
|
+
const newAccount = acc(ix, 1) ?? "";
|
|
176
|
+
return {
|
|
177
|
+
program: "System",
|
|
178
|
+
type: "createAccount",
|
|
179
|
+
decoded: true,
|
|
180
|
+
args: { lamports: lamports.toString(), space: space.toString(), owner },
|
|
181
|
+
accountNames: ["funding", "new"],
|
|
182
|
+
effects: [
|
|
183
|
+
{
|
|
184
|
+
kind: "account-created",
|
|
185
|
+
address: newAccount,
|
|
186
|
+
owner,
|
|
187
|
+
lamports,
|
|
188
|
+
space: Number(space),
|
|
189
|
+
as: "system"
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
case 1: {
|
|
195
|
+
const owner = r.pubkey("owner");
|
|
196
|
+
return {
|
|
197
|
+
program: "System",
|
|
198
|
+
type: "assign",
|
|
199
|
+
decoded: true,
|
|
200
|
+
args: { owner },
|
|
201
|
+
accountNames: ["account"]
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
case 2: {
|
|
205
|
+
const lamports = r.u64("lamports");
|
|
206
|
+
const from = acc(ix, 0) ?? "";
|
|
207
|
+
const to = acc(ix, 1) ?? "";
|
|
208
|
+
return {
|
|
209
|
+
program: "System",
|
|
210
|
+
type: "transfer",
|
|
211
|
+
decoded: true,
|
|
212
|
+
args: { lamports: lamports.toString() },
|
|
213
|
+
accountNames: ["from", "to"],
|
|
214
|
+
effects: [{ kind: "sol-transfer", from, to, lamports }]
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
case 3: {
|
|
218
|
+
const base = r.pubkey("base");
|
|
219
|
+
const seedLen = Number(r.u64("seed length"));
|
|
220
|
+
const seed = new TextDecoder().decode(r.bytes_(seedLen, "seed"));
|
|
221
|
+
const lamports = r.u64("lamports");
|
|
222
|
+
const space = r.u64("space");
|
|
223
|
+
const owner = r.pubkey("owner");
|
|
224
|
+
const newAccount = acc(ix, 1) ?? "";
|
|
225
|
+
return {
|
|
226
|
+
program: "System",
|
|
227
|
+
type: "createAccountWithSeed",
|
|
228
|
+
decoded: true,
|
|
229
|
+
args: { base, seed, lamports: lamports.toString(), space: space.toString(), owner },
|
|
230
|
+
accountNames: ["funding", "new", "base"],
|
|
231
|
+
effects: [
|
|
232
|
+
{
|
|
233
|
+
kind: "account-created",
|
|
234
|
+
address: newAccount,
|
|
235
|
+
owner,
|
|
236
|
+
lamports,
|
|
237
|
+
space: Number(space),
|
|
238
|
+
as: "system"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
case 8: {
|
|
244
|
+
const space = r.u64("space");
|
|
245
|
+
return {
|
|
246
|
+
program: "System",
|
|
247
|
+
type: "allocate",
|
|
248
|
+
decoded: true,
|
|
249
|
+
args: { space: space.toString() },
|
|
250
|
+
accountNames: ["account"]
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
case 9: {
|
|
254
|
+
const base = r.pubkey("base");
|
|
255
|
+
const seedLen = Number(r.u64("seed length"));
|
|
256
|
+
const seed = new TextDecoder().decode(r.bytes_(seedLen, "seed"));
|
|
257
|
+
const space = r.u64("space");
|
|
258
|
+
const owner = r.pubkey("owner");
|
|
259
|
+
return {
|
|
260
|
+
program: "System",
|
|
261
|
+
type: "allocateWithSeed",
|
|
262
|
+
decoded: true,
|
|
263
|
+
args: { base, seed, space: space.toString(), owner },
|
|
264
|
+
accountNames: ["account", "base"]
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
case 10: {
|
|
268
|
+
const base = r.pubkey("base");
|
|
269
|
+
const seedLen = Number(r.u64("seed length"));
|
|
270
|
+
const seed = new TextDecoder().decode(r.bytes_(seedLen, "seed"));
|
|
271
|
+
const owner = r.pubkey("owner");
|
|
272
|
+
return {
|
|
273
|
+
program: "System",
|
|
274
|
+
type: "assignWithSeed",
|
|
275
|
+
decoded: true,
|
|
276
|
+
args: { base, seed, owner },
|
|
277
|
+
accountNames: ["account", "base"]
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
case 11: {
|
|
281
|
+
const lamports = r.u64("lamports");
|
|
282
|
+
const seedLen = Number(r.u64("seed length"));
|
|
283
|
+
const fromSeed = new TextDecoder().decode(r.bytes_(seedLen, "fromSeed"));
|
|
284
|
+
const fromOwner = r.pubkey("fromOwner");
|
|
285
|
+
const from = acc(ix, 0) ?? "";
|
|
286
|
+
const to = acc(ix, 2) ?? "";
|
|
287
|
+
return {
|
|
288
|
+
program: "System",
|
|
289
|
+
type: "transferWithSeed",
|
|
290
|
+
decoded: true,
|
|
291
|
+
args: { lamports: lamports.toString(), fromSeed, fromOwner },
|
|
292
|
+
accountNames: ["from", "base", "to"],
|
|
293
|
+
effects: [{ kind: "sol-transfer", from, to, lamports }]
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
default: {
|
|
297
|
+
const names = {
|
|
298
|
+
4: "advanceNonceAccount",
|
|
299
|
+
5: "withdrawNonceAccount",
|
|
300
|
+
6: "initializeNonceAccount",
|
|
301
|
+
7: "authorizeNonceAccount"
|
|
302
|
+
};
|
|
303
|
+
return {
|
|
304
|
+
program: "System",
|
|
305
|
+
type: names[disc] ?? `unknown(${disc})`,
|
|
306
|
+
decoded: disc in names
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} catch (err) {
|
|
311
|
+
return {
|
|
312
|
+
program: "System",
|
|
313
|
+
decoded: false,
|
|
314
|
+
warning: err instanceof Error ? err.message : "system decode failed",
|
|
315
|
+
warningCode: "partial-decode"
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
var systemDecoder = {
|
|
320
|
+
programId: SYSTEM_PROGRAM_ID,
|
|
321
|
+
name: "System",
|
|
322
|
+
kind: "system",
|
|
323
|
+
decode: decodeSystem
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// src/decode/programs/spl-token.ts
|
|
327
|
+
var MAX_U64 = (1n << 64n) - 1n;
|
|
328
|
+
function acc2(ix, i) {
|
|
329
|
+
return ix.accounts[i]?.pubkey;
|
|
330
|
+
}
|
|
331
|
+
function decodeTokenInstruction(ix, programName, variant) {
|
|
332
|
+
if (ix.data.length < 1) {
|
|
333
|
+
return { decoded: false, program: programName, warning: "empty instruction data" };
|
|
334
|
+
}
|
|
335
|
+
const r = new Reader(ix.data);
|
|
336
|
+
const tag = r.u8("tag");
|
|
337
|
+
try {
|
|
338
|
+
switch (tag) {
|
|
339
|
+
case 0: {
|
|
340
|
+
const decimals = r.u8("decimals");
|
|
341
|
+
return {
|
|
342
|
+
program: programName,
|
|
343
|
+
type: "initializeMint",
|
|
344
|
+
decoded: true,
|
|
345
|
+
args: { decimals },
|
|
346
|
+
accountNames: ["mint", "rent"]
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
case 20: {
|
|
350
|
+
const decimals = r.u8("decimals");
|
|
351
|
+
return {
|
|
352
|
+
program: programName,
|
|
353
|
+
type: "initializeMint2",
|
|
354
|
+
decoded: true,
|
|
355
|
+
args: { decimals },
|
|
356
|
+
accountNames: ["mint"]
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
case 1:
|
|
360
|
+
case 16:
|
|
361
|
+
case 18: {
|
|
362
|
+
const account = acc2(ix, 0) ?? "";
|
|
363
|
+
const mint = acc2(ix, 1) ?? "";
|
|
364
|
+
const owner = acc2(ix, 2);
|
|
365
|
+
const type = tag === 1 ? "initializeAccount" : tag === 16 ? "initializeAccount2" : "initializeAccount3";
|
|
366
|
+
return {
|
|
367
|
+
program: programName,
|
|
368
|
+
type,
|
|
369
|
+
decoded: true,
|
|
370
|
+
accountNames: ["account", "mint", "owner"],
|
|
371
|
+
effects: [
|
|
372
|
+
{
|
|
373
|
+
kind: "account-created",
|
|
374
|
+
address: account,
|
|
375
|
+
owner: owner ?? mint,
|
|
376
|
+
as: "token-account"
|
|
377
|
+
}
|
|
378
|
+
]
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
case 3: {
|
|
382
|
+
const amount = r.u64("amount");
|
|
383
|
+
const from = acc2(ix, 0) ?? "";
|
|
384
|
+
const to = acc2(ix, 1) ?? "";
|
|
385
|
+
return {
|
|
386
|
+
program: programName,
|
|
387
|
+
type: "transfer",
|
|
388
|
+
decoded: true,
|
|
389
|
+
args: { amount: amount.toString() },
|
|
390
|
+
accountNames: ["source", "destination", "authority"],
|
|
391
|
+
// No decimals/mint in unchecked transfer — correlate fills from diff.
|
|
392
|
+
effects: [{ kind: "token-transfer", from, to, amount, tokenProgram: variant }],
|
|
393
|
+
warning: "unchecked transfer carries no mint/decimals",
|
|
394
|
+
warningCode: "ambiguous-amount"
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
case 12: {
|
|
398
|
+
const amount = r.u64("amount");
|
|
399
|
+
const decimals = r.u8("decimals");
|
|
400
|
+
const source = acc2(ix, 0) ?? "";
|
|
401
|
+
const mint = acc2(ix, 1) ?? "";
|
|
402
|
+
const dest = acc2(ix, 2) ?? "";
|
|
403
|
+
return {
|
|
404
|
+
program: programName,
|
|
405
|
+
type: "transferChecked",
|
|
406
|
+
decoded: true,
|
|
407
|
+
args: { amount: amount.toString(), decimals },
|
|
408
|
+
accountNames: ["source", "mint", "destination", "authority"],
|
|
409
|
+
effects: [
|
|
410
|
+
{ kind: "token-transfer", from: source, to: dest, mint, amount, decimals, tokenProgram: variant }
|
|
411
|
+
]
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
case 4: {
|
|
415
|
+
const amount = r.u64("amount");
|
|
416
|
+
const delegate = acc2(ix, 1) ?? "";
|
|
417
|
+
const owner = acc2(ix, 2) ?? "";
|
|
418
|
+
return {
|
|
419
|
+
program: programName,
|
|
420
|
+
type: "approve",
|
|
421
|
+
decoded: true,
|
|
422
|
+
args: { amount: amount.toString() },
|
|
423
|
+
accountNames: ["source", "delegate", "owner"],
|
|
424
|
+
effects: [
|
|
425
|
+
{
|
|
426
|
+
kind: "approval",
|
|
427
|
+
owner,
|
|
428
|
+
delegate,
|
|
429
|
+
mint: "",
|
|
430
|
+
amount: amount === MAX_U64 ? "unlimited" : amount
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
case 13: {
|
|
436
|
+
const amount = r.u64("amount");
|
|
437
|
+
const decimals = r.u8("decimals");
|
|
438
|
+
const mint = acc2(ix, 1) ?? "";
|
|
439
|
+
const delegate = acc2(ix, 2) ?? "";
|
|
440
|
+
const owner = acc2(ix, 3) ?? "";
|
|
441
|
+
return {
|
|
442
|
+
program: programName,
|
|
443
|
+
type: "approveChecked",
|
|
444
|
+
decoded: true,
|
|
445
|
+
args: { amount: amount.toString(), decimals },
|
|
446
|
+
accountNames: ["source", "mint", "delegate", "owner"],
|
|
447
|
+
effects: [
|
|
448
|
+
{
|
|
449
|
+
kind: "approval",
|
|
450
|
+
owner,
|
|
451
|
+
delegate,
|
|
452
|
+
mint,
|
|
453
|
+
amount: amount === MAX_U64 ? "unlimited" : amount
|
|
454
|
+
}
|
|
455
|
+
]
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
case 5: {
|
|
459
|
+
const owner = acc2(ix, 1) ?? "";
|
|
460
|
+
return {
|
|
461
|
+
program: programName,
|
|
462
|
+
type: "revoke",
|
|
463
|
+
decoded: true,
|
|
464
|
+
accountNames: ["source", "owner"],
|
|
465
|
+
effects: [{ kind: "approval", owner, delegate: "", mint: "", amount: 0n, revoke: true }]
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
case 6: {
|
|
469
|
+
return {
|
|
470
|
+
program: programName,
|
|
471
|
+
type: "setAuthority",
|
|
472
|
+
decoded: true,
|
|
473
|
+
accountNames: ["account", "currentAuthority"]
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
case 7: {
|
|
477
|
+
const amount = r.u64("amount");
|
|
478
|
+
const mint = acc2(ix, 0) ?? "";
|
|
479
|
+
const to = acc2(ix, 1) ?? "";
|
|
480
|
+
return {
|
|
481
|
+
program: programName,
|
|
482
|
+
type: "mintTo",
|
|
483
|
+
decoded: true,
|
|
484
|
+
args: { amount: amount.toString() },
|
|
485
|
+
accountNames: ["mint", "destination", "authority"],
|
|
486
|
+
effects: [{ kind: "mint", mint, to, amount }]
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
case 14: {
|
|
490
|
+
const amount = r.u64("amount");
|
|
491
|
+
const decimals = r.u8("decimals");
|
|
492
|
+
const mint = acc2(ix, 0) ?? "";
|
|
493
|
+
const to = acc2(ix, 1) ?? "";
|
|
494
|
+
return {
|
|
495
|
+
program: programName,
|
|
496
|
+
type: "mintToChecked",
|
|
497
|
+
decoded: true,
|
|
498
|
+
args: { amount: amount.toString(), decimals },
|
|
499
|
+
accountNames: ["mint", "destination", "authority"],
|
|
500
|
+
effects: [{ kind: "mint", mint, to, amount, decimals }]
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
case 8: {
|
|
504
|
+
const amount = r.u64("amount");
|
|
505
|
+
const from = acc2(ix, 0) ?? "";
|
|
506
|
+
const mint = acc2(ix, 1) ?? "";
|
|
507
|
+
return {
|
|
508
|
+
program: programName,
|
|
509
|
+
type: "burn",
|
|
510
|
+
decoded: true,
|
|
511
|
+
args: { amount: amount.toString() },
|
|
512
|
+
accountNames: ["account", "mint", "authority"],
|
|
513
|
+
effects: [{ kind: "burn", mint, from, amount }]
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
case 15: {
|
|
517
|
+
const amount = r.u64("amount");
|
|
518
|
+
const decimals = r.u8("decimals");
|
|
519
|
+
const from = acc2(ix, 0) ?? "";
|
|
520
|
+
const mint = acc2(ix, 1) ?? "";
|
|
521
|
+
return {
|
|
522
|
+
program: programName,
|
|
523
|
+
type: "burnChecked",
|
|
524
|
+
decoded: true,
|
|
525
|
+
args: { amount: amount.toString(), decimals },
|
|
526
|
+
accountNames: ["account", "mint", "authority"],
|
|
527
|
+
effects: [{ kind: "burn", mint, from, amount, decimals }]
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
case 9: {
|
|
531
|
+
const account = acc2(ix, 0) ?? "";
|
|
532
|
+
const destination = acc2(ix, 1) ?? "";
|
|
533
|
+
return {
|
|
534
|
+
program: programName,
|
|
535
|
+
type: "closeAccount",
|
|
536
|
+
decoded: true,
|
|
537
|
+
accountNames: ["account", "destination", "owner"],
|
|
538
|
+
effects: [{ kind: "close-account", account, destination }]
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
case 10:
|
|
542
|
+
return {
|
|
543
|
+
program: programName,
|
|
544
|
+
type: "freezeAccount",
|
|
545
|
+
decoded: true,
|
|
546
|
+
accountNames: ["account", "mint", "authority"]
|
|
547
|
+
};
|
|
548
|
+
case 11:
|
|
549
|
+
return {
|
|
550
|
+
program: programName,
|
|
551
|
+
type: "thawAccount",
|
|
552
|
+
decoded: true,
|
|
553
|
+
accountNames: ["account", "mint", "authority"]
|
|
554
|
+
};
|
|
555
|
+
case 17: {
|
|
556
|
+
const account = acc2(ix, 0) ?? "";
|
|
557
|
+
return {
|
|
558
|
+
program: programName,
|
|
559
|
+
type: "syncNative",
|
|
560
|
+
decoded: true,
|
|
561
|
+
accountNames: ["account"],
|
|
562
|
+
effects: [{ kind: "sync-native", account }]
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
default:
|
|
566
|
+
return {
|
|
567
|
+
program: programName,
|
|
568
|
+
type: `unknown(${tag})`,
|
|
569
|
+
decoded: false,
|
|
570
|
+
warning: `unrecognized ${programName} instruction tag ${tag}`,
|
|
571
|
+
warningCode: "partial-decode"
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
} catch (err) {
|
|
575
|
+
return {
|
|
576
|
+
program: programName,
|
|
577
|
+
decoded: false,
|
|
578
|
+
warning: err instanceof Error ? err.message : "token decode failed",
|
|
579
|
+
warningCode: "partial-decode"
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/decode/programs/token-2022.ts
|
|
585
|
+
var EXTENSION_TAGS = {
|
|
586
|
+
21: "getAccountDataSize",
|
|
587
|
+
22: "initializeMintCloseAuthority",
|
|
588
|
+
23: "transferFeeExtension",
|
|
589
|
+
24: "confidentialTransferExtension",
|
|
590
|
+
25: "defaultAccountStateExtension",
|
|
591
|
+
26: "reallocate",
|
|
592
|
+
27: "memoTransferExtension",
|
|
593
|
+
28: "createNativeMint",
|
|
594
|
+
29: "initializeNonTransferableMint",
|
|
595
|
+
30: "interestBearingMintExtension",
|
|
596
|
+
31: "cpiGuardExtension",
|
|
597
|
+
32: "initializePermanentDelegate",
|
|
598
|
+
33: "transferHookExtension",
|
|
599
|
+
34: "confidentialTransferFeeExtension",
|
|
600
|
+
35: "withdrawExcessLamports",
|
|
601
|
+
36: "metadataPointerExtension",
|
|
602
|
+
37: "groupPointerExtension",
|
|
603
|
+
38: "groupMemberPointerExtension"
|
|
604
|
+
};
|
|
605
|
+
function decodeToken2022(ix) {
|
|
606
|
+
if (ix.data.length < 1) {
|
|
607
|
+
return { decoded: false, program: "Token-2022", warning: "empty instruction data" };
|
|
608
|
+
}
|
|
609
|
+
const tag = ix.data[0];
|
|
610
|
+
if (tag >= 21) {
|
|
611
|
+
const name = EXTENSION_TAGS[tag] ?? `extension(${tag})`;
|
|
612
|
+
return {
|
|
613
|
+
program: "Token-2022",
|
|
614
|
+
type: name,
|
|
615
|
+
decoded: false,
|
|
616
|
+
warning: `Token-2022 extension instruction "${name}" not byte-decoded; effect visible in balance diff`,
|
|
617
|
+
warningCode: "token-2022-extension-unparsed"
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
return decodeTokenInstruction(ix, "Token-2022", "token-2022");
|
|
621
|
+
}
|
|
622
|
+
var token2022Decoder = {
|
|
623
|
+
programId: TOKEN_2022_PROGRAM_ID,
|
|
624
|
+
name: "Token-2022",
|
|
625
|
+
kind: "token-2022",
|
|
626
|
+
decode: decodeToken2022
|
|
627
|
+
};
|
|
628
|
+
var splTokenDecoder = {
|
|
629
|
+
programId: TOKEN_PROGRAM_ID,
|
|
630
|
+
name: "SPL Token",
|
|
631
|
+
kind: "token",
|
|
632
|
+
decode: (ix) => decodeTokenInstruction(ix, "SPL Token", "spl-token")
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// src/decode/programs/ata.ts
|
|
636
|
+
function acc3(ix, i) {
|
|
637
|
+
return ix.accounts[i]?.pubkey;
|
|
638
|
+
}
|
|
639
|
+
function decodeAta(ix) {
|
|
640
|
+
const tag = ix.data.length === 0 ? 0 : ix.data[0];
|
|
641
|
+
const type = tag === 0 ? "create" : tag === 1 ? "createIdempotent" : tag === 2 ? "recoverNested" : void 0;
|
|
642
|
+
if (type === void 0) {
|
|
643
|
+
return {
|
|
644
|
+
program: "Associated Token Account",
|
|
645
|
+
decoded: false,
|
|
646
|
+
warning: `unrecognized ATA instruction tag ${tag}`,
|
|
647
|
+
warningCode: "partial-decode"
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
if (type === "recoverNested") {
|
|
651
|
+
return {
|
|
652
|
+
program: "Associated Token Account",
|
|
653
|
+
type,
|
|
654
|
+
decoded: true,
|
|
655
|
+
accountNames: ["nestedAta", "nestedMint", "destinationAta", "ownerAta", "ownerMint", "wallet"]
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
const ata = acc3(ix, 1) ?? "";
|
|
659
|
+
const owner = acc3(ix, 2) ?? "";
|
|
660
|
+
const tokenProgram = acc3(ix, 5);
|
|
661
|
+
return {
|
|
662
|
+
program: "Associated Token Account",
|
|
663
|
+
type,
|
|
664
|
+
decoded: true,
|
|
665
|
+
accountNames: ["payer", "ata", "owner", "mint", "systemProgram", "tokenProgram"],
|
|
666
|
+
effects: [
|
|
667
|
+
{
|
|
668
|
+
kind: "account-created",
|
|
669
|
+
address: ata,
|
|
670
|
+
owner: owner || (tokenProgram ?? ""),
|
|
671
|
+
as: "ata"
|
|
672
|
+
}
|
|
673
|
+
]
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
var ataDecoder = {
|
|
677
|
+
programId: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
678
|
+
name: "Associated Token Account",
|
|
679
|
+
kind: "ata",
|
|
680
|
+
decode: decodeAta
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
// src/decode/programs/memo.ts
|
|
684
|
+
var MAX_DISPLAY = 256;
|
|
685
|
+
function decodeMemoData(ix, name) {
|
|
686
|
+
const text = new TextDecoder("utf-8", { fatal: false }).decode(ix.data);
|
|
687
|
+
const display = text.length > MAX_DISPLAY ? `${text.slice(0, MAX_DISPLAY)}\u2026` : text;
|
|
688
|
+
const truncated = text.length > MAX_DISPLAY;
|
|
689
|
+
return {
|
|
690
|
+
program: name,
|
|
691
|
+
type: "memo",
|
|
692
|
+
decoded: true,
|
|
693
|
+
args: { text: display, ...truncated ? { truncated: true } : {} },
|
|
694
|
+
effects: [{ kind: "memo", text: display }],
|
|
695
|
+
...truncated ? { warning: "memo truncated for display; full bytes available via --raw", warningCode: "partial-decode" } : {}
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
var memoDecoder = {
|
|
699
|
+
programId: MEMO_PROGRAM_ID,
|
|
700
|
+
name: "Memo",
|
|
701
|
+
kind: "memo",
|
|
702
|
+
decode: (ix) => decodeMemoData(ix, "Memo")
|
|
703
|
+
};
|
|
704
|
+
var memoV1Decoder = {
|
|
705
|
+
programId: MEMO_V1_PROGRAM_ID,
|
|
706
|
+
name: "Memo (v1)",
|
|
707
|
+
kind: "memo",
|
|
708
|
+
decode: (ix) => decodeMemoData(ix, "Memo (v1)")
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
// src/decode/programs/compute-budget.ts
|
|
712
|
+
function decodeComputeBudget(ix) {
|
|
713
|
+
if (ix.data.length < 1) {
|
|
714
|
+
return { decoded: false, program: "Compute Budget", warning: "empty instruction data" };
|
|
715
|
+
}
|
|
716
|
+
const r = new Reader(ix.data);
|
|
717
|
+
const tag = r.u8("tag");
|
|
718
|
+
try {
|
|
719
|
+
switch (tag) {
|
|
720
|
+
case 1: {
|
|
721
|
+
const bytes = r.u32("heap bytes");
|
|
722
|
+
return {
|
|
723
|
+
program: "Compute Budget",
|
|
724
|
+
type: "requestHeapFrame",
|
|
725
|
+
decoded: true,
|
|
726
|
+
args: { bytes }
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
case 2: {
|
|
730
|
+
const units = r.u32("unit limit");
|
|
731
|
+
return {
|
|
732
|
+
program: "Compute Budget",
|
|
733
|
+
type: "setComputeUnitLimit",
|
|
734
|
+
decoded: true,
|
|
735
|
+
args: { units },
|
|
736
|
+
effects: [{ kind: "compute-budget", unitLimit: units }]
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
case 3: {
|
|
740
|
+
const price = r.u64("micro-lamports");
|
|
741
|
+
return {
|
|
742
|
+
program: "Compute Budget",
|
|
743
|
+
type: "setComputeUnitPrice",
|
|
744
|
+
decoded: true,
|
|
745
|
+
args: { microLamports: price.toString() },
|
|
746
|
+
effects: [{ kind: "compute-budget", unitPriceMicroLamports: price }]
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
case 4: {
|
|
750
|
+
const bytes = r.u32("data size limit");
|
|
751
|
+
return {
|
|
752
|
+
program: "Compute Budget",
|
|
753
|
+
type: "setLoadedAccountsDataSizeLimit",
|
|
754
|
+
decoded: true,
|
|
755
|
+
args: { bytes }
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
case 0:
|
|
759
|
+
return {
|
|
760
|
+
program: "Compute Budget",
|
|
761
|
+
type: "requestUnits",
|
|
762
|
+
decoded: true
|
|
763
|
+
};
|
|
764
|
+
default:
|
|
765
|
+
return {
|
|
766
|
+
program: "Compute Budget",
|
|
767
|
+
type: `unknown(${tag})`,
|
|
768
|
+
decoded: false,
|
|
769
|
+
warningCode: "partial-decode"
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
} catch (err) {
|
|
773
|
+
return {
|
|
774
|
+
program: "Compute Budget",
|
|
775
|
+
decoded: false,
|
|
776
|
+
warning: err instanceof Error ? err.message : "compute-budget decode failed",
|
|
777
|
+
warningCode: "partial-decode"
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
var computeBudgetDecoder = {
|
|
782
|
+
programId: COMPUTE_BUDGET_PROGRAM_ID,
|
|
783
|
+
name: "Compute Budget",
|
|
784
|
+
kind: "compute-budget",
|
|
785
|
+
decode: decodeComputeBudget
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
// src/decode/programs/recognize.ts
|
|
789
|
+
var ALREADY_DECODED = /* @__PURE__ */ new Set([
|
|
790
|
+
"11111111111111111111111111111111",
|
|
791
|
+
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
|
|
792
|
+
"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",
|
|
793
|
+
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
|
|
794
|
+
"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr",
|
|
795
|
+
"Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo",
|
|
796
|
+
"ComputeBudget111111111111111111111111111111"
|
|
797
|
+
]);
|
|
798
|
+
function buildRecognizers() {
|
|
799
|
+
const decoders = [];
|
|
800
|
+
for (const [programId, info] of Object.entries(KNOWN_PROGRAMS)) {
|
|
801
|
+
if (ALREADY_DECODED.has(programId)) continue;
|
|
802
|
+
decoders.push({
|
|
803
|
+
programId,
|
|
804
|
+
name: info.name,
|
|
805
|
+
kind: info.kind,
|
|
806
|
+
decode: () => ({
|
|
807
|
+
program: info.name,
|
|
808
|
+
decoded: false,
|
|
809
|
+
// Honest signal: we know *who* but not the exact ix semantics.
|
|
810
|
+
warning: `${info.name} recognized by program id; semantics inferred from balance diff (no IDL)`
|
|
811
|
+
})
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
return decoders;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// src/decode/registry.ts
|
|
818
|
+
var Registry = class _Registry {
|
|
819
|
+
map;
|
|
820
|
+
constructor(decoders) {
|
|
821
|
+
this.map = /* @__PURE__ */ new Map();
|
|
822
|
+
for (const d of decoders) this.map.set(d.programId, d);
|
|
823
|
+
}
|
|
824
|
+
get(programId) {
|
|
825
|
+
return this.map.get(programId);
|
|
826
|
+
}
|
|
827
|
+
has(programId) {
|
|
828
|
+
return this.map.has(programId);
|
|
829
|
+
}
|
|
830
|
+
list() {
|
|
831
|
+
return [...this.map.values()];
|
|
832
|
+
}
|
|
833
|
+
merge(decoders) {
|
|
834
|
+
const merged = new Map(this.map);
|
|
835
|
+
for (const d of decoders) merged.set(d.programId, d);
|
|
836
|
+
return new _Registry([...merged.values()]);
|
|
837
|
+
}
|
|
838
|
+
};
|
|
839
|
+
var BUNDLED_DECODERS = [
|
|
840
|
+
systemDecoder,
|
|
841
|
+
splTokenDecoder,
|
|
842
|
+
token2022Decoder,
|
|
843
|
+
ataDecoder,
|
|
844
|
+
memoDecoder,
|
|
845
|
+
memoV1Decoder,
|
|
846
|
+
computeBudgetDecoder
|
|
847
|
+
];
|
|
848
|
+
function createRegistry(decoders) {
|
|
849
|
+
const base = [...BUNDLED_DECODERS, ...buildRecognizers()];
|
|
850
|
+
const reg = new Registry(base);
|
|
851
|
+
return decoders && decoders.length > 0 ? reg.merge(decoders) : reg;
|
|
852
|
+
}
|
|
853
|
+
var defaultRegistry = createRegistry();
|
|
854
|
+
function decodeInstruction(ix, registry = defaultRegistry, precomputed) {
|
|
855
|
+
const decoder = registry.get(ix.programId);
|
|
856
|
+
const known = knownProgram(ix.programId);
|
|
857
|
+
const baseAccounts = ix.accounts.map((a) => ({
|
|
858
|
+
pubkey: a.pubkey,
|
|
859
|
+
isSigner: a.isSigner,
|
|
860
|
+
isWritable: a.isWritable
|
|
861
|
+
}));
|
|
862
|
+
if (!decoder) {
|
|
863
|
+
return {
|
|
864
|
+
index: ix.index,
|
|
865
|
+
programId: ix.programId,
|
|
866
|
+
...known ? { program: known.name } : {},
|
|
867
|
+
decoded: false,
|
|
868
|
+
accounts: baseAccounts,
|
|
869
|
+
warning: known ? `${known.name} recognized by program id (no byte decoder)` : "unknown program (no decoder)"
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
let out;
|
|
873
|
+
try {
|
|
874
|
+
out = precomputed ?? decoder.decode(ix);
|
|
875
|
+
} catch (err) {
|
|
876
|
+
return {
|
|
877
|
+
index: ix.index,
|
|
878
|
+
programId: ix.programId,
|
|
879
|
+
program: decoder.name,
|
|
880
|
+
decoded: false,
|
|
881
|
+
accounts: baseAccounts,
|
|
882
|
+
warning: `decoder error: ${err instanceof Error ? err.message : String(err)}`
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
const accounts = baseAccounts.map((a, i) => {
|
|
886
|
+
const name = out.accountNames?.[i];
|
|
887
|
+
return name !== void 0 ? { ...a, name } : a;
|
|
888
|
+
});
|
|
889
|
+
return {
|
|
890
|
+
index: ix.index,
|
|
891
|
+
programId: ix.programId,
|
|
892
|
+
...out.program !== void 0 ? { program: out.program } : {},
|
|
893
|
+
...out.type !== void 0 ? { type: out.type } : {},
|
|
894
|
+
decoded: out.decoded,
|
|
895
|
+
accounts,
|
|
896
|
+
...out.args !== void 0 ? { args: out.args } : {},
|
|
897
|
+
...out.warning !== void 0 ? { warning: out.warning } : {}
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
function decodeInstructionRaw(ix, registry = defaultRegistry) {
|
|
901
|
+
const decoder = registry.get(ix.programId);
|
|
902
|
+
if (!decoder) return { decoded: decodeInstruction(ix, registry), effects: [] };
|
|
903
|
+
let out;
|
|
904
|
+
try {
|
|
905
|
+
out = decoder.decode(ix);
|
|
906
|
+
} catch {
|
|
907
|
+
return { decoded: decodeInstruction(ix, registry), effects: [] };
|
|
908
|
+
}
|
|
909
|
+
const decoded = decodeInstruction(ix, registry, out);
|
|
910
|
+
return {
|
|
911
|
+
decoded,
|
|
912
|
+
effects: out.effects ?? [],
|
|
913
|
+
...out.warningCode !== void 0 ? { warningCode: out.warningCode } : {}
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
export { BUNDLED_DECODERS, KNOWN_PROGRAMS, createRegistry, decodeInstruction, decodeInstructionRaw, defaultRegistry, knownProgram };
|
|
918
|
+
//# sourceMappingURL=programs.js.map
|
|
919
|
+
//# sourceMappingURL=programs.js.map
|