Add anypay payment. Add filter by search for ionia, add get purchased items for ionia.

This commit is contained in:
M 2022-06-28 14:31:51 +01:00
parent 1447ea32ba
commit 657265a10a
15 changed files with 378 additions and 58 deletions

View file

@ -2,8 +2,9 @@ import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_core/output_info.dart';
class BitcoinTransactionCredentials {
BitcoinTransactionCredentials(this.outputs, this.priority);
BitcoinTransactionCredentials(this.outputs, {this.priority, this.feeRate});
final List<OutputInfo> outputs;
BitcoinTransactionPriority priority;
final BitcoinTransactionPriority priority;
final int feeRate;
}

View file

@ -208,8 +208,14 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
}
amount = credentialsAmount;
fee = calculateEstimatedFee(transactionCredentials.priority, amount,
outputsCount: outputs.length + 1);
if (transactionCredentials.feeRate != null) {
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount,
outputsCount: outputs.length + 1);
} else {
fee = calculateEstimatedFee(transactionCredentials.priority, amount,
outputsCount: outputs.length + 1);
}
} else {
final output = outputs.first;
credentialsAmount = !output.sendAll
@ -223,9 +229,14 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
amount = output.sendAll || allAmount - credentialsAmount < minAmount
? allAmount
: credentialsAmount;
fee = output.sendAll || amount == allAmount
? allAmountFee
: calculateEstimatedFee(transactionCredentials.priority, amount);
if (output.sendAll || amount == allAmount) {
fee = allAmountFee;
} else if (transactionCredentials.feeRate != null) {
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount);
} else {
fee = calculateEstimatedFee(transactionCredentials.priority, amount);
}
}
if (fee == 0) {
@ -296,7 +307,14 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
final estimatedSize =
estimatedTransactionSize(inputs.length, outputs.length + 1);
final feeAmount = feeRate(transactionCredentials.priority) * estimatedSize;
var feeAmount = 0;
if (transactionCredentials.feeRate != null) {
feeAmount = transactionCredentials.feeRate * estimatedSize;
} else {
feeAmount = feeRate(transactionCredentials.priority) * estimatedSize;
}
final changeValue = totalInputAmount - amount - feeAmount;
if (changeValue > minAmount) {
@ -346,45 +364,57 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
int outputsCount) =>
feeRate(priority) * estimatedTransactionSize(inputsCount, outputsCount);
int feeAmountWithFeeRate(int feeRate, int inputsCount,
int outputsCount) =>
feeRate * estimatedTransactionSize(inputsCount, outputsCount);
@override
int calculateEstimatedFee(TransactionPriority priority, int amount,
{int outputsCount}) {
if (priority is BitcoinTransactionPriority) {
int inputsCount = 0;
if (amount != null) {
int totalValue = 0;
for (final input in unspentCoins) {
if (totalValue >= amount) {
break;
}
if (input.isSending) {
totalValue += input.value;
inputsCount += 1;
}
}
if (totalValue < amount) return 0;
} else {
for (final input in unspentCoins) {
if (input.isSending) {
inputsCount += 1;
}
}
}
// If send all, then we have no change value
final _outputsCount = outputsCount ?? (amount != null ? 2 : 1);
return feeAmountForPriority(
priority, inputsCount, _outputsCount);
return calculateEstimatedFeeWithFeeRate(
feeRate(priority),
amount,
outputsCount: outputsCount);
}
return 0;
}
int calculateEstimatedFeeWithFeeRate(int feeRate, int amount,
{int outputsCount}) {
int inputsCount = 0;
if (amount != null) {
int totalValue = 0;
for (final input in unspentCoins) {
if (totalValue >= amount) {
break;
}
if (input.isSending) {
totalValue += input.value;
inputsCount += 1;
}
}
if (totalValue < amount) return 0;
} else {
for (final input in unspentCoins) {
if (input.isSending) {
inputsCount += 1;
}
}
}
// If send all, then we have no change value
final _outputsCount = outputsCount ?? (amount != null ? 2 : 1);
return feeAmountWithFeeRate(
feeRate, inputsCount, _outputsCount);
}
@override
Future<void> save() async {
final path = await makePath();

View file

@ -25,7 +25,7 @@ class PendingBitcoinTransaction with PendingTransaction {
String get id => _tx.getId();
@override
String get hex => '';
String get hex => _tx.toHex();
@override
String get amountFormatted => bitcoinAmountToString(amount: amount);

View file

@ -0,0 +1,5 @@
class AnyPayChain {
static const xmr = 'XMR';
static const btc = 'BTC';
static const ltc = 'LTC';
}

View file

@ -22,6 +22,8 @@ class AnyPayPaymentInstruction {
outputs: outputs);
}
static const transactionType = 'transaction';
final String type;
final int requiredFeeRate;
final bool txKey;

View file

@ -0,0 +1,9 @@
import 'package:flutter/foundation.dart';
class AnyPayTransaction {
const AnyPayTransaction(this.tx, {@required this.id, @required this.key});
final String tx;
final String id;
final String key;
}

View file

@ -1,16 +1,23 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/anypay/any_pay_payment.dart';
import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
class AnyPayApi {
static const contentTypePaymentRequest = 'application/payment-request';
static const contentTypePayment = 'application/payment';
static const xPayproVersion = '2';
static String chainByScheme(String scheme) {
switch (scheme.toLowerCase()) {
case 'monero':
return CryptoCurrency.xmr.title;
case 'bitcoin':
return CryptoCurrency.btc.title;
case 'litecoin':
return CryptoCurrency.ltc.title;
default:
return '';
}
@ -20,12 +27,16 @@ class AnyPayApi {
switch (scheme.toLowerCase()) {
case 'monero':
return CryptoCurrency.xmr;
case 'bitcoin':
return CryptoCurrency.btc;
case 'litecoin':
return CryptoCurrency.ltc;
default:
return null;
}
}
Future<AnyPayPayment> pay(String uri) async {
Future<AnyPayPayment> paymentRequest(String uri) async {
final fragments = uri.split(':?r=');
final scheme = fragments.first;
final url = fragments[1];
@ -45,4 +56,24 @@ class AnyPayApi {
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
return AnyPayPayment.fromMap(decodedBody);
}
Future<void> payment(
String uri,
{@required String chain,
@required String currency,
@required List<AnyPayTransaction> transactions}) async {
final headers = <String, String>{
'Content-Type': contentTypePayment,
'X-Paypro-Version': xPayproVersion,
'Accept': '*/*',};
final body = <String, dynamic>{
'chain': chain,
'currency': currency,
'transactions': transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()};
final response = await post(uri, headers: headers, body: utf8.encode(json.encode(body)));
if (response.statusCode != 200) {
return null;
}
}
}

View file

@ -55,7 +55,7 @@ class CWBitcoin extends Bitcoin {
}
@override
Object createBitcoinTransactionCredentials(List<Output> outputs, TransactionPriority priority)
Object createBitcoinTransactionCredentials(List<Output> outputs, {TransactionPriority priority, int feeRate})
=> BitcoinTransactionCredentials(
outputs.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
@ -67,7 +67,15 @@ class CWBitcoin extends Bitcoin {
isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount))
.toList(),
priority as BitcoinTransactionPriority);
priority: priority != null ? priority as BitcoinTransactionPriority : null,
feeRate: feeRate);
@override
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority priority, int feeRate})
=> BitcoinTransactionCredentials(
outputs,
priority: priority != null ? priority as BitcoinTransactionPriority : null,
feeRate: feeRate);
@override
List<String> getAddresses(Object wallet) {

View file

@ -131,6 +131,7 @@ import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
import 'package:cake_wallet/ionia/ionia_token_service.dart';
import 'package:cake_wallet/anypay/anypay_api.dart';
final getIt = GetIt.instance;
@ -651,6 +652,8 @@ Future setup(
getIt.registerFactory(() => IoniaApi());
getIt.registerFactory(() => AnyPayApi());
getIt.registerFactory<IoniaService>(
() => IoniaService(getIt.get<FlutterSecureStorage>(), getIt.get<IoniaApi>()));

View file

@ -0,0 +1,89 @@
import 'package:flutter/foundation.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/output_info.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/anypay/any_pay_payment.dart';
import 'package:cake_wallet/anypay/any_pay_payment_instruction.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/anypay/anypay_api.dart';
import 'package:cake_wallet/anypay/any_pay_chain.dart';
import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/monero/monero.dart';
class IoniaAnyPay {
IoniaAnyPay(this.ioniaService, this.anyPayApi, this.wallet);
final IoniaService ioniaService;
final AnyPayApi anyPayApi;
final WalletBase wallet;
Future<AnyPayPayment> purchase({
@required String merchId,
@required double amount,
@required String currency}) async {
final invoice = await ioniaService.purchaseGiftCard(
merchId: merchId,
amount: amount,
currency: currency);
return anyPayApi.paymentRequest(invoice.uri);
}
Future<void> commitInvoice(AnyPayPayment payment) async {
final transactionCredentials = payment.instructions
.where((instruction) => instruction.type == AnyPayPaymentInstruction.transactionType)
.map((AnyPayPaymentInstruction instruction) {
switch(payment.chain.toUpperCase()) {
case AnyPayChain.xmr:
return monero.createMoneroTransactionCreationCredentialsRaw(
outputs: instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
address: out.address,
cryptoAmount: moneroAmountToString(amount: out.amount),
sendAll: false)).toList(),
priority: MoneroTransactionPriority.medium); // FIXME: HARDCODED PRIORITY
case AnyPayChain.btc:
return bitcoin.createBitcoinTransactionCredentialsRaw(
instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
address: out.address,
formattedCryptoAmount: out.amount,
sendAll: false)).toList(),
feeRate: instruction.requiredFeeRate);
case AnyPayChain.ltc:
return bitcoin.createBitcoinTransactionCredentialsRaw(
instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
address: out.address,
formattedCryptoAmount: out.amount,
sendAll: false)).toList(),
feeRate: instruction.requiredFeeRate);
default:
throw Exception('Incorrect transaction chain: ${payment.chain.toUpperCase()}');
}
});
final transactions = (await Future.wait(transactionCredentials
.map((Object credentials) async => await wallet.createTransaction(credentials))))
.map((PendingTransaction pendingTransaction) {
switch (payment.chain.toUpperCase()){
case AnyPayChain.xmr:
final ptx = monero.pendingTransactionInfo(pendingTransaction);
return AnyPayTransaction(ptx['hex'], id: ptx['id'], key: ptx['key']);
default:
return AnyPayTransaction(pendingTransaction.hex, id: pendingTransaction.id, key: null);
}
})
.toList();
await anyPayApi.payment(
payment.paymentUrl,
chain: payment.chain,
currency: payment.chain,
transactions: transactions);
}
}

View file

@ -14,6 +14,7 @@ class IoniaApi {
static final createCardUri = Uri.https(baseUri, '/$pathPrefix/CreateCard');
static final getCardsUri = Uri.https(baseUri, '/$pathPrefix/GetCards');
static final getMerchantsUrl = Uri.https(baseUri, '/$pathPrefix/GetMerchants');
static final getMerchantsByFilterUrl = Uri.https(baseUri, '/$pathPrefix/GetMerchantsByFilter');
static final getPurchaseMerchantsUrl = Uri.https(baseUri, '/$pathPrefix/PurchaseGiftCard');
// Create user
@ -157,6 +158,52 @@ class IoniaApi {
}).toList();
}
// Get Merchants By Filter
Future<List<IoniaMerchant>> getMerchantsByFilter({
@required String username,
@required String password,
@required String clientId,
String search,
List<int> categories,
int merchantFilterType = 0}) async {
// MerchantFilterType: {All = 0, Nearby = 1, Popular = 2, Online = 3, MyFaves = 4, Search = 5}
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
'Content-Type': 'application/json'};
final body = <String, dynamic>{'MerchantFilterType': merchantFilterType};
if (search != null) {
body['SearchCriteria'] = search;
}
if (categories != null) {
body['Categories'] = categories;
}
final response = await post(getMerchantsByFilterUrl, headers: headers, body: json.encode(body));
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
final element = e as Map<String, dynamic>;
return IoniaMerchant.fromJsonMap(element);
}).toList();
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
@ -173,8 +220,8 @@ class IoniaApi {
'Content-Type': 'application/json'};
final body = <String, dynamic>{
'Amount': amount,
'Currency': currency,
'MerchantId': merchId};
'Currency': currency,
'MerchantId': merchId};
final response = await post(getPurchaseMerchantsUrl, headers: headers, body: json.encode(body));
if (response.statusCode != 200) {
@ -191,4 +238,34 @@ class IoniaApi {
final data = decodedBody['Data'] as Map<String, dynamic>;
return IoniaOrder.fromMap(data);
}
// Get Current User Gift Card Summaries
Future<List<IoniaMerchant>> getCurrentUserGiftCardSummaries({
@required String username,
@required String password,
@required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password};
final response = await post(getMerchantsUrl, headers: headers);
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
return data.map((dynamic e) {
final element = e as Map<String, dynamic>;
return IoniaMerchant.fromJsonMap(element);
}).toList();
}
}

View file

@ -71,6 +71,23 @@ class IoniaService {
return ioniaApi.getMerchants(username: username, password: password, clientId: clientId);
}
// Get Merchants By Filter
Future<List<IoniaMerchant>> getMerchantsByFilter({
String search,
List<int> categories,
int merchantFilterType = 0}) async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
return ioniaApi.getMerchantsByFilter(
username: username,
password: password,
clientId: clientId,
search: search,
categories: categories,
merchantFilterType: merchantFilterType);
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
@ -87,4 +104,12 @@ class IoniaService {
password: password,
clientId: clientId);
}
// Get Current User Gift Card Summaries
Future<List<IoniaMerchant>> getCurrentUserGiftCardSummaries() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey);
final password = await secureStorage.read(key: ioniaPasswordStorageKey);
return ioniaApi.getCurrentUserGiftCardSummaries(username: username, password: password, clientId: clientId);
}
}

View file

@ -2,7 +2,7 @@ part of 'monero.dart';
class CWMoneroAccountList extends MoneroAccountList {
CWMoneroAccountList(this._wallet);
Object _wallet;
final Object _wallet;
@override
@computed
@ -39,13 +39,13 @@ class CWMoneroAccountList extends MoneroAccountList {
@override
Future<void> addAccount(Object wallet, {String label}) async {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.accountList.addAccount(label: label);
await moneroWallet.walletAddresses.accountList.addAccount(label: label);
}
@override
Future<void> setLabelAccount(Object wallet, {int accountIndex, String label}) async {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.accountList
await moneroWallet.walletAddresses.accountList
.setLabelAccount(
accountIndex: accountIndex,
label: label);
@ -95,7 +95,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
@override
Future<void> addSubaddress(Object wallet, {int accountIndex, String label}) async {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.subaddressList
await moneroWallet.walletAddresses.subaddressList
.addSubaddress(
accountIndex: accountIndex,
label: label);
@ -105,7 +105,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
Future<void> setLabelSubaddress(Object wallet,
{int accountIndex, int addressIndex, String label}) async {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.subaddressList
await moneroWallet.walletAddresses.subaddressList
.setLabelSubaddress(
accountIndex: accountIndex,
addressIndex: addressIndex,
@ -140,35 +140,43 @@ class CWMonero extends Monero {
return CWMoneroAccountList(wallet);
}
@override
MoneroSubaddressList getSubaddressList(Object wallet) {
return CWMoneroSubaddressList(wallet);
}
@override
TransactionHistoryBase getTransactionHistory(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
return moneroWallet.transactionHistory;
}
@override
MoneroWalletDetails getMoneroWalletDetails(Object wallet) {
return CWMoneroWalletDetails(wallet);
}
@override
int getHeigthByDate({DateTime date}) {
return getMoneroHeigthByDate(date: date);
}
@override
TransactionPriority getDefaultTransactionPriority() {
return MoneroTransactionPriority.slow;
}
@override
TransactionPriority deserializeMoneroTransactionPriority({int raw}) {
return MoneroTransactionPriority.deserialize(raw: raw);
}
@override
List<TransactionPriority> getTransactionPriorities() {
return MoneroTransactionPriority.all;
}
@override
List<String> getMoneroWordList(String language) {
switch (language.toLowerCase()) {
case 'english':
@ -196,14 +204,15 @@ class CWMonero extends Monero {
}
}
@override
WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
String name,
String spendKey,
String viewKey,
String address,
String password,
String language,
int height}) {
String spendKey,
String viewKey,
String address,
String password,
String language,
int height}) {
return MoneroRestoreWalletFromKeysCredentials(
name: name,
spendKey: spendKey,
@ -214,6 +223,7 @@ class CWMonero extends Monero {
height: height);
}
@override
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic}) {
return MoneroRestoreWalletFromSeedCredentials(
name: name,
@ -222,6 +232,7 @@ class CWMonero extends Monero {
mnemonic: mnemonic);
}
@override
WalletCredentials createMoneroNewWalletCredentials({String name, String password, String language}) {
return MoneroNewWalletCredentials(
name: name,
@ -229,6 +240,7 @@ class CWMonero extends Monero {
language: language);
}
@override
Map<String, String> getKeys(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
final keys = moneroWallet.keys;
@ -239,6 +251,7 @@ class CWMonero extends Monero {
'publicViewKey': keys.publicViewKey};
}
@override
Object createMoneroTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority}) {
return MoneroTransactionCreationCredentials(
outputs: outputs.map((out) => OutputInfo(
@ -254,49 +267,72 @@ class CWMonero extends Monero {
priority: priority as MoneroTransactionPriority);
}
@override
Object createMoneroTransactionCreationCredentialsRaw({List<OutputInfo> outputs, TransactionPriority priority}) {
return MoneroTransactionCreationCredentials(
outputs: outputs,
priority: priority as MoneroTransactionPriority);
}
@override
String formatterMoneroAmountToString({int amount}) {
return moneroAmountToString(amount: amount);
}
@override
double formatterMoneroAmountToDouble({int amount}) {
return moneroAmountToDouble(amount: amount);
}
@override
int formatterMoneroParseAmount({String amount}) {
return moneroParseAmount(amount: amount);
}
@override
Account getCurrentAccount(Object wallet) {
final moneroWallet = wallet as MoneroWallet;
final acc = moneroWallet.walletAddresses.account;
return Account(id: acc.id, label: acc.label);
}
@override
void setCurrentAccount(Object wallet, int id, String label) {
final moneroWallet = wallet as MoneroWallet;
moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
}
@override
void onStartup() {
monero_wallet_api.onStartup();
}
@override
int getTransactionInfoAccountId(TransactionInfo tx) {
final moneroTransactionInfo = tx as MoneroTransactionInfo;
return moneroTransactionInfo.accountIndex;
}
@override
WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource) {
return MoneroWalletService(walletInfoSource);
}
@override
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
final moneroWallet = wallet as MoneroWallet;
return moneroWallet.getTransactionAddress(accountIndex, addressIndex);
}
@override
String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex) {
final moneroWallet = wallet as MoneroWallet;
return moneroWallet.getSubaddressLabel(accountIndex, addressIndex);
}
@override
Map<String, String> pendingTransactionInfo(Object transaction) {
final ptx = transaction as PendingMoneroTransaction;
return {'id': ptx.id, 'hex': ptx.hex, 'key': ptx.txKey};
}
}

View file

@ -222,11 +222,11 @@ abstract class SendViewModelBase with Store {
case WalletType.bitcoin:
final priority = _settingsStore.priority[_wallet.type];
return bitcoin.createBitcoinTransactionCredentials(outputs, priority);
return bitcoin.createBitcoinTransactionCredentials(outputs, priority: priority);
case WalletType.litecoin:
final priority = _settingsStore.priority[_wallet.type];
return bitcoin.createBitcoinTransactionCredentials(outputs, priority);
return bitcoin.createBitcoinTransactionCredentials(outputs, priority: priority);
case WalletType.monero:
final priority = _settingsStore.priority[_wallet.type];

View file

@ -77,7 +77,8 @@ abstract class Bitcoin {
TransactionPriority deserializeBitcoinTransactionPriority(int raw);
int getFeeRate(Object wallet, TransactionPriority priority);
Future<void> generateNewAddress(Object wallet);
Object createBitcoinTransactionCredentials(List<Output> outputs, TransactionPriority priority);
Object createBitcoinTransactionCredentials(List<Output> outputs, {TransactionPriority priority, int feeRate});
Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority priority, int feeRate});
List<String> getAddresses(Object wallet);
String getAddress(Object wallet);
@ -146,6 +147,7 @@ import 'package:cw_monero/mnemonics/spanish.dart';
import 'package:cw_monero/mnemonics/portuguese.dart';
import 'package:cw_monero/mnemonics/french.dart';
import 'package:cw_monero/mnemonics/italian.dart';
import 'package:cw_monero/pending_monero_transaction.dart';
""";
const moneroCwPart = "part 'cw_monero.dart';";
const moneroContent = """
@ -229,6 +231,7 @@ abstract class Monero {
WalletCredentials createMoneroNewWalletCredentials({String name, String password, String language});
Map<String, String> getKeys(Object wallet);
Object createMoneroTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority});
Object createMoneroTransactionCreationCredentialsRaw({List<OutputInfo> outputs, TransactionPriority priority});
String formatterMoneroAmountToString({int amount});
double formatterMoneroAmountToDouble({int amount});
int formatterMoneroParseAmount({String amount});
@ -237,6 +240,7 @@ abstract class Monero {
void onStartup();
int getTransactionInfoAccountId(TransactionInfo tx);
WalletService createMoneroWalletService(Box<WalletInfo> walletInfoSource);
Map<String, String> pendingTransactionInfo(Object transaction);
}
abstract class MoneroSubaddressList {