Skip to content

Commit

Permalink
Update SLP balanced endpoints for vastly improved peformance.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Cardona committed Feb 16, 2019
1 parent 0e235bb commit 7d97568
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 683 deletions.
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const repl = require("repl")
const SLP = require("./lib/SLP").default
const clone = require("git-clone")

program.version("1.2.0", "-v, --version")
program.version("1.2.2", "-v, --version")

program
.command("new <name>")
Expand Down
1 change: 1 addition & 0 deletions lib/Address.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
}
};
Object.defineProperty(exports, "__esModule", { value: true });
// require deps
var BITBOXAddress = require("bitbox-sdk/lib/Address").default;
var BITBOXSDK = require("bitbox-sdk/lib/bitbox-sdk").default;
var BITBOX = new BITBOXSDK();
Expand Down
133 changes: 26 additions & 107 deletions lib/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
Object.defineProperty(exports, "__esModule", { value: true });
// require deps
var BITBOXSDK = require("bitbox-sdk/lib/bitbox-sdk").default;
var utils = require("slpjs").Utils;
var slpjs = require("slpjs");
//const slpjs = require("../../slpjs")
var BigNumber = require("bignumber.js");
var axios_1 = require("axios");
// Used for debugging and iterrogating JS objects.
var util = require("util");
Expand Down Expand Up @@ -80,130 +77,52 @@ var Utils = /** @class */ (function () {
});
});
};
// Get raw SLP balances and utxos from the REST server.
// This function was created to faciliate unit and integration tests.
Utils.prototype.slpBalancesUtxos = function (bitboxNetwork, addr) {
return __awaiter(this, void 0, void 0, function () {
var balances;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, bitboxNetwork.getAllSlpBalancesAndUtxos(addy.toSLPAddress(addr))];
case 1:
balances = _a.sent();
return [2 /*return*/, balances];
}
});
});
};
// Retrieve token metadata from the REST server using an input array of txids
// This function was created to faciliate unit and integration tests.
Utils.prototype.getTokenMetadata = function (keys, bitboxNetwork, balances) {
return __awaiter(this, void 0, void 0, function () {
var axiosPromises, axiosResult;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
axiosPromises = keys.map(function (key) { return __awaiter(_this, void 0, void 0, function () {
var tokenMetadata;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, bitboxNetwork.getTokenInformation(key)];
case 1:
tokenMetadata = _a.sent();
return [2 /*return*/, {
tokenId: key,
balance: balances.slpTokenBalances[key]
.div(Math.pow(10, tokenMetadata.decimals))
.toString(),
decimalCount: tokenMetadata.decimals
}];
}
});
}); });
return [4 /*yield*/, axios_1.default.all(axiosPromises)];
case 1:
axiosResult = _a.sent();
return [2 /*return*/, axiosResult];
}
});
});
};
// Retrieve token balances for a given address.
Utils.prototype.balancesForAddress = function (address) {
return __awaiter(this, void 0, void 0, function () {
var network, tmpBITBOX, getRawTransactions, slpValidator, bitboxNetwork, balances, keys, tokenMeta;
var _this = this;
var path, response, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
network = addy.detectAddressNetwork(address);
// Determine network (mainnet or testnet)
if (network === "mainnet") {
tmpBITBOX = new BITBOXSDK({ restURL: "https://rest.bitcoin.com/v2/" });
}
else {
tmpBITBOX = new BITBOXSDK({ restURL: "https://trest.bitcoin.com/v2/" });
}
getRawTransactions = function (txids) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, tmpBITBOX.RawTransactions.getRawTransaction(txids)];
case 1: return [2 /*return*/, _a.sent()];
}
});
}); };
slpValidator = new slpjs.LocalValidator(tmpBITBOX, getRawTransactions);
bitboxNetwork = new slpjs.BitboxNetwork(tmpBITBOX, slpValidator);
return [4 /*yield*/, this.slpBalancesUtxos(bitboxNetwork, address)
// Get the TXIDs for tokens associated with this address.
];
path = this.restURL + "slp/balancesForAddress/" + address;
_a.label = 1;
case 1:
balances = _a.sent();
keys = Object.keys(balances.slpTokenBalances);
return [4 /*yield*/, this.getTokenMetadata(keys, bitboxNetwork, balances)];
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default.get(path)];
case 2:
tokenMeta = _a.sent();
return [2 /*return*/, tokenMeta];
response = _a.sent();
return [2 /*return*/, response.data];
case 3:
error_2 = _a.sent();
if (error_2.response && error_2.response.data)
throw error_2.response.data;
throw error_2;
case 4: return [2 /*return*/];
}
});
});
};
// Retrieve a balance for a specific address and token ID
Utils.prototype.balance = function (address, tokenId) {
return __awaiter(this, void 0, void 0, function () {
var network, tmpBITBOX, getRawTransactions, slpValidator, bitboxNetwork, balances, tokenMeta;
var _this = this;
var path, response, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
network = addy.detectAddressNetwork(address);
// Determine network (mainnet or testnet)
if (network === "mainnet") {
tmpBITBOX = new BITBOXSDK({ restURL: "https://rest.bitcoin.com/v2/" });
}
else {
tmpBITBOX = new BITBOXSDK({ restURL: "https://trest.bitcoin.com/v2/" });
}
getRawTransactions = function (txids) { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, tmpBITBOX.RawTransactions.getRawTransaction(txids)];
case 1: return [2 /*return*/, _a.sent()];
}
});
}); };
slpValidator = new slpjs.LocalValidator(tmpBITBOX, getRawTransactions);
bitboxNetwork = new slpjs.BitboxNetwork(tmpBITBOX, slpValidator);
return [4 /*yield*/, this.slpBalancesUtxos(bitboxNetwork, address)
// Get the metadata for this single token.
];
path = this.restURL + "slp/balance/" + address + "/" + tokenId;
_a.label = 1;
case 1:
balances = _a.sent();
return [4 /*yield*/, this.getTokenMetadata([tokenId], bitboxNetwork, balances)];
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, axios_1.default.get(path)];
case 2:
tokenMeta = _a.sent();
return [2 /*return*/, tokenMeta[0]];
response = _a.sent();
return [2 /*return*/, response.data];
case 3:
error_3 = _a.sent();
if (error_3.response && error_3.response.data)
throw error_3.response.data;
throw error_3;
case 4: return [2 /*return*/];
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "slp-sdk",
"version": "1.2.1",
"version": "1.2.2",
"description": "SLP SDK powered by BITBOX",
"main": "index.js",
"scripts": {
"build": "node ./node_modules/gulp/bin/gulp.js build && ./node_modules/typescript/bin/tsc",
"test": "TEST=unit nyc --reporter=text mocha --require babel-core/register --timeout 300000 test/",
"test:integration": "TEST=integration nyc --reporter=text mocha --require babel-core/register --timeout 300000 test/",
"test": "TEST=unit nyc --reporter=text mocha --require babel-core/register --timeout 10000 test/",
"test:integration": "TEST=integration nyc --reporter=text mocha --require babel-core/register --timeout 10000 test/",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"coverage:report": "nyc --reporter=html mocha --require babel-core/register --timeout 10000",
"semantic-release": "semantic-release"
Expand Down
1 change: 1 addition & 0 deletions src/Address.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// require deps
const BITBOXAddress = require("bitbox-sdk/lib/Address").default
const BITBOXSDK = require("bitbox-sdk/lib/bitbox-sdk").default
const BITBOX = new BITBOXSDK()
Expand Down
111 changes: 14 additions & 97 deletions src/Utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// require deps
const BITBOXSDK = require("bitbox-sdk/lib/bitbox-sdk").default
const utils = require("slpjs").Utils
const slpjs = require("slpjs")
//const slpjs = require("../../slpjs")
const BigNumber: any = require("bignumber.js")
import axios from "axios"

// Used for debugging and iterrogating JS objects.
Expand Down Expand Up @@ -36,110 +33,30 @@ class Utils {
}
}

// Get raw SLP balances and utxos from the REST server.
// This function was created to faciliate unit and integration tests.
async slpBalancesUtxos(bitboxNetwork: any, addr: any) {
let balances: any = await bitboxNetwork.getAllSlpBalancesAndUtxos(
addy.toSLPAddress(addr)
)

return balances
}

// Retrieve token metadata from the REST server using an input array of txids
// This function was created to faciliate unit and integration tests.
async getTokenMetadata(
keys: Array<string>,
bitboxNetwork: any,
balances: any
) {
const axiosPromises = keys.map(async (key: any) => {
let tokenMetadata: any = await bitboxNetwork.getTokenInformation(key)

return {
tokenId: key,
balance: balances.slpTokenBalances[key]
.div(10 ** tokenMetadata.decimals)
.toString(),
decimalCount: tokenMetadata.decimals
}
})

// Wait for all parallel promises to return.
const axiosResult: Array<any> = await axios.all(axiosPromises)

return axiosResult
}

// Retrieve token balances for a given address.
async balancesForAddress(address: string): Promise<Object> {
let network: string = addy.detectAddressNetwork(address)
let tmpBITBOX: any

// Determine network (mainnet or testnet)
if (network === "mainnet") {
tmpBITBOX = new BITBOXSDK({ restURL: "https://rest.bitcoin.com/v2/" })
} else {
tmpBITBOX = new BITBOXSDK({ restURL: "https://trest.bitcoin.com/v2/" })
}
let path: string = `${this.restURL}slp/balancesForAddress/${address}`

const getRawTransactions = async (txids: any) => {
return await tmpBITBOX.RawTransactions.getRawTransaction(txids)
try {
const response = await axios.get(path)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
throw error
}

// Instantiate a local SLP TX validator
const slpValidator: any = new slpjs.LocalValidator(
tmpBITBOX,
getRawTransactions
)

// Get raw SLP information for this address.
const bitboxNetwork: any = new slpjs.BitboxNetwork(tmpBITBOX, slpValidator)
let balances: any = await this.slpBalancesUtxos(bitboxNetwork, address)

// Get the TXIDs for tokens associated with this address.
let keys: Array<string> = Object.keys(balances.slpTokenBalances)

// Retrieve the token metadata for the TXIDs.
const tokenMeta = await this.getTokenMetadata(keys, bitboxNetwork, balances)

return tokenMeta
}

// Retrieve a balance for a specific address and token ID
async balance(address: string, tokenId: string): Promise<Object> {
let network: string = addy.detectAddressNetwork(address)
let tmpBITBOX: any
let path: string = `${this.restURL}slp/balance/${address}/${tokenId}`

// Determine network (mainnet or testnet)
if (network === "mainnet") {
tmpBITBOX = new BITBOXSDK({ restURL: "https://rest.bitcoin.com/v2/" })
} else {
tmpBITBOX = new BITBOXSDK({ restURL: "https://trest.bitcoin.com/v2/" })
}

const getRawTransactions = async (txids: any) => {
return await tmpBITBOX.RawTransactions.getRawTransaction(txids)
try {
const response = await axios.get(path)
return response.data
} catch (error) {
if (error.response && error.response.data) throw error.response.data
throw error
}

// Instantiate a local SLP TX validator
const slpValidator: any = new slpjs.LocalValidator(
tmpBITBOX,
getRawTransactions
)

// Get raw SLP information for this address.
const bitboxNetwork: any = new slpjs.BitboxNetwork(tmpBITBOX, slpValidator)
let balances: any = await this.slpBalancesUtxos(bitboxNetwork, address)

// Get the metadata for this single token.
const tokenMeta = await this.getTokenMetadata(
[tokenId],
bitboxNetwork,
balances
)

return tokenMeta[0]
}

async validateTxid(
Expand Down
Loading

0 comments on commit 7d97568

Please sign in to comment.