@bitgo/wasm-solana 2.4.0 → 2.5.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/dist/cjs/js/explain.d.ts +100 -0
- package/dist/cjs/js/explain.js +311 -0
- package/dist/cjs/js/index.d.ts +40 -3
- package/dist/cjs/js/index.js +44 -2
- package/dist/cjs/js/keypair.d.ts +0 -5
- package/dist/cjs/js/keypair.js +0 -7
- package/dist/cjs/js/parser.d.ts +6 -40
- package/dist/cjs/js/parser.js +8 -38
- package/dist/cjs/js/transaction.d.ts +41 -15
- package/dist/cjs/js/transaction.js +43 -16
- package/dist/cjs/js/wasm/wasm_solana.d.ts +5 -9
- package/dist/cjs/js/wasm/wasm_solana.js +8 -29
- package/dist/cjs/js/wasm/wasm_solana_bg.wasm +0 -0
- package/dist/cjs/js/wasm/wasm_solana_bg.wasm.d.ts +1 -2
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/js/explain.d.ts +100 -0
- package/dist/esm/js/explain.js +307 -0
- package/dist/esm/js/index.d.ts +40 -3
- package/dist/esm/js/index.js +40 -1
- package/dist/esm/js/keypair.d.ts +0 -5
- package/dist/esm/js/keypair.js +0 -7
- package/dist/esm/js/parser.d.ts +6 -40
- package/dist/esm/js/parser.js +7 -37
- package/dist/esm/js/transaction.d.ts +41 -15
- package/dist/esm/js/transaction.js +43 -16
- package/dist/esm/js/wasm/wasm_solana.d.ts +5 -9
- package/dist/esm/js/wasm/wasm_solana_bg.js +8 -29
- package/dist/esm/js/wasm/wasm_solana_bg.wasm +0 -0
- package/dist/esm/js/wasm/wasm_solana_bg.wasm.d.ts +1 -2
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level transaction explanation.
|
|
3
|
+
*
|
|
4
|
+
* Builds on top of `parseTransaction` (WASM) to provide a structured
|
|
5
|
+
* "explain" view of a Solana transaction: type, outputs, inputs, fee, etc.
|
|
6
|
+
*
|
|
7
|
+
* The WASM parser returns raw individual instructions. This module combines
|
|
8
|
+
* related instruction sequences into higher-level operations and derives the
|
|
9
|
+
* overall transaction type.
|
|
10
|
+
*/
|
|
11
|
+
export declare enum TransactionType {
|
|
12
|
+
Send = "Send",
|
|
13
|
+
StakingActivate = "StakingActivate",
|
|
14
|
+
StakingDeactivate = "StakingDeactivate",
|
|
15
|
+
StakingWithdraw = "StakingWithdraw",
|
|
16
|
+
StakingAuthorize = "StakingAuthorize",
|
|
17
|
+
StakingDelegate = "StakingDelegate",
|
|
18
|
+
WalletInitialization = "WalletInitialization",
|
|
19
|
+
AssociatedTokenAccountInitialization = "AssociatedTokenAccountInitialization"
|
|
20
|
+
}
|
|
21
|
+
export interface ExplainOptions {
|
|
22
|
+
/** Defaults to 5000 (Solana protocol constant). */
|
|
23
|
+
lamportsPerSignature?: bigint | number | string;
|
|
24
|
+
tokenAccountRentExemptAmount?: bigint | number | string;
|
|
25
|
+
}
|
|
26
|
+
export interface ExplainedOutput {
|
|
27
|
+
address: string;
|
|
28
|
+
amount: bigint;
|
|
29
|
+
tokenName?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ExplainedInput {
|
|
32
|
+
address: string;
|
|
33
|
+
value: bigint;
|
|
34
|
+
}
|
|
35
|
+
export interface TokenEnablement {
|
|
36
|
+
/** The ATA address being created */
|
|
37
|
+
address: string;
|
|
38
|
+
/** The SPL token mint address */
|
|
39
|
+
mintAddress: string;
|
|
40
|
+
}
|
|
41
|
+
export interface StakingAuthorizeInfo {
|
|
42
|
+
stakingAddress: string;
|
|
43
|
+
oldAuthorizeAddress: string;
|
|
44
|
+
newAuthorizeAddress: string;
|
|
45
|
+
authorizeType: "Staker" | "Withdrawer";
|
|
46
|
+
custodianAddress?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ExplainedTransaction {
|
|
49
|
+
/** Transaction ID (base58 signature). Undefined if the transaction is unsigned. */
|
|
50
|
+
id: string | undefined;
|
|
51
|
+
type: TransactionType;
|
|
52
|
+
feePayer: string;
|
|
53
|
+
fee: bigint;
|
|
54
|
+
blockhash: string;
|
|
55
|
+
durableNonce?: {
|
|
56
|
+
walletNonceAddress: string;
|
|
57
|
+
authWalletAddress: string;
|
|
58
|
+
};
|
|
59
|
+
outputs: ExplainedOutput[];
|
|
60
|
+
inputs: ExplainedInput[];
|
|
61
|
+
outputAmount: bigint;
|
|
62
|
+
memo?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Maps ATA address → owner address for CreateAssociatedTokenAccount instructions.
|
|
65
|
+
* Allows resolving newly-created token account ownership without an external lookup.
|
|
66
|
+
*/
|
|
67
|
+
ataOwnerMap: Record<string, string>;
|
|
68
|
+
/**
|
|
69
|
+
* Token enablements from CreateAssociatedTokenAccount instructions.
|
|
70
|
+
* Contains the ATA address and mint address (consumer resolves token names).
|
|
71
|
+
*/
|
|
72
|
+
tokenEnablements: TokenEnablement[];
|
|
73
|
+
/** Staking authorize details, present when the transaction changes stake authority. */
|
|
74
|
+
stakingAuthorize?: StakingAuthorizeInfo;
|
|
75
|
+
numSignatures: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Explain a Solana transaction.
|
|
79
|
+
*
|
|
80
|
+
* Takes raw transaction bytes and fee parameters, then returns a structured
|
|
81
|
+
* explanation including transaction type, outputs, inputs, fee, memo, and
|
|
82
|
+
* associated-token-account owner mappings.
|
|
83
|
+
*
|
|
84
|
+
* @param input - Raw transaction bytes (caller is responsible for decoding base64/hex)
|
|
85
|
+
* @param options - Fee parameters for calculating the total fee
|
|
86
|
+
* @returns An ExplainedTransaction with all fields populated
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* import { explainTransaction } from '@bitgo/wasm-solana';
|
|
91
|
+
*
|
|
92
|
+
* const txBytes = Buffer.from(txBase64, 'base64');
|
|
93
|
+
* const explained = explainTransaction(txBytes, {
|
|
94
|
+
* lamportsPerSignature: 5000n,
|
|
95
|
+
* tokenAccountRentExemptAmount: 2039280n,
|
|
96
|
+
* });
|
|
97
|
+
* console.log(explained.type); // "Send", "StakingActivate", etc.
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare function explainTransaction(input: Uint8Array, options: ExplainOptions): ExplainedTransaction;
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* High-level transaction explanation.
|
|
4
|
+
*
|
|
5
|
+
* Builds on top of `parseTransaction` (WASM) to provide a structured
|
|
6
|
+
* "explain" view of a Solana transaction: type, outputs, inputs, fee, etc.
|
|
7
|
+
*
|
|
8
|
+
* The WASM parser returns raw individual instructions. This module combines
|
|
9
|
+
* related instruction sequences into higher-level operations and derives the
|
|
10
|
+
* overall transaction type.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.TransactionType = void 0;
|
|
14
|
+
exports.explainTransaction = explainTransaction;
|
|
15
|
+
const parser_js_1 = require("./parser.js");
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// Public types
|
|
18
|
+
// =============================================================================
|
|
19
|
+
var TransactionType;
|
|
20
|
+
(function (TransactionType) {
|
|
21
|
+
TransactionType["Send"] = "Send";
|
|
22
|
+
TransactionType["StakingActivate"] = "StakingActivate";
|
|
23
|
+
TransactionType["StakingDeactivate"] = "StakingDeactivate";
|
|
24
|
+
TransactionType["StakingWithdraw"] = "StakingWithdraw";
|
|
25
|
+
TransactionType["StakingAuthorize"] = "StakingAuthorize";
|
|
26
|
+
TransactionType["StakingDelegate"] = "StakingDelegate";
|
|
27
|
+
TransactionType["WalletInitialization"] = "WalletInitialization";
|
|
28
|
+
TransactionType["AssociatedTokenAccountInitialization"] = "AssociatedTokenAccountInitialization";
|
|
29
|
+
})(TransactionType || (exports.TransactionType = TransactionType = {}));
|
|
30
|
+
/** Solana base fee per signature (protocol constant). */
|
|
31
|
+
const DEFAULT_LAMPORTS_PER_SIGNATURE = 5000n;
|
|
32
|
+
/**
|
|
33
|
+
* Scan for multi-instruction patterns that should be combined:
|
|
34
|
+
*
|
|
35
|
+
* 1. CreateAccount + StakeInitialize [+ StakingDelegate] → StakingActivate
|
|
36
|
+
* - With Delegate following = NATIVE staking
|
|
37
|
+
* - Without Delegate = MARINADE staking (Marinade's program handles delegation)
|
|
38
|
+
* 2. CreateAccount + NonceInitialize → WalletInitialization
|
|
39
|
+
* - BitGo creates a nonce account during wallet initialization
|
|
40
|
+
*/
|
|
41
|
+
function detectCombinedPattern(instructions) {
|
|
42
|
+
for (let i = 0; i < instructions.length - 1; i++) {
|
|
43
|
+
const curr = instructions[i];
|
|
44
|
+
const next = instructions[i + 1];
|
|
45
|
+
if (curr.type === "CreateAccount" && next.type === "StakeInitialize") {
|
|
46
|
+
return {
|
|
47
|
+
kind: "StakingActivate",
|
|
48
|
+
fromAddress: curr.fromAddress,
|
|
49
|
+
stakingAddress: curr.newAddress,
|
|
50
|
+
amount: curr.amount,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (curr.type === "CreateAccount" && next.type === "NonceInitialize") {
|
|
54
|
+
return {
|
|
55
|
+
kind: "WalletInitialization",
|
|
56
|
+
fromAddress: curr.fromAddress,
|
|
57
|
+
nonceAddress: curr.newAddress,
|
|
58
|
+
amount: curr.amount,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
// =============================================================================
|
|
65
|
+
// Transaction type derivation
|
|
66
|
+
// =============================================================================
|
|
67
|
+
const BOILERPLATE_TYPES = new Set([
|
|
68
|
+
"NonceAdvance",
|
|
69
|
+
"Memo",
|
|
70
|
+
"SetComputeUnitLimit",
|
|
71
|
+
"SetPriorityFee",
|
|
72
|
+
]);
|
|
73
|
+
function deriveTransactionType(instructions, combined, memo) {
|
|
74
|
+
if (combined)
|
|
75
|
+
return TransactionType[combined.kind];
|
|
76
|
+
// Marinade deactivate: Transfer + memo containing "PrepareForRevoke"
|
|
77
|
+
if (memo?.includes("PrepareForRevoke"))
|
|
78
|
+
return TransactionType.StakingDeactivate;
|
|
79
|
+
// Jito pool operations map to staking types
|
|
80
|
+
if (instructions.some((i) => i.type === "StakePoolDepositSol"))
|
|
81
|
+
return TransactionType.StakingActivate;
|
|
82
|
+
if (instructions.some((i) => i.type === "StakePoolWithdrawStake"))
|
|
83
|
+
return TransactionType.StakingDeactivate;
|
|
84
|
+
// ATA-only transactions (ignoring boilerplate like nonce/memo/compute budget)
|
|
85
|
+
const meaningful = instructions.filter((i) => !BOILERPLATE_TYPES.has(i.type));
|
|
86
|
+
if (meaningful.length > 0 && meaningful.every((i) => i.type === "CreateAssociatedTokenAccount")) {
|
|
87
|
+
return TransactionType.AssociatedTokenAccountInitialization;
|
|
88
|
+
}
|
|
89
|
+
// For staking instructions, the instruction type IS the transaction type
|
|
90
|
+
const staking = instructions.find((i) => i.type in TransactionType);
|
|
91
|
+
if (staking)
|
|
92
|
+
return TransactionType[staking.type];
|
|
93
|
+
return TransactionType.Send;
|
|
94
|
+
}
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// Transaction ID extraction
|
|
97
|
+
// =============================================================================
|
|
98
|
+
// Base58 encoding of 64 zero bytes. Unsigned transactions have all-zero
|
|
99
|
+
// signatures which encode to this constant.
|
|
100
|
+
const ALL_ZEROS_BASE58 = "1111111111111111111111111111111111111111111111111111111111111111";
|
|
101
|
+
function extractTransactionId(signatures) {
|
|
102
|
+
const sig = signatures[0];
|
|
103
|
+
if (!sig || sig === ALL_ZEROS_BASE58)
|
|
104
|
+
return undefined;
|
|
105
|
+
return sig;
|
|
106
|
+
}
|
|
107
|
+
// =============================================================================
|
|
108
|
+
// Main export
|
|
109
|
+
// =============================================================================
|
|
110
|
+
/**
|
|
111
|
+
* Explain a Solana transaction.
|
|
112
|
+
*
|
|
113
|
+
* Takes raw transaction bytes and fee parameters, then returns a structured
|
|
114
|
+
* explanation including transaction type, outputs, inputs, fee, memo, and
|
|
115
|
+
* associated-token-account owner mappings.
|
|
116
|
+
*
|
|
117
|
+
* @param input - Raw transaction bytes (caller is responsible for decoding base64/hex)
|
|
118
|
+
* @param options - Fee parameters for calculating the total fee
|
|
119
|
+
* @returns An ExplainedTransaction with all fields populated
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* import { explainTransaction } from '@bitgo/wasm-solana';
|
|
124
|
+
*
|
|
125
|
+
* const txBytes = Buffer.from(txBase64, 'base64');
|
|
126
|
+
* const explained = explainTransaction(txBytes, {
|
|
127
|
+
* lamportsPerSignature: 5000n,
|
|
128
|
+
* tokenAccountRentExemptAmount: 2039280n,
|
|
129
|
+
* });
|
|
130
|
+
* console.log(explained.type); // "Send", "StakingActivate", etc.
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
function explainTransaction(input, options) {
|
|
134
|
+
const { lamportsPerSignature, tokenAccountRentExemptAmount } = options;
|
|
135
|
+
const parsed = (0, parser_js_1.parseTransactionData)(input);
|
|
136
|
+
// --- Transaction ID ---
|
|
137
|
+
const id = extractTransactionId(parsed.signatures);
|
|
138
|
+
// --- Fee calculation ---
|
|
139
|
+
// Base fee = numSignatures × lamportsPerSignature
|
|
140
|
+
let fee = BigInt(parsed.numSignatures) *
|
|
141
|
+
(lamportsPerSignature !== undefined
|
|
142
|
+
? BigInt(lamportsPerSignature)
|
|
143
|
+
: DEFAULT_LAMPORTS_PER_SIGNATURE);
|
|
144
|
+
// Each CreateAssociatedTokenAccount instruction creates a new token account,
|
|
145
|
+
// which requires a rent-exempt deposit. Add that to the fee.
|
|
146
|
+
const ataCount = parsed.instructionsData.filter((i) => i.type === "CreateAssociatedTokenAccount").length;
|
|
147
|
+
if (ataCount > 0 && tokenAccountRentExemptAmount !== undefined) {
|
|
148
|
+
fee += BigInt(ataCount) * BigInt(tokenAccountRentExemptAmount);
|
|
149
|
+
}
|
|
150
|
+
// --- Extract memo (needed before type derivation) ---
|
|
151
|
+
let memo;
|
|
152
|
+
for (const instr of parsed.instructionsData) {
|
|
153
|
+
if (instr.type === "Memo") {
|
|
154
|
+
memo = instr.memo;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// --- Detect combined instruction patterns ---
|
|
158
|
+
const combined = detectCombinedPattern(parsed.instructionsData);
|
|
159
|
+
const txType = deriveTransactionType(parsed.instructionsData, combined, memo);
|
|
160
|
+
// Marinade deactivate: Transfer + PrepareForRevoke memo.
|
|
161
|
+
// The Transfer is a contract interaction (not a real value transfer),
|
|
162
|
+
// so we skip it from outputs.
|
|
163
|
+
const isMarinadeDeactivate = txType === TransactionType.StakingDeactivate &&
|
|
164
|
+
memo !== undefined &&
|
|
165
|
+
memo.includes("PrepareForRevoke");
|
|
166
|
+
// --- Extract outputs and inputs ---
|
|
167
|
+
const outputs = [];
|
|
168
|
+
const inputs = [];
|
|
169
|
+
if (combined?.kind === "StakingActivate") {
|
|
170
|
+
// Combined native/Marinade staking activate — the staking address receives
|
|
171
|
+
// the full amount from the funding account.
|
|
172
|
+
outputs.push({
|
|
173
|
+
address: combined.stakingAddress,
|
|
174
|
+
amount: combined.amount,
|
|
175
|
+
});
|
|
176
|
+
inputs.push({
|
|
177
|
+
address: combined.fromAddress,
|
|
178
|
+
value: combined.amount,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
else if (combined?.kind === "WalletInitialization") {
|
|
182
|
+
// Wallet initialization — funds the new nonce account.
|
|
183
|
+
outputs.push({
|
|
184
|
+
address: combined.nonceAddress,
|
|
185
|
+
amount: combined.amount,
|
|
186
|
+
});
|
|
187
|
+
inputs.push({
|
|
188
|
+
address: combined.fromAddress,
|
|
189
|
+
value: combined.amount,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
// Process individual instructions for outputs/inputs
|
|
194
|
+
for (const instr of parsed.instructionsData) {
|
|
195
|
+
switch (instr.type) {
|
|
196
|
+
case "Transfer":
|
|
197
|
+
// Skip Transfer for Marinade deactivate — it's a program interaction,
|
|
198
|
+
// not a real value transfer to an external address.
|
|
199
|
+
if (isMarinadeDeactivate)
|
|
200
|
+
break;
|
|
201
|
+
outputs.push({
|
|
202
|
+
address: instr.toAddress,
|
|
203
|
+
amount: instr.amount,
|
|
204
|
+
});
|
|
205
|
+
inputs.push({
|
|
206
|
+
address: instr.fromAddress,
|
|
207
|
+
value: instr.amount,
|
|
208
|
+
});
|
|
209
|
+
break;
|
|
210
|
+
case "TokenTransfer":
|
|
211
|
+
outputs.push({
|
|
212
|
+
address: instr.toAddress,
|
|
213
|
+
amount: instr.amount,
|
|
214
|
+
tokenName: instr.tokenAddress,
|
|
215
|
+
});
|
|
216
|
+
inputs.push({
|
|
217
|
+
address: instr.fromAddress,
|
|
218
|
+
value: instr.amount,
|
|
219
|
+
});
|
|
220
|
+
break;
|
|
221
|
+
case "StakingActivate":
|
|
222
|
+
outputs.push({
|
|
223
|
+
address: instr.stakingAddress,
|
|
224
|
+
amount: instr.amount,
|
|
225
|
+
});
|
|
226
|
+
inputs.push({
|
|
227
|
+
address: instr.fromAddress,
|
|
228
|
+
value: instr.amount,
|
|
229
|
+
});
|
|
230
|
+
break;
|
|
231
|
+
case "StakingWithdraw":
|
|
232
|
+
// Withdraw: SOL flows FROM the staking address TO the recipient.
|
|
233
|
+
// `fromAddress` is the recipient (where funds go),
|
|
234
|
+
// `stakingAddress` is the source.
|
|
235
|
+
outputs.push({
|
|
236
|
+
address: instr.fromAddress,
|
|
237
|
+
amount: instr.amount,
|
|
238
|
+
});
|
|
239
|
+
inputs.push({
|
|
240
|
+
address: instr.stakingAddress,
|
|
241
|
+
value: instr.amount,
|
|
242
|
+
});
|
|
243
|
+
break;
|
|
244
|
+
case "StakePoolDepositSol":
|
|
245
|
+
// Jito liquid staking: SOL is deposited into the stake pool.
|
|
246
|
+
// The funding account is debited; output goes to the pool address.
|
|
247
|
+
outputs.push({
|
|
248
|
+
address: instr.stakePool,
|
|
249
|
+
amount: instr.lamports,
|
|
250
|
+
});
|
|
251
|
+
inputs.push({
|
|
252
|
+
address: instr.fundingAccount,
|
|
253
|
+
value: instr.lamports,
|
|
254
|
+
});
|
|
255
|
+
break;
|
|
256
|
+
// StakingDeactivate, StakingAuthorize, StakingDelegate,
|
|
257
|
+
// StakePoolWithdrawStake, NonceAdvance, CreateAccount,
|
|
258
|
+
// StakeInitialize, NonceInitialize, SetComputeUnitLimit,
|
|
259
|
+
// SetPriorityFee, CreateAssociatedTokenAccount,
|
|
260
|
+
// CloseAssociatedTokenAccount, Memo, Unknown
|
|
261
|
+
// — no value inputs/outputs.
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// --- Output amount ---
|
|
266
|
+
// Only count native SOL outputs (no tokenName). Token amounts are in different
|
|
267
|
+
// denominations and shouldn't be mixed with SOL lamports.
|
|
268
|
+
const outputAmount = outputs.filter((o) => !o.tokenName).reduce((sum, o) => sum + o.amount, 0n);
|
|
269
|
+
// --- ATA owner mapping and token enablements ---
|
|
270
|
+
const ataOwnerMap = {};
|
|
271
|
+
const tokenEnablements = [];
|
|
272
|
+
for (const instr of parsed.instructionsData) {
|
|
273
|
+
if (instr.type === "CreateAssociatedTokenAccount") {
|
|
274
|
+
ataOwnerMap[instr.ataAddress] = instr.ownerAddress;
|
|
275
|
+
tokenEnablements.push({
|
|
276
|
+
address: instr.ataAddress,
|
|
277
|
+
mintAddress: instr.mintAddress,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// --- Staking authorize ---
|
|
282
|
+
let stakingAuthorize;
|
|
283
|
+
for (const instr of parsed.instructionsData) {
|
|
284
|
+
if (instr.type === "StakingAuthorize") {
|
|
285
|
+
stakingAuthorize = {
|
|
286
|
+
stakingAddress: instr.stakingAddress,
|
|
287
|
+
oldAuthorizeAddress: instr.oldAuthorizeAddress,
|
|
288
|
+
newAuthorizeAddress: instr.newAuthorizeAddress,
|
|
289
|
+
authorizeType: instr.authorizeType,
|
|
290
|
+
custodianAddress: instr.custodianAddress,
|
|
291
|
+
};
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
id,
|
|
297
|
+
type: txType,
|
|
298
|
+
feePayer: parsed.feePayer,
|
|
299
|
+
fee,
|
|
300
|
+
blockhash: parsed.nonce,
|
|
301
|
+
durableNonce: parsed.durableNonce,
|
|
302
|
+
outputs,
|
|
303
|
+
inputs,
|
|
304
|
+
outputAmount,
|
|
305
|
+
memo,
|
|
306
|
+
ataOwnerMap,
|
|
307
|
+
tokenEnablements,
|
|
308
|
+
stakingAuthorize,
|
|
309
|
+
numSignatures: parsed.numSignatures,
|
|
310
|
+
};
|
|
311
|
+
}
|
package/dist/cjs/js/index.d.ts
CHANGED
|
@@ -3,16 +3,53 @@ export * as pubkey from "./pubkey.js";
|
|
|
3
3
|
export * as transaction from "./transaction.js";
|
|
4
4
|
export * as parser from "./parser.js";
|
|
5
5
|
export * as builder from "./builder.js";
|
|
6
|
+
export * as explain from "./explain.js";
|
|
6
7
|
export { Keypair } from "./keypair.js";
|
|
7
8
|
export { Pubkey } from "./pubkey.js";
|
|
8
9
|
export { Transaction } from "./transaction.js";
|
|
9
10
|
export { VersionedTransaction, isVersionedTransaction } from "./versioned.js";
|
|
10
11
|
export type { AddressLookupTableData } from "./versioned.js";
|
|
11
|
-
export {
|
|
12
|
+
export { parseTransactionData } from "./parser.js";
|
|
12
13
|
export { buildFromVersionedData } from "./builder.js";
|
|
13
14
|
export { buildFromIntent, buildFromIntent as buildTransactionFromIntent } from "./intentBuilder.js";
|
|
14
|
-
export
|
|
15
|
+
export { explainTransaction, TransactionType } from "./explain.js";
|
|
16
|
+
import { Transaction as _Transaction } from "./transaction.js";
|
|
17
|
+
/**
|
|
18
|
+
* Parse a Solana transaction from raw bytes.
|
|
19
|
+
*
|
|
20
|
+
* Returns a `Transaction` instance that can be both inspected and signed.
|
|
21
|
+
* Use `.parse()` on the returned Transaction to get decoded instruction data.
|
|
22
|
+
*
|
|
23
|
+
* This is the single entry point for working with transactions — like
|
|
24
|
+
* `BitGoPsbt.fromBytes()` in wasm-utxo.
|
|
25
|
+
*
|
|
26
|
+
* @param bytes - Raw transaction bytes
|
|
27
|
+
* @returns A Transaction that can be inspected (`.parse()`) and signed (`.addSignature()`)
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* import { parseTransaction } from '@bitgo/wasm-solana';
|
|
32
|
+
*
|
|
33
|
+
* const tx = parseTransaction(txBytes);
|
|
34
|
+
*
|
|
35
|
+
* // Inspect
|
|
36
|
+
* const parsed = tx.parse();
|
|
37
|
+
* console.log(parsed.feePayer);
|
|
38
|
+
* for (const instr of parsed.instructionsData) {
|
|
39
|
+
* if (instr.type === 'Transfer') {
|
|
40
|
+
* console.log(`${instr.amount} lamports to ${instr.toAddress}`);
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* // Sign
|
|
45
|
+
* tx.addSignature(pubkey, signature);
|
|
46
|
+
* const signedBytes = tx.toBytes();
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseTransaction(bytes: Uint8Array): _Transaction;
|
|
50
|
+
export type { BaseIntent, PaymentIntent, StakeIntent, UnstakeIntent, ClaimIntent, DeactivateIntent, DelegateIntent, EnableTokenIntent, CloseAtaIntent, ConsolidateIntent, AuthorizeIntent, CustomTxIntent, CustomTxInstruction, CustomTxKey, SolanaIntent, StakePoolConfig, BuildFromIntentParams, BuildFromIntentResult, GeneratedKeypair, NonceSource, BlockhashNonce, DurableNonce, } from "./intentBuilder.js";
|
|
15
51
|
export { system_program_id as systemProgramId, stake_program_id as stakeProgramId, compute_budget_program_id as computeBudgetProgramId, memo_program_id as memoProgramId, token_program_id as tokenProgramId, token_2022_program_id as token2022ProgramId, ata_program_id as ataProgramId, stake_pool_program_id as stakePoolProgramId, stake_account_space as stakeAccountSpace, nonce_account_space as nonceAccountSpace, sysvar_recent_blockhashes as sysvarRecentBlockhashes, get_associated_token_address as getAssociatedTokenAddress, find_withdraw_authority_program_address as findWithdrawAuthorityProgramAddress, } from "./wasm/wasm_solana.js";
|
|
16
52
|
export type { AccountMeta, Instruction } from "./transaction.js";
|
|
17
|
-
export type {
|
|
53
|
+
export type { ParsedTransaction, DurableNonce as ParsedDurableNonce, InstructionParams, TransferParams, CreateAccountParams, NonceAdvanceParams, CreateNonceAccountParams, NonceInitializeParams, StakeInitializeParams, StakingActivateParams, StakingDeactivateParams, StakingWithdrawParams, StakingDelegateParams, StakingAuthorizeParams, SetComputeUnitLimitParams, SetPriorityFeeParams, TokenTransferParams, CreateAtaParams, CloseAtaParams, MemoParams, StakePoolDepositSolParams, StakePoolWithdrawStakeParams, UnknownInstructionParams, } from "./parser.js";
|
|
54
|
+
export type { ExplainedTransaction, ExplainedOutput, ExplainedInput, ExplainOptions, TokenEnablement, StakingAuthorizeInfo, } from "./explain.js";
|
|
18
55
|
export type { AddressLookupTable as BuilderAddressLookupTable, RawVersionedTransactionData, VersionedInstruction as BuilderVersionedInstruction, MessageHeader, } from "./builder.js";
|
package/dist/cjs/js/index.js
CHANGED
|
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.findWithdrawAuthorityProgramAddress = exports.getAssociatedTokenAddress = exports.sysvarRecentBlockhashes = exports.nonceAccountSpace = exports.stakeAccountSpace = exports.stakePoolProgramId = exports.ataProgramId = exports.token2022ProgramId = exports.tokenProgramId = exports.memoProgramId = exports.computeBudgetProgramId = exports.stakeProgramId = exports.systemProgramId = exports.buildTransactionFromIntent = exports.buildFromIntent = exports.buildFromVersionedData = exports.
|
|
36
|
+
exports.findWithdrawAuthorityProgramAddress = exports.getAssociatedTokenAddress = exports.sysvarRecentBlockhashes = exports.nonceAccountSpace = exports.stakeAccountSpace = exports.stakePoolProgramId = exports.ataProgramId = exports.token2022ProgramId = exports.tokenProgramId = exports.memoProgramId = exports.computeBudgetProgramId = exports.stakeProgramId = exports.systemProgramId = exports.TransactionType = exports.explainTransaction = exports.buildTransactionFromIntent = exports.buildFromIntent = exports.buildFromVersionedData = exports.parseTransactionData = exports.isVersionedTransaction = exports.VersionedTransaction = exports.Transaction = exports.Pubkey = exports.Keypair = exports.explain = exports.builder = exports.parser = exports.transaction = exports.pubkey = exports.keypair = void 0;
|
|
37
|
+
exports.parseTransaction = parseTransaction;
|
|
37
38
|
const wasm = __importStar(require("./wasm/wasm_solana.js"));
|
|
38
39
|
// Force webpack to include the WASM module
|
|
39
40
|
void wasm;
|
|
@@ -43,6 +44,7 @@ exports.pubkey = __importStar(require("./pubkey.js"));
|
|
|
43
44
|
exports.transaction = __importStar(require("./transaction.js"));
|
|
44
45
|
exports.parser = __importStar(require("./parser.js"));
|
|
45
46
|
exports.builder = __importStar(require("./builder.js"));
|
|
47
|
+
exports.explain = __importStar(require("./explain.js"));
|
|
46
48
|
// Top-level class exports for convenience
|
|
47
49
|
var keypair_js_1 = require("./keypair.js");
|
|
48
50
|
Object.defineProperty(exports, "Keypair", { enumerable: true, get: function () { return keypair_js_1.Keypair; } });
|
|
@@ -56,12 +58,52 @@ Object.defineProperty(exports, "VersionedTransaction", { enumerable: true, get:
|
|
|
56
58
|
Object.defineProperty(exports, "isVersionedTransaction", { enumerable: true, get: function () { return versioned_js_1.isVersionedTransaction; } });
|
|
57
59
|
// Top-level function exports
|
|
58
60
|
var parser_js_1 = require("./parser.js");
|
|
59
|
-
Object.defineProperty(exports, "
|
|
61
|
+
Object.defineProperty(exports, "parseTransactionData", { enumerable: true, get: function () { return parser_js_1.parseTransactionData; } });
|
|
60
62
|
var builder_js_1 = require("./builder.js");
|
|
61
63
|
Object.defineProperty(exports, "buildFromVersionedData", { enumerable: true, get: function () { return builder_js_1.buildFromVersionedData; } });
|
|
62
64
|
var intentBuilder_js_1 = require("./intentBuilder.js");
|
|
63
65
|
Object.defineProperty(exports, "buildFromIntent", { enumerable: true, get: function () { return intentBuilder_js_1.buildFromIntent; } });
|
|
64
66
|
Object.defineProperty(exports, "buildTransactionFromIntent", { enumerable: true, get: function () { return intentBuilder_js_1.buildFromIntent; } });
|
|
67
|
+
var explain_js_1 = require("./explain.js");
|
|
68
|
+
Object.defineProperty(exports, "explainTransaction", { enumerable: true, get: function () { return explain_js_1.explainTransaction; } });
|
|
69
|
+
Object.defineProperty(exports, "TransactionType", { enumerable: true, get: function () { return explain_js_1.TransactionType; } });
|
|
70
|
+
// Re-export Transaction import for parseTransaction
|
|
71
|
+
const transaction_js_2 = require("./transaction.js");
|
|
72
|
+
/**
|
|
73
|
+
* Parse a Solana transaction from raw bytes.
|
|
74
|
+
*
|
|
75
|
+
* Returns a `Transaction` instance that can be both inspected and signed.
|
|
76
|
+
* Use `.parse()` on the returned Transaction to get decoded instruction data.
|
|
77
|
+
*
|
|
78
|
+
* This is the single entry point for working with transactions — like
|
|
79
|
+
* `BitGoPsbt.fromBytes()` in wasm-utxo.
|
|
80
|
+
*
|
|
81
|
+
* @param bytes - Raw transaction bytes
|
|
82
|
+
* @returns A Transaction that can be inspected (`.parse()`) and signed (`.addSignature()`)
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { parseTransaction } from '@bitgo/wasm-solana';
|
|
87
|
+
*
|
|
88
|
+
* const tx = parseTransaction(txBytes);
|
|
89
|
+
*
|
|
90
|
+
* // Inspect
|
|
91
|
+
* const parsed = tx.parse();
|
|
92
|
+
* console.log(parsed.feePayer);
|
|
93
|
+
* for (const instr of parsed.instructionsData) {
|
|
94
|
+
* if (instr.type === 'Transfer') {
|
|
95
|
+
* console.log(`${instr.amount} lamports to ${instr.toAddress}`);
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
*
|
|
99
|
+
* // Sign
|
|
100
|
+
* tx.addSignature(pubkey, signature);
|
|
101
|
+
* const signedBytes = tx.toBytes();
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
function parseTransaction(bytes) {
|
|
105
|
+
return transaction_js_2.Transaction.fromBytes(bytes);
|
|
106
|
+
}
|
|
65
107
|
// Program ID constants (from WASM)
|
|
66
108
|
var wasm_solana_js_1 = require("./wasm/wasm_solana.js");
|
|
67
109
|
Object.defineProperty(exports, "systemProgramId", { enumerable: true, get: function () { return wasm_solana_js_1.system_program_id; } });
|
package/dist/cjs/js/keypair.d.ts
CHANGED
|
@@ -39,11 +39,6 @@ export declare class Keypair {
|
|
|
39
39
|
* @returns The address as a base58 string
|
|
40
40
|
*/
|
|
41
41
|
getAddress(): string;
|
|
42
|
-
/**
|
|
43
|
-
* Get the public key as a base58 string
|
|
44
|
-
* @returns The public key as a base58 string
|
|
45
|
-
*/
|
|
46
|
-
toBase58(): string;
|
|
47
42
|
/**
|
|
48
43
|
* Sign a message with this keypair
|
|
49
44
|
* @param message - The message bytes to sign
|
package/dist/cjs/js/keypair.js
CHANGED
|
@@ -59,13 +59,6 @@ class Keypair {
|
|
|
59
59
|
getAddress() {
|
|
60
60
|
return this._wasm.address();
|
|
61
61
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Get the public key as a base58 string
|
|
64
|
-
* @returns The public key as a base58 string
|
|
65
|
-
*/
|
|
66
|
-
toBase58() {
|
|
67
|
-
return this._wasm.to_base58();
|
|
68
|
-
}
|
|
69
62
|
/**
|
|
70
63
|
* Sign a message with this keypair
|
|
71
64
|
* @param message - The message bytes to sign
|
package/dist/cjs/js/parser.d.ts
CHANGED
|
@@ -5,14 +5,7 @@
|
|
|
5
5
|
* matching BitGoJS's TxData format.
|
|
6
6
|
*
|
|
7
7
|
* All monetary amounts (amount, fee, lamports, poolTokens) are returned as bigint.
|
|
8
|
-
* Accepts both raw bytes and Transaction objects for convenience.
|
|
9
8
|
*/
|
|
10
|
-
import type { Transaction } from "./transaction.js";
|
|
11
|
-
import type { VersionedTransaction } from "./versioned.js";
|
|
12
|
-
/**
|
|
13
|
-
* Input type for parseTransaction - accepts bytes or Transaction objects.
|
|
14
|
-
*/
|
|
15
|
-
export type TransactionInput = Uint8Array | Transaction | VersionedTransaction;
|
|
16
9
|
/** SOL transfer parameters */
|
|
17
10
|
export interface TransferParams {
|
|
18
11
|
type: "Transfer";
|
|
@@ -214,40 +207,13 @@ export interface ParsedTransaction {
|
|
|
214
207
|
signatures: string[];
|
|
215
208
|
}
|
|
216
209
|
/**
|
|
217
|
-
* Parse
|
|
218
|
-
*
|
|
219
|
-
* This is the main entry point for transaction parsing. It deserializes the
|
|
220
|
-
* transaction and decodes all instructions into semantic types.
|
|
221
|
-
*
|
|
222
|
-
* All monetary amounts (amount, fee, lamports, poolTokens) are returned as bigint
|
|
223
|
-
* directly from WASM - no post-processing needed.
|
|
210
|
+
* Parse raw transaction bytes into a plain data object with decoded instructions.
|
|
224
211
|
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
212
|
+
* This is the low-level parsing function. Most callers should use the top-level
|
|
213
|
+
* `parseTransaction(bytes)` which returns a `Transaction` instance with both
|
|
214
|
+
* inspection (`.parse()`) and signing (`.addSignature()`) capabilities.
|
|
228
215
|
*
|
|
229
|
-
* @param
|
|
216
|
+
* @param bytes - Raw transaction bytes
|
|
230
217
|
* @returns A ParsedTransaction with all instructions decoded
|
|
231
|
-
* @throws Error if the transaction cannot be parsed
|
|
232
|
-
*
|
|
233
|
-
* @example
|
|
234
|
-
* ```typescript
|
|
235
|
-
* import { parseTransaction, buildTransaction, Transaction } from '@bitgo/wasm-solana';
|
|
236
|
-
*
|
|
237
|
-
* // From bytes
|
|
238
|
-
* const txBytes = Buffer.from(base64EncodedTx, 'base64');
|
|
239
|
-
* const parsed = parseTransaction(txBytes);
|
|
240
|
-
*
|
|
241
|
-
* // Directly from a Transaction object (no roundtrip through bytes)
|
|
242
|
-
* const tx = buildTransaction(intent);
|
|
243
|
-
* const parsed = parseTransaction(tx);
|
|
244
|
-
*
|
|
245
|
-
* console.log(parsed.feePayer);
|
|
246
|
-
* for (const instr of parsed.instructionsData) {
|
|
247
|
-
* if (instr.type === 'Transfer') {
|
|
248
|
-
* console.log(`Transfer ${instr.amount} from ${instr.fromAddress} to ${instr.toAddress}`);
|
|
249
|
-
* }
|
|
250
|
-
* }
|
|
251
|
-
* ```
|
|
252
218
|
*/
|
|
253
|
-
export declare function
|
|
219
|
+
export declare function parseTransactionData(bytes: Uint8Array): ParsedTransaction;
|