sensible-sdk
Version:
Sensible-SDK
341 lines (340 loc) • 12.9 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetaSV = void 0;
const scryptlib_1 = require("scryptlib");
const error_1 = require("../common/error");
const net_1 = require("../net");
const index_1 = require("./index");
class MetaSV {
constructor(apiNet, serverBase) {
if (apiNet == index_1.API_NET.MAIN) {
this.serverBase = "https://apiv2.metasv.com";
}
else {
throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, "metasv only support mainnet");
}
if (serverBase) {
this.serverBase = serverBase;
}
}
authorize(options) {
const { authorization, privateKey } = options;
if (authorization) {
if (authorization.indexOf("Bearer") != 0) {
this.authorization = `Bearer ${authorization}`;
}
else {
this.authorization = authorization;
}
}
else {
//https://github.com/metasv/metasv-client-signature
this.privateKey = new scryptlib_1.bsv.PrivateKey(privateKey);
this.publicKey = this.privateKey.toPublicKey();
}
}
_getHeaders(path) {
let headers = {};
if (this.authorization) {
headers = { authorization: this.authorization };
}
else if (this.privateKey) {
const timestamp = Date.now();
const nonce = Math.random().toString().substr(2, 10);
const message = path + "_" + timestamp + "_" + nonce;
const hash = scryptlib_1.bsv.crypto.Hash.sha256(Buffer.from(message));
const sig = scryptlib_1.bsv.crypto.ECDSA.sign(hash, this.privateKey);
const sigEncoded = sig.toBuffer().toString("base64");
headers = {
"MetaSV-Timestamp": timestamp,
"MetaSV-Client-Pubkey": this.publicKey.toHex(),
"MetaSV-Nonce": nonce,
"MetaSV-Signature": sigEncoded,
};
}
else {
throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, "MetaSV should be authorized to access api.");
}
return headers;
}
/**
* @param {string} address
*/
getUnspents(address) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/address/${address}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {}, {
headers: this._getHeaders(path),
});
let ret = _res.map((v) => ({
txId: v.txid,
outputIndex: v.outIndex,
satoshis: v.value,
address: address,
}));
return ret;
});
}
/**
* @param {string} hex
*/
broadcast(hex) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/tx/broadcast`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpPost(url, {
hex,
}, {
headers: this._getHeaders(path),
});
return _res.txid;
});
}
/**
* @param {string} txid
*/
getRawTxData(txid) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/tx/${txid}/raw`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {}, {
headers: this._getHeaders(path),
});
return _res.hex;
});
}
/**
* 通过FT合约CodeHash+溯源genesis获取某地址的utxo列表
*/
getFungibleTokenUnspents(codehash, genesis, address, size = 10) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/ft/address/${address}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {
codeHash: codehash,
genesis,
}, {
headers: this._getHeaders(path),
});
let ret = _res.map((v) => ({
txId: v.txid,
outputIndex: v.txIndex,
tokenAddress: address,
tokenAmount: v.valueString,
}));
return ret;
});
}
/**
* 查询某人持有的某FT的余额
*/
getFungibleTokenBalance(codehash, genesis, address) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/ft/address/${address}/balance`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
let ret = {
balance: "0",
pendingBalance: "0",
utxoCount: 0,
decimal: 0,
};
if (_res.length > 0) {
ret = {
balance: _res[0].confirmedString,
pendingBalance: _res[0].unconfirmedString,
utxoCount: _res[0].utxoCount,
decimal: _res[0].decimal,
};
}
return ret;
});
}
/**
* 查询某人持有的FT Token列表。获得每个token的余额
*/
getFungibleTokenSummary(address) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/ft/address/${address}/balance`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
let data = [];
_res.forEach((v) => {
data.push({
codehash: v.codeHash,
genesis: v.genesis,
sensibleId: v.sensibleId,
symbol: v.symbol,
decimal: v.decimal,
balance: v.confirmedString,
pendingBalance: v.unconfirmedString,
});
});
return data;
});
}
/**
* 通过NFT合约CodeHash+溯源genesis获取某地址的utxo列表
*/
getNonFungibleTokenUnspents(codehash, genesis, address, cursor = 0, size = 20) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/nft/address/${address}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, { codeHash: codehash, genesis }, { headers: this._getHeaders(path) });
let ret = _res.map((v) => ({
txId: v.txid,
outputIndex: v.txIndex,
tokenAddress: address,
tokenIndex: v.tokenIndex,
metaTxId: v.metaTxid,
metaOutputIndex: v.metaOutputIndex,
}));
return ret;
});
}
/**
* 查询某人持有的某NFT的UTXO
*/
getNonFungibleTokenUnspentDetail(codehash, genesis, tokenIndex) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/nft/genesis/${codehash}/${genesis}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
let ret = _res.map((v) => ({
txId: v.txid,
outputIndex: v.txIndex,
tokenAddress: v.address,
tokenIndex: v.tokenIndex,
metaTxId: v.metaTxid,
metaOutputIndex: v.metaOutputIndex,
}))[0];
return ret;
});
}
/**
* 查询某人持有的所有NFT Token列表。获得持有的nft数量计数
* @param {String} address
* @returns
*/
getNonFungibleTokenSummary(address) {
return __awaiter(this, void 0, void 0, function* () {
let url = `https://api.sensiblequery.com/nft/summary/${address}`;
let _res = yield net_1.Net.httpGet(url, {});
const { code, data, msg } = _res;
if (code != 0) {
throw new error_1.CodeError(error_1.ErrCode.EC_SENSIBLE_API_ERROR, `request api failed. [url]:${url} [msg]:${msg}`);
}
let ret = [];
data.forEach((v) => {
ret.push({
codehash: v.codehash,
genesis: v.genesis,
sensibleId: v.sensibleId,
count: v.count,
pendingCount: v.pendingCount,
metaTxId: v.metaTxId,
metaOutputIndex: v.metaOutputIndex,
supply: v.supply,
});
});
return ret;
});
}
getBalance(address) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/address/${address}/balance`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {}, {
headers: this._getHeaders(path),
});
return {
balance: _res.confirmed,
pendingBalance: _res.unconfirmed,
};
});
}
getNftSellUtxo(codehash, genesis, tokenIndex) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/nft/sell/genesis/${codehash}/${genesis}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, { tokenIndex }, { headers: this._getHeaders(path) });
let ret = _res
.filter((v) => v.isReady == true)
.map((v) => ({
codehash,
genesis,
tokenIndex,
txId: v.txid,
outputIndex: v.txIndex,
sellerAddress: v.address,
satoshisPrice: v.price,
}))[0];
return ret;
});
}
getNftSellList(codehash, genesis, cursor = 0, size = 20) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/nft/sell/genesis/${codehash}/${genesis}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
let ret = _res
.filter((v) => v.isReady == true)
.map((v) => ({
codehash,
genesis,
tokenIndex: v.tokenIndex,
txId: v.txid,
outputIndex: v.txIndex,
sellerAddress: v.address,
satoshisPrice: v.price,
}))[0];
return ret;
});
}
getNftSellListByAddress(address, cursor = 0, size = 20) {
return __awaiter(this, void 0, void 0, function* () {
let path = `/sensible/nft/sell/address/${address}/utxo`;
let url = this.serverBase + path;
let _res = yield net_1.Net.httpGet(url, {}, { headers: this._getHeaders(path) });
let ret = _res
// .filter((v) => v.isReady == true)
.map((v) => ({
codehash: v.codeHash,
genesis: v.genesis,
tokenIndex: v.tokenIndex,
txId: v.txid,
outputIndex: v.txIndex,
sellerAddress: v.address,
satoshisPrice: v.price,
}));
return ret;
});
}
getOutpointSpent(txId, index) {
return __awaiter(this, void 0, void 0, function* () {
let url = `https://api.sensiblequery.com/tx/${txId}/out/${index}/spent`;
let _res = yield net_1.Net.httpGet(url, {});
const { code, data, msg } = _res;
if (code != 0) {
return null;
}
if (!data)
return null;
return {
spentTxId: data.txid,
spentInputIndex: data.idx,
};
});
}
}
exports.MetaSV = MetaSV;