mcps-sdk-js
Version:
MCPS JavaScript SDK
168 lines (156 loc) • 5.38 kB
text/typescript
'use strict';
import { TxModelCreator } from '../helper';
import * as types from '../types';
const Sha256 = require('sha256');
export class ProtoTx {
txData:any;
body:any;
authInfo:any;
signatures:string[] = [];
constructor(properties?:{
msgs:types.Msg[],
memo:string,
stdFee:types.StdFee,
chain_id:string,
account_number?:string,
sequence?:string,
publicKey?:string|types.Pubkey
}, protoTxModel?:any) {
if (!properties && !protoTxModel) {
throw new Error("there must be one properties or protoTxModel");
}
if (properties) {
let {msgs, memo, stdFee, account_number, chain_id, sequence, publicKey} = properties;
this.txData = properties;
this.body = TxModelCreator.createBodyModel(msgs, memo, 0);
this.authInfo = TxModelCreator.createAuthInfoModel(stdFee, sequence, publicKey);
}else if(protoTxModel){
if (protoTxModel.hasBody() && protoTxModel.hasAuthInfo()) {
this.txData = {};
this.body = protoTxModel.getBody();
this.authInfo = protoTxModel.getAuthInfo();
this.signatures = protoTxModel.getSignaturesList();
}
}
}
static newStdTxFromProtoTxModel(protoTxModel:any):types.ProtoTx{
if (!protoTxModel.hasBody() || !protoTxModel.hasAuthInfo()){
throw new Error("Proto Tx Model is invalid");
}
return new ProtoTx( undefined ,protoTxModel);
}
/**
* add signature
* @param {[string]} signature base64
*/
addSignature(signature:string){
if (!signature || !signature.length) {
throw new Error("signature is empty");
}
this.signatures.push(signature);
}
/**
* add public key
* @param {[string]} bech32/hex or object. if string, default Secp256k1
* @param {optional [number]} sequence
*/
setPubKey(pubkey:string|types.Pubkey, sequence?:string){
sequence = sequence || this.txData.sequence;
if (!sequence) {
throw new Error("sequence is empty");
}
let signerInfo = TxModelCreator.createSignerInfoModel(sequence, pubkey);
this.authInfo.addSignerInfos(signerInfo);
}
/**
* Get SignDoc for signature
* @returns SignDoc protobuf.Tx.SignDoc
*/
getSignDoc(account_number?:string, chain_id?:string):any{
if (!this.hasPubKey()) {
throw new Error("please set pubKey");
}
if (!account_number && !this.txData.account_number) {
throw new Error("account_number is empty");
}
if (!chain_id && !this.txData.chain_id) {
throw new Error("chain_id is empty");
}
let signDoc = new types.tx_tx_pb.SignDoc();
signDoc.setBodyBytes(this.body.serializeBinary());
signDoc.setAuthInfoBytes(this.authInfo.serializeBinary());
signDoc.setAccountNumber(Number(account_number || this.txData.account_number));
signDoc.setChainId(chain_id || this.txData.chain_id);
return signDoc;
}
/**
* TxRaw is a variant of Tx that pins the signer's exact binary representation
of body and auth_info. This is used for signing, broadcasting and
verification. The binary `serialize(tx: TxRaw)` is stored in Tendermint and
the hash `sha256(serialize(tx: TxRaw))` becomes the "txhash", commonly used
as the transaction ID.
* @returns TxRaw protobuf.Tx.TxRaw
*/
getTxRaw():any{
if (!this.hasPubKey()) {
throw new Error("please set pubKey");
}
if (!this.signatures || !this.signatures.length) {
throw new Error("please sign tx");
}
let txRaw = new types.tx_tx_pb.TxRaw();
txRaw.setBodyBytes(this.body.serializeBinary());
txRaw.setAuthInfoBytes(this.authInfo.serializeBinary());
this.signatures.forEach((signature)=>{
txRaw.addSignatures(signature);
})
return txRaw;
}
/**
* has PubKey
* @returns true/false
*/
hasPubKey():boolean{
return this.authInfo.getSignerInfosList().length > 0;
}
/**
* Used for RPC send transactions
* You can commit the data directly to RPC
* @returns base64 string
*/
getData():Uint8Array {
let tx = new types.tx_tx_pb.Tx();
tx.setBody(this.body);
tx.setAuthInfo(this.authInfo);
this.signatures.forEach((signature)=>{
tx.addSignatures(signature);
})
return tx.serializeBinary();
}
/**
* get Tx Hash
* @returns tx hash
*/
getTxHash():string{
let txRaw = this.getTxRaw();
let txHash:string = (Sha256(txRaw.serializeBinary()) || '').toUpperCase();
return txHash;
}
getProtoModel():any{
let tx = new types.tx_tx_pb.Tx();
tx.setBody(this.body);
tx.setAuthInfo(this.authInfo);
this.signatures.forEach((signature)=>{
tx.addSignatures(signature);
});
return tx;
}
/**
* get tx content
* @returns tx info
*/
getDisplayContent():string{
let tx = this.getProtoModel();
return JSON.stringify(tx.toObject());
}
}