CW-555-Add-Solana-Wallet (#1272)

* chore: Create cw_solana package and clean up files

* feat: Add Solana Wallet - Create, Restore form seed, restore from Key, Restore from QR, Send, Receive, transaction history, spl tokens

* fix: Make transactions file specific to solana only for solana transactions

* chore: Revert inject app details script

* fix: Fix issue with node and switch current node to main beta instead of testnet

* fix: Fix merge conflicts and adjust migration version

* fix: Fetch spl token error

Signed-off-by: Blazebrain <davidadegoke16@gmail.com>

* fix: Diplay and activate spl tokens bug

* fix: Review and fixes

* fix: reverted formatting for cryptocurrency class

* fix: Review comments, split sending flow into signing and sending separately, fix issues

* fix: Revert throwing unimplenented error

* chore: Fix comment

* chore: Fix comment

* fix: Errors in flow

* Update provider_types.dart [skip ci]

* fix: Issues with solana wallet

* Update solana_wallet.dart [skip ci]

* fix: Review comments

* fix: Date time config

* fix: Revert bash script for app details

* fix: Error with balance, displaying fees, fixing sent or received identifier bug, displaying token symbol with token transaction item in transactions list

* fix: Issues with address validation when sending spl tokens and walletconnect initial setup

* fix: Issues with sending, fetching transactions history, almost wrapping up walletconnect

* fix: Adjust imports that would affect monerocom building successfully

* fix: Refine transaction direction and continue work on walletconnect

* feat: Display SPL token transfers in the transaction history and finally settle the transaction direction

* fix: Delay in transactions history dispaly, show native token transactions first, then process spl token transactions

* feat: Switch node and revert solana chain id to previous id

* fix: Remove print statement

* fix: Remove await for transactions, fetch all transaction histories instantly and adjust solana send success message

* chore: Code refactoring and streamlined wallet type check for solana send success message

* fix: Make timeout error for node silent and add spl token images

---------

Signed-off-by: Blazebrain <davidadegoke16@gmail.com>
Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Adegoke David 2024-02-23 14:39:19 +01:00 committed by GitHub
parent 5a7ea87543
commit 109bba4301
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
133 changed files with 5356 additions and 353 deletions

View file

@ -30,6 +30,7 @@ const polygonDefaultNodeUri = 'polygon-bor.publicnode.com';
const cakeWalletBitcoinCashDefaultNodeUri = 'bitcoincash.stackwallet.com:50002';
const nanoDefaultNodeUri = 'rpc.nano.to';
const nanoDefaultPowNodeUri = 'rpc.nano.to';
const solanaDefaultNodeUri = 'rpc.ankr.com';
Future<void> defaultSettingsMigration(
{required int version,
@ -186,10 +187,15 @@ Future<void> defaultSettingsMigration(
await rewriteSecureStoragePin(secureStorage: secureStorage);
break;
case 26:
/// commented out as it was a probable cause for some users to have white screen issues
/// maybe due to multiple access on Secure Storage at once
/// or long await time on start of the app
// await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences);
/// commented out as it was a probable cause for some users to have white screen issues
/// maybe due to multiple access on Secure Storage at once
/// or long await time on start of the app
// await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences);
case 27:
await addSolanaNodeList(nodes: nodes);
await changeSolanaCurrentNodeToDefault(
sharedPreferences: sharedPreferences, nodes: nodes);
break;
default:
break;
@ -384,6 +390,11 @@ Node getMoneroDefaultNode({required Box<Node> nodes}) {
}
}
Node? getSolanaDefaultNode({required Box<Node> nodes}) {
return nodes.values.firstWhereOrNull((Node node) => node.uriRaw == solanaDefaultNodeUri) ??
nodes.values.firstWhereOrNull((node) => node.type == WalletType.solana);
}
Future<void> insecureStorageMigration({
required SharedPreferences sharedPreferences,
required FlutterSecureStorage secureStorage,
@ -673,6 +684,7 @@ Future<void> checkCurrentNodes(
final currentNanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
final currentBitcoinCashNodeId =
sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
final currentSolanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
final currentMoneroNode =
nodeSource.values.firstWhereOrNull((node) => node.key == currentMoneroNodeId);
final currentBitcoinElectrumServer =
@ -691,6 +703,8 @@ Future<void> checkCurrentNodes(
powNodeSource.values.firstWhereOrNull((node) => node.key == currentNanoPowNodeId);
final currentBitcoinCashNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinCashNodeId);
final currentSolanaNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentSolanaNodeId);
if (currentMoneroNode == null) {
final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero);
await nodeSource.add(newCakeWalletNode);
@ -750,6 +764,12 @@ Future<void> checkCurrentNodes(
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentPolygonNodeIdKey, node.key as int);
}
if (currentSolanaNodeServer == null) {
final node = Node(uri: solanaDefaultNodeUri, type: WalletType.solana);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, node.key as int);
}
}
Future<void> resetBitcoinElectrumServer(
@ -861,3 +881,20 @@ Future<void> changePolygonCurrentNodeToDefault(
await sharedPreferences.setInt(PreferencesKey.currentPolygonNodeIdKey, nodeId);
}
Future<void> addSolanaNodeList({required Box<Node> nodes}) async {
final nodeList = await loadDefaultSolanaNodes();
for (var node in nodeList) {
if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) {
await nodes.add(node);
}
}
}
Future<void> changeSolanaCurrentNodeToDefault(
{required SharedPreferences sharedPreferences, required Box<Node> nodes}) async {
final node = getSolanaDefaultNode(nodes: nodes);
final nodeId = node?.key as int? ?? 0;
await sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, nodeId);
}