getMigrateWalletChecks method
Implementation
Future<MigrateWalletChecks> getMigrateWalletChecks({
required String fromAddress,
required String toAddress,
}) async {
final errors = <MigrateWalletValidationError>{};
OwnerKeyBondInfo? ownerKeyBondInfo;
if (fromAddress.isEmpty) {
final toIdtyStatus = await getIdtyStatus(toAddress);
return MigrateWalletChecks(
fromBalance: WalletBalance.empty(),
fromIdtyStatus: IdtyStatus.none,
toIdtyStatus: toIdtyStatus,
errors: {MigrateWalletValidationError.sourceAccountIsEmpty},
);
}
final results = await Future.wait([
getBalance(fromAddress),
getIdtyStatusMulti([fromAddress, toAddress]),
getIdentityIndexOf(fromAddress),
]);
final fromBalance = results[0] as WalletBalance;
final statusList = results[1] as List<IdtyStatus>;
final fromIdtyIndex = results[2] as int?;
final fromIdtyStatus = statusList[0];
final toIdtyStatus = statusList[1];
if (fromIdtyIndex != null) {
// Detect the "owner key changed too recently" cool-down. The identity
// pallet stores `oldOwnerKey = Some((oldKey, blockOfChange))` for the
// duration of `changeOwnerKeyPeriod` after a change_owner_key; any new
// migration during that window is rejected with
// `OwnerKeyAlreadyRecentlyChanged`. (The previous implementation read the
// SMITH `reportLongevity`/`lastOnline`, which is unrelated to identity
// owner-key changes and produced a meaningless bond period.)
final idtyData = await _chain.query.identity.identities(fromIdtyIndex);
final oldOwnerKey = idtyData?.oldOwnerKey;
if (oldOwnerKey != null) {
final currentBlock = await getCurrentBlockHeight();
final int changeBlock = oldOwnerKey.value1;
final int changeOwnerKeyPeriod = currencyConstants.changeOwnerKeyPeriod;
final bondEndBlock = changeBlock + changeOwnerKeyPeriod;
log.d(
'getMigrateWalletChecks - oldOwnerKey present: changeBlock: $changeBlock, '
'changeOwnerKeyPeriod: $changeOwnerKeyPeriod, bondEndBlock: $bondEndBlock, currentBlock: $currentBlock',
);
if (currentBlock < bondEndBlock) {
final now = DateTime.now();
// Guard against stale/rolled-back chain data where currentBlock could
// be < changeBlock, which would otherwise push changeDate into the future.
final elapsedBlocks =
currentBlock > changeBlock ? currentBlock - changeBlock : 0;
final changeDate = now.subtract(
Duration(seconds: elapsedBlocks * _blockTime),
);
final bondEndDate = now.add(
Duration(seconds: (bondEndBlock - currentBlock) * _blockTime),
);
ownerKeyBondInfo = OwnerKeyBondInfo(
changeDate: changeDate,
bondEndDate: bondEndDate,
);
log.d(
'getMigrateWalletChecks - In owner-key cool-down! hasEnded=${ownerKeyBondInfo.hasEnded}, remaining=${ownerKeyBondInfo.remainingTime}',
);
}
}
}
if (fromBalance.transferableBalance == BigInt.zero) {
errors.add(MigrateWalletValidationError.sourceAccountIsEmpty);
}
if (fromIdtyStatus != IdtyStatus.none && toIdtyStatus != IdtyStatus.none) {
errors.add(MigrateWalletValidationError.cannotMigrateIdentityToIdentity);
}
return MigrateWalletChecks(
fromBalance: fromBalance,
fromIdtyStatus: fromIdtyStatus,
toIdtyStatus: toIdtyStatus,
errors: errors,
ownerKeyBondInfo: ownerKeyBondInfo,
);
}