namillum
Version:
Bubble Protocol SDK
189 lines (163 loc) • 5.4 kB
text/typescript
// import { cloneDeep } from 'lodash';
import BN from "bn.js";
import { RPCMethod } from "@zilliqa-js/core";
export enum TokenFields {
TotalSupply = "total_supply",
Balances = "balances",
}
export enum DexFields {
ZWAPPools = "pools",
ZWAPBalances = "balances",
XCADbalances = "xbalances",
XCADPools = "xpools",
}
export class blockchain {
private _http = `https://api.zilliqa.com/`;
private _zilswap = "459cb2d3baf7e61cfbd5fe362f289ae92b2babb0";
private _xcad = "1fb1a4fd7ba94b1617641d6022ba48cafa77eef0";
private _xcadToken = "0x153feaddc48871108e286de3304b9597c817b456";
private _100 = new BN(100000);
private _zero = new BN(0);
public async getLiquidity(token: string, address: string) {
const batch = [
{
method: RPCMethod.GetSmartContractSubState,
params: [this._zilswap, DexFields.ZWAPPools, [token]],
id: 1,
jsonrpc: `2.0`,
},
{
method: RPCMethod.GetSmartContractSubState,
params: [this._zilswap, DexFields.ZWAPBalances, [token]],
id: 1,
jsonrpc: `2.0`,
},
{
method: RPCMethod.GetSmartContractSubState,
params: [this._xcad, DexFields.XCADPools, []],
id: 1,
jsonrpc: `2.0`,
},
{
method: RPCMethod.GetSmartContractSubState,
params: [
this._xcad,
DexFields.XCADbalances,
[`${this._xcadToken},${token}`],
],
id: 1,
jsonrpc: `2.0`,
},
{
method: RPCMethod.GetSmartContractSubState,
params: [this._toHex(token), TokenFields.Balances, []],
id: 1,
jsonrpc: `2.0`,
},
{
method: RPCMethod.GetSmartContractSubState,
params: [this._toHex(token), TokenFields.TotalSupply, []],
id: 1,
jsonrpc: `2.0`,
},
];
const res = await this._send(batch);
let tokenBalances = res[4]["result"][TokenFields.Balances];
const totalSupply = res[5]["result"][TokenFields.TotalSupply];
tokenBalances = this._parseZilSwap(res, token, tokenBalances);
tokenBalances = this._parseXcad(res, token, tokenBalances);
const userBalance = tokenBalances[address];
return {
balances: tokenBalances,
totalSupply,
userBalance,
};
}
private _parseXcad(res: object[], token: string, tokenBalances: object) {
try {
const xBalance =
res[3]["result"][DexFields.XCADbalances][`${this._xcadToken},${token}`][
this._xcadToken
];
const [, , , tokenReserve] =
res[2]["result"][DexFields.XCADPools][`${this._xcadToken},${token}`][
"arguments"
];
let poolAmount = new BN("0");
let contribution = new BN(tokenReserve);
for (const iterator of Object.values(xBalance)) {
if (typeof iterator === "string") {
const v = new BN(iterator);
poolAmount = poolAmount.add(v);
}
}
for (const key in xBalance) {
if (key in tokenBalances) {
const userContributionbalance = new BN(xBalance[key]);
const contributionPercentage = userContributionbalance
.mul(this._100)
.div(poolAmount);
if (this._zero.eq(contributionPercentage)) {
continue;
}
const userValue = contribution
.mul(contributionPercentage)
.div(this._100);
const currentBalance = new BN(tokenBalances[key]);
tokenBalances[key] = currentBalance.add(userValue).toString();
}
}
} catch (err) {
console.log("parse-xcad", err);
}
return tokenBalances;
}
private _parseZilSwap(res: object[], token: string, tokenBalances: object) {
try {
const [, tokenReserve] =
res[0]["result"][DexFields.ZWAPPools][token]["arguments"];
const zBalance = res[1]["result"][DexFields.ZWAPBalances][token];
let poolAmount = new BN("0");
let contribution = new BN(tokenReserve);
for (const iterator of Object.values(zBalance)) {
if (typeof iterator === "string") {
const v = new BN(iterator);
poolAmount = poolAmount.add(v);
}
}
for (const key in zBalance) {
if (key in tokenBalances) {
const userContributionbalance = new BN(zBalance[key]);
const contributionPercentage = userContributionbalance
.mul(this._100)
.div(poolAmount);
if (this._zero.eq(contributionPercentage)) {
continue;
}
const userValue = contribution
.mul(contributionPercentage)
.div(this._100);
const currentBalance = new BN(tokenBalances[key]);
tokenBalances[key] = currentBalance.add(userValue).toString();
}
}
} catch (err) {
console.log("zilswap-parse", err);
}
return tokenBalances;
}
private _toHex(address: string) {
return String(address).replace("0x", "").toLowerCase();
}
private async _send(batch: object[]) {
const res = await fetch(this._http, {
method: `POST`,
headers: {
"Content-Type": `application/json`,
},
body: JSON.stringify(batch),
});
return res.json();
}
}
// new blockchain().getLiquidity('0xa845c1034cd077bd8d32be0447239c7e4be6cb21', '0x837Eb6850BB3A1172Eb94B557762e474A8e9Ac73'.toLowerCase());