From 615cbaac232fd7c7d7e34bd2c6b9adff39448bcc Mon Sep 17 00:00:00 2001 From: Luca Spinazzola Date: Sat, 18 Feb 2023 17:03:05 -0500 Subject: [PATCH] decrypt errors for execute and simulate --- .../io/eqoty/secretk/client/RestClient.kt | 36 +++++++++------- .../secretk/client/SigningCosmWasmClient.kt | 43 +++++++------------ 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/RestClient.kt b/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/RestClient.kt index 5bcba65..6e69fc9 100644 --- a/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/RestClient.kt +++ b/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/RestClient.kt @@ -174,26 +174,30 @@ internal class RestClient( throw Error(responseData.message) } } - } catch (err: Throwable) { - val message = err.message ?: throw err - val errorMessageRgx = Regex("""encrypted: (.+?): (?:instantiate|execute|query|reply to) contract failed""") - val matches = errorMessageRgx.findAll(message).toList() - if (matches.isEmpty() || matches.first().groupValues.size < 2) { - throw err - } - val decodedError: Error = try { - val errorCipherB64 = matches.first().groupValues[1] - val errorCipherBz = errorCipherB64.decodeBase64()!!.toUByteArray() - val errorPlainBz = enigmautils.decrypt(errorCipherBz, nonce).decodeToString() - Error(errorPlainBz) - } catch (decryptionError: Throwable) { - Error("Failed to decrypt the following error message: ${err.message}. Due to decryptionError: $decryptionError") - } - throw decodedError + } catch (t: Throwable) { + throw decrypt(t, nonce) } return response } + suspend fun decrypt(t: Throwable, nonce: UByteArray): Throwable { + val message = t.message ?: return t + val errorMessageRgx = Regex("""encrypted: (.+?): (?:instantiate|execute|query|reply to) contract failed""") + val matches = errorMessageRgx.findAll(message).toList() + if (matches.isEmpty() || matches.first().groupValues.size < 2) { + return t + } + val decodedError: Error = try { + val errorCipherB64 = matches.first().groupValues[1] + val errorCipherBz = errorCipherB64.decodeBase64()!!.toUByteArray() + val errorPlainBz = enigmautils.decrypt(errorCipherBz, nonce).decodeToString() + Error(errorPlainBz) + } catch (decryptionError: Throwable) { + Error("Failed to decrypt the following error message: ${t.message}. Due to decryptionError: $decryptionError") + } + return decodedError + } + suspend fun decryptDataField(msg: MsgProto, nonce: UByteArray?): UByteArray { val dataField = when (msg) { is MsgExecuteContractResponseProto -> { diff --git a/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/SigningCosmWasmClient.kt b/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/SigningCosmWasmClient.kt index 36775ce..b910d1c 100644 --- a/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/SigningCosmWasmClient.kt +++ b/secretk/src/commonMain/kotlin/io/eqoty/secretk/client/SigningCosmWasmClient.kt @@ -95,7 +95,13 @@ private constructor( val simulateTxResponse = try { postSimulateTx(txRawBytes) } catch (t: Throwable) { - throw t + val nonces = msgs.map { msg -> + msg.populateCodeHash() + msg.toProto(this.restClient.enigmautils).value + }.map { anyProto -> + extractMessageNonceIfNeeded(anyProto) + } + throw restClient.decrypt(t, nonces[0]!!) } return simulateTxResponse.gasInfo!! } @@ -108,33 +114,16 @@ private constructor( val txRawBytes = ProtoBuf.encodeToByteArray(txRawProto).toUByteArray() val txResponse = try { postTx(txRawBytes) - } catch (err: Throwable) { -// try { -// const errorMessageRgx = /failed to execute message; message index: 0: encrypted: (.+?): (?:instantiate|execute|query) contract failed/g; -// // console.log(`Got error message: ${err.message}`); -// -// const rgxMatches = errorMessageRgx.exec(err.message); -// if (rgxMatches == null || rgxMatches.length != 2) { -// throw err; -// } -// -// const errorCipherB64 = rgxMatches[1]; -// -// // console.log(`Got error message: ${errorCipherB64}`); -// -// const errorCipherBz = Encoding.fromBase64(errorCipherB64); -// -// const errorPlainBz = await this.restClient.enigmautils.decrypt(errorCipherBz, encryptionNonce); -// -// err.message = err.message.replace(errorCipherB64, Encoding.fromUtf8(errorPlainBz)); -// } catch (decryptionError) { -// throw new Error( -// `Failed to decrypt the following error message: ${err.message}. Decryption error of the error message: ${decryptionError.message}`, -// ); -// } - - throw err + } catch (t: Throwable) { + val nonces = msgs.map { msg -> + msg.populateCodeHash() + msg.toProto(this.restClient.enigmautils).value + }.map { anyProto -> + extractMessageNonceIfNeeded(anyProto) + } + throw restClient.decrypt(t, nonces[0]!!) } + txResponse.data = if (this.restClient.broadcastMode == BroadcastMode.Block) { // inject tx here to standardize decoding tx responses. Since txsQuery responses (not implemented yet) // will actually have a tx value populated.