nerve-sdk-js
Version:
nerve nerve-js nerve-sdk nerve-js-sdk
592 lines (556 loc) • 18.9 kB
JavaScript
const http = require('./https.js');
const sdk = require('../../api/sdk');
const cryptos = require("crypto");
const numberUtil = require("../../utils/numberUtil");
module.exports = {
/**
* 判断是否为主网
* @param chainId
**/
isMainNet(chainId) {
if (chainId === 2) {
return true;
}
return false;
},
/**
* 计算手续费
* @param tx
* @param signatrueCount 签名数量,默认为1
**/
countFee(tx, signatrueCount) {
let txSize = tx.txSerialize().length;
txSize += signatrueCount * 110;
return 100000 * Math.ceil(txSize / 1024);
},
/**
* 计算跨链交易手续费
* @param tx
* @param signatrueCount 签名数量,默认为1
**/
countCtxFee(tx, signatrueCount) {
let txSize = tx.txSerialize().length;
txSize += signatrueCount * 110;
return 1000000 * Math.ceil(txSize / 1024);
},
/**
* 获取inputs 、 outputs
* @param transferInfo
* @param balanceInfo
* @param type
* @returns {*}
*/
mutiInputsOrOutputs(transferInfo, balanceInfo, type) {
let newAmount = numberUtil.Plus(transferInfo.from.amount, transferInfo.fee);
let newLocked = 0;
let newNonce = balanceInfo.nonce;
if (numberUtil.isLessThan(balanceInfo.balance, newAmount)) {
return {success: false, data: "Your balance is not enough."}
}
let inputs = [{
address: transferInfo.from.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newAmount,
locked: newLocked,
nonce: newNonce
}];
let outputs = [];
for (let i = 0; i < transferInfo.to.length; i++) {
let to = transferInfo.to[i];
outputs.push({
address: to.toAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: to.amount,
lockTime: to.lockTime ? to.lockTime : 0
})
}
return {success: true, data: {inputs: inputs, outputs: outputs}};
},
/**
* 获取inputs 、 outputs
* @param transferInfo
* @param balanceInfo
* @param type 2:转账 4:创建节点 5:加入staking 6:退出staking 9:注销节点 28:追加保证金 29:退出保证金
* @returns {*}
*/
inputsOrOutputs(transferInfo, balanceInfo, type) {
transferInfo.amount = numberUtil.instance(transferInfo.amount).toFixed();
transferInfo.fee = numberUtil.instance(transferInfo.fee).toFixed();
let newAmount = numberUtil.Plus(transferInfo.amount, transferInfo.fee);
let newLocked = 0;
let newNonce = balanceInfo.nonce;
let newoutputAmount = numberUtil.instance(transferInfo.amount);
let newLockTime = 0;
let inputs = [];
let outputs = [];
if (type === 4) {
newLockTime = -1;
} else if (type === 5) {
if (transferInfo.defaultAssetsInfo) { // 加入的资产不是nvt input组装两个
let newArr = {
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
locked: 0,
nonce: balanceInfo.nonce
};
inputs.push(newArr);
let feeArr = {
address: transferInfo.fromAddress,
assetsChainId: transferInfo.defaultAssetsInfo.chainId,
assetsId: transferInfo.defaultAssetsInfo.assetsId,
amount: transferInfo.fee,
locked: 0,
nonce: transferInfo.feeBalanceInfo.nonce
};
inputs.push(feeArr);
} else { // 加入的资产是nvt 合并amount+fee
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newAmount.toFixed(),
locked: 0,
nonce: balanceInfo.nonce
});
}
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
lockTime: transferInfo.locked
});
return {success: true, data: {inputs: inputs, outputs: outputs}};
} else if (type === 6) {
if (transferInfo.defaultAssetsInfo) { // 加入的资产不是nvt input组装两个
let newArr = {
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
locked: -1,
nonce: balanceInfo.nonce
};
inputs.push(newArr);
let feeArr = {
address: transferInfo.fromAddress,
assetsChainId: transferInfo.defaultAssetsInfo.chainId,
assetsId: transferInfo.defaultAssetsInfo.assetsId,
amount: transferInfo.fee,
locked: -1,
nonce: transferInfo.feeBalanceInfo.nonce
};
inputs.push(feeArr);
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
lockTime: 0
});
} else { // 加入的资产是nvt 合并amount+fee
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
locked: -1,
nonce: balanceInfo.nonce
});
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: numberUtil.Minus(transferInfo.amount, transferInfo.fee).toFixed(),
lockTime: 0
});
}
return {success: true, data: {inputs: inputs, outputs: outputs}};
} else if (type === 9) { //注销节点
newoutputAmount = numberUtil.Minus(transferInfo.amount, transferInfo.fee);
let times = (new Date()).valueOf() + 3600000 * 72;//锁定三天
newLockTime = Number(times.toString().substr(0, times.toString().length - 3));
for (let item of transferInfo.nonceList) {
let newArr = {
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: item.deposit,
locked: -1,
nonce: item.nonce
};
inputs.push(newArr)
}
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newoutputAmount.toFixed(),
lockTime: newLockTime
});
return {success: true, data: {inputs: inputs, outputs: outputs}};
} else if (type === 28) { //追加保证金
newLockTime = -1;
} else if (type === 29) { //退出保证金
newoutputAmount = numberUtil.Minus(transferInfo.amount, transferInfo.fee);
//锁定三天
let times = (new Date()).valueOf() + 3600000 * 72;
newLockTime = Number(times.toString().substr(0, times.toString().length - 3));
for (let item of transferInfo.nonceList) {
let newArr = {
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: item.deposit,
locked: -1,
nonce: item.nonce
};
inputs.push(newArr)
}
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newoutputAmount.toFixed(),
lockTime: newLockTime
});
let allAmount = 0;
for (let item of transferInfo.nonceList) {
// allAmount = allAmount + Number(item.deposit);
allAmount = numberUtil.Plus(allAmount, item.deposit);
}
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: numberUtil.Minus(allAmount, transferInfo.amount).toFixed(),
lockTime: -1
});
return {success: true, data: {inputs: inputs, outputs: outputs}};
}
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newAmount.toFixed(),
locked: newLocked,
nonce: newNonce
});
outputs.push({
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newoutputAmount.toFixed(),
lockTime: newLockTime
});
/*console.log(inputs);
console.log(outputs);*/
return {success: true, data: {inputs: inputs, outputs: outputs}};
},
/**
* 获取跨链交易inputs 、 outputs
* @param transferInfo
* @param balanceInfo
* @param chainId
* @returns {*}
*/
async ctxInputsOrOutputs(transferInfo, balanceInfo, chainId) {
let inputs = [];
let outputs = [{
address: transferInfo.toAddress ? transferInfo.toAddress : transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
lockTime: 0
}];
let mainNetBalanceInfo = await this.getBalance(chainId, 2, 1, transferInfo.fromAddress);
let localBalanceInfo;
//如果不是主网需要收取NULS手续费
if (!isMainNet(chainId)) {
if (mainNetBalanceInfo.balance < transferInfo.fee) {
console.log("余额不足");
return;
}
}
//如果转出资产为本链主资产,则直接将手续费加到转出金额上
if (chainId === transferInfo.assetsChainId && transferInfo.assetsId === 1) {
let newAmount = transferInfo.amount + transferInfo.fee;
if (balanceInfo.balance < transferInfo.amount + transferInfo.fee) {
console.log("余额不足");
return;
}
//转出的本链资产 = 转出资产amount + 本链手续费
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newAmount,
locked: 0,
nonce: balanceInfo.nonce
});
//如果不是主网需收取主网NULS手续费
if (!isMainNet(chainId)) {
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: 2,
assetsId: 1,
amount: transferInfo.fee,
locked: 0,
nonce: mainNetBalanceInfo.nonce
});
}
} else {
localBalanceInfo = await this.getBalance(chainId, chainId, 1, transferInfo.fromAddress);
if (localBalanceInfo.balance < transferInfo.fee) {
console.log("该账户本链主资产不足够支付手续费!");
return;
}
//如果转出的是NULS,则需要把NULS手续费添加到转出金额上
if (transferInfo.assetsChainId === 2 && transferInfo.assetsId === 1) {
let newAmount = transferInfo.amount + transferInfo.fee;
if (mainNetBalanceInfo.balance < newAmount) {
console.log("余额不足");
return;
}
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: newAmount,
locked: 0,
nonce: mainNetBalanceInfo.nonce
});
} else {
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: transferInfo.assetsChainId,
assetsId: transferInfo.assetsId,
amount: transferInfo.amount,
locked: 0,
nonce: balanceInfo.nonce
});
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: 2,
assetsId: 1,
amount: transferInfo.fee,
locked: 0,
nonce: mainNetBalanceInfo.nonce
});
}
//本链主资产手续费
if (!isMainNet(chainId)) {
inputs.push({
address: transferInfo.fromAddress,
assetsChainId: chainId,
assetsId: 1,
amount: transferInfo.fee,
locked: 0,
nonce: localBalanceInfo.nonce
});
}
}
return {success: true, data: {inputs: inputs, outputs: outputs}};
},
/**
* 获取账户的余额及nonce
* @param address
* @param chainId
* @param assetChainId
* @param assetId
* @returns {Promise<AxiosResponse<any>>}
*/
async getBalance(chainId, assetChainId = 5, assetId = 1, address) {
return await http.postComplete('/', 'getAccountBalance', [chainId, assetChainId, assetId, address])
.then((response) => {
//console.log(response);
return {'balance': response.result.balance, 'nonce': response.result.nonce};
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 获取账户的余额及nonce
* @param address
* @returns {Promise<AxiosResponse<any>>}
*/
async getNulsBalance(address, chainId = 5, assetId = 1) {
return await http.post('/', 'getAccountBalance', [chainId, assetId, address])
.then((response) => {
//console.log(response);
if (response.hasOwnProperty("result")) {
return {success: true, data: {balance: response.result.balance, nonce: response.result.nonce}}
} else {
throw "Get balance error"
// return {success: false, data: response}
}
})
.catch((error) => {
// console.log(error)
throw "Network error"
// return {success: false, data: error};
});
},
/**
* 验证交易
* @param txHex
* @returns {Promise<AxiosResponse<any>>}
*/
async validateTx(txHex) {
return await http.post('/', 'validateTx', [txHex])
.then((response) => {
//console.log(response);
if (response.hasOwnProperty("result")) {
return {success: true, data: response.result};
} else {
return {success: false, error: response.error};
}
})
.catch((error) => {
return {success: false, error: error};
});
},
/**
* 获取所有地址前缀映射关系
* @returns {Promise<AxiosResponse<any>>}
*/
async getAllAddressPrefix() {
return await http.post('/', 'getAllAddressPrefix', [])
.then((response) => {
console.log(response);
if (response.hasOwnProperty("result")) {
let data = {};
for (var i = 0; i < response.result.length; i++) {
data[response.result[i].chainId] = response.result[i].addressPrefix
}
return {success: true, data: data};
} else {
return {success: false, data: response.error};
}
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 获取所有可用于swap交易的稳定币交易池
* @returns {Promise<AxiosResponse<any>>}
*/
async getStablePairListForSwapTrade() {
return await http.post('/', 'getStablePairListForSwapTrade', [])
.then((response) => {
console.log(response);
if (response.hasOwnProperty("result")) {
return {success: true, data: response.result};
} else {
return {success: false, data: response.error};
}
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 广播交易
* @param txHex
* @returns {Promise<AxiosResponse<any>>}
*/
async broadcastTx(txHex) {
return await http.post('/', 'broadcastTx', [txHex])
.then((response) => {
if (response.hasOwnProperty("result")) {
return response.result;
} else {
return response.error;
}
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 跨链交易广播
* @param txHex
* @returns {Promise<AxiosResponse<any>>}
*/
async sendCrossTx(txHex) {
return await http.post('/', 'sendCrossTx', [8, txHex])
.then((response) => {
console.log(response);
return response.result;
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 获取节点详细信息
* @param agentHash
* @returns {Promise<AxiosResponse<any>>}
*/
async getConsensusNode(agentHash) {
return await http.post('/', 'getConsensusNode', [agentHash])
.then((response) => {
if (response.hasOwnProperty('result')) {
return {success: true, data: response.result}
} else {
return {success: false, data: response}
}
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 查询资产的USD价格
* @returns {Promise<AxiosResponse<any>>}
*/
async getSymbolPriceOfUsdt(chainId, assetId, assetType = '') {
return await http.postComplete('/', 'getQuotationUsdtPrice', [chainId, assetId, assetType])
// return await http.postComplete('/', 'getBestSymbolPrice', [chainId, assetId, assetType])
.then((response) => {
if (response.hasOwnProperty("result")) {
return response.result;
} else {
return response.error;
}
})
.catch((error) => {
return {success: false, data: error};
});
},
/**
* 返回异构链主资产在NERVE网络的资产信息
*/
async getHeterogeneousMainAsset(htgChainId) {
return await http.postComplete('/', 'getHeterogeneousMainAsset', [htgChainId])
.then((response) => {
if (response.hasOwnProperty("result")) {
return response.result;
} else {
return response.error;
}
})
.catch((error) => {
return {success: false, data: error};
});
},
async getMinimumFeeOfWithdrawal(htgChainId, nerveTxHash) {
return await http.postComplete('/', 'getMinimumFeeOfWithdrawal', [htgChainId, nerveTxHash])
.then((response) => {
if (response.hasOwnProperty("result")) {
return response.result;
} else {
return response.error;
}
})
.catch((error) => {
return {success: false, data: error};
});
},
};