openchain-sdk-yxl-ts
Version:
OpenChain SDK for browser
243 lines (212 loc) • 6.06 kB
JavaScript
import long from 'long';
import humps from 'humps';
import JSONbig from 'json-bigint';
import errors from '../exception/index.js';
import CommonUtil from '../common/util.js';
class Transaction extends CommonUtil {
constructor(options = {}) {
super(options);
if (!(this instanceof Transaction)) {
return new Transaction(options);
}
}
buildBlob(args) {
try {
if (Array.isArray(args) || typeof args !== 'object' || args === null) {
return this._responseError(errors.INVALID_ARGUMENTS);
}
const schema = {
sourceAddress: {
required: true,
string: true,
address: true,
},
gasPrice: {
required: true,
numeric: true,
},
feeLimit: {
required: true,
numeric: true,
},
nonce: {
required: true,
numeric: true,
},
ceilLedgerSeq: {
required: false,
numeric: true,
},
operations: {
required: true,
operations: true,
},
metadata: {
required: false,
string: true,
}
};
const validation = this._validate(args, schema);
if (!validation.tag) {
return this._responseError(errors[validation.msg]);
}
return this._responseData(this._buildBlob(args));
} catch (err) {
console.error('Error in buildBlob:', err);
throw err;
}
}
sign(args) {
try {
if (Array.isArray(args) || typeof args !== 'object' || args === null) {
return this._responseError(errors.INVALID_ARGUMENTS);
}
const schema = {
privateKeys: {
required: true,
privateKeys: true,
},
blob: {
required: true,
hex: true,
},
};
const validation = this._validate(args, schema);
if (!validation.tag) {
return this._responseError(errors[validation.msg]);
}
return this._responseData(this._signBlob(args));
} catch (err) {
console.error('Error in sign:', err);
throw err;
}
}
async submit(args) {
try {
if (Array.isArray(args) || typeof args !== 'object' || args === null) {
return this._responseError(errors.INVALID_ARGUMENTS);
}
const schema = {
signature: {
required: true,
signatures: true,
},
blob: {
required: true,
hex: true,
},
};
const validation = this._validate(args, schema);
if (!validation.tag) {
return this._responseError(errors[validation.msg]);
}
const decamelizedArgs = humps.decamelizeKeys(args, { separator: '_' });
return await this._submit(decamelizedArgs);
} catch (err) {
console.error('Error in submit:', err);
throw err;
}
}
async evaluateFee(args) {
try {
if (Array.isArray(args) || typeof args !== 'object' || args === null) {
return this._responseError(errors.INVALID_ARGUMENTS);
}
let { sourceAddress, nonce, operations, signtureNumber, metadata, ceilLedgerSeq } = args;
signtureNumber = signtureNumber || '1';
const schema = {
sourceAddress: {
required: true,
string: true,
address: true,
},
nonce: {
required: true,
string: true,
numeric: true,
},
operations: {
required: true,
operations: true,
},
signtureNumber: {
required: false,
string: true,
numeric: true,
},
metadata: {
required: false,
string: true,
},
ceilLedgerSeq: {
required: false,
numeric: true,
},
};
const validation = this._validate(args, schema);
if (!validation.tag) {
return this._responseError(errors[validation.msg]);
}
signtureNumber = signtureNumber || 1;
console.log('signtureNumber', args);
const operationList = operations.map(item => {
const operationItem = this._buildOperation(item.type, item.data);
console.log('operationItem', operationItem);
let operationMsg = humps.decamelizeKeys(operationItem, { separator: '_' });
return this._longToInt(operationMsg);
});
const requestData = {
items: [{
transaction_json: {
source_address: sourceAddress,
metadata,
nonce,
operations: operationList,
ceil_ledger_seq: ceilLedgerSeq,
chain_id: this.options.chainId,
},
}]
};
const data = JSONbig.stringify(requestData);
const response = await this._request('post', 'testTransaction', data);
const info = response;
if (info.error_code === 0) {
if (info.result.txs && info.result.txs.length > 0) {
const fee = info.result.txs[0].transaction_env.transaction;
return this._responseData({
feeLimit: fee.fee_limit,
gasPrice: fee.gas_price,
});
}
}
return {
errorCode: info.error_code,
errorDesc: info.error_desc,
};
} catch (err) {
console.error('Error in evaluateFee:', err);
throw err;
}
}
async getInfo(hash) {
try {
if (typeof hash !== 'string' || this._isEmptyString(hash)) {
return this._responseError(errors.INVALID_HASH_ERROR);
}
const data = await this._request('get', 'getTransactionHistory', {
hash,
});
if (data.error_code === 0) {
return this._responseData(data.result);
}
if (data.error_code === 4) {
return this._responseError(errors.QUERY_RESULT_NOT_EXIST, data.result);
}
return this._responseError(errors.FAIL);
} catch (err) {
console.error('Error in getInfo:', err);
throw err;
}
}
}
export default Transaction;