@firmachain/firma-js
Version:
The Official FirmaChain Javascript SDK written in Typescript
467 lines (466 loc) • 22.5 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
to[j] = from[i];
return to;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSignAndBroadcastOption = exports.DefaultTxMisc = exports.FirmaUtil = void 0;
var fs_1 = require("fs");
var tx_1 = require("cosmjs-types/cosmos/tx/v1beta1/tx");
var TendermintQueryClient_1 = require("./firmachain/common/TendermintQueryClient");
var encoding_1 = require("@cosmjs/encoding");
var LedgerSigningStargateClient_1 = require("./firmachain/common/LedgerSigningStargateClient");
var encoding_2 = require("@cosmjs/encoding");
var crypto_1 = require("@cosmjs/crypto");
var amino_1 = require("@cosmjs/amino");
var signingaminostargateclient_1 = require("./firmachain/common/signingaminostargateclient");
var proto_signing_1 = require("@cosmjs/proto-signing");
var signingstargateclient_1 = require("./firmachain/common/signingstargateclient");
var any_1 = require("./firmachain/google/protobuf/any");
var long_1 = __importDefault(require("long"));
var CommonTxClient_1 = require("./firmachain/common/CommonTxClient");
var CryptoJS = require("crypto-js");
var sha1 = require("crypto-js/sha1");
var sha256 = require("crypto-js/sha256");
var encHex = require("crypto-js/enc-hex");
var FirmaUtil = /** @class */ (function () {
function FirmaUtil(firmaConfig) {
FirmaUtil.config = firmaConfig;
}
FirmaUtil.getSignAndBroadcastOption = function (denom, txMisc) {
if (txMisc.memo == null)
txMisc.memo = "";
// INFO: if fee or gas data is not set default, those value will be null. So we have to double check it.
if (txMisc.fee == 0 || txMisc.fee == null)
txMisc.fee = FirmaUtil.config.defaultFee;
if (txMisc.gas == 0 || txMisc.gas == null)
txMisc.gas = FirmaUtil.config.defaultGas;
if (txMisc.feeGranter == null)
txMisc.feeGranter = "";
var gasFeeAmount = { denom: denom, amount: txMisc.fee.toString() };
var defaultFee = { amount: [gasFeeAmount], gas: txMisc.gas.toString(), granter: txMisc.feeGranter };
return { fee: defaultFee, memo: txMisc.memo };
};
FirmaUtil.getUTokenStringFromTokenStr = function (tokenAmount, decimal) {
var fct = Number.parseFloat(tokenAmount);
var decimalMutiplyer = Math.pow(10, decimal);
var big = fct * decimalMutiplyer;
return big.toFixed(0);
};
FirmaUtil.getTokenStringFromUTokenStr = function (uTokenAmount, decimal) {
var ufct = Number.parseInt(uTokenAmount);
var decimalMutiplyer = Math.pow(10, decimal);
return (ufct / decimalMutiplyer).toString();
};
FirmaUtil.getUTokenStringFromToken = function (tokenAmount, decimal) {
var decimalMutiplyer = Math.pow(10, decimal);
var big = tokenAmount * decimalMutiplyer;
return big.toFixed(0);
};
FirmaUtil.getUTokenFromToken = function (tokenAmount, decimal) {
var decimalMutiplyer = Math.pow(10, decimal);
var big = tokenAmount * decimalMutiplyer;
var newBig = big.toFixed(0);
return Number.parseInt(newBig);
};
FirmaUtil.arrayBufferToBase64 = function (buffer) {
return Buffer.from(buffer).toString("base64");
/*var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);*/
};
FirmaUtil.base64ToArrayBuffer = function (base64) {
var buffer = Buffer.from(base64, "base64");
return new Uint8Array(buffer);
/* var binary_string = atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes;*/
};
FirmaUtil.getTokenStringFromUToken = function (uTokenAmount, decimal) {
var fixedUTokenAmount = Math.floor(uTokenAmount);
var decimalMutiplyer = Math.pow(10, decimal);
return (fixedUTokenAmount / decimalMutiplyer).toString();
};
FirmaUtil.getUFCTStringFromFCTStr = function (fctAmount) {
return this.getUTokenStringFromTokenStr(fctAmount, this.FctDecimal);
};
FirmaUtil.getUFCTFromFCT = function (fctAmount) {
return this.getUTokenFromToken(fctAmount, this.FctDecimal);
};
FirmaUtil.getFCTStringFromUFCTStr = function (uFctAmount) {
return this.getTokenStringFromUTokenStr(uFctAmount, this.FctDecimal);
};
FirmaUtil.getUFCTStringFromFCT = function (fctAmount) {
return this.getUTokenStringFromToken(fctAmount, this.FctDecimal);
};
FirmaUtil.getFCTStringFromUFCT = function (uFctAmount) {
return this.getTokenStringFromUToken(uFctAmount, this.FctDecimal);
};
FirmaUtil.getFileHash = function (filePath) {
return __awaiter(this, void 0, void 0, function () {
var fileData, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fs_1.promises.readFile(filePath)];
case 1:
fileData = _a.sent();
data = CryptoJS.lib.WordArray.create(fileData.buffer);
return [2 /*return*/, sha256(data).toString(encHex)];
}
});
});
};
FirmaUtil.getFileHashFromBuffer = function (buffer) {
var data = CryptoJS.lib.WordArray.create(buffer);
return sha256(data).toString(encHex);
};
FirmaUtil.getSha1HashFromString = function (text) {
var data = CryptoJS.lib.WordArray.create(text);
return sha1(data).toString(encHex);
};
FirmaUtil.getHashFromString = function (text) {
var data = CryptoJS.lib.WordArray.create(text);
return sha256(data).toString(encHex);
};
FirmaUtil.isValidAddress = function (address) {
try {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
encoding_1.Bech32.decode(address).data;
return true;
}
catch (e) {
}
return false;
};
FirmaUtil.buf2hex = function (buffer) {
return __spreadArray([], __read(new Uint8Array(buffer))).map(function (x) { return x.toString(16).padStart(2, '0'); })
.join('');
};
// for evm address support
FirmaUtil.getHexAddressFromAddress = function (address) {
var data = encoding_1.Bech32.decode(address).data;
return "0x" + FirmaUtil.buf2hex(data);
};
FirmaUtil.getValOperAddressFromAccAddress = function (address) {
var data = encoding_1.Bech32.decode(address).data;
return encoding_1.Bech32.encode(FirmaUtil.config.prefix + "valoper", data);
};
FirmaUtil.getValConsAddressFromAccAddress = function (consensusPubkey) {
var ed25519PubkeyRaw = encoding_2.fromBase64(consensusPubkey);
var addressData = crypto_1.sha256(ed25519PubkeyRaw).slice(0, 20);
return encoding_1.Bech32.encode(FirmaUtil.config.prefix + "valcons", addressData);
};
FirmaUtil.getAccAddressFromValOperAddress = function (address) {
var data = encoding_1.Bech32.decode(address).data;
return encoding_1.Bech32.encode(FirmaUtil.config.prefix, data);
};
FirmaUtil.getSignerDataForLedger = function (address) {
return __awaiter(this, void 0, void 0, function () {
var signingClient, sequence, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
return [4 /*yield*/, LedgerSigningStargateClient_1.LedgerSigningStargateClient.connectWithSigner(FirmaUtil.config.rpcAddress)];
case 1:
signingClient = _a.sent();
return [4 /*yield*/, signingClient.getSignerData(address)];
case 2:
sequence = _a.sent();
return [2 /*return*/, sequence];
case 3:
error_1 = _a.sent();
FirmaUtil.printLog(error_1);
throw error_1;
case 4: return [2 /*return*/];
}
});
});
};
FirmaUtil.estimateGas = function (txRaw) {
return __awaiter(this, void 0, void 0, function () {
var encodedTx, hexTx, queryClient, gas, multiplier, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
encodedTx = Uint8Array.from(tx_1.TxRaw.encode(txRaw).finish());
hexTx = "0x" + Buffer.from(encodedTx).toString("hex");
queryClient = new TendermintQueryClient_1.TendermintQueryClient(FirmaUtil.config.rpcAddress);
return [4 /*yield*/, queryClient.queryEstimateGas(hexTx)];
case 1:
gas = _a.sent();
multiplier = 1.15;
return [2 /*return*/, Math.ceil(gas * multiplier)];
case 2:
error_2 = _a.sent();
FirmaUtil.printLog(error_2);
throw error_2;
case 3: return [2 /*return*/];
}
});
});
};
FirmaUtil.estimateGasRaw = function (txRaw) {
return __awaiter(this, void 0, void 0, function () {
var encodedTx, hexTx, queryClient, gas, multiplier, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
encodedTx = Uint8Array.from(txRaw);
hexTx = "0x" + Buffer.from(encodedTx).toString("hex");
console.log("hexTx:" + hexTx);
queryClient = new TendermintQueryClient_1.TendermintQueryClient(FirmaUtil.config.rpcAddress);
return [4 /*yield*/, queryClient.queryEstimateGas(hexTx)];
case 1:
gas = _a.sent();
multiplier = 1.25;
return [2 /*return*/, Math.ceil(gas * multiplier)];
case 2:
error_3 = _a.sent();
FirmaUtil.printLog(error_3);
throw error_3;
case 3: return [2 /*return*/];
}
});
});
};
FirmaUtil.printLog = function (log) {
if (FirmaUtil.config.isShowLog === false)
return;
console.log("[FirmaSDK] " + log);
};
FirmaUtil.experimentalAdr36Sign = function (wallet, data) {
return __awaiter(this, void 0, void 0, function () {
var registry, aliceClient, address, userData, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 4, , 5]);
registry = new proto_signing_1.Registry();
return [4 /*yield*/, signingaminostargateclient_1.SigningAminoStargateClient.connectWithSigner(FirmaUtil.config.rpcAddress, wallet.getRawAminoWallet(), registry)];
case 1:
aliceClient = _a.sent();
return [4 /*yield*/, wallet.getAddress()];
case 2:
address = _a.sent();
userData = Buffer.from(data);
return [4 /*yield*/, aliceClient.experimentalAdr36Sign(address, userData)];
case 3: return [2 /*return*/, _a.sent()];
case 4:
error_4 = _a.sent();
FirmaUtil.printLog(error_4);
throw error_4;
case 5: return [2 /*return*/];
}
});
});
};
FirmaUtil.experimentalAdr36Verify = function (data, checkMsg) {
return __awaiter(this, void 0, void 0, function () {
var error_5;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, signingaminostargateclient_1.SigningAminoStargateClient.experimentalAdr36Verify(data, checkMsg)];
case 1: return [2 /*return*/, _a.sent()];
case 2:
error_5 = _a.sent();
FirmaUtil.printLog(error_5);
throw error_5;
case 3: return [2 /*return*/];
}
});
});
};
FirmaUtil.recoverSigningAddress = function (signature, hash, recoveryIndex) {
return __awaiter(this, void 0, void 0, function () {
var sig, extendedSig, recoveredPubKey, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (recoveryIndex > 3) {
throw new Error('Invalid recovery index');
}
sig = crypto_1.Secp256k1Signature.fromFixedLength(encoding_2.fromBase64(signature));
extendedSig = new crypto_1.ExtendedSecp256k1Signature(sig.r(), sig.s(), recoveryIndex);
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, crypto_1.Secp256k1.recoverPubkey(extendedSig, hash)];
case 2:
recoveredPubKey = _b.sent();
return [2 /*return*/, amino_1.pubkeyToAddress({
type: 'tendermint/PubKeySecp256k1',
value: encoding_2.toBase64(crypto_1.Secp256k1.compressPubkey(recoveredPubKey)),
}, 'firma')];
case 3:
_a = _b.sent();
return [2 /*return*/, null];
case 4: return [2 /*return*/];
}
});
});
};
FirmaUtil.verifySignature = function (address, signature, hash) {
return __awaiter(this, void 0, void 0, function () {
var i, recoveredAddress;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0;
_a.label = 1;
case 1:
if (!(i < 4)) return [3 /*break*/, 4];
return [4 /*yield*/, this.recoverSigningAddress(signature, hash, i)];
case 2:
recoveredAddress = _a.sent();
if (recoveredAddress === address) {
return [2 /*return*/, true];
}
_a.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/, false];
}
});
});
};
FirmaUtil.verifyDirectSignature = function (address, signature, signDoc) {
var messageHash = crypto_1.sha256(proto_signing_1.makeSignBytes(signDoc));
return this.verifySignature(address, signature, messageHash);
};
;
FirmaUtil.parseSignDocValues = function (signDocString) {
var signDoc = JSON.parse(signDocString);
return __assign(__assign({}, signDoc), { bodyBytes: encoding_2.fromHex(signDoc.bodyBytes), authInfoBytes: encoding_2.fromHex(signDoc.authInfoBytes), accountNumber: long_1.default.fromString(signDoc.accountNumber) });
};
FirmaUtil.stringifySignDocValues = function (signDoc) {
return JSON.stringify(__assign(__assign({}, signDoc), { bodyBytes: encoding_2.toHex(signDoc.bodyBytes), authInfoBytes: encoding_2.toHex(signDoc.authInfoBytes), accountNumber: signDoc.accountNumber.toString() }));
};
FirmaUtil.makeSignDoc = function (signerAddress, pubkey, messages, txMisc) {
if (txMisc === void 0) { txMisc = exports.DefaultTxMisc; }
return __awaiter(this, void 0, void 0, function () {
var result, chainID, serverUrl, registry;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
result = FirmaUtil.getSignAndBroadcastOption(FirmaUtil.config.denom, txMisc);
chainID = FirmaUtil.config.chainID;
serverUrl = FirmaUtil.config.rpcAddress;
registry = CommonTxClient_1.CommonTxClient.getRegistry();
return [4 /*yield*/, signingstargateclient_1.SigningStargateClient.makeSignDocForSend(signerAddress, pubkey, messages, result.fee, result.memo, serverUrl, chainID, registry)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
};
FirmaUtil.makeSignDocWithStringify = function (signerAddress, pubkey, messages, txMisc) {
if (txMisc === void 0) { txMisc = exports.DefaultTxMisc; }
return __awaiter(this, void 0, void 0, function () {
var signDoc, stringSignDoc;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.makeSignDoc(signerAddress, pubkey, messages, txMisc)];
case 1:
signDoc = _a.sent();
stringSignDoc = this.stringifySignDocValues(signDoc);
return [2 /*return*/, stringSignDoc];
}
});
});
};
FirmaUtil.getAnyData = function (registry, message) {
var anyData = any_1.Any.fromPartial({
typeUrl: message.typeUrl,
value: registry.encode(message)
});
return anyData;
};
FirmaUtil.getCommonTxClient = function (aliceWallet) {
return new CommonTxClient_1.CommonTxClient(aliceWallet, FirmaUtil.config.rpcAddress);
};
FirmaUtil.FctDecimal = 6;
return FirmaUtil;
}());
exports.FirmaUtil = FirmaUtil;
exports.DefaultTxMisc = { memo: "", fee: 0, gas: 0, feeGranter: "" };
exports.getSignAndBroadcastOption = FirmaUtil.getSignAndBroadcastOption;