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;
|
short_tx_id:string;
|
||||||
timestamp:uint32;
|
timestamp:uint32;
|
||||||
name:string;
|
name:string;
|
||||||
value:uint64;
|
value:int64;
|
||||||
address:string;
|
address:string;
|
||||||
memo:string;
|
memo:string;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,48 @@ table ShieldedTxVec {
|
||||||
txs:[ShieldedTx];
|
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 {
|
table Message {
|
||||||
id_msg:uint32;
|
id_msg:uint32;
|
||||||
id_tx:uint32;
|
id_tx:uint32;
|
||||||
|
|
|
@ -25,6 +25,11 @@ class _AccountState extends State<AccountPage>
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true; //Set to true
|
bool get wantKeepAlive => true; //Set to true
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
if (!_hasAddress(active.addrMode)) active.addrMode = _getNextMode();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
|
@ -182,7 +187,7 @@ class QRAddressState extends State<QRAddressWidget> {
|
||||||
final simpleMode = settings.simpleMode;
|
final simpleMode = settings.simpleMode;
|
||||||
final address = _address();
|
final address = _address();
|
||||||
final shortAddress = centerTrim(address);
|
final shortAddress = centerTrim(address);
|
||||||
final addrMode = active.addrMode;
|
var addrMode = active.addrMode;
|
||||||
final qrSize = getScreenSize(context) / 2.5;
|
final qrSize = getScreenSize(context) / 2.5;
|
||||||
final coinDef = active.coinDef;
|
final coinDef = active.coinDef;
|
||||||
final nextMode = _getNextMode();
|
final nextMode = _getNextMode();
|
||||||
|
@ -199,7 +204,7 @@ class QRAddressState extends State<QRAddressWidget> {
|
||||||
child: QrImage(
|
child: QrImage(
|
||||||
data: address,
|
data: address,
|
||||||
size: qrSize,
|
size: qrSize,
|
||||||
embeddedImage: coinDef.image,
|
embeddedImage: AssetImage(coinDef.image),
|
||||||
backgroundColor: Colors.white))),
|
backgroundColor: Colors.white))),
|
||||||
Padding(padding: EdgeInsets.symmetric(vertical: 8)),
|
Padding(padding: EdgeInsets.symmetric(vertical: 8)),
|
||||||
RichText(
|
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) {
|
String? _getTapMessage(int mode) {
|
||||||
final s = S.of(context);
|
final s = S.of(context);
|
||||||
switch (mode) {
|
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');
|
_getBalanceLo(int b) => (b.abs() % 100000).toString().padLeft(5, '0');
|
||||||
|
|
||||||
_sign(int b) => b < 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;
|
break;
|
||||||
}
|
}
|
||||||
final weight = a.active ? FontWeight.bold : FontWeight.normal;
|
final weight = a.active ? FontWeight.bold : FontWeight.normal;
|
||||||
|
final def = settings.coins[a.coin].def;
|
||||||
final zbal = a.balance / ZECUNIT;
|
final zbal = a.balance / ZECUNIT;
|
||||||
final tbal = a.tbalance / ZECUNIT;
|
final tbal = def.coin < 2 ? a.tbalance / ZECUNIT : 0.0;
|
||||||
final balance = zbal + tbal;
|
final balance = zbal + tbal;
|
||||||
return Card(
|
return Card(
|
||||||
child: Dismissible(
|
child: Dismissible(
|
||||||
key: Key(a.name),
|
key: Key(a.name),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: CircleAvatar(
|
leading:
|
||||||
backgroundImage: settings.coins[a.coin].def.image),
|
CircleAvatar(backgroundImage: AssetImage(def.image)),
|
||||||
title: RichText(
|
title: RichText(
|
||||||
text: TextSpan(children: [
|
text: TextSpan(children: [
|
||||||
TextSpan(
|
TextSpan(
|
||||||
|
|
|
@ -162,6 +162,8 @@ abstract class _ActiveAccount with Store {
|
||||||
return AccountId(coin, id);
|
return AccountId(coin, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get isPrivate => coin < 2;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
Future<void> restore() async {
|
Future<void> restore() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
@ -234,7 +236,7 @@ abstract class _ActiveAccount with Store {
|
||||||
@action
|
@action
|
||||||
void updateTBalance() {
|
void updateTBalance() {
|
||||||
try {
|
try {
|
||||||
tbalance = WarpApi.getTBalance();
|
tbalance = WarpApi.getTBalance(active.coin, active.id);
|
||||||
} on String {}
|
} on String {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,13 +370,15 @@ abstract class _ActiveAccount with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void excludeNote(Note note) {
|
void excludeNote(Note note) {
|
||||||
WarpApi.updateExcluded(coin, note.id, note.excluded);
|
if (active.isPrivate) WarpApi.updateExcluded(coin, note.id, note.excluded);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void invertExcludedNotes() {
|
void invertExcludedNotes() {
|
||||||
WarpApi.invertExcluded(coin, id);
|
if (active.isPrivate) {
|
||||||
notes = notes.map((n) => n.invertExcluded).toList();
|
WarpApi.invertExcluded(coin, id);
|
||||||
|
notes = notes.map((n) => n.invertExcluded).toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|
122
lib/budget.dart
122
lib/budget.dart
|
@ -31,22 +31,26 @@ class BudgetState extends State<BudgetWidget>
|
||||||
final _ = active.dataEpoch;
|
final _ = active.dataEpoch;
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
Card(
|
if (active.isPrivate)
|
||||||
child: Column(children: [
|
Card(
|
||||||
Text(S.of(context).largestSpendingsByAddress,
|
child: Column(children: [
|
||||||
style: Theme.of(context).textTheme.titleLarge),
|
Text(S.of(context).largestSpendingsByAddress,
|
||||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
BudgetChart(),
|
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||||
])),
|
BudgetChart(),
|
||||||
|
])),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Card(
|
child: Card(
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
Text(S.of(context).accountBalanceHistory,
|
Text(S.of(context).accountBalanceHistory,
|
||||||
style: Theme.of(context).textTheme.titleLarge),
|
style: Theme.of(context).textTheme.titleLarge),
|
||||||
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
Padding(padding: EdgeInsets.symmetric(vertical: 4)),
|
||||||
Expanded(child: Padding(padding: EdgeInsets.only(right: 20),
|
Expanded(
|
||||||
child: LineChartTimeSeries.fromTimeSeries(active.accountBalances)))
|
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);
|
super.build(context);
|
||||||
return IconTheme.merge(
|
return IconTheme.merge(
|
||||||
data: IconThemeData(opacity: 0.54),
|
data: IconThemeData(opacity: 0.54),
|
||||||
child:
|
child: Column(children: [
|
||||||
Column(children: [
|
|
||||||
Row(children: [
|
Row(children: [
|
||||||
Expanded(child:
|
Expanded(
|
||||||
FormBuilderRadioGroup(
|
child: FormBuilderRadioGroup(
|
||||||
orientation: OptionsOrientation.horizontal,
|
orientation: OptionsOrientation.horizontal,
|
||||||
name: S.of(context).pnl,
|
name: S.of(context).pnl,
|
||||||
initialValue: active.pnlSeriesIndex,
|
initialValue: active.pnlSeriesIndex,
|
||||||
onChanged: (int? v) {
|
onChanged: (int? v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
active.setPnlSeriesIndex(v!);
|
active.setPnlSeriesIndex(v!);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).price), value: 0),
|
FormBuilderFieldOption(
|
||||||
|
child: Text(S.of(context).price), value: 0),
|
||||||
FormBuilderFieldOption(
|
FormBuilderFieldOption(
|
||||||
child: Text(S.of(context).realized), value: 1),
|
child: Text(S.of(context).realized), value: 1),
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).mm), value: 2),
|
FormBuilderFieldOption(
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).total), value: 3),
|
child: Text(S.of(context).mm), value: 2),
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).qty), value: 4),
|
FormBuilderFieldOption(
|
||||||
FormBuilderFieldOption(child: Text(S.of(context).table), value: 5),
|
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)),
|
IconButton(onPressed: _onExport, icon: Icon(Icons.save)),
|
||||||
]),
|
]),
|
||||||
|
@ -97,21 +105,23 @@ class PnLState extends State<PnLWidget> with AutomaticKeepAliveClientMixin {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.only(right: 20),
|
padding: EdgeInsets.only(right: 20),
|
||||||
child: active.pnlSeriesIndex != 5
|
child: active.pnlSeriesIndex != 5
|
||||||
? PnLChart(
|
? PnLChart(active.pnls, active.pnlSeriesIndex)
|
||||||
active.pnls, active.pnlSeriesIndex)
|
|
||||||
: PnLTable()));
|
: PnLTable()));
|
||||||
})
|
})
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onExport() async {
|
_onExport() async {
|
||||||
final csvData = active.pnlSorted.map((pnl) => [
|
final csvData = active.pnlSorted
|
||||||
pnl.timestamp,
|
.map((pnl) => [
|
||||||
pnl.amount,
|
pnl.timestamp,
|
||||||
pnl.price,
|
pnl.amount,
|
||||||
pnl.realized,
|
pnl.price,
|
||||||
pnl.unrealized,
|
pnl.realized,
|
||||||
pnl.realized + pnl.unrealized]).toList();
|
pnl.unrealized,
|
||||||
|
pnl.realized + pnl.unrealized
|
||||||
|
])
|
||||||
|
.toList();
|
||||||
await shareCsv(csvData, 'pnl_history.csv', S.of(context).pnlHistory);
|
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) {
|
List<PnL> data, int index, BuildContext context) {
|
||||||
return data
|
return data
|
||||||
.map((pnl) => TimeSeriesPoint(
|
.map((pnl) => TimeSeriesPoint(
|
||||||
pnl.timestamp.millisecondsSinceEpoch ~/ DAY_MS,
|
pnl.timestamp.millisecondsSinceEpoch ~/ DAY_MS,
|
||||||
_seriesData(pnl, index)))
|
_seriesData(pnl, index)))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,10 +237,13 @@ class BudgetChartState extends State<BudgetChart> {
|
||||||
return Observer(
|
return Observer(
|
||||||
builder: (context) => Padding(
|
builder: (context) => Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||||
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
child: Column(
|
||||||
HorizontalBarChart(active.spendings.map((s) => s.amount / ZECUNIT).toList()),
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
BudgetTable(active.spendings)
|
children: [
|
||||||
])));
|
HorizontalBarChart(
|
||||||
|
active.spendings.map((s) => s.amount / ZECUNIT).toList()),
|
||||||
|
BudgetTable(active.spendings)
|
||||||
|
])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,17 +254,24 @@ class BudgetTable extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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 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!;
|
final recipient = e.value.recipient!;
|
||||||
return TableRow(children: [
|
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)
|
Text(decimalFormat(e.value.amount / ZECUNIT, 8), style: style)
|
||||||
]);
|
]);
|
||||||
}).toList();
|
}).toList();
|
||||||
return Table(
|
return Table(
|
||||||
columnWidths: { 0: FlexColumnWidth(), 1: IntrinsicColumnWidth() },
|
columnWidths: {0: FlexColumnWidth(), 1: IntrinsicColumnWidth()},
|
||||||
children: rows);
|
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 {
|
abstract class CoinBase {
|
||||||
String get name;
|
String get name;
|
||||||
int get coin;
|
int get coin;
|
||||||
String get app;
|
|
||||||
String get symbol;
|
String get symbol;
|
||||||
String get currency;
|
String get currency;
|
||||||
String get ticker;
|
String get ticker;
|
||||||
int get coinIndex;
|
int get coinIndex;
|
||||||
AssetImage get image;
|
String get image;
|
||||||
String get dbName;
|
String get dbName;
|
||||||
late String dbDir;
|
late String dbDir;
|
||||||
late String dbFullPath;
|
late String dbFullPath;
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import 'coin.dart';
|
import 'coin.dart';
|
||||||
import 'ycash.dart';
|
import 'ycash.dart';
|
||||||
import 'zcash.dart';
|
import 'zcash.dart';
|
||||||
import 'zcashtest.dart';
|
import 'btc.dart';
|
||||||
|
|
||||||
CoinBase ycash = YcashCoin();
|
CoinBase ycash = YcashCoin();
|
||||||
CoinBase zcash = ZcashCoin();
|
CoinBase zcash = ZcashCoin();
|
||||||
CoinBase zcashtest = ZcashTestCoin();
|
CoinBase btc = BTCCoin();
|
||||||
|
|
||||||
final coins = [zcash, ycash];
|
|
||||||
|
|
||||||
|
final coins = [zcash, ycash, btc];
|
||||||
|
|
|
@ -5,13 +5,12 @@ import "coin.dart";
|
||||||
class YcashCoin extends CoinBase {
|
class YcashCoin extends CoinBase {
|
||||||
int coin = 1;
|
int coin = 1;
|
||||||
String name = "Ycash";
|
String name = "Ycash";
|
||||||
String app = "YWallet";
|
|
||||||
String symbol = "\u24E8";
|
String symbol = "\u24E8";
|
||||||
String currency = "ycash";
|
String currency = "ycash";
|
||||||
int coinIndex = 347;
|
int coinIndex = 347;
|
||||||
String ticker = "YEC";
|
String ticker = "YEC";
|
||||||
String dbName = "yec.db";
|
String dbName = "yec.db";
|
||||||
AssetImage image = AssetImage('assets/ycash.png');
|
String image = 'assets/ycash.png';
|
||||||
List<LWInstance> lwd = [
|
List<LWInstance> lwd = [
|
||||||
LWInstance("Lightwalletd", "https://lite.ycash.xyz:9067"),
|
LWInstance("Lightwalletd", "https://lite.ycash.xyz:9067"),
|
||||||
];
|
];
|
||||||
|
|
|
@ -5,13 +5,12 @@ import 'coin.dart';
|
||||||
class ZcashCoin extends CoinBase {
|
class ZcashCoin extends CoinBase {
|
||||||
int coin = 0;
|
int coin = 0;
|
||||||
String name = "Zcash";
|
String name = "Zcash";
|
||||||
String app = "ZWallet";
|
|
||||||
String symbol = "\u24E9";
|
String symbol = "\u24E9";
|
||||||
String currency = "zcash";
|
String currency = "zcash";
|
||||||
int coinIndex = 133;
|
int coinIndex = 133;
|
||||||
String ticker = "ZEC";
|
String ticker = "ZEC";
|
||||||
String dbName = "zec.db";
|
String dbName = "zec.db";
|
||||||
AssetImage image = AssetImage('assets/zcash.png');
|
String image = 'assets/zcash.png';
|
||||||
List<LWInstance> lwd = [
|
List<LWInstance> lwd = [
|
||||||
LWInstance("Lightwalletd", "https://mainnet.lightwalletd.com:9067"),
|
LWInstance("Lightwalletd", "https://mainnet.lightwalletd.com:9067"),
|
||||||
LWInstance("Zecwallet", "https://lwdv3.zecwallet.co"),
|
LWInstance("Zecwallet", "https://lwdv3.zecwallet.co"),
|
||||||
|
|
|
@ -5,13 +5,12 @@ import 'coin.dart';
|
||||||
class ZcashTestCoin extends CoinBase {
|
class ZcashTestCoin extends CoinBase {
|
||||||
int coin = 0;
|
int coin = 0;
|
||||||
String name = "Zcash Test";
|
String name = "Zcash Test";
|
||||||
String app = "ZWallet";
|
|
||||||
String symbol = "\u24E9";
|
String symbol = "\u24E9";
|
||||||
String currency = "zcash";
|
String currency = "zcash";
|
||||||
int coinIndex = 133;
|
int coinIndex = 133;
|
||||||
String ticker = "ZEC";
|
String ticker = "ZEC";
|
||||||
String dbName = "zec-test.db";
|
String dbName = "zec-test.db";
|
||||||
AssetImage image = AssetImage('assets/zcash.png');
|
String image = 'assets/zcash.png';
|
||||||
List<LWInstance> lwd = [
|
List<LWInstance> lwd = [
|
||||||
LWInstance("Lightwalletd", "https://testnet.lightwalletd.com:9067"),
|
LWInstance("Lightwalletd", "https://testnet.lightwalletd.com:9067"),
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:collection';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
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:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:url_launcher/url_launcher.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/data_fb_generated.dart';
|
||||||
import 'package:warp_api/warp_api.dart';
|
import 'package:warp_api/warp_api.dart';
|
||||||
import 'package:badges/badges.dart' as Badges;
|
import 'package:badges/badges.dart' as Badges;
|
||||||
|
@ -112,13 +114,34 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
TabController? _tabController;
|
TabController? _tabController;
|
||||||
int _tabIndex = 0;
|
int _tabIndex = 0;
|
||||||
final contactKey = GlobalKey<ContactsState>();
|
final contactKey = GlobalKey<ContactsState>();
|
||||||
|
List<String> tabsShown = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
if (Platform.isAndroid) _initForegroundTask();
|
if (Platform.isAndroid) _initForegroundTask();
|
||||||
final tabController =
|
var tabs = {
|
||||||
TabController(length: settings.simpleMode ? 4 : 7, vsync: this);
|
// 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(() {
|
tabController.addListener(() {
|
||||||
setState(() {
|
setState(() {
|
||||||
_tabIndex = tabController.index;
|
_tabIndex = tabController.index;
|
||||||
|
@ -133,7 +156,8 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final simpleMode = settings.simpleMode;
|
final simpleMode = settings.simpleMode;
|
||||||
|
|
||||||
final contactTabIndex = simpleMode ? 3 : 6;
|
final contactTabIndex = tabsShown.indexOf("contacts");
|
||||||
|
final messageTabIndex = tabsShown.indexOf("messages");
|
||||||
Widget button = Container();
|
Widget button = Container();
|
||||||
if (_tabIndex == 0)
|
if (_tabIndex == 0)
|
||||||
button = FloatingActionButton(
|
button = FloatingActionButton(
|
||||||
|
@ -147,7 +171,7 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
backgroundColor: theme.colorScheme.secondary,
|
backgroundColor: theme.colorScheme.secondary,
|
||||||
child: Icon(Icons.add),
|
child: Icon(Icons.add),
|
||||||
);
|
);
|
||||||
else if (_tabIndex == 1)
|
else if (_tabIndex == messageTabIndex)
|
||||||
button = FloatingActionButton(
|
button = FloatingActionButton(
|
||||||
onPressed: _onSend,
|
onPressed: _onSend,
|
||||||
backgroundColor: theme.colorScheme.secondary,
|
backgroundColor: theme.colorScheme.secondary,
|
||||||
|
@ -184,13 +208,15 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
return SizedBox(); // Show a placeholder
|
return SizedBox(); // Show a placeholder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final privateCoin = active.isPrivate;
|
||||||
|
|
||||||
final menu = PopupMenuButton<String>(
|
final menu = PopupMenuButton<String>(
|
||||||
itemBuilder: (context) {
|
itemBuilder: (context) {
|
||||||
return [
|
return [
|
||||||
PopupMenuItem(child: Text(s.accounts), value: "Accounts"),
|
PopupMenuItem(child: Text(s.accounts), value: "Accounts"),
|
||||||
PopupMenuItem(child: Text(s.backup), value: "Backup"),
|
PopupMenuItem(child: Text(s.backup), value: "Backup"),
|
||||||
PopupMenuItem(child: Text(rescanMsg), value: "Rescan"),
|
PopupMenuItem(child: Text(rescanMsg), value: "Rescan"),
|
||||||
if (!simpleMode)
|
if (!simpleMode && privateCoin)
|
||||||
PopupMenuItem(child: Text(s.pools), value: "Pools"),
|
PopupMenuItem(child: Text(s.pools), value: "Pools"),
|
||||||
if (!simpleMode)
|
if (!simpleMode)
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
@ -216,18 +242,18 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
child: Text(s.broadcast), value: "Broadcast"),
|
child: Text(s.broadcast), value: "Broadcast"),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(s.multipay), value: "MultiPay"),
|
child: Text(s.multipay), value: "MultiPay"),
|
||||||
PopupMenuItem(
|
if (privateCoin)
|
||||||
child: Text(s.keyTool),
|
PopupMenuItem(
|
||||||
enabled: active.canPay,
|
child: Text(s.keyTool),
|
||||||
value: "KeyTool"),
|
enabled: active.canPay,
|
||||||
PopupMenuItem(
|
value: "KeyTool"),
|
||||||
child: Text(s.sweep),
|
if (privateCoin)
|
||||||
enabled: active.canPay,
|
PopupMenuItem(
|
||||||
value: "Sweep"),
|
child: Text(s.sweep),
|
||||||
|
enabled: active.canPay,
|
||||||
|
value: "Sweep"),
|
||||||
],
|
],
|
||||||
onSelected: _onMenu)),
|
onSelected: _onMenu)),
|
||||||
// if (!simpleMode && !isMobile())
|
|
||||||
// PopupMenuItem(child: Text(s.ledger), value: "Ledger"),
|
|
||||||
if (settings.isDeveloper)
|
if (settings.isDeveloper)
|
||||||
PopupMenuItem(child: Text(s.expert), value: "Expert"),
|
PopupMenuItem(child: Text(s.expert), value: "Expert"),
|
||||||
PopupMenuItem(child: Text(s.settings), value: "Settings"),
|
PopupMenuItem(child: Text(s.settings), value: "Settings"),
|
||||||
|
@ -252,12 +278,12 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
isScrollable: true,
|
isScrollable: true,
|
||||||
tabs: [
|
tabs: [
|
||||||
Tab(text: s.account),
|
Tab(text: s.account),
|
||||||
messageTab,
|
if (tabsShown.contains("messages")) messageTab,
|
||||||
if (!simpleMode) Tab(text: s.notes),
|
if (tabsShown.contains("notes")) Tab(text: s.notes),
|
||||||
Tab(text: s.history),
|
if (tabsShown.contains("history")) Tab(text: s.history),
|
||||||
if (!simpleMode) Tab(text: s.budget),
|
if (tabsShown.contains("budget")) Tab(text: s.budget),
|
||||||
if (!simpleMode) Tab(text: s.tradingPl),
|
if (tabsShown.contains("pnl")) Tab(text: s.tradingPl),
|
||||||
Tab(text: s.contacts),
|
if (tabsShown.contains("contacts")) Tab(text: s.contacts),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
actions: [menu],
|
actions: [menu],
|
||||||
|
@ -266,12 +292,12 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
children: [
|
children: [
|
||||||
AccountPage(),
|
AccountPage(),
|
||||||
MessageWidget(messageKey),
|
if (tabsShown.contains("messages")) MessageWidget(messageKey),
|
||||||
if (!simpleMode) NoteWidget(),
|
if (tabsShown.contains("notes")) NoteWidget(),
|
||||||
HistoryWidget(),
|
if (tabsShown.contains("history")) HistoryWidget(),
|
||||||
if (!simpleMode) BudgetWidget(),
|
if (tabsShown.contains("budget")) BudgetWidget(),
|
||||||
if (!simpleMode) PnLWidget(),
|
if (tabsShown.contains("pnl")) PnLWidget(),
|
||||||
ContactsTab(key: contactKey),
|
if (tabsShown.contains("contacts")) ContactsTab(key: contactKey),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
floatingActionButton: button,
|
floatingActionButton: button,
|
||||||
|
@ -492,7 +518,7 @@ class HomeInnerState extends State<HomeInnerPage>
|
||||||
|
|
||||||
if (rawTx != null) {
|
if (rawTx != null) {
|
||||||
try {
|
try {
|
||||||
final res = WarpApi.broadcast(rawTx);
|
final res = WarpApi.broadcast(active.coin, rawTx);
|
||||||
showSnackBar(res);
|
showSnackBar(res);
|
||||||
} on String catch (e) {
|
} on String catch (e) {
|
||||||
showSnackBar(e, error: true);
|
showSnackBar(e, error: true);
|
||||||
|
|
|
@ -12,12 +12,17 @@ class NoteWidget extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Observer(builder: (context) {
|
return Observer(builder: (context) {
|
||||||
switch (settings.noteView) {
|
switch (settings.noteView) {
|
||||||
case ViewStyle.Table: return NoteTable();
|
case ViewStyle.Table:
|
||||||
case ViewStyle.List: return NoteList();
|
return NoteTable();
|
||||||
case ViewStyle.Auto: return OrientationBuilder(builder: (context, orientation) {
|
case ViewStyle.List:
|
||||||
if (orientation == Orientation.portrait) return NoteList();
|
return NoteList();
|
||||||
else return NoteTable();
|
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();
|
State<StatefulWidget> createState() => _NoteTableState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NoteTableState extends State<NoteTable> with AutomaticKeepAliveClientMixin {
|
class _NoteTableState extends State<NoteTable>
|
||||||
|
with AutomaticKeepAliveClientMixin {
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true; //Set to true
|
bool get wantKeepAlive => true; //Set to true
|
||||||
|
|
||||||
|
@ -77,7 +83,9 @@ class _NoteTableState extends State<NoteTable> with AutomaticKeepAliveClientMixi
|
||||||
header: Text(S.of(context).selectNotesToExcludeFromPayments,
|
header: Text(S.of(context).selectNotesToExcludeFromPayments,
|
||||||
style: Theme.of(context).textTheme.bodyMedium),
|
style: Theme.of(context).textTheme.bodyMedium),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(onPressed: _selectInverse, icon: Icon(MdiIcons.selectInverse)),
|
IconButton(
|
||||||
|
onPressed: _selectInverse,
|
||||||
|
icon: Icon(MdiIcons.selectInverse)),
|
||||||
],
|
],
|
||||||
columnSpacing: 16,
|
columnSpacing: 16,
|
||||||
showCheckboxColumn: false,
|
showCheckboxColumn: false,
|
||||||
|
@ -93,6 +101,7 @@ class _NoteTableState extends State<NoteTable> with AutomaticKeepAliveClientMixi
|
||||||
}
|
}
|
||||||
|
|
||||||
_onRowSelected(Note note) {
|
_onRowSelected(Note note) {
|
||||||
|
if (!active.isPrivate) return;
|
||||||
active.excludeNote(note);
|
active.excludeNote(note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,8 +130,7 @@ class NotesDataSource extends DataTableSource {
|
||||||
|
|
||||||
if (note.spent)
|
if (note.spent)
|
||||||
style = style.merge(TextStyle(decoration: TextDecoration.lineThrough));
|
style = style.merge(TextStyle(decoration: TextDecoration.lineThrough));
|
||||||
if (note.orchard)
|
if (note.orchard) style = style.merge(TextStyle(color: theme.primaryColor));
|
||||||
style = style.merge(TextStyle(color: theme.primaryColor));
|
|
||||||
|
|
||||||
final amountStyle = weightFromAmount(style, note.value);
|
final amountStyle = weightFromAmount(style, note.value);
|
||||||
|
|
||||||
|
@ -135,7 +143,8 @@ class NotesDataSource extends DataTableSource {
|
||||||
: theme.colorScheme.background),
|
: theme.colorScheme.background),
|
||||||
cells: [
|
cells: [
|
||||||
DataCell(Text("$confsOrHeight", style: style)),
|
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)),
|
DataCell(Text(decimalFormat(note.value, 8), style: amountStyle)),
|
||||||
],
|
],
|
||||||
onSelectChanged: (selected) => _noteSelected(note, selected),
|
onSelectChanged: (selected) => _noteSelected(note, selected),
|
||||||
|
@ -152,6 +161,7 @@ class NotesDataSource extends DataTableSource {
|
||||||
int get selectedRowCount => 0;
|
int get selectedRowCount => 0;
|
||||||
|
|
||||||
void _noteSelected(Note note, bool? selected) {
|
void _noteSelected(Note note, bool? selected) {
|
||||||
|
if (!active.isPrivate) return;
|
||||||
note.excluded = !note.excluded;
|
note.excluded = !note.excluded;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
onRowSelected(note);
|
onRowSelected(note);
|
||||||
|
@ -170,21 +180,24 @@ class NoteListState extends State<NoteList> with AutomaticKeepAliveClientMixin {
|
||||||
final s = S.of(context);
|
final s = S.of(context);
|
||||||
return Observer(builder: (context) {
|
return Observer(builder: (context) {
|
||||||
final notes = active.sortedNotes;
|
final notes = active.sortedNotes;
|
||||||
return Padding(padding: EdgeInsets.all(16), child: CustomScrollView(
|
return Padding(
|
||||||
key: UniqueKey(),
|
padding: EdgeInsets.all(16),
|
||||||
slivers: [
|
child: CustomScrollView(
|
||||||
SliverToBoxAdapter(child: ListTile(
|
key: UniqueKey(),
|
||||||
onTap: _onInvert,
|
slivers: [
|
||||||
title: Text(s.selectNotesToExcludeFromPayments),
|
SliverToBoxAdapter(
|
||||||
trailing: Icon(Icons.select_all),
|
child: ListTile(
|
||||||
)),
|
onTap: _onInvert,
|
||||||
SliverFixedExtentList(
|
title: Text(s.selectNotesToExcludeFromPayments),
|
||||||
itemExtent: 50,
|
trailing: Icon(Icons.select_all),
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
)),
|
||||||
return NoteItem(notes[index], index);
|
SliverFixedExtentList(
|
||||||
}, childCount: notes.length))
|
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)));
|
style = style.merge(TextStyle(color: style.color!.withOpacity(0.5)));
|
||||||
if (note.spent)
|
if (note.spent)
|
||||||
style = style.merge(TextStyle(decoration: TextDecoration.lineThrough));
|
style = style.merge(TextStyle(decoration: TextDecoration.lineThrough));
|
||||||
if (note.orchard)
|
if (note.orchard) style = style.merge(TextStyle(color: theme.primaryColor));
|
||||||
style = style.merge(TextStyle(color: theme.primaryColor));
|
|
||||||
|
|
||||||
final amountStyle = weightFromAmount(style, note.value);
|
final amountStyle = weightFromAmount(style, note.value);
|
||||||
|
|
||||||
return GestureDetector(onTap: _onSelected, behavior: HitTestBehavior.opaque, child:
|
return GestureDetector(
|
||||||
ColoredBox(color: excluded ? theme.primaryColor.withOpacity(0.5) : theme.colorScheme.background, child:
|
onTap: _onSelected,
|
||||||
Padding(padding: EdgeInsets.all(8), child:
|
behavior: HitTestBehavior.opaque,
|
||||||
Row(children: [
|
child: ColoredBox(
|
||||||
Column(children: [Text("${note.height}", style: theme.textTheme.bodySmall),
|
color: excluded
|
||||||
Text("$confirmations", style: theme.textTheme.bodyMedium),
|
? theme.primaryColor.withOpacity(0.5)
|
||||||
]),
|
: theme.colorScheme.background,
|
||||||
Expanded(child: Center(child: Text("${note.value}", style: amountStyle))),
|
child: Padding(
|
||||||
Text("$timestamp"),
|
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() {
|
_onSelected() {
|
||||||
|
if (!active.isPrivate) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
excluded = !excluded;
|
excluded = !excluded;
|
||||||
widget.note.excluded = excluded;
|
widget.note.excluded = excluded;
|
||||||
|
@ -254,4 +276,3 @@ class NoteItemState extends State<NoteItem> {
|
||||||
bool confirmed(int height) {
|
bool confirmed(int height) {
|
||||||
return syncStatus.latestHeight - height >= settings.anchorOffset;
|
return syncStatus.latestHeight - height >= settings.anchorOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ final rescanKey = GlobalKey<RescanFormState>();
|
||||||
|
|
||||||
Future<int?> rescanDialog(BuildContext context) async {
|
Future<int?> rescanDialog(BuildContext context) async {
|
||||||
try {
|
try {
|
||||||
|
if (active.coin >= 2) return 0;
|
||||||
DateTime minDate = WarpApi.getActivationDate();
|
DateTime minDate = WarpApi.getActivationDate();
|
||||||
final bool approved = await showDialog<bool>(
|
final bool approved = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
@ -36,6 +36,14 @@ class _AddAccountPageState extends State<AddAccountPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final s = S.of(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(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(s.newAccount),
|
title: Text(s.newAccount),
|
||||||
|
@ -70,22 +78,7 @@ class _AddAccountPageState extends State<AddAccountPage> {
|
||||||
_coin = v!;
|
_coin = v!;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
options: [
|
options: 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),
|
|
||||||
]),
|
|
||||||
FormBuilderCheckbox(
|
FormBuilderCheckbox(
|
||||||
name: 'restore',
|
name: 'restore',
|
||||||
title: Text(s.restoreAnAccount),
|
title: Text(s.restoreAnAccount),
|
||||||
|
|
119
lib/send.dart
119
lib/send.dart
|
@ -101,8 +101,10 @@ class SendState extends State<SendPage> {
|
||||||
_setPaymentURI(uri);
|
_setPaymentURI(uri);
|
||||||
});
|
});
|
||||||
|
|
||||||
final templateIds = active.dbReader.loadTemplates();
|
if (active.isPrivate) {
|
||||||
_templates = templateIds;
|
final templateIds = active.dbReader.loadTemplates();
|
||||||
|
_templates = templateIds;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -214,64 +216,67 @@ class SendState extends State<SendPage> {
|
||||||
if (!simpleMode)
|
if (!simpleMode)
|
||||||
BalanceTable(_sBalance, _tBalance, _excludedBalance,
|
BalanceTable(_sBalance, _tBalance, _excludedBalance,
|
||||||
_underConfirmedBalance, change, _usedBalance, _fee),
|
_underConfirmedBalance, change, _usedBalance, _fee),
|
||||||
Container(
|
if (active.isPrivate)
|
||||||
child: InputDecorator(
|
Container(
|
||||||
decoration: InputDecoration(labelText: s.memo),
|
child: InputDecorator(
|
||||||
child: Column(children: [
|
decoration: InputDecoration(labelText: s.memo),
|
||||||
FormBuilderCheckbox(
|
child: Column(children: [
|
||||||
key: UniqueKey(),
|
FormBuilderCheckbox(
|
||||||
name: 'reply-to',
|
key: UniqueKey(),
|
||||||
title: Text(s.includeReplyTo),
|
name: 'reply-to',
|
||||||
initialValue: _replyTo,
|
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) {
|
onChanged: (v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_replyTo = v ?? false;
|
_template = v;
|
||||||
});
|
});
|
||||||
},
|
})),
|
||||||
),
|
addReset,
|
||||||
TextFormField(
|
IconButton(
|
||||||
decoration:
|
onPressed:
|
||||||
InputDecoration(labelText: s.subject),
|
_template != null ? _openTemplate : null,
|
||||||
controller: _subjectController,
|
icon: Icon(Icons.open_in_new)),
|
||||||
),
|
IconButton(
|
||||||
TextFormField(
|
onPressed: _template != null
|
||||||
decoration:
|
? () {
|
||||||
InputDecoration(labelText: s.body),
|
_saveTemplate(_template!.id,
|
||||||
minLines: 4,
|
_template!.title!, true);
|
||||||
maxLines: null,
|
}
|
||||||
keyboardType: TextInputType.multiline,
|
: null,
|
||||||
controller: _memoController,
|
icon: Icon(Icons.save)),
|
||||||
)
|
IconButton(
|
||||||
]))),
|
onPressed:
|
||||||
Padding(padding: EdgeInsets.all(8)),
|
_template != null ? _deleteTemplate : null,
|
||||||
Row(children: [
|
icon: Icon(Icons.delete)),
|
||||||
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)),
|
|
||||||
]),
|
|
||||||
Padding(padding: EdgeInsets.all(8)),
|
Padding(padding: EdgeInsets.all(8)),
|
||||||
ButtonBar(children: [
|
ButtonBar(children: [
|
||||||
ElevatedButton.icon(
|
ElevatedButton.icon(
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
import 'package:velocity_x/velocity_x.dart';
|
||||||
import 'package:queue/queue.dart';
|
import 'package:queue/queue.dart';
|
||||||
import 'package:shared_preferences_android/shared_preferences_android.dart';
|
import 'package:shared_preferences_android/shared_preferences_android.dart';
|
||||||
import 'package:shared_preferences_ios/shared_preferences_ios.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 'package:sensors_plus/sensors_plus.dart';
|
||||||
|
|
||||||
import 'coin/coin.dart';
|
import 'coin/coin.dart';
|
||||||
|
import 'coin/coins.dart' as Coins;
|
||||||
import 'generated/l10n.dart';
|
import 'generated/l10n.dart';
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
|
|
||||||
|
@ -92,7 +94,10 @@ abstract class _Settings with Store {
|
||||||
@observable
|
@observable
|
||||||
bool simpleMode = true;
|
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
|
@observable
|
||||||
String version = "1.0.0";
|
String version = "1.0.0";
|
||||||
|
@ -636,8 +641,8 @@ abstract class _PriceStore with Store {
|
||||||
if (f ||
|
if (f ||
|
||||||
_lastChartUpdateTime == null ||
|
_lastChartUpdateTime == null ||
|
||||||
now > _lastChartUpdateTime + 5 * 60) {
|
now > _lastChartUpdateTime + 5 * 60) {
|
||||||
await fetchQueue
|
await fetchQueue.add(
|
||||||
.add(() => WarpApi.syncHistoricalPrices(settings.currency));
|
() => WarpApi.syncHistoricalPrices(active.coin, settings.currency));
|
||||||
active.fetchChartData();
|
active.fetchChartData();
|
||||||
lastChartUpdateTime = now;
|
lastChartUpdateTime = now;
|
||||||
}
|
}
|
||||||
|
@ -739,7 +744,7 @@ abstract class _SyncStatus with Store {
|
||||||
if (url.isNotEmpty) WarpApi.updateLWD(active.coin, url);
|
if (url.isNotEmpty) WarpApi.updateLWD(active.coin, url);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
latestHeight = await WarpApi.getLatestHeight();
|
latestHeight = await WarpApi.getLatestHeight(active.coin);
|
||||||
} on String {}
|
} on String {}
|
||||||
final _syncedInfo = getDbSyncedHeight();
|
final _syncedInfo = getDbSyncedHeight();
|
||||||
// if syncedHeight = 0, we just started sync therefore don't set it back to null
|
// 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));
|
showSnackBar(S.current.rescanRequested(height));
|
||||||
syncedHeight = height;
|
syncedHeight = height;
|
||||||
timestamp = null;
|
timestamp = null;
|
||||||
WarpApi.rescanFrom(height);
|
WarpApi.rescanFrom(active.coin, height);
|
||||||
await sync(true);
|
await sync(true);
|
||||||
final rh = pendingRescanHeight;
|
final rh = pendingRescanHeight;
|
||||||
if (rh != null) {
|
if (rh != null) {
|
||||||
|
|
|
@ -50,17 +50,20 @@ class TransactionState extends State<TransactionPage> {
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(S.of(context).amount),
|
title: Text(S.of(context).amount),
|
||||||
subtitle: SelectableText(decimalFormat(tx.value, 8))),
|
subtitle: SelectableText(decimalFormat(tx.value, 8))),
|
||||||
ListTile(
|
if (active.isPrivate)
|
||||||
title: Text(S.of(context).address),
|
ListTile(
|
||||||
subtitle: SelectableText('${tx.address}'),
|
title: Text(S.of(context).address),
|
||||||
trailing: IconButton(
|
subtitle: SelectableText('${tx.address}'),
|
||||||
icon: Icon(Icons.contacts), onPressed: _addContact)),
|
trailing: IconButton(
|
||||||
ListTile(
|
icon: Icon(Icons.contacts), onPressed: _addContact)),
|
||||||
title: Text(S.of(context).contactName),
|
if (active.isPrivate)
|
||||||
subtitle: SelectableText('${tx.contact ?? "N/A"}')),
|
ListTile(
|
||||||
ListTile(
|
title: Text(S.of(context).contactName),
|
||||||
title: Text(S.of(context).memo),
|
subtitle: SelectableText('${tx.contact ?? "N/A"}')),
|
||||||
subtitle: SelectableText('${tx.memo}')),
|
if (active.isPrivate)
|
||||||
|
ListTile(
|
||||||
|
title: Text(S.of(context).memo),
|
||||||
|
subtitle: SelectableText('${tx.memo}')),
|
||||||
ButtonBar(alignment: MainAxisAlignment.center, children: [
|
ButtonBar(alignment: MainAxisAlignment.center, children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: txIndex > 0 ? _prev : null,
|
onPressed: txIndex > 0 ? _prev : null,
|
||||||
|
|
|
@ -31,10 +31,12 @@ class TxPlanPage extends StatelessWidget {
|
||||||
.map((e) => DataRow(cells: [
|
.map((e) => DataRow(cells: [
|
||||||
DataCell(Text('...${trailing(e.address!, 12)}')),
|
DataCell(Text('...${trailing(e.address!, 12)}')),
|
||||||
DataCell(Text('${poolToString(e.pool)}')),
|
DataCell(Text('${poolToString(e.pool)}')),
|
||||||
DataCell(Text('${amountToString(e.amount, 3)}')),
|
DataCell(Text('${amountToString(e.amount, MAX_PRECISION)}')),
|
||||||
]))
|
]))
|
||||||
.toList();
|
.toList();
|
||||||
final invalidPrivacy = report.privacyLevel < settings.minPrivacyLevel;
|
final invalidPrivacy = report.privacyLevel < settings.minPrivacyLevel;
|
||||||
|
// TODO: Abstract sat into coinDef
|
||||||
|
final feeFx = decimalFormat(report.fee * priceStore.coinPrice / ZECUNIT, 2);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text('Transaction Plan')),
|
appBar: AppBar(title: Text('Transaction Plan')),
|
||||||
|
@ -60,20 +62,22 @@ class TxPlanPage extends StatelessWidget {
|
||||||
title: Text('Transparent Input'),
|
title: Text('Transparent Input'),
|
||||||
trailing:
|
trailing:
|
||||||
Text(amountToString(report.transparent, MAX_PRECISION))),
|
Text(amountToString(report.transparent, MAX_PRECISION))),
|
||||||
ListTile(
|
if (active.isPrivate)
|
||||||
title: Text('Sapling Input'),
|
ListTile(
|
||||||
trailing:
|
title: Text('Sapling Input'),
|
||||||
Text(amountToString(report.sapling, MAX_PRECISION))),
|
trailing:
|
||||||
if (supportsUA)
|
Text(amountToString(report.sapling, MAX_PRECISION))),
|
||||||
|
if (active.isPrivate && supportsUA)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Orchard Input'),
|
title: Text('Orchard Input'),
|
||||||
trailing:
|
trailing:
|
||||||
Text(amountToString(report.orchard, MAX_PRECISION))),
|
Text(amountToString(report.orchard, MAX_PRECISION))),
|
||||||
ListTile(
|
if (active.isPrivate)
|
||||||
title: Text('Net Sapling Change'),
|
ListTile(
|
||||||
trailing:
|
title: Text('Net Sapling Change'),
|
||||||
Text(amountToString(report.netSapling, MAX_PRECISION))),
|
trailing:
|
||||||
if (supportsUA)
|
Text(amountToString(report.netSapling, MAX_PRECISION))),
|
||||||
|
if (active.isPrivate && supportsUA)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Net Orchard Change'),
|
title: Text('Net Orchard Change'),
|
||||||
trailing:
|
trailing:
|
||||||
|
@ -81,6 +85,9 @@ class TxPlanPage extends StatelessWidget {
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('Fee'),
|
title: Text('Fee'),
|
||||||
trailing: Text(amountToString(report.fee, MAX_PRECISION))),
|
trailing: Text(amountToString(report.fee, MAX_PRECISION))),
|
||||||
|
ListTile(
|
||||||
|
title: Text('Fee ${settings.currency}'),
|
||||||
|
trailing: Text(feeFx)),
|
||||||
privacyToString(context, report.privacyLevel)!,
|
privacyToString(context, report.privacyLevel)!,
|
||||||
if (invalidPrivacy)
|
if (invalidPrivacy)
|
||||||
Padding(
|
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);
|
String? get shortTxId => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10);
|
||||||
int get timestamp => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
|
int get timestamp => const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
|
||||||
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 14);
|
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 address => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 18);
|
||||||
String? get memo => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 20);
|
String? get memo => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 20);
|
||||||
|
|
||||||
|
@ -900,7 +900,7 @@ class ShieldedTxT implements fb.Packable {
|
||||||
fbBuilder.addOffset(3, shortTxIdOffset);
|
fbBuilder.addOffset(3, shortTxIdOffset);
|
||||||
fbBuilder.addUint32(4, timestamp);
|
fbBuilder.addUint32(4, timestamp);
|
||||||
fbBuilder.addOffset(5, nameOffset);
|
fbBuilder.addOffset(5, nameOffset);
|
||||||
fbBuilder.addUint64(6, value);
|
fbBuilder.addInt64(6, value);
|
||||||
fbBuilder.addOffset(7, addressOffset);
|
fbBuilder.addOffset(7, addressOffset);
|
||||||
fbBuilder.addOffset(8, memoOffset);
|
fbBuilder.addOffset(8, memoOffset);
|
||||||
return fbBuilder.endTable();
|
return fbBuilder.endTable();
|
||||||
|
@ -954,7 +954,7 @@ class ShieldedTxBuilder {
|
||||||
return fbBuilder.offset;
|
return fbBuilder.offset;
|
||||||
}
|
}
|
||||||
int addValue(int? value) {
|
int addValue(int? value) {
|
||||||
fbBuilder.addUint64(6, value);
|
fbBuilder.addInt64(6, value);
|
||||||
return fbBuilder.offset;
|
return fbBuilder.offset;
|
||||||
}
|
}
|
||||||
int addAddressOffset(int? offset) {
|
int addAddressOffset(int? offset) {
|
||||||
|
@ -1023,7 +1023,7 @@ class ShieldedTxObjectBuilder extends fb.ObjectBuilder {
|
||||||
fbBuilder.addOffset(3, shortTxIdOffset);
|
fbBuilder.addOffset(3, shortTxIdOffset);
|
||||||
fbBuilder.addUint32(4, _timestamp);
|
fbBuilder.addUint32(4, _timestamp);
|
||||||
fbBuilder.addOffset(5, nameOffset);
|
fbBuilder.addOffset(5, nameOffset);
|
||||||
fbBuilder.addUint64(6, _value);
|
fbBuilder.addInt64(6, _value);
|
||||||
fbBuilder.addOffset(7, addressOffset);
|
fbBuilder.addOffset(7, addressOffset);
|
||||||
fbBuilder.addOffset(8, memoOffset);
|
fbBuilder.addOffset(8, memoOffset);
|
||||||
return fbBuilder.endTable();
|
return fbBuilder.endTable();
|
||||||
|
@ -1139,6 +1139,906 @@ class ShieldedTxVecObjectBuilder extends fb.ObjectBuilder {
|
||||||
return fbBuilder.buffer;
|
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 {
|
class Message {
|
||||||
Message._(this._bc, this._bcOffset);
|
Message._(this._bc, this._bcOffset);
|
||||||
factory Message(List<int> bytes) {
|
factory Message(List<int> bytes) {
|
||||||
|
|
|
@ -117,10 +117,6 @@ class WarpApi {
|
||||||
name.toNativeUtf8().cast<Int8>(), index, count);
|
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) {
|
static void convertToWatchOnly(int coin, int id) {
|
||||||
warp_api_lib.convert_to_watchonly(coin, id);
|
warp_api_lib.convert_to_watchonly(coin, id);
|
||||||
}
|
}
|
||||||
|
@ -159,8 +155,8 @@ class WarpApi {
|
||||||
return unwrapResultU32(warp_api_lib.rewind_to(height));
|
return unwrapResultU32(warp_api_lib.rewind_to(height));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rescanFrom(int height) {
|
static void rescanFrom(int coin, int height) {
|
||||||
warp_api_lib.rescan_from(height);
|
warp_api_lib.rescan_from(coin, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int warpSync(SyncParams params) {
|
static int warpSync(SyncParams params) {
|
||||||
|
@ -174,8 +170,8 @@ class WarpApi {
|
||||||
warp_api_lib.cancel_warp();
|
warp_api_lib.cancel_warp();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<int> getLatestHeight() async {
|
static Future<int> getLatestHeight(int coin) async {
|
||||||
return await compute(getLatestHeightIsolateFn, null);
|
return await compute(getLatestHeightIsolateFn, coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validKey(int coin, String key) {
|
static int validKey(int coin, String key) {
|
||||||
|
@ -221,8 +217,8 @@ class WarpApi {
|
||||||
// recipientJson, useTransparent, anchorOffset, receivePort.sendPort));
|
// recipientJson, useTransparent, anchorOffset, receivePort.sendPort));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
static int getTBalance() {
|
static int getTBalance(int coin, int account) {
|
||||||
final balance = warp_api_lib.get_taddr_balance(0xFF, 0);
|
final balance = warp_api_lib.get_taddr_balance(coin, account);
|
||||||
return unwrapResultU64(balance);
|
return unwrapResultU64(balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,8 +299,9 @@ class WarpApi {
|
||||||
SignOnlyParams(coin, account, tx, receivePort.sendPort));
|
SignOnlyParams(coin, account, tx, receivePort.sendPort));
|
||||||
}
|
}
|
||||||
|
|
||||||
static String broadcast(String txStr) {
|
static String broadcast(int coin, String txStr) {
|
||||||
final res = warp_api_lib.broadcast_tx(txStr.toNativeUtf8().cast<Int8>());
|
final res =
|
||||||
|
warp_api_lib.broadcast_tx(coin, txStr.toNativeUtf8().cast<Int8>());
|
||||||
return unwrapResultString(res);
|
return unwrapResultString(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,9 +338,9 @@ class WarpApi {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<int> syncHistoricalPrices(String currency) async {
|
static Future<int> syncHistoricalPrices(int coin, String currency) async {
|
||||||
return await compute(
|
return await compute(syncHistoricalPricesIsolateFn,
|
||||||
syncHistoricalPricesIsolateFn, SyncHistoricalPricesParams(currency));
|
SyncHistoricalPricesParams(coin, currency));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setDbPasswd(int coin, String passwd) {
|
static void setDbPasswd(int coin, String passwd) {
|
||||||
|
@ -455,14 +452,6 @@ class WarpApi {
|
||||||
return kp;
|
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 {
|
static Future<String> ledgerSend(int coin, String txPlan) async {
|
||||||
return await compute((_) {
|
return await compute((_) {
|
||||||
return unwrapResultString(
|
return unwrapResultString(
|
||||||
|
@ -667,8 +656,8 @@ String signOnlyIsolateFn(SignOnlyParams params) {
|
||||||
return convertCString(txIdRes.value);
|
return convertCString(txIdRes.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLatestHeightIsolateFn(Null n) {
|
int getLatestHeightIsolateFn(int coin) {
|
||||||
return unwrapResultU32(warp_api_lib.get_latest_height());
|
return unwrapResultU32(warp_api_lib.get_latest_height(coin));
|
||||||
}
|
}
|
||||||
|
|
||||||
String transferPoolsIsolateFn(TransferPoolsParams params) {
|
String transferPoolsIsolateFn(TransferPoolsParams params) {
|
||||||
|
@ -689,6 +678,7 @@ int syncHistoricalPricesIsolateFn(SyncHistoricalPricesParams params) {
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final today = DateTime.utc(now.year, now.month, now.day);
|
final today = DateTime.utc(now.year, now.month, now.day);
|
||||||
return unwrapResultU32(warp_api_lib.sync_historical_prices(
|
return unwrapResultU32(warp_api_lib.sync_historical_prices(
|
||||||
|
params.coin,
|
||||||
today.millisecondsSinceEpoch ~/ 1000,
|
today.millisecondsSinceEpoch ~/ 1000,
|
||||||
365,
|
365,
|
||||||
params.currency.toNativeUtf8().cast<Int8>()));
|
params.currency.toNativeUtf8().cast<Int8>()));
|
||||||
|
@ -768,9 +758,10 @@ class TransferPoolsParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SyncHistoricalPricesParams {
|
class SyncHistoricalPricesParams {
|
||||||
|
final int coin;
|
||||||
final String currency;
|
final String currency;
|
||||||
|
|
||||||
SyncHistoricalPricesParams(this.currency);
|
SyncHistoricalPricesParams(this.coin, this.currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetTBalanceParams {
|
class GetTBalanceParams {
|
||||||
|
|
|
@ -415,8 +415,12 @@ class NativeLibrary {
|
||||||
late final _dart_get_diversified_address _get_diversified_address =
|
late final _dart_get_diversified_address _get_diversified_address =
|
||||||
_get_diversified_address_ptr.asFunction<_dart_get_diversified_address>();
|
_get_diversified_address_ptr.asFunction<_dart_get_diversified_address>();
|
||||||
|
|
||||||
CResult_u32 get_latest_height() {
|
CResult_u32 get_latest_height(
|
||||||
return _get_latest_height();
|
int coin,
|
||||||
|
) {
|
||||||
|
return _get_latest_height(
|
||||||
|
coin,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _get_latest_height_ptr =
|
late final _get_latest_height_ptr =
|
||||||
|
@ -424,37 +428,6 @@ class NativeLibrary {
|
||||||
late final _dart_get_latest_height _get_latest_height =
|
late final _dart_get_latest_height _get_latest_height =
|
||||||
_get_latest_height_ptr.asFunction<_dart_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(
|
void skip_to_last_height(
|
||||||
int coin,
|
int coin,
|
||||||
) {
|
) {
|
||||||
|
@ -483,9 +456,11 @@ class NativeLibrary {
|
||||||
_rewind_to_ptr.asFunction<_dart_rewind_to>();
|
_rewind_to_ptr.asFunction<_dart_rewind_to>();
|
||||||
|
|
||||||
void rescan_from(
|
void rescan_from(
|
||||||
|
int coin,
|
||||||
int height,
|
int height,
|
||||||
) {
|
) {
|
||||||
return _rescan_from(
|
return _rescan_from(
|
||||||
|
coin,
|
||||||
height,
|
height,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -649,9 +624,11 @@ class NativeLibrary {
|
||||||
_sign_and_broadcast_ptr.asFunction<_dart_sign_and_broadcast>();
|
_sign_and_broadcast_ptr.asFunction<_dart_sign_and_broadcast>();
|
||||||
|
|
||||||
CResult_____c_char broadcast_tx(
|
CResult_____c_char broadcast_tx(
|
||||||
|
int coin,
|
||||||
ffi.Pointer<ffi.Int8> tx_str,
|
ffi.Pointer<ffi.Int8> tx_str,
|
||||||
) {
|
) {
|
||||||
return _broadcast_tx(
|
return _broadcast_tx(
|
||||||
|
coin,
|
||||||
tx_str,
|
tx_str,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -717,11 +694,13 @@ class NativeLibrary {
|
||||||
_get_block_by_time_ptr.asFunction<_dart_get_block_by_time>();
|
_get_block_by_time_ptr.asFunction<_dart_get_block_by_time>();
|
||||||
|
|
||||||
CResult_u32 sync_historical_prices(
|
CResult_u32 sync_historical_prices(
|
||||||
|
int coin,
|
||||||
int now,
|
int now,
|
||||||
int days,
|
int days,
|
||||||
ffi.Pointer<ffi.Int8> currency,
|
ffi.Pointer<ffi.Int8> currency,
|
||||||
) {
|
) {
|
||||||
return _sync_historical_prices(
|
return _sync_historical_prices(
|
||||||
|
coin,
|
||||||
now,
|
now,
|
||||||
days,
|
days,
|
||||||
currency,
|
currency,
|
||||||
|
@ -1655,6 +1634,16 @@ const int ShieldedTx_VT_MEMO = 20;
|
||||||
|
|
||||||
const int ShieldedTxVec_VT_TXS = 4;
|
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_MSG = 4;
|
||||||
|
|
||||||
const int Message_VT_ID_TX = 6;
|
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_NET_ORCHARD = 14;
|
||||||
|
|
||||||
const int TxReport_VT_FEE = 16;
|
|
||||||
|
|
||||||
const int TxReport_VT_PRIVACY_LEVEL = 18;
|
const int TxReport_VT_PRIVACY_LEVEL = 18;
|
||||||
|
|
||||||
typedef _c_dummy_export = ffi.Void Function();
|
typedef _c_dummy_export = ffi.Void Function();
|
||||||
|
@ -2005,26 +1992,14 @@ typedef _dart_get_diversified_address = CResult_____c_char Function(
|
||||||
int time,
|
int time,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _c_get_latest_height = CResult_u32 Function();
|
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(
|
|
||||||
ffi.Uint8 coin,
|
ffi.Uint8 coin,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _dart_ledger_get_fvk = CResult_____c_char Function(
|
typedef _dart_get_latest_height = CResult_u32 Function(
|
||||||
int coin,
|
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(
|
typedef _c_skip_to_last_height = ffi.Void Function(
|
||||||
ffi.Uint8 coin,
|
ffi.Uint8 coin,
|
||||||
);
|
);
|
||||||
|
@ -2042,10 +2017,12 @@ typedef _dart_rewind_to = CResult_u32 Function(
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _c_rescan_from = ffi.Void Function(
|
typedef _c_rescan_from = ffi.Void Function(
|
||||||
|
ffi.Uint8 coin,
|
||||||
ffi.Uint32 height,
|
ffi.Uint32 height,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _dart_rescan_from = void Function(
|
typedef _dart_rescan_from = void Function(
|
||||||
|
int coin,
|
||||||
int height,
|
int height,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2162,10 +2139,12 @@ typedef _dart_sign_and_broadcast = CResult_____c_char Function(
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _c_broadcast_tx = CResult_____c_char Function(
|
typedef _c_broadcast_tx = CResult_____c_char Function(
|
||||||
|
ffi.Uint8 coin,
|
||||||
ffi.Pointer<ffi.Int8> tx_str,
|
ffi.Pointer<ffi.Int8> tx_str,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _dart_broadcast_tx = CResult_____c_char Function(
|
typedef _dart_broadcast_tx = CResult_____c_char Function(
|
||||||
|
int coin,
|
||||||
ffi.Pointer<ffi.Int8> tx_str,
|
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(
|
typedef _c_sync_historical_prices = CResult_u32 Function(
|
||||||
|
ffi.Uint8 coin,
|
||||||
ffi.Int64 now,
|
ffi.Int64 now,
|
||||||
ffi.Uint32 days,
|
ffi.Uint32 days,
|
||||||
ffi.Pointer<ffi.Int8> currency,
|
ffi.Pointer<ffi.Int8> currency,
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef _dart_sync_historical_prices = CResult_u32 Function(
|
typedef _dart_sync_historical_prices = CResult_u32 Function(
|
||||||
|
int coin,
|
||||||
int now,
|
int now,
|
||||||
int days,
|
int days,
|
||||||
ffi.Pointer<ffi.Int8> currency,
|
ffi.Pointer<ffi.Int8> currency,
|
||||||
|
|
|
@ -30,7 +30,7 @@ ffigen:
|
||||||
- '../../native/zcash-sync/binding.h'
|
- '../../native/zcash-sync/binding.h'
|
||||||
# On MacOS
|
# On MacOS
|
||||||
llvm-path:
|
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
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# 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.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.4.1+447
|
version: 1.4.1+454
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
@ -147,6 +147,7 @@ flutter:
|
||||||
- assets/multipay.svg
|
- assets/multipay.svg
|
||||||
- assets/ycash.png
|
- assets/ycash.png
|
||||||
- assets/zcash.png
|
- assets/zcash.png
|
||||||
|
- assets/bitcoin.png
|
||||||
- assets/success.mp3
|
- assets/success.mp3
|
||||||
- assets/fail.mp3
|
- assets/fail.mp3
|
||||||
- assets/ding.mp3
|
- assets/ding.mp3
|
||||||
|
|
Loading…
Reference in New Issue