cosmjs
cosmjs copied to clipboard
CosmWasmClient: Add an optional msg transformer
Feature Request
Adding an optional MsgTransformer to CosmWasmClient (via its constructor).
MsgTransformer will be an interface that transforms the MsgInstantiateContract and MsgExecuteContract before init, handle and query, and also transforms tx responses and errors.
Suggested interface:
interface MsgTransformer {
transformInitMsg: (MsgInstantiateContract) => MsgInstantiateContract;
transformHandleMsg: (MsgExecuteContract) => MsgExecuteContract;
transformSmartQueryMsg: (object) => object;
transformInitResult: (MsgInstantiateContract, BroadcastTxResult) => BroadcastTxResult;
transformHandleResult: (MsgExecuteContract, BroadcastTxResult) => BroadcastTxResult;
transformSmartQueryResult: (object, JsonObject) => JsonObject;
}
(Not sure if the Result transformers also cover errors)
The default implementation would just look like:
const defaultMsgTransformer: MsgTransformer = {
transformInitMsg: (x: MsgInstantiateContract) => x,
transformHandleMsg: (x: MsgExecuteContract) => x,
transformSmartQueryMsg: (x: object) => x,
transformInitResult: (x: MsgInstantiateContract, y: BroadcastTxResult) => y,
transformHandleResult: (x: MsgExecuteContract, y: BroadcastTxResult) => y,
transformSmartQueryResult: (x: object, y: JsonObject) => y,
};
The Use Case
Currently at Secret Network we are maintaining an old fork of cosmwasmjs with just our encryption code before sending and after receiving a tx response. cosmjs is miles ahead of our fork, and we don't really see the point of maintaining a fork to just basically have this line modified: https://github.com/enigmampc/SecretNetwork/blob/8e8628e648bd897a0fe1a225ab58f8294464950d/cosmwasm-js/packages/sdk/src/signingcosmwasmclient.ts#L203
Also, in the above link you can see that we modified the x/wasmd message to have additional fields: callback_code_hash and callback_sig, and also removed everything admin / migrate / history related. I'm thinking other chains that are going to adopt CosmWasm in the future might also want to modify some of these parts for their use case.
What I have in mind is passing executeMsg to the transformer before this line: https://github.com/cosmos/cosmjs/blob/4fdab7f65d9f2fa3627ce63d569aae3d6cfe6402/packages/cosmwasm/src/signingcosmwasmclient.ts#L330
And then before returning, passing result with its executeMsg again to the transformer.
Let me know what you think. I'm happy to create a PR for this if you think this feature is something that will benefit cosmjs and other chains in the ecosystem. :blush:
@assafmo Thanks for the interesting feature request. I just want to confirm first of all that it doesn't make sense in your situation to perform the transform in the signer rather than in the signing client itself? We already allow for the possibility that the signer wants to modify the sign doc (eg change the fees or whatever) and return something different to the signing client. See eg https://github.com/cosmos/cosmjs/blob/4fdab7f65d9f2fa3627ce63d569aae3d6cfe6402/packages/proto-signing/src/signer.ts#L5-L20
Does the signer allows modifying the result/error as well?
@assafmo Not the OfflineSigners (Direct or Amino) which we have so far, because they don't know anything about broadcasting. There's been some discussion about whether to provide an OnlineSigner (see https://github.com/cosmos/cosmjs/issues/316).
@assafmo This seems like a lot of overhead to maintain for a very uncommon use case. Ethan came up with the idea of having a wrapper class like SecretCosmWasmClient around CosmWasmClient, which does the operations for you. You would need something like that on your side anyways, if you don't want every single user to define the transformers. Is thatis something that works for you?
On current master, the cosmwasm package was renamesd to @cosmjs/cosmwasm-launchpad. This should in theory be CosmWasm 0.10 compatible. However, nobody is testing this right now.
Yes! This is a great idea, let me know what I can do to make this happen 🤩