From 5b9309e9c2867b860feddf113c73c3b3bf2820fd Mon Sep 17 00:00:00 2001 From: piercetrey-figure Date: Tue, 7 Nov 2023 11:14:42 -0700 Subject: [PATCH] flexibility improvements for signing transactions --- build.gradle.kts | 4 ++++ .../kotlin/io/provenance/client/grpc/BaseReq.kt | 14 ++++++++++++-- .../client/coroutines/PbCoroutinesClient.kt | 17 +++++++++-------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 98e51a5..97cd081 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -67,6 +67,10 @@ subprojects { configurations.forEach { it.exclude("org.slf4j", "slf4j-api") } val artifactName = "pb-grpc-$name-kotlin" + tasks.withType { + signing.isRequired = false + } + configure { publications { create("maven") { diff --git a/client-common/src/main/kotlin/io/provenance/client/grpc/BaseReq.kt b/client-common/src/main/kotlin/io/provenance/client/grpc/BaseReq.kt index 05e75d7..3dd50a7 100644 --- a/client-common/src/main/kotlin/io/provenance/client/grpc/BaseReq.kt +++ b/client-common/src/main/kotlin/io/provenance/client/grpc/BaseReq.kt @@ -21,11 +21,16 @@ interface Signer { fun sign(data: ByteArray): ByteArray } +typealias CustomUnpackAccount = (Any.() -> Auth.BaseAccount) +typealias CustomizeSignerInfo = (SignerInfo.() -> SignerInfo) data class BaseReqSigner( val signer: Signer, val sequenceOffset: Int = 0, - val account: Auth.BaseAccount? = null + val account: Auth.BaseAccount? = null, + private val customizeSignerInfo: CustomizeSignerInfo? = null, + val unpackAccount: CustomUnpackAccount? = null, ) { + fun buildSignerInfo(): SignerInfo = SignerInfo.newBuilder() .setPublicKey(Any.pack(this.signer.pubKey(), "")) @@ -34,7 +39,12 @@ data class BaseReqSigner( .setSingle(Single.newBuilder().setModeValue(SignMode.SIGN_MODE_DIRECT_VALUE)) ) .setSequence(this.account!!.sequence + this.sequenceOffset) - .build() + .build().let { + customizeSignerInfo?.invoke(it) ?: it + } + + fun withCustomizeSignerInfo(customizeSignerInfo: CustomizeSignerInfo) = copy(customizeSignerInfo = customizeSignerInfo) + fun withUnpackAccount(unpackAccount: CustomUnpackAccount) = copy(unpackAccount = unpackAccount) } data class BaseReq( diff --git a/client-coroutines/src/main/kotlin/io/provenance/client/coroutines/PbCoroutinesClient.kt b/client-coroutines/src/main/kotlin/io/provenance/client/coroutines/PbCoroutinesClient.kt index b7c3f1e..9b7779b 100644 --- a/client-coroutines/src/main/kotlin/io/provenance/client/coroutines/PbCoroutinesClient.kt +++ b/client-coroutines/src/main/kotlin/io/provenance/client/coroutines/PbCoroutinesClient.kt @@ -1,6 +1,8 @@ package io.provenance.client.coroutines +import com.google.protobuf.Any import com.google.protobuf.ByteString +import cosmos.auth.v1beta1.Auth.BaseAccount import cosmos.auth.v1beta1.QueryGrpcKt import cosmos.auth.v1beta1.QueryOuterClass import cosmos.base.tendermint.v1beta1.getLatestBlockRequest @@ -82,10 +84,8 @@ open class PbCoroutinesClient( feePayer: String? = null, ): BaseReq = signers.map { - BaseReqSigner( - signer = it.signer, - sequenceOffset = it.sequenceOffset, - account = it.account ?: this.authClient.getBaseAccount(it.signer.address()) + it.copy( + account = it.account ?: this.authClient.getBaseAccount(it.signer.address(), unpackAccount = it.unpackAccount) ) }.let { BaseReq( @@ -173,7 +173,7 @@ open class PbCoroutinesClient( .setMode(actualMode) .build() ).let { res -> - if (simulateBlock) { + if (simulateBlock && res.txResponse.code == 0) { val timeoutHeight = providedTimeoutHeight.takeIf { it > 0 } ?: (latestHeight() + 10) // default to 10 block timeout for polling if no height set val txHash = res.txResponse.txhash do { @@ -204,12 +204,13 @@ open class PbCoroutinesClient( * See [Accounts](https://github.com/FigureTechnologies/service-wallet/blob/v45/pb-client/src/main/kotlin/com/figure/wallet/pbclient/client/grpc/Accounts.kt#L18). * * @param bech32Address The bech32 address to fetch. - * @return [cosmos.auth.v1beta1.Auth.BaseAccount] or throw [IllegalArgumentException] if the account type is not supported. + * @return [BaseAccount] or throw [IllegalArgumentException] if the account type is not supported. */ -suspend fun QueryGrpcKt.QueryCoroutineStub.getBaseAccount(bech32Address: String): cosmos.auth.v1beta1.Auth.BaseAccount = +suspend fun QueryGrpcKt.QueryCoroutineStub.getBaseAccount(bech32Address: String, unpackAccount: (Any.() -> BaseAccount)? = null): BaseAccount = account(QueryOuterClass.QueryAccountRequest.newBuilder().setAddress(bech32Address).build()).account.run { when { - this.`is`(cosmos.auth.v1beta1.Auth.BaseAccount::class.java) -> unpack(cosmos.auth.v1beta1.Auth.BaseAccount::class.java) + unpackAccount != null -> unpackAccount() + this.`is`(BaseAccount::class.java) -> unpack(BaseAccount::class.java) else -> throw IllegalArgumentException("Account type not handled:$typeUrl") } }