Skip to content
Snippets Groups Projects
Commit cd91ea83 authored by poka's avatar poka
Browse files

refactor substrate_sdk.dart provider file; Add local node entry in settings

parent c487749f
Branches
Tags
1 merge request!26Features gdev2
Pipeline #16713 waiting for manual action
...@@ -33,170 +33,66 @@ class SubstrateSdk with ChangeNotifier { ...@@ -33,170 +33,66 @@ class SubstrateSdk with ChangeNotifier {
TextEditingController jsonKeystore = TextEditingController(); TextEditingController jsonKeystore = TextEditingController();
TextEditingController keystorePassword = TextEditingController(); TextEditingController keystorePassword = TextEditingController();
Future getStorage(String call) async { /////////////////////////////////////
return await sdk.webView!.evalJavascript('api.query.$call'); ////////// 1: API METHODS ///////////
} /////////////////////////////////////
Future<void> initApi() async {
sdkLoading = true;
await keyring.init([ss58]);
keyring.setSS58(ss58);
await sdk.init(keyring);
sdkReady = true;
sdkLoading = false;
notifyListeners();
}
Future<void> connectNode(BuildContext ctx) async {
HomeProvider homeProvider = Provider.of<HomeProvider>(ctx, listen: false);
homeProvider.changeMessage("connectionPending".tr(), 0);
// configBox.delete('customEndpoint');
final List<NetworkParams> listEndpoints =
configBox.containsKey('customEndpoint')
? [getDuniterCustomEndpoint()]
: getDuniterBootstrap();
int timeout = 10000;
if (sdk.api.connectedNode?.endpoint != null) {
await sdk.api.setting.unsubscribeBestNumber();
}
isLoadingEndpoint = true; Future<String> executeCall(
notifyListeners(); TxInfoData txInfo, txOptions, String password) async {
final res = await sdk.api.connectNode(keyring, listEndpoints).timeout( try {
Duration(milliseconds: timeout), final hash = await sdk.api.tx
onTimeout: () => null, .signAndSend(
txInfo,
txOptions,
password,
)
.timeout(
const Duration(seconds: 12),
onTimeout: () => {},
); );
isLoadingEndpoint = false; log.d(hash);
notifyListeners(); if (hash.isEmpty) {
if (res != null) { transactionStatus = 'timeout';
nodeConnected = true;
// await getSs58Prefix();
// Subscribe bloc number
sdk.api.setting.subscribeBestNumber((res) {
blocNumber = int.parse(res.toString());
// log.d(sdk.api.connectedNode?.endpoint);
if (sdk.api.connectedNode?.endpoint == null) {
nodeConnected = false;
homeProvider.changeMessage("networkLost".tr(), 0);
} else {
nodeConnected = true;
}
notifyListeners(); notifyListeners();
});
// currencyName = await getCurencyName(); return 'timeout';
notifyListeners();
homeProvider.changeMessage(
"wellConnectedToNode"
.tr(args: [getConnectedEndpoint()!.split('/')[2]]),
5);
// snackNode(ctx, true);
} else { } else {
nodeConnected = false; transactionStatus = hash.toString();
debugConnection = res.toString();
notifyListeners(); notifyListeners();
homeProvider.changeMessage("noDuniterEndointAvailable".tr(), 0); return hash.toString();
// snackNode(ctx, false);
}
log.d(sdk.api.connectedNode?.endpoint);
}
List<NetworkParams> getDuniterBootstrap() {
List<NetworkParams> node = [];
for (String endpoint in configBox.get('endpoint')) {
final n = NetworkParams();
n.name = currencyName;
n.endpoint = endpoint;
n.ss58 = ss58;
node.add(n);
} }
return node; } catch (e) {
transactionStatus = e.toString();
notifyListeners();
return e.toString();
} }
NetworkParams getDuniterCustomEndpoint() {
final nodeParams = NetworkParams();
nodeParams.name = currencyName;
nodeParams.endpoint = configBox.get('customEndpoint');
nodeParams.ss58 = ss58;
return nodeParams;
} }
Future<String> importAccount( Future getStorage(String call) async {
{String mnemonic = '', return await sdk.webView!.evalJavascript('api.query.$call');
bool fromMnemonic = false,
String derivePath = '',
String password = ''}) async {
// toy exercise immense month enter answer table prefer speed cycle gold phone
final clipboardData = await Clipboard.getData(Clipboard.kTextPlain);
if (mnemonic != '') {
fromMnemonic = true;
generatedMnemonic = mnemonic;
} else if (clipboardData!.text!.split(' ').length == 12) {
fromMnemonic = true;
generatedMnemonic = clipboardData.text!;
} }
if (password == '') { List batchCall(TxSenderData sender, List calls) {
password = keystorePassword.text; TxInfoData txInfo = TxInfoData(
} 'utility',
'batchAll',
sender,
);
List txOptions = calls;
final KeyType keytype; return [txInfo, txOptions];
final String keyToImport;
if (fromMnemonic) {
keytype = KeyType.mnemonic;
keyToImport = generatedMnemonic;
} else {
keytype = KeyType.keystore;
keyToImport = jsonKeystore.text.replaceAll("'", "\\'");
} }
importIsLoading = true; TxSenderData _setSender() {
notifyListeners(); return TxSenderData(
if (clipboardData?.text != null) jsonKeystore.text = clipboardData!.text!; keyring.current.address,
var json = await sdk.api.keyring keyring.current.pubKey,
.importAccount(keyring,
keyType: keytype,
key: keyToImport,
name: derivePath,
password: password,
derivePath: derivePath,
cryptoType: CryptoType.sr25519)
.catchError((e) {
importIsLoading = false;
notifyListeners();
});
if (json == null) return '';
// log.d(json);
try {
await sdk.api.keyring.addAccount(
keyring,
keyType: keytype,
acc: json,
password: password,
); );
} catch (e) {
log.e(e);
importIsLoading = false;
notifyListeners();
}
importIsLoading = false;
notifyListeners();
return keyring.allAccounts.last.address!;
} }
void reload() { ////////////////////////////////////////////
notifyListeners(); ////////// 2: GET ONCHAIN STORAGE //////////
} ////////////////////////////////////////////
Future<List<AddressInfo>> getKeyStoreAddress() async { Future<List<AddressInfo>> getKeyStoreAddress() async {
List<AddressInfo> result = []; List<AddressInfo> result = [];
...@@ -322,54 +218,296 @@ class SubstrateSdk with ChangeNotifier { ...@@ -322,54 +218,296 @@ class SubstrateSdk with ChangeNotifier {
return totalAmount; return totalAmount;
} }
Future<double> subscribeBalance(String address, {bool isUd = false}) async { Future<int> getSs58Prefix() async {
double balance = 0.0; final List res = await sdk.webView!.evalJavascript(
if (nodeConnected) { 'api.consts.system.ss58Prefix.words',
await sdk.api.account.subscribeBalance(address, (balanceData) { wrapPromise: false) ??
balance = int.parse(balanceData.freeBalance) / 100; [42];
notifyListeners();
}); ss58 = res[0];
log.d(ss58);
return ss58;
} }
return balance; Future<bool> isMemberGet(String address) async {
return await idtyStatus(address) == 'Validated';
} }
KeyPairData getKeypair(String address) { Future<String> getMemberAddress() async {
return keyring.keyPairs.firstWhere((kp) => kp.address == address, // TODOO: Continue digging memberAddress detection
orElse: (() => KeyPairData())); 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<bool> checkPassword(String address, String pass) async { Future<Map<String, int>> certState(String from, String to) async {
final account = getKeypair(address); 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
return await sdk.api.keyring.checkPassword(account, pass); 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<String> getSeed(String address, String pin) async { Future<Map> getCertMeta(String address) async {
final account = getKeypair(address); var idtyIndex = await getIdentityIndexOf(address);
keyring.setCurrent(account);
final seed = await sdk.api.keyring.getDecryptedSeed(keyring, pin); final certMeta =
await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
String seedText; return certMeta;
if (seed == null) {
seedText = '';
} else {
seedText = seed.seed!.split('//')[0];
} }
log.d(seedText); Future<String> idtyStatus(String address, [bool smooth = true]) async {
return seedText; var idtyIndex = await getIdentityIndexOf(address);
}
int getDerivationNumber(String address) { if (idtyIndex == 0) {
final account = getKeypair(address); return 'noid';
final deriveNbr = account.name!.split('//')[1];
return int.parse(deriveNbr);
} }
Future<KeyPairData?> changePassword(BuildContext context, String address, final idtyStatus = await getStorage('identity.identities($idtyIndex)');
String passOld, String? passNew) async {
if (idtyStatus != null) {
final String status = idtyStatus['status'];
return (status);
} else {
return 'expired';
}
}
Future getCurencyName() async {}
/////////////////////////////////////
////// 3: SUBSTRATE CONNECTION //////
/////////////////////////////////////
Future<void> initApi() async {
sdkLoading = true;
await keyring.init([ss58]);
keyring.setSS58(ss58);
await sdk.init(keyring);
sdkReady = true;
sdkLoading = false;
notifyListeners();
}
String? getConnectedEndpoint() {
return sdk.api.connectedNode?.endpoint;
}
Future<void> connectNode(BuildContext ctx) async {
HomeProvider homeProvider = Provider.of<HomeProvider>(ctx, listen: false);
homeProvider.changeMessage("connectionPending".tr(), 0);
// configBox.delete('customEndpoint');
final List<NetworkParams> listEndpoints =
configBox.containsKey('customEndpoint')
? [getDuniterCustomEndpoint()]
: getDuniterBootstrap();
int timeout = 10000;
if (sdk.api.connectedNode?.endpoint != null) {
await sdk.api.setting.unsubscribeBestNumber();
}
isLoadingEndpoint = true;
notifyListeners();
final res = await sdk.api.connectNode(keyring, listEndpoints).timeout(
Duration(milliseconds: timeout),
onTimeout: () => null,
);
isLoadingEndpoint = false;
notifyListeners();
if (res != null) {
nodeConnected = true;
// await getSs58Prefix();
// Subscribe bloc number
sdk.api.setting.subscribeBestNumber((res) {
blocNumber = int.parse(res.toString());
// log.d(sdk.api.connectedNode?.endpoint);
if (sdk.api.connectedNode?.endpoint == null) {
nodeConnected = false;
homeProvider.changeMessage("networkLost".tr(), 0);
} else {
nodeConnected = true;
}
notifyListeners();
});
// currencyName = await getCurencyName();
notifyListeners();
homeProvider.changeMessage(
"wellConnectedToNode"
.tr(args: [getConnectedEndpoint()!.split('/')[2]]),
5);
// snackNode(ctx, true);
} else {
nodeConnected = false;
debugConnection = res.toString();
notifyListeners();
homeProvider.changeMessage("noDuniterEndointAvailable".tr(), 0);
// snackNode(ctx, false);
}
log.d(sdk.api.connectedNode?.endpoint);
}
List<NetworkParams> getDuniterBootstrap() {
List<NetworkParams> node = [];
for (String endpoint in configBox.get('endpoint')) {
final n = NetworkParams();
n.name = currencyName;
n.endpoint = endpoint;
n.ss58 = ss58;
node.add(n);
}
return node;
}
NetworkParams getDuniterCustomEndpoint() {
final nodeParams = NetworkParams();
nodeParams.name = currencyName;
nodeParams.endpoint = configBox.get('customEndpoint');
nodeParams.ss58 = ss58;
return nodeParams;
}
Future<String> importAccount(
{String mnemonic = '',
bool fromMnemonic = false,
String derivePath = '',
String password = ''}) async {
// toy exercise immense month enter answer table prefer speed cycle gold phone
final clipboardData = await Clipboard.getData(Clipboard.kTextPlain);
if (mnemonic != '') {
fromMnemonic = true;
generatedMnemonic = mnemonic;
} else if (clipboardData!.text!.split(' ').length == 12) {
fromMnemonic = true;
generatedMnemonic = clipboardData.text!;
}
if (password == '') {
password = keystorePassword.text;
}
final KeyType keytype;
final String keyToImport;
if (fromMnemonic) {
keytype = KeyType.mnemonic;
keyToImport = generatedMnemonic;
} else {
keytype = KeyType.keystore;
keyToImport = jsonKeystore.text.replaceAll("'", "\\'");
}
importIsLoading = true;
notifyListeners();
if (clipboardData?.text != null) jsonKeystore.text = clipboardData!.text!;
var json = await sdk.api.keyring
.importAccount(keyring,
keyType: keytype,
key: keyToImport,
name: derivePath,
password: password,
derivePath: derivePath,
cryptoType: CryptoType.sr25519)
.catchError((e) {
importIsLoading = false;
notifyListeners();
});
if (json == null) return '';
// log.d(json);
try {
await sdk.api.keyring.addAccount(
keyring,
keyType: keytype,
acc: json,
password: password,
);
} catch (e) {
log.e(e);
importIsLoading = false;
notifyListeners();
}
importIsLoading = false;
notifyListeners();
return keyring.allAccounts.last.address!;
}
//////////////////////////////////
/////// 4: CRYPTOGRAPHY //////////
//////////////////////////////////
KeyPairData getKeypair(String address) {
return keyring.keyPairs.firstWhere((kp) => kp.address == address,
orElse: (() => KeyPairData()));
}
Future<bool> checkPassword(String address, String pass) async {
final account = getKeypair(address);
return await sdk.api.keyring.checkPassword(account, pass);
}
Future<String> getSeed(String address, String pin) async {
final account = getKeypair(address);
keyring.setCurrent(account);
final seed = await sdk.api.keyring.getDecryptedSeed(keyring, pin);
String seedText;
if (seed == null) {
seedText = '';
} else {
seedText = seed.seed!.split('//')[0];
}
log.d(seedText);
return seedText;
}
int getDerivationNumber(String address) {
final account = getKeypair(address);
final deriveNbr = account.name!.split('//')[1];
return int.parse(deriveNbr);
}
Future<KeyPairData?> changePassword(BuildContext context, String address,
String passOld, String? passNew) async {
final account = getKeypair(address); final account = getKeypair(address);
MyWalletsProvider myWalletProvider = MyWalletsProvider myWalletProvider =
Provider.of<MyWalletsProvider>(context, listen: false); Provider.of<MyWalletsProvider>(context, listen: false);
...@@ -423,91 +561,93 @@ class SubstrateSdk with ChangeNotifier { ...@@ -423,91 +561,93 @@ class SubstrateSdk with ChangeNotifier {
} }
} }
Future<String> derive(
BuildContext context, String address, int number, String password) async {
final keypair = getKeypair(address);
final seedMap =
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
if (seedMap?['type'] != 'mnemonic') return '';
final List seedList = seedMap!['seed'].split('//');
generatedMnemonic = seedList[0];
return await importAccount(
mnemonic: generatedMnemonic,
fromMnemonic: true,
derivePath: '//$number',
password: password);
}
Future<String> generateRootKeypair(String address, String password) async {
final keypair = getKeypair(address);
final seedMap =
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
if (seedMap?['type'] != 'mnemonic') return '';
final List seedList = seedMap!['seed'].split('//');
generatedMnemonic = seedList[0];
return await importAccount(fromMnemonic: true, password: password);
}
Future<bool> isMnemonicValid(String mnemonic) async {
// Needed for bad encoding of UTF-8
mnemonic = mnemonic.replaceAll('é', 'é');
mnemonic = mnemonic.replaceAll('è', 'è');
return await sdk.api.keyring.checkMnemonicValid(mnemonic);
}
//////////////////////////////////////
///////// 5: CALLS EXECUTION /////////
//////////////////////////////////////
Future<String> pay( Future<String> pay(
{required String fromAddress, {required String fromAddress,
required String destAddress, required String destAddress,
required double amount, required double amount,
required String password}) async { required String password}) async {
transactionStatus = ''; transactionStatus = '';
log.d(keyring.current.address);
log.d(fromAddress);
log.d(password);
final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]);
log.d(fromPubkey!.keys.first); final int amountUnit = (amount * 100).toInt();
final sender = TxSenderData( final sender = TxSenderData(
fromAddress, fromAddress,
fromPubkey.keys.first, fromPubkey!.keys.first,
); );
final txInfo = TxInfoData( final txInfo = TxInfoData(
'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender); 'balances', amount == -1 ? 'transferAll' : 'transferKeepAlive', sender);
final txOptions = [destAddress, amount == -1 ? false : amountUnit];
final int amountUnit = (amount * 100).toInt(); return await executeCall(txInfo, txOptions, password);
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( Future<String> certify(
String fromAddress, String password, String toAddress) async { String fromAddress, String password, String toAddress) async {
transactionStatus = ''; transactionStatus = '';
log.d('me: $fromAddress');
log.d('to: $toAddress');
final myIdtyStatus = await idtyStatus(fromAddress); final myIdtyStatus = await idtyStatus(fromAddress);
final toIdtyStatus = await idtyStatus(toAddress); final toIdtyStatus = await idtyStatus(toAddress);
final fromIndex = await getIdentityIndexOf(fromAddress); final fromIndex = await getIdentityIndexOf(fromAddress);
final toIndex = await getIdentityIndexOf(toAddress); final toIndex = await getIdentityIndexOf(toAddress);
log.d(myIdtyStatus);
log.d(toIdtyStatus);
if (myIdtyStatus != 'Validated') { if (myIdtyStatus != 'Validated') {
transactionStatus = 'notMember'; transactionStatus = 'notMember';
notifyListeners(); notifyListeners();
return 'notMember'; return 'notMember';
} }
final toCerts = await getCerts(toAddress); final sender = _setSender();
final currencyParameters = await getParameters();
final sender = TxSenderData(
keyring.current.address,
keyring.current.pubKey,
);
TxInfoData txInfo; TxInfoData txInfo;
List txOptions = []; List txOptions = [];
final toCerts = await getCerts(toAddress);
final currencyParameters = await getParameters();
if (toIdtyStatus == 'noid') { if (toIdtyStatus == 'noid') {
txInfo = TxInfoData( txInfo = TxInfoData(
'identity', 'identity',
...@@ -520,15 +660,12 @@ class SubstrateSdk with ChangeNotifier { ...@@ -520,15 +660,12 @@ class SubstrateSdk with ChangeNotifier {
if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] && if (toCerts[0] >= currencyParameters['wotMinCertForMembership'] &&
toIdtyStatus != 'Validated') { toIdtyStatus != 'Validated') {
log.i('Batch cert and membership validation'); log.i('Batch cert and membership validation');
txInfo = TxInfoData( List batch = batchCall(sender, [
'utility',
'batchAll',
sender,
);
txOptions = [
'cert.addCert($fromIndex, $toIndex)', 'cert.addCert($fromIndex, $toIndex)',
'identity.validateIdentity($toIndex)' 'identity.validateIdentity($toIndex)'
]; ]);
txInfo = batch[0];
txOptions = batch[1];
} else { } else {
txInfo = TxInfoData( txInfo = TxInfoData(
'cert', 'cert',
...@@ -544,52 +681,22 @@ class SubstrateSdk with ChangeNotifier { ...@@ -544,52 +681,22 @@ class SubstrateSdk with ChangeNotifier {
} }
log.d('Cert action: ${txInfo.call!}'); log.d('Cert action: ${txInfo.call!}');
return await executeCall(txInfo, txOptions, password);
try {
final hash = await sdk.api.tx
.signAndSend(
txInfo,
txOptions,
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 idtyIndex = await getIdentityIndexOf(address);
if (idtyIndex == 0) {
return 'noid';
} }
final idtyStatus = await getStorage('identity.identities($idtyIndex)'); Future claimUDs(String password) async {
final sender = TxSenderData(
keyring.current.address,
keyring.current.pubKey,
);
if (idtyStatus != null) { final txInfo = TxInfoData(
final String status = idtyStatus['status']; 'universalDividend',
'claimUds',
sender,
);
return (status); return await executeCall(txInfo, [], password);
} else {
return 'expired';
}
} }
Future<String> confirmIdentity( Future<String> confirmIdentity(
...@@ -606,92 +713,9 @@ class SubstrateSdk with ChangeNotifier { ...@@ -606,92 +713,9 @@ class SubstrateSdk with ChangeNotifier {
'confirmIdentity', 'confirmIdentity',
sender, sender,
); );
final txOptions = [name];
try { return await executeCall(txInfo, txOptions, password);
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 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);
}
}
return result;
}
Future<Map> getCertMeta(String address) async {
var idtyIndex = await getIdentityIndexOf(address);
final certMeta =
await getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
return certMeta;
} }
Future revokeIdentity(String address, String password) async { Future revokeIdentity(String address, String password) async {
...@@ -711,91 +735,19 @@ class SubstrateSdk with ChangeNotifier { ...@@ -711,91 +735,19 @@ class SubstrateSdk with ChangeNotifier {
sender, sender,
); );
try { final txOptions = [idtyIndex];
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'; return await executeCall(txInfo, txOptions, password);
} else {
transactionStatus = hash.toString();
notifyListeners();
return hash.toString();
}
} catch (e) {
transactionStatus = e.toString();
notifyListeners();
return e.toString();
}
}
Future getCurencyName() async {}
Future<String> derive(
BuildContext context, String address, int number, String password) async {
final keypair = getKeypair(address);
final seedMap =
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
if (seedMap?['type'] != 'mnemonic') return '';
final List seedList = seedMap!['seed'].split('//');
generatedMnemonic = seedList[0];
return await importAccount(
mnemonic: generatedMnemonic,
fromMnemonic: true,
derivePath: '//$number',
password: password);
}
Future<String> generateRootKeypair(String address, String password) async {
final keypair = getKeypair(address);
final seedMap =
await keyring.store.getDecryptedSeed(keypair.pubKey, password);
if (seedMap?['type'] != 'mnemonic') return '';
final List seedList = seedMap!['seed'].split('//');
generatedMnemonic = seedList[0];
return await importAccount(fromMnemonic: true, password: password);
} }
Future<bool> isMnemonicValid(String mnemonic) async { void reload() {
// Needed for bad encoding of UTF-8 notifyListeners();
mnemonic = mnemonic.replaceAll('é', 'é');
mnemonic = mnemonic.replaceAll('è', 'è');
return await sdk.api.keyring.checkMnemonicValid(mnemonic);
} }
String? getConnectedEndpoint() {
return sdk.api.connectedNode?.endpoint;
} }
Future<int> getSs58Prefix() async { ////////////////////////////////////////////
final List res = await sdk.webView!.evalJavascript( /////// 6: UI ELEMENTS (off class) /////////
'api.consts.system.ss58Prefix.words', ////////////////////////////////////////////
wrapPromise: false) ??
[42];
ss58 = res[0];
log.d(ss58);
return ss58;
}
}
void snack(BuildContext context, String message, {int duration = 2}) { void snack(BuildContext context, String message, {int duration = 2}) {
final snackBar = final snackBar =
......
...@@ -78,10 +78,13 @@ class SettingsScreen extends StatelessWidget { ...@@ -78,10 +78,13 @@ class SettingsScreen extends StatelessWidget {
final customEndpoint = NetworkParams(); final customEndpoint = NetworkParams();
customEndpoint.endpoint = 'Personnalisé'; customEndpoint.endpoint = 'Personnalisé';
final localEndpoint = NetworkParams();
localEndpoint.endpoint = 'ws://127.0.0.1:9944';
final automaticEndpoint = NetworkParams(); final automaticEndpoint = NetworkParams();
automaticEndpoint.endpoint = 'Auto'; automaticEndpoint.endpoint = 'Auto';
// 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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment