diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 7b2b611d3..8fef4fdb6 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -97,6 +97,7 @@ jobs:
cd cw_ethereum && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_bitcoin_cash && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_nano && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
+ cd cw_polygon && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
flutter packages pub run build_runner build --delete-conflicting-outputs
- name: Add secrets
@@ -131,6 +132,7 @@ jobs:
echo "const fiatApiKey = '${{ secrets.FIAT_API_KEY }}';" >> lib/.secrets.g.dart
echo "const payfuraApiKey = '${{ secrets.PAYFURA_API_KEY }}';" >> lib/.secrets.g.dart
echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_ethereum/lib/.secrets.g.dart
+ echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_ethereum/lib/.secrets.g.dart
echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart
echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart
echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart
diff --git a/.gitignore b/.gitignore
index c735d4058..0a883dd18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -126,6 +126,7 @@ lib/haven/haven.dart
lib/ethereum/ethereum.dart
lib/bitcoin_cash/bitcoin_cash.dart
lib/nano/nano.dart
+lib/polygon/polygon.dart
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_180.png
ios/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_120.png
diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml
index 910149f60..f32482e22 100644
--- a/android/app/src/main/AndroidManifestBase.xml
+++ b/android/app/src/main/AndroidManifestBase.xml
@@ -62,6 +62,9 @@
+
+
+
(other is Erc20Token && other.contractAddress == contractAddress) ||
diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart
index 484325f91..cc749f23a 100644
--- a/cw_core/lib/node.dart
+++ b/cw_core/lib/node.dart
@@ -88,6 +88,8 @@ class Node extends HiveObject with Keyable {
} else {
return Uri.http(uriRaw, '');
}
+ case WalletType.polygon:
+ return Uri.https(uriRaw, '');
default:
throw Exception('Unexpected type ${type.toString()} for Node uri');
}
@@ -146,6 +148,8 @@ class Node extends HiveObject with Keyable {
case WalletType.nano:
case WalletType.banano:
return requestNanoNode();
+ case WalletType.polygon:
+ return requestElectrumServer();
default:
return false;
}
diff --git a/cw_core/lib/wallet_type.dart b/cw_core/lib/wallet_type.dart
index debf92e11..20f0bdb19 100644
--- a/cw_core/lib/wallet_type.dart
+++ b/cw_core/lib/wallet_type.dart
@@ -13,6 +13,7 @@ const walletTypes = [
WalletType.bitcoinCash,
WalletType.nano,
WalletType.banano,
+ WalletType.polygon,
];
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
@@ -44,6 +45,8 @@ enum WalletType {
@HiveField(8)
bitcoinCash,
+ @HiveField(9)
+ polygon
}
int serializeToInt(WalletType type) {
@@ -64,6 +67,8 @@ int serializeToInt(WalletType type) {
return 6;
case WalletType.bitcoinCash:
return 7;
+ case WalletType.polygon:
+ return 8;
default:
return -1;
}
@@ -87,6 +92,8 @@ WalletType deserializeFromInt(int raw) {
return WalletType.banano;
case 7:
return WalletType.bitcoinCash;
+ case 8:
+ return WalletType.polygon;
default:
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
}
@@ -110,6 +117,8 @@ String walletTypeToString(WalletType type) {
return 'Nano';
case WalletType.banano:
return 'Banano';
+ case WalletType.polygon:
+ return 'Polygon';
default:
return '';
}
@@ -133,6 +142,8 @@ String walletTypeToDisplayName(WalletType type) {
return 'Nano (XNO)';
case WalletType.banano:
return 'Banano (BAN)';
+ case WalletType.polygon:
+ return 'Polygon (MATIC)';
default:
return '';
}
@@ -156,7 +167,10 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
return CryptoCurrency.nano;
case WalletType.banano:
return CryptoCurrency.banano;
+ case WalletType.polygon:
+ return CryptoCurrency.maticpoly;
default:
- throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
+ throw Exception(
+ 'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
}
}
diff --git a/cw_ethereum/lib/ethereum_client.dart b/cw_ethereum/lib/ethereum_client.dart
index f0c7381e8..5e408bb9e 100644
--- a/cw_ethereum/lib/ethereum_client.dart
+++ b/cw_ethereum/lib/ethereum_client.dart
@@ -15,12 +15,12 @@ import 'package:cw_ethereum/ethereum_transaction_priority.dart';
import 'package:cw_ethereum/.secrets.g.dart' as secrets;
class EthereumClient {
- final _httpClient = Client();
+ final httpClient = Client();
Web3Client? _client;
bool connect(Node node) {
try {
- _client = Web3Client(node.uri.toString(), _httpClient);
+ _client = Web3Client(node.uri.toString(), httpClient);
return true;
} catch (e) {
@@ -74,9 +74,11 @@ class EthereumClient {
required int exponent,
String? contractAddress,
}) async {
- assert(currency == CryptoCurrency.eth || contractAddress != null);
+ assert(currency == CryptoCurrency.eth ||
+ currency == CryptoCurrency.maticpoly ||
+ contractAddress != null);
- bool _isEthereum = currency == CryptoCurrency.eth;
+ bool _isEVMCompatibleChain = currency == CryptoCurrency.eth || currency == CryptoCurrency.maticpoly;
final price = _client!.getGasPrice();
@@ -84,19 +86,23 @@ class EthereumClient {
from: privateKey.address,
to: EthereumAddress.fromHex(toAddress),
maxPriorityFeePerGas: EtherAmount.fromInt(EtherUnit.gwei, priority.tip),
- value: _isEthereum ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(),
+ value: _isEVMCompatibleChain ? EtherAmount.inWei(BigInt.parse(amount)) : EtherAmount.zero(),
);
- final signedTransaction = await _client!.signTransaction(privateKey, transaction);
+ final chainId = _getChainIdForCurrency(currency);
+
+ final signedTransaction =
+ await _client!.signTransaction(privateKey, transaction, chainId: chainId);
final Function _sendTransaction;
- if (_isEthereum) {
+ if (_isEVMCompatibleChain) {
_sendTransaction = () async => await sendTransaction(signedTransaction);
} else {
final erc20 = ERC20(
client: _client!,
address: EthereumAddress.fromHex(contractAddress!),
+ chainId: chainId,
);
_sendTransaction = () async {
@@ -118,6 +124,16 @@ class EthereumClient {
);
}
+ int _getChainIdForCurrency(CryptoCurrency currency) {
+ switch (currency) {
+ case CryptoCurrency.maticpoly:
+ return 137;
+ case CryptoCurrency.eth:
+ default:
+ return 1;
+ }
+ }
+
Future sendTransaction(Uint8List signedTransaction) async =>
await _client!.sendRawTransaction(prependTransactionType(0x02, signedTransaction));
@@ -198,7 +214,7 @@ I/flutter ( 4474): Gas Used: 53000
Future> fetchTransactions(String address,
{String? contractAddress}) async {
try {
- final response = await _httpClient.get(Uri.https("api.etherscan.io", "/api", {
+ final response = await httpClient.get(Uri.https("api.etherscan.io", "/api", {
"module": "account",
"action": contractAddress != null ? "tokentx" : "txlist",
if (contractAddress != null) "contractaddress": contractAddress,
diff --git a/cw_ethereum/lib/ethereum_transaction_info.dart b/cw_ethereum/lib/ethereum_transaction_info.dart
index a0649ba25..f0deae931 100644
--- a/cw_ethereum/lib/ethereum_transaction_info.dart
+++ b/cw_ethereum/lib/ethereum_transaction_info.dart
@@ -1,3 +1,5 @@
+import 'dart:math';
+
import 'package:cw_core/format_amount.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart';
@@ -34,8 +36,10 @@ class EthereumTransactionInfo extends TransactionInfo {
final String? to;
@override
- String amountFormatted() =>
- '${formatAmount((ethAmount / BigInt.from(10).pow(exponent)).toString())} $tokenSymbol';
+ String amountFormatted() {
+ final amount = formatAmount((ethAmount / BigInt.from(10).pow(exponent)).toString());
+ return '${amount.substring(0, min(10, amount.length))} $tokenSymbol';
+ }
@override
String fiatAmount() => _fiatAmount ?? '';
@@ -44,7 +48,10 @@ class EthereumTransactionInfo extends TransactionInfo {
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
@override
- String feeFormatted() => '${(ethFee / BigInt.from(10).pow(18)).toString()} ETH';
+ String feeFormatted() {
+ final amount = (ethFee / BigInt.from(10).pow(18)).toString();
+ return '${amount.substring(0, min(10, amount.length))} ETH';
+ }
factory EthereumTransactionInfo.fromJson(Map data) {
return EthereumTransactionInfo(
diff --git a/cw_ethereum/lib/ethereum_transaction_model.dart b/cw_ethereum/lib/ethereum_transaction_model.dart
index c1260795a..3b5f724fc 100644
--- a/cw_ethereum/lib/ethereum_transaction_model.dart
+++ b/cw_ethereum/lib/ethereum_transaction_model.dart
@@ -1,3 +1,4 @@
+//! Model used for in parsing transactions fetched using etherscan
class EthereumTransactionModel {
final DateTime date;
final String hash;
diff --git a/cw_ethereum/lib/pending_ethereum_transaction.dart b/cw_ethereum/lib/pending_ethereum_transaction.dart
index 35b0123cc..d47630fd6 100644
--- a/cw_ethereum/lib/pending_ethereum_transaction.dart
+++ b/cw_ethereum/lib/pending_ethereum_transaction.dart
@@ -21,8 +21,8 @@ class PendingEthereumTransaction with PendingTransaction {
@override
String get amountFormatted {
- final _amount = BigInt.parse(amount) / BigInt.from(pow(10, exponent));
- return _amount.toStringAsFixed(min(15, _amount.toString().length));
+ final _amount = (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString();
+ return _amount.substring(0, min(10, _amount.length));
}
@override
@@ -30,8 +30,8 @@ class PendingEthereumTransaction with PendingTransaction {
@override
String get feeFormatted {
- final _fee = fee / BigInt.from(pow(10, 18));
- return _fee.toStringAsFixed(min(15, _fee.toString().length));
+ final _fee = (fee / BigInt.from(pow(10, 18))).toString();
+ return _fee.substring(0, min(10, _fee.length));
}
@override
diff --git a/cw_polygon/.gitignore b/cw_polygon/.gitignore
new file mode 100644
index 000000000..96486fd93
--- /dev/null
+++ b/cw_polygon/.gitignore
@@ -0,0 +1,30 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+.packages
+build/
diff --git a/cw_polygon/.metadata b/cw_polygon/.metadata
new file mode 100644
index 000000000..fa347fc6a
--- /dev/null
+++ b/cw_polygon/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+ channel: stable
+
+project_type: package
diff --git a/cw_polygon/CHANGELOG.md b/cw_polygon/CHANGELOG.md
new file mode 100644
index 000000000..41cc7d819
--- /dev/null
+++ b/cw_polygon/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.0.1
+
+* TODO: Describe initial release.
diff --git a/cw_polygon/LICENSE b/cw_polygon/LICENSE
new file mode 100644
index 000000000..ba75c69f7
--- /dev/null
+++ b/cw_polygon/LICENSE
@@ -0,0 +1 @@
+TODO: Add your license here.
diff --git a/cw_polygon/README.md b/cw_polygon/README.md
new file mode 100644
index 000000000..02fe8ecab
--- /dev/null
+++ b/cw_polygon/README.md
@@ -0,0 +1,39 @@
+
+
+TODO: Put a short description of the package here that helps potential users
+know whether this package might be useful for them.
+
+## Features
+
+TODO: List what your package can do. Maybe include images, gifs, or videos.
+
+## Getting started
+
+TODO: List prerequisites and provide or point to information on how to
+start using the package.
+
+## Usage
+
+TODO: Include short and useful examples for package users. Add longer examples
+to `/example` folder.
+
+```dart
+const like = 'sample';
+```
+
+## Additional information
+
+TODO: Tell users more about the package: where to find more information, how to
+contribute to the package, how to file issues, what response they can expect
+from the package authors, and more.
diff --git a/cw_polygon/analysis_options.yaml b/cw_polygon/analysis_options.yaml
new file mode 100644
index 000000000..a5744c1cf
--- /dev/null
+++ b/cw_polygon/analysis_options.yaml
@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/cw_polygon/lib/cw_polygon.dart b/cw_polygon/lib/cw_polygon.dart
new file mode 100644
index 000000000..5d4e447d1
--- /dev/null
+++ b/cw_polygon/lib/cw_polygon.dart
@@ -0,0 +1,7 @@
+library cw_polygon;
+
+/// A Calculator.
+class Calculator {
+ /// Returns [value] plus 1.
+ int addOne(int value) => value + 1;
+}
diff --git a/cw_polygon/lib/default_erc20_tokens.dart b/cw_polygon/lib/default_erc20_tokens.dart
new file mode 100644
index 000000000..132c52e4c
--- /dev/null
+++ b/cw_polygon/lib/default_erc20_tokens.dart
@@ -0,0 +1,86 @@
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/erc20_token.dart';
+
+class DefaultPolygonErc20Tokens {
+ final List _defaultTokens = [
+ Erc20Token(
+ name: "Wrapped Ether",
+ symbol: "WETH",
+ contractAddress: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
+ decimal: 18,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Tether USD (PoS)",
+ symbol: "USDT",
+ contractAddress: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
+ decimal: 6,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "USD Coin",
+ symbol: "USDC",
+ contractAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
+ decimal: 6,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "USD Coin (POS)",
+ symbol: "USDC.e",
+ contractAddress: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
+ decimal: 6,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Avalanche Token",
+ symbol: "AVAX",
+ contractAddress: "0x2C89bbc92BD86F8075d1DEcc58C7F4E0107f286b",
+ decimal: 18,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Wrapped BTC (PoS)",
+ symbol: "WBTC",
+ contractAddress: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
+ decimal: 8,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Dai (PoS)",
+ symbol: "DAI",
+ contractAddress: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
+ decimal: 18,
+ enabled: true,
+ ),
+ Erc20Token(
+ name: "SHIBA INU (PoS)",
+ symbol: "SHIB",
+ contractAddress: "0x6f8a06447Ff6FcF75d803135a7de15CE88C1d4ec",
+ decimal: 18,
+ enabled: false,
+ ),
+ Erc20Token(
+ name: "Uniswap (PoS)",
+ symbol: "UNI",
+ contractAddress: "0xb33EaAd8d922B1083446DC23f610c2567fB5180f",
+ decimal: 18,
+ enabled: false,
+ ),
+ ];
+
+ List get initialPolygonErc20Tokens => _defaultTokens.map((token) {
+ String? iconPath;
+ try {
+ iconPath = CryptoCurrency.all
+ .firstWhere((element) =>
+ element.title.toUpperCase() == token.symbol.toUpperCase())
+ .iconPath;
+ } catch (_) {}
+
+ if (iconPath != null) {
+ return Erc20Token.copyWith(token, iconPath);
+ }
+
+ return token;
+ }).toList();
+}
diff --git a/cw_polygon/lib/pending_polygon_transaction.dart b/cw_polygon/lib/pending_polygon_transaction.dart
new file mode 100644
index 000000000..50f1f0638
--- /dev/null
+++ b/cw_polygon/lib/pending_polygon_transaction.dart
@@ -0,0 +1,19 @@
+import 'dart:typed_data';
+
+import 'package:cw_ethereum/pending_ethereum_transaction.dart';
+
+class PendingPolygonTransaction extends PendingEthereumTransaction {
+ PendingPolygonTransaction({
+ required Function sendTransaction,
+ required Uint8List signedTransaction,
+ required BigInt fee,
+ required String amount,
+ required int exponent,
+ }) : super(
+ amount: amount,
+ sendTransaction: sendTransaction,
+ signedTransaction: signedTransaction,
+ fee: fee,
+ exponent: exponent,
+ );
+}
diff --git a/cw_polygon/lib/polygon_client.dart b/cw_polygon/lib/polygon_client.dart
new file mode 100644
index 000000000..86c2253af
--- /dev/null
+++ b/cw_polygon/lib/polygon_client.dart
@@ -0,0 +1,34 @@
+import 'dart:convert';
+
+import 'package:cw_ethereum/ethereum_client.dart';
+import 'package:cw_polygon/polygon_transaction_model.dart';
+import 'package:cw_ethereum/.secrets.g.dart' as secrets;
+
+class PolygonClient extends EthereumClient {
+ @override
+ Future> fetchTransactions(String address,
+ {String? contractAddress}) async {
+ try {
+ final response = await httpClient.get(Uri.https("api.polygonscan.com", "/api", {
+ "module": "account",
+ "action": contractAddress != null ? "tokentx" : "txlist",
+ if (contractAddress != null) "contractaddress": contractAddress,
+ "address": address,
+ "apikey": secrets.polygonScanApiKey,
+ }));
+
+ final jsonResponse = json.decode(response.body) as Map;
+
+ if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
+ return (jsonResponse['result'] as List)
+ .map((e) => PolygonTransactionModel.fromJson(e as Map))
+ .toList();
+ }
+
+ return [];
+ } catch (e) {
+ print(e);
+ return [];
+ }
+ }
+}
diff --git a/cw_polygon/lib/polygon_exceptions.dart b/cw_polygon/lib/polygon_exceptions.dart
new file mode 100644
index 000000000..2d08106b6
--- /dev/null
+++ b/cw_polygon/lib/polygon_exceptions.dart
@@ -0,0 +1,6 @@
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_ethereum/ethereum_exceptions.dart';
+
+class PolygonTransactionCreationException extends EthereumTransactionCreationException {
+ PolygonTransactionCreationException(CryptoCurrency currency) : super(currency);
+}
diff --git a/cw_polygon/lib/polygon_formatter.dart b/cw_polygon/lib/polygon_formatter.dart
new file mode 100644
index 000000000..f016db7ab
--- /dev/null
+++ b/cw_polygon/lib/polygon_formatter.dart
@@ -0,0 +1,25 @@
+import 'package:intl/intl.dart';
+
+const polygonAmountLength = 12;
+const polygonAmountDivider = 1000000000000;
+final polygonAmountFormat = NumberFormat()
+ ..maximumFractionDigits = polygonAmountLength
+ ..minimumFractionDigits = 1;
+
+class PolygonFormatter {
+ static int parsePolygonAmount(String amount) {
+ try {
+ return (double.parse(amount) * polygonAmountDivider).round();
+ } catch (_) {
+ return 0;
+ }
+ }
+
+ static double parsePolygonAmountToDouble(int amount) {
+ try {
+ return amount / polygonAmountDivider;
+ } catch (_) {
+ return 0;
+ }
+ }
+}
diff --git a/cw_polygon/lib/polygon_mnemonics_exception.dart b/cw_polygon/lib/polygon_mnemonics_exception.dart
new file mode 100644
index 000000000..c1a2fcc84
--- /dev/null
+++ b/cw_polygon/lib/polygon_mnemonics_exception.dart
@@ -0,0 +1,5 @@
+class PolygonMnemonicIsIncorrectException implements Exception {
+ @override
+ String toString() =>
+ 'Polygon mnemonic has incorrect format. Mnemonic should contain 12 or 24 words separated by space.';
+}
diff --git a/cw_polygon/lib/polygon_transaction_credentials.dart b/cw_polygon/lib/polygon_transaction_credentials.dart
new file mode 100644
index 000000000..6611e15da
--- /dev/null
+++ b/cw_polygon/lib/polygon_transaction_credentials.dart
@@ -0,0 +1,18 @@
+import 'package:cw_core/crypto_currency.dart';
+import 'package:cw_core/output_info.dart';
+import 'package:cw_ethereum/ethereum_transaction_credentials.dart';
+import 'package:cw_polygon/polygon_transaction_priority.dart';
+
+class PolygonTransactionCredentials extends EthereumTransactionCredentials {
+ PolygonTransactionCredentials(
+ List outputs, {
+ required PolygonTransactionPriority? priority,
+ required CryptoCurrency currency,
+ final int? feeRate,
+ }) : super(
+ outputs,
+ currency: currency,
+ priority: priority,
+ feeRate: feeRate,
+ );
+}
diff --git a/cw_polygon/lib/polygon_transaction_history.dart b/cw_polygon/lib/polygon_transaction_history.dart
new file mode 100644
index 000000000..a06b8be4a
--- /dev/null
+++ b/cw_polygon/lib/polygon_transaction_history.dart
@@ -0,0 +1,77 @@
+import 'dart:convert';
+import 'dart:core';
+import 'package:cw_core/pathForWallet.dart';
+import 'package:cw_core/wallet_info.dart';
+import 'package:cw_ethereum/file.dart';
+import 'package:cw_polygon/polygon_transaction_info.dart';
+import 'package:mobx/mobx.dart';
+import 'package:cw_core/transaction_history.dart';
+
+part 'polygon_transaction_history.g.dart';
+
+const transactionsHistoryFileName = 'polygon_transactions.json';
+
+class PolygonTransactionHistory = PolygonTransactionHistoryBase with _$PolygonTransactionHistory;
+
+abstract class PolygonTransactionHistoryBase extends TransactionHistoryBase
+ with Store {
+ PolygonTransactionHistoryBase({required this.walletInfo, required String password})
+ : _password = password {
+ transactions = ObservableMap();
+ }
+
+ final WalletInfo walletInfo;
+ String _password;
+
+ Future init() async => await _load();
+
+ @override
+ Future save() async {
+ try {
+ final dirPath = await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
+ final path = '$dirPath/$transactionsHistoryFileName';
+ final data = json.encode({'transactions': transactions});
+ await writeData(path: path, password: _password, data: data);
+ } catch (e, s) {
+ print('Error while saving polygon transaction history: ${e.toString()}');
+ print(s);
+ }
+ }
+
+ @override
+ void addOne(PolygonTransactionInfo transaction) => transactions[transaction.id] = transaction;
+
+ @override
+ void addMany(Map transactions) =>
+ this.transactions.addAll(transactions);
+
+ Future