From 5a0dc762fd2af6fb8538671a29ff8b3eeca90cc5 Mon Sep 17 00:00:00 2001 From: Hanh Date: Sun, 23 Oct 2022 18:30:28 +0800 Subject: [PATCH] Upgrade flutter to 3.3.8 --- Cargo.toml | 9 ++ lib/account.dart | 2 +- lib/accounts.dart | 26 ++-- lib/db.dart | 6 +- lib/devmode.dart | 5 + lib/home.dart | 5 + lib/main.dart | 7 +- lib/payment_uri.dart | 2 +- lib/send.dart | 12 +- lib/settings.dart | 55 +++++-- lib/store.dart | 38 ++++- lib/sync_chart.dart | 65 ++++++++ lib/txplan.dart | 89 +++++++++++ misc/me.hanh.zwallet.Ywallet.yml | 2 - native/zcash-params | 2 +- native/zcash-sync | 2 +- packages/warp_api_ffi/lib/types.dart | 38 +++++ packages/warp_api_ffi/lib/warp_api.dart | 42 +++-- .../warp_api_ffi/lib/warp_api_generated.dart | 145 ++++++++++++++++-- 19 files changed, 483 insertions(+), 69 deletions(-) create mode 100644 lib/sync_chart.dart create mode 100644 lib/txplan.dart diff --git a/Cargo.toml b/Cargo.toml index 81c0d21..6fb9021 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,14 @@ debug = false [patch."https://github.com/hhanh00/zcash-params.git"] zcash_params = { path = "native/zcash-params" } +[patch."https://github.com/hhanh00/librustzcash.git"] +zcash_client_backend = { path = "librustzcash/zcash_client_backend" } +zcash_primitives = { path = "librustzcash/zcash_primitives" } +zcash_proofs = { path = "librustzcash/zcash_proofs" } +zcash_address = { path = "librustzcash/components/zcash_address" } +zcash_encoding = { path = "librustzcash/components/zcash_encoding" } +zcash_note_encryption = { path = "librustzcash/components/zcash_note_encryption" } + [patch.crates-io] jubjub = { git = "https://github.com/hhanh00/jubjub.git", rev = "4a3edf3d242f368b5aa418ec659d01f191127cf3" } +zcash_note_encryption = { path = "librustzcash/components/zcash_note_encryption" } diff --git a/lib/account.dart b/lib/account.dart index e2deaef..6838498 100644 --- a/lib/account.dart +++ b/lib/account.dart @@ -288,7 +288,7 @@ class QRAddressState extends State { ? active.taddress : _useSnapAddress ? _snapAddress - : active.account.address; + : active.address; return address; } } diff --git a/lib/accounts.dart b/lib/accounts.dart index d22294c..943c6c8 100644 --- a/lib/accounts.dart +++ b/lib/accounts.dart @@ -17,15 +17,18 @@ class Account { final int coin; final int id; final String name; - final String address; final int balance; int tbalance = 0; final ShareInfo? share; - Account(this.coin, this.id, this.name, this.address, this.balance, this.tbalance, this.share); + Account(this.coin, this.id, this.name, this.balance, this.tbalance, this.share); + + String get address { + return WarpApi.getAddress(this.coin, this.id, settings.uaType); + } } -final Account emptyAccount = Account(0, 0, "", "", 0, 0, null); +final Account emptyAccount = Account(0, 0, "", 0, 0, null); class AccountManager2 = _AccountManager2 with _$AccountManager2; @@ -94,21 +97,16 @@ abstract class _AccountManager2 with Store { List accounts = []; final List res = await db.rawQuery( - "WITH notes AS (SELECT a.id_account, a.name, a.address, CASE WHEN r.spent IS NULL THEN r.value ELSE 0 END AS nv FROM accounts a LEFT JOIN received_notes r ON a.id_account = r.account)," - "accounts2 AS (SELECT id_account, name, address, COALESCE(sum(nv), 0) AS balance FROM notes GROUP by id_account) " - "SELECT a.id_account, a.name, a.address, a.balance FROM accounts2 a", + "WITH notes AS (SELECT a.id_account, a.name, CASE WHEN r.spent IS NULL THEN r.value ELSE 0 END AS nv FROM accounts a LEFT JOIN received_notes r ON a.id_account = r.account)," + "accounts2 AS (SELECT id_account, name, COALESCE(sum(nv), 0) AS balance FROM notes GROUP by id_account) " + "SELECT a.id_account, a.name, a.balance FROM accounts2 a", []); for (var r in res) { final int id = r['id_account']; - // final shareInfo = r['secret'] != null - // ? ShareInfo( - // r['idx'], r['threshold'], r['participants'], r['secret']) - // : null; // TODO: Multisig final account = Account( coin, id, r['name'], - r['address'], r['balance'], 0, null); @@ -316,7 +314,7 @@ abstract class _ActiveAccount with Store { final dbr = DbReader(coin, id); notes = await dbr.getNotes(); txs = await dbr.getTxs(); - messages = ObservableList.of(await dbr.getMessages(account.address)); + messages = ObservableList.of(await dbr.getMessages()); unread = messages.where((m) => !m.read).length; dataEpoch += 1; } @@ -474,6 +472,10 @@ abstract class _ActiveAccount with Store { void setBanner(String msg) { banner = msg; } + + String get address { // TODO + return account.address; + } } Future getBackup(AccountId account) async { diff --git a/lib/db.dart b/lib/db.dart index ef91402..a49b2f0 100644 --- a/lib/db.dart +++ b/lib/db.dart @@ -33,7 +33,7 @@ class DbReader { "SELECT SUM(value) AS value FROM received_notes WHERE account = ?1 AND spent = 0", [id])) ?? 0; final underConfirmedBalance = Sqflite.firstIntValue(await db.rawQuery( - "SELECT SUM(value) AS value FROM received_notes WHERE account = ?1 AND height > ?2", + "SELECT SUM(value) AS value FROM received_notes WHERE account = ?1 AND spent IS NULL AND height > ?2", [id, confirmHeight])) ?? 0; final excludedBalance = Sqflite.firstIntValue(await db.rawQuery( "SELECT SUM(value) FROM received_notes WHERE account = ?1 AND spent IS NULL " @@ -198,7 +198,7 @@ class DbReader { return accountBalances; } - Future> getMessages(String myAddress) async { + Future> getMessages() async { final List res = await db.rawQuery( "SELECT m.id, m.id_tx, m.timestamp, m.sender, m.recipient, c.name as scontact, a.name as saccount, c2.name as rcontact, a2.name as raccount, " "subject, body, height, read FROM messages m " @@ -221,7 +221,7 @@ class DbReader { final subject = row['subject']; final body = row['body']; final read = row['read'] == 1; - final incoming = recipient == myAddress; + final incoming = false; // TODO: How do we know the message direction when using UA? messages.add(ZMessage(id, txId, incoming, from, to, subject, body, timestamp, height, read)); } return messages; diff --git a/lib/devmode.dart b/lib/devmode.dart index 7e5a07b..f53d792 100644 --- a/lib/devmode.dart +++ b/lib/devmode.dart @@ -29,6 +29,7 @@ class DevPageState extends State { children: [ ListTile(title: Text('Import Database'), trailing: Icon(Icons.chevron_right), onTap: _importDb), ListTile(title: Text('Export Database'), trailing: Icon(Icons.chevron_right), onTap: _exportDb), + ListTile(title: Text('Sync Stats'), trailing: Icon(Icons.chevron_right), onTap: _syncStats), ListTile(title: Text('Import Sync Data'), trailing: Icon(Icons.chevron_right), onTap: _importSyncData), ListTile(title: Text('Reset Scan State'), trailing: Icon(Icons.chevron_right), onTap: _resetScan), ListTile(title: Text('Reset App'), trailing: Icon(Icons.chevron_right), onTap: _resetApp), @@ -74,6 +75,10 @@ class DevPageState extends State { } } + void _syncStats() { + Navigator.of(context).pushNamed('/syncstats'); + } + Future _importSyncData() async { final s = S.of(context); diff --git a/lib/home.dart b/lib/home.dart index d456dc3..508ba96 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -77,6 +77,7 @@ class HomeState extends State { FlutterForegroundTask.updateService( notificationText: "${progress} %"); } + syncStats.add(DateTime.now(), syncedHeight.height); } else { WarpApi.mempoolReset(); } @@ -181,6 +182,7 @@ class HomeInnerState extends State with SingleTickerProviderState final menu = PopupMenuButton( itemBuilder: (context) { return [ + PopupMenuItem(child: Text('TxPlan'), value: "TxPlan"), PopupMenuItem(child: Text(s.accounts), value: "Accounts"), PopupMenuItem(child: Text(s.backup), value: "Backup"), PopupMenuItem(child: Text(rescanMsg), value: "Rescan"), @@ -254,6 +256,9 @@ class HomeInnerState extends State with SingleTickerProviderState _onMenu(String choice) { switch (choice) { + case "TxPlan": + Navigator.of(context).pushNamed('/txplan', arguments: ""); + break; case "Accounts": Navigator.of(context).pushNamed('/accounts'); break; diff --git a/lib/main.dart b/lib/main.dart index 2356865..ebaf2fe 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -55,6 +55,8 @@ import 'sign.dart'; import 'store.dart'; import 'theme_editor.dart'; import 'transaction.dart'; +import 'sync_chart.dart'; +import 'txplan.dart'; import 'welcome.dart'; const ZECUNIT = 100000000.0; @@ -76,6 +78,7 @@ var settings = Settings(); var multipayData = MultiPayStore(); var eta = ETAStore(); var contacts = ContactStore(); +var syncStats = SyncStatsStore(); var accounts = AccountManager2(); var active = ActiveAccount(); final messageKey = GlobalKey(); @@ -268,6 +271,8 @@ void main() { '/sign': (context) => Sign.init(routeSettings.arguments as String), '/keytool': (context) => KeyToolPage(), '/dev': (context) => DevPage(), + '/txplan': (context) => TxPlanPage.fromPlan(routeSettings.arguments as String), + '/syncstats': (context) => SyncChartPage(), }; return MaterialPageRoute(builder: routes[routeSettings.name]!); }, @@ -788,7 +793,7 @@ Future shieldTAddr(BuildContext context) async { final s = S.of(context); Navigator.of(context).pop(); showSnackBar(s.shieldingInProgress, autoClose: true); - final txid = await WarpApi.shieldTAddr(); + final txid = await WarpApi.shieldTAddr(active.coin, active.id); showSnackBar(s.txId(txid)); })), ); diff --git a/lib/payment_uri.dart b/lib/payment_uri.dart index a770c80..ceff8a5 100644 --- a/lib/payment_uri.dart +++ b/lib/payment_uri.dart @@ -11,7 +11,7 @@ import 'settings.dart'; class PaymentURIPage extends StatefulWidget { final String address; - PaymentURIPage(String? _address): address = _address ?? active.account.address; + PaymentURIPage(String? _address): address = _address ?? active.address; @override PaymentURIState createState() => PaymentURIState(); diff --git a/lib/send.dart b/lib/send.dart index 4a436a3..e47d404 100644 --- a/lib/send.dart +++ b/lib/send.dart @@ -497,16 +497,12 @@ Future send(BuildContext context, List recipients, bool useTran needClose = false; Navigator.of(context).pop(); active.setBanner(s.paymentInProgress); - final txId = await WarpApi.sendPayment(active.coin, active.id, recipients, - useTransparent, settings.anchorOffset, (progress) { - progressPort.sendPort.send(progress); - }); - progressPort.sendPort.send(0); - await player.play(AssetSource("success.mp3")); - showSnackBar(s.txId(txId)); + final txPlan = await WarpApi.prepareTx(active.coin, active.id, recipients, + useTransparent, settings.anchorOffset); + Navigator.pushNamed(context, '/txplan', arguments: txPlan); await active.update(); } else { - final txjson = WarpApi.prepareTx( + final txjson = WarpApi.prepareTx(active.coin, active.id, recipients, useTransparent, settings.anchorOffset); if (settings.qrOffline) { diff --git a/lib/settings.dart b/lib/settings.dart index 6931da1..655a4a8 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -43,6 +43,12 @@ class SettingsState extends State final simpleMode = settings.simpleMode; _memoController.text = settings.memoSignature ?? s.sendFrom(APP_NAME); + final uaType = settings.uaType; + List uaList = []; + if (uaType & 1 != 0) uaList.add('T'); + if (uaType & 2 != 0) uaList.add('S'); + if (uaType & 4 != 0) uaList.add('O'); + return Scaffold( appBar: AppBar(title: Text(s.settings)), body: Padding( @@ -78,14 +84,6 @@ class SettingsState extends State ServerSelect(0), ServerSelect(1) ])), - // if (!simpleMode) FormBuilderRadioGroup( - // orientation: OptionsOrientation.vertical, - // name: 'servers', - // decoration: InputDecoration( - // labelText: s.server), - // initialValue: settings.ldUrlChoice, - // onSaved: _onChoice, - // options: options), FormBuilderRadioGroup( orientation: OptionsOrientation.horizontal, name: 'themes', @@ -165,6 +163,7 @@ class SettingsState extends State // initialValue: settings.useUA, // onSaved: _onUseUA)), ]), + if (!simpleMode) FormBuilderTextField( decoration: InputDecoration( @@ -192,6 +191,19 @@ class SettingsState extends State FormBuilderFieldOption( child: Text(s.Y1), value: '1Y'), ]), + if (!simpleMode) // TODO: Only Enable for UA accounts + FormBuilderCheckboxGroup( + orientation: OptionsOrientation.horizontal, + name: 'ua', + decoration: InputDecoration(labelText: 'Main Address Type'), + initialValue: uaList, + onSaved: _onUAType, + validator: _checkUA, + options: [ + FormBuilderFieldOption(value: 'T'), + FormBuilderFieldOption(value: 'S'), + FormBuilderFieldOption(value: 'O'), + ]), if (!simpleMode) FormBuilderCheckbox( name: 'get_tx', @@ -343,10 +355,33 @@ class SettingsState extends State settings.setAutoShieldThreshold(v); } - _onUseUA(v) { - settings.setUseUA(v); + _onUAType(List? vs) { + if (vs == null) return; + final type = _unpackUAType(vs); + settings.setUAType(type); } + String? _checkUA(List? vs) { + if (vs == null) return null; + final type = _unpackUAType(vs); + if (type < 2) return "Invalid Address Type"; + return null; + } + + int _unpackUAType(List vs) { + int r = 0; + for (var v in vs) { + switch (v) { + case 'T': r |= 1; break; + case 'S': r |= 2; break; + case 'O': r |= 4; break; + } + } + return r; + } + + + _onAutoHide(v) { settings.setAutoHide(v); } diff --git a/lib/store.dart b/lib/store.dart index 438ed99..ddf350a 100644 --- a/lib/store.dart +++ b/lib/store.dart @@ -206,6 +206,9 @@ abstract class _Settings with Store { bool instantSync = false; + @observable + int uaType = 7; + @observable int developerMode = 10; @@ -250,6 +253,8 @@ abstract class _Settings with Store { final _developerMode = prefs.getBool('developer_mode') ?? false; developerMode = _developerMode ? 0 : 10; + uaType = prefs.getInt('ua_type') ?? 7; + for (var s in servers) { await s.loadPrefs(); } @@ -551,6 +556,13 @@ abstract class _Settings with Store { prefs.setString('memo_signature', v); } + @action + Future setUAType(int v) async { + final prefs = await SharedPreferences.getInstance(); + uaType = v; + prefs.setInt('ua_type', v); + } + @action Future tapDeveloperMode(BuildContext context) async { developerMode -= 1; @@ -933,6 +945,23 @@ abstract class _ContactStore with Store { } } +class SyncStatsStore = _SyncStatsStore with _$SyncStatsStore; + +abstract class _SyncStatsStore with Store { + @observable + ObservableList syncData = ObservableList.of([]); + + @action + void reset() { + syncData = ObservableList.of([]); + } + + @action + void add(DateTime now, int height) { + syncData.add(SyncDatum(now, height)); + } +} + class ETACheckpoint { int height; DateTime timestamp; @@ -1154,4 +1183,11 @@ class BlockInfo { final int height; final DateTime timestamp; BlockInfo(this.height, this.timestamp); -} \ No newline at end of file +} + +class SyncDatum { + final DateTime timestamp; // elapsed time in secs + final int height; // block time stamp + + SyncDatum(this.timestamp, this.height); +} diff --git a/lib/sync_chart.dart b/lib/sync_chart.dart new file mode 100644 index 0000000..3387cc1 --- /dev/null +++ b/lib/sync_chart.dart @@ -0,0 +1,65 @@ +import 'package:YWallet/main.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:k_chart/k_chart_widget.dart'; +import 'package:k_chart/flutter_k_chart.dart'; + +class SyncChartPage extends StatefulWidget { + @override + State createState() => SyncChartState(); +} + +class SyncChartState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('Sync Stats')), + body: Column(children: [ + Expanded(child: Observer(builder: (context) { + final syncData = syncStats.syncData; + List datas = syncData.map((datum) { + final h = datum.height.toDouble(); + return KLineEntity.fromCustom( + time: datum.timestamp.millisecondsSinceEpoch, + open: h, + close: h, + high: h, + low: h, + amount: 0, + vol: 0); + }).toList(); + return KChartWidget( + datas, + ChartStyle(), + ChartColors(context: context), + isLine: true, + volHidden: true, + showInfoDialog: true, + mainState: MainState.MA, + secondaryState: SecondaryState.NONE, + ); + })), + ButtonBar(children: [ + ElevatedButton.icon( + onPressed: _refresh, + label: Text('Reset'), + icon: Icon(Icons.restart_alt)), + ElevatedButton.icon( + onPressed: _export, + label: Text('Export'), + icon: Icon(Icons.save)) + ]) + ])); + } + + _refresh() { + syncStats.reset(); + } + + _export() async { + final csvData = syncStats.syncData.map((data) => [ + data.timestamp, + data.height]).toList(); + await shareCsv(csvData, 'sync_status.csv', 'Sync Status Data'); + } +} diff --git a/lib/txplan.dart b/lib/txplan.dart new file mode 100644 index 0000000..3f68ba1 --- /dev/null +++ b/lib/txplan.dart @@ -0,0 +1,89 @@ +import 'dart:convert'; + +import 'package:YWallet/main.dart'; +import 'package:flutter/material.dart'; +import 'package:warp_api/types.dart'; +import 'package:warp_api/warp_api.dart'; + +class TxPlanPage extends StatelessWidget { + final String plan; + final TxReport report; + + TxPlanPage(this.plan, this.report); + + factory TxPlanPage.fromPlan(String plan) { + // final reportStr = + // r'{"outputs":[{"id":0,"address":"zregtestsapling1qzy9wafd2axnenul6t6wav76dys6s8uatsq778mpmdvmx4k9myqxsd9m73aqdgc7gwnv53wga4j","amount":500000000,"pool":1}],"transparent":0,"sapling":500010000,"orchard":0,"net_sapling":-10000,"net_orchard":0,"fee":10000,"privacy_level":3}'; + final reportStr = WarpApi.transactionReport(active.coin, plan); + print(reportStr); + final json = jsonDecode(reportStr); + final report = TxReport.fromJson(json); + return TxPlanPage(plan, report); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final rows = report.outputs + .map((e) => DataRow(cells: [ + DataCell(Text('...${trailing(e.address, 12)}')), + DataCell(Text('${poolToString(e.pool)}')), + DataCell(Text('${amountToString(e.amount, 3)}')), + ])) + .toList(); + + return Scaffold( + appBar: AppBar(title: Text('Transaction Plan')), + body: Padding( + padding: EdgeInsets.all(8), + child: SingleChildScrollView(child: Wrap( + direction: Axis.vertical, + spacing: 20, + runSpacing: 20, + children: [ + DataTable(columns: [ + DataColumn(label: Text('Address')), + DataColumn(label: Text('Pool')), + DataColumn(label: Expanded(child: Text('Amount'))), + ], rows: rows), + Text( + 'Transparent Input: ${amountToString(report.transparent, MAX_PRECISION)}'), + Text( + 'Sapling Input: ${amountToString(report.sapling, MAX_PRECISION)}'), + Text( + 'Orchard Input: ${amountToString(report.orchard, MAX_PRECISION)}'), + Text( + 'Net Sapling Change: ${amountToString(report.net_sapling, MAX_PRECISION)}'), + Text( + 'Net Orchard Change: ${amountToString(report.net_orchard, MAX_PRECISION)}'), + Text('Fee: ${amountToString(report.fee, MAX_PRECISION)}'), + privacyToString(report.privacy_level, theme.textTheme.titleSmall!)!, + ButtonBar(children: confirmButtons(context, _onSend, okLabel: 'Send')), + ])))); + } + + _onSend() { + final txid = WarpApi.signAndBroadcast(active.coin, active.id, this.plan); + showSnackBar("TxID: $txid"); + navigatorKey.currentState?.pop(); + } +} + +String poolToString(int pool) { + switch (pool) { + case 0: + return "Transparent"; + case 1: + return "Sapling"; + } + return "Orchard"; +} + +Widget? privacyToString(int privacyLevel, TextStyle baseStyle) { + switch (privacyLevel) { + case 0: return Text("PRIVACY: VERY LOW", style: baseStyle.copyWith(color: Colors.red)); + case 1: return Text("PRIVACY: LOW", style: baseStyle.copyWith(color: Colors.orange)); + case 2: return Text("PRIVACY: MEDIUM", style: baseStyle.copyWith(color: Colors.yellow)); + case 3: return Text("PRIVACY: HIGH", style: baseStyle.copyWith(color: Colors.green)); + } +} \ No newline at end of file diff --git a/misc/me.hanh.zwallet.Ywallet.yml b/misc/me.hanh.zwallet.Ywallet.yml index 5c32db2..813a409 100644 --- a/misc/me.hanh.zwallet.Ywallet.yml +++ b/misc/me.hanh.zwallet.Ywallet.yml @@ -1,8 +1,6 @@ id: me.hanh.zwallet.Ywallet runtime: org.freedesktop.Platform runtime-version: "22.08" -platform-extensions: - - org.freedesktop.Platform.GL.nvidia sdk: org.freedesktop.Sdk command: ywallet finish-args: diff --git a/native/zcash-params b/native/zcash-params index 0f1975b..849107a 160000 --- a/native/zcash-params +++ b/native/zcash-params @@ -1 +1 @@ -Subproject commit 0f1975b0d8799d852fe62e717dad8885eec1f106 +Subproject commit 849107a56e83f150c86405df733bf87ae589811d diff --git a/native/zcash-sync b/native/zcash-sync index cb39045..25a2e28 160000 --- a/native/zcash-sync +++ b/native/zcash-sync @@ -1 +1 @@ -Subproject commit cb3904577a1e2d69112af256c603ce604bb43e18 +Subproject commit 25a2e28e7416a521ce02f606e0a930fb84422326 diff --git a/packages/warp_api_ffi/lib/types.dart b/packages/warp_api_ffi/lib/types.dart index fc4647c..eb2a85b 100644 --- a/packages/warp_api_ffi/lib/types.dart +++ b/packages/warp_api_ffi/lib/types.dart @@ -87,3 +87,41 @@ class Progress { Map toJson() => _$ProgressToJson(this); } + +@JsonSerializable() +class TxOutput { + final int id; + final String address; + final int amount; + final int pool; + + TxOutput(this.id, this.address, this.amount, this.pool); + + factory TxOutput.fromJson(Map json) => + _$TxOutputFromJson(json); + + Map toJson() => _$TxOutputToJson(this); +} + +@JsonSerializable() +class TxReport { + final List outputs; + final int transparent; + final int sapling; + final int orchard; + final int net_sapling; + final int net_orchard; + final int fee; + final int privacy_level; + + TxReport(this.outputs, this.transparent, this.sapling, + this.orchard, this.net_sapling, this.net_orchard, + this.fee, this.privacy_level); + + factory TxReport.fromJson(Map json) => + _$TxReportFromJson(json); + + Map toJson() => _$TxReportToJson(this); +} + + diff --git a/packages/warp_api_ffi/lib/warp_api.dart b/packages/warp_api_ffi/lib/warp_api.dart index 5163f94..c230d84 100644 --- a/packages/warp_api_ffi/lib/warp_api.dart +++ b/packages/warp_api_ffi/lib/warp_api.dart @@ -86,6 +86,11 @@ class WarpApi { name.toNativeUtf8().cast(), index, count); } + static String getAddress(int coin, int id, int uaType) { + final address = warp_api_lib.get_address(coin, id, uaType); + return unwrapResultString(address); + } + static void importTransparentPath(int coin, int id, String path) { warp_api_lib.import_transparent_key( coin, id, path.toNativeUtf8().cast()); @@ -176,7 +181,7 @@ class WarpApi { return await compute( sendPaymentIsolateFn, - PaymentParams( + PaymentParams(coin, account, recipientJson, useTransparent, anchorOffset, receivePort.sendPort)); } @@ -191,8 +196,8 @@ class WarpApi { return balance; } - static Future shieldTAddr() async { - final txId = await compute(shieldTAddrIsolateFn, null); + static Future shieldTAddr(int coin, int account) async { + final txId = await compute(shieldTAddrIsolateFn, ShieldTAddrParams(coin, account)); return txId; } @@ -202,17 +207,27 @@ class WarpApi { ScanTransparentAccountsParams(gapLimit)); } - static String prepareTx( + static String prepareTx(int coin, int account, List recipients, bool useTransparent, int anchorOffset) { final recipientsJson = jsonEncode(recipients); final res = warp_api_lib.prepare_multi_payment( + coin, account, recipientsJson.toNativeUtf8().cast(), - useTransparent ? 1 : 0, anchorOffset); final json = unwrapResultString(res); return json; } + static String transactionReport(int coin, String plan) { + final report = warp_api_lib.transaction_report(coin, plan.toNativeUtf8().cast()); + return unwrapResultString(report); + } + + static String signAndBroadcast (int coin, int account, String plan) { + final txid = warp_api_lib.sign_and_broadcast(coin, account, plan.toNativeUtf8().cast()); + return unwrapResultString(txid); + } + static Future signOnly( int coin, int account, String tx, void Function(int) f) async { var receivePort = ReceivePort(); @@ -221,7 +236,7 @@ class WarpApi { }); return await compute( - signOnlyIsolateFn, SignOnlyParams(tx, receivePort.sendPort)); + signOnlyIsolateFn, SignOnlyParams(coin, account, tx, receivePort.sendPort)); } static String broadcast(String txStr) { @@ -453,15 +468,16 @@ class WarpApi { String sendPaymentIsolateFn(PaymentParams params) { final txId = warp_api_lib.send_multi_payment( + params.coin, params.account, params.recipientsJson.toNativeUtf8().cast(), params.anchorOffset, - params.useTransparent ? 1 : 0, params.port.nativePort); return unwrapResultString(txId); } String signOnlyIsolateFn(SignOnlyParams params) { final txIdRes = warp_api_lib.sign( + params.coin, params.account, params.tx.toNativeUtf8().cast(), params.port.nativePort); if (txIdRes.error != nullptr) throw convertCString(txIdRes.error); return convertCString(txIdRes.value); @@ -475,8 +491,8 @@ int mempoolSyncIsolateFn(Null n) { return unwrapResultI64(warp_api_lib.mempool_sync()); } -String shieldTAddrIsolateFn(Null n) { - final txId = warp_api_lib.shield_taddr(); +String shieldTAddrIsolateFn(ShieldTAddrParams params) { + final txId = warp_api_lib.shield_taddr(params.coin, params.account); return unwrapResultString(txId); } @@ -518,20 +534,24 @@ class SyncParams { } class PaymentParams { + final int coin; + final int account; final String recipientsJson; final bool useTransparent; final int anchorOffset; final SendPort port; PaymentParams( - this.recipientsJson, this.useTransparent, this.anchorOffset, this.port); + this.coin, this.account, this.recipientsJson, this.useTransparent, this.anchorOffset, this.port); } class SignOnlyParams { + final int coin; + final int account; final String tx; final SendPort port; - SignOnlyParams(this.tx, this.port); + SignOnlyParams(this.coin, this.account, this.tx, this.port); } class ShieldTAddrParams { diff --git a/packages/warp_api_ffi/lib/warp_api_generated.dart b/packages/warp_api_ffi/lib/warp_api_generated.dart index c70b8ba..70e694e 100644 --- a/packages/warp_api_ffi/lib/warp_api_generated.dart +++ b/packages/warp_api_ffi/lib/warp_api_generated.dart @@ -167,6 +167,23 @@ class NativeLibrary { late final _dart_new_sub_account _new_sub_account = _new_sub_account_ptr.asFunction<_dart_new_sub_account>(); + CResult_____c_char get_address( + int coin, + int id_account, + int ua_type, + ) { + return _get_address( + coin, + id_account, + ua_type, + ); + } + + late final _get_address_ptr = + _lookup>('get_address'); + late final _dart_get_address _get_address = + _get_address_ptr.asFunction<_dart_get_address>(); + void import_transparent_key( int coin, int id_account, @@ -282,14 +299,16 @@ class NativeLibrary { _get_latest_height_ptr.asFunction<_dart_get_latest_height>(); CResult_____c_char send_multi_payment( + int coin, + int account, ffi.Pointer recipients_json, - int use_transparent, int anchor_offset, int port, ) { return _send_multi_payment( + coin, + account, recipients_json, - use_transparent, anchor_offset, port, ); @@ -383,8 +402,14 @@ class NativeLibrary { late final _dart_get_taddr_balance _get_taddr_balance = _get_taddr_balance_ptr.asFunction<_dart_get_taddr_balance>(); - CResult_____c_char shield_taddr() { - return _shield_taddr(); + CResult_____c_char shield_taddr( + int coin, + int account, + ) { + return _shield_taddr( + coin, + account, + ); } late final _shield_taddr_ptr = @@ -408,13 +433,15 @@ class NativeLibrary { .asFunction<_dart_scan_transparent_accounts>(); CResult_____c_char prepare_multi_payment( + int coin, + int account, ffi.Pointer recipients_json, - int use_transparent, int anchor_offset, ) { return _prepare_multi_payment( + coin, + account, recipients_json, - use_transparent, anchor_offset, ); } @@ -425,11 +452,30 @@ class NativeLibrary { late final _dart_prepare_multi_payment _prepare_multi_payment = _prepare_multi_payment_ptr.asFunction<_dart_prepare_multi_payment>(); + CResult_____c_char transaction_report( + int coin, + ffi.Pointer plan, + ) { + return _transaction_report( + coin, + plan, + ); + } + + late final _transaction_report_ptr = + _lookup>('transaction_report'); + late final _dart_transaction_report _transaction_report = + _transaction_report_ptr.asFunction<_dart_transaction_report>(); + CResult_____c_char sign( + int coin, + int account, ffi.Pointer tx, int port, ) { return _sign( + coin, + account, tx, port, ); @@ -438,6 +484,23 @@ class NativeLibrary { late final _sign_ptr = _lookup>('sign'); late final _dart_sign _sign = _sign_ptr.asFunction<_dart_sign>(); + CResult_____c_char sign_and_broadcast( + int coin, + int account, + ffi.Pointer tx_plan, + ) { + return _sign_and_broadcast( + coin, + account, + tx_plan, + ); + } + + late final _sign_and_broadcast_ptr = + _lookup>('sign_and_broadcast'); + late final _dart_sign_and_broadcast _sign_and_broadcast = + _sign_and_broadcast_ptr.asFunction<_dart_sign_and_broadcast>(); + CResult_____c_char broadcast_tx( ffi.Pointer tx_str, ) { @@ -824,15 +887,15 @@ class CResult_u32 extends ffi.Struct { external ffi.Pointer error; } -class CResult_u8 extends ffi.Struct { - @ffi.Uint8() - external int value; +class CResult_____c_char extends ffi.Struct { + external ffi.Pointer value; external ffi.Pointer error; } -class CResult_____c_char extends ffi.Struct { - external ffi.Pointer value; +class CResult_u8 extends ffi.Struct { + @ffi.Uint8() + external int value; external ffi.Pointer error; } @@ -949,6 +1012,18 @@ typedef _dart_new_sub_account = void Function( int count, ); +typedef _c_get_address = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Uint32 id_account, + ffi.Uint8 ua_type, +); + +typedef _dart_get_address = CResult_____c_char Function( + int coin, + int id_account, + int ua_type, +); + typedef _c_import_transparent_key = ffi.Void Function( ffi.Uint8 coin, ffi.Uint32 id_account, @@ -1022,15 +1097,17 @@ typedef _c_get_latest_height = CResult_u32 Function(); typedef _dart_get_latest_height = CResult_u32 Function(); typedef _c_send_multi_payment = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Uint32 account, ffi.Pointer recipients_json, - ffi.Int8 use_transparent, ffi.Uint32 anchor_offset, ffi.Int64 port, ); typedef _dart_send_multi_payment = CResult_____c_char Function( + int coin, + int account, ffi.Pointer recipients_json, - int use_transparent, int anchor_offset, int port, ); @@ -1081,9 +1158,15 @@ typedef _dart_get_taddr_balance = CResult_u64 Function( int id_account, ); -typedef _c_shield_taddr = CResult_____c_char Function(); +typedef _c_shield_taddr = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Uint32 account, +); -typedef _dart_shield_taddr = CResult_____c_char Function(); +typedef _dart_shield_taddr = CResult_____c_char Function( + int coin, + int account, +); typedef _c_scan_transparent_accounts = ffi.Void Function( ffi.Uint32 gap_limit, @@ -1094,27 +1177,55 @@ typedef _dart_scan_transparent_accounts = void Function( ); typedef _c_prepare_multi_payment = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Uint32 account, ffi.Pointer recipients_json, - ffi.Int8 use_transparent, ffi.Uint32 anchor_offset, ); typedef _dart_prepare_multi_payment = CResult_____c_char Function( + int coin, + int account, ffi.Pointer recipients_json, - int use_transparent, int anchor_offset, ); +typedef _c_transaction_report = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Pointer plan, +); + +typedef _dart_transaction_report = CResult_____c_char Function( + int coin, + ffi.Pointer plan, +); + typedef _c_sign = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Uint32 account, ffi.Pointer tx, ffi.Int64 port, ); typedef _dart_sign = CResult_____c_char Function( + int coin, + int account, ffi.Pointer tx, int port, ); +typedef _c_sign_and_broadcast = CResult_____c_char Function( + ffi.Uint8 coin, + ffi.Uint32 account, + ffi.Pointer tx_plan, +); + +typedef _dart_sign_and_broadcast = CResult_____c_char Function( + int coin, + int account, + ffi.Pointer tx_plan, +); + typedef _c_broadcast_tx = CResult_____c_char Function( ffi.Pointer tx_str, );