@firmachain/firma-js
Version:
The Official FirmaChain Javascript SDK written in Typescript
595 lines (594 loc) • 28.2 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 (g && (g = 0, op[0] && (_ = 0)), _) 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, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
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 axios_1 = __importDefault(require("axios"));
var duration_1 = require("cosmjs-types/google/protobuf/duration");
var encoding_1 = require("@cosmjs/encoding");
var proto_signing_1 = require("@cosmjs/proto-signing");
var crypto_1 = require("@cosmjs/crypto");
var any_1 = require("cosmjs-types/google/protobuf/any");
var CommonTxClient_1 = require("./firmachain/common/CommonTxClient");
var TendermintQueryClient_1 = require("./firmachain/common/TendermintQueryClient");
var bignumber_js_1 = require("bignumber.js");
var tendermint_rpc_1 = require("@cosmjs/tendermint-rpc");
var coin_1 = require("cosmjs-types/cosmos/base/v1beta1/coin");
var SigningStargateClient_1 = require("./firmachain/common/SigningStargateClient");
var SigningProtobufStargateClient_1 = require("./firmachain/common/SigningProtobufStargateClient");
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 = coin_1.Coin.fromPartial({
denom: denom,
amount: txMisc.fee.toString(),
});
var fee = tx_1.Fee.fromPartial({
amount: [gasFeeAmount],
gasLimit: BigInt(txMisc.gas),
granter: txMisc.feeGranter,
payer: "",
});
return { fee: fee, 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");
};
FirmaUtil.base64ToArrayBuffer = function (base64) {
var buffer = Buffer.from(base64, "base64");
return new Uint8Array(buffer);
};
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
(0, encoding_1.fromBech32)(address).data;
return true;
}
catch (e) {
}
return false;
};
FirmaUtil.buf2hex = function (buffer) {
return __spreadArray([], __read(new Uint8Array(buffer)), false).map(function (x) { return x.toString(16).padStart(2, '0'); })
.join('');
};
// for evm address support
FirmaUtil.getHexAddressFromAddress = function (address) {
var data = (0, encoding_1.fromBech32)(address).data;
return "0x" + FirmaUtil.buf2hex(data);
};
FirmaUtil.getValOperAddressFromAccAddress = function (address) {
var data = (0, encoding_1.fromBech32)(address).data;
return (0, encoding_1.toBech32)(FirmaUtil.config.prefix + "valoper", data);
};
FirmaUtil.getValConsAddressFromAccAddress = function (consensusPubkey) {
var ed25519PubkeyRaw = (0, encoding_1.fromBase64)(consensusPubkey);
var addressData = (0, crypto_1.sha256)(ed25519PubkeyRaw).slice(0, 20);
return (0, encoding_1.toBech32)(FirmaUtil.config.prefix + "valcons", addressData);
};
FirmaUtil.getAccAddressFromValOperAddress = function (address) {
var data = (0, encoding_1.fromBech32)(address).data;
return (0, encoding_1.toBech32)(FirmaUtil.config.prefix, data);
};
FirmaUtil.estimateGas = function (txRaw) {
return __awaiter(this, void 0, void 0, function () {
var encodedTx, hexTx, queryClient, gas, multiplier, error_1;
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".concat(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_1 = _a.sent();
FirmaUtil.printLog(error_1);
throw error_1;
case 3: return [2 /*return*/];
}
});
});
};
FirmaUtil.estimateGasRaw = 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(txRaw);
hexTx = "0x".concat(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.25;
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.getAccountInfo = function (address) {
return __awaiter(this, void 0, void 0, function () {
var res, json, baseAccount, result, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, axios_1.default.get("".concat(FirmaUtil.config.restApiAddress, "/cosmos/auth/v1beta1/accounts/").concat(address))];
case 1:
res = _a.sent();
if (res.status !== 200) {
throw new Error("HTTP ".concat(res.status, ": ").concat(res.statusText));
}
json = res.data;
baseAccount = json.account.base_account || json.account;
result = {
account_number: baseAccount.account_number,
sequence: baseAccount.sequence,
};
return [2 /*return*/, result];
case 2:
error_3 = _a.sent();
throw error_3;
case 3: return [2 /*return*/];
}
});
});
};
FirmaUtil.getChainId = function () {
return __awaiter(this, void 0, void 0, function () {
var res, json;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios_1.default.get("".concat(FirmaUtil.config.restApiAddress, "/cosmos/base/tendermint/v1beta1/node_info"))];
case 1:
res = _a.sent();
json = res.data;
return [2 /*return*/, json.default_node_info.network];
}
});
});
};
FirmaUtil.printLog = function (log) {
if (FirmaUtil.config.isShowLog === false)
return;
console.log("[FirmaSDK] ".concat(log));
};
/**
* ADR-036 protobuf arbitrary signing (wrapper for protobufArbitrarySign)
*
* @param wallet - FirmaWalletService instance
* @param data - Arbitrary data string to sign
* @returns ArbitraryVerifyData for verification
*/
FirmaUtil.experimentalAdr36Sign = function (wallet, data) {
return __awaiter(this, void 0, void 0, function () {
var client, address, dataBytes, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 4, , 5]);
return [4 /*yield*/, SigningProtobufStargateClient_1.SigningProtobufStargateClient.connectWithSigner(FirmaUtil.config.rpcAddress, wallet.getRawWallet(), {})];
case 1:
client = _a.sent();
return [4 /*yield*/, wallet.getAddress()];
case 2:
address = _a.sent();
dataBytes = Buffer.from(data, 'utf8');
return [4 /*yield*/, client.experimentalAdr36Sign(address, dataBytes)];
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*/];
}
});
});
};
/**
* ADR-036 protobuf arbitrary signature verification (wrapper for protobufArbitraryVerify)
*
* @param data - ArbitraryVerifyData to verify
* @param checkMsg - Original message that was signed
* @returns boolean indicating if the signature is valid
*/
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*/, SigningProtobufStargateClient_1.SigningProtobufStargateClient.experimentalAdr36Verify(data, checkMsg)];
case 1: return [2 /*return*/, _a.sent()];
case 2:
error_5 = _a.sent();
FirmaUtil.printLog(error_5);
return [2 /*return*/, false];
case 3: return [2 /*return*/];
}
});
});
};
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, fee;
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();
fee = {
amount: __spreadArray([], __read(result.fee.amount), false),
gasLimit: result.fee.gasLimit,
granter: result.fee.granter || "",
payer: ""
};
return [4 /*yield*/, SigningStargateClient_1.SigningStargateClient.makeSignDocForSend(signerAddress, pubkey, messages, 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.recoverSigningAddress = function (signature, hash, recoveryIndex) {
return __awaiter(this, void 0, void 0, function () {
var sig, extendedSig, recoveredPubKey, compressedPubkey, rawAddress, _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((0, encoding_1.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();
compressedPubkey = crypto_1.Secp256k1.compressPubkey(recoveredPubKey);
rawAddress = (0, tendermint_rpc_1.rawSecp256k1PubkeyToRawAddress)(compressedPubkey);
return [2 /*return*/, (0, encoding_1.toBech32)('firma', rawAddress)];
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 = (0, crypto_1.sha256)((0, 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: (0, encoding_1.fromHex)(signDoc.bodyBytes), authInfoBytes: (0, encoding_1.fromHex)(signDoc.authInfoBytes), accountNumber: BigInt(signDoc.accountNumber) });
};
FirmaUtil.stringifySignDocValues = function (signDoc) {
return JSON.stringify(__assign(__assign({}, signDoc), { bodyBytes: (0, encoding_1.toHex)(signDoc.bodyBytes), authInfoBytes: (0, encoding_1.toHex)(signDoc.authInfoBytes), accountNumber: signDoc.accountNumber.toString() }));
};
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.parseDurationString = function (durationStr) {
if (!durationStr || durationStr.trim() === "") {
return { seconds: BigInt(0), nanos: 0 };
}
var input = durationStr.trim();
var totalSeconds = 0;
var totalNanos = 0;
// Handle negative durations
var isNegative = input.startsWith('-');
var cleanInput = isNegative ? input.substring(1) : input;
// Regular expression to match duration components
var regex = /(\d+(?:\.\d+)?)(d|h|m|s|ms|µs|us|ns)/g;
var match;
var hasMatches = false;
while ((match = regex.exec(cleanInput)) !== null) {
hasMatches = true;
var value = parseFloat(match[1]);
var unit = match[2];
switch (unit) {
case 'd': // days
totalSeconds += value * 24 * 60 * 60;
break;
case 'h': // hours
totalSeconds += value * 60 * 60;
break;
case 'm': // minutes
totalSeconds += value * 60;
break;
case 's': // seconds
totalSeconds += value;
break;
case 'ms': // milliseconds
totalNanos += value * 1000000;
break;
case 'µs':
case 'us': // microseconds
totalNanos += value * 1000;
break;
case 'ns': // nanoseconds
totalNanos += value;
break;
}
}
if (!hasMatches) {
throw new Error("Invalid duration format: ".concat(durationStr));
}
// Convert excess nanos to seconds
var extraSeconds = Math.floor(totalNanos / 1000000000);
totalSeconds += extraSeconds;
totalNanos = totalNanos % 1000000000;
// Apply negative sign
var finalSeconds = isNegative ? -totalSeconds : totalSeconds;
var finalNanos = isNegative ? -totalNanos : totalNanos;
return {
seconds: BigInt(Math.floor(finalSeconds)),
nanos: Math.floor(finalNanos)
};
};
FirmaUtil.createDurationFromString = function (durationStr) {
var _a = FirmaUtil.parseDurationString(durationStr), seconds = _a.seconds, nanos = _a.nanos;
return duration_1.Duration.fromPartial({
seconds: seconds,
nanos: nanos
});
};
/**
* Safely processes commission rate strings to prevent big.Int conversion errors.
* Converts decimal commission rates to Cosmos SDK atomics format (integer representation).
*
* @param commissionRate - Commission rate string from staking params
* @returns Processed commission rate string safe for protobuf usage (atomics format or empty string)
*/
FirmaUtil.processCommissionRateAsDecimal = function (commissionRate) {
var trimmed = commissionRate.trim();
if (!commissionRate || trimmed === "") {
throw new Error("Invalid commission rate format: ".concat(commissionRate));
}
if (!/^-?\d+\.?\d*$/.test(trimmed)) {
throw new Error("Invalid commission rate format: ".concat(commissionRate));
}
// Validates input and creates BigNumber instance
var commissionRateBN = new bignumber_js_1.BigNumber(trimmed);
// Checks if it's a valid finite number
if (!commissionRateBN.isFinite())
throw new Error("Invalid commission rate format: " + commissionRate);
// Validates range (0 to 1 inclusive)
if (commissionRateBN.isNegative() || commissionRateBN.isGreaterThan(1))
throw new Error("Invalid commission rate range. Must be between 0 and 1 inclusive.");
// Converts to atomics format (multiply by 10^18)
var atomics = commissionRateBN.multipliedBy(new bignumber_js_1.BigNumber(10).pow(18));
// Returns integer string
return atomics.integerValue(bignumber_js_1.BigNumber.ROUND_DOWN).toString();
};
FirmaUtil.FctDecimal = 6;
return FirmaUtil;
}());
exports.FirmaUtil = FirmaUtil;
exports.DefaultTxMisc = { memo: "", fee: 0, gas: 0, feeGranter: "" };
exports.getSignAndBroadcastOption = FirmaUtil.getSignAndBroadcastOption;