This commit is contained in:
likho 2023-07-20 17:40:49 +02:00
parent e0df4723ae
commit bbd070ba7f
2 changed files with 118 additions and 57 deletions

View file

@ -60,7 +60,7 @@ class StellarWallet extends CoinServiceAPI
late final TransactionNotificationTracker txTracker; late final TransactionNotificationTracker txTracker;
late SecureStorageInterface _secureStore; late SecureStorageInterface _secureStore;
final StellarSDK stellarSdk = StellarSDK.PUBLIC; final StellarSDK stellarSdk = StellarSDK.TESTNET;
@override @override
bool get isFavorite => _isFavorite ??= getCachedIsFavorite(); bool get isFavorite => _isFavorite ??= getCachedIsFavorite();
@ -154,9 +154,37 @@ class StellarWallet extends CoinServiceAPI
late Coin _coin; late Coin _coin;
@override @override
Future<String> confirmSend({required Map<String, dynamic> txData}) { Future<String> confirmSend({required Map<String, dynamic> txData}) async {
// TODO: implement confirmSend print("TX DATA IS $txData");
throw UnimplementedError(); final secretSeed = await _secureStore.read(
key: '${_walletId}_secretSeed'
);
// final amt = Amount(
// rawValue: BigInt.from(txData['recipientAmt']),
// fractionDigits: coin.decimals,
// );
//
// print("THIS AMOUNT IS $amount");
//First check if account exists, can be skipped, but if the account does not exist,
// the transaction fee will be charged when the transaction fails.
AccountResponse receiverAccount = await stellarSdk.accounts
.account(txData['address'] as String).onError(
(error, stackTrace) => throw("Error getting account :: Cannot send transaction"));
KeyPair senderKeyPair = KeyPair.fromSecretSeed(secretSeed!);
AccountResponse sender = await stellarSdk.accounts.account(senderKeyPair.accountId);
Transaction transaction = TransactionBuilder(sender)
.addOperation(PaymentOperationBuilder(receiverAccount.accountId, Asset.NATIVE, "100").build())
.build();
transaction.sign(senderKeyPair, Network.TESTNET);
SubmitTransactionResponse response = await stellarSdk.submitTransaction(transaction);
if (!response.success) {
throw("Unable to send transaction");
}
return response.hash!;
} }
Future<SWAddress.Address?> get _currentReceivingAddress => Future<SWAddress.Address?> get _currentReceivingAddress =>
@ -219,9 +247,13 @@ class StellarWallet extends CoinServiceAPI
@override @override
Future<FeeObject> get fees async { Future<FeeObject> get fees async {
final nodeURI = Uri.parse("${getCurrentNode().host}:${getCurrentNode().port}"); // final nodeURI = Uri.parse("${getCurrentNode().host}:${getCurrentNode().port}");
final nodeURI = Uri.parse(getCurrentNode().host);
final httpClient = http.Client(); final httpClient = http.Client();
FeeStatsResponse fsp = await FeeStatsRequestBuilder(httpClient, nodeURI).execute(); FeeStatsResponse fsp = await FeeStatsRequestBuilder(httpClient, nodeURI).execute();
return FeeObject( return FeeObject(
numberOfBlocksFast: 0, numberOfBlocksFast: 0,
numberOfBlocksAverage: 0, numberOfBlocksAverage: 0,
@ -265,10 +297,9 @@ class StellarWallet extends CoinServiceAPI
await _prefs.init(); await _prefs.init();
String mnemonic = await Wallet.generate24WordsMnemonic(); String mnemonic = await Wallet.generate24WordsMnemonic();
final mnemonicArray = mnemonic.split(" ");
await _secureStore.write( await _secureStore.write(
key: '${_walletId}_mnemonic', key: '${_walletId}_mnemonic',
value: mnemonicArray.join(" ") value: mnemonic
); );
await _secureStore.write( await _secureStore.write(
key: '${_walletId}_mnemonicPassphrase', key: '${_walletId}_mnemonicPassphrase',
@ -278,6 +309,13 @@ class StellarWallet extends CoinServiceAPI
Wallet wallet = await Wallet.from(mnemonic); Wallet wallet = await Wallet.from(mnemonic);
KeyPair keyPair = await wallet.getKeyPair(index: 0); KeyPair keyPair = await wallet.getKeyPair(index: 0);
String address = keyPair.accountId; String address = keyPair.accountId;
String secretSeed = keyPair.secretSeed; //This will be required for sending a tx
await _secureStore.write(
key: '${_walletId}_secretSeed',
value: secretSeed
);
final swAddress = SWAddress.Address( final swAddress = SWAddress.Address(
walletId: walletId, walletId: walletId,
@ -301,8 +339,10 @@ class StellarWallet extends CoinServiceAPI
var mnemonic = await _secureStore.read( var mnemonic = await _secureStore.read(
key: '${_walletId}_mnemonic' key: '${_walletId}_mnemonic'
); );
var wallet = await Wallet.from(mnemonic!);
var keyPair = await wallet.getKeyPair(index: 0); Wallet wallet = await Wallet.from(mnemonic!);
KeyPair keyPair = await wallet.getKeyPair(index: 0);
return Future.value(keyPair.accountId); return Future.value(keyPair.accountId);
} }
@ -368,6 +408,7 @@ class StellarWallet extends CoinServiceAPI
var wallet = await Wallet.from(mnemonic); var wallet = await Wallet.from(mnemonic);
var keyPair = await wallet.getKeyPair(index: 0); var keyPair = await wallet.getKeyPair(index: 0);
var address = keyPair.accountId; var address = keyPair.accountId;
var secretSeed = keyPair.secretSeed;
await _secureStore.write( await _secureStore.write(
key: '${_walletId}_mnemonic', value: mnemonic.trim()); key: '${_walletId}_mnemonic', value: mnemonic.trim());
@ -375,6 +416,10 @@ class StellarWallet extends CoinServiceAPI
key: '${_walletId}_mnemonicPassphrase', key: '${_walletId}_mnemonicPassphrase',
value: mnemonicPassphrase ?? "", value: mnemonicPassphrase ?? "",
); );
await _secureStore.write(
key: '${_walletId}_secretSeed',
value: secretSeed
);
final swAddress = SWAddress.Address( final swAddress = SWAddress.Address(
walletId: walletId, walletId: walletId,
@ -404,20 +449,29 @@ class StellarWallet extends CoinServiceAPI
} }
Future<void> updateTransactions() async { Future<void> updateTransactions() async {
List<Tuple2<SWTransaction.Transaction, SWAddress.Address?>> transactionList = [];
Page<OperationResponse> payments = await stellarSdk.payments.forAccount(await getAddressSW()).order(RequestBuilderOrder.DESC).execute(); try {
for (OperationResponse response in payments.records!) { List<Tuple2<SWTransaction.Transaction, SWAddress.Address?>> transactionList = [];
if (response is PaymentOperationResponse) {
var por = response; Page<OperationResponse> payments = await stellarSdk.payments
SWTransaction.TransactionType type; .forAccount(await getAddressSW()).order(RequestBuilderOrder.DESC)
if (por.sourceAccount == await getAddressSW()) { .execute().onError((error, stackTrace) =>
type = SWTransaction.TransactionType.outgoing; throw("Could not fetch transactions")
} else { );
type = SWTransaction.TransactionType.incoming;
} for (OperationResponse response in payments.records!) {
final amount = Amount( if (response is PaymentOperationResponse) {
var por = response;
SWTransaction.TransactionType type;
if (por.sourceAccount == await getAddressSW()) {
type = SWTransaction.TransactionType.outgoing;
} else {
type = SWTransaction.TransactionType.incoming;
}
final amount = Amount(
rawValue: BigInt.parse(float.parse(por.amount!).toStringAsFixed(7).replaceAll(".", "")), rawValue: BigInt.parse(float.parse(por.amount!).toStringAsFixed(7).replaceAll(".", "")),
fractionDigits: 7, fractionDigits: 7,
<<<<<<< HEAD
); );
int fee = 0; int fee = 0;
int height = 0; int height = 0;
@ -468,39 +522,39 @@ class StellarWallet extends CoinServiceAPI
type = SWTransaction.TransactionType.incoming; type = SWTransaction.TransactionType.incoming;
} }
final amount = Amount( final amount = Amount(
rawValue: BigInt.parse(float.parse(caor.startingBalance!).toStringAsFixed(7).replaceAll(".", "")), rawValue: BigInt.parse(float.parse(caor.startingBalance!).toStringAsFixed(coin.decimals).replaceAll(".", "")),
fractionDigits: 7, fractionDigits: coin.decimals,
); );
int fee = 0; int fee = 0;
int height = 0; int height = 0;
var transaction = caor.transaction; var transaction = caor.transaction;
if (transaction != null) { if (transaction != null) {
fee = transaction.feeCharged!; fee = transaction.feeCharged!;
height = transaction.ledger; height = transaction.ledger;
} }
var theTransaction = SWTransaction.Transaction( var theTransaction = SWTransaction.Transaction(
walletId: walletId, walletId: walletId,
txid: caor.transactionHash!, txid: caor.transactionHash!,
timestamp: DateTime.parse(caor.createdAt!).millisecondsSinceEpoch ~/ 1000, timestamp: DateTime.parse(caor.createdAt!).millisecondsSinceEpoch ~/ 1000,
type: type, type: type,
subType: SWTransaction.TransactionSubType.none, subType: SWTransaction.TransactionSubType.none,
amount: 0, amount: 0,
amountString: amount.toJsonString(), amountString: amount.toJsonString(),
fee: fee, fee: fee,
height: height, height: height,
isCancelled: false, isCancelled: false,
isLelantus: false, isLelantus: false,
slateId: "", slateId: "",
otherData: "", otherData: "",
inputs: [], inputs: [],
outputs: [], outputs: [],
nonce: 0, nonce: 0,
numberOfMessages: null, numberOfMessages: null,
); );
SWAddress.Address? receivingAddress = await _currentReceivingAddress; SWAddress.Address? receivingAddress = await _currentReceivingAddress;
SWAddress.Address address = type == SWTransaction.TransactionType.incoming SWAddress.Address address = type == SWTransaction.TransactionType.incoming
? receivingAddress! ? receivingAddress!
: SWAddress.Address( : SWAddress.Address(
walletId: walletId, walletId: walletId,
value: caor.sourceAccount!, value: caor.sourceAccount!,
publicKey: KeyPair.fromAccountId(caor.sourceAccount!).publicKey, publicKey: KeyPair.fromAccountId(caor.sourceAccount!).publicKey,
@ -511,9 +565,16 @@ class StellarWallet extends CoinServiceAPI
); );
Tuple2<SWTransaction.Transaction, SWAddress.Address> tuple = Tuple2(theTransaction, address); Tuple2<SWTransaction.Transaction, SWAddress.Address> tuple = Tuple2(theTransaction, address);
transactionList.add(tuple); transactionList.add(tuple);
}
} }
await db.addNewTransactionData(transactionList, walletId);
} catch (e, s) {
Logging.instance.log(
"Exception rethrown from updateTransactions(): $e\n$s",
level: LogLevel.Error);
rethrow;
} }
await db.addNewTransactionData(transactionList, walletId);
} }
Future<void> updateBalance() async { Future<void> updateBalance() async {

View file

@ -182,11 +182,11 @@ abstract class DefaultNodes {
isDown: false); isDown: false);
static NodeModel get stellar => NodeModel( static NodeModel get stellar => NodeModel(
host: "https://horizon.stellar.org", host: "https://horizon-testnet.stellar.org",
port: 443, port: 443,
name: defaultName, name: defaultName,
id: _nodeId(Coin.stellar), id: _nodeId(Coin.stellar),
useSSL: true, useSSL: false,
enabled: true, enabled: true,
coinName: Coin.stellar.name, coinName: Coin.stellar.name,
isFailover: true, isFailover: true,