qos-qweb
Version:
qos js sdk
193 lines • 17.4 kB
JavaScript
import bech32 from 'bech32';
import { Int64BE } from 'int64-buffer';
import { Codec } from 'js-amino';
import nacl from 'tweetnacl';
import { accMul, Int64ToBuffer, stringToBuffer } from '.';
import { qosDecimal } from '../types/common';
import { MsgMultiSend, PubKeyEd25519, QSC, Receiver, Sender, Signature, StdTx } from '../types/tx';
export function getOriginAddress(address) {
const addrDecode = bech32.decode(address);
const fromwords = bech32.fromWords(addrDecode.words);
return fromwords;
}
export function signTxMsg(oMsg) {
const msg = makeTxSignMsg(oMsg);
const signatureData = nacl.sign.detached(Buffer.from(msg.signedMsg), oMsg.account.keypair.secretKey);
const codec = registerCodec();
const pubKey = new PubKeyEd25519([...oMsg.account.keypair.publicKey]);
const sig = new Signature(pubKey, [...signatureData], oMsg.nonce.toString());
const sendMultiMsg = new MsgMultiSend(msg.senders, msg.receivers);
const stdtx = new StdTx(sendMultiMsg, [sig], oMsg.chainid, oMsg.maxGas.toString());
// const jsonTx = codec.marshalJson(stdtx)
// logger.debug('stdtx: ')
// logger.info(jsonTx)
// logger.debug('marshalBinary: ')
const binary = codec.marshalBinary(stdtx);
// logger.debug(binary.toString())
// const decodedDataTx = new StdTx();
// codec.unMarshalBinary(binary, decodedDataTx)
// logger.debug('unMb StdTx: ')
// logger.info(decodedDataTx.JsObject())
return binary;
}
function makeTxSignMsg({ account, tx, chainid, maxGas, nonce }) {
let arrMsg = [];
// push buffer of orginaddress
const fromAddress = getOriginAddress(account.address);
arrMsg = arrMsg.concat(fromAddress);
const allData = composeData(tx);
// concat buffer of qosAmount
arrMsg = arrMsg.concat([...stringToBuffer(allData.qosAmount.toString())]);
// concat buffer of qscAmount
const qscArray = [];
const qscArr = [];
for (const qsc of allData.qscAmountArr) {
qscArray.push(`${qsc.amount}${qsc.coinName}`);
qscArr.push(new QSC(qsc.coinName, qsc.amount.toString()));
}
// compose qsc string , e.g. 2qsca,3qscb
const qscString = qscArray.join(',');
arrMsg = arrMsg.concat([...stringToBuffer(qscString)]);
arrMsg = arrMsg.concat([...allData.arrReceiver]);
const chaidBufferArray = [...stringToBuffer(chainid)];
arrMsg = arrMsg.concat(chaidBufferArray);
arrMsg = arrMsg.concat([...Int64ToBuffer(maxGas)]);
arrMsg = arrMsg.concat([...Int64ToBuffer(nonce)]);
arrMsg = arrMsg.concat(chaidBufferArray);
const senders = [
new Sender(fromAddress, allData.qosAmount.toString(), qscArr)
];
const receivers = allData.receivers;
return { signedMsg: arrMsg, senders, receivers };
}
function registerCodec() {
const codec = new Codec();
codec.registerConcrete(new StdTx(), 'qbase/txs/stdtx', {});
codec.registerConcrete(new MsgMultiSend(), 'transfer/txs/TxTransfer', {});
codec.registerConcrete(new PubKeyEd25519(), 'tendermint/PubKeyEd25519', {});
return codec;
}
function composeData(tx) {
const coinNameArr = getQscCoinNames(tx);
if (Array.isArray(tx)) {
return txIsArrayForComposeData(tx, coinNameArr);
}
return txForComposeData(tx, coinNameArr);
}
function txIsArrayForComposeData(tx, coinNameArr) {
let qosAmount = 0;
const qscAmountArr = [];
// 添加 receiver 代签名 byte[]
let arrReceiver = [];
const receivers = [];
for (const item of tx) {
item.qos = accMul(item.qos, qosDecimal);
qosAmount += item.qos;
const toAddress = getOriginAddress(item.to);
arrReceiver = arrReceiver.concat(toAddress);
arrReceiver = arrReceiver.concat([...stringToBuffer(item.qos.toString())]);
const qscArr = [];
const cqscAmountArr = [];
if (item.qscs && item.qscs.length > 0) {
for (const coinName of coinNameArr) {
const cqsc = item.qscs
.filter(x => x.coin_name.toLowerCase() === coinName)
.reduce((pre, current) => {
return {
coin_name: pre.coin_name,
amount: pre.amount + current.amount
};
});
cqsc.amount = accMul(cqsc.amount, qosDecimal);
cqscAmountArr.push(`${cqsc.amount}${coinName}`);
qscArr.push(new QSC(coinName, cqsc.amount.toString()));
const index = qscAmountArr.findIndex(x => x.coinName === coinName);
if (index > -1) {
qscAmountArr[index].amount += cqsc.amount;
}
else {
qscAmountArr.push({
coinName,
amount: cqsc.amount
});
}
}
arrReceiver = arrReceiver.concat([
...stringToBuffer(cqscAmountArr.join(','))
]);
}
receivers.push(new Receiver(toAddress, item.qos.toString(), qscArr));
}
return {
qosAmount: new Int64BE(qosAmount),
qscAmountArr,
arrReceiver,
receivers
};
}
function txForComposeData(tx, coinNameArr) {
let qosAmount = 0;
const qscAmountArr = [];
// 添加 receiver 代签名 byte[]
let arrReceiver = [];
const qscArr = [];
qosAmount = accMul(tx.qos, qosDecimal);
const toAddress = getOriginAddress(tx.to);
arrReceiver = arrReceiver.concat(toAddress);
arrReceiver = arrReceiver.concat([...stringToBuffer(tx.qos.toString())]);
const cqscAmountArr = [];
if (tx.qscs && tx.qscs.length > 0) {
for (const coinName of coinNameArr) {
const cqsc = tx.qscs
.filter(x => x.coin_name.toLowerCase() === coinName)
.reduce((pre, current) => {
return {
coin_name: pre.coin_name,
amount: pre.amount + current.amount
};
});
cqsc.amount = accMul(cqsc.amount, qosDecimal);
cqscAmountArr.push(`${cqsc.amount}${coinName}`);
qscAmountArr.push({
coinName,
amount: cqsc.amount
});
qscArr.push(new QSC(coinName, cqsc.amount.toString()));
}
arrReceiver = arrReceiver.concat([
...stringToBuffer(cqscAmountArr.join(','))
]);
}
const receivers = [new Receiver(toAddress, tx.qos.toString(), qscAmountArr)];
return {
qosAmount: new Int64BE(qosAmount),
qscAmountArr,
arrReceiver,
receivers
};
}
/**
* 去重并获取所有QSC的CoinName数组,如['QSC']
* @param tx 交易体
*/
function getQscCoinNames(tx) {
const qscSet = new Set();
if (Array.isArray(tx)) {
for (const item of tx) {
if (item.qscs && item.qscs.length > 0) {
for (const qsc of item.qscs) {
qscSet.add(qsc.coin_name.toLowerCase());
}
}
}
}
else {
if (tx.qscs && tx.qscs.length > 0) {
for (const qsc of tx.qscs) {
qscSet.add(qsc.coin_name.toLowerCase());
}
}
}
return [...qscSet];
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHhTaWduRGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb3JlL3V0aWxzL1R4U2lnbkRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNqQyxPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLE1BQU0sR0FBRyxDQUFDO0FBRTFELE9BQU8sRUFBVyxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsWUFBWSxFQUNaLGFBQWEsRUFDYixHQUFHLEVBQ0gsUUFBUSxFQUNSLE1BQU0sRUFDTixTQUFTLEVBQ1QsS0FBSyxFQUNOLE1BQU0sYUFBYSxDQUFDO0FBRXJCLE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUFlO0lBQzlDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDMUMsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckQsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsSUFNekI7SUFDQyxNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQ3RDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUMxQixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQy9CLENBQUM7SUFFRixNQUFNLEtBQUss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