collectHashes method
Implementation
@visibleForTesting
List<String>? collectHashes(String namespace, JsonRpcResponse response) {
if (response.result == null || response.error != null) {
return null;
}
switch (namespace) {
case 'solana':
try {
final result = (response.result as Map<String, dynamic>);
// if contain signature it's either solana_signTransaction or solana_signTransaction
final signature = ReownCoreUtils.recursiveSearchForMapKey(
result,
'signature',
);
if (signature != null) {
return <String>[...signature];
}
// if contain transactions it's solana_signAllTransactions
final transactions = ReownCoreUtils.recursiveSearchForMapKey(
result,
'transactions',
);
if (transactions != null) {
// Decode transactions and extract signature to send as TVF data
final signatures = (transactions as List).map((encodedTx) {
return SolanaChainUtils.extractSolanaSignature(encodedTx);
}).toList();
return signatures;
}
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: solana, $e');
}
return null;
case 'xrpl':
try {
final result = (response.result as Map<String, dynamic>);
final txHash = ReownCoreUtils.recursiveSearchForMapKey(
result,
'hash',
);
if (txHash != null) {
return <String>[txHash];
}
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: xrpl, $e');
}
return null;
case 'algo':
try {
final result = (response.result as List);
final txHashesList = AlgorandChainUtils.calculateTxIDs(result);
return <String>[...txHashesList];
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: algo, $e');
}
return null;
case 'sui':
try {
final result = (response.result as Map<String, dynamic>);
// if sui_signAndExecuteTransaction then it'll contain digest
final digest = ReownCoreUtils.recursiveSearchForMapKey(
result,
'digest',
);
if (digest != null) {
return <String>[digest];
}
// if sui_signTransaction the it'll contain signature and transactionBytes
final signature = ReownCoreUtils.recursiveSearchForMapKey(
result,
'signature',
);
if (signature != null) {
final transactionBytes = ReownCoreUtils.recursiveSearchForMapKey(
result,
'transactionBytes',
);
if (transactionBytes != null) {
final computedHash = SuiChainUtils.getSuiDigestFromEncodedTx(
transactionBytes,
);
return <String>[computedHash.toString()];
}
}
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: sui, $e');
}
return null;
case 'tron':
try {
final result = (response.result as Map<String, dynamic>);
final txID = ReownCoreUtils.recursiveSearchForMapKey(result, 'txID');
if (txID != null) {
return <String>[txID.toString()];
}
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: tron, $e');
}
return null;
case 'hedera':
try {
final result = (response.result as Map<String, dynamic>);
final transactionId = ReownCoreUtils.recursiveSearchForMapKey(
result,
'transactionId',
);
if (transactionId != null) {
return <String>[transactionId.toString()];
}
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: hedera, $e');
}
return null;
case 'bip122':
try {
final result = (response.result as Map<String, dynamic>);
final txid = ReownCoreUtils.recursiveSearchForMapKey(result, 'txid');
return <String>[txid.toString()];
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: bip122, $e');
}
return null;
case 'stacks':
try {
final result = (response.result as Map<String, dynamic>);
final txid = ReownCoreUtils.recursiveSearchForMapKey(result, 'txid');
return <String>[txid.toString()];
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: stacks, $e');
}
return null;
case 'near':
try {
final result = NearChainUtils.parseResponse(response.result);
final hash = NearChainUtils.computeNearHashFromTxBytes(result);
return <String>[hash];
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: near, $e');
}
return null;
case 'polkadot':
try {
final result = (response.result as Map<String, dynamic>);
final signature = ReownCoreUtils.recursiveSearchForMapKey(
result,
'signature',
);
if (signature != null) {
final id = response.id;
final requestParams = pendingTVFRequests[id]!.requestParams;
final params = requestParams as Map<String, dynamic>;
final payload = ReownCoreUtils.recursiveSearchForMapKey(
params,
'transactionPayload',
);
final ss58Address = ReownCoreUtils.recursiveSearchForMapKey(
params,
'address',
);
final publicKey = PolkadotChainUtils.ss58AddressToPublicKey(
ss58Address,
);
final extrinsic = PolkadotChainUtils.addSignatureToExtrinsic(
publicKey: Uint8List.fromList(publicKey),
hexSignature: signature,
payload: payload,
);
final signedHex = hex.encode(extrinsic);
final hash = PolkadotChainUtils.deriveExtrinsicHash(signedHex);
return <String>[hash];
}
} catch (e) {
core.logger.e('[$runtimeType] _tvf data: polkadot, $e');
}
return null;
case 'cosmos':
try {
// only cosmos_signDirect and cosmos_signAmino has a result of type Map
// cosmos_getAccounts would respond with a List but we don't want to parse this method
// wrapping it with a try/catch as for other methods is enough
final result = (response.result as Map<String, dynamic>);
final signature = ReownCoreUtils.recursiveSearchForMapKey(
result,
'signature',
);
if (signature != null) {
final bodyBytes = ReownCoreUtils.recursiveSearchForMapKey(
result,
'bodyBytes',
);
final authInfoBytes = ReownCoreUtils.recursiveSearchForMapKey(
result,
'authInfoBytes',
);
final hash = CosmosUtils.computeTxHash(
bodyBytesBase64: bodyBytes,
authInfoBytesBase64: authInfoBytes,
signatureBase64: signature['signature'],
);
return <String>[hash];
}
} catch (e) {
core.logger.e('[$runtimeType] collectHashes: cosmos, $e');
}
return null;
default:
// default to EVM
try {
if (response.result is Map) {
// wallet_sendCalls 2.0.0
final id = ReownCoreUtils.recursiveSearchForMapKey(
response.result,
'id',
);
if (id != null) {
final transactionHashes =
(ReownCoreUtils.recursiveSearchForMapKey(
response.result,
'transactionHashes',
)
as List)
.map((e) => e.toString())
.toList();
return <String>[id.toString(), ...transactionHashes];
}
return null;
}
return <String>[response.result.toString()];
} catch (e) {
core.logger.e('[$runtimeType] _collectHashes: evm, $e');
}
return null;
}
}