Skip to content

Instantly share code, notes, and snippets.

@anthonyjoeseph
Created May 12, 2023 17:59
Show Gist options
  • Save anthonyjoeseph/0c4885fec79b0889a8fd2d01f6042356 to your computer and use it in GitHub Desktop.
Save anthonyjoeseph/0c4885fec79b0889a8fd2d01f6042356 to your computer and use it in GitHub Desktop.
CosmJs Unjail Validator
import {
AminoConverters,
AminoMsgUnjail,
AminoTypes,
SigningStargateClient,
StargateClient,
createDefaultAminoConverters,
defaultRegistryTypes,
makeMultisignedTxBytes,
} from "@cosmjs/stargate";
import { GeneratedType, Registry, coins } from "@cosmjs/proto-signing";
import { MultisigThresholdPubkey, Secp256k1HdWallet, makeCosmoshubPath } from "@cosmjs/amino";
import { MsgUnjail } from "cosmjs-types/cosmos/slashing/v1beta1/tx";
const createSlashingAminoConverters = (): AminoConverters => ({
"/cosmos.slashing.v1beta1.MsgUnjail": {
aminoType: "cosmos-sdk/MsgUnjail",
fromAmino: (value: AminoMsgUnjail["value"]): MsgUnjail =>
MsgUnjail.fromPartial({
validatorAddr: value.validator_addr,
}),
toAmino: (val: MsgUnjail): AminoMsgUnjail["value"] => ({
validator_addr: val.validatorAddr,
}),
},
});
export const createAminoConverters = (): AminoConverters => ({
...createDefaultAminoConverters(),
...createSlashingAminoConverters(),
});
export const createRegistryTypes = (): ReadonlyArray<[string, GeneratedType]> => [
...defaultRegistryTypes,
["/cosmos.slashing.v1beta1.MsgUnjail", MsgUnjail],
];
(async () => {
const client = await StargateClient.connect("https://rpc.osmotest5.osmosis.zone");
const accountOnChain = await client.getAccount("osmo1wqx3uvz9xry82jy2suppg57mpeg50dwdqhhwtq");
if (!accountOnChain) throw new Error("missing acct on chain");
const fee = {
amount: coins(2000, "uosmo"),
gas: "200000",
};
const signerData = {
accountNumber: accountOnChain.accountNumber,
sequence: accountOnChain.sequence,
chainId: await client.getChainId(),
};
// replace with real mnemonics
const mnemonics = [
"the quick brown fox jumped over the lazy dog",
"please excuse my dear aunt sally"
];
// works
const msgEdit = {
typeUrl: "/cosmos.staking.v1beta1.MsgEditValidator",
value: {
description: {
moniker: "New-Moniker",
identity: "[do-not-modify]",
website: "[do-not-modify]",
securityContact: "[do-not-modify]",
details: "[do-not-modify]",
},
validatorAddress: "osmovaloper1wqx3uvz9xry82jy2suppg57mpeg50dwd6qldu8",
commissionRate: null,
minSelfDelegation: null,
},
};
// doesn't work
const msgUnjail = {
typeUrl: "/cosmos.slashing.v1beta1.MsgUnjail",
value: {
validatorAddr: "osmovaloper1wqx3uvz9xry82jy2suppg57mpeg50dwd6qldu8",
},
};
const signatures = await Promise.all(
mnemonics.map(async (mnemonic) => {
const wallet = await Secp256k1HdWallet.fromMnemonic(mnemonic, {
hdPaths: [makeCosmoshubPath(0)], // [44, 118, 0, 0, 0]
prefix: "osmo",
});
const address = (await wallet.getAccounts())[0]?.address;
if (!address) throw new Error("missing address");
const registry = new Registry(createRegistryTypes());
const aminoTypes = new AminoTypes(createAminoConverters());
const signingClient = await SigningStargateClient.offline(wallet, {
aminoTypes,
registry,
});
const {
bodyBytes,
signatures: [signature],
} = await signingClient.sign(address, [msgUnjail], fee, "Use your tokens wisely", signerData);
if (!signature) throw new Error("missing signature");
return { address, bodyBytes, signature };
}),
);
if (!signatures[0]) throw new Error("missing mnemonic");
const multisigPubkey = accountOnChain.pubkey as MultisigThresholdPubkey;
const bodyBytes = signatures[0]?.bodyBytes;
const signedTxBytes = makeMultisignedTxBytes(
multisigPubkey,
accountOnChain.sequence,
fee,
bodyBytes,
new Map(signatures.map((s) => [s.address, s.signature])),
);
const result = await client.broadcastTx(signedTxBytes);
console.log(result);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment