BTC Testnet
This commit is contained in:
parent
0b1f2447be
commit
2efa5dfa21
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
44
idl/data.fbs
44
idl/data.fbs
|
@ -47,7 +47,7 @@ table ShieldedTx {
|
|||
short_tx_id:string;
|
||||
timestamp:uint32;
|
||||
name:string;
|
||||
value:uint64;
|
||||
value:int64;
|
||||
address:string;
|
||||
memo:string;
|
||||
}
|
||||
|
@ -56,6 +56,48 @@ table ShieldedTxVec {
|
|||
txs:[ShieldedTx];
|
||||
}
|
||||
|
||||
table PlainTx {
|
||||
id:uint32;
|
||||
tx_id:string;
|
||||
height:uint32;
|
||||
timestamp:uint32;
|
||||
value:int64;
|
||||
}
|
||||
|
||||
table PlainTxVec {
|
||||
txs:[PlainTx];
|
||||
}
|
||||
|
||||
table PlainNote {
|
||||
id:uint32;
|
||||
tx_id:string;
|
||||
height:uint32;
|
||||
timestamp:uint32;
|
||||
vout:uint32;
|
||||
value:uint64;
|
||||
}
|
||||
|
||||
table PlainNoteVec {
|
||||
notes:[PlainNote];
|
||||
}
|
||||
|
||||
table BTCInput {
|
||||
tx_id:string;
|
||||
vout:uint32;
|
||||
value:uint64;
|
||||
}
|
||||
|
||||
table BTCOutput {
|
||||
script_pubkey:string;
|
||||
value:uint64;
|
||||
}
|
||||
|
||||
table BTCTx {
|
||||
txins:[BTCInput];
|
||||
txouts:[BTCOutput];
|
||||
fee:uint64;
|
||||
}
|
||||
|
||||
table Message {
|
||||
id_msg:uint32;
|
||||
id_tx:uint32;
|
||||
|
|
|
@ -25,6 +25,11 @@ class _AccountState extends State<AccountPage>
|
|||
@override
|
||||
bool get wantKeepAlive => true; //Set to true
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (!_hasAddress(active.addrMode)) active.addrMode = _getNextMode();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
|
@ -182,7 +187,7 @@ class QRAddressState extends State<QRAddressWidget> {
|
|||
final simpleMode = settings.simpleMode;
|
||||
final address = _address();
|
||||
final shortAddress = centerTrim(address);
|
||||
final addrMode = active.addrMode;
|
||||
var addrMode = active.addrMode;
|
||||
final qrSize = getScreenSize(context) / 2.5;
|
||||
final coinDef = active.coinDef;
|
||||
final nextMode = _getNextMode();
|
||||
|
@ -199,7 +204,7 @@ class QRAddressState extends State<QRAddressWidget> {
|
|||
child: QrImage(
|
||||
data: address,
|
||||
size: qrSize,
|
||||
embeddedImage: coinDef.image,
|
||||
embeddedImage: AssetImage(coinDef.image),
|
||||
backgroundColor: Colors.white))),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 8)),
|
||||
RichText(
|
||||
|
@ -338,24 +343,6 @@ class QRAddressState extends State<QRAddressWidget> {
|
|||
}
|
||||
}
|
||||
|
||||
int _getNextMode() {
|
||||
int next = active.addrMode;
|
||||
do {
|
||||
next = (next + 1) % 3;
|
||||
switch (next) {
|
||||
case 0:
|
||||
return next;
|
||||
case 1: // we have orchard -> show zaddr
|
||||
if (addrsAvailable & 4 != 0) return next;
|
||||
break;
|
||||
case 2: // we have taddr -> show taddr
|
||||
if (addrsAvailable & 1 != 0) return next;
|
||||
break;
|
||||
}
|
||||
} while (next != active.addrMode);
|
||||
return 0; // unreachable
|
||||
}
|
||||
|
||||
String? _getTapMessage(int mode) {
|
||||
final s = S.of(context);
|
||||
switch (mode) {
|
||||
|
@ -519,3 +506,24 @@ _getBalanceHi(int b) => decimalFormat((b.abs() ~/ 100000) / 1000.0, 3);
|
|||
_getBalanceLo(int b) => (b.abs() % 100000).toString().padLeft(5, '0');
|
||||
|
||||
_sign(int b) => b < 0 ? '-' : '+';
|
||||
|
||||
bool _hasAddress(int mode) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return active.availabeAddrs & 2 != 0;
|
||||
case 1:
|
||||
return active.availabeAddrs & 4 != 0;
|
||||
case 2:
|
||||
return active.availabeAddrs & 1 != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int _getNextMode() {
|
||||
int next = active.addrMode;
|
||||
do {
|
||||
next = (next + 1) % 3;
|
||||
if (_hasAddress(next)) return next;
|
||||
} while (next != active.addrMode);
|
||||
return 0; // unreachable
|
||||
}
|
||||
|
|
|
@ -80,15 +80,16 @@ class AccountManagerState extends State<AccountManagerPage> {
|
|||
break;
|
||||
}
|
||||
final weight = a.active ? FontWeight.bold : FontWeight.normal;
|
||||
final def = settings.coins[a.coin].def;
|
||||
final zbal = a.balance / ZECUNIT;
|
||||
final tbal = a.tbalance / ZECUNIT;
|
||||
final tbal = def.coin < 2 ? a.tbalance / ZECUNIT : 0.0;
|
||||
final balance = zbal + tbal;
|
||||
return Card(
|
||||
child: Dismissible(
|
||||
key: Key(a.name),
|
||||
child: ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: settings.coins[a.coin].def.image),
|
||||
leading:
|
||||
CircleAvatar(backgroundImage: AssetImage(def.image)),
|
||||
title: RichText(
|
||||
text: TextSpan(children: [
|
||||
TextSpan(
|
||||
|
|
|
@ -162,6 +162,8 @@ abstract class _ActiveAccount with Store {
|
|||
return AccountId(coin, id);
|
||||
}
|
||||
|
||||
bool get isPrivate => coin < 2;
|
||||
|
||||
@action
|
||||
Future<void> restore() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
@ -234,7 +236,7 @@ abstract class _ActiveAccount with Store {
|
|||
@action
|
||||
void updateTBalance() {
|
||||
try {
|
||||
tbalance = WarpApi.getTBalance();
|
||||
tbalance = WarpApi.getTBalance(active.coin, active.id);
|
||||
} on String {}
|
||||
}
|
||||
|
||||
|
@ -368,13 +370,15 @@ abstract class _ActiveAccount with Store {
|
|||
|
||||
@action
|
||||
void excludeNote(Note note) {
|
||||
WarpApi.updateExcluded(coin, note.id, note.excluded);
|
||||
if (active.isPrivate) WarpApi.updateExcluded(coin, note.id, note.excluded);
|
||||
}
|
||||
|
||||
@action
|
||||
void invertExcludedNotes() {
|
||||
WarpApi.invertExcluded(coin, id);
|
||||
notes = notes.map((n) => n.invertExcluded).toList();
|
||||
if (active.isPrivate) {
|
||||
WarpApi.invertExcluded(coin, id);
|
||||
notes = notes.map((n) => n.invertExcluded).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
122
lib/budget.dart
122
lib/budget.dart
|
@ -31,22 +31,26 @@ class BudgetState extends State<BudgetWidget>
|
|||
final _ = active.dataEpoch;
|
||||
return Column(
|
||||
children: [
|
||||
Card(
|
||||
child: Column(children: [
|
||||
Text(S.of(context).largestSpendingsByAddress,
|
||||
style: Theme.of(context).textTheme.titleLarge),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
BudgetChart(),
|
||||
])),
|
||||
if (active.isPrivate)
|
||||
Card(
|
||||
child: Column(children: [
|
||||
Text(S.of(context).largestSpendingsByAddress,
|
||||
style: Theme.of(context).textTheme.titleLarge),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
BudgetChart(),
|
||||
])),
|
||||
Expanded(
|
||||
child: Card(
|
||||
child: Column(children: [
|
||||
Text(S.of(context).accountBalanceHistory,
|
||||
style: Theme.of(context).textTheme.titleLarge),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
Expanded(child: Padding(padding: EdgeInsets.only(right: 20),
|
||||
child: LineChartTimeSeries.fromTimeSeries(active.accountBalances)))
|
||||
]))),
|
||||
Text(S.of(context).accountBalanceHistory,
|
||||
style: Theme.of(context).textTheme.titleLarge),
|
||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 20),
|
||||
child: LineChartTimeSeries.fromTimeSeries(
|
||||
active.accountBalances)))
|
||||
]))),
|
||||
],
|
||||
);
|
||||
}));
|
||||
|
@ -67,27 +71,31 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
|
|||
super.build(context);
|
||||
return IconTheme.merge(
|
||||
data: IconThemeData(opacity: 0.54),
|
||||
child:
|
||||
Column(children: [
|
||||
child: Column(children: [
|
||||
Row(children: [
|
||||
Expanded(child:
|
||||
FormBuilderRadioGroup(
|
||||
orientation: OptionsOrientation.horizontal,
|
||||
name: S.of(context).pnl,
|
||||
initialValue: active.pnlSeriesIndex,
|
||||
onChanged: (int? v) {
|
||||
setState(() {
|
||||
active.setPnlSeriesIndex(v!);
|
||||
});
|
||||
},
|
||||
options: [
|
||||
FormBuilderFieldOption(child: Text(S.of(context).price), value: 0),
|
||||
Expanded(
|
||||
child: FormBuilderRadioGroup(
|
||||
orientation: OptionsOrientation.horizontal,
|
||||
name: S.of(context).pnl,
|
||||
initialValue: active.pnlSeriesIndex,
|
||||
onChanged: (int? v) {
|
||||
setState(() {
|
||||
active.setPnlSeriesIndex(v!);
|
||||
});
|
||||
},
|
||||
options: [
|
||||
FormBuilderFieldOption(
|
||||
child: Text(S.of(context).price), value: 0),
|
||||
FormBuilderFieldOption(
|
||||
child: Text(S.of(context).realized), value: 1),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).mm), value: 2),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).total), value: 3),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).qty), value: 4),
|
||||
FormBuilderFieldOption(child: Text(S.of(context).table), value: 5),
|
||||
FormBuilderFieldOption(
|
||||
child: Text(S.of(context).mm), value: 2),
|
||||
FormBuilderFieldOption(
|
||||
child: Text(S.of(context).total), value: 3),
|
||||
FormBuilderFieldOption(
|
||||
child: Text(S.of(context).qty), value: 4),
|
||||
FormBuilderFieldOption(
|
||||
child: Text(S.of(context).table), value: 5),
|
||||
])),
|
||||
IconButton(onPressed: _onExport, icon: Icon(Icons.save)),
|
||||
]),
|
||||
|
@ -97,21 +105,23 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
|
|||
child: Padding(
|
||||
padding: EdgeInsets.only(right: 20),
|
||||
child: active.pnlSeriesIndex != 5
|
||||
? PnLChart(
|
||||
active.pnls, active.pnlSeriesIndex)
|
||||
? PnLChart(active.pnls, active.pnlSeriesIndex)
|
||||
: PnLTable()));
|
||||
})
|
||||
]));
|
||||
}
|
||||
|
||||
_onExport() async {
|
||||
final csvData = active.pnlSorted.map((pnl) => [
|
||||
pnl.timestamp,
|
||||
pnl.amount,
|
||||
pnl.price,
|
||||
pnl.realized,
|
||||
pnl.unrealized,
|
||||
pnl.realized + pnl.unrealized]).toList();
|
||||
final csvData = active.pnlSorted
|
||||
.map((pnl) => [
|
||||
pnl.timestamp,
|
||||
pnl.amount,
|
||||
pnl.price,
|
||||
pnl.realized,
|
||||
pnl.unrealized,
|
||||
pnl.realized + pnl.unrealized
|
||||
])
|
||||
.toList();
|
||||
await shareCsv(csvData, 'pnl_history.csv', S.of(context).pnlHistory);
|
||||
}
|
||||
}
|
||||
|
@ -148,8 +158,8 @@ class PnLChart extends StatelessWidget {
|
|||
List<PnL> data, int index, BuildContext context) {
|
||||
return data
|
||||
.map((pnl) => TimeSeriesPoint(
|
||||
pnl.timestamp.millisecondsSinceEpoch ~/ DAY_MS,
|
||||
_seriesData(pnl, index)))
|
||||
pnl.timestamp.millisecondsSinceEpoch ~/ DAY_MS,
|
||||
_seriesData(pnl, index)))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
@ -227,10 +237,13 @@ class BudgetChartState extends State<BudgetChart> {
|
|||
return Observer(
|
||||
builder: (context) => Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||
HorizontalBarChart(active.spendings.map((s) => s.amount / ZECUNIT).toList()),
|
||||
BudgetTable(active.spendings)
|
||||
])));
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
HorizontalBarChart(
|
||||
active.spendings.map((s) => s.amount / ZECUNIT).toList()),
|
||||
BudgetTable(active.spendings)
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,17 +254,24 @@ class BudgetTable extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final palette = getPalette(Theme.of(context).primaryColor, spendings.length);
|
||||
final palette =
|
||||
getPalette(Theme.of(context).primaryColor, spendings.length);
|
||||
final rows = spendings.asMap().entries.map((e) {
|
||||
final style = TextStyle(color: palette[e.key], fontFeatures: [FontFeature.tabularFigures()]);
|
||||
final style = TextStyle(
|
||||
color: palette[e.key], fontFeatures: [FontFeature.tabularFigures()]);
|
||||
final recipient = e.value.recipient!;
|
||||
return TableRow(children: [
|
||||
Text(recipient, style: style, maxLines: 1, overflow: TextOverflow.ellipsis,),
|
||||
Text(
|
||||
recipient,
|
||||
style: style,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(decimalFormat(e.value.amount / ZECUNIT, 8), style: style)
|
||||
]);
|
||||
}).toList();
|
||||
return Table(
|
||||
columnWidths: { 0: FlexColumnWidth(), 1: IntrinsicColumnWidth() },
|
||||
children: rows);
|
||||
columnWidths: {0: FlexColumnWidth(), 1: IntrinsicColumnWidth()},
|
||||
children: rows);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import "coin.dart";
|
||||
|
||||
class BTCCoin extends CoinBase {
|
||||
int coin = 2;
|
||||
bool transparentOnly = true;
|
||||
String name = "Bitcoin";
|
||||
String symbol = "\u20BF";
|
||||
String currency = "bitcoin";
|
||||
int coinIndex = 0;
|
||||
String ticker = "BTC";
|
||||
String dbName = "btc.db";
|
||||
String image = 'assets/bitcoin.png';
|
||||
List<LWInstance> lwd = [
|
||||
LWInstance("Blockstream", "tcp://blackie.c3-soft.com:57005")
|
||||
];
|
||||
bool supportsUA = false;
|
||||
bool supportsMultisig = false;
|
||||
List<double> weights = [0.001, 0.01, 0.1];
|
||||
List<String> blockExplorers = ["https://blockstream.info/testnet/tx"];
|
||||
bool supportsLedger = false;
|
||||
}
|
|
@ -16,12 +16,11 @@ class LWInstance {
|
|||
abstract class CoinBase {
|
||||
String get name;
|
||||
int get coin;
|
||||
String get app;
|
||||
String get symbol;
|
||||
String get currency;
|
||||
String get ticker;
|
||||
int get coinIndex;
|
||||
AssetImage get image;
|
||||
String get image;
|
||||
String get dbName;
|
||||
late String dbDir;
|
||||
late String dbFullPath;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import 'coin.dart';
|
||||
import 'ycash.dart';
|
||||
import 'zcash.dart';
|
||||
import 'zcashtest.dart';
|
||||
import 'btc.dart';
|
||||
|
||||
CoinBase ycash = YcashCoin();
|
||||
CoinBase zcash = ZcashCoin();
|
||||
CoinBase zcashtest = ZcashTestCoin();
|
||||
|
||||
final coins = [zcash, ycash];
|
||||
CoinBase btc = BTCCoin();
|
||||
|
||||
final coins = [zcash, ycash, btc];
|
||||
|
|
|
@ -5,13 +5,12 @@ import "coin.dart";
|
|||
class YcashCoin extends CoinBase {
|
||||
int coin = 1;
|
||||
String name = "Ycash";
|
||||
String app = "YWallet";
|
||||
String symbol = "\u24E8";
|
||||
String currency = "ycash";
|
||||
int coinIndex = 347;
|
||||
String ticker = "YEC";
|
||||
String dbName = "yec.db";
|
||||
AssetImage image = AssetImage('assets/ycash.png');
|
||||
String image = 'assets/ycash.png';
|
||||
List<LWInstance> lwd = [
|
||||
LWInstance("Lightwalletd", "https://lite.ycash.xyz:9067"),
|
||||
];
|
||||
|
|
|
@ -5,13 +5,12 @@ import 'coin.dart';
|
|||
class ZcashCoin extends CoinBase {
|
||||
int coin = 0;
|
||||
String name = "Zcash";
|
||||
String app = "ZWallet";
|
||||
String symbol = "\u24E9";
|
||||
String currency = "zcash";
|
||||
int coinIndex = 133;
|
||||
String ticker = "ZEC";
|
||||
String dbName = "zec.db";
|
||||
AssetImage image = AssetImage('assets/zcash.png');
|
||||
String image = 'assets/zcash.png';
|
||||
List<LWInstance> lwd = [
|
||||
LWInstance("Lightwalletd", "https://mainnet.lightwalletd.com:9067"),
|
||||
LWInstance("Zecwallet", "https://lwdv3.zecwallet.co"),
|
||||
|
|
|
@ -5,13 +5,12 @@ import 'coin.dart';
|
|||
class ZcashTestCoin extends CoinBase {
|
||||
int coin = 0;
|
||||
String name = "Zcash Test";
|
||||
String app = "ZWallet";
|
||||
String symbol = "\u24E9";
|
||||
String currency = "zcash";
|
||||
int coinIndex = 133;
|
||||
String ticker = "ZEC";
|
||||
String dbName = "zec-test.db";
|
||||
AssetImage image = AssetImage('assets/zcash.png');
|
||||
String image = 'assets/zcash.png';
|
||||
List<LWInstance> lwd = [
|
||||
LWInstance("Lightwalletd", "https://testnet.lightwalletd.com:9067"),
|
||||
];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
|
@ -8,6 +9,7 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
import 'package:warp_api/data_fb_generated.dart';
|
||||
import 'package:warp_api/warp_api.dart';
|
||||
import 'package:badges/badges.dart' as Badges;
|
||||
|
@ -112,13 +114,34 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
TabController? _tabController;
|
||||
int _tabIndex = 0;
|
||||
final contactKey = GlobalKey<ContactsState>();
|
||||
List<String> tabsShown = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (Platform.isAndroid) _initForegroundTask();
|
||||
final tabController =
|
||||
TabController(length: settings.simpleMode ? 4 : 7, vsync: this);
|
||||
var tabs = {
|
||||
// order is guaranteed by dart
|
||||
"account": true,
|
||||
"messages": true,
|
||||
"notes": false,
|
||||
"history": true,
|
||||
"budget": false,
|
||||
"pnl": false,
|
||||
"contacts": true,
|
||||
};
|
||||
if (!settings.simpleMode) {
|
||||
tabs["notes"] = true;
|
||||
tabs["budget"] = true;
|
||||
tabs["pnl"] = true;
|
||||
}
|
||||
if (!active.isPrivate) {
|
||||
tabs["messages"] = false;
|
||||
tabs["contacts"] = false;
|
||||
}
|
||||
tabsShown =
|
||||
tabs.entries.where((kv) => kv.value).map((kv) => kv.key).toList();
|
||||
final tabController = TabController(length: tabsShown.length, vsync: this);
|
||||
tabController.addListener(() {
|
||||
setState(() {
|
||||
_tabIndex = tabController.index;
|
||||
|
@ -133,7 +156,8 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
final theme = Theme.of(context);
|
||||
final simpleMode = settings.simpleMode;
|
||||
|
||||
final contactTabIndex = simpleMode ? 3 : 6;
|
||||
final contactTabIndex = tabsShown.indexOf("contacts");
|
||||
final messageTabIndex = tabsShown.indexOf("messages");
|
||||
Widget button = Container();
|
||||
if (_tabIndex == 0)
|
||||
button = FloatingActionButton(
|
||||
|
@ -147,7 +171,7 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
backgroundColor: theme.colorScheme.secondary,
|
||||
child: Icon(Icons.add),
|
||||
);
|
||||
else if (_tabIndex == 1)
|
||||
else if (_tabIndex == messageTabIndex)
|
||||
button = FloatingActionButton(
|
||||
onPressed: _onSend,
|
||||
backgroundColor: theme.colorScheme.secondary,
|
||||
|
@ -184,13 +208,15 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
return SizedBox(); // Show a placeholder
|
||||
}
|
||||
|
||||
final privateCoin = active.isPrivate;
|
||||
|
||||
final menu = PopupMenuButton<String>(
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
PopupMenuItem(child: Text(s.accounts), value: "Accounts"),
|
||||
PopupMenuItem(child: Text(s.backup), value: "Backup"),
|
||||
PopupMenuItem(child: Text(rescanMsg), value: "Rescan"),
|
||||
if (!simpleMode)
|
||||
if (!simpleMode && privateCoin)
|
||||
PopupMenuItem(child: Text(s.pools), value: "Pools"),
|
||||
if (!simpleMode)
|
||||
PopupMenuItem(
|
||||
|
@ -216,18 +242,18 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
child: Text(s.broadcast), value: "Broadcast"),
|
||||
PopupMenuItem(
|
||||
child: Text(s.multipay), value: "MultiPay"),
|
||||
PopupMenuItem(
|
||||
child: Text(s.keyTool),
|
||||
enabled: active.canPay,
|
||||
value: "KeyTool"),
|
||||
PopupMenuItem(
|
||||
child: Text(s.sweep),
|
||||
enabled: active.canPay,
|
||||
value: "Sweep"),
|
||||
if (privateCoin)
|
||||
PopupMenuItem(
|
||||
child: Text(s.keyTool),
|
||||
enabled: active.canPay,
|
||||
value: "KeyTool"),
|
||||
if (privateCoin)
|
||||
PopupMenuItem(
|
||||
child: Text(s.sweep),
|
||||
enabled: active.canPay,
|
||||
value: "Sweep"),
|
||||
],
|
||||
onSelected: _onMenu)),
|
||||
// if (!simpleMode && !isMobile())
|
||||
// PopupMenuItem(child: Text(s.ledger), value: "Ledger"),
|
||||
if (settings.isDeveloper)
|
||||
PopupMenuItem(child: Text(s.expert), value: "Expert"),
|
||||
PopupMenuItem(child: Text(s.settings), value: "Settings"),
|
||||
|
@ -252,12 +278,12 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
isScrollable: true,
|
||||
tabs: [
|
||||
Tab(text: s.account),
|
||||
messageTab,
|
||||
if (!simpleMode) Tab(text: s.notes),
|
||||
Tab(text: s.history),
|
||||
if (!simpleMode) Tab(text: s.budget),
|
||||
if (!simpleMode) Tab(text: s.tradingPl),
|
||||
Tab(text: s.contacts),
|
||||
if (tabsShown.contains("messages")) messageTab,
|
||||
if (tabsShown.contains("notes")) Tab(text: s.notes),
|
||||
if (tabsShown.contains("history")) Tab(text: s.history),
|
||||
if (tabsShown.contains("budget")) Tab(text: s.budget),
|
||||
if (tabsShown.contains("pnl")) Tab(text: s.tradingPl),
|
||||
if (tabsShown.contains("contacts")) Tab(text: s.contacts),
|
||||
],
|
||||
),
|
||||
actions: [menu],
|
||||
|
@ -266,12 +292,12 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
controller: _tabController,
|
||||
children: [
|
||||
AccountPage(),
|
||||
MessageWidget(messageKey),
|
||||
if (!simpleMode) NoteWidget(),
|
||||
HistoryWidget(),
|
||||
if (!simpleMode) BudgetWidget(),
|
||||
if (!simpleMode) PnLWidget(),
|
||||
ContactsTab(key: contactKey),
|
||||
if (tabsShown.contains("messages")) MessageWidget(messageKey),
|
||||
if (tabsShown.contains("notes")) NoteWidget(),
|
||||
if (tabsShown.contains("history")) HistoryWidget(),
|
||||
if (tabsShown.contains("budget")) BudgetWidget(),
|
||||
if (tabsShown.contains("pnl")) PnLWidget(),
|
||||
if (tabsShown.contains("contacts")) ContactsTab(key: contactKey),
|
||||
],
|
||||
),
|
||||
floatingActionButton: button,
|
||||
|
@ -492,7 +518,7 @@ class HomeInnerState extends State<HomeInnerPage>
|
|||
|
||||
if (rawTx != null) {
|
||||
try {
|
||||
final res = WarpApi.broadcast(rawTx);
|
||||
final res = WarpApi.broadcast(active.coin, rawTx);
|
||||
showSnackBar(res);
|
||||
} on String catch (e) {
|
||||
showSnackBar(e, error: true);
|
||||
|
|
|
@ -12,12 +12,17 @@ class NoteWidget extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Observer(builder: (context) {
|
||||
switch (settings.noteView) {
|
||||
case ViewStyle.Table: return NoteTable();
|
||||
case ViewStyle.List: return NoteList();
|
||||
case ViewStyle.Auto: return OrientationBuilder(builder: (context, orientation) {
|
||||
if (orientation == Orientation.portrait) return NoteList();
|
||||
else return NoteTable();
|
||||
});
|
||||
case ViewStyle.Table:
|
||||
return NoteTable();
|
||||
case ViewStyle.List:
|
||||
return NoteList();
|
||||
case ViewStyle.Auto:
|
||||
return OrientationBuilder(builder: (context, orientation) {
|
||||
if (orientation == Orientation.portrait)
|
||||
return NoteList();
|
||||
else
|
||||
return NoteTable();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -30,7 +35,8 @@ class NoteTable extends StatefulWidget {
|
|||
State<StatefulWidget> createState() => _NoteTableState();
|
||||
}
|
||||
|
||||
class _NoteTableState extends State<NoteTable> with AutomaticKeepAliveClientMixin {
|
||||
class _NoteTableState extends State<NoteTable>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
bool get wantKeepAlive => true; //Set to true
|
||||
|
||||
|
@ -77,7 +83,9 @@ class _NoteTableState extends State<NoteTable> with AutomaticKeepAliveClientMixi
|
|||
header: Text(S.of(context).selectNotesToExcludeFromPayments,
|
||||
style: Theme.of(context).textTheme.bodyMedium),
|
||||
actions: [
|
||||
IconButton(onPressed: _selectInverse, icon: Icon(MdiIcons.selectInverse)),
|
||||
IconButton(
|
||||
onPressed: _selectInverse,
|
||||
icon: Icon(MdiIcons.selectInverse)),
|
||||
],
|
||||
columnSpacing: 16,
|
||||
showCheckboxColumn: false,
|
||||
|
@ -93,6 +101,7 @@ class _NoteTableState extends State<NoteTable> with AutomaticKeepAliveClientMixi
|
|||
}
|
||||
|
||||
_onRowSelected(Note note) {
|
||||
if (!active.isPrivate) return;
|
||||
active.excludeNote(note);
|
||||
}
|
||||
|
||||
|
@ -121,8 +130,7 @@ class NotesDataSource extends DataTableSource {
|
|||
|
||||
if (note.spent)
|
||||
style = style.merge(TextStyle(decoration: TextDecoration.lineThrough));
|
||||
if (note.orchard)
|
||||
style = style.merge(TextStyle(color: theme.primaryColor));
|
||||
if (note.orchard) style = style.merge(TextStyle(color: theme.primaryColor));
|
||||
|
||||
final amountStyle = weightFromAmount(style, note.value);
|
||||
|
||||
|
@ -135,7 +143,8 @@ class NotesDataSource extends DataTableSource {
|
|||
: theme.colorScheme.background),
|
||||
cells: [
|
||||
DataCell(Text("$confsOrHeight", style: style)),
|
||||
DataCell(Text("${noteDateFormat.format(note.timestamp)}", style: style)),
|
||||
DataCell(
|
||||
Text("${noteDateFormat.format(note.timestamp)}", style: style)),
|
||||
DataCell(Text(decimalFormat(note.value, 8), style: amountStyle)),
|
||||
],
|
||||
onSelectChanged: (selected) => _noteSelected(note, selected),
|
||||
|
@ -152,6 +161,7 @@ class NotesDataSource extends DataTableSource {
|
|||
int get selectedRowCount => 0;
|
||||
|
||||
void _noteSelected(Note note, bool? selected) {
|
||||
if (!active.isPrivate) return;
|
||||
note.excluded = !note.excluded;
|
||||
notifyListeners();
|
||||
onRowSelected(note);
|
||||
|
@ -170,21 +180,24 @@ class NoteListState extends State<NoteList> with AutomaticKeepAliveClientMixin {
|
|||
final s = S.of(context);
|
||||
return Observer(builder: (context) {
|
||||
final notes = active.sortedNotes;
|
||||
return Padding(padding: EdgeInsets.all(16), child: CustomScrollView(
|
||||
key: UniqueKey(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(child: ListTile(
|
||||
onTap: _onInvert,
|
||||
title: Text(s.selectNotesToExcludeFromPayments),
|
||||
trailing: Icon(Icons.select_all),
|
||||
)),
|
||||
SliverFixedExtentList(
|
||||
itemExtent: 50,
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return NoteItem(notes[index], index);
|
||||
}, childCount: notes.length))
|
||||
],
|
||||
));
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: CustomScrollView(
|
||||
key: UniqueKey(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: ListTile(
|
||||
onTap: _onInvert,
|
||||
title: Text(s.selectNotesToExcludeFromPayments),
|
||||
trailing: Icon(Icons.select_all),
|
||||
)),
|
||||
SliverFixedExtentList(
|
||||
itemExtent: 50,
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return NoteItem(notes[index], index);
|
||||
}, childCount: notes.length))
|
||||
],
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -225,24 +238,33 @@ class NoteItemState extends State<NoteItem> {
|
|||
style = style.merge(TextStyle(color: style.color!.withOpacity(0.5)));
|
||||
if (note.spent)
|
||||
style = style.merge(TextStyle(decoration: TextDecoration.lineThrough));
|
||||
if (note.orchard)
|
||||
style = style.merge(TextStyle(color: theme.primaryColor));
|
||||
if (note.orchard) style = style.merge(TextStyle(color: theme.primaryColor));
|
||||
|
||||
final amountStyle = weightFromAmount(style, note.value);
|
||||
|
||||
return GestureDetector(onTap: _onSelected, behavior: HitTestBehavior.opaque, child:
|
||||
ColoredBox(color: excluded ? theme.primaryColor.withOpacity(0.5) : theme.colorScheme.background, child:
|
||||
Padding(padding: EdgeInsets.all(8), child:
|
||||
Row(children: [
|
||||
Column(children: [Text("${note.height}", style: theme.textTheme.bodySmall),
|
||||
Text("$confirmations", style: theme.textTheme.bodyMedium),
|
||||
]),
|
||||
Expanded(child: Center(child: Text("${note.value}", style: amountStyle))),
|
||||
Text("$timestamp"),
|
||||
]))));
|
||||
return GestureDetector(
|
||||
onTap: _onSelected,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: ColoredBox(
|
||||
color: excluded
|
||||
? theme.primaryColor.withOpacity(0.5)
|
||||
: theme.colorScheme.background,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8),
|
||||
child: Row(children: [
|
||||
Column(children: [
|
||||
Text("${note.height}", style: theme.textTheme.bodySmall),
|
||||
Text("$confirmations", style: theme.textTheme.bodyMedium),
|
||||
]),
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text("${note.value}", style: amountStyle))),
|
||||
Text("$timestamp"),
|
||||
]))));
|
||||
}
|
||||
|
||||
_onSelected() {
|
||||
if (!active.isPrivate) return;
|
||||
setState(() {
|
||||
excluded = !excluded;
|
||||
widget.note.excluded = excluded;
|
||||
|
@ -254,4 +276,3 @@ class NoteItemState extends State<NoteItem> {
|
|||
bool confirmed(int height) {
|
||||
return syncStatus.latestHeight - height >= settings.anchorOffset;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ final rescanKey = GlobalKey<RescanFormState>();
|
|||
|
||||
Future<int?> rescanDialog(BuildContext context) async {
|
||||
try {
|
||||
if (active.coin >= 2) return 0;
|
||||
DateTime minDate = WarpApi.getActivationDate();
|
||||
final bool approved = await showDialog<bool>(
|
||||
context: context,
|
||||
|
|
|
@ -36,6 +36,14 @@ class _AddAccountPageState extends State<AddAccountPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final s = S.of(context);
|
||||
|
||||
final options = coins
|
||||
.map((c) => FormBuilderFieldOption(
|
||||
child: ListTile(
|
||||
title: Text(c.name),
|
||||
trailing: Image.asset(c.image, height: 32)),
|
||||
value: c.coin))
|
||||
.toList();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(s.newAccount),
|
||||
|
@ -70,22 +78,7 @@ class _AddAccountPageState extends State<AddAccountPage> {
|
|||
_coin = v!;
|
||||
});
|
||||
},
|
||||
options: [
|
||||
FormBuilderFieldOption(
|
||||
child: ListTile(
|
||||
title: Text('Ycash'),
|
||||
trailing: Image.asset(
|
||||
'assets/ycash.png',
|
||||
height: 32)),
|
||||
value: 1),
|
||||
FormBuilderFieldOption(
|
||||
child: ListTile(
|
||||
title: Text('Zcash'),
|
||||
trailing: Image.asset(
|
||||
'assets/zcash.png',
|
||||
height: 32)),
|
||||
value: 0),
|
||||
]),
|
||||
options: options),
|
||||
FormBuilderCheckbox(
|
||||
name: 'restore',
|
||||
title: Text(s.restoreAnAccount),
|
||||
|
|
119
lib/send.dart
119
lib/send.dart
|
@ -101,8 +101,10 @@ class SendState extends State<SendPage> {
|
|||
_setPaymentURI(uri);
|
||||
});
|
||||
|
||||
final templateIds = active.dbReader.loadTemplates();
|
||||
_templates = templateIds;
|
||||
if (active.isPrivate) {
|
||||
final templateIds = active.dbReader.loadTemplates();
|
||||
_templates = templateIds;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -214,64 +216,67 @@ class SendState extends State<SendPage> {
|
|||
if (!simpleMode)
|
||||
BalanceTable(_sBalance, _tBalance, _excludedBalance,
|
||||
_underConfirmedBalance, change, _usedBalance, _fee),
|
||||
Container(
|
||||
child: InputDecorator(
|
||||
decoration: InputDecoration(labelText: s.memo),
|
||||
child: Column(children: [
|
||||
FormBuilderCheckbox(
|
||||
key: UniqueKey(),
|
||||
name: 'reply-to',
|
||||
title: Text(s.includeReplyTo),
|
||||
initialValue: _replyTo,
|
||||
if (active.isPrivate)
|
||||
Container(
|
||||
child: InputDecorator(
|
||||
decoration: InputDecoration(labelText: s.memo),
|
||||
child: Column(children: [
|
||||
FormBuilderCheckbox(
|
||||
key: UniqueKey(),
|
||||
name: 'reply-to',
|
||||
title: Text(s.includeReplyTo),
|
||||
initialValue: _replyTo,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_replyTo = v ?? false;
|
||||
});
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: s.subject),
|
||||
controller: _subjectController,
|
||||
),
|
||||
TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: s.body),
|
||||
minLines: 4,
|
||||
maxLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
controller: _memoController,
|
||||
)
|
||||
]))),
|
||||
Padding(padding: EdgeInsets.all(8)),
|
||||
if (active.isPrivate)
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: DropdownButtonFormField<SendTemplateT>(
|
||||
hint: Text(s.template),
|
||||
items: templates,
|
||||
value: _template,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_replyTo = v ?? false;
|
||||
_template = v;
|
||||
});
|
||||
},
|
||||
),
|
||||
TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: s.subject),
|
||||
controller: _subjectController,
|
||||
),
|
||||
TextFormField(
|
||||
decoration:
|
||||
InputDecoration(labelText: s.body),
|
||||
minLines: 4,
|
||||
maxLines: null,
|
||||
keyboardType: TextInputType.multiline,
|
||||
controller: _memoController,
|
||||
)
|
||||
]))),
|
||||
Padding(padding: EdgeInsets.all(8)),
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: DropdownButtonFormField<SendTemplateT>(
|
||||
hint: Text(s.template),
|
||||
items: templates,
|
||||
value: _template,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_template = v;
|
||||
});
|
||||
})),
|
||||
addReset,
|
||||
IconButton(
|
||||
onPressed: _template != null ? _openTemplate : null,
|
||||
icon: Icon(Icons.open_in_new)),
|
||||
IconButton(
|
||||
onPressed: _template != null
|
||||
? () {
|
||||
_saveTemplate(
|
||||
_template!.id, _template!.title!, true);
|
||||
}
|
||||
: null,
|
||||
icon: Icon(Icons.save)),
|
||||
IconButton(
|
||||
onPressed:
|
||||
_template != null ? _deleteTemplate : null,
|
||||
icon: Icon(Icons.delete)),
|
||||
]),
|
||||
})),
|
||||
addReset,
|
||||
IconButton(
|
||||
onPressed:
|
||||
_template != null ? _openTemplate : null,
|
||||
icon: Icon(Icons.open_in_new)),
|
||||
IconButton(
|
||||
onPressed: _template != null
|
||||
? () {
|
||||
_saveTemplate(_template!.id,
|
||||
_template!.title!, true);
|
||||
}
|
||||
: null,
|
||||
icon: Icon(Icons.save)),
|
||||
IconButton(
|
||||
onPressed:
|
||||
_template != null ? _deleteTemplate : null,
|
||||
icon: Icon(Icons.delete)),
|
||||
]),
|
||||
Padding(padding: EdgeInsets.all(8)),
|
||||
ButtonBar(children: [
|
||||
ElevatedButton.icon(
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:json_annotation/json_annotation.dart';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
import 'package:queue/queue.dart';
|
||||
import 'package:shared_preferences_android/shared_preferences_android.dart';
|
||||
import 'package:shared_preferences_ios/shared_preferences_ios.dart';
|
||||
|
@ -21,6 +22,7 @@ import 'package:flex_color_scheme/flex_color_scheme.dart';
|
|||
import 'package:sensors_plus/sensors_plus.dart';
|
||||
|
||||
import 'coin/coin.dart';
|
||||
import 'coin/coins.dart' as Coins;
|
||||
import 'generated/l10n.dart';
|
||||
import 'main.dart';
|
||||
|
||||
|
@ -92,7 +94,10 @@ abstract class _Settings with Store {
|
|||
@observable
|
||||
bool simpleMode = true;
|
||||
|
||||
List<CoinData> coins = [CoinData(0, zcash), CoinData(1, ycash)];
|
||||
List<CoinData> coins = Coins.coins
|
||||
.sortedByNum((c) => c.coin)
|
||||
.map((c) => CoinData(c.coin, c))
|
||||
.toList();
|
||||
|
||||
@observable
|
||||
String version = "1.0.0";
|
||||
|
@ -636,8 +641,8 @@ abstract class _PriceStore with Store {
|
|||
if (f ||
|
||||
_lastChartUpdateTime == null ||
|
||||
now > _lastChartUpdateTime + 5 * 60) {
|
||||
await fetchQueue
|
||||
.add(() => WarpApi.syncHistoricalPrices(settings.currency));
|
||||
await fetchQueue.add(
|
||||
() => WarpApi.syncHistoricalPrices(active.coin, settings.currency));
|
||||
active.fetchChartData();
|
||||
lastChartUpdateTime = now;
|
||||
}
|
||||
|
@ -739,7 +744,7 @@ abstract class _SyncStatus with Store {
|
|||
if (url.isNotEmpty) WarpApi.updateLWD(active.coin, url);
|
||||
}
|
||||
try {
|
||||
latestHeight = await WarpApi.getLatestHeight();
|
||||
latestHeight = await WarpApi.getLatestHeight(active.coin);
|
||||
} on String {}
|
||||
final _syncedInfo = getDbSyncedHeight();
|
||||
// if syncedHeight = 0, we just started sync therefore don't set it back to null
|
||||
|
@ -816,7 +821,7 @@ abstract class _SyncStatus with Store {
|
|||
showSnackBar(S.current.rescanRequested(height));
|
||||
syncedHeight = height;
|
||||
timestamp = null;
|
||||
WarpApi.rescanFrom(height);
|
||||
WarpApi.rescanFrom(active.coin, height);
|
||||
await sync(true);
|
||||
final rh = pendingRescanHeight;
|
||||
if (rh != null) {
|
||||
|
|
|
@ -50,17 +50,20 @@ class TransactionState extends State<TransactionPage> {
|
|||
ListTile(
|
||||
title: Text(S.of(context).amount),
|
||||
subtitle: SelectableText(decimalFormat(tx.value, 8))),
|
||||
ListTile(
|
||||
title: Text(S.of(context).address),
|
||||
subtitle: SelectableText('${tx.address}'),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.contacts), onPressed: _addContact)),
|
||||
ListTile(
|
||||
title: Text(S.of(context).contactName),
|
||||
subtitle: SelectableText('${tx.contact ?? "N/A"}')),
|
||||
ListTile(
|
||||
title: Text(S.of(context).memo),
|
||||
subtitle: SelectableText('${tx.memo}')),
|
||||
if (active.isPrivate)
|
||||
ListTile(
|
||||
title: Text(S.of(context).address),
|
||||
subtitle: SelectableText('${tx.address}'),
|
||||
trailing: IconButton(
|
||||
icon: Icon(Icons.contacts), onPressed: _addContact)),
|
||||
if (active.isPrivate)
|
||||
ListTile(
|
||||
title: Text(S.of(context).contactName),
|
||||
subtitle: SelectableText('${tx.contact ?? "N/A"}')),
|
||||
if (active.isPrivate)
|
||||
ListTile(
|
||||
title: Text(S.of(context).memo),
|
||||
subtitle: SelectableText('${tx.memo}')),
|
||||
ButtonBar(alignment: MainAxisAlignment.center, children: [
|
||||
IconButton(
|
||||
onPressed: txIndex > 0 ? _prev : null,
|
||||
|
|
|
@ -31,10 +31,12 @@ class TxPlanPage extends StatelessWidget {
|
|||
.map((e) => DataRow(cells: [
|
||||
DataCell(Text('...${trailing(e.address!, 12)}')),
|
||||
DataCell(Text('${poolToString(e.pool)}')),
|
||||
DataCell(Text('${amountToString(e.amount, 3)}')),
|
||||
DataCell(Text('${amountToString(e.amount, MAX_PRECISION)}')),
|
||||
]))
|
||||
.toList();
|
||||
final invalidPrivacy = report.privacyLevel < settings.minPrivacyLevel;
|
||||
// TODO: Abstract sat into coinDef
|
||||
final feeFx = decimalFormat(report.fee * priceStore.coinPrice / ZECUNIT, 2);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('Transaction Plan')),
|
||||
|
@ -60,20 +62,22 @@ class TxPlanPage extends StatelessWidget {
|
|||
title: Text('Transparent Input'),
|
||||
trailing:
|
||||
Text(amountToString(report.transparent, MAX_PRECISION))),
|
||||
ListTile(
|
||||
title: Text('Sapling Input'),
|
||||
trailing:
|
||||
Text(amountToString(report.sapling, MAX_PRECISION))),
|
||||
if (supportsUA)
|
||||
if (active.isPrivate)
|
||||
ListTile(
|
||||
title: Text('Sapling Input'),
|
||||
trailing:
|
||||
Text(amountToString(report.sapling, MAX_PRECISION))),
|
||||
if (active.isPrivate && supportsUA)
|
||||
ListTile(
|
||||
title: Text('Orchard Input'),
|
||||
trailing:
|
||||
Text(amountToString(report.orchard, MAX_PRECISION))),
|
||||
ListTile(
|
||||
title: Text('Net Sapling Change'),
|
||||
trailing:
|
||||
Text(amountToString(report.netSapling, MAX_PRECISION))),
|
||||
if (supportsUA)
|
||||
if (active.isPrivate)
|
||||
ListTile(
|
||||
title: Text('Net Sapling Change'),
|
||||
trailing:
|
||||
Text(amountToString(report.netSapling, MAX_PRECISION))),
|
||||
if (active.isPrivate && supportsUA)
|
||||
ListTile(
|
||||
title: Text('Net Orchard Change'),
|
||||
trailing:
|
||||
|
@ -81,6 +85,9 @@ class TxPlanPage extends StatelessWidget {
|
|||
ListTile(
|
||||
title: Text('Fee'),
|
||||
trailing: Text(amountToString(report.fee, MAX_PRECISION))),
|
||||
ListTile(
|
||||
title: Text('Fee ${settings.currency}'),
|
||||
trailing: Text(feeFx)),
|
||||
privacyToString(context, report.privacyLevel)!,
|
||||
if (invalidPrivacy)
|
||||
Padding(
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 388e3de26c0a6a5d899024a406510285aee28736
|
||||
Subproject commit ad2515d47ae1ba4a97cb9860170f4fa9228ffcaa
|
|
@ -833,7 +833,7 @@ class ShieldedTx {
|
|||
String? get shortTxId => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10);
|
||||
int get timestamp => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
|
||||
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 14);
|
||||
int get value => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 16, 0);
|
||||
int get value => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 16, 0);
|
||||
String? get address => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 18);
|
||||
String? get memo => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 20);
|
||||
|
||||
|
@ -900,7 +900,7 @@ class ShieldedTxT implements fb.Packable {
|
|||
fbBuilder.addOffset(3, shortTxIdOffset);
|
||||
fbBuilder.addUint32(4, timestamp);
|
||||
fbBuilder.addOffset(5, nameOffset);
|
||||
fbBuilder.addUint64(6, value);
|
||||
fbBuilder.addInt64(6, value);
|
||||
fbBuilder.addOffset(7, addressOffset);
|
||||
fbBuilder.addOffset(8, memoOffset);
|
||||
return fbBuilder.endTable();
|
||||
|
@ -954,7 +954,7 @@ class ShieldedTxBuilder {
|
|||
return fbBuilder.offset;
|
||||
}
|
||||
int addValue(int? value) {
|
||||
fbBuilder.addUint64(6, value);
|
||||
fbBuilder.addInt64(6, value);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addAddressOffset(int? offset) {
|
||||
|
@ -1023,7 +1023,7 @@ class ShieldedTxObjectBuilder extends fb.ObjectBuilder {
|
|||
fbBuilder.addOffset(3, shortTxIdOffset);
|
||||
fbBuilder.addUint32(4, _timestamp);
|
||||
fbBuilder.addOffset(5, nameOffset);
|
||||
fbBuilder.addUint64(6, _value);
|
||||
fbBuilder.addInt64(6, _value);
|
||||
fbBuilder.addOffset(7, addressOffset);
|
||||
fbBuilder.addOffset(8, memoOffset);
|
||||
return fbBuilder.endTable();
|
||||
|
@ -1139,6 +1139,906 @@ class ShieldedTxVecObjectBuilder extends fb.ObjectBuilder {
|
|||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class PlainTx {
|
||||
PlainTx._(this._bc, this._bcOffset);
|
||||
factory PlainTx(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<PlainTx> reader = _PlainTxReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
int get id => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
|
||||
String? get txId => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 6);
|
||||
int get height => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
|
||||
int get timestamp => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0);
|
||||
int get value => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 12, 0);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainTx{id: ${id}, txId: ${txId}, height: ${height}, timestamp: ${timestamp}, value: ${value}}';
|
||||
}
|
||||
|
||||
PlainTxT unpack() => PlainTxT(
|
||||
id: id,
|
||||
txId: txId,
|
||||
height: height,
|
||||
timestamp: timestamp,
|
||||
value: value);
|
||||
|
||||
static int pack(fb.Builder fbBuilder, PlainTxT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class PlainTxT implements fb.Packable {
|
||||
int id;
|
||||
String? txId;
|
||||
int height;
|
||||
int timestamp;
|
||||
int value;
|
||||
|
||||
PlainTxT({
|
||||
this.id = 0,
|
||||
this.txId,
|
||||
this.height = 0,
|
||||
this.timestamp = 0,
|
||||
this.value = 0});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? txIdOffset = txId == null ? null
|
||||
: fbBuilder.writeString(txId!);
|
||||
fbBuilder.startTable(5);
|
||||
fbBuilder.addUint32(0, id);
|
||||
fbBuilder.addOffset(1, txIdOffset);
|
||||
fbBuilder.addUint32(2, height);
|
||||
fbBuilder.addUint32(3, timestamp);
|
||||
fbBuilder.addInt64(4, value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainTxT{id: ${id}, txId: ${txId}, height: ${height}, timestamp: ${timestamp}, value: ${value}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _PlainTxReader extends fb.TableReader<PlainTx> {
|
||||
const _PlainTxReader();
|
||||
|
||||
@override
|
||||
PlainTx createObject(fb.BufferContext bc, int offset) =>
|
||||
PlainTx._(bc, offset);
|
||||
}
|
||||
|
||||
class PlainTxBuilder {
|
||||
PlainTxBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(5);
|
||||
}
|
||||
|
||||
int addId(int? id) {
|
||||
fbBuilder.addUint32(0, id);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addTxIdOffset(int? offset) {
|
||||
fbBuilder.addOffset(1, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addHeight(int? height) {
|
||||
fbBuilder.addUint32(2, height);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addTimestamp(int? timestamp) {
|
||||
fbBuilder.addUint32(3, timestamp);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addValue(int? value) {
|
||||
fbBuilder.addInt64(4, value);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class PlainTxObjectBuilder extends fb.ObjectBuilder {
|
||||
final int? _id;
|
||||
final String? _txId;
|
||||
final int? _height;
|
||||
final int? _timestamp;
|
||||
final int? _value;
|
||||
|
||||
PlainTxObjectBuilder({
|
||||
int? id,
|
||||
String? txId,
|
||||
int? height,
|
||||
int? timestamp,
|
||||
int? value,
|
||||
})
|
||||
: _id = id,
|
||||
_txId = txId,
|
||||
_height = height,
|
||||
_timestamp = timestamp,
|
||||
_value = value;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? txIdOffset = _txId == null ? null
|
||||
: fbBuilder.writeString(_txId!);
|
||||
fbBuilder.startTable(5);
|
||||
fbBuilder.addUint32(0, _id);
|
||||
fbBuilder.addOffset(1, txIdOffset);
|
||||
fbBuilder.addUint32(2, _height);
|
||||
fbBuilder.addUint32(3, _timestamp);
|
||||
fbBuilder.addInt64(4, _value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class PlainTxVec {
|
||||
PlainTxVec._(this._bc, this._bcOffset);
|
||||
factory PlainTxVec(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<PlainTxVec> reader = _PlainTxVecReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
List<PlainTx>? get txs => const fb.ListReader<PlainTx>(PlainTx.reader).vTableGetNullable(_bc, _bcOffset, 4);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainTxVec{txs: ${txs}}';
|
||||
}
|
||||
|
||||
PlainTxVecT unpack() => PlainTxVecT(
|
||||
txs: txs?.map((e) => e.unpack()).toList());
|
||||
|
||||
static int pack(fb.Builder fbBuilder, PlainTxVecT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class PlainTxVecT implements fb.Packable {
|
||||
List<PlainTxT>? txs;
|
||||
|
||||
PlainTxVecT({
|
||||
this.txs});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? txsOffset = txs == null ? null
|
||||
: fbBuilder.writeList(txs!.map((b) => b.pack(fbBuilder)).toList());
|
||||
fbBuilder.startTable(1);
|
||||
fbBuilder.addOffset(0, txsOffset);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainTxVecT{txs: ${txs}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _PlainTxVecReader extends fb.TableReader<PlainTxVec> {
|
||||
const _PlainTxVecReader();
|
||||
|
||||
@override
|
||||
PlainTxVec createObject(fb.BufferContext bc, int offset) =>
|
||||
PlainTxVec._(bc, offset);
|
||||
}
|
||||
|
||||
class PlainTxVecBuilder {
|
||||
PlainTxVecBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(1);
|
||||
}
|
||||
|
||||
int addTxsOffset(int? offset) {
|
||||
fbBuilder.addOffset(0, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class PlainTxVecObjectBuilder extends fb.ObjectBuilder {
|
||||
final List<PlainTxObjectBuilder>? _txs;
|
||||
|
||||
PlainTxVecObjectBuilder({
|
||||
List<PlainTxObjectBuilder>? txs,
|
||||
})
|
||||
: _txs = txs;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? txsOffset = _txs == null ? null
|
||||
: fbBuilder.writeList(_txs!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
|
||||
fbBuilder.startTable(1);
|
||||
fbBuilder.addOffset(0, txsOffset);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class PlainNote {
|
||||
PlainNote._(this._bc, this._bcOffset);
|
||||
factory PlainNote(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<PlainNote> reader = _PlainNoteReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
int get id => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
|
||||
String? get txId => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 6);
|
||||
int get height => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
|
||||
int get timestamp => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0);
|
||||
int get vout => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
|
||||
int get value => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 14, 0);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainNote{id: ${id}, txId: ${txId}, height: ${height}, timestamp: ${timestamp}, vout: ${vout}, value: ${value}}';
|
||||
}
|
||||
|
||||
PlainNoteT unpack() => PlainNoteT(
|
||||
id: id,
|
||||
txId: txId,
|
||||
height: height,
|
||||
timestamp: timestamp,
|
||||
vout: vout,
|
||||
value: value);
|
||||
|
||||
static int pack(fb.Builder fbBuilder, PlainNoteT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class PlainNoteT implements fb.Packable {
|
||||
int id;
|
||||
String? txId;
|
||||
int height;
|
||||
int timestamp;
|
||||
int vout;
|
||||
int value;
|
||||
|
||||
PlainNoteT({
|
||||
this.id = 0,
|
||||
this.txId,
|
||||
this.height = 0,
|
||||
this.timestamp = 0,
|
||||
this.vout = 0,
|
||||
this.value = 0});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? txIdOffset = txId == null ? null
|
||||
: fbBuilder.writeString(txId!);
|
||||
fbBuilder.startTable(6);
|
||||
fbBuilder.addUint32(0, id);
|
||||
fbBuilder.addOffset(1, txIdOffset);
|
||||
fbBuilder.addUint32(2, height);
|
||||
fbBuilder.addUint32(3, timestamp);
|
||||
fbBuilder.addUint32(4, vout);
|
||||
fbBuilder.addUint64(5, value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainNoteT{id: ${id}, txId: ${txId}, height: ${height}, timestamp: ${timestamp}, vout: ${vout}, value: ${value}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _PlainNoteReader extends fb.TableReader<PlainNote> {
|
||||
const _PlainNoteReader();
|
||||
|
||||
@override
|
||||
PlainNote createObject(fb.BufferContext bc, int offset) =>
|
||||
PlainNote._(bc, offset);
|
||||
}
|
||||
|
||||
class PlainNoteBuilder {
|
||||
PlainNoteBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(6);
|
||||
}
|
||||
|
||||
int addId(int? id) {
|
||||
fbBuilder.addUint32(0, id);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addTxIdOffset(int? offset) {
|
||||
fbBuilder.addOffset(1, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addHeight(int? height) {
|
||||
fbBuilder.addUint32(2, height);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addTimestamp(int? timestamp) {
|
||||
fbBuilder.addUint32(3, timestamp);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addVout(int? vout) {
|
||||
fbBuilder.addUint32(4, vout);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addValue(int? value) {
|
||||
fbBuilder.addUint64(5, value);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class PlainNoteObjectBuilder extends fb.ObjectBuilder {
|
||||
final int? _id;
|
||||
final String? _txId;
|
||||
final int? _height;
|
||||
final int? _timestamp;
|
||||
final int? _vout;
|
||||
final int? _value;
|
||||
|
||||
PlainNoteObjectBuilder({
|
||||
int? id,
|
||||
String? txId,
|
||||
int? height,
|
||||
int? timestamp,
|
||||
int? vout,
|
||||
int? value,
|
||||
})
|
||||
: _id = id,
|
||||
_txId = txId,
|
||||
_height = height,
|
||||
_timestamp = timestamp,
|
||||
_vout = vout,
|
||||
_value = value;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? txIdOffset = _txId == null ? null
|
||||
: fbBuilder.writeString(_txId!);
|
||||
fbBuilder.startTable(6);
|
||||
fbBuilder.addUint32(0, _id);
|
||||
fbBuilder.addOffset(1, txIdOffset);
|
||||
fbBuilder.addUint32(2, _height);
|
||||
fbBuilder.addUint32(3, _timestamp);
|
||||
fbBuilder.addUint32(4, _vout);
|
||||
fbBuilder.addUint64(5, _value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class PlainNoteVec {
|
||||
PlainNoteVec._(this._bc, this._bcOffset);
|
||||
factory PlainNoteVec(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<PlainNoteVec> reader = _PlainNoteVecReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
List<PlainNote>? get notes => const fb.ListReader<PlainNote>(PlainNote.reader).vTableGetNullable(_bc, _bcOffset, 4);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainNoteVec{notes: ${notes}}';
|
||||
}
|
||||
|
||||
PlainNoteVecT unpack() => PlainNoteVecT(
|
||||
notes: notes?.map((e) => e.unpack()).toList());
|
||||
|
||||
static int pack(fb.Builder fbBuilder, PlainNoteVecT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class PlainNoteVecT implements fb.Packable {
|
||||
List<PlainNoteT>? notes;
|
||||
|
||||
PlainNoteVecT({
|
||||
this.notes});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? notesOffset = notes == null ? null
|
||||
: fbBuilder.writeList(notes!.map((b) => b.pack(fbBuilder)).toList());
|
||||
fbBuilder.startTable(1);
|
||||
fbBuilder.addOffset(0, notesOffset);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PlainNoteVecT{notes: ${notes}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _PlainNoteVecReader extends fb.TableReader<PlainNoteVec> {
|
||||
const _PlainNoteVecReader();
|
||||
|
||||
@override
|
||||
PlainNoteVec createObject(fb.BufferContext bc, int offset) =>
|
||||
PlainNoteVec._(bc, offset);
|
||||
}
|
||||
|
||||
class PlainNoteVecBuilder {
|
||||
PlainNoteVecBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(1);
|
||||
}
|
||||
|
||||
int addNotesOffset(int? offset) {
|
||||
fbBuilder.addOffset(0, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class PlainNoteVecObjectBuilder extends fb.ObjectBuilder {
|
||||
final List<PlainNoteObjectBuilder>? _notes;
|
||||
|
||||
PlainNoteVecObjectBuilder({
|
||||
List<PlainNoteObjectBuilder>? notes,
|
||||
})
|
||||
: _notes = notes;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? notesOffset = _notes == null ? null
|
||||
: fbBuilder.writeList(_notes!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
|
||||
fbBuilder.startTable(1);
|
||||
fbBuilder.addOffset(0, notesOffset);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class Btcinput {
|
||||
Btcinput._(this._bc, this._bcOffset);
|
||||
factory Btcinput(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<Btcinput> reader = _BtcinputReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
String? get txId => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4);
|
||||
int get vout => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
|
||||
int get value => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 8, 0);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Btcinput{txId: ${txId}, vout: ${vout}, value: ${value}}';
|
||||
}
|
||||
|
||||
BtcinputT unpack() => BtcinputT(
|
||||
txId: txId,
|
||||
vout: vout,
|
||||
value: value);
|
||||
|
||||
static int pack(fb.Builder fbBuilder, BtcinputT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class BtcinputT implements fb.Packable {
|
||||
String? txId;
|
||||
int vout;
|
||||
int value;
|
||||
|
||||
BtcinputT({
|
||||
this.txId,
|
||||
this.vout = 0,
|
||||
this.value = 0});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? txIdOffset = txId == null ? null
|
||||
: fbBuilder.writeString(txId!);
|
||||
fbBuilder.startTable(3);
|
||||
fbBuilder.addOffset(0, txIdOffset);
|
||||
fbBuilder.addUint32(1, vout);
|
||||
fbBuilder.addUint64(2, value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BtcinputT{txId: ${txId}, vout: ${vout}, value: ${value}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _BtcinputReader extends fb.TableReader<Btcinput> {
|
||||
const _BtcinputReader();
|
||||
|
||||
@override
|
||||
Btcinput createObject(fb.BufferContext bc, int offset) =>
|
||||
Btcinput._(bc, offset);
|
||||
}
|
||||
|
||||
class BtcinputBuilder {
|
||||
BtcinputBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(3);
|
||||
}
|
||||
|
||||
int addTxIdOffset(int? offset) {
|
||||
fbBuilder.addOffset(0, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addVout(int? vout) {
|
||||
fbBuilder.addUint32(1, vout);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addValue(int? value) {
|
||||
fbBuilder.addUint64(2, value);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class BtcinputObjectBuilder extends fb.ObjectBuilder {
|
||||
final String? _txId;
|
||||
final int? _vout;
|
||||
final int? _value;
|
||||
|
||||
BtcinputObjectBuilder({
|
||||
String? txId,
|
||||
int? vout,
|
||||
int? value,
|
||||
})
|
||||
: _txId = txId,
|
||||
_vout = vout,
|
||||
_value = value;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? txIdOffset = _txId == null ? null
|
||||
: fbBuilder.writeString(_txId!);
|
||||
fbBuilder.startTable(3);
|
||||
fbBuilder.addOffset(0, txIdOffset);
|
||||
fbBuilder.addUint32(1, _vout);
|
||||
fbBuilder.addUint64(2, _value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class Btcoutput {
|
||||
Btcoutput._(this._bc, this._bcOffset);
|
||||
factory Btcoutput(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<Btcoutput> reader = _BtcoutputReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
String? get scriptPubkey => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4);
|
||||
int get value => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 6, 0);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Btcoutput{scriptPubkey: ${scriptPubkey}, value: ${value}}';
|
||||
}
|
||||
|
||||
BtcoutputT unpack() => BtcoutputT(
|
||||
scriptPubkey: scriptPubkey,
|
||||
value: value);
|
||||
|
||||
static int pack(fb.Builder fbBuilder, BtcoutputT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class BtcoutputT implements fb.Packable {
|
||||
String? scriptPubkey;
|
||||
int value;
|
||||
|
||||
BtcoutputT({
|
||||
this.scriptPubkey,
|
||||
this.value = 0});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? scriptPubkeyOffset = scriptPubkey == null ? null
|
||||
: fbBuilder.writeString(scriptPubkey!);
|
||||
fbBuilder.startTable(2);
|
||||
fbBuilder.addOffset(0, scriptPubkeyOffset);
|
||||
fbBuilder.addUint64(1, value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BtcoutputT{scriptPubkey: ${scriptPubkey}, value: ${value}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _BtcoutputReader extends fb.TableReader<Btcoutput> {
|
||||
const _BtcoutputReader();
|
||||
|
||||
@override
|
||||
Btcoutput createObject(fb.BufferContext bc, int offset) =>
|
||||
Btcoutput._(bc, offset);
|
||||
}
|
||||
|
||||
class BtcoutputBuilder {
|
||||
BtcoutputBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(2);
|
||||
}
|
||||
|
||||
int addScriptPubkeyOffset(int? offset) {
|
||||
fbBuilder.addOffset(0, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addValue(int? value) {
|
||||
fbBuilder.addUint64(1, value);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class BtcoutputObjectBuilder extends fb.ObjectBuilder {
|
||||
final String? _scriptPubkey;
|
||||
final int? _value;
|
||||
|
||||
BtcoutputObjectBuilder({
|
||||
String? scriptPubkey,
|
||||
int? value,
|
||||
})
|
||||
: _scriptPubkey = scriptPubkey,
|
||||
_value = value;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? scriptPubkeyOffset = _scriptPubkey == null ? null
|
||||
: fbBuilder.writeString(_scriptPubkey!);
|
||||
fbBuilder.startTable(2);
|
||||
fbBuilder.addOffset(0, scriptPubkeyOffset);
|
||||
fbBuilder.addUint64(1, _value);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class Btctx {
|
||||
Btctx._(this._bc, this._bcOffset);
|
||||
factory Btctx(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<Btctx> reader = _BtctxReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
List<Btcinput>? get txins => const fb.ListReader<Btcinput>(Btcinput.reader).vTableGetNullable(_bc, _bcOffset, 4);
|
||||
List<Btcoutput>? get txouts => const fb.ListReader<Btcoutput>(Btcoutput.reader).vTableGetNullable(_bc, _bcOffset, 6);
|
||||
int get fee => const fb.Uint64Reader().vTableGet(_bc, _bcOffset, 8, 0);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Btctx{txins: ${txins}, txouts: ${txouts}, fee: ${fee}}';
|
||||
}
|
||||
|
||||
BtctxT unpack() => BtctxT(
|
||||
txins: txins?.map((e) => e.unpack()).toList(),
|
||||
txouts: txouts?.map((e) => e.unpack()).toList(),
|
||||
fee: fee);
|
||||
|
||||
static int pack(fb.Builder fbBuilder, BtctxT? object) {
|
||||
if (object == null) return 0;
|
||||
return object.pack(fbBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
class BtctxT implements fb.Packable {
|
||||
List<BtcinputT>? txins;
|
||||
List<BtcoutputT>? txouts;
|
||||
int fee;
|
||||
|
||||
BtctxT({
|
||||
this.txins,
|
||||
this.txouts,
|
||||
this.fee = 0});
|
||||
|
||||
@override
|
||||
int pack(fb.Builder fbBuilder) {
|
||||
final int? txinsOffset = txins == null ? null
|
||||
: fbBuilder.writeList(txins!.map((b) => b.pack(fbBuilder)).toList());
|
||||
final int? txoutsOffset = txouts == null ? null
|
||||
: fbBuilder.writeList(txouts!.map((b) => b.pack(fbBuilder)).toList());
|
||||
fbBuilder.startTable(3);
|
||||
fbBuilder.addOffset(0, txinsOffset);
|
||||
fbBuilder.addOffset(1, txoutsOffset);
|
||||
fbBuilder.addUint64(2, fee);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BtctxT{txins: ${txins}, txouts: ${txouts}, fee: ${fee}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _BtctxReader extends fb.TableReader<Btctx> {
|
||||
const _BtctxReader();
|
||||
|
||||
@override
|
||||
Btctx createObject(fb.BufferContext bc, int offset) =>
|
||||
Btctx._(bc, offset);
|
||||
}
|
||||
|
||||
class BtctxBuilder {
|
||||
BtctxBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(3);
|
||||
}
|
||||
|
||||
int addTxinsOffset(int? offset) {
|
||||
fbBuilder.addOffset(0, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addTxoutsOffset(int? offset) {
|
||||
fbBuilder.addOffset(1, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addFee(int? fee) {
|
||||
fbBuilder.addUint64(2, fee);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class BtctxObjectBuilder extends fb.ObjectBuilder {
|
||||
final List<BtcinputObjectBuilder>? _txins;
|
||||
final List<BtcoutputObjectBuilder>? _txouts;
|
||||
final int? _fee;
|
||||
|
||||
BtctxObjectBuilder({
|
||||
List<BtcinputObjectBuilder>? txins,
|
||||
List<BtcoutputObjectBuilder>? txouts,
|
||||
int? fee,
|
||||
})
|
||||
: _txins = txins,
|
||||
_txouts = txouts,
|
||||
_fee = fee;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? txinsOffset = _txins == null ? null
|
||||
: fbBuilder.writeList(_txins!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
|
||||
final int? txoutsOffset = _txouts == null ? null
|
||||
: fbBuilder.writeList(_txouts!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
|
||||
fbBuilder.startTable(3);
|
||||
fbBuilder.addOffset(0, txinsOffset);
|
||||
fbBuilder.addOffset(1, txoutsOffset);
|
||||
fbBuilder.addUint64(2, _fee);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class Message {
|
||||
Message._(this._bc, this._bcOffset);
|
||||
factory Message(List<int> bytes) {
|
||||
|
|
|
@ -117,10 +117,6 @@ class WarpApi {
|
|||
name.toNativeUtf8().cast<Int8>(), index, count);
|
||||
}
|
||||
|
||||
static String ledgerGetFVK(int coin) {
|
||||
return unwrapResultString(warp_api_lib.ledger_get_fvk(coin));
|
||||
}
|
||||
|
||||
static void convertToWatchOnly(int coin, int id) {
|
||||
warp_api_lib.convert_to_watchonly(coin, id);
|
||||
}
|
||||
|
@ -159,8 +155,8 @@ class WarpApi {
|
|||
return unwrapResultU32(warp_api_lib.rewind_to(height));
|
||||
}
|
||||
|
||||
static void rescanFrom(int height) {
|
||||
warp_api_lib.rescan_from(height);
|
||||
static void rescanFrom(int coin, int height) {
|
||||
warp_api_lib.rescan_from(coin, height);
|
||||
}
|
||||
|
||||
static int warpSync(SyncParams params) {
|
||||
|
@ -174,8 +170,8 @@ class WarpApi {
|
|||
warp_api_lib.cancel_warp();
|
||||
}
|
||||
|
||||
static Future<int> getLatestHeight() async {
|
||||
return await compute(getLatestHeightIsolateFn, null);
|
||||
static Future<int> getLatestHeight(int coin) async {
|
||||
return await compute(getLatestHeightIsolateFn, coin);
|
||||
}
|
||||
|
||||
static int validKey(int coin, String key) {
|
||||
|
@ -221,8 +217,8 @@ class WarpApi {
|
|||
// recipientJson, useTransparent, anchorOffset, receivePort.sendPort));
|
||||
// }
|
||||
|
||||
static int getTBalance() {
|
||||
final balance = warp_api_lib.get_taddr_balance(0xFF, 0);
|
||||
static int getTBalance(int coin, int account) {
|
||||
final balance = warp_api_lib.get_taddr_balance(coin, account);
|
||||
return unwrapResultU64(balance);
|
||||
}
|
||||
|
||||
|
@ -303,8 +299,9 @@ class WarpApi {
|
|||
SignOnlyParams(coin, account, tx, receivePort.sendPort));
|
||||
}
|
||||
|
||||
static String broadcast(String txStr) {
|
||||
final res = warp_api_lib.broadcast_tx(txStr.toNativeUtf8().cast<Int8>());
|
||||
static String broadcast(int coin, String txStr) {
|
||||
final res =
|
||||
warp_api_lib.broadcast_tx(coin, txStr.toNativeUtf8().cast<Int8>());
|
||||
return unwrapResultString(res);
|
||||
}
|
||||
|
||||
|
@ -341,9 +338,9 @@ class WarpApi {
|
|||
return res;
|
||||
}
|
||||
|
||||
static Future<int> syncHistoricalPrices(String currency) async {
|
||||
return await compute(
|
||||
syncHistoricalPricesIsolateFn, SyncHistoricalPricesParams(currency));
|
||||
static Future<int> syncHistoricalPrices(int coin, String currency) async {
|
||||
return await compute(syncHistoricalPricesIsolateFn,
|
||||
SyncHistoricalPricesParams(coin, currency));
|
||||
}
|
||||
|
||||
static void setDbPasswd(int coin, String passwd) {
|
||||
|
@ -455,14 +452,6 @@ class WarpApi {
|
|||
return kp;
|
||||
}
|
||||
|
||||
static void ledgerBuildKeys() {
|
||||
unwrapResultU8(warp_api_lib.ledger_build_keys());
|
||||
}
|
||||
|
||||
static String ledgerGetAddress() {
|
||||
return unwrapResultString(warp_api_lib.ledger_get_address());
|
||||
}
|
||||
|
||||
static Future<String> ledgerSend(int coin, String txPlan) async {
|
||||
return await compute((_) {
|
||||
return unwrapResultString(
|
||||
|
@ -667,8 +656,8 @@ String signOnlyIsolateFn(SignOnlyParams params) {
|
|||
return convertCString(txIdRes.value);
|
||||
}
|
||||
|
||||
int getLatestHeightIsolateFn(Null n) {
|
||||
return unwrapResultU32(warp_api_lib.get_latest_height());
|
||||
int getLatestHeightIsolateFn(int coin) {
|
||||
return unwrapResultU32(warp_api_lib.get_latest_height(coin));
|
||||
}
|
||||
|
||||
String transferPoolsIsolateFn(TransferPoolsParams params) {
|
||||
|
@ -689,6 +678,7 @@ int syncHistoricalPricesIsolateFn(SyncHistoricalPricesParams params) {
|
|||
final now = DateTime.now();
|
||||
final today = DateTime.utc(now.year, now.month, now.day);
|
||||
return unwrapResultU32(warp_api_lib.sync_historical_prices(
|
||||
params.coin,
|
||||
today.millisecondsSinceEpoch ~/ 1000,
|
||||
365,
|
||||
params.currency.toNativeUtf8().cast<Int8>()));
|
||||
|
@ -768,9 +758,10 @@ class TransferPoolsParams {
|
|||
}
|
||||
|
||||
class SyncHistoricalPricesParams {
|
||||
final int coin;
|
||||
final String currency;
|
||||
|
||||
SyncHistoricalPricesParams(this.currency);
|
||||
SyncHistoricalPricesParams(this.coin, this.currency);
|
||||
}
|
||||
|
||||
class GetTBalanceParams {
|
||||
|
|
|
@ -415,8 +415,12 @@ class NativeLibrary {
|
|||
late final _dart_get_diversified_address _get_diversified_address =
|
||||
_get_diversified_address_ptr.asFunction<_dart_get_diversified_address>();
|
||||
|
||||
CResult_u32 get_latest_height() {
|
||||
return _get_latest_height();
|
||||
CResult_u32 get_latest_height(
|
||||
int coin,
|
||||
) {
|
||||
return _get_latest_height(
|
||||
coin,
|
||||
);
|
||||
}
|
||||
|
||||
late final _get_latest_height_ptr =
|
||||
|
@ -424,37 +428,6 @@ class NativeLibrary {
|
|||
late final _dart_get_latest_height _get_latest_height =
|
||||
_get_latest_height_ptr.asFunction<_dart_get_latest_height>();
|
||||
|
||||
CResult_u8 ledger_build_keys() {
|
||||
return _ledger_build_keys();
|
||||
}
|
||||
|
||||
late final _ledger_build_keys_ptr =
|
||||
_lookup<ffi.NativeFunction<_c_ledger_build_keys>>('ledger_build_keys');
|
||||
late final _dart_ledger_build_keys _ledger_build_keys =
|
||||
_ledger_build_keys_ptr.asFunction<_dart_ledger_build_keys>();
|
||||
|
||||
CResult_____c_char ledger_get_fvk(
|
||||
int coin,
|
||||
) {
|
||||
return _ledger_get_fvk(
|
||||
coin,
|
||||
);
|
||||
}
|
||||
|
||||
late final _ledger_get_fvk_ptr =
|
||||
_lookup<ffi.NativeFunction<_c_ledger_get_fvk>>('ledger_get_fvk');
|
||||
late final _dart_ledger_get_fvk _ledger_get_fvk =
|
||||
_ledger_get_fvk_ptr.asFunction<_dart_ledger_get_fvk>();
|
||||
|
||||
CResult_____c_char ledger_get_address() {
|
||||
return _ledger_get_address();
|
||||
}
|
||||
|
||||
late final _ledger_get_address_ptr =
|
||||
_lookup<ffi.NativeFunction<_c_ledger_get_address>>('ledger_get_address');
|
||||
late final _dart_ledger_get_address _ledger_get_address =
|
||||
_ledger_get_address_ptr.asFunction<_dart_ledger_get_address>();
|
||||
|
||||
void skip_to_last_height(
|
||||
int coin,
|
||||
) {
|
||||
|
@ -483,9 +456,11 @@ class NativeLibrary {
|
|||
_rewind_to_ptr.asFunction<_dart_rewind_to>();
|
||||
|
||||
void rescan_from(
|
||||
int coin,
|
||||
int height,
|
||||
) {
|
||||
return _rescan_from(
|
||||
coin,
|
||||
height,
|
||||
);
|
||||
}
|
||||
|
@ -649,9 +624,11 @@ class NativeLibrary {
|
|||
_sign_and_broadcast_ptr.asFunction<_dart_sign_and_broadcast>();
|
||||
|
||||
CResult_____c_char broadcast_tx(
|
||||
int coin,
|
||||
ffi.Pointer<ffi.Int8> tx_str,
|
||||
) {
|
||||
return _broadcast_tx(
|
||||
coin,
|
||||
tx_str,
|
||||
);
|
||||
}
|
||||
|
@ -717,11 +694,13 @@ class NativeLibrary {
|
|||
_get_block_by_time_ptr.asFunction<_dart_get_block_by_time>();
|
||||
|
||||
CResult_u32 sync_historical_prices(
|
||||
int coin,
|
||||
int now,
|
||||
int days,
|
||||
ffi.Pointer<ffi.Int8> currency,
|
||||
) {
|
||||
return _sync_historical_prices(
|
||||
coin,
|
||||
now,
|
||||
days,
|
||||
currency,
|
||||
|
@ -1655,6 +1634,16 @@ const int ShieldedTx_VT_MEMO = 20;
|
|||
|
||||
const int ShieldedTxVec_VT_TXS = 4;
|
||||
|
||||
const int PlainNote_VT_VOUT = 12;
|
||||
|
||||
const int BTCOutput_VT_SCRIPT_PUBKEY = 4;
|
||||
|
||||
const int BTCTx_VT_TXINS = 4;
|
||||
|
||||
const int BTCTx_VT_TXOUTS = 6;
|
||||
|
||||
const int BTCTx_VT_FEE = 8;
|
||||
|
||||
const int Message_VT_ID_MSG = 4;
|
||||
|
||||
const int Message_VT_ID_TX = 6;
|
||||
|
@ -1743,8 +1732,6 @@ const int TxReport_VT_NET_SAPLING = 12;
|
|||
|
||||
const int TxReport_VT_NET_ORCHARD = 14;
|
||||
|
||||
const int TxReport_VT_FEE = 16;
|
||||
|
||||
const int TxReport_VT_PRIVACY_LEVEL = 18;
|
||||
|
||||
typedef _c_dummy_export = ffi.Void Function();
|
||||
|
@ -2005,26 +1992,14 @@ typedef _dart_get_diversified_address = CResult_____c_char Function(
|
|||
int time,
|
||||
);
|
||||
|
||||
typedef _c_get_latest_height = CResult_u32 Function();
|
||||
|
||||
typedef _dart_get_latest_height = CResult_u32 Function();
|
||||
|
||||
typedef _c_ledger_build_keys = CResult_u8 Function();
|
||||
|
||||
typedef _dart_ledger_build_keys = CResult_u8 Function();
|
||||
|
||||
typedef _c_ledger_get_fvk = CResult_____c_char Function(
|
||||
typedef _c_get_latest_height = CResult_u32 Function(
|
||||
ffi.Uint8 coin,
|
||||
);
|
||||
|
||||
typedef _dart_ledger_get_fvk = CResult_____c_char Function(
|
||||
typedef _dart_get_latest_height = CResult_u32 Function(
|
||||
int coin,
|
||||
);
|
||||
|
||||
typedef _c_ledger_get_address = CResult_____c_char Function();
|
||||
|
||||
typedef _dart_ledger_get_address = CResult_____c_char Function();
|
||||
|
||||
typedef _c_skip_to_last_height = ffi.Void Function(
|
||||
ffi.Uint8 coin,
|
||||
);
|
||||
|
@ -2042,10 +2017,12 @@ typedef _dart_rewind_to = CResult_u32 Function(
|
|||
);
|
||||
|
||||
typedef _c_rescan_from = ffi.Void Function(
|
||||
ffi.Uint8 coin,
|
||||
ffi.Uint32 height,
|
||||
);
|
||||
|
||||
typedef _dart_rescan_from = void Function(
|
||||
int coin,
|
||||
int height,
|
||||
);
|
||||
|
||||
|
@ -2162,10 +2139,12 @@ typedef _dart_sign_and_broadcast = CResult_____c_char Function(
|
|||
);
|
||||
|
||||
typedef _c_broadcast_tx = CResult_____c_char Function(
|
||||
ffi.Uint8 coin,
|
||||
ffi.Pointer<ffi.Int8> tx_str,
|
||||
);
|
||||
|
||||
typedef _dart_broadcast_tx = CResult_____c_char Function(
|
||||
int coin,
|
||||
ffi.Pointer<ffi.Int8> tx_str,
|
||||
);
|
||||
|
||||
|
@ -2204,12 +2183,14 @@ typedef _dart_get_block_by_time = CResult_u32 Function(
|
|||
);
|
||||
|
||||
typedef _c_sync_historical_prices = CResult_u32 Function(
|
||||
ffi.Uint8 coin,
|
||||
ffi.Int64 now,
|
||||
ffi.Uint32 days,
|
||||
ffi.Pointer<ffi.Int8> currency,
|
||||
);
|
||||
|
||||
typedef _dart_sync_historical_prices = CResult_u32 Function(
|
||||
int coin,
|
||||
int now,
|
||||
int days,
|
||||
ffi.Pointer<ffi.Int8> currency,
|
||||
|
|
|
@ -30,7 +30,7 @@ ffigen:
|
|||
- '../../native/zcash-sync/binding.h'
|
||||
# On MacOS
|
||||
llvm-path:
|
||||
- '/opt/homebrew/Cellar/llvm/15.0.7_1'
|
||||
- '/opt/homebrew/Cellar/llvm/16.0.5'
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.4.1+447
|
||||
version: 1.4.1+454
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
@ -147,6 +147,7 @@ flutter:
|
|||
- assets/multipay.svg
|
||||
- assets/ycash.png
|
||||
- assets/zcash.png
|
||||
- assets/bitcoin.png
|
||||
- assets/success.mp3
|
||||
- assets/fail.mp3
|
||||
- assets/ding.mp3
|
||||
|
|
Loading…
Reference in New Issue