mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-04-01 11:59:06 +00:00
WIP stellar memo field on send screens as well as in trade details and exchange flow
This commit is contained in:
parent
98f3046e04
commit
bc25d5b3af
7 changed files with 431 additions and 63 deletions
lib
pages
exchange_view
send_view
pages_desktop_specific
desktop_exchange/exchange_steps/subwidgets
my_stack_view/wallet_view/sub_widgets
services/coins/stellar
|
@ -252,10 +252,17 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
},
|
||||
);
|
||||
} else {
|
||||
final memo =
|
||||
manager.coin == Coin.stellar || manager.coin == Coin.stellarTestnet
|
||||
? model.trade!.payInExtraId.isNotEmpty
|
||||
? model.trade!.payInExtraId
|
||||
: null
|
||||
: null;
|
||||
txDataFuture = manager.prepareSend(
|
||||
address: address,
|
||||
amount: amount,
|
||||
args: {
|
||||
"memo": memo,
|
||||
"feeRate": FeeRateType.average,
|
||||
// ref.read(feeRateTypeStateProvider)
|
||||
},
|
||||
|
@ -568,6 +575,74 @@ class _Step4ViewState extends ConsumerState<Step4View> {
|
|||
const SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
if (model.trade!.payInExtraId.isNotEmpty)
|
||||
RoundedWhiteContainer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Memo",
|
||||
style:
|
||||
STextStyles.itemSubtitle(context),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
final data = ClipboardData(
|
||||
text:
|
||||
model.trade!.payInExtraId);
|
||||
await clipboard.setData(data);
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message:
|
||||
"Copied to clipboard",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.svg.copy,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.infoItemIcons,
|
||||
width: 10,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Text(
|
||||
"Copy",
|
||||
style:
|
||||
STextStyles.link2(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
Text(
|
||||
model.trade!.payInExtraId,
|
||||
style:
|
||||
STextStyles.itemSubtitle12(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (model.trade!.payInExtraId.isNotEmpty)
|
||||
const SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
child: Row(
|
||||
children: [
|
||||
|
|
|
@ -268,10 +268,17 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
|
|||
|
||||
// if not firo then do normal send
|
||||
if (shouldSendPublicFiroFunds == null) {
|
||||
final memo =
|
||||
manager.coin == Coin.stellar || manager.coin == Coin.stellarTestnet
|
||||
? trade.payInExtraId.isNotEmpty
|
||||
? trade.payInExtraId
|
||||
: null
|
||||
: null;
|
||||
txDataFuture = manager.prepareSend(
|
||||
address: address,
|
||||
amount: amount,
|
||||
args: {
|
||||
"memo": memo,
|
||||
"feeRate": FeeRateType.average,
|
||||
// ref.read(feeRateTypeStateProvider)
|
||||
},
|
||||
|
|
|
@ -850,6 +850,81 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
|
|||
: const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
if (trade.payInExtraId.isNotEmpty && !sentFromStack && !hasTx)
|
||||
RoundedWhiteContainer(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.all(16)
|
||||
: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Memo",
|
||||
style: STextStyles.itemSubtitle(context),
|
||||
),
|
||||
isDesktop
|
||||
? IconCopyButton(
|
||||
data: trade.payInExtraId,
|
||||
)
|
||||
: GestureDetector(
|
||||
onTap: () async {
|
||||
final address = trade.payInExtraId;
|
||||
await Clipboard.setData(
|
||||
ClipboardData(
|
||||
text: address,
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
unawaited(
|
||||
showFloatingFlushBar(
|
||||
type: FlushBarType.info,
|
||||
message: "Copied to clipboard",
|
||||
context: context,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
Assets.svg.copy,
|
||||
width: 12,
|
||||
height: 12,
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.infoItemIcons,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Text(
|
||||
"Copy",
|
||||
style: STextStyles.link2(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 4,
|
||||
),
|
||||
SelectableText(
|
||||
trade.payInExtraId,
|
||||
style: STextStyles.itemSubtitle12(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (trade.payInExtraId.isNotEmpty && !sentFromStack && !hasTx)
|
||||
isDesktop
|
||||
? const _Divider()
|
||||
: const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.all(16)
|
||||
|
|
|
@ -103,6 +103,7 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
late TextEditingController noteController;
|
||||
late TextEditingController onChainNoteController;
|
||||
late TextEditingController feeController;
|
||||
late TextEditingController memoController;
|
||||
|
||||
late final SendViewAutoFillData? _data;
|
||||
|
||||
|
@ -111,6 +112,9 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
final _onChainNoteFocusNode = FocusNode();
|
||||
final _cryptoFocus = FocusNode();
|
||||
final _baseFocus = FocusNode();
|
||||
final _memoFocus = FocusNode();
|
||||
|
||||
late final bool isStellar;
|
||||
|
||||
Amount? _amountToSend;
|
||||
Amount? _cachedAmountToSend;
|
||||
|
@ -522,10 +526,15 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
},
|
||||
);
|
||||
} else {
|
||||
final memo =
|
||||
manager.coin == Coin.stellar || manager.coin == Coin.stellarTestnet
|
||||
? memoController.text
|
||||
: null;
|
||||
txDataFuture = manager.prepareSend(
|
||||
address: _address!,
|
||||
amount: amount,
|
||||
args: {
|
||||
"memo": memo,
|
||||
"feeRate": ref.read(feeRateTypeStateProvider),
|
||||
"satsPerVByte": isCustomFee ? customFeeRate : null,
|
||||
"UTXOs": (manager.hasCoinControlSupport &&
|
||||
|
@ -622,6 +631,7 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
walletId = widget.walletId;
|
||||
clipboard = widget.clipboard;
|
||||
scanner = widget.barcodeScanner;
|
||||
isStellar = coin == Coin.stellar || coin == Coin.stellarTestnet;
|
||||
|
||||
sendToController = TextEditingController();
|
||||
cryptoAmountController = TextEditingController();
|
||||
|
@ -629,6 +639,7 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
noteController = TextEditingController();
|
||||
onChainNoteController = TextEditingController();
|
||||
feeController = TextEditingController();
|
||||
memoController = TextEditingController();
|
||||
|
||||
onCryptoAmountChanged = _cryptoAmountChanged;
|
||||
cryptoAmountController.addListener(onCryptoAmountChanged);
|
||||
|
@ -704,12 +715,14 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
noteController.dispose();
|
||||
onChainNoteController.dispose();
|
||||
feeController.dispose();
|
||||
memoController.dispose();
|
||||
|
||||
_noteFocusNode.dispose();
|
||||
_onChainNoteFocusNode.dispose();
|
||||
_addressFocusNode.dispose();
|
||||
_cryptoFocus.dispose();
|
||||
_baseFocus.dispose();
|
||||
_memoFocus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -1298,6 +1311,88 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
if (isStellar)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(
|
||||
Constants.size.circularBorderRadius,
|
||||
),
|
||||
child: TextField(
|
||||
key: const Key("sendViewMemoFieldKey"),
|
||||
controller: memoController,
|
||||
readOnly: false,
|
||||
autocorrect: false,
|
||||
enableSuggestions: false,
|
||||
focusNode: _memoFocus,
|
||||
style: STextStyles.field(context),
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
decoration: standardInputDecoration(
|
||||
"Enter memo (optional)",
|
||||
_memoFocus,
|
||||
context,
|
||||
).copyWith(
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
top: 6,
|
||||
bottom: 8,
|
||||
right: 5,
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: memoController.text.isEmpty
|
||||
? const EdgeInsets.only(right: 8)
|
||||
: const EdgeInsets.only(right: 0),
|
||||
child: UnconstrainedBox(
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
memoController.text.isNotEmpty
|
||||
? TextFieldIconButton(
|
||||
semanticsLabel:
|
||||
"Clear Button. Clears The Memo Field Input.",
|
||||
key: const Key(
|
||||
"sendViewClearMemoFieldButtonKey"),
|
||||
onTap: () {
|
||||
memoController.text = "";
|
||||
setState(() {});
|
||||
},
|
||||
child: const XIcon(),
|
||||
)
|
||||
: TextFieldIconButton(
|
||||
semanticsLabel:
|
||||
"Paste Button. Pastes From Clipboard To Memo Field Input.",
|
||||
key: const Key(
|
||||
"sendViewPasteMemoFieldButtonKey"),
|
||||
onTap: () async {
|
||||
final ClipboardData? data =
|
||||
await clipboard.getData(
|
||||
Clipboard
|
||||
.kTextPlain);
|
||||
if (data?.text != null &&
|
||||
data!
|
||||
.text!.isNotEmpty) {
|
||||
String content =
|
||||
data.text!.trim();
|
||||
|
||||
memoController.text =
|
||||
content.trim();
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
child: const ClipboardIcon(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Builder(
|
||||
builder: (_) {
|
||||
final error = _updateInvalidAddressText(
|
||||
|
@ -1817,7 +1912,8 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
),
|
||||
child: TextField(
|
||||
autocorrect: Util.isDesktop ? false : true,
|
||||
enableSuggestions: Util.isDesktop ? false : true,
|
||||
enableSuggestions:
|
||||
Util.isDesktop ? false : true,
|
||||
maxLength: 256,
|
||||
controller: onChainNoteController,
|
||||
focusNode: _onChainNoteFocusNode,
|
||||
|
@ -1828,25 +1924,27 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
_onChainNoteFocusNode,
|
||||
context,
|
||||
).copyWith(
|
||||
suffixIcon: onChainNoteController.text.isNotEmpty
|
||||
suffixIcon: onChainNoteController
|
||||
.text.isNotEmpty
|
||||
? Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(right: 0),
|
||||
child: UnconstrainedBox(
|
||||
child: Row(
|
||||
children: [
|
||||
TextFieldIconButton(
|
||||
child: const XIcon(),
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
onChainNoteController.text = "";
|
||||
});
|
||||
},
|
||||
padding:
|
||||
const EdgeInsets.only(right: 0),
|
||||
child: UnconstrainedBox(
|
||||
child: Row(
|
||||
children: [
|
||||
TextFieldIconButton(
|
||||
child: const XIcon(),
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
onChainNoteController
|
||||
.text = "";
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
|
@ -1856,8 +1954,9 @@ class _SendViewState extends ConsumerState<SendView> {
|
|||
height: 12,
|
||||
),
|
||||
Text(
|
||||
(coin == Coin.epicCash) ? "Local Note (optional)"
|
||||
: "Note (optional)",
|
||||
(coin == Coin.epicCash)
|
||||
? "Local Note (optional)"
|
||||
: "Note (optional)",
|
||||
style: STextStyles.smallMed12(context),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
|
|
|
@ -155,6 +155,23 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
|
|||
height: 1,
|
||||
color: Theme.of(context).extension<StackColors>()!.background,
|
||||
),
|
||||
if (ref.watch(desktopExchangeModelProvider
|
||||
.select((value) => value!.trade?.payInExtraId)) !=
|
||||
null)
|
||||
DesktopStepItem(
|
||||
vertical: true,
|
||||
label: "Memo",
|
||||
value: ref.watch(desktopExchangeModelProvider
|
||||
.select((value) => value!.trade?.payInExtraId)) ??
|
||||
"Error",
|
||||
),
|
||||
if (ref.watch(desktopExchangeModelProvider
|
||||
.select((value) => value!.trade?.payInExtraId)) !=
|
||||
null)
|
||||
Container(
|
||||
height: 1,
|
||||
color: Theme.of(context).extension<StackColors>()!.background,
|
||||
),
|
||||
DesktopStepItem(
|
||||
label: "Amount",
|
||||
value:
|
||||
|
|
|
@ -97,12 +97,16 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
late TextEditingController cryptoAmountController;
|
||||
late TextEditingController baseAmountController;
|
||||
// late TextEditingController feeController;
|
||||
late TextEditingController memoController;
|
||||
|
||||
late final SendViewAutoFillData? _data;
|
||||
|
||||
final _addressFocusNode = FocusNode();
|
||||
final _cryptoFocus = FocusNode();
|
||||
final _baseFocus = FocusNode();
|
||||
final _memoFocus = FocusNode();
|
||||
|
||||
late final bool isStellar;
|
||||
|
||||
String? _note;
|
||||
String? _onChainNote;
|
||||
|
@ -326,10 +330,12 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
},
|
||||
);
|
||||
} else {
|
||||
final memo = isStellar ? memoController.text : null;
|
||||
txDataFuture = manager.prepareSend(
|
||||
address: _address!,
|
||||
amount: amount,
|
||||
args: {
|
||||
"memo": memo,
|
||||
"feeRate": ref.read(feeRateTypeStateProvider),
|
||||
"satsPerVByte": isCustomFee ? customFeeRate : null,
|
||||
"UTXOs": (manager.hasCoinControlSupport &&
|
||||
|
@ -663,6 +669,23 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> pasteMemo() async {
|
||||
if (memoController.text.isNotEmpty) {
|
||||
setState(() {
|
||||
memoController.text = "";
|
||||
});
|
||||
} else {
|
||||
final ClipboardData? data = await clipboard.getData(Clipboard.kTextPlain);
|
||||
if (data?.text != null && data!.text!.isNotEmpty) {
|
||||
String content = data.text!.trim();
|
||||
|
||||
setState(() {
|
||||
memoController.text = content;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fiatTextFieldOnChanged(String baseAmountString) {
|
||||
final baseAmount = Amount.tryParseFiatString(
|
||||
baseAmountString,
|
||||
|
@ -762,10 +785,12 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin;
|
||||
clipboard = widget.clipboard;
|
||||
scanner = widget.barcodeScanner;
|
||||
isStellar = coin == Coin.stellar || coin == Coin.stellarTestnet;
|
||||
|
||||
sendToController = TextEditingController();
|
||||
cryptoAmountController = TextEditingController();
|
||||
baseAmountController = TextEditingController();
|
||||
memoController = TextEditingController();
|
||||
// feeController = TextEditingController();
|
||||
|
||||
onCryptoAmountChanged = _cryptoAmountChanged;
|
||||
|
@ -814,11 +839,13 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
sendToController.dispose();
|
||||
cryptoAmountController.dispose();
|
||||
baseAmountController.dispose();
|
||||
memoController.dispose();
|
||||
// feeController.dispose();
|
||||
|
||||
_addressFocusNode.dispose();
|
||||
_cryptoFocus.dispose();
|
||||
_baseFocus.dispose();
|
||||
_memoFocus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
@ -1367,6 +1394,67 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
|
|||
}
|
||||
},
|
||||
),
|
||||
if (isStellar)
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
if (isStellar)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(
|
||||
Constants.size.circularBorderRadius,
|
||||
),
|
||||
child: TextField(
|
||||
minLines: 1,
|
||||
maxLines: 5,
|
||||
key: const Key("sendViewMemoFieldKey"),
|
||||
controller: memoController,
|
||||
readOnly: false,
|
||||
autocorrect: false,
|
||||
enableSuggestions: false,
|
||||
focusNode: _memoFocus,
|
||||
onChanged: (_) {
|
||||
setState(() {});
|
||||
},
|
||||
style: STextStyles.desktopTextExtraSmall(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldActiveText,
|
||||
height: 1.8,
|
||||
),
|
||||
decoration: standardInputDecoration(
|
||||
"Enter memo (optional)",
|
||||
_memoFocus,
|
||||
context,
|
||||
desktopMed: true,
|
||||
).copyWith(
|
||||
contentPadding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
top: 11,
|
||||
bottom: 12,
|
||||
right: 5,
|
||||
),
|
||||
suffixIcon: Padding(
|
||||
padding: memoController.text.isEmpty
|
||||
? const EdgeInsets.only(right: 8)
|
||||
: const EdgeInsets.only(right: 0),
|
||||
child: UnconstrainedBox(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
TextFieldIconButton(
|
||||
key: const Key("sendViewPasteMemoButtonKey"),
|
||||
onTap: pasteMemo,
|
||||
child: memoController.text.isEmpty
|
||||
? const ClipboardIcon()
|
||||
: const XIcon(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!isPaynymSend)
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
|
|
|
@ -181,6 +181,41 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
return exists;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> prepareSend(
|
||||
{required String address,
|
||||
required Amount amount,
|
||||
Map<String, dynamic>? args}) async {
|
||||
try {
|
||||
final feeRate = args?["feeRate"];
|
||||
var fee = 1000;
|
||||
if (feeRate is FeeRateType) {
|
||||
final theFees = await fees;
|
||||
switch (feeRate) {
|
||||
case FeeRateType.fast:
|
||||
fee = theFees.fast;
|
||||
case FeeRateType.slow:
|
||||
fee = theFees.slow;
|
||||
case FeeRateType.average:
|
||||
default:
|
||||
fee = theFees.medium;
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> txData = {
|
||||
"fee": fee,
|
||||
"address": address,
|
||||
"recipientAmt": amount,
|
||||
"memo": args?["memo"] as String?,
|
||||
};
|
||||
|
||||
Logging.instance.log("prepare send: $txData", level: LogLevel.Info);
|
||||
return txData;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Error getting fees $e - $s", level: LogLevel.Error);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> confirmSend({required Map<String, dynamic> txData}) async {
|
||||
final secretSeed = await _secureStore.read(key: '${_walletId}_secretSeed');
|
||||
|
@ -188,27 +223,33 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
AccountResponse sender =
|
||||
await stellarSdk.accounts.account(senderKeyPair.accountId);
|
||||
final amountToSend = txData['recipientAmt'] as Amount;
|
||||
final memo = txData["memo"] as String?;
|
||||
|
||||
//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.
|
||||
bool validAccount = await _accountExists(txData['address'] as String);
|
||||
Transaction transaction;
|
||||
TransactionBuilder transactionBuilder;
|
||||
|
||||
if (!validAccount) {
|
||||
//Fund the account, user must ensure account is correct
|
||||
CreateAccountOperationBuilder createAccBuilder =
|
||||
CreateAccountOperationBuilder(
|
||||
txData['address'] as String, amountToSend.decimal.toString());
|
||||
transaction = TransactionBuilder(sender)
|
||||
.addOperation(createAccBuilder.build())
|
||||
.build();
|
||||
transactionBuilder =
|
||||
TransactionBuilder(sender).addOperation(createAccBuilder.build());
|
||||
} else {
|
||||
transaction = TransactionBuilder(sender)
|
||||
.addOperation(PaymentOperationBuilder(txData['address'] as String,
|
||||
Asset.NATIVE, amountToSend.decimal.toString())
|
||||
.build())
|
||||
.build();
|
||||
transactionBuilder = TransactionBuilder(sender).addOperation(
|
||||
PaymentOperationBuilder(txData['address'] as String, Asset.NATIVE,
|
||||
amountToSend.decimal.toString())
|
||||
.build());
|
||||
}
|
||||
|
||||
if (memo != null) {
|
||||
transactionBuilder.addMemo(MemoText(memo));
|
||||
}
|
||||
|
||||
final transaction = transactionBuilder.build();
|
||||
|
||||
transaction.sign(senderKeyPair, stellarNetwork);
|
||||
try {
|
||||
SubmitTransactionResponse response = await stellarSdk
|
||||
|
@ -441,40 +482,6 @@ class StellarWallet extends CoinServiceAPI with WalletCache, WalletDB {
|
|||
Future<String?> get mnemonicString =>
|
||||
_secureStore.read(key: '${_walletId}_mnemonic');
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> prepareSend(
|
||||
{required String address,
|
||||
required Amount amount,
|
||||
Map<String, dynamic>? args}) async {
|
||||
try {
|
||||
final feeRate = args?["feeRate"];
|
||||
var fee = 1000;
|
||||
if (feeRate is FeeRateType) {
|
||||
final theFees = await fees;
|
||||
switch (feeRate) {
|
||||
case FeeRateType.fast:
|
||||
fee = theFees.fast;
|
||||
case FeeRateType.slow:
|
||||
fee = theFees.slow;
|
||||
case FeeRateType.average:
|
||||
default:
|
||||
fee = theFees.medium;
|
||||
}
|
||||
}
|
||||
Map<String, dynamic> txData = {
|
||||
"fee": fee,
|
||||
"address": address,
|
||||
"recipientAmt": amount,
|
||||
};
|
||||
|
||||
Logging.instance.log("prepare send: $txData", level: LogLevel.Info);
|
||||
return txData;
|
||||
} catch (e, s) {
|
||||
Logging.instance.log("Error getting fees $e - $s", level: LogLevel.Error);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _recoverWalletFromBIP32SeedPhrase({
|
||||
required String mnemonic,
|
||||
required String mnemonicPassphrase,
|
||||
|
|
Loading…
Reference in a new issue