CW-1035: Solana New Fixes(Cont.) (#2206)
* fix: Error while restoring Solana Wallet with PrivateKey * fix: Enhance Solana Error Messages, especially for ATA Creation Errors * - Optimize Solana Transaction History, now more smoother and faster - fix bug with transactions history not being displayed in real time until next reload * fix: Resolve Solana Issue from Github where user transaction showed amount and fee as the same
David Adegoke committed
Apr 23, 2025 at 23:57 UTC
1b04619c2a5d39749bab209f3d1473345bc57e06
1 file changed
+76
-28
cw_solana/lib/solana_client.dart
+76
-28
@@ -171,37 +171,85 @@ class SolanaWalletClient {
171
172
if (programId == SystemProgramConst.programId) {
173
// For native solana transactions
174
- if (instruction.accounts.length < 2) continue;
175
- final senderIndex = instruction.accounts[0];
176
- final receiverIndex = instruction.accounts[1];
177
-
178
- sender = message.accountKeys[senderIndex].address;
179
- receiver = message.accountKeys[receiverIndex].address;
180
-
181
- final feeForTx = fee / SolanaUtils.lamportsPerSol;
174
183
- final preBalances = meta.preBalances;
184
- final postBalances = meta.postBalances;
185
-
186
- final amountInString =
187
- (((preBalances[senderIndex] - postBalances[senderIndex]) / BigInt.from(1e9))
188
- .toDouble() -
189
- feeForTx)
190
- .toStringAsFixed(6);
175
+ if (txResponse.version == TransactionType.legacy) {
176
+ // For legacy transfers, the fee payer (index 0) is the sender.
177
+ sender = message.accountKeys[0].address;
178
+
179
+ final senderPreBalance = meta.preBalances[0];
180
+ final senderPostBalance = meta.postBalances[0];
181
+ final feeForTx = fee / SolanaUtils.lamportsPerSol;
182
+
183
+ // The loss on the sender's account would include both the transfer amount and the fee.
184
+ // So we would subtract the fee to calculate the actual amount that was transferred (in lamports).
185
+ final transferLamports = (senderPreBalance - senderPostBalance) - BigInt.from(fee);
186
+
187
+ // Next, we attempt to find the receiver by comparing the balance changes.
188
+ // (The index 0 is for the sender so we skip it.)
189
+ bool foundReceiver = false;
190
+ for (int i = 1; i < meta.preBalances.length; i++) {
191
+ // The increase in balance on the receiver account should correspond to the transfer amount we calculated earlieer.
192
+ final pre = meta.preBalances[i];
193
+ final post = meta.postBalances[i];
194
+ if ((post - pre) == transferLamports) {
195
+ receiver = message.accountKeys[i].address;
196
+ foundReceiver = true;
197
+ break;
198
+ }
199
+ }
200
192
- final amount = double.parse(amountInString);
201
+ if (!foundReceiver) {
202
+ // Optionally (and rarely), if no account shows the exact expected change,
203
+ // we set the receiver address to unknown.
204
+ receiver = "unknown";
205
+ }
206
194
- return SolanaTransactionModel(
195
- isOutgoingTx: sender == walletAddress,
196
- from: sender,
197
- to: receiver,
198
- id: signature,
199
- amount: amount.abs(),
200
- programId: SystemProgramConst.programId.address,
201
- tokenSymbol: 'SOL',
202
- blockTimeInInt: blockTime?.toInt() ?? 0,
203
- fee: feeForTx,
204
- );
207
+ final amount = transferLamports / BigInt.from(1e9);
208
+
209
+ return SolanaTransactionModel(
210
+ isOutgoingTx: sender == walletAddress,
211
+ from: sender,
212
+ to: receiver,
213
+ id: signature,
214
+ amount: amount.abs(),
215
+ programId: SystemProgramConst.programId.address,
216
+ tokenSymbol: 'SOL',
217
+ blockTimeInInt: blockTime?.toInt() ?? 0,
218
+ fee: feeForTx,
219
+ );
220
+ } else {
221
+ if (instruction.accounts.length < 2) continue;
222
+ final senderIndex = instruction.accounts[0];
223
+ final receiverIndex = instruction.accounts[1];
224
+
225
+ sender = message.accountKeys[senderIndex].address;
226
+ receiver = message.accountKeys[receiverIndex].address;
227
+
228
+ final feeForTx = fee / SolanaUtils.lamportsPerSol;
229
+
230
+ final preBalances = meta.preBalances;
231
+ final postBalances = meta.postBalances;
232
+
233
+ final amountInString =
234
+ (((preBalances[senderIndex] - postBalances[senderIndex]) / BigInt.from(1e9))
235
+ .toDouble() -
236
+ feeForTx)
237
+ .toStringAsFixed(6);
238
+
239
+ final amount = double.parse(amountInString);
240
+
241
+ return SolanaTransactionModel(
242
+ isOutgoingTx: sender == walletAddress,
243
+ from: sender,
244
+ to: receiver,
245
+ id: signature,
246
+ amount: amount.abs(),
247
+ programId: SystemProgramConst.programId.address,
248
+ tokenSymbol: 'SOL',
249
+ blockTimeInInt: blockTime?.toInt() ?? 0,
250
+ fee: feeForTx,
251
+ );
252
+ }
253
} else if (programId == SPLTokenProgramConst.tokenProgramId) {
254
// For SPL Token transactions
255
if (instruction.accounts.length < 2) continue;