metal-presale
Version:
SDK for Metal Presales - Client and Server utilities
169 lines (168 loc) • 5.78 kB
JavaScript
var N = /* @__PURE__ */ ((e) => (e.NETWORK_ERROR = "NETWORK_ERROR", e.TIMEOUT = "TIMEOUT", e.UNAUTHORIZED = "UNAUTHORIZED", e.FORBIDDEN = "FORBIDDEN", e.NOT_FOUND = "NOT_FOUND", e.RATE_LIMITED = "RATE_LIMITED", e.INSUFFICIENT_BALANCE = "INSUFFICIENT_BALANCE", e.PRESALE_ENDED = "PRESALE_ENDED", e.PRESALE_NOT_STARTED = "PRESALE_NOT_STARTED", e.PRESALE_FULL = "PRESALE_FULL", e.INVALID_AMOUNT = "INVALID_AMOUNT", e.TOKEN_LOCKED = "TOKEN_LOCKED", e.UNKNOWN = "UNKNOWN", e))(N || {});
class T extends Error {
constructor(s, t, n, r) {
super(t), this.code = s, this.statusCode = n, this.details = r, this.name = "MetalError";
}
static fromResponse(s, t) {
var f, a, i, u, o;
let n = "UNKNOWN", r = "An unknown error occurred";
switch (s.status) {
case 401:
n = "UNAUTHORIZED", r = "Invalid API key";
break;
case 403:
n = "FORBIDDEN", r = "Access forbidden";
break;
case 404:
n = "NOT_FOUND", r = "Resource not found";
break;
case 429:
n = "RATE_LIMITED", r = "Rate limit exceeded";
break;
case 400:
(f = t == null ? void 0 : t.error) != null && f.includes("insufficient balance") ? (n = "INSUFFICIENT_BALANCE", r = "Insufficient balance") : (a = t == null ? void 0 : t.error) != null && a.includes("presale ended") ? (n = "PRESALE_ENDED", r = "Presale has ended") : (i = t == null ? void 0 : t.error) != null && i.includes("presale not started") ? (n = "PRESALE_NOT_STARTED", r = "Presale has not started") : (u = t == null ? void 0 : t.error) != null && u.includes("presale full") ? (n = "PRESALE_FULL", r = "Presale target reached") : (o = t == null ? void 0 : t.error) != null && o.includes("invalid amount") ? (n = "INVALID_AMOUNT", r = t.error) : t != null && t.error && (r = t.error);
break;
default:
s.status >= 500 && (r = "Server error");
}
return new T(n, r, s.status, t);
}
isRetryable() {
return [
"NETWORK_ERROR",
"TIMEOUT",
"RATE_LIMITED"
/* RATE_LIMITED */
].includes(this.code) || this.statusCode !== void 0 && this.statusCode >= 500;
}
}
const A = 3, O = 1e3;
async function R(e) {
return new Promise((s) => setTimeout(s, e));
}
async function m(e, s = {}) {
const {
retries: t = A,
retryDelay: n = O,
...r
} = s;
let f;
for (let a = 0; a <= t; a++)
try {
const i = `https://api.metal.build${e}`, u = {
"Content-Type": "application/json",
...r.headers
}, o = await fetch(i, {
...r,
headers: u
});
if (!o.ok) {
let c;
try {
c = await o.json();
} catch {
}
const l = T.fromResponse(o, c);
if (l.isRetryable() && a < t) {
f = l, await R(n * Math.pow(2, a));
continue;
}
throw l;
}
const E = await o.json();
if ("success" in E && E.success === !1)
throw new T(
N.UNKNOWN,
"Metal API request failed",
o.status,
E
);
return E;
} catch (i) {
if (i instanceof T)
throw i;
const u = new T(
N.NETWORK_ERROR,
i instanceof Error ? i.message : "Network error"
);
if (a < t) {
f = u, await R(n * Math.pow(2, a));
continue;
}
throw u;
}
throw f || new T(N.UNKNOWN, "Unknown error after retries");
}
async function D(e, s) {
return m(`/holder/${e}?publicKey=${s}`);
}
async function I(e, s) {
return m(`/token/presales/${e}?publicKey=${s}`);
}
function U(e) {
var a, i, u, o, E;
const s = (a = e.tokens) == null ? void 0 : a.find((c) => c.symbol === "USDC"), t = (s == null ? void 0 : s.balance) || 0, n = ((u = (i = e.tokens) == null ? void 0 : i.filter((c) => c.symbol !== "USDC")) == null ? void 0 : u.reduce((c, l) => c + l.value, 0)) || 0, r = ((o = e.locks) == null ? void 0 : o.reduce((c, l) => c + l.value, 0)) || 0, f = ((E = e.presales) == null ? void 0 : E.reduce((c, l) => c + l.value, 0)) || 0;
return {
totalValue: e.totalValue || 0,
buyingPower: t,
holdings: n,
vaulted: r,
presaleValue: f,
tokens: e.tokens || [],
presales: e.presales || [],
vaults: e.locks || []
};
}
function L(e) {
const s = Date.now(), t = e.startTimestamp * 1e3, n = e.endTimestamp * 1e3;
return e.status === "active" && s >= t && s <= n && e.purchasedUsdcAmount < e.targetUsdcAmount;
}
function h(e) {
if (e.targetUsdcAmount === 0) return 0;
const s = e.purchasedUsdcAmount / e.targetUsdcAmount * 100;
return Math.min(s, 100);
}
function _(e) {
const s = Date.now(), n = e.endTimestamp * 1e3 - s;
return Math.max(n, 0);
}
function w(e) {
if (e <= 0) return "Ended";
const s = Math.floor(e / 1e3), t = Math.floor(s / 60), n = Math.floor(t / 60), r = Math.floor(n / 24);
return r > 0 ? `${r} day${r !== 1 ? "s" : ""} remaining` : n > 0 ? `${n} hour${n !== 1 ? "s" : ""} remaining` : t > 0 ? `${t} minute${t !== 1 ? "s" : ""} remaining` : `${s} second${s !== 1 ? "s" : ""} remaining`;
}
function d(e, s) {
return e.filter((t) => t.type === s);
}
function p(e) {
return e.reduce((s, t) => s + t.value, 0);
}
function k(e, s) {
const t = s.toLowerCase();
return e.find(
(n) => n.symbol.toLowerCase() === t || n.address.toLowerCase() === t
);
}
function g(e) {
return [...e].sort((s, t) => t.value - s.value);
}
function P(e) {
var t, n;
const s = new Set(((t = e.locks) == null ? void 0 : t.map((r) => r.address.toLowerCase())) || []);
return ((n = e.tokens) == null ? void 0 : n.filter((r) => !s.has(r.address.toLowerCase()))) || [];
}
export {
I as a,
h as b,
U as c,
_ as d,
d as e,
w as f,
D as g,
p as h,
L as i,
k as j,
P as k,
m as l,
g as s
};