UNPKG

@tedcryptoorg/cosmos-signer

Version:

Cosmos Signer - A library for signing transactions for Cosmos SDK chains

161 lines (160 loc) 8.73 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultAdapter = void 0; const tx_js_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx.js"); const signing_1 = require("cosmjs-types/cosmos/tx/signing/v1beta1/signing"); const stargate_1 = require("@cosmjs/stargate"); const keys_1 = require("cosmjs-types/cosmos/crypto/secp256k1/keys"); const signingstargateclient_1 = require("@cosmjs/stargate/build/signingstargateclient"); const encoding_1 = require("@cosmjs/encoding"); const amino_1 = require("@cosmjs/amino"); const proto_signing_1 = require("@cosmjs/proto-signing"); const lodash_1 = __importDefault(require("lodash")); const long_1 = __importDefault(require("long")); const Authz_1 = require("../../converters/Authz"); class DefaultAdapter { constructor(network, wallet) { this.network = network; this.wallet = wallet; this.registry = new proto_signing_1.Registry(signingstargateclient_1.defaultRegistryTypes); const defaultConverters = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (0, stargate_1.createAuthzAminoConverters)()), (0, stargate_1.createBankAminoConverters)()), (0, stargate_1.createDistributionAminoConverters)()), (0, stargate_1.createGovAminoConverters)()), (0, stargate_1.createStakingAminoConverters)()), (0, stargate_1.createIbcAminoConverters)()); const aminoTypes = new stargate_1.AminoTypes(defaultConverters); this.aminoTypes = new stargate_1.AminoTypes(Object.assign(Object.assign(Object.assign({}, defaultConverters), (0, Authz_1.createAuthzAminoConverters)()), (0, Authz_1.createAuthzExecAminoConverters)(this.registry, aminoTypes))); } sign(account, messages, fee, memo) { return __awaiter(this, void 0, void 0, function* () { const { chainId } = this.network; const { account_number: accountNumber, sequence, address } = account; let aminoMsgs = undefined; try { aminoMsgs = this.convertToAmino(messages); } catch (e) { console.log(e); } if (aminoMsgs && this.wallet.signAminoSupport()) { const signDoc = (0, amino_1.makeSignDoc)(aminoMsgs, { gas: fee.gasLimit.toString(), amount: fee.amount }, chainId, memo, accountNumber, sequence); const { signature, signed } = yield this.wallet.signAmino(address, signDoc); const authInfoBytes = yield this.makeAuthInfoBytes(account, fee, signing_1.SignMode.SIGN_MODE_LEGACY_AMINO_JSON); return { bodyBytes: this.makeBodyBytes(messages, signed.memo), authInfoBytes, signatures: [Buffer.from(signature.signature, "base64")], }; } if (this.wallet.signDirectSupport()) { const authInfoBytes = yield this.makeAuthInfoBytes(account, fee, signing_1.SignMode.SIGN_MODE_DIRECT); const signDoc = (0, proto_signing_1.makeSignDoc)(this.makeBodyBytes(messages, memo), authInfoBytes, chainId, accountNumber); const { signature, signed } = yield this.wallet.signDirect(address, signDoc); return { bodyBytes: signed.bodyBytes, authInfoBytes: signed.authInfoBytes, signatures: [(0, encoding_1.fromBase64)(signature.signature)], }; } throw new Error('Unable to sign message with this wallet/signer'); }); } simulate(account, messages, fee, memo) { return __awaiter(this, void 0, void 0, function* () { return { bodyBytes: this.makeBodyBytes(messages, memo), authInfoBytes: yield this.makeAuthInfoBytes(account, fee, signing_1.SignMode.SIGN_MODE_UNSPECIFIED), signatures: [new Uint8Array()], }; }); } convertToAmino(messages) { return messages.map((message) => { if (message.typeUrl.startsWith('/cosmos.authz')) { if (!this.network.authzAminoSupport) { throw new Error('This chain does not support amino conversion for Authz messages'); } if (this.network.authzAminoGenericOnly && this.wallet.signDirectSupport()) { throw new Error('This chain does not fully support amino conversion for Authz messages, using signDirect instead'); } } if (message.typeUrl === '/cosmos.authz.v1beta1.MsgExec') { const execTypes = message.value.msgs.map((msg) => msg.typeUrl); const preventedTypes = execTypes.filter((type) => this.network.authzAminoExecPreventTypes.some((prevent) => type.match(lodash_1.default.escapeRegExp(prevent)))); if (preventedTypes.length > 0) { throw new Error(`This chain does not support amino conversion for Authz Exec with message types: ${preventedTypes.join(', ')}`); } } else if (this.network.aminoPreventTypes.some((prevent) => message.typeUrl.match(lodash_1.default.escapeRegExp(prevent)))) { throw new Error(`This chain does not support amino conversion for message type: ${message.typeUrl}`); } let aminoMessage = this.aminoTypes.toAmino(message); if (this.network.authzAminoLiftedValues) { switch (aminoMessage.type) { case 'cosmos-sdk/MsgGrant': aminoMessage = aminoMessage.value; aminoMessage.grant.authorization = aminoMessage.grant.authorization.value; break; case 'cosmos-sdk/MsgRevoke': aminoMessage = aminoMessage.value; break; case 'cosmos-sdk/MsgExec': throw new Error('This chain does not support amino conversion for MsgExec'); } } return aminoMessage; }); } makeBodyBytes(messages, memo) { const anyMsgs = messages.map((m) => this.registry.encodeAsAny(m)); return tx_js_1.TxBody.encode(tx_js_1.TxBody.fromPartial({ messages: anyMsgs, memo, })).finish(); } makeAuthInfoBytes(account, fee, mode) { return __awaiter(this, void 0, void 0, function* () { const { sequence } = account; const accountFromSigner = (yield this.wallet.getAccounts())[0]; if (!accountFromSigner) { throw new Error("Failed to retrieve account from signer"); } const signerPubkey = accountFromSigner.pubkey; return tx_js_1.AuthInfo.encode({ signerInfos: [ { publicKey: { typeUrl: this.pubkeyTypeUrl(account.pub_key), value: keys_1.PubKey.encode({ key: signerPubkey, }).finish(), }, sequence: long_1.default.fromNumber(sequence, true), modeInfo: { single: { mode } }, }, ], fee, }).finish(); }); } pubkeyTypeUrl(pub_key) { if (pub_key === null || pub_key === void 0 ? void 0 : pub_key['@type']) return pub_key['@type']; if (this.network.path === 'injective') { return '/injective.crypto.v1beta1.ethsecp256k1.PubKey'; } if (this.network.slip44 === 60) { return '/ethermint.crypto.v1.ethsecp256k1.PubKey'; } return '/cosmos.crypto.secp256k1.PubKey'; } } exports.DefaultAdapter = DefaultAdapter;