UNPKG

sensible-sdk

Version:

Sensible-SDK

341 lines (340 loc) 12.9 kB
"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;