Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simulate extension for fee granter param #243

Merged
merged 4 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eighty-plants-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@burnt-labs/abstraxion-core": minor
---

GranteeSignerClient simulate extension for fee granter param
1 change: 1 addition & 0 deletions packages/abstraxion-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@cosmjs/cosmwasm-stargate": "^0.32.4",
"@cosmjs/crypto": "^0.32.4",
"@cosmjs/encoding": "^0.32.4",
"@cosmjs/math": "^0.32.4",
"@cosmjs/proto-signing": "^0.32.4",
"@cosmjs/stargate": "^0.32.4",
"@cosmjs/tendermint-rpc": "^0.32.4",
Expand Down
121 changes: 110 additions & 11 deletions packages/abstraxion-core/src/GranteeSignerClient.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { customAccountFromAny } from "@burnt-labs/signers";
import {
DeliverTxResponse,
SigningCosmWasmClient,
Expand All @@ -6,23 +7,31 @@ import {
import {
AccountData,
EncodeObject,
encodePubkey,
OfflineSigner,
} from "@cosmjs/proto-signing";
import {
calculateFee,
createProtobufRpcClient,
GasPrice,
type Account,
type SignerData,
type StdFee,
} from "@cosmjs/stargate";
import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { AuthInfo, Fee, TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { MsgExec } from "cosmjs-types/cosmos/authz/v1beta1/tx";
import {
HttpEndpoint,
Tendermint37Client,
TendermintClient,
} from "@cosmjs/tendermint-rpc";
import { customAccountFromAny } from "@burnt-labs/signers";
import { Uint53 } from "@cosmjs/math";
import { encodeSecp256k1Pubkey } from "@cosmjs/amino";
import {
ServiceClientImpl,
SimulateRequest,
} from "cosmjs-types/cosmos/tx/v1beta1/service";
import { SignMode } from "cosmjs-types/cosmos/tx/signing/v1beta1/signing";

export interface GranteeSignerOptions {
readonly granterAddress: string;
Expand Down Expand Up @@ -104,16 +113,13 @@ export class GranteeSignerClient extends SigningCosmWasmClient {
return customAccountFromAny(account);
}

public async signAndBroadcast(
private transformForMsgExec(
signerAddress: string,
messages: readonly EncodeObject[],
fee: StdFee | "auto" | number,
memo = "",
): Promise<DeliverTxResponse> {
// Figure out if the signerAddress is a granter
): { signerAddress: string; messages: readonly EncodeObject[] } {
if (signerAddress === this.granterAddress) {
signerAddress = this.granteeAddress;
// Wrap the signerAddress in a MsgExec

messages = [
{
typeUrl: "/cosmos.authz.v1beta1.MsgExec",
Expand All @@ -125,6 +131,94 @@ export class GranteeSignerClient extends SigningCosmWasmClient {
];
}

return { signerAddress, messages };
}

public async simulate(
signerAddress: string,
messages: readonly EncodeObject[],
memo: string | undefined,
feeGranter?: string,
): Promise<number> {
const {
signerAddress: transformedSignerAddress,
messages: transformedMessages,
} = this.transformForMsgExec(signerAddress, messages);

const { sequence } = await this.getSequence(transformedSignerAddress);
const accountFromSigner = (await this._signer.getAccounts()).find(
(account) => account.address === transformedSignerAddress,
);

if (!accountFromSigner) {
throw new Error("No account found.");
}

const pubkey = encodeSecp256k1Pubkey(accountFromSigner.pubkey);

const queryClient = this.getQueryClient();
if (!queryClient) {
throw new Error("Couldn't get query client");
}

const rpc = createProtobufRpcClient(queryClient);
const queryService = new ServiceClientImpl(rpc);

const authInfo = AuthInfo.fromPartial({
fee: Fee.fromPartial({ granter: feeGranter }),
signerInfos: [
{
publicKey: encodePubkey(pubkey),
modeInfo: {
single: {
mode: SignMode.SIGN_MODE_DIRECT,
},
},
sequence: BigInt(sequence),
},
],
});
const authInfoBytes = AuthInfo.encode(authInfo).finish();

const txBodyEncodeObject = {
typeUrl: "/cosmos.tx.v1beta1.TxBody",
value: {
messages: transformedMessages,
memo: memo,
},
};
const bodyBytes = this.registry.encode(txBodyEncodeObject);

const tx = TxRaw.fromPartial({
bodyBytes,
authInfoBytes,
signatures: [new Uint8Array([10])],
});

const request = SimulateRequest.fromPartial({
txBytes: TxRaw.encode(tx).finish(),
});

const { gasInfo } = await queryService.Simulate(request);

if (!gasInfo) {
throw new Error("No gas info returned");
}

return Uint53.fromString(gasInfo.gasUsed.toString()).toNumber();
}

public async signAndBroadcast(
signerAddress: string,
messages: readonly EncodeObject[],
fee: StdFee | "auto" | number,
memo = "",
): Promise<DeliverTxResponse> {
const {
signerAddress: transformedSignerAddress,
messages: transformedMessages,
} = this.transformForMsgExec(signerAddress, messages);

let usedFee: StdFee;

const granter = this._treasury ? this._treasury : this.granterAddress;
Expand All @@ -135,7 +229,12 @@ export class GranteeSignerClient extends SigningCosmWasmClient {
"Gas price must be set in the client options when auto gas is used",
);
}
const gasEstimation = await this.simulate(signerAddress, messages, memo);
const gasEstimation = await this.simulate(
transformedSignerAddress,
transformedMessages,
memo,
granter,
);
const multiplier =
typeof fee == "number" ? fee : this._defaultGasMultiplier;
const calculatedFee = calculateFee(
Expand All @@ -152,8 +251,8 @@ export class GranteeSignerClient extends SigningCosmWasmClient {
}

const txRaw = await this.sign(
signerAddress,
messages,
transformedSignerAddress,
transformedMessages,
usedFee,
memo,
undefined,
Expand Down
3 changes: 2 additions & 1 deletion packages/abstraxion/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export {
useModal,
} from "./hooks";

export { ContractGrantDescription } from "./components/AbstraxionContext";
export type { ContractGrantDescription } from "./components/AbstraxionContext";
export type { GranteeSignerClient } from "@burnt-labs/abstraxion-core";
Loading
Loading