Merge branch 'featuresGdev2' into 'master'
Features gdev2 See merge request clients/gecko!26
This commit is contained in:
commit
6d55b551b1
|
@ -46,7 +46,6 @@ Color floattingYellow = const Color(0xffEFEFBF);
|
||||||
Color backgroundColor = const Color(0xFFF5F5F5);
|
Color backgroundColor = const Color(0xFFF5F5F5);
|
||||||
|
|
||||||
// Substrate settings
|
// Substrate settings
|
||||||
const int ss58 = 42;
|
|
||||||
String currencyName = 'ĞD';
|
String currencyName = 'ĞD';
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
|
|
@ -385,19 +385,20 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) {
|
for (var derivationNbr in [for (var i = 0; i < numberScan; i += 1) i]) {
|
||||||
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(ss58,
|
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(
|
||||||
|
sub.ss58,
|
||||||
cryptoType: CryptoType.sr25519,
|
cryptoType: CryptoType.sr25519,
|
||||||
mnemonic: generatedMnemonic!,
|
mnemonic: generatedMnemonic!,
|
||||||
derivePath: '//$derivationNbr');
|
derivePath: '//$derivationNbr');
|
||||||
|
|
||||||
final balance = await sub.getBalance(addressData.address!).timeout(
|
final balance = await sub.getBalance(addressData.address!).timeout(
|
||||||
const Duration(seconds: 1),
|
const Duration(seconds: 1),
|
||||||
onTimeout: () => 0,
|
onTimeout: () => {},
|
||||||
);
|
);
|
||||||
// const balance = 0;
|
// const balance = 0;
|
||||||
|
|
||||||
log.d(balance);
|
log.d(balance);
|
||||||
if (balance != 0) {
|
if (balance != {}) {
|
||||||
isAlive = true;
|
isAlive = true;
|
||||||
String walletName = scanedWalletNumber == 0
|
String walletName = scanedWalletNumber == 0
|
||||||
? 'currentWallet'.tr()
|
? 'currentWallet'.tr()
|
||||||
|
@ -426,16 +427,16 @@ class GenerateWalletsProvider with ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> scanRootBalance(SubstrateSdk sub, int currentChestNumber) async {
|
Future<bool> scanRootBalance(SubstrateSdk sub, int currentChestNumber) async {
|
||||||
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(ss58,
|
final addressData = await sub.sdk.api.keyring.addressFromMnemonic(sub.ss58,
|
||||||
cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!);
|
cryptoType: CryptoType.sr25519, mnemonic: generatedMnemonic!);
|
||||||
|
|
||||||
final balance = await sub.getBalance(addressData.address!).timeout(
|
final balance = await sub.getBalance(addressData.address!).timeout(
|
||||||
const Duration(seconds: 1),
|
const Duration(seconds: 1),
|
||||||
onTimeout: () => 0,
|
onTimeout: () => {},
|
||||||
);
|
);
|
||||||
|
|
||||||
log.d(balance);
|
log.d(balance);
|
||||||
if (balance != 0) {
|
if (balance != {}) {
|
||||||
String walletName = 'myRootWallet'.tr();
|
String walletName = 'myRootWallet'.tr();
|
||||||
await sub.importAccount(
|
await sub.importAccount(
|
||||||
mnemonic: '', fromMnemonic: true, password: pin.text);
|
mnemonic: '', fromMnemonic: true, password: pin.text);
|
||||||
|
|
|
@ -28,10 +28,287 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
bool isLoadingEndpoint = false;
|
bool isLoadingEndpoint = false;
|
||||||
String debugConnection = '';
|
String debugConnection = '';
|
||||||
String transactionStatus = '';
|
String transactionStatus = '';
|
||||||
|
int ss58 = 42;
|
||||||
|
|
||||||
TextEditingController jsonKeystore = TextEditingController();
|
TextEditingController jsonKeystore = TextEditingController();
|
||||||
TextEditingController keystorePassword = TextEditingController();
|
TextEditingController keystorePassword = TextEditingController();
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
////////// 1: API METHODS ///////////
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
Future<String> executeCall(TxInfoData txInfo, txOptions, String password,
|
||||||
|
[String? rawParams]) async {
|
||||||
|
try {
|
||||||
|
final hash = await sdk.api.tx
|
||||||
|
.signAndSend(txInfo, txOptions, password, rawParam: rawParams)
|
||||||
|
.timeout(
|
||||||
|
const Duration(seconds: 12),
|
||||||
|
onTimeout: () => {},
|
||||||
|
);
|
||||||
|
log.d(hash);
|
||||||
|
if (hash.isEmpty) {
|
||||||
|
transactionStatus = 'timeout';
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
|
return 'timeout';
|
||||||
|
} else {
|
||||||
|
transactionStatus = hash.toString();
|
||||||
|
notifyListeners();
|
||||||
|
return hash.toString();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
transactionStatus = e.toString();
|
||||||
|
notifyListeners();
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future getStorage(String call) async {
|
||||||
|
return await sdk.webView!.evalJavascript('api.query.$call');
|
||||||
|
}
|
||||||
|
|
||||||
|
TxSenderData _setSender() {
|
||||||
|
return TxSenderData(
|
||||||
|
keyring.current.address,
|
||||||
|
keyring.current.pubKey,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
////////// 2: GET ONCHAIN STORAGE //////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
|
Future<List<AddressInfo>> getKeyStoreAddress() async {
|
||||||
|
List<AddressInfo> result = [];
|
||||||
|
|
||||||
|
for (var element in keyring.allAccounts) {
|
||||||
|
final account = AddressInfo(address: element.address);
|
||||||
|
final globalBalance = await getBalance(element.address!);
|
||||||
|
account.balance = globalBalance['transferableBalance']!;
|
||||||
|
|
||||||
|
result.add(account);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getIdentityIndexOf(String address) async {
|
||||||
|
return await getStorage('identity.identityIndexOf("$address")') ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<int>> getCerts(String address) async {
|
||||||
|
final idtyIndex = await getIdentityIndexOf(address);
|
||||||
|
final certsReceiver =
|
||||||
|
await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? [];
|
||||||
|
|
||||||
|
return [certsReceiver['receivedCount'], certsReceiver['issuedCount']];
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getCertValidityPeriod(String from, String to) async {
|
||||||
|
final idtyIndexFrom = await getIdentityIndexOf(from);
|
||||||
|
final idtyIndexTo = await getIdentityIndexOf(to);
|
||||||
|
|
||||||
|
if (idtyIndexFrom == 0 || idtyIndexTo == 0) return 0;
|
||||||
|
|
||||||
|
final List certData =
|
||||||
|
await getStorage('cert.certsByReceiver($idtyIndexTo)') ?? [];
|
||||||
|
|
||||||
|
if (certData.isEmpty) return 0;
|
||||||
|
for (List certInfo in certData) {
|
||||||
|
if (certInfo[0] == idtyIndexFrom) {
|
||||||
|
return certInfo[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> getParameters() async {
|
||||||
|
final currencyParameters =
|
||||||
|
await getStorage('parameters.parametersStorage()') ?? {};
|
||||||
|
return currencyParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> hasAccountConsumers(String address) async {
|
||||||
|
final accountInfo = await getStorage('system.account("$address")');
|
||||||
|
final consumers = accountInfo['consumers'];
|
||||||
|
return consumers == 0 ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future<double> getBalance(String address) async {
|
||||||
|
// double balance = 0.0;
|
||||||
|
|
||||||
|
// if (nodeConnected) {
|
||||||
|
// final brutBalance = await sdk.api.account.queryBalance(address);
|
||||||
|
// // log.d(brutBalance?.toJson());
|
||||||
|
// balance = int.parse(brutBalance!.freeBalance) / 100;
|
||||||
|
// } else {
|
||||||
|
// balance = -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// await getUnclaimedUd(address);
|
||||||
|
// return balance;
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<Map<String, double>> getBalance(String address) async {
|
||||||
|
if (!nodeConnected) {
|
||||||
|
return {
|
||||||
|
'transferableBalance': 0,
|
||||||
|
'free': 0,
|
||||||
|
'unclaimedUds': 0,
|
||||||
|
'reserved': 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get onchain storage values
|
||||||
|
final Map balanceGlobal = await getStorage('system.account("$address")');
|
||||||
|
final int? idtyIndex =
|
||||||
|
await getStorage('identity.identityIndexOf("$address")');
|
||||||
|
final Map? idtyData = idtyIndex == null
|
||||||
|
? null
|
||||||
|
: await getStorage('identity.identities($idtyIndex)');
|
||||||
|
final int currentUdIndex =
|
||||||
|
int.parse(await getStorage('universalDividend.currentUdIndex()'));
|
||||||
|
final List pastReevals =
|
||||||
|
await getStorage('universalDividend.pastReevals()');
|
||||||
|
|
||||||
|
// Compute amount of claimable UDs
|
||||||
|
final int unclaimedUds = _computeUnclaimUds(currentUdIndex,
|
||||||
|
idtyData?['data']?['firstEligibleUd'] ?? 0, pastReevals);
|
||||||
|
|
||||||
|
// Calculate transferable and potential balance
|
||||||
|
final int transferableBalance =
|
||||||
|
(balanceGlobal['data']['free'] + unclaimedUds);
|
||||||
|
|
||||||
|
Map<String, double> finalBalances = {
|
||||||
|
'transferableBalance': transferableBalance / 100,
|
||||||
|
'free': balanceGlobal['data']['free'] / 100,
|
||||||
|
'unclaimedUds': unclaimedUds / 100,
|
||||||
|
'reserved': balanceGlobal['data']['reserved'] / 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
// log.i(finalBalances);
|
||||||
|
|
||||||
|
return finalBalances;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _computeUnclaimUds(
|
||||||
|
int currentUdIndex, int firstEligibleUd, List pastReevals) {
|
||||||
|
int totalAmount = 0;
|
||||||
|
|
||||||
|
if (firstEligibleUd == 0) return 0;
|
||||||
|
|
||||||
|
for (final List reval in pastReevals.reversed) {
|
||||||
|
final int revalNbr = reval[0];
|
||||||
|
final int revalValue = reval[1];
|
||||||
|
|
||||||
|
// Loop each UDs revaluations and sum unclaimed balance
|
||||||
|
if (revalNbr <= firstEligibleUd) {
|
||||||
|
final count = currentUdIndex - firstEligibleUd;
|
||||||
|
totalAmount += count * revalValue;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
final count = currentUdIndex - revalNbr;
|
||||||
|
totalAmount += count * revalValue;
|
||||||
|
currentUdIndex = revalNbr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return totalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> getSs58Prefix() async {
|
||||||
|
final List res = await sdk.webView!.evalJavascript(
|
||||||
|
'api.consts.system.ss58Prefix.words',
|
||||||
|
wrapPromise: false) ??
|
||||||
|
[42];
|
||||||
|
|
||||||
|
ss58 = res[0];
|
||||||
|
log.d(ss58);
|
||||||
|
return ss58;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isMemberGet(String address) async {
|
||||||
|
return await idtyStatus(address) == 'Validated';
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getMemberAddress() async {
|
||||||
|
// TODOO: Continue digging memberAddress detection
|
||||||
|
String memberAddress = '';
|
||||||
|
walletBox.toMap().forEach((key, value) async {
|
||||||
|
final bool isMember = await isMemberGet(value.address!);
|
||||||
|
log.d(isMember);
|
||||||
|
if (isMember) {
|
||||||
|
final currentChestNumber = configBox.get('currentChest');
|
||||||
|
ChestData newChestData = chestBox.get(currentChestNumber)!;
|
||||||
|
newChestData.memberWallet = value.number;
|
||||||
|
await chestBox.put(currentChestNumber, newChestData);
|
||||||
|
memberAddress = value.address!;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
log.d(memberAddress);
|
||||||
|
return memberAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map<String, int>> certState(String from, String to) async {
|
||||||
|
Map<String, int> result = {};
|
||||||
|
if (from != to && await isMemberGet(from)) {
|
||||||
|
final removableOn = await getCertValidityPeriod(from, to);
|
||||||
|
final certMeta = await getCertMeta(from);
|
||||||
|
final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0;
|
||||||
|
final certRemovableDuration = (removableOn - blocNumber) * 6;
|
||||||
|
const int renewDelay = 2 * 30 * 24 * 3600; // 2 months
|
||||||
|
|
||||||
|
if (certRemovableDuration >= renewDelay) {
|
||||||
|
final certRenewDuration = certRemovableDuration - renewDelay;
|
||||||
|
result.putIfAbsent('certRenewable', () => certRenewDuration);
|
||||||
|
} else if (nextIssuableOn > blocNumber) {
|
||||||
|
final certDelayDuration = (nextIssuableOn - blocNumber) * 6;
|
||||||
|
result.putIfAbsent('certDelay', () => certDelayDuration);
|
||||||
|
} else {
|
||||||
|
result.putIfAbsent('canCert', () => 0);
|
||||||
|
}
|
||||||
|
log.d('tatatatata: ${nextIssuableOn - blocNumber}');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Map> getCertMeta(String address) async {
|
||||||
|
var idtyIndex = await getIdentityIndexOf(address);
|
||||||
|
|
||||||
|
final certMeta =
|
||||||
|
await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
|
||||||
|
|
||||||
|
return certMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> idtyStatus(String address, [bool smooth = true]) async {
|
||||||
|
var idtyIndex = await getIdentityIndexOf(address);
|
||||||
|
|
||||||
|
if (idtyIndex == 0) {
|
||||||
|
return 'noid';
|
||||||
|
}
|
||||||
|
|
||||||
|
final idtyStatus = await getStorage('identity.identities($idtyIndex)');
|
||||||
|
|
||||||
|
if (idtyStatus != null) {
|
||||||
|
final String status = idtyStatus['status'];
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
} else {
|
||||||
|
return 'expired';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future getCurencyName() async {}
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
////// 3: SUBSTRATE CONNECTION //////
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
Future<void> initApi() async {
|
Future<void> initApi() async {
|
||||||
sdkLoading = true;
|
sdkLoading = true;
|
||||||
await keyring.init([ss58]);
|
await keyring.init([ss58]);
|
||||||
|
@ -43,15 +320,13 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? getConnectedEndpoint() {
|
||||||
|
return sdk.api.connectedNode?.endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> connectNode(BuildContext ctx) async {
|
Future<void> connectNode(BuildContext ctx) async {
|
||||||
HomeProvider homeProvider = Provider.of<HomeProvider>(ctx, listen: false);
|
HomeProvider homeProvider = Provider.of<HomeProvider>(ctx, listen: false);
|
||||||
|
|
||||||
// var connectivityResult = await (Connectivity().checkConnectivity());
|
|
||||||
// if (connectivityResult == ConnectivityResult.mobile ||
|
|
||||||
// connectivityResult == ConnectivityResult.wifi) {
|
|
||||||
// _homeProvider.changeMessage("Vous n'êtes pas connecté à internet", 0);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
homeProvider.changeMessage("connectionPending".tr(), 0);
|
homeProvider.changeMessage("connectionPending".tr(), 0);
|
||||||
|
|
||||||
// configBox.delete('customEndpoint');
|
// configBox.delete('customEndpoint');
|
||||||
|
@ -60,31 +335,8 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
? [getDuniterCustomEndpoint()]
|
? [getDuniterCustomEndpoint()]
|
||||||
: getDuniterBootstrap();
|
: getDuniterBootstrap();
|
||||||
|
|
||||||
// final nodes = getDuniterBootstrap();
|
|
||||||
|
|
||||||
int timeout = 10000;
|
int timeout = 10000;
|
||||||
|
|
||||||
// if (n.endpoint!.startsWith('ws://')) {
|
|
||||||
// timeout = 5000;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//// Check websocket conenction - only for wss
|
|
||||||
// final channel = IOWebSocketChannel.connect(
|
|
||||||
// Uri.parse('wss://192.168.1.72:9944'),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// channel.stream.listen(
|
|
||||||
// (dynamic message) {
|
|
||||||
// log.d('message $message');
|
|
||||||
// },
|
|
||||||
// onDone: () {
|
|
||||||
// log.d('ws channel closed');
|
|
||||||
// },
|
|
||||||
// onError: (error) {
|
|
||||||
// log.d('ws error $error');
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
if (sdk.api.connectedNode?.endpoint != null) {
|
if (sdk.api.connectedNode?.endpoint != null) {
|
||||||
await sdk.api.setting.unsubscribeBestNumber();
|
await sdk.api.setting.unsubscribeBestNumber();
|
||||||
}
|
}
|
||||||
|
@ -99,6 +351,7 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
nodeConnected = true;
|
nodeConnected = true;
|
||||||
|
// await getSs58Prefix();
|
||||||
|
|
||||||
// Subscribe bloc number
|
// Subscribe bloc number
|
||||||
sdk.api.setting.subscribeBestNumber((res) {
|
sdk.api.setting.subscribeBestNumber((res) {
|
||||||
|
@ -197,7 +450,7 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
});
|
});
|
||||||
if (json == null) return '';
|
if (json == null) return '';
|
||||||
log.d(json);
|
// log.d(json);
|
||||||
try {
|
try {
|
||||||
await sdk.api.keyring.addAccount(
|
await sdk.api.keyring.addAccount(
|
||||||
keyring,
|
keyring,
|
||||||
|
@ -205,7 +458,6 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
acc: json,
|
acc: json,
|
||||||
password: password,
|
password: password,
|
||||||
);
|
);
|
||||||
// Clipboard.setData(ClipboardData(text: jsonEncode(acc.toJson())));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.e(e);
|
log.e(e);
|
||||||
importIsLoading = false;
|
importIsLoading = false;
|
||||||
|
@ -218,91 +470,9 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
return keyring.allAccounts.last.address!;
|
return keyring.allAccounts.last.address!;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reload() {
|
//////////////////////////////////
|
||||||
notifyListeners();
|
/////// 4: CRYPTOGRAPHY //////////
|
||||||
}
|
//////////////////////////////////
|
||||||
|
|
||||||
Future<List<AddressInfo>> getKeyStoreAddress() async {
|
|
||||||
List<AddressInfo> result = [];
|
|
||||||
|
|
||||||
// sdk.api.account.unsubscribeBalance();
|
|
||||||
for (var element in keyring.allAccounts) {
|
|
||||||
// Clipboard.setData(ClipboardData(text: jsonEncode(element)));
|
|
||||||
final account = AddressInfo(address: element.address);
|
|
||||||
// await sdk.api.account.subscribeBalance(element.address, (p0) {
|
|
||||||
// account.balance = int.parse(p0.freeBalance) / 100;
|
|
||||||
// });
|
|
||||||
// sdk.api.setting.unsubscribeBestNumber();
|
|
||||||
account.balance = await getBalance(element.address!);
|
|
||||||
result.add(account);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<int>> getCerts(String address) async {
|
|
||||||
final idtyIndex = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identityIndexOf("$address")');
|
|
||||||
// log.d('u32: ' + idtyIndex.toString());
|
|
||||||
|
|
||||||
final certsReceiver = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.cert.storageIdtyCertMeta($idtyIndex)') ??
|
|
||||||
[];
|
|
||||||
|
|
||||||
return [certsReceiver['receivedCount'], certsReceiver['issuedCount']];
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map> getCertData(String from, String to) async {
|
|
||||||
final idtyIndexFrom = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identityIndexOf("$from")');
|
|
||||||
|
|
||||||
final idtyIndexTo = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identityIndexOf("$to")');
|
|
||||||
|
|
||||||
if (idtyIndexFrom == null || idtyIndexTo == null) return {};
|
|
||||||
|
|
||||||
final certData = await sdk.webView!.evalJavascript(
|
|
||||||
'api.query.cert.storageCertsByIssuer($idtyIndexFrom, $idtyIndexTo)') ??
|
|
||||||
'';
|
|
||||||
|
|
||||||
if (certData == '') return {};
|
|
||||||
|
|
||||||
// log.d(_certData);
|
|
||||||
return certData;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> hasAccountConsumers(String address) async {
|
|
||||||
final accountInfo = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.system.account("$address")');
|
|
||||||
final consumers = accountInfo['consumers'];
|
|
||||||
// log.d('Consumers: $_consumers');
|
|
||||||
return consumers == 0 ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<double> getBalance(String address, {bool isUd = false}) async {
|
|
||||||
double balance = 0.0;
|
|
||||||
|
|
||||||
// log.d('nodeConnected: ' + nodeConnected.toString());
|
|
||||||
if (nodeConnected) {
|
|
||||||
final brutBalance = await sdk.api.account.queryBalance(address);
|
|
||||||
balance = int.parse(brutBalance!.freeBalance) / 100;
|
|
||||||
} else {
|
|
||||||
balance = -1;
|
|
||||||
}
|
|
||||||
return balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<double> subscribeBalance(String address, {bool isUd = false}) async {
|
|
||||||
double balance = 0.0;
|
|
||||||
if (nodeConnected) {
|
|
||||||
await sdk.api.account.subscribeBalance(address, (balanceData) {
|
|
||||||
balance = int.parse(balanceData.freeBalance) / 100;
|
|
||||||
notifyListeners();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyPairData getKeypair(String address) {
|
KeyPairData getKeypair(String address) {
|
||||||
return keyring.keyPairs.firstWhere((kp) => kp.address == address,
|
return keyring.keyPairs.firstWhere((kp) => kp.address == address,
|
||||||
|
@ -311,7 +481,6 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
|
|
||||||
Future<bool> checkPassword(String address, String pass) async {
|
Future<bool> checkPassword(String address, String pass) async {
|
||||||
final account = getKeypair(address);
|
final account = getKeypair(address);
|
||||||
// log.d(account.address);
|
|
||||||
|
|
||||||
return await sdk.api.keyring.checkPassword(account, pass);
|
return await sdk.api.keyring.checkPassword(account, pass);
|
||||||
}
|
}
|
||||||
|
@ -367,8 +536,6 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
final gen = await sdk.api.keyring.generateMnemonic(ss58);
|
final gen = await sdk.api.keyring.generateMnemonic(ss58);
|
||||||
generatedMnemonic = gen.mnemonic!;
|
generatedMnemonic = gen.mnemonic!;
|
||||||
|
|
||||||
// final res = await importAccount(fromMnemonic: true);
|
|
||||||
// await Clipboard.setData(ClipboardData(text: generatedMnemonic));
|
|
||||||
return gen.mnemonic!;
|
return gen.mnemonic!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,319 +563,6 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> pay(
|
|
||||||
{required String fromAddress,
|
|
||||||
required String destAddress,
|
|
||||||
required double amount,
|
|
||||||
required String password}) async {
|
|
||||||
transactionStatus = '';
|
|
||||||
|
|
||||||
// setCurrentWallet(fromAddress);
|
|
||||||
|
|
||||||
log.d(keyring.current.address);
|
|
||||||
log.d(fromAddress);
|
|
||||||
log.d(password);
|
|
||||||
// log.d(await checkPassword(fromAddress, password));
|
|
||||||
|
|
||||||
final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]);
|
|
||||||
log.d(fromPubkey!.keys.first);
|
|
||||||
final sender = TxSenderData(
|
|
||||||
fromAddress,
|
|
||||||
fromPubkey.keys.first,
|
|
||||||
);
|
|
||||||
final txInfo = TxInfoData(
|
|
||||||
'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender);
|
|
||||||
|
|
||||||
final int amountUnit = (amount * 100).toInt();
|
|
||||||
try {
|
|
||||||
final hash = await sdk.api.tx.signAndSend(
|
|
||||||
txInfo,
|
|
||||||
[destAddress, amount == -1 ? false : amountUnit],
|
|
||||||
password,
|
|
||||||
onStatusChange: (status) {
|
|
||||||
log.d('Transaction status: $status');
|
|
||||||
transactionStatus = status;
|
|
||||||
notifyListeners();
|
|
||||||
},
|
|
||||||
).timeout(
|
|
||||||
const Duration(seconds: 12),
|
|
||||||
onTimeout: () => {},
|
|
||||||
);
|
|
||||||
log.d(hash.toString());
|
|
||||||
if (hash.isEmpty) {
|
|
||||||
transactionStatus = 'timeout';
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
return 'timeout';
|
|
||||||
} else {
|
|
||||||
transactionStatus = hash.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return hash.toString();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
transactionStatus = e.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return e.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> certify(
|
|
||||||
String fromAddress, String password, String toAddress) async {
|
|
||||||
transactionStatus = '';
|
|
||||||
|
|
||||||
// setCurrentWallet(fromAddress);
|
|
||||||
log.d('me: $fromAddress');
|
|
||||||
log.d('to: $toAddress');
|
|
||||||
|
|
||||||
final myIdtyStatus = await idtyStatus(fromAddress);
|
|
||||||
final toIdtyStatus = await idtyStatus(toAddress);
|
|
||||||
|
|
||||||
log.d(myIdtyStatus);
|
|
||||||
log.d(toIdtyStatus);
|
|
||||||
|
|
||||||
if (myIdtyStatus != 'Validated') {
|
|
||||||
transactionStatus = 'notMember';
|
|
||||||
notifyListeners();
|
|
||||||
return 'notMember';
|
|
||||||
}
|
|
||||||
|
|
||||||
final sender = TxSenderData(
|
|
||||||
keyring.current.address,
|
|
||||||
keyring.current.pubKey,
|
|
||||||
);
|
|
||||||
TxInfoData txInfo;
|
|
||||||
|
|
||||||
if (toIdtyStatus == 'noid') {
|
|
||||||
txInfo = TxInfoData(
|
|
||||||
'identity',
|
|
||||||
'createIdentity',
|
|
||||||
sender,
|
|
||||||
);
|
|
||||||
} else if (toIdtyStatus == 'Validated' ||
|
|
||||||
toIdtyStatus == 'ConfirmedByOwner') {
|
|
||||||
txInfo = TxInfoData(
|
|
||||||
'cert',
|
|
||||||
'addCert',
|
|
||||||
sender,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
transactionStatus = 'cantBeCert';
|
|
||||||
notifyListeners();
|
|
||||||
return 'cantBeCert';
|
|
||||||
}
|
|
||||||
|
|
||||||
log.d('Cert action: ${txInfo.call!}');
|
|
||||||
|
|
||||||
try {
|
|
||||||
final hash = await sdk.api.tx
|
|
||||||
.signAndSend(
|
|
||||||
txInfo,
|
|
||||||
[toAddress],
|
|
||||||
password,
|
|
||||||
)
|
|
||||||
.timeout(
|
|
||||||
const Duration(seconds: 12),
|
|
||||||
onTimeout: () => {},
|
|
||||||
);
|
|
||||||
log.d(hash);
|
|
||||||
if (hash.isEmpty) {
|
|
||||||
transactionStatus = 'timeout';
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
return 'timeout';
|
|
||||||
} else {
|
|
||||||
transactionStatus = hash.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return hash.toString();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
transactionStatus = e.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return e.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> idtyStatus(String address, [bool smooth = true]) async {
|
|
||||||
// var tata = await sdk.webView!
|
|
||||||
// .evalJavascript('api.query.system.account("$address")');
|
|
||||||
|
|
||||||
var idtyIndex = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identityIndexOf("$address")');
|
|
||||||
|
|
||||||
if (idtyIndex == null) {
|
|
||||||
return 'noid';
|
|
||||||
}
|
|
||||||
|
|
||||||
final idtyStatus = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identities($idtyIndex)');
|
|
||||||
|
|
||||||
if (idtyStatus != null) {
|
|
||||||
final String status = idtyStatus['status'];
|
|
||||||
// log.d('Status $address: $_status');
|
|
||||||
return (status);
|
|
||||||
} else {
|
|
||||||
return 'expired';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> confirmIdentity(
|
|
||||||
String fromAddress, String name, String password) async {
|
|
||||||
// Confirm identity
|
|
||||||
// setCurrentWallet(fromAddress);
|
|
||||||
log.d('me: ${keyring.current.address!}');
|
|
||||||
|
|
||||||
final sender = TxSenderData(
|
|
||||||
keyring.current.address,
|
|
||||||
keyring.current.pubKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
final txInfo = TxInfoData(
|
|
||||||
'identity',
|
|
||||||
'confirmIdentity',
|
|
||||||
sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final hash = await sdk.api.tx.signAndSend(
|
|
||||||
txInfo,
|
|
||||||
[name],
|
|
||||||
password,
|
|
||||||
onStatusChange: (status) {
|
|
||||||
log.d('Transaction status: $status');
|
|
||||||
transactionStatus = status;
|
|
||||||
notifyListeners();
|
|
||||||
},
|
|
||||||
).timeout(
|
|
||||||
const Duration(seconds: 12),
|
|
||||||
onTimeout: () => {},
|
|
||||||
);
|
|
||||||
log.d(hash);
|
|
||||||
if (hash.isEmpty) {
|
|
||||||
transactionStatus = 'timeout';
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
return 'timeout';
|
|
||||||
} else {
|
|
||||||
transactionStatus = hash.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return hash.toString();
|
|
||||||
}
|
|
||||||
} on Exception catch (e) {
|
|
||||||
log.e(e);
|
|
||||||
transactionStatus = e.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return e.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isMemberGet(String address) async {
|
|
||||||
return await idtyStatus(address) == 'Validated';
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> getMemberAddress() async {
|
|
||||||
// TODOO: Continue digging memberAddress detection
|
|
||||||
String memberAddress = '';
|
|
||||||
walletBox.toMap().forEach((key, value) async {
|
|
||||||
final bool isMember = await isMemberGet(value.address!);
|
|
||||||
log.d(isMember);
|
|
||||||
if (isMember) {
|
|
||||||
final currentChestNumber = configBox.get('currentChest');
|
|
||||||
ChestData newChestData = chestBox.get(currentChestNumber)!;
|
|
||||||
newChestData.memberWallet = value.number;
|
|
||||||
await chestBox.put(currentChestNumber, newChestData);
|
|
||||||
memberAddress = value.address!;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
log.d(memberAddress);
|
|
||||||
return memberAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map<String, int>> certState(String from, String to) async {
|
|
||||||
Map<String, int> result = {};
|
|
||||||
if (from != to && await isMemberGet(from)) {
|
|
||||||
final certData = await getCertData(from, to);
|
|
||||||
final certMeta = await getCertMeta(from);
|
|
||||||
final int removableOn = certData['removableOn'] ?? 0;
|
|
||||||
final int nextIssuableOn = certMeta['nextIssuableOn'] ?? 0;
|
|
||||||
final certRemovableDuration = (removableOn - blocNumber) * 6;
|
|
||||||
const int renewDelay = 2 * 30 * 24 * 3600; // 2 months
|
|
||||||
|
|
||||||
if (certRemovableDuration >= renewDelay) {
|
|
||||||
final certRenewDuration = certRemovableDuration - renewDelay;
|
|
||||||
result.putIfAbsent('certRenewable', () => certRenewDuration);
|
|
||||||
} else if (nextIssuableOn > blocNumber) {
|
|
||||||
final certDelayDuration = (nextIssuableOn - blocNumber) * 6;
|
|
||||||
result.putIfAbsent('certDelay', () => certDelayDuration);
|
|
||||||
} else {
|
|
||||||
result.putIfAbsent('canCert', () => 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Map> getCertMeta(String address) async {
|
|
||||||
var idtyIndex = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identityIndexOf("$address")');
|
|
||||||
|
|
||||||
final certMeta = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.cert.storageIdtyCertMeta($idtyIndex)') ??
|
|
||||||
'';
|
|
||||||
// if (_certMeta['nextIssuableOn'] != 0) return {};
|
|
||||||
|
|
||||||
// log.d(_certMeta);
|
|
||||||
return certMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future revokeIdentity(String address, String password) async {
|
|
||||||
final idtyIndex = await sdk.webView!
|
|
||||||
.evalJavascript('api.query.identity.identityIndexOf("$address")');
|
|
||||||
|
|
||||||
final sender = TxSenderData(
|
|
||||||
keyring.current.address,
|
|
||||||
keyring.current.pubKey,
|
|
||||||
);
|
|
||||||
|
|
||||||
log.d(sender.address);
|
|
||||||
TxInfoData txInfo;
|
|
||||||
|
|
||||||
txInfo = TxInfoData(
|
|
||||||
'membership',
|
|
||||||
'revokeMembership',
|
|
||||||
sender,
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final hash = await sdk.api.tx
|
|
||||||
.signAndSend(
|
|
||||||
txInfo,
|
|
||||||
[idtyIndex],
|
|
||||||
password,
|
|
||||||
)
|
|
||||||
.timeout(
|
|
||||||
const Duration(seconds: 12),
|
|
||||||
onTimeout: () => {},
|
|
||||||
);
|
|
||||||
log.d(hash);
|
|
||||||
if (hash.isEmpty) {
|
|
||||||
transactionStatus = 'timeout';
|
|
||||||
notifyListeners();
|
|
||||||
|
|
||||||
return 'timeout';
|
|
||||||
} else {
|
|
||||||
transactionStatus = hash.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return hash.toString();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
transactionStatus = e.toString();
|
|
||||||
notifyListeners();
|
|
||||||
return e.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future getCurencyName() async {}
|
|
||||||
|
|
||||||
Future<String> derive(
|
Future<String> derive(
|
||||||
BuildContext context, String address, int number, String password) async {
|
BuildContext context, String address, int number, String password) async {
|
||||||
final keypair = getKeypair(address);
|
final keypair = getKeypair(address);
|
||||||
|
@ -748,11 +602,179 @@ class SubstrateSdk with ChangeNotifier {
|
||||||
return await sdk.api.keyring.checkMnemonicValid(mnemonic);
|
return await sdk.api.keyring.checkMnemonicValid(mnemonic);
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getConnectedEndpoint() {
|
//////////////////////////////////////
|
||||||
return sdk.api.connectedNode?.endpoint;
|
///////// 5: CALLS EXECUTION /////////
|
||||||
|
//////////////////////////////////////
|
||||||
|
|
||||||
|
Future<String> pay(
|
||||||
|
{required String fromAddress,
|
||||||
|
required String destAddress,
|
||||||
|
required double amount,
|
||||||
|
required String password}) async {
|
||||||
|
transactionStatus = '';
|
||||||
|
final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]);
|
||||||
|
final int amountUnit = (amount * 100).toInt();
|
||||||
|
|
||||||
|
final sender = TxSenderData(
|
||||||
|
fromAddress,
|
||||||
|
fromPubkey!.keys.first,
|
||||||
|
);
|
||||||
|
|
||||||
|
final globalBalance = await getBalance(fromAddress);
|
||||||
|
TxInfoData txInfo;
|
||||||
|
List txOptions = [];
|
||||||
|
String? rawParams;
|
||||||
|
|
||||||
|
if (globalBalance['unclaimedUds'] == 0) {
|
||||||
|
txInfo = TxInfoData('balances',
|
||||||
|
amount == -1 ? 'transferAll' : 'transferKeepAlive', sender);
|
||||||
|
txOptions = [destAddress, amount == -1 ? false : amountUnit];
|
||||||
|
} else {
|
||||||
|
txInfo = TxInfoData(
|
||||||
|
'utility',
|
||||||
|
'batchAll',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
const tx1 = 'api.tx.universalDividend.claimUds()';
|
||||||
|
final tx2 = amount == -1
|
||||||
|
? 'api.tx.balances.transferAll(false)'
|
||||||
|
: 'api.tx.balances.transferKeepAlive("$destAddress", $amountUnit)';
|
||||||
|
|
||||||
|
rawParams = '[[$tx1, $tx2]]';
|
||||||
|
}
|
||||||
|
|
||||||
|
// log.d('pay args: ${txInfo.module}, ${txInfo.call}, $txOptions, $rawParams');
|
||||||
|
return await executeCall(txInfo, txOptions, password, rawParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> certify(
|
||||||
|
String fromAddress, String password, String toAddress) async {
|
||||||
|
transactionStatus = '';
|
||||||
|
|
||||||
|
final myIdtyStatus = await idtyStatus(fromAddress);
|
||||||
|
final toIdtyStatus = await idtyStatus(toAddress);
|
||||||
|
|
||||||
|
final fromIndex = await getIdentityIndexOf(fromAddress);
|
||||||
|
final toIndex = await getIdentityIndexOf(toAddress);
|
||||||
|
|
||||||
|
if (myIdtyStatus != 'Validated') {
|
||||||
|
transactionStatus = 'notMember';
|
||||||
|
notifyListeners();
|
||||||
|
return 'notMember';
|
||||||
|
}
|
||||||
|
|
||||||
|
final sender = _setSender();
|
||||||
|
TxInfoData txInfo;
|
||||||
|
List txOptions = [];
|
||||||
|
String? rawParams;
|
||||||
|
|
||||||
|
final toCerts = await getCerts(toAddress);
|
||||||
|
final currencyParameters = await getParameters();
|
||||||
|
|
||||||
|
if (toIdtyStatus == 'noid') {
|
||||||
|
txInfo = TxInfoData(
|
||||||
|
'identity',
|
||||||
|
'createIdentity',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
txOptions = [toAddress];
|
||||||
|
} else if (toIdtyStatus == 'Validated' ||
|
||||||
|
toIdtyStatus == 'ConfirmedByOwner') {
|
||||||
|
if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] &&
|
||||||
|
toIdtyStatus != 'Validated') {
|
||||||
|
log.i('Batch cert and membership validation');
|
||||||
|
txInfo = TxInfoData(
|
||||||
|
'utility',
|
||||||
|
'batchAll',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
final tx1 = 'cert.addCert($fromIndex, $toIndex)';
|
||||||
|
final tx2 = 'identity.validateIdentity($toIndex)';
|
||||||
|
|
||||||
|
rawParams = '[[$tx1, $tx2]]';
|
||||||
|
} else {
|
||||||
|
txInfo = TxInfoData(
|
||||||
|
'cert',
|
||||||
|
'addCert',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
txOptions = [fromIndex, toIndex];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
transactionStatus = 'cantBeCert';
|
||||||
|
notifyListeners();
|
||||||
|
return 'cantBeCert';
|
||||||
|
}
|
||||||
|
|
||||||
|
log.d('Cert action: ${txInfo.call!}');
|
||||||
|
return await executeCall(txInfo, txOptions, password, rawParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Future claimUDs(String password) async {
|
||||||
|
// final sender = TxSenderData(
|
||||||
|
// keyring.current.address,
|
||||||
|
// keyring.current.pubKey,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// final txInfo = TxInfoData(
|
||||||
|
// 'universalDividend',
|
||||||
|
// 'claimUds',
|
||||||
|
// sender,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// return await executeCall(txInfo, [], password);
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<String> confirmIdentity(
|
||||||
|
String fromAddress, String name, String password) async {
|
||||||
|
log.d('me: ${keyring.current.address!}');
|
||||||
|
|
||||||
|
final sender = TxSenderData(
|
||||||
|
keyring.current.address,
|
||||||
|
keyring.current.pubKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
final txInfo = TxInfoData(
|
||||||
|
'identity',
|
||||||
|
'confirmIdentity',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
final txOptions = [name];
|
||||||
|
|
||||||
|
return await executeCall(txInfo, txOptions, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future revokeIdentity(String address, String password) async {
|
||||||
|
final idtyIndex = await getIdentityIndexOf(address);
|
||||||
|
|
||||||
|
final sender = TxSenderData(
|
||||||
|
keyring.current.address,
|
||||||
|
keyring.current.pubKey,
|
||||||
|
);
|
||||||
|
|
||||||
|
log.d(sender.address);
|
||||||
|
TxInfoData txInfo;
|
||||||
|
|
||||||
|
txInfo = TxInfoData(
|
||||||
|
'membership',
|
||||||
|
'revokeMembership',
|
||||||
|
sender,
|
||||||
|
);
|
||||||
|
|
||||||
|
final txOptions = [idtyIndex];
|
||||||
|
|
||||||
|
return await executeCall(txInfo, txOptions, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reload() {
|
||||||
|
notifyListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
/////// 6: UI ELEMENTS (off class) /////////
|
||||||
|
////////////////////////////////////////////
|
||||||
|
|
||||||
void snack(BuildContext context, String message, {int duration = 2}) {
|
void snack(BuildContext context, String message, {int duration = 2}) {
|
||||||
final snackBar =
|
final snackBar =
|
||||||
SnackBar(content: Text(message), duration: Duration(seconds: duration));
|
SnackBar(content: Text(message), duration: Duration(seconds: duration));
|
||||||
|
|
|
@ -56,7 +56,7 @@ class WalletOptionsProvider with ChangeNotifier {
|
||||||
if (answer ?? false) {
|
if (answer ?? false) {
|
||||||
//Check if balance is null
|
//Check if balance is null
|
||||||
final balance = await sub.getBalance(wallet.address!);
|
final balance = await sub.getBalance(wallet.address!);
|
||||||
if (balance != 0) {
|
if (balance != {}) {
|
||||||
MyWalletsProvider myWalletProvider =
|
MyWalletsProvider myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
final defaultWallet = myWalletProvider.getDefaultWallet();
|
final defaultWallet = myWalletProvider.getDefaultWallet();
|
||||||
|
@ -531,9 +531,10 @@ Widget balance(BuildContext context, String address, double size,
|
||||||
Consumer<SubstrateSdk>(builder: (context, sdk, _) {
|
Consumer<SubstrateSdk>(builder: (context, sdk, _) {
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: sdk.getBalance(address),
|
future: sdk.getBalance(address),
|
||||||
builder: (BuildContext context, AsyncSnapshot<double> balance) {
|
builder: (BuildContext context,
|
||||||
if (balance.connectionState != ConnectionState.done ||
|
AsyncSnapshot<Map<String, double>> globalBalance) {
|
||||||
balance.hasError) {
|
if (globalBalance.connectionState != ConnectionState.done ||
|
||||||
|
globalBalance.hasError) {
|
||||||
if (balanceCache[address] != null &&
|
if (balanceCache[address] != null &&
|
||||||
balanceCache[address] != -1) {
|
balanceCache[address] != -1) {
|
||||||
return Text(
|
return Text(
|
||||||
|
@ -551,7 +552,7 @@ Widget balance(BuildContext context, String address, double size,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
balanceCache[address] = balance.data!;
|
balanceCache[address] = globalBalance.data!['transferableBalance']!;
|
||||||
if (balanceCache[address] != -1) {
|
if (balanceCache[address] != -1) {
|
||||||
return Text(
|
return Text(
|
||||||
"${balanceCache[address]!.toString()} $currencyName",
|
"${balanceCache[address]!.toString()} $currencyName",
|
||||||
|
|
|
@ -457,12 +457,15 @@ class WalletOptions extends StatelessWidget {
|
||||||
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);
|
||||||
MyWalletsProvider myWalletProvider =
|
MyWalletsProvider myWalletProvider =
|
||||||
Provider.of<MyWalletsProvider>(context, listen: false);
|
Provider.of<MyWalletsProvider>(context, listen: false);
|
||||||
|
WalletOptionsProvider walletOptions =
|
||||||
|
Provider.of<WalletOptionsProvider>(context, listen: false);
|
||||||
|
|
||||||
// WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!;
|
// WalletData defaultWallet = _myWalletProvider.getDefaultWallet()!;
|
||||||
// defaultWallet = wallet;
|
// defaultWallet = wallet;
|
||||||
await sub.setCurrentWallet(wallet);
|
await sub.setCurrentWallet(wallet);
|
||||||
myWalletProvider.readAllWallets(currentChest);
|
myWalletProvider.readAllWallets(currentChest);
|
||||||
myWalletProvider.rebuildWidget();
|
myWalletProvider.rebuildWidget();
|
||||||
|
walletOptions.reloadBuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget deleteWallet(BuildContext context,
|
Widget deleteWallet(BuildContext context,
|
||||||
|
|
|
@ -77,16 +77,14 @@ class SettingsScreen extends StatelessWidget {
|
||||||
sub.getConnectedEndpoint() ?? duniterBootstrapNodes.first.endpoint;
|
sub.getConnectedEndpoint() ?? duniterBootstrapNodes.first.endpoint;
|
||||||
|
|
||||||
final customEndpoint = NetworkParams();
|
final customEndpoint = NetworkParams();
|
||||||
customEndpoint.name = currencyName;
|
|
||||||
customEndpoint.endpoint = 'Personnalisé';
|
customEndpoint.endpoint = 'Personnalisé';
|
||||||
customEndpoint.ss58 = ss58;
|
final localEndpoint = NetworkParams();
|
||||||
|
localEndpoint.endpoint = 'ws://127.0.0.1:9944';
|
||||||
final automaticEndpoint = NetworkParams();
|
final automaticEndpoint = NetworkParams();
|
||||||
automaticEndpoint.name = currencyName;
|
|
||||||
automaticEndpoint.endpoint = 'Auto';
|
automaticEndpoint.endpoint = 'Auto';
|
||||||
automaticEndpoint.ss58 = ss58;
|
|
||||||
// duniterBootstrapNodes.add(_sub.getDuniterCustomEndpoint());
|
// duniterBootstrapNodes.add(_sub.getDuniterCustomEndpoint());
|
||||||
duniterBootstrapNodes.insert(0, automaticEndpoint);
|
duniterBootstrapNodes.insert(0, automaticEndpoint);
|
||||||
|
duniterBootstrapNodes.add(localEndpoint);
|
||||||
duniterBootstrapNodes.add(customEndpoint);
|
duniterBootstrapNodes.add(customEndpoint);
|
||||||
|
|
||||||
if (configBox.get('autoEndpoint') == true) {
|
if (configBox.get('autoEndpoint') == true) {
|
||||||
|
|
|
@ -129,6 +129,9 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
|
builder: (context, AsyncSnapshot<Map<String, int>> snapshot) {
|
||||||
if (snapshot.data == null) return const SizedBox();
|
if (snapshot.data == null) return const SizedBox();
|
||||||
String duration = '';
|
String duration = '';
|
||||||
|
log.d('certDelay ${snapshot.data!['certDelay']}');
|
||||||
|
log.d('certRenewable ${snapshot.data!['certRenewable']}');
|
||||||
|
|
||||||
if (snapshot.data!['certDelay'] != null ||
|
if (snapshot.data!['certDelay'] != null ||
|
||||||
snapshot.data!['certRenewable'] != null) {
|
snapshot.data!['certRenewable'] != null) {
|
||||||
final Duration durationSeconds = Duration(
|
final Duration durationSeconds = Duration(
|
||||||
|
@ -515,10 +518,11 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
future:
|
future:
|
||||||
sub.getBalance(defaultWallet.address!),
|
sub.getBalance(defaultWallet.address!),
|
||||||
builder: (BuildContext context,
|
builder: (BuildContext context,
|
||||||
AsyncSnapshot<double> balance) {
|
AsyncSnapshot<Map<String, double>>
|
||||||
if (balance.connectionState !=
|
globalBalance) {
|
||||||
|
if (globalBalance.connectionState !=
|
||||||
ConnectionState.done ||
|
ConnectionState.done ||
|
||||||
balance.hasError) {
|
globalBalance.hasError) {
|
||||||
if (balanceCache[
|
if (balanceCache[
|
||||||
defaultWallet.address!] !=
|
defaultWallet.address!] !=
|
||||||
null) {
|
null) {
|
||||||
|
@ -539,7 +543,8 @@ class WalletViewScreen extends StatelessWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
balanceCache[defaultWallet.address!] =
|
balanceCache[defaultWallet.address!] =
|
||||||
balance.data!;
|
globalBalance
|
||||||
|
.data!['transferableBalance']!;
|
||||||
return Text(
|
return Text(
|
||||||
"${balanceCache[defaultWallet.address!]} $currencyName",
|
"${balanceCache[defaultWallet.address!]} $currencyName",
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
|
|
|
@ -5,7 +5,7 @@ description: Pay with G1.
|
||||||
# pub.dev using `pub publish`. This is preferred for private packages.
|
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
version: 0.0.9+16
|
version: 0.0.9+18
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.12.0 <3.0.0'
|
sdk: '>=2.12.0 <3.0.0'
|
||||||
|
@ -60,7 +60,7 @@ dependencies:
|
||||||
desktop_window: ^0.4.0
|
desktop_window: ^0.4.0
|
||||||
durt: ^0.1.6
|
durt: ^0.1.6
|
||||||
package_info_plus: ^1.4.2
|
package_info_plus: ^1.4.2
|
||||||
polkawallet_sdk: #^0.4.8
|
polkawallet_sdk: #^0.4.9
|
||||||
git:
|
git:
|
||||||
url: https://github.com/poka-IT/sdk.git
|
url: https://github.com/poka-IT/sdk.git
|
||||||
ref: gecko-old
|
ref: gecko-old
|
||||||
|
|
Loading…
Reference in New Issue