revos-sdk-js-mainnet
Version:
revos client and wallet SDK
424 lines (375 loc) • 14.4 kB
JavaScript
;
import axios from "axios";
import Amount from "./amount";
import * as address from "../wallet/address";
import * as errors from "./errors";
import * as transaction from "../wallet/transaction";
import * as util from "./util";
import * as transactionfunc from "../wallet/address";
import * as transactionproto from "../common/pb/transaction_pb";
const rpcTimeout = 10000;
const methods = {
getWsAddr: { method: "getwsaddr" },
getWssAddr: { method: "getwssaddr" },
getSubscribers: {
method: "getsubscribers",
defaultParams: { offset: 0, limit: 1000, meta: false, txPool: false },
},
getSubscribersCount: { method: "getsubscriberscount" },
getSubscription: { method: "getsubscription" },
getBalanceByAddr: { method: "getbalancebyaddr" },
getNeighbor: { method: "getneighbor" },
getRDCBalanceByAddr: { method: "getbalancebyassetid" },
getNonceByAddr: { method: "getnoncebyaddr" },
getRegistrant: { method: "getregistrant" },
getLatestBlockHash: { method: "getlatestblockhash" },
sendRawTransaction: { method: "sendrawtransaction" },
getBlock: { method: "getblock" },
getBlockCount: { method: "getblockcount" },
getLatestBlockHeight: { method: "getlatestblockheight" },
getBlockTxsByHeight: { method: "getblocktxsbyheight" },
getTransaction: { method: "gettransaction" },
};
var rpc = {};
for (let method in methods) {
if (methods.hasOwnProperty(method)) {
rpc[method] = (addr, params) => {
params = util.assignDefined({}, methods[method].defaultParams, params);
return rpcCall(addr, methods[method].method, params);
};
}
}
async function rpcCall(addr, method, params = {}) {
const source = axios.CancelToken.source();
let response = null;
setTimeout(() => {
if (response === null) {
source.cancel("rpc timeout");
}
}, rpcTimeout);
try {
response = await axios({
url: addr,
method: "POST",
timeout: rpcTimeout,
cancelToken: source.token,
data: {
id: "nkn-sdk-js",
jsonrpc: "2.0",
method: method,
params: params,
},
});
} catch (e) {
if (axios.isCancel(e)) {
throw new errors.RpcTimeoutError(e.message);
} else {
throw new errors.RpcError(e.message);
}
}
let data = response.data;
if (data.error) {
throw new errors.ServerError(data.error);
}
if (data.result !== undefined) {
return data.result;
}
throw new errors.InvalidResponseError(
"rpc response contains no result or error field"
);
}
export async function getWsAddr(address, options = {}) {
return rpc.getWsAddr(options.rpcServerAddr, { address });
}
export async function getWssAddr(address, options = {}) {
return rpc.getWssAddr(options.rpcServerAddr, { address });
}
export async function getLatestBlock(options = {}) {
return rpc.getLatestBlockHash(options.rpcServerAddr);
}
export async function getNeighbors(options = {}) {
return rpc.getNeighbor(options.rpcServerAddr);
}
export async function getBlockByHash(hash, options = {}) {
return rpc.getBlock(options.rpcServerAddr, { hash });
}
export async function getBlockByHeight(height, options = {}) {
return rpc.getBlock(options.rpcServerAddr, { height });
}
export async function getBlockTxsByHeight(height, options = {}) {
return rpc.getBlockTxsByHeight(options.rpcServerAddr, { height });
}
export async function getTransaction(hash, options = {}) {
const data = await rpc.getTransaction(options.rpcServerAddr, { hash });
const payLoad = data.payloadData;
const txType = data.txType;
let txData;
let senderAddress;
let amount;
let recipientAddress;
let decodedPayload;
switch (txType) {
case "COINBASE_TYPE":
txData = transactionproto.Coinbase.deserializeBinary(
util.hexToBytes(payLoad)
);
senderAddress = address.programHashStringToAddress(
util.bytesToHex(txData.array[0])
);
const recipient_PoP_ChallengersAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[1]));
const recipient_PoP_ChallengessAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[2]));
const recipient_Revos_Token_Corporate_TreasuryAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[3]));
const recipient_Revos_Token_SalesAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[4]));
const recipient_PoN_Connectivity_UtilizationAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[5]));
const recipient_PoN_Compute_UtilizationAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[6]));
const recipient_PoN_Storage_UtilizationAddress =
address.programHashStringToAddress(util.bytesToHex(txData.array[7]));
amount = txData.array[8];
const amount_PoP_Challengers = txData.array[9];
const amount_PoP_Challengess = txData.array[10];
const amount_Revos_Token_Corporate_Treasury = txData.array[11];
const amount_Revos_Token_Sales = txData.array[12];
const amount_PoN_Connectivity_Utilization = txData.array[13];
const amount_PoN_Compute_Utilization = txData.array[14];
const amount_PoN_Storage_Utilization = txData.array[15];
decodedPayload = {
sender: senderAddress,
recipient_PoP_Challengers: recipient_PoP_ChallengersAddress,
recipient_PoP_Challengess: recipient_PoP_ChallengessAddress,
recipient_Revos_Token_Corporate_Treasury:
recipient_Revos_Token_Corporate_TreasuryAddress,
recipient_Revos_Token_Sales: recipient_Revos_Token_SalesAddress,
recipient_PoN_Connectivity_Utilization:
recipient_PoN_Connectivity_UtilizationAddress,
recipient_PoN_Compute_Utilization:
recipient_PoN_Compute_UtilizationAddress,
recipient_PoN_Storage_Utilization:
recipient_PoN_Storage_UtilizationAddress,
amount,
amount_PoP_Challengers,
amount_PoP_Challengess,
amount_Revos_Token_Corporate_Treasury,
amount_Revos_Token_Sales,
amount_PoN_Connectivity_Utilization,
amount_PoN_Compute_Utilization,
amount_PoN_Storage_Utilization,
};
data.decodedPayload = decodedPayload;
break;
case "TRANSFER_ASSET_TYPE" :
case "TRANSFER_RDC_ASSET_TYPE":
txData = transactionproto.TransferAsset.deserializeBinary(
util.hexToBytes(payLoad)
);
senderAddress = address.programHashStringToAddress(
util.bytesToHex(txData.array[0])
);
recipientAddress = address.programHashStringToAddress(
util.bytesToHex(txData.array[1])
);
amount = txData.array[2];
decodedPayload = {
sender: senderAddress,
recipient: recipientAddress,
amount,
};
data.decodedPayload = decodedPayload;
break;
case "SWAP_ASSET_TYPE" :
case "SWAP_RDC_ASSET_TYPE":
txData = transactionproto.SwapAsset.deserializeBinary(
util.hexToBytes(payLoad)
);
senderAddress = address.programHashStringToAddress(
util.bytesToHex(txData.array[0])
);
recipientAddress = address.programHashStringToAddress(
util.bytesToHex(txData.array[1])
);
amount = txData.array[2];
decodedPayload = {
sender: senderAddress,
recipient: recipientAddress,
amount,
};
data.decodedPayload = decodedPayload;
break;
default:
break;
}
return data;
}
export async function getRegistrant(name, options = {}) {
return rpc.getRegistrant(options.rpcServerAddr, { name });
}
export async function getSubscribers(topic, options = {}) {
return rpc.getSubscribers(options.rpcServerAddr, {
topic,
offset: options.offset,
limit: options.limit,
meta: options.meta,
txPool: options.txPool,
});
}
export async function getSubscribersCount(topic, options = {}) {
return rpc.getSubscribersCount(options.rpcServerAddr, { topic });
}
export async function getSubscription(topic, subscriber, options = {}) {
return rpc.getSubscription(options.rpcServerAddr, { topic, subscriber });
}
export async function getBalance(address, options = {}) {
if (!address) {
throw new errors.InvalidArgumentError("address is empty");
}
let data = await rpc.getBalanceByAddr(options.rpcServerAddr, { address });
if (!data.amount) {
throw new errors.InvalidResponseError("amount is empty");
}
return new Amount(data.amount);
}
export async function getRDCBalance(address, options = {}) {
if (!address) {
throw new errors.InvalidArgumentError("address is empty");
}
let data = await rpc.getRDCBalanceByAddr(options.rpcServerAddr, { address });
if (!data.amount) {
throw new errors.InvalidResponseError("amount is empty");
}
return new Amount(data.amount);
}
export async function getNonce(address, options = {}) {
if (!address) {
throw new errors.InvalidArgumentError("address is empty");
}
options = util.assignDefined({ txPool: true }, options);
let data = await rpc.getNonceByAddr(options.rpcServerAddr, { address });
if (typeof data.nonce !== "number") {
throw new errors.InvalidResponseError("nonce is not a number");
}
let nonce = data.nonce;
if (options.txPool && data.nonceInTxPool && data.nonceInTxPool > nonce) {
nonce = data.nonceInTxPool;
}
return nonce;
}
export async function sendTransaction(txn, options = {}) {
return rpc.sendRawTransaction(options.rpcServerAddr, {
tx: util.bytesToHex(txn.serializeBinary()),
});
}
export async function transferTo(toAddress, amount, options = {}) {
if (!address.verifyAddress(toAddress)) {
throw new errors.InvalidAddressError("invalid recipient address");
}
let nonce = options.nonce || (await this.getNonce());
let signatureRedeem = address.publicKeyToSignatureRedeem(this.getPublicKey());
let programHash = address.hexStringToProgramHash(signatureRedeem);
let pld = transaction.newTransferPayload(
programHash,
address.addressStringToProgramHash(toAddress),
amount
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function transferRDCTo(toAddress, amount, options = {}) {
if (!address.verifyAddress(toAddress)) {
throw new errors.InvalidAddressError("invalid recipient address");
}
let nonce = options.nonce || (await this.getNonce());
let signatureRedeem = address.publicKeyToSignatureRedeem(this.getPublicKey());
let programHash = address.hexStringToProgramHash(signatureRedeem);
let pld = transaction.newRDCTransferPayload(
programHash,
address.addressStringToProgramHash(toAddress),
amount
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function swap(toAddress, amount, options = {}) {
if (!address.verifyAddress(toAddress)) {
throw new errors.InvalidAddressError("invalid recipient address");
}
let nonce = options.nonce || (await this.getNonce());
let signatureRedeem = address.publicKeyToSignatureRedeem(this.getPublicKey());
let programHash = address.hexStringToProgramHash(signatureRedeem);
let pld = transaction.newSwapPayload(
programHash,
address.addressStringToProgramHash(toAddress),
amount
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function swapRDC(toAddress, amount, options = {}) {
if (!address.verifyAddress(toAddress)) {
throw new errors.InvalidAddressError("invalid recipient address");
}
let nonce = options.nonce || (await this.getNonce());
let signatureRedeem = address.publicKeyToSignatureRedeem(this.getPublicKey());
let programHash = address.hexStringToProgramHash(signatureRedeem);
let pld = transaction.newRDCSwapPayload(
programHash,
address.addressStringToProgramHash(toAddress),
amount
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function registerName(name, options = {}) {
let nonce = options.nonce || (await this.getNonce());
let pld = transaction.newRegisterNamePayload(this.getPublicKey(), name);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function transferName(name, recipient, options = {}) {
let nonce = options.nonce || (await this.getNonce());
let pld = transaction.newTransferNamePayload(
name,
this.getPublicKey(),
recipient
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function deleteName(name, options = {}) {
let nonce = options.nonce || (await this.getNonce());
let pld = transaction.newDeleteNamePayload(this.getPublicKey(), name);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function subscribe(
topic,
duration,
identifier,
meta,
options = {}
) {
let nonce = options.nonce || (await this.getNonce());
let pld = transaction.newSubscribePayload(
this.getPublicKey(),
identifier,
topic,
duration,
meta
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}
export async function unsubscribe(topic, identifier, options = {}) {
let nonce = options.nonce || (await this.getNonce());
let pld = transaction.newUnsubscribePayload(
this.getPublicKey(),
identifier,
topic
);
let txn = await this.createTransaction(pld, nonce, options);
return options.buildOnly ? txn : await this.sendTransaction(txn);
}