@tedcryptoorg/cosmos-signer
Version:
Cosmos Signer - A library for signing transactions for Cosmos SDK chains
161 lines (160 loc) • 8.73 kB
JavaScript
;
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;