mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 11:39:22 +00:00
Nano-GPT (#1336)
* init * updates * nano updates * updates * updates * [skipci] wip deep link changes * fix deep links * minor fix * add reminder message on buy and exchange routes * [skip ci] font fixes * review updates * [skip ci] minor fix * save * fixes * minor code cleanup * minor potential fix
This commit is contained in:
parent
e5be737236
commit
baad7f7469
46 changed files with 486 additions and 195 deletions
1
.github/workflows/pr_test_build.yml
vendored
1
.github/workflows/pr_test_build.yml
vendored
|
@ -151,6 +151,7 @@ jobs:
|
||||||
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
|
||||||
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
|
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
|
||||||
|
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
|
||||||
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
|
||||||
|
|
||||||
- name: Rename app
|
- name: Rename app
|
||||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -94,6 +94,7 @@ android/app/key.jks
|
||||||
**/tool/.evm-secrets-config.json
|
**/tool/.evm-secrets-config.json
|
||||||
**/tool/.ethereum-secrets-config.json
|
**/tool/.ethereum-secrets-config.json
|
||||||
**/tool/.solana-secrets-config.json
|
**/tool/.solana-secrets-config.json
|
||||||
|
**/tool/.nano-secrets-config.json
|
||||||
**/tool/.tron-secrets-config.json
|
**/tool/.tron-secrets-config.json
|
||||||
**/lib/.secrets.g.dart
|
**/lib/.secrets.g.dart
|
||||||
**/cw_evm/lib/.secrets.g.dart
|
**/cw_evm/lib/.secrets.g.dart
|
||||||
|
|
|
@ -91,6 +91,13 @@
|
||||||
<data android:scheme="tron-wallet" />
|
<data android:scheme="tron-wallet" />
|
||||||
<data android:scheme="tron_wallet" />
|
<data android:scheme="tron_wallet" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<!-- nano-gpt link scheme -->
|
||||||
|
<intent-filter android:autoVerify="true">
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="nano-gpt" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
|
|
5
assets/banano_node_list.yml
Normal file
5
assets/banano_node_list.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
-
|
||||||
|
uri: kaliumapi.appditto.com
|
||||||
|
path: /api
|
||||||
|
useSSL: true
|
||||||
|
is_default: true
|
|
@ -259,10 +259,16 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
||||||
element.tag == walletCurrency?.tag));
|
element.tag == walletCurrency?.tag));
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
|
// search by fullName if not found by title:
|
||||||
|
try {
|
||||||
|
return CryptoCurrency.all.firstWhere((element) => element.fullName?.toLowerCase() == name);
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
if (CryptoCurrency._nameCurrencyMap[name.toLowerCase()] == null) {
|
if (CryptoCurrency._nameCurrencyMap[name.toLowerCase()] == null) {
|
||||||
final s = 'Unexpected token: $name for CryptoCurrency fromString';
|
final s = 'Unexpected token: $name for CryptoCurrency fromString';
|
||||||
throw ArgumentError.value(name, 'name', s);
|
throw ArgumentError.value(name, 'name', s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CryptoCurrency._nameCurrencyMap[name.toLowerCase()]!;
|
return CryptoCurrency._nameCurrencyMap[name.toLowerCase()]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
import 'package:cw_core/balance.dart';
|
import 'package:cw_core/balance.dart';
|
||||||
import 'package:nanoutil/nanoutil.dart';
|
import 'package:nanoutil/nanoutil.dart';
|
||||||
|
|
||||||
|
BigInt stringAmountToBigIntBanano(String amount) {
|
||||||
|
return BigInt.parse(NanoAmounts.getAmountAsRaw(amount, NanoAmounts.rawPerBanano));
|
||||||
|
}
|
||||||
|
|
||||||
class BananoBalance extends Balance {
|
class BananoBalance extends Balance {
|
||||||
final BigInt currentBalance;
|
final BigInt currentBalance;
|
||||||
final BigInt receivableBalance;
|
final BigInt receivableBalance;
|
||||||
|
|
||||||
BananoBalance({required this.currentBalance, required this.receivableBalance}) : super(0, 0);
|
BananoBalance({required this.currentBalance, required this.receivableBalance}) : super(0, 0);
|
||||||
|
|
||||||
|
BananoBalance.fromFormattedString(
|
||||||
|
{required String formattedCurrentBalance, required String formattedReceivableBalance})
|
||||||
|
: currentBalance = stringAmountToBigIntBanano(formattedCurrentBalance),
|
||||||
|
receivableBalance = stringAmountToBigIntBanano(formattedReceivableBalance),
|
||||||
|
super(0, 0);
|
||||||
|
|
||||||
|
BananoBalance.fromRawString(
|
||||||
|
{required String currentBalance, required String receivableBalance})
|
||||||
|
: currentBalance = BigInt.parse(currentBalance),
|
||||||
|
receivableBalance = BigInt.parse(receivableBalance),
|
||||||
|
super(0, 0);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get formattedAvailableBalance {
|
String get formattedAvailableBalance {
|
||||||
return NanoAmounts.getRawAsUsableString(currentBalance.toString(), NanoAmounts.rawPerBanano);
|
return NanoAmounts.getRawAsUsableString(currentBalance.toString(), NanoAmounts.rawPerBanano);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:cw_core/balance.dart';
|
import 'package:cw_core/balance.dart';
|
||||||
import 'package:nanoutil/nanoutil.dart';
|
import 'package:nanoutil/nanoutil.dart';
|
||||||
|
|
||||||
BigInt stringAmountToBigInt(String amount) {
|
BigInt stringAmountToBigIntNano(String amount) {
|
||||||
return BigInt.parse(NanoAmounts.getAmountAsRaw(amount, NanoAmounts.rawPerNano));
|
return BigInt.parse(NanoAmounts.getAmountAsRaw(amount, NanoAmounts.rawPerNano));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ class NanoBalance extends Balance {
|
||||||
|
|
||||||
NanoBalance.fromFormattedString(
|
NanoBalance.fromFormattedString(
|
||||||
{required String formattedCurrentBalance, required String formattedReceivableBalance})
|
{required String formattedCurrentBalance, required String formattedReceivableBalance})
|
||||||
: currentBalance = stringAmountToBigInt(formattedCurrentBalance),
|
: currentBalance = stringAmountToBigIntNano(formattedCurrentBalance),
|
||||||
receivableBalance = stringAmountToBigInt(formattedReceivableBalance),
|
receivableBalance = stringAmountToBigIntNano(formattedReceivableBalance),
|
||||||
super(0, 0);
|
super(0, 0);
|
||||||
|
|
||||||
NanoBalance.fromRawString(
|
NanoBalance.fromRawString(
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:nanodart/nanodart.dart';
|
||||||
import 'package:cw_core/node.dart';
|
import 'package:cw_core/node.dart';
|
||||||
import 'package:nanoutil/nanoutil.dart';
|
import 'package:nanoutil/nanoutil.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:cw_nano/.secrets.g.dart' as secrets;
|
||||||
|
|
||||||
class NanoClient {
|
class NanoClient {
|
||||||
static const Map<String, String> CAKE_HEADERS = {
|
static const Map<String, String> CAKE_HEADERS = {
|
||||||
|
@ -52,10 +53,19 @@ class NanoClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, String> getHeaders() {
|
||||||
|
if (_node!.uri == "https://rpc.nano.to") {
|
||||||
|
return CAKE_HEADERS..addAll({
|
||||||
|
"key": secrets.nano2ApiKey,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return CAKE_HEADERS;
|
||||||
|
}
|
||||||
|
|
||||||
Future<NanoBalance> getBalance(String address) async {
|
Future<NanoBalance> getBalance(String address) async {
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
_node!.uri,
|
_node!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: jsonEncode(
|
body: jsonEncode(
|
||||||
{
|
{
|
||||||
"action": "account_balance",
|
"action": "account_balance",
|
||||||
|
@ -82,7 +92,7 @@ class NanoClient {
|
||||||
try {
|
try {
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
_node!.uri,
|
_node!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: jsonEncode(
|
body: jsonEncode(
|
||||||
{
|
{
|
||||||
"action": "account_info",
|
"action": "account_info",
|
||||||
|
@ -94,7 +104,7 @@ class NanoClient {
|
||||||
final data = await jsonDecode(response.body);
|
final data = await jsonDecode(response.body);
|
||||||
return AccountInfoResponse.fromJson(data as Map<String, dynamic>);
|
return AccountInfoResponse.fromJson(data as Map<String, dynamic>);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("error while getting account info");
|
print("error while getting account info $e");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +159,7 @@ class NanoClient {
|
||||||
Future<String> requestWork(String hash) async {
|
Future<String> requestWork(String hash) async {
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
_powNode!.uri,
|
_powNode!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: json.encode(
|
body: json.encode(
|
||||||
{
|
{
|
||||||
"action": "work_generate",
|
"action": "work_generate",
|
||||||
|
@ -192,7 +202,7 @@ class NanoClient {
|
||||||
|
|
||||||
final processResponse = await http.post(
|
final processResponse = await http.post(
|
||||||
_node!.uri,
|
_node!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: processBody,
|
body: processBody,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -351,7 +361,7 @@ class NanoClient {
|
||||||
});
|
});
|
||||||
final processResponse = await http.post(
|
final processResponse = await http.post(
|
||||||
_node!.uri,
|
_node!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: processBody,
|
body: processBody,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -367,7 +377,7 @@ class NanoClient {
|
||||||
required String privateKey,
|
required String privateKey,
|
||||||
}) async {
|
}) async {
|
||||||
final receivableResponse = await http.post(_node!.uri,
|
final receivableResponse = await http.post(_node!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
"action": "receivable",
|
"action": "receivable",
|
||||||
"account": destinationAddress,
|
"account": destinationAddress,
|
||||||
|
@ -417,7 +427,7 @@ class NanoClient {
|
||||||
Future<List<NanoTransactionModel>> fetchTransactions(String address) async {
|
Future<List<NanoTransactionModel>> fetchTransactions(String address) async {
|
||||||
try {
|
try {
|
||||||
final response = await http.post(_node!.uri,
|
final response = await http.post(_node!.uri,
|
||||||
headers: CAKE_HEADERS,
|
headers: getHeaders(),
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
"action": "account_history",
|
"action": "account_history",
|
||||||
"account": address,
|
"account": address,
|
||||||
|
|
|
@ -140,6 +140,16 @@
|
||||||
<string>nano-wallet</string>
|
<string>nano-wallet</string>
|
||||||
</array>
|
</array>
|
||||||
</dict>
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Viewer</string>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>nano-gpt</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>nano-gpt</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleTypeRole</key>
|
<key>CFBundleTypeRole</key>
|
||||||
<string>Editor</string>
|
<string>Editor</string>
|
||||||
|
|
145
lib/di.dart
145
lib/di.dart
|
@ -26,6 +26,7 @@ import 'package:cake_wallet/entities/contact.dart';
|
||||||
import 'package:cake_wallet/entities/contact_record.dart';
|
import 'package:cake_wallet/entities/contact_record.dart';
|
||||||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||||
|
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||||
import 'package:cake_wallet/tron/tron.dart';
|
import 'package:cake_wallet/tron/tron.dart';
|
||||||
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
|
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
|
||||||
import 'package:cw_core/receive_page_option.dart';
|
import 'package:cw_core/receive_page_option.dart';
|
||||||
|
@ -268,6 +269,7 @@ Future<void> setup({
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
||||||
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
|
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
|
||||||
required FlutterSecureStorage secureStorage,
|
required FlutterSecureStorage secureStorage,
|
||||||
|
required GlobalKey<NavigatorState> navigatorKey,
|
||||||
}) async {
|
}) async {
|
||||||
_walletInfoSource = walletInfoSource;
|
_walletInfoSource = walletInfoSource;
|
||||||
_nodeSource = nodeSource;
|
_nodeSource = nodeSource;
|
||||||
|
@ -429,68 +431,89 @@ Future<void> setup({
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactory<AuthPage>(() {
|
getIt.registerLazySingleton<LinkViewModel>(() {
|
||||||
return AuthPage(getIt.get<AuthViewModel>(),
|
return LinkViewModel(
|
||||||
|
appStore: getIt.get<AppStore>(),
|
||||||
|
settingsStore: getIt.get<SettingsStore>(),
|
||||||
|
authenticationStore: getIt.get<AuthenticationStore>(),
|
||||||
|
navigatorKey: navigatorKey,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
getIt.registerFactory<AuthPage>(instanceName: 'login', () {
|
||||||
|
return AuthPage(getIt.get<AuthViewModel>(), closable: false,
|
||||||
onAuthenticationFinished: (isAuthenticated, AuthPageState authPageState) {
|
onAuthenticationFinished: (isAuthenticated, AuthPageState authPageState) {
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
final authStore = getIt.get<AuthenticationStore>();
|
|
||||||
final appStore = getIt.get<AppStore>();
|
|
||||||
final useTotp = appStore.settingsStore.useTOTP2FA;
|
|
||||||
final shouldUseTotp2FAToAccessWallets =
|
|
||||||
appStore.settingsStore.shouldRequireTOTP2FAForAccessingWallet;
|
|
||||||
if (useTotp && shouldUseTotp2FAToAccessWallets) {
|
|
||||||
authPageState.close(
|
|
||||||
route: Routes.totpAuthCodePage,
|
|
||||||
arguments: TotpAuthArgumentsModel(
|
|
||||||
isForSetup: false,
|
|
||||||
isClosable: false,
|
|
||||||
onTotpAuthenticationFinished: (bool isAuthenticatedSuccessfully,
|
|
||||||
TotpAuthCodePageState totpAuthPageState) async {
|
|
||||||
if (!isAuthenticatedSuccessfully) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (appStore.wallet != null) {
|
|
||||||
authStore.allowed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
totpAuthPageState.changeProcessText('Loading the wallet');
|
|
||||||
|
|
||||||
if (loginError != null) {
|
|
||||||
totpAuthPageState.changeProcessText('ERROR: ${loginError.toString()}');
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactionDisposer? _reaction;
|
|
||||||
_reaction = reaction((_) => appStore.wallet, (Object? _) {
|
|
||||||
_reaction?.reaction.dispose();
|
|
||||||
authStore.allowed();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (appStore.wallet != null) {
|
|
||||||
authStore.allowed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
authPageState.changeProcessText('Loading the wallet');
|
|
||||||
|
|
||||||
if (loginError != null) {
|
|
||||||
authPageState.changeProcessText('ERROR: ${loginError.toString()}');
|
|
||||||
}
|
|
||||||
|
|
||||||
ReactionDisposer? _reaction;
|
|
||||||
_reaction = reaction((_) => appStore.wallet, (Object? _) {
|
|
||||||
_reaction?.reaction.dispose();
|
|
||||||
authStore.allowed();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, closable: false);
|
final authStore = getIt.get<AuthenticationStore>();
|
||||||
}, instanceName: 'login');
|
final appStore = getIt.get<AppStore>();
|
||||||
|
final useTotp = appStore.settingsStore.useTOTP2FA;
|
||||||
|
final shouldUseTotp2FAToAccessWallets =
|
||||||
|
appStore.settingsStore.shouldRequireTOTP2FAForAccessingWallet;
|
||||||
|
if (useTotp && shouldUseTotp2FAToAccessWallets) {
|
||||||
|
authPageState.close(
|
||||||
|
route: Routes.totpAuthCodePage,
|
||||||
|
arguments: TotpAuthArgumentsModel(
|
||||||
|
isForSetup: false,
|
||||||
|
isClosable: false,
|
||||||
|
onTotpAuthenticationFinished:
|
||||||
|
(bool isAuthenticatedSuccessfully, TotpAuthCodePageState totpAuthPageState) async {
|
||||||
|
if (!isAuthenticatedSuccessfully) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (appStore.wallet != null) {
|
||||||
|
authStore.allowed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
totpAuthPageState.changeProcessText('Loading the wallet');
|
||||||
|
|
||||||
|
if (loginError != null) {
|
||||||
|
totpAuthPageState.changeProcessText('ERROR: ${loginError.toString()}');
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactionDisposer? _reaction;
|
||||||
|
_reaction = reaction((_) => appStore.wallet, (Object? _) {
|
||||||
|
_reaction?.reaction.dispose();
|
||||||
|
authStore.allowed();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// wallet is already loaded:
|
||||||
|
if (appStore.wallet != null) {
|
||||||
|
// goes to the dashboard:
|
||||||
|
authStore.allowed();
|
||||||
|
// trigger any deep links:
|
||||||
|
final linkViewModel = getIt.get<LinkViewModel>();
|
||||||
|
if (linkViewModel.currentLink != null) {
|
||||||
|
linkViewModel.handleLink();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the wallet:
|
||||||
|
|
||||||
|
authPageState.changeProcessText('Loading the wallet');
|
||||||
|
|
||||||
|
if (loginError != null) {
|
||||||
|
authPageState.changeProcessText('ERROR: ${loginError.toString()}');
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactionDisposer? _reaction;
|
||||||
|
_reaction = reaction((_) => appStore.wallet, (Object? _) {
|
||||||
|
_reaction?.reaction.dispose();
|
||||||
|
authStore.allowed();
|
||||||
|
final linkViewModel = getIt.get<LinkViewModel>();
|
||||||
|
if (linkViewModel.currentLink != null) {
|
||||||
|
linkViewModel.handleLink();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
getIt.registerSingleton<BottomSheetService>(BottomSheetServiceImpl());
|
getIt.registerSingleton<BottomSheetService>(BottomSheetServiceImpl());
|
||||||
|
|
||||||
|
@ -849,8 +872,10 @@ Future<void> setup({
|
||||||
tradesStore: getIt.get<TradesStore>(),
|
tradesStore: getIt.get<TradesStore>(),
|
||||||
sendViewModel: getIt.get<SendViewModel>()));
|
sendViewModel: getIt.get<SendViewModel>()));
|
||||||
|
|
||||||
getIt.registerFactory(
|
getIt.registerFactoryParam<ExchangePage, PaymentRequest?, void>(
|
||||||
() => ExchangePage(getIt.get<ExchangeViewModel>(), getIt.get<AuthService>()));
|
(PaymentRequest? paymentRequest, __) {
|
||||||
|
return ExchangePage(getIt.get<ExchangeViewModel>(), getIt.get<AuthService>(), paymentRequest);
|
||||||
|
});
|
||||||
|
|
||||||
getIt.registerFactory(() => ExchangeConfirmPage(tradesStore: getIt.get<TradesStore>()));
|
getIt.registerFactory(() => ExchangeConfirmPage(tradesStore: getIt.get<TradesStore>()));
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/locales/locale.dart';
|
||||||
import 'package:cake_wallet/store/yat/yat_store.dart';
|
import 'package:cake_wallet/store/yat/yat_store.dart';
|
||||||
import 'package:cake_wallet/utils/device_info.dart';
|
import 'package:cake_wallet/utils/device_info.dart';
|
||||||
import 'package:cake_wallet/utils/exception_handler.dart';
|
import 'package:cake_wallet/utils/exception_handler.dart';
|
||||||
|
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||||
import 'package:cw_core/address_info.dart';
|
import 'package:cw_core/address_info.dart';
|
||||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||||
import 'package:cw_core/hive_type_ids.dart';
|
import 'package:cw_core/hive_type_ids.dart';
|
||||||
|
@ -205,18 +206,20 @@ Future<void> initialSetup(
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
powNodes: powNodes);
|
powNodes: powNodes);
|
||||||
await setup(
|
await setup(
|
||||||
walletInfoSource: walletInfoSource,
|
walletInfoSource: walletInfoSource,
|
||||||
nodeSource: nodes,
|
nodeSource: nodes,
|
||||||
powNodeSource: powNodes,
|
powNodeSource: powNodes,
|
||||||
contactSource: contactSource,
|
contactSource: contactSource,
|
||||||
tradesSource: tradesSource,
|
tradesSource: tradesSource,
|
||||||
templates: templates,
|
templates: templates,
|
||||||
exchangeTemplates: exchangeTemplates,
|
exchangeTemplates: exchangeTemplates,
|
||||||
transactionDescriptionBox: transactionDescriptions,
|
transactionDescriptionBox: transactionDescriptions,
|
||||||
ordersSource: ordersSource,
|
ordersSource: ordersSource,
|
||||||
anonpayInvoiceInfoSource: anonpayInvoiceInfo,
|
anonpayInvoiceInfoSource: anonpayInvoiceInfo,
|
||||||
unspentCoinsInfoSource: unspentCoinsInfoSource,
|
unspentCoinsInfoSource: unspentCoinsInfoSource,
|
||||||
secureStorage: secureStorage);
|
secureStorage: secureStorage,
|
||||||
|
navigatorKey: navigatorKey,
|
||||||
|
);
|
||||||
await bootstrap(navigatorKey);
|
await bootstrap(navigatorKey);
|
||||||
monero?.onStartup();
|
monero?.onStartup();
|
||||||
}
|
}
|
||||||
|
@ -287,6 +290,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
|
||||||
return Observer(builder: (BuildContext context) {
|
return Observer(builder: (BuildContext context) {
|
||||||
final appStore = getIt.get<AppStore>();
|
final appStore = getIt.get<AppStore>();
|
||||||
final authService = getIt.get<AuthService>();
|
final authService = getIt.get<AuthService>();
|
||||||
|
final linkViewModel = getIt.get<LinkViewModel>();
|
||||||
final settingsStore = appStore.settingsStore;
|
final settingsStore = appStore.settingsStore;
|
||||||
final statusBarColor = Colors.transparent;
|
final statusBarColor = Colors.transparent;
|
||||||
final authenticationStore = getIt.get<AuthenticationStore>();
|
final authenticationStore = getIt.get<AuthenticationStore>();
|
||||||
|
@ -309,6 +313,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
|
||||||
authenticationStore: authenticationStore,
|
authenticationStore: authenticationStore,
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
authService: authService,
|
authService: authService,
|
||||||
|
linkViewModel: linkViewModel,
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
navigatorObservers: [routeObserver],
|
navigatorObservers: [routeObserver],
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
|
|
|
@ -221,7 +221,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
builder: (_) => getIt.get<SetupPinCodePage>(
|
builder: (_) => getIt.get<SetupPinCodePage>(
|
||||||
param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
|
param1: (PinCodeState<PinCodeWidget> context, dynamic _) =>
|
||||||
Navigator.of(context.context).pushNamed(Routes.restoreWalletFromHardwareWallet, arguments: false),
|
Navigator.of(context.context)
|
||||||
|
.pushNamed(Routes.restoreWalletFromHardwareWallet, arguments: false),
|
||||||
),
|
),
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
);
|
);
|
||||||
|
@ -231,9 +232,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
builder: (_) => ConnectDevicePage(
|
builder: (_) => ConnectDevicePage(
|
||||||
ConnectDevicePageParams(
|
ConnectDevicePageParams(
|
||||||
walletType: availableWalletTypes.first,
|
walletType: availableWalletTypes.first,
|
||||||
onConnectDevice: (BuildContext context, _) =>
|
onConnectDevice: (BuildContext context, _) => Navigator.of(context).pushNamed(
|
||||||
Navigator.of(context).pushNamed(Routes.chooseHardwareWalletAccount,
|
Routes.chooseHardwareWalletAccount,
|
||||||
arguments: [availableWalletTypes.first]),
|
arguments: [availableWalletTypes.first]),
|
||||||
),
|
),
|
||||||
getIt.get<LedgerViewModel>(),
|
getIt.get<LedgerViewModel>(),
|
||||||
));
|
));
|
||||||
|
@ -243,9 +244,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
param1: (BuildContext context, WalletType type) {
|
param1: (BuildContext context, WalletType type) {
|
||||||
final arguments = ConnectDevicePageParams(
|
final arguments = ConnectDevicePageParams(
|
||||||
walletType: type,
|
walletType: type,
|
||||||
onConnectDevice: (BuildContext context, _) =>
|
onConnectDevice: (BuildContext context, _) => Navigator.of(context)
|
||||||
Navigator.of(context).pushNamed(Routes.chooseHardwareWalletAccount,
|
.pushNamed(Routes.chooseHardwareWalletAccount, arguments: [type]),
|
||||||
arguments: [type]),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Navigator.of(context).pushNamed(Routes.connectDevices, arguments: arguments);
|
Navigator.of(context).pushNamed(Routes.connectDevices, arguments: arguments);
|
||||||
|
@ -308,8 +308,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
case Routes.bumpFeePage:
|
case Routes.bumpFeePage:
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
builder: (_) =>
|
builder: (_) => getIt.get<RBFDetailsPage>(param1: settings.arguments as TransactionInfo));
|
||||||
getIt.get<RBFDetailsPage>(param1: settings.arguments as TransactionInfo));
|
|
||||||
|
|
||||||
case Routes.newSubaddress:
|
case Routes.newSubaddress:
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
|
@ -461,7 +460,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
|
|
||||||
case Routes.exchange:
|
case Routes.exchange:
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
fullscreenDialog: true, builder: (_) => getIt.get<ExchangePage>());
|
fullscreenDialog: true,
|
||||||
|
builder: (_) => getIt.get<ExchangePage>(param1: settings.arguments as PaymentRequest?),
|
||||||
|
);
|
||||||
|
|
||||||
case Routes.exchangeTemplate:
|
case Routes.exchangeTemplate:
|
||||||
return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangeTemplatePage>());
|
return CupertinoPageRoute<void>(builder: (_) => getIt.get<ExchangeTemplatePage>());
|
||||||
|
|
|
@ -59,12 +59,15 @@ class MarketPlacePage extends StatelessWidget {
|
||||||
// ),
|
// ),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
DashBoardRoundedCardWidget(
|
DashBoardRoundedCardWidget(
|
||||||
onTap: () => launchUrl(
|
|
||||||
Uri.https("buy.cakepay.com"),
|
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
title: S.of(context).cake_pay_web_cards_title,
|
title: S.of(context).cake_pay_web_cards_title,
|
||||||
subTitle: S.of(context).cake_pay_web_cards_subtitle,
|
subTitle: S.of(context).cake_pay_web_cards_subtitle,
|
||||||
|
onTap: () => _launchMarketPlaceUrl("buy.cakepay.com"),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
DashBoardRoundedCardWidget(
|
||||||
|
title: "NanoGPT",
|
||||||
|
subTitle: S.of(context).nanogpt_subtitle,
|
||||||
|
onTap: () => _launchMarketPlaceUrl("cake.nano-gpt.com"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -76,6 +79,17 @@ class MarketPlacePage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _launchMarketPlaceUrl(String url) async {
|
||||||
|
try {
|
||||||
|
launchUrl(
|
||||||
|
Uri.https(url),
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Remove ionia flow/files if we will discard it
|
// TODO: Remove ionia flow/files if we will discard it
|
||||||
void _navigatorToGiftCardsPage(BuildContext context) {
|
void _navigatorToGiftCardsPage(BuildContext context) {
|
||||||
final walletType = dashboardViewModel.type;
|
final walletType = dashboardViewModel.type;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cake_wallet/src/widgets/add_template_button.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
import 'package:cake_wallet/themes/theme_base.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/utils/debounce.dart';
|
import 'package:cake_wallet/utils/debounce.dart';
|
||||||
|
import 'package:cake_wallet/utils/payment_request.dart';
|
||||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||||
import 'package:cw_core/sync_status.dart';
|
import 'package:cw_core/sync_status.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
@ -43,7 +44,7 @@ import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker
|
||||||
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
|
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
|
||||||
|
|
||||||
class ExchangePage extends BasePage {
|
class ExchangePage extends BasePage {
|
||||||
ExchangePage(this.exchangeViewModel, this.authService) {
|
ExchangePage(this.exchangeViewModel, this.authService, this.initialPaymentRequest) {
|
||||||
depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr
|
depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr
|
||||||
? exchangeViewModel.wallet.name
|
? exchangeViewModel.wallet.name
|
||||||
: null;
|
: null;
|
||||||
|
@ -54,6 +55,7 @@ class ExchangePage extends BasePage {
|
||||||
|
|
||||||
final ExchangeViewModel exchangeViewModel;
|
final ExchangeViewModel exchangeViewModel;
|
||||||
final AuthService authService;
|
final AuthService authService;
|
||||||
|
final PaymentRequest? initialPaymentRequest;
|
||||||
final depositKey = GlobalKey<ExchangeCardState>();
|
final depositKey = GlobalKey<ExchangeCardState>();
|
||||||
final receiveKey = GlobalKey<ExchangeCardState>();
|
final receiveKey = GlobalKey<ExchangeCardState>();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
@ -543,6 +545,12 @@ class ExchangePage extends BasePage {
|
||||||
// amount: depositAmountController.text);
|
// amount: depositAmountController.text);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (initialPaymentRequest != null) {
|
||||||
|
exchangeViewModel.receiveCurrency = CryptoCurrency.fromString(initialPaymentRequest!.scheme);
|
||||||
|
exchangeViewModel.depositAmount = initialPaymentRequest!.amount;
|
||||||
|
exchangeViewModel.receiveAddress = initialPaymentRequest!.address;
|
||||||
|
}
|
||||||
|
|
||||||
_isReactionsSet = true;
|
_isReactionsSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
||||||
import 'package:cake_wallet/utils/device_info.dart';
|
import 'package:cake_wallet/utils/device_info.dart';
|
||||||
import 'package:cake_wallet/utils/payment_request.dart';
|
import 'package:cake_wallet/utils/payment_request.dart';
|
||||||
|
import 'package:cake_wallet/view_model/link_view_model.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
|
@ -25,6 +26,7 @@ class Root extends StatefulWidget {
|
||||||
required this.child,
|
required this.child,
|
||||||
required this.navigatorKey,
|
required this.navigatorKey,
|
||||||
required this.authService,
|
required this.authService,
|
||||||
|
required this.linkViewModel,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final AuthenticationStore authenticationStore;
|
final AuthenticationStore authenticationStore;
|
||||||
|
@ -32,6 +34,7 @@ class Root extends StatefulWidget {
|
||||||
final GlobalKey<NavigatorState> navigatorKey;
|
final GlobalKey<NavigatorState> navigatorKey;
|
||||||
final AuthService authService;
|
final AuthService authService;
|
||||||
final Widget child;
|
final Widget child;
|
||||||
|
final LinkViewModel linkViewModel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RootState createState() => RootState();
|
RootState createState() => RootState();
|
||||||
|
@ -53,7 +56,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
StreamSubscription<Uri?>? stream;
|
StreamSubscription<Uri?>? stream;
|
||||||
ReactionDisposer? _walletReactionDisposer;
|
ReactionDisposer? _walletReactionDisposer;
|
||||||
ReactionDisposer? _deepLinksReactionDisposer;
|
ReactionDisposer? _deepLinksReactionDisposer;
|
||||||
Uri? launchUri;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -98,7 +100,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
void handleDeepLinking(Uri? uri) async {
|
void handleDeepLinking(Uri? uri) async {
|
||||||
if (uri == null || !mounted) return;
|
if (uri == null || !mounted) return;
|
||||||
|
|
||||||
launchUri = uri;
|
widget.linkViewModel.currentLink = uri;
|
||||||
|
|
||||||
bool requireAuth = await widget.authService.requireAuth();
|
bool requireAuth = await widget.authService.requireAuth();
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
(AuthenticationState state) {
|
(AuthenticationState state) {
|
||||||
if (state == AuthenticationState.allowed) {
|
if (state == AuthenticationState.allowed) {
|
||||||
if (widget.appStore.wallet == null) {
|
if (widget.appStore.wallet == null) {
|
||||||
waitForWalletInstance(context, launchUri!);
|
waitForWalletInstance(context);
|
||||||
} else {
|
} else {
|
||||||
_navigateToDeepLinkScreen();
|
_navigateToDeepLinkScreen();
|
||||||
}
|
}
|
||||||
|
@ -150,6 +152,8 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// this only happens when the app has been in the background for some time
|
||||||
|
// this does NOT trigger when the app is started from the "closed" state!
|
||||||
if (_isInactive && !_postFrameCallback && _requestAuth) {
|
if (_isInactive && !_postFrameCallback && _requestAuth) {
|
||||||
_postFrameCallback = true;
|
_postFrameCallback = true;
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
@ -158,40 +162,38 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
|
arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
|
||||||
if (!isAuthenticatedSuccessfully) {
|
if (!isAuthenticatedSuccessfully) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
final useTotp = widget.appStore.settingsStore.useTOTP2FA;
|
||||||
|
final shouldUseTotp2FAToAccessWallets =
|
||||||
|
widget.appStore.settingsStore.shouldRequireTOTP2FAForAccessingWallet;
|
||||||
|
if (useTotp && shouldUseTotp2FAToAccessWallets) {
|
||||||
|
_reset();
|
||||||
|
auth.close(
|
||||||
|
route: Routes.totpAuthCodePage,
|
||||||
|
arguments: TotpAuthArgumentsModel(
|
||||||
|
onTotpAuthenticationFinished:
|
||||||
|
(bool isAuthenticatedSuccessfully, TotpAuthCodePageState totpAuth) {
|
||||||
|
if (!isAuthenticatedSuccessfully) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_reset();
|
||||||
|
totpAuth.close(
|
||||||
|
route: widget.linkViewModel.getRouteToGo(),
|
||||||
|
arguments: widget.linkViewModel.getRouteArgs(),
|
||||||
|
);
|
||||||
|
widget.linkViewModel.currentLink = null;
|
||||||
|
},
|
||||||
|
isForSetup: false,
|
||||||
|
isClosable: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
final useTotp = widget.appStore.settingsStore.useTOTP2FA;
|
_reset();
|
||||||
final shouldUseTotp2FAToAccessWallets =
|
auth.close(
|
||||||
widget.appStore.settingsStore.shouldRequireTOTP2FAForAccessingWallet;
|
route: widget.linkViewModel.getRouteToGo(),
|
||||||
if (useTotp && shouldUseTotp2FAToAccessWallets) {
|
arguments: widget.linkViewModel.getRouteArgs(),
|
||||||
_reset();
|
);
|
||||||
auth.close(
|
widget.linkViewModel.currentLink = null;
|
||||||
route: Routes.totpAuthCodePage,
|
|
||||||
arguments: TotpAuthArgumentsModel(
|
|
||||||
onTotpAuthenticationFinished:
|
|
||||||
(bool isAuthenticatedSuccessfully, TotpAuthCodePageState totpAuth) {
|
|
||||||
if (!isAuthenticatedSuccessfully) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_reset();
|
|
||||||
totpAuth.close(
|
|
||||||
route: _getRouteToGo(),
|
|
||||||
arguments:
|
|
||||||
isWalletConnectLink ? launchUri : PaymentRequest.fromUri(launchUri),
|
|
||||||
);
|
|
||||||
launchUri = null;
|
|
||||||
},
|
|
||||||
isForSetup: false,
|
|
||||||
isClosable: false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_reset();
|
|
||||||
auth.close(
|
|
||||||
route: _getRouteToGo(),
|
|
||||||
arguments: isWalletConnectLink ? launchUri : PaymentRequest.fromUri(launchUri),
|
|
||||||
);
|
|
||||||
launchUri = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -216,36 +218,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
_isInactiveController.add(value);
|
_isInactiveController.add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isValidPaymentUri() => launchUri?.path.isNotEmpty ?? false;
|
void waitForWalletInstance(BuildContext context) {
|
||||||
|
|
||||||
bool get isWalletConnectLink => launchUri?.authority == 'wc';
|
|
||||||
|
|
||||||
String? _getRouteToGo() {
|
|
||||||
if (isWalletConnectLink) {
|
|
||||||
if (isEVMCompatibleChain(widget.appStore.wallet!.type)) {
|
|
||||||
_nonETHWalletErrorToast(S.current.switchToEVMCompatibleWallet);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Routes.walletConnectConnectionsListing;
|
|
||||||
} else if (_isValidPaymentUri()) {
|
|
||||||
return Routes.send;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _nonETHWalletErrorToast(String message) async {
|
|
||||||
Fluttertoast.showToast(
|
|
||||||
msg: message,
|
|
||||||
toastLength: Toast.LENGTH_LONG,
|
|
||||||
gravity: ToastGravity.SNACKBAR,
|
|
||||||
backgroundColor: Colors.black,
|
|
||||||
textColor: Colors.white,
|
|
||||||
fontSize: 16.0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void waitForWalletInstance(BuildContext context, Uri tempLaunchUri) {
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
_walletReactionDisposer = reaction(
|
_walletReactionDisposer = reaction(
|
||||||
|
@ -263,14 +236,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _navigateToDeepLinkScreen() {
|
void _navigateToDeepLinkScreen() {
|
||||||
if (_getRouteToGo() != null) {
|
widget.linkViewModel.handleLink();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
widget.navigatorKey.currentState?.pushNamed(
|
|
||||||
_getRouteToGo()!,
|
|
||||||
arguments: isWalletConnectLink ? launchUri : PaymentRequest.fromUri(launchUri),
|
|
||||||
);
|
|
||||||
launchUri = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class SendPage extends BasePage {
|
class SendPage extends BasePage {
|
||||||
SendPage({
|
SendPage({
|
||||||
|
@ -420,12 +422,10 @@ class SendPage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
reaction((_) => sendViewModel.state, (ExecutionState state) {
|
reaction((_) => sendViewModel.state, (ExecutionState state) {
|
||||||
|
|
||||||
if (dialogContext != null && dialogContext?.mounted == true) {
|
if (dialogContext != null && dialogContext?.mounted == true) {
|
||||||
Navigator.of(dialogContext!).pop();
|
Navigator.of(dialogContext!).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (state is FailureState) {
|
if (state is FailureState) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
showPopUp<void>(
|
showPopUp<void>(
|
||||||
|
@ -460,10 +460,10 @@ class SendPage extends BasePage {
|
||||||
outputs: sendViewModel.outputs,
|
outputs: sendViewModel.outputs,
|
||||||
rightButtonText: S.of(_dialogContext).send,
|
rightButtonText: S.of(_dialogContext).send,
|
||||||
leftButtonText: S.of(_dialogContext).cancel,
|
leftButtonText: S.of(_dialogContext).cancel,
|
||||||
actionRightButton: () {
|
actionRightButton: () async {
|
||||||
Navigator.of(_dialogContext).pop();
|
Navigator.of(_dialogContext).pop();
|
||||||
sendViewModel.commitTransaction();
|
sendViewModel.commitTransaction();
|
||||||
showPopUp<void>(
|
await showPopUp<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext _dialogContext) {
|
builder: (BuildContext _dialogContext) {
|
||||||
return Observer(builder: (_) {
|
return Observer(builder: (_) {
|
||||||
|
@ -481,12 +481,14 @@ class SendPage extends BasePage {
|
||||||
sendViewModel.selectedCryptoCurrency.toString());
|
sendViewModel.selectedCryptoCurrency.toString());
|
||||||
|
|
||||||
final waitMessage = sendViewModel.walletType == WalletType.solana
|
final waitMessage = sendViewModel.walletType == WalletType.solana
|
||||||
? '. ${S.of(_dialogContext).waitFewSecondForTxUpdate}' : '';
|
? '. ${S.of(_dialogContext).waitFewSecondForTxUpdate}'
|
||||||
|
: '';
|
||||||
|
|
||||||
final newContactMessage = newContactAddress != null
|
final newContactMessage = newContactAddress != null
|
||||||
? '\n${S.of(_dialogContext).add_contact_to_address_book}' : '';
|
? '\n${S.of(_dialogContext).add_contact_to_address_book}'
|
||||||
|
: '';
|
||||||
|
|
||||||
final alertContent =
|
String alertContent =
|
||||||
"$successMessage$waitMessage$newContactMessage";
|
"$successMessage$waitMessage$newContactMessage";
|
||||||
|
|
||||||
if (newContactAddress != null) {
|
if (newContactAddress != null) {
|
||||||
|
@ -509,6 +511,10 @@ class SendPage extends BasePage {
|
||||||
newContactAddress = null;
|
newContactAddress = null;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
if (initialPaymentRequest?.callbackMessage?.isNotEmpty ??
|
||||||
|
false) {
|
||||||
|
alertContent = initialPaymentRequest!.callbackMessage!;
|
||||||
|
}
|
||||||
return AlertWithOneAction(
|
return AlertWithOneAction(
|
||||||
alertTitle: '',
|
alertTitle: '',
|
||||||
alertContent: alertContent,
|
alertContent: alertContent,
|
||||||
|
@ -523,6 +529,20 @@ class SendPage extends BasePage {
|
||||||
return Offstage();
|
return Offstage();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
if (state is TransactionCommitted) {
|
||||||
|
if (initialPaymentRequest?.callbackUrl?.isNotEmpty ?? false) {
|
||||||
|
// wait a second so it's not as jarring:
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
try {
|
||||||
|
launchUrl(
|
||||||
|
Uri.parse(initialPaymentRequest!.callbackUrl!),
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
actionLeftButton: () => Navigator.of(_dialogContext).pop());
|
actionLeftButton: () => Navigator.of(_dialogContext).pop());
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,19 +1,29 @@
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/nano/nano.dart';
|
import 'package:cake_wallet/nano/nano.dart';
|
||||||
|
|
||||||
class PaymentRequest {
|
class PaymentRequest {
|
||||||
PaymentRequest(this.address, this.amount, this.note, this.scheme);
|
PaymentRequest(this.address, this.amount, this.note, this.scheme, {this.callbackUrl, this.callbackMessage});
|
||||||
|
|
||||||
factory PaymentRequest.fromUri(Uri? uri) {
|
factory PaymentRequest.fromUri(Uri? uri) {
|
||||||
var address = "";
|
var address = "";
|
||||||
var amount = "";
|
var amount = "";
|
||||||
var note = "";
|
var note = "";
|
||||||
var scheme = "";
|
var scheme = "";
|
||||||
|
String? callbackUrl;
|
||||||
|
String? callbackMessage;
|
||||||
|
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
address = uri.path;
|
address = uri.queryParameters['address'] ?? uri.path;
|
||||||
amount = uri.queryParameters['tx_amount'] ?? uri.queryParameters['amount'] ?? "";
|
amount = uri.queryParameters['tx_amount'] ?? uri.queryParameters['amount'] ?? "";
|
||||||
note = uri.queryParameters['tx_description'] ?? uri.queryParameters['message'] ?? "";
|
note = uri.queryParameters['tx_description'] ?? uri.queryParameters['message'] ?? "";
|
||||||
scheme = uri.scheme;
|
scheme = uri.scheme;
|
||||||
|
callbackUrl = uri.queryParameters['callback'];
|
||||||
|
callbackMessage = uri.queryParameters['callbackMessage'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheme == "nano-gpt") {
|
||||||
|
// treat as nano so filling out the address works:
|
||||||
|
scheme = "nano";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nano != null) {
|
if (nano != null) {
|
||||||
|
@ -26,11 +36,20 @@ class PaymentRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PaymentRequest(address, amount, note, scheme);
|
return PaymentRequest(
|
||||||
|
address,
|
||||||
|
amount,
|
||||||
|
note,
|
||||||
|
scheme,
|
||||||
|
callbackUrl: callbackUrl,
|
||||||
|
callbackMessage: callbackMessage,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String address;
|
final String address;
|
||||||
final String amount;
|
final String amount;
|
||||||
final String note;
|
final String note;
|
||||||
final String scheme;
|
final String scheme;
|
||||||
|
final String? callbackUrl;
|
||||||
|
final String? callbackMessage;
|
||||||
}
|
}
|
||||||
|
|
118
lib/view_model/link_view_model.dart
Normal file
118
lib/view_model/link_view_model.dart
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
||||||
|
import 'package:cake_wallet/routes.dart';
|
||||||
|
import 'package:cake_wallet/store/app_store.dart';
|
||||||
|
import 'package:cake_wallet/store/authentication_store.dart';
|
||||||
|
import 'package:cake_wallet/store/settings_store.dart';
|
||||||
|
import 'package:cake_wallet/utils/payment_request.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
part 'link_view_model.g.dart';
|
||||||
|
|
||||||
|
class LinkViewModel = LinkViewModelBase with _$LinkViewModel;
|
||||||
|
|
||||||
|
abstract class LinkViewModelBase with Store {
|
||||||
|
LinkViewModelBase({
|
||||||
|
required this.settingsStore,
|
||||||
|
required this.appStore,
|
||||||
|
required this.authenticationStore,
|
||||||
|
required this.navigatorKey,
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
final SettingsStore settingsStore;
|
||||||
|
final AppStore appStore;
|
||||||
|
final AuthenticationStore authenticationStore;
|
||||||
|
final GlobalKey<NavigatorState> navigatorKey;
|
||||||
|
Uri? currentLink;
|
||||||
|
|
||||||
|
bool get _isValidPaymentUri => currentLink?.path.isNotEmpty ?? false;
|
||||||
|
bool get isWalletConnectLink => currentLink?.authority == 'wc';
|
||||||
|
bool get isNanoGptLink => currentLink?.scheme == 'nano-gpt';
|
||||||
|
|
||||||
|
String? getRouteToGo() {
|
||||||
|
if (isWalletConnectLink) {
|
||||||
|
if (!isEVMCompatibleChain(appStore.wallet!.type)) {
|
||||||
|
_errorToast(S.current.switchToEVMCompatibleWallet);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Routes.walletConnectConnectionsListing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (authenticationStore.state == AuthenticationState.uninitialized) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNanoGptLink) {
|
||||||
|
switch (currentLink?.authority ?? '') {
|
||||||
|
case "exchange":
|
||||||
|
return Routes.exchange;
|
||||||
|
case "send":
|
||||||
|
return Routes.send;
|
||||||
|
case "buy":
|
||||||
|
return Routes.buySellPage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isValidPaymentUri) {
|
||||||
|
return Routes.send;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic getRouteArgs() {
|
||||||
|
if (isWalletConnectLink) {
|
||||||
|
return currentLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNanoGptLink) {
|
||||||
|
switch (currentLink?.authority ?? '') {
|
||||||
|
case "exchange":
|
||||||
|
case "send":
|
||||||
|
return PaymentRequest.fromUri(currentLink);
|
||||||
|
case "buy":
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isValidPaymentUri) {
|
||||||
|
return PaymentRequest.fromUri(currentLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _errorToast(String message, {double fontSize = 16}) async {
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: message,
|
||||||
|
toastLength: Toast.LENGTH_LONG,
|
||||||
|
gravity: ToastGravity.SNACKBAR,
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
textColor: Colors.white,
|
||||||
|
fontSize: fontSize,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> handleLink() async {
|
||||||
|
String? route = getRouteToGo();
|
||||||
|
dynamic args = getRouteArgs();
|
||||||
|
if (route != null) {
|
||||||
|
if (appStore.wallet == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNanoGptLink) {
|
||||||
|
if (route == Routes.buySellPage || route == Routes.exchange) {
|
||||||
|
await _errorToast(S.current.nano_gpt_thanks_message, fontSize: 14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentLink = null;
|
||||||
|
navigatorKey.currentState?.pushNamed(
|
||||||
|
route,
|
||||||
|
arguments: args,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "المزيد من الخيارات",
|
"more_options": "المزيد من الخيارات",
|
||||||
"name": "ﻢﺳﺍ",
|
"name": "ﻢﺳﺍ",
|
||||||
|
"nano_gpt_thanks_message": "شكرا لاستخدام nanogpt! تذكر أن تعود إلى المتصفح بعد اكتمال معاملتك!",
|
||||||
|
"nanogpt_subtitle": "جميع النماذج الأحدث (GPT-4 ، Claude). \\ nno اشتراك ، ادفع مع Crypto.",
|
||||||
"nano_current_rep": "الممثل الحالي",
|
"nano_current_rep": "الممثل الحالي",
|
||||||
"nano_pick_new_rep": "اختر ممثلًا جديدًا",
|
"nano_pick_new_rep": "اختر ممثلًا جديدًا",
|
||||||
"narrow": "ضيق",
|
"narrow": "ضيق",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Още настройки",
|
"more_options": "Още настройки",
|
||||||
"name": "Име",
|
"name": "Име",
|
||||||
|
"nano_gpt_thanks_message": "Благодаря, че използвахте Nanogpt! Не забравяйте да се върнете обратно към браузъра, след като транзакцията ви приключи!",
|
||||||
|
"nanogpt_subtitle": "Всички най-нови модели (GPT-4, Claude). \\ Nno абонамент, платете с Crypto.",
|
||||||
"nano_current_rep": "Настоящ представител",
|
"nano_current_rep": "Настоящ представител",
|
||||||
"nano_pick_new_rep": "Изберете нов представител",
|
"nano_pick_new_rep": "Изберете нов представител",
|
||||||
"narrow": "Тесен",
|
"narrow": "Тесен",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Více možností",
|
"more_options": "Více možností",
|
||||||
"name": "název",
|
"name": "název",
|
||||||
|
"nano_gpt_thanks_message": "Děkujeme za používání Nanogpt! Nezapomeňte se po dokončení transakce vydat zpět do prohlížeče!",
|
||||||
|
"nanogpt_subtitle": "Všechny nejnovější modely (GPT-4, Claude). \\ Nno předplatné, plaťte krypto.",
|
||||||
"nano_current_rep": "Současný zástupce",
|
"nano_current_rep": "Současný zástupce",
|
||||||
"nano_pick_new_rep": "Vyberte nového zástupce",
|
"nano_pick_new_rep": "Vyberte nového zástupce",
|
||||||
"narrow": "Úzký",
|
"narrow": "Úzký",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
|
"moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein",
|
||||||
"more_options": "Weitere Optionen",
|
"more_options": "Weitere Optionen",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"nano_gpt_thanks_message": "Danke, dass du Nanogpt benutzt hast! Denken Sie daran, nach Abschluss Ihrer Transaktion zurück zum Browser zu gehen!",
|
||||||
|
"nanogpt_subtitle": "Alle neuesten Modelle (GPT-4, Claude).",
|
||||||
"nano_current_rep": "Aktueller Vertreter",
|
"nano_current_rep": "Aktueller Vertreter",
|
||||||
"nano_pick_new_rep": "Wählen Sie einen neuen Vertreter aus",
|
"nano_pick_new_rep": "Wählen Sie einen neuen Vertreter aus",
|
||||||
"narrow": "Eng",
|
"narrow": "Eng",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "More Options",
|
"more_options": "More Options",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!",
|
||||||
|
"nanogpt_subtitle": "All the newest models (GPT-4, Claude).\\nNo subscription, pay with crypto.",
|
||||||
"nano_current_rep": "Current Representative",
|
"nano_current_rep": "Current Representative",
|
||||||
"nano_pick_new_rep": "Pick a new representative",
|
"nano_pick_new_rep": "Pick a new representative",
|
||||||
"narrow": "Narrow",
|
"narrow": "Narrow",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Más Opciones",
|
"more_options": "Más Opciones",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
|
"nano_gpt_thanks_message": "¡Gracias por usar nanogpt! ¡Recuerde regresar al navegador después de que se complete su transacción!",
|
||||||
|
"nanogpt_subtitle": "Todos los modelos más nuevos (GPT-4, Claude). \\ Nno suscripción, pague con cripto.",
|
||||||
"nano_current_rep": "Representante actual",
|
"nano_current_rep": "Representante actual",
|
||||||
"nano_pick_new_rep": "Elija un nuevo representante",
|
"nano_pick_new_rep": "Elija un nuevo representante",
|
||||||
"narrow": "Angosto",
|
"narrow": "Angosto",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Plus d'options",
|
"more_options": "Plus d'options",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
|
"nano_gpt_thanks_message": "Merci d'avoir utilisé Nanogpt! N'oubliez pas de retourner au navigateur une fois votre transaction terminée!",
|
||||||
|
"nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude). \\ NNO abonnement, payez avec crypto.",
|
||||||
"nano_current_rep": "Représentant actuel",
|
"nano_current_rep": "Représentant actuel",
|
||||||
"nano_pick_new_rep": "Choisissez un nouveau représentant",
|
"nano_pick_new_rep": "Choisissez un nouveau représentant",
|
||||||
"narrow": "Étroit",
|
"narrow": "Étroit",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Ƙarin Zaɓuɓɓuka",
|
"more_options": "Ƙarin Zaɓuɓɓuka",
|
||||||
"name": "Suna",
|
"name": "Suna",
|
||||||
|
"nano_gpt_thanks_message": "Na gode da amfani da Nanogpt! Ka tuna da komawa zuwa mai bincike bayan ma'amalar ka ta cika!",
|
||||||
|
"nanogpt_subtitle": "Duk sabbin samfuran (GPT-4, CLODE). \\ NNO biyan kuɗi, biya tare da crypto.",
|
||||||
"nano_current_rep": "Wakilin Yanzu",
|
"nano_current_rep": "Wakilin Yanzu",
|
||||||
"nano_pick_new_rep": "Dauki sabon wakili",
|
"nano_pick_new_rep": "Dauki sabon wakili",
|
||||||
"narrow": "kunkuntar",
|
"narrow": "kunkuntar",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "और विकल्प",
|
"more_options": "और विकल्प",
|
||||||
"name": "नाम",
|
"name": "नाम",
|
||||||
|
"nano_gpt_thanks_message": "Nanogpt का उपयोग करने के लिए धन्यवाद! अपने लेन -देन के पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!",
|
||||||
|
"nanogpt_subtitle": "सभी नवीनतम मॉडल (GPT-4, क्लाउड)। \\ nno सदस्यता, क्रिप्टो के साथ भुगतान करें।",
|
||||||
"nano_current_rep": "वर्तमान प्रतिनिधि",
|
"nano_current_rep": "वर्तमान प्रतिनिधि",
|
||||||
"nano_pick_new_rep": "एक नया प्रतिनिधि चुनें",
|
"nano_pick_new_rep": "एक नया प्रतिनिधि चुनें",
|
||||||
"narrow": "सँकरा",
|
"narrow": "सँकरा",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Više opcija",
|
"more_options": "Više opcija",
|
||||||
"name": "Ime",
|
"name": "Ime",
|
||||||
|
"nano_gpt_thanks_message": "Hvala što ste koristili nanogpt! Ne zaboravite da se vratite u preglednik nakon što vam se transakcija završi!",
|
||||||
|
"nanogpt_subtitle": "Svi najnoviji modeli (GPT-4, Claude). \\ NNO pretplata, plaćajte kripto.",
|
||||||
"nano_current_rep": "Trenutni predstavnik",
|
"nano_current_rep": "Trenutni predstavnik",
|
||||||
"nano_pick_new_rep": "Odaberite novog predstavnika",
|
"nano_pick_new_rep": "Odaberite novog predstavnika",
|
||||||
"narrow": "Usko",
|
"narrow": "Usko",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Opsi Lainnya",
|
"more_options": "Opsi Lainnya",
|
||||||
"name": "Nama",
|
"name": "Nama",
|
||||||
|
"nano_gpt_thanks_message": "Terima kasih telah menggunakan Nanogpt! Ingatlah untuk kembali ke browser setelah transaksi Anda selesai!",
|
||||||
|
"nanogpt_subtitle": "Semua model terbaru (GPT-4, Claude). \\ Nno langganan, bayar dengan crypto.",
|
||||||
"nano_current_rep": "Perwakilan saat ini",
|
"nano_current_rep": "Perwakilan saat ini",
|
||||||
"nano_pick_new_rep": "Pilih perwakilan baru",
|
"nano_pick_new_rep": "Pilih perwakilan baru",
|
||||||
"narrow": "Sempit",
|
"narrow": "Sempit",
|
||||||
|
|
|
@ -367,6 +367,8 @@
|
||||||
"moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Altre opzioni",
|
"more_options": "Altre opzioni",
|
||||||
"name": "Nome",
|
"name": "Nome",
|
||||||
|
"nano_gpt_thanks_message": "Grazie per aver usato il nanogpt! Ricorda di tornare al browser dopo il completamento della transazione!",
|
||||||
|
"nanogpt_subtitle": "Tutti i modelli più recenti (GPT-4, Claude). Abbonamento nno, paga con cripto.",
|
||||||
"nano_current_rep": "Rappresentante attuale",
|
"nano_current_rep": "Rappresentante attuale",
|
||||||
"nano_pick_new_rep": "Scegli un nuovo rappresentante",
|
"nano_pick_new_rep": "Scegli un nuovo rappresentante",
|
||||||
"narrow": "Stretto",
|
"narrow": "Stretto",
|
||||||
|
|
|
@ -367,6 +367,8 @@
|
||||||
"moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "その他のオプション",
|
"more_options": "その他のオプション",
|
||||||
"name": "名前",
|
"name": "名前",
|
||||||
|
"nano_gpt_thanks_message": "NanoGptを使用してくれてありがとう!トランザクションが完了したら、ブラウザに戻ることを忘れないでください!",
|
||||||
|
"nanogpt_subtitle": "すべての最新モデル(GPT-4、Claude)。\\ nnoサブスクリプション、暗号で支払います。",
|
||||||
"nano_current_rep": "現在の代表",
|
"nano_current_rep": "現在の代表",
|
||||||
"nano_pick_new_rep": "新しい代表者を選びます",
|
"nano_pick_new_rep": "新しい代表者を選びます",
|
||||||
"narrow": "狭い",
|
"narrow": "狭い",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "추가 옵션",
|
"more_options": "추가 옵션",
|
||||||
"name": "이름",
|
"name": "이름",
|
||||||
|
"nano_gpt_thanks_message": "Nanogpt를 사용해 주셔서 감사합니다! 거래가 완료된 후 브라우저로 돌아가는 것을 잊지 마십시오!",
|
||||||
|
"nanogpt_subtitle": "모든 최신 모델 (GPT-4, Claude). \\ nno 구독, Crypto로 지불하십시오.",
|
||||||
"nano_current_rep": "현재 대표",
|
"nano_current_rep": "현재 대표",
|
||||||
"nano_pick_new_rep": "새로운 담당자를 선택하십시오",
|
"nano_pick_new_rep": "새로운 담당자를 선택하십시오",
|
||||||
"narrow": "좁은",
|
"narrow": "좁은",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်",
|
"moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်",
|
||||||
"more_options": "နောက်ထပ် ရွေးချယ်စရာများ",
|
"more_options": "နောက်ထပ် ရွေးချယ်စရာများ",
|
||||||
"name": "နာမည်",
|
"name": "နာမည်",
|
||||||
|
"nano_gpt_thanks_message": "nanogpt ကိုသုံးပြီးကျေးဇူးတင်ပါတယ် သင်၏ငွေပေးငွေယူပြီးနောက် browser သို့ပြန်သွားရန်သတိရပါ။",
|
||||||
|
"nanogpt_subtitle": "အားလုံးနောက်ဆုံးပေါ်မော်ဒယ်များ (GPT-4, Claude) ။ \\ nno subscription, crypto နှင့်အတူပေးဆောင်။",
|
||||||
"nano_current_rep": "လက်ရှိကိုယ်စားလှယ်",
|
"nano_current_rep": "လက်ရှိကိုယ်စားလှယ်",
|
||||||
"nano_pick_new_rep": "အသစ်တစ်ခုကိုရွေးပါ",
|
"nano_pick_new_rep": "အသစ်တစ်ခုကိုရွေးပါ",
|
||||||
"narrow": "ကျဉ်းသော",
|
"narrow": "ကျဉ်းသော",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Meer opties",
|
"more_options": "Meer opties",
|
||||||
"name": "Naam",
|
"name": "Naam",
|
||||||
|
"nano_gpt_thanks_message": "Bedankt voor het gebruik van Nanogpt! Vergeet niet om terug te gaan naar de browser nadat uw transactie is voltooid!",
|
||||||
|
"nanogpt_subtitle": "Alle nieuwste modellen (GPT-4, Claude). \\ Nno-abonnement, betalen met crypto.",
|
||||||
"nano_current_rep": "Huidige vertegenwoordiger",
|
"nano_current_rep": "Huidige vertegenwoordiger",
|
||||||
"nano_pick_new_rep": "Kies een nieuwe vertegenwoordiger",
|
"nano_pick_new_rep": "Kies een nieuwe vertegenwoordiger",
|
||||||
"narrow": "Smal",
|
"narrow": "Smal",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Więcej opcji",
|
"more_options": "Więcej opcji",
|
||||||
"name": "Nazwa",
|
"name": "Nazwa",
|
||||||
|
"nano_gpt_thanks_message": "Dzięki za użycie Nanogpt! Pamiętaj, aby wrócić do przeglądarki po zakończeniu transakcji!",
|
||||||
|
"nanogpt_subtitle": "Wszystkie najnowsze modele (GPT-4, Claude). \\ Nno subskrypcja, płacą za pomocą kryptografii.",
|
||||||
"nano_current_rep": "Obecny przedstawiciel",
|
"nano_current_rep": "Obecny przedstawiciel",
|
||||||
"nano_pick_new_rep": "Wybierz nowego przedstawiciela",
|
"nano_pick_new_rep": "Wybierz nowego przedstawiciela",
|
||||||
"narrow": "Wąski",
|
"narrow": "Wąski",
|
||||||
|
|
|
@ -367,6 +367,8 @@
|
||||||
"moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Mais opções",
|
"more_options": "Mais opções",
|
||||||
"name": "Nome",
|
"name": "Nome",
|
||||||
|
"nano_gpt_thanks_message": "Obrigado por usar o Nanogpt! Lembre -se de voltar para o navegador após a conclusão da transação!",
|
||||||
|
"nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude). \\ Nno assinatura, pagam com criptografia.",
|
||||||
"nano_current_rep": "Representante atual",
|
"nano_current_rep": "Representante atual",
|
||||||
"nano_pick_new_rep": "Escolha um novo representante",
|
"nano_pick_new_rep": "Escolha um novo representante",
|
||||||
"narrow": "Estreito",
|
"narrow": "Estreito",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Дополнительные параметры",
|
"more_options": "Дополнительные параметры",
|
||||||
"name": "Имя",
|
"name": "Имя",
|
||||||
|
"nano_gpt_thanks_message": "Спасибо за использование Nanogpt! Не забудьте вернуться в браузер после завершения транзакции!",
|
||||||
|
"nanogpt_subtitle": "Все новейшие модели (GPT-4, Claude). \\ Nno Подписка, платите с крипто.",
|
||||||
"nano_current_rep": "Нынешний представитель",
|
"nano_current_rep": "Нынешний представитель",
|
||||||
"nano_pick_new_rep": "Выберите нового представителя",
|
"nano_pick_new_rep": "Выберите нового представителя",
|
||||||
"narrow": "Узкий",
|
"narrow": "Узкий",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "ตัวเลือกเพิ่มเติม",
|
"more_options": "ตัวเลือกเพิ่มเติม",
|
||||||
"name": "ชื่อ",
|
"name": "ชื่อ",
|
||||||
|
"nano_gpt_thanks_message": "ขอบคุณที่ใช้ Nanogpt! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากการทำธุรกรรมของคุณเสร็จสิ้น!",
|
||||||
|
"nanogpt_subtitle": "รุ่นใหม่ล่าสุดทั้งหมด (GPT-4, Claude). การสมัครสมาชิก \\ nno, จ่ายด้วย crypto",
|
||||||
"nano_current_rep": "ตัวแทนปัจจุบัน",
|
"nano_current_rep": "ตัวแทนปัจจุบัน",
|
||||||
"nano_pick_new_rep": "เลือกตัวแทนใหม่",
|
"nano_pick_new_rep": "เลือกตัวแทนใหม่",
|
||||||
"narrow": "แคบ",
|
"narrow": "แคบ",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Ang halaga ng halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Ang halaga ng halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Higit pang mga pagpipilian",
|
"more_options": "Higit pang mga pagpipilian",
|
||||||
"name": "Pangalan",
|
"name": "Pangalan",
|
||||||
|
"nano_gpt_thanks_message": "Salamat sa paggamit ng nanogpt! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!",
|
||||||
|
"nanogpt_subtitle": "Ang lahat ng mga pinakabagong modelo (GPT-4, Claude). \\ Nno subscription, magbayad gamit ang crypto.",
|
||||||
"nano_current_rep": "Kasalukuyang kinatawan",
|
"nano_current_rep": "Kasalukuyang kinatawan",
|
||||||
"nano_pick_new_rep": "Pumili ng isang bagong kinatawan",
|
"nano_pick_new_rep": "Pumili ng isang bagong kinatawan",
|
||||||
"narrow": "Makitid",
|
"narrow": "Makitid",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır",
|
"moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır",
|
||||||
"more_options": "Daha Fazla Seçenek",
|
"more_options": "Daha Fazla Seçenek",
|
||||||
"name": "İsim",
|
"name": "İsim",
|
||||||
|
"nano_gpt_thanks_message": "Nanogpt kullandığınız için teşekkürler! İşleminiz tamamlandıktan sonra tarayıcıya geri dönmeyi unutmayın!",
|
||||||
|
"nanogpt_subtitle": "En yeni modeller (GPT-4, Claude). \\ Nno aboneliği, kripto ile ödeme yapın.",
|
||||||
"nano_current_rep": "Mevcut temsilci",
|
"nano_current_rep": "Mevcut temsilci",
|
||||||
"nano_pick_new_rep": "Yeni bir temsilci seçin",
|
"nano_pick_new_rep": "Yeni bir temsilci seçin",
|
||||||
"narrow": "Dar",
|
"narrow": "Dar",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Більше параметрів",
|
"more_options": "Більше параметрів",
|
||||||
"name": "Ім'я",
|
"name": "Ім'я",
|
||||||
|
"nano_gpt_thanks_message": "Дякуємо за використання наногпта! Не забудьте повернутися до браузера після завершення транзакції!",
|
||||||
|
"nanogpt_subtitle": "Усі найновіші моделі (GPT-4, Claude). \\ Nno підписка, оплата криптовалютою.",
|
||||||
"nano_current_rep": "Поточний представник",
|
"nano_current_rep": "Поточний представник",
|
||||||
"nano_pick_new_rep": "Виберіть нового представника",
|
"nano_pick_new_rep": "Виберіть нового представника",
|
||||||
"narrow": "вузькі",
|
"narrow": "вузькі",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔",
|
"moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔",
|
||||||
"more_options": "مزید زرائے",
|
"more_options": "مزید زرائے",
|
||||||
"name": "ﻡﺎﻧ",
|
"name": "ﻡﺎﻧ",
|
||||||
|
"nano_gpt_thanks_message": "نانوگپٹ استعمال کرنے کا شکریہ! اپنے لین دین کی تکمیل کے بعد براؤزر کی طرف واپس جانا یاد رکھیں!",
|
||||||
|
"nanogpt_subtitle": "تمام تازہ ترین ماڈل (GPT-4 ، کلاڈ)۔ n n no سبسکرپشن ، کریپٹو کے ساتھ ادائیگی کریں۔",
|
||||||
"nano_current_rep": "موجودہ نمائندہ",
|
"nano_current_rep": "موجودہ نمائندہ",
|
||||||
"nano_pick_new_rep": "ایک نیا نمائندہ منتخب کریں",
|
"nano_pick_new_rep": "ایک نیا نمائندہ منتخب کریں",
|
||||||
"narrow": "تنگ",
|
"narrow": "تنگ",
|
||||||
|
|
|
@ -367,6 +367,8 @@
|
||||||
"moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "Ìyàn àfikún",
|
"more_options": "Ìyàn àfikún",
|
||||||
"name": "Oruko",
|
"name": "Oruko",
|
||||||
|
"nano_gpt_thanks_message": "O ṣeun fun lilo Nonnogt! Ranti lati tẹle pada si ẹrọ lilọ kiri ayelujara lẹhin iṣowo rẹ pari!",
|
||||||
|
"nanogpt_subtitle": "Gbogbo awọn awoṣe tuntun (GPT-4, Claude). \\ Nno alabapin kan, sanwo pẹlu Crypto.",
|
||||||
"nano_current_rep": "Aṣoju lọwọlọwọ",
|
"nano_current_rep": "Aṣoju lọwọlọwọ",
|
||||||
"nano_pick_new_rep": "Mu aṣoju tuntun kan",
|
"nano_pick_new_rep": "Mu aṣoju tuntun kan",
|
||||||
"narrow": "Taara",
|
"narrow": "Taara",
|
||||||
|
|
|
@ -366,6 +366,8 @@
|
||||||
"moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}",
|
"moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}",
|
||||||
"more_options": "更多选项",
|
"more_options": "更多选项",
|
||||||
"name": "姓名",
|
"name": "姓名",
|
||||||
|
"nano_gpt_thanks_message": "感谢您使用Nanogpt!事务完成后,请记住回到浏览器!",
|
||||||
|
"nanogpt_subtitle": "所有最新型号(GPT-4,Claude)。\\ nno订阅,用加密货币付款。",
|
||||||
"nano_current_rep": "当前代表",
|
"nano_current_rep": "当前代表",
|
||||||
"nano_pick_new_rep": "选择新代表",
|
"nano_pick_new_rep": "选择新代表",
|
||||||
"narrow": "狭窄的",
|
"narrow": "狭窄的",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'utils/utils.dart';
|
||||||
const configPath = 'tool/.secrets-config.json';
|
const configPath = 'tool/.secrets-config.json';
|
||||||
const evmChainsConfigPath = 'tool/.evm-secrets-config.json';
|
const evmChainsConfigPath = 'tool/.evm-secrets-config.json';
|
||||||
const solanaConfigPath = 'tool/.solana-secrets-config.json';
|
const solanaConfigPath = 'tool/.solana-secrets-config.json';
|
||||||
|
const nanoConfigPath = 'tool/.nano-secrets-config.json';
|
||||||
const tronConfigPath = 'tool/.tron-secrets-config.json';
|
const tronConfigPath = 'tool/.tron-secrets-config.json';
|
||||||
|
|
||||||
Future<void> main(List<String> args) async => generateSecretsConfig(args);
|
Future<void> main(List<String> args) async => generateSecretsConfig(args);
|
||||||
|
@ -21,6 +22,7 @@ Future<void> generateSecretsConfig(List<String> args) async {
|
||||||
final configFile = File(configPath);
|
final configFile = File(configPath);
|
||||||
final evmChainsConfigFile = File(evmChainsConfigPath);
|
final evmChainsConfigFile = File(evmChainsConfigPath);
|
||||||
final solanaConfigFile = File(solanaConfigPath);
|
final solanaConfigFile = File(solanaConfigPath);
|
||||||
|
final nanoConfigFile = File(nanoConfigPath);
|
||||||
final tronConfigFile = File(tronConfigPath);
|
final tronConfigFile = File(tronConfigPath);
|
||||||
|
|
||||||
final secrets = <String, dynamic>{};
|
final secrets = <String, dynamic>{};
|
||||||
|
@ -42,45 +44,48 @@ Future<void> generateSecretsConfig(List<String> args) async {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// base:
|
||||||
SecretKey.base.forEach((sec) {
|
SecretKey.base.forEach((sec) {
|
||||||
if (secrets[sec.name] != null) {
|
if (secrets[sec.name] != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets[sec.name] = sec.generate();
|
secrets[sec.name] = sec.generate();
|
||||||
});
|
});
|
||||||
|
|
||||||
var secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
var secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
await configFile.writeAsString(secretsJson);
|
await configFile.writeAsString(secretsJson);
|
||||||
|
|
||||||
secrets.clear();
|
secrets.clear();
|
||||||
|
|
||||||
|
// evm chains:
|
||||||
SecretKey.evmChainsSecrets.forEach((sec) {
|
SecretKey.evmChainsSecrets.forEach((sec) {
|
||||||
if (secrets[sec.name] != null) {
|
if (secrets[sec.name] != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets[sec.name] = sec.generate();
|
secrets[sec.name] = sec.generate();
|
||||||
});
|
});
|
||||||
|
|
||||||
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
|
|
||||||
await evmChainsConfigFile.writeAsString(secretsJson);
|
await evmChainsConfigFile.writeAsString(secretsJson);
|
||||||
|
|
||||||
secrets.clear();
|
secrets.clear();
|
||||||
|
|
||||||
|
// solana:
|
||||||
SecretKey.solanaSecrets.forEach((sec) {
|
SecretKey.solanaSecrets.forEach((sec) {
|
||||||
if (secrets[sec.name] != null) {
|
if (secrets[sec.name] != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
secrets[sec.name] = sec.generate();
|
secrets[sec.name] = sec.generate();
|
||||||
});
|
});
|
||||||
|
|
||||||
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
|
|
||||||
await solanaConfigFile.writeAsString(secretsJson);
|
await solanaConfigFile.writeAsString(secretsJson);
|
||||||
|
secrets.clear();
|
||||||
|
|
||||||
|
// nano:
|
||||||
|
SecretKey.nanoSecrets.forEach((sec) {
|
||||||
|
if (secrets[sec.name] != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
secrets[sec.name] = sec.generate();
|
||||||
|
});
|
||||||
|
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
|
await nanoConfigFile.writeAsString(secretsJson);
|
||||||
secrets.clear();
|
secrets.clear();
|
||||||
|
|
||||||
SecretKey.tronSecrets.forEach((sec) {
|
SecretKey.tronSecrets.forEach((sec) {
|
||||||
|
@ -90,8 +95,7 @@ Future<void> generateSecretsConfig(List<String> args) async {
|
||||||
|
|
||||||
secrets[sec.name] = sec.generate();
|
secrets[sec.name] = sec.generate();
|
||||||
});
|
});
|
||||||
|
|
||||||
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
secretsJson = JsonEncoder.withIndent(' ').convert(secrets);
|
||||||
|
|
||||||
await tronConfigFile.writeAsString(secretsJson);
|
await tronConfigFile.writeAsString(secretsJson);
|
||||||
|
secrets.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,10 @@ class SecretKey {
|
||||||
SecretKey('ankrApiKey', () => ''),
|
SecretKey('ankrApiKey', () => ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
static final nanoSecrets = [
|
||||||
|
SecretKey('nano2ApiKey', () => ''),
|
||||||
|
];
|
||||||
|
|
||||||
static final tronSecrets = [
|
static final tronSecrets = [
|
||||||
SecretKey('tronGridApiKey', () => ''),
|
SecretKey('tronGridApiKey', () => ''),
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue