vezgo-sdk-js
Version:
Official Vezgo JS SDK for the Browser & NodeJS
428 lines (427 loc) • 14.9 kB
JavaScript
import C from "apisauce";
import N from "jsonwebtoken";
const T = "https://api.vezgo.com", S = "https://connect.vezgo.com", V = "v1", U = `${T}/${V}`, j = () => typeof window < "u" && Object.prototype.toString.call(window) === "[object Window]" && !window.Deno, B = () => typeof global < "u" && Object.prototype.toString.call(global) === "[object global]", q = () => typeof Deno < "u", x = () => B() || q(), D = () => typeof navigator < "u" && navigator.product === "ReactNative";
function M() {
const s = "vezgo-connect-widget", e = document.createElement("iframe");
return e.name = s, e.frameBorder = 0, e.allow = "clipboard-read *; clipboard-write *", e.setAttribute("style", [
"width:100%; height:100%;",
"position:fixed;",
"top:0; left:0; right:0; bottom:0;",
"z-index:2147483647;"
// max possible z-index
].join(" ")), document.body.appendChild(e), e.style.display = "block", e;
}
function K({ url: s, token: e, iframe: t }) {
const i = document.createElement("form");
i.target = t.name, i.method = "POST", i.action = s, i.style.display = "none";
const r = document.createElement("input");
return r.type = "text", r.name = "token", r.value = e, i.appendChild(r), document.body.appendChild(i), i;
}
const d = (s = {}) => {
const e = new URLSearchParams();
return Object.keys(s).forEach((t) => {
e.append(t, s[t]);
}), e.toString();
};
class F {
constructor(e) {
this.api = e.userApi;
}
async getList(e = {}) {
let t = "/accounts";
const i = d(e);
i && (t = `${t}?${i}`);
const r = await this.api.get(t);
if (!r.ok) throw r.originalError;
return r.data;
}
async getOne(e, t = {}) {
if (!e || typeof e != "string") throw new Error("Please provide a valid Vezgo account id.");
let i = `/accounts/${e}`;
const r = d(t);
r && (i = `${i}?${r}`);
const o = await this.api.get(i);
if (!o.ok) throw o.originalError;
return o.data;
}
async sync(e) {
if (!e || typeof e != "string") throw new Error("Please provide a valid Vezgo account id.");
const t = await this.api.post(`/accounts/${e}/sync`, {});
if (!t.ok) throw t.originalError;
return t.data;
}
async remove(e) {
if (!e || typeof e != "string") throw new Error("Please provide a valid Vezgo account id.");
const t = await this.api.delete(`/accounts/${e}`);
if (!t.ok) throw t.originalError;
}
}
class J {
constructor(e) {
this.api = e.userApi;
}
async getList(e = {}) {
const { accountId: t, ...i } = e;
if (!t || typeof t != "string")
throw new Error("Please provide a valid Vezgo account id.");
let r = `/accounts/${t}/history`;
const o = d(i);
o && (r = `${r}?${o}`);
const n = await this.api.get(r);
if (!n.ok) throw n.originalError;
return n.data;
}
}
class G {
constructor(e) {
this.api = e.api;
}
async getList(e = {}) {
let t = "/providers";
const i = d(e);
i && (t = `${t}?${i}`);
const r = await this.api.get(t);
if (!r.ok) throw r.originalError;
return r.data;
}
async getOne(e) {
if (!e || typeof e != "string")
throw new Error("Please provide a valid Vezgo provider id.");
const t = await this.api.get(`/providers/${e}`);
if (!t.ok) throw t.originalError;
return t.data;
}
}
class H {
constructor(e) {
this.api = e.api, this.clientId = e.config.clientId;
}
async info() {
const e = await this.api.get(`/teams/info?client_id=${this.clientId}`);
if (!e.ok) throw e.originalError;
return e.data;
}
}
class Q {
constructor(e) {
this.api = e.userApi;
}
async getList(e = {}) {
const { accountId: t, ...i } = e;
if (!t || typeof t != "string")
throw new Error("Please provide a valid Vezgo account id.");
let r = `/accounts/${t}/transactions`;
const o = d(i);
o && (r = `${r}?${o}`);
const n = await this.api.get(r);
if (!n.ok) throw n.originalError;
return n.data;
}
async getOne(e = {}) {
const { accountId: t, txId: i, ...r } = e;
if (!t || typeof t != "string")
throw new Error("Please provide a valid Vezgo account id.");
if (!i || typeof i != "string")
throw new Error("Please provide a valid Vezgo transaction id.");
let o = `/accounts/${t}/transactions/${i}`;
const n = d(r);
n && (o = `${o}?${n}`);
const a = await this.api.get(o);
if (!a.ok) throw a.originalError;
return a.data;
}
}
class X {
constructor(e) {
this.api = e.userApi;
}
async getList(e = {}) {
const { accountId: t, ...i } = e;
if (!t || typeof t != "string")
throw new Error("Please provide a valid Vezgo account id.");
let r = `/accounts/${t}/orders`;
const o = d(i);
o && (r = `${r}?${o}`);
const n = await this.api.get(r);
if (!n.ok) throw n.originalError;
return n.data;
}
async getOne(e = {}) {
const { accountId: t, orderId: i, ...r } = e;
if (!t || typeof t != "string")
throw new Error("Please provide a valid Vezgo account id.");
if (!i || typeof i != "string")
throw new Error("Please provide a valid Vezgo order id.");
let o = `/accounts/${t}/orders/${i}`;
const n = d(r);
n && (o = `${o}?${n}`);
const a = await this.api.get(o);
if (!a.ok) throw a.originalError;
return a.data;
}
}
const Y = {
accounts: F,
history: J,
providers: G,
teams: H,
transactions: Q,
orders: X
};
function O(s, e) {
return e.reduce((t, i) => (t[i] = new Y[i](s), t), {});
}
const b = "_onConnection", v = "_onError", L = "_onEvent";
class P {
constructor(e) {
this.config = { ...e }, this.config.baseURL = this.config.baseURL || U, this.config.connectURL = this.config.connectURL || S;
const { clientId: t, secret: i } = this.config;
if (this.isBrowser = j(), this.isNodeOrSimilar = x(), this.isReactNative = D(), this.isClient = this.isBrowser || this.isReactNative, !t || typeof t != "string")
throw new Error("Please provide a valid Vezgo clientId.");
if (this.isNodeOrSimilar && (!i || typeof i != "string"))
throw new Error("Please provide a valid Vezgo secret.");
if (this.isBrowser) {
const r = e.auth || {};
this.config.authEndpoint = this.config.authEndpoint || "/vezgo/auth", this.config.auth = {
params: r.params || {},
headers: r.headers || {}
}, this.authApi = C.create({ headers: this.config.auth.headers });
}
this._token = {}, this._onWidgetMessage = this._onMessage.bind(this), this._widgetOpened = !1, this._widgetActive = !1;
}
_init() {
const { loginName: e, baseURL: t } = this.config;
this.api = C.create({ baseURL: t });
const i = O(this, ["providers", "teams"]);
return Object.assign(this, i), e ? this.login(e) : this;
}
login(e) {
if (this.isNodeOrSimilar && (!e || typeof e != "string"))
throw new Error("Please provide a valid loginName.");
const { baseURL: t } = this.config, i = new P({ ...this.config, loginName: null });
i._init(), i.userApi = C.create({ baseURL: t }), i.userApi.addAsyncRequestTransform(async (o) => (o.headers.Authorization = `Bearer ${await i.getToken()}`, o));
const r = O(i, ["accounts", "history", "transactions"]);
return Object.assign(i, r), i.config.loginName = e, i;
}
async getToken(e = {}) {
const t = (/* @__PURE__ */ new Date()).valueOf(), { payload: i } = this._token;
let { token: r } = this._token;
return (!i || t > (i.exp - (e.minimumLifetime || 10)) * 1e3) && (r = await this.fetchToken()), r;
}
async fetchToken() {
const e = await (this.isClient ? this._fetchTokenClient() : this._fetchTokenNode());
if (!e.ok && !e.token)
throw e.originalError;
const { token: t } = e.data || e, i = N.decode(t);
return this._token = { token: t, payload: i }, this._token.token;
}
_fetchTokenNode() {
const { clientId: e, secret: t, loginName: i } = this.config;
return this.api.post("/auth/token", { clientId: e, secret: t }, { headers: { loginName: i } });
}
_fetchTokenClient() {
const { auth: e, authEndpoint: t, authorizer: i } = this.config, { params: r } = e;
return typeof i == "function" ? new Promise((o, n) => {
i((a, c) => {
if (a) {
n(a);
return;
}
if (!c || typeof c != "object" || !c.token) {
n(new Error('Invalid authorizer result. Expecting `{ token: "the token" }`.'));
return;
}
o(c);
});
}) : this.authApi.post(t, r);
}
getTeam() {
return this.teams.info();
}
async getConnectData(e = {}) {
const {
provider: t,
disabledProviders: i,
accountId: r,
state: o,
origin: n = this.isBrowser ? window.location.origin : void 0,
lang: a,
redirectURI: c = this.config.redirectURI,
syncNfts: y = !0,
providerCategories: l,
providers: f,
theme: g,
providersPerLine: u,
features: _,
multiWallet: p,
hideWalletConnectWallets: w,
providersPreferences: R
} = e, { clientId: z, connectURL: E } = this.config;
let k = t;
if (t && !r) {
if (!this.cachedProviders)
try {
this.cachedProviders = await this.providers.getList();
} catch ($) {
throw console.error($), new Error("Failed to fetch providers list.");
}
const h = this.cachedProviders.find(($) => $.name === t);
if (!h)
throw new Error("Provider not found.");
h.alternate_names && (k = h.alternate_names[h.alternate_names.length - 1]);
}
const W = await this.getToken({ minimumLifetime: 600 }), m = {
client_id: z,
redirect_uri: c,
state: o,
lang: a || "en",
origin: n,
sync_nfts: y === !1 ? !1 : void 0,
// only pass if it is false
demo: this.config.demo ? !0 : void 0,
// 'provider' param in priority, skip 'provider_categories' param if 'provider' is set
provider_categories: !t && Array.isArray(l) && l.length ? l.join(",") : void 0,
// 'provider' param in priority, skip 'providers' param if 'provider' is set
providers: !t && Array.isArray(f) && f.length ? f.join(",") : void 0,
disabled_providers: i && Array.isArray(i) && i.length ? i.join(",") : void 0,
theme: ["light", "dark"].includes(g) ? g : "light",
providers_per_line: u && ["1", "2"].includes(u.toString()) ? u.toString() : "2",
features: _,
multi_wallet: p,
hide_wallet_connect_wallets: w,
providers_preferences: JSON.stringify(R)
};
Object.keys(m).forEach(
(h) => [void 0, null, ""].includes(m[h]) && delete m[h]
);
const I = new URLSearchParams(m).toString();
let A = k ? `${E}/connect/${k}` : `${E}/connect`;
return r && (A = `${E}/reconnect/${r}`), { url: `${A}?${I}`, token: W };
}
connect(e = {}) {
return this._connect(e), this;
}
reconnect(e, t = {}) {
if (!e || typeof e != "string")
throw new Error("Please provide a valid accountId.");
return this._connect({ accountId: e, ...t }), this;
}
onConnection(e) {
if (typeof e != "function") throw new Error("Callback must be a function.");
return this[b] = e.bind(this), this;
}
onError(e) {
if (typeof e != "function") throw new Error("Callback must be a function.");
return this[v] = e.bind(this), this;
}
onEvent(e) {
if (typeof e != "function") throw new Error("Callback must be a function.");
return this[L] = e.bind(this), this;
}
_connect(e = {}) {
if (!this.isBrowser) throw new Error("Only supported in Browser.");
(async () => {
try {
this._widgetOpened = !0;
const {
provider: t,
providers: i,
disabledProviders: r,
providerCategories: o,
accountId: n,
lang: a,
theme: c,
providersPerLine: y,
syncNfts: l,
features: f,
multiWallet: g,
hideWalletConnectWallets: u,
providersPreferences: _
} = e, { url: p, token: w } = await this.getConnectData({
provider: t,
providers: i,
disabledProviders: r,
providerCategories: o,
accountId: n,
lang: a,
theme: c,
providersPerLine: y,
syncNfts: l,
features: f,
multiWallet: g,
hideWalletConnectWallets: u,
providersPreferences: _
});
this.iframe = M(), e.connectionType === "GET" ? this.widget = window.open(`${p}&token=${w}`, this.iframe.name) : (this.widget = window.open("", this.iframe.name), this.form = K({ url: p, token: w, iframe: this.iframe }), this.form.submit()), this.widget.focus(), this._widgetActive = !0, this._addListeners(), this._addWatchers();
} catch {
this._closeWidgetWithError(500, "Connection refused");
}
})();
}
_onMessage({ origin: e, data: t }) {
let i = t;
try {
i = JSON.parse(t);
} catch {
}
if (i.vezgo) {
if (e !== this.config.connectURL && !/\.vezgo\.com$/.test(new URL(e).hostname))
throw new Error(`Calling Vezgo from unauthorized origin ${e}`);
switch (i.event) {
case "success": {
this._triggerCallback(b, i.account);
break;
}
case "error": {
this._triggerCallback(v, i.error);
break;
}
case "close": {
this._closeWidgetWithError(400, "Connection closed");
break;
}
default:
this._triggerCallback(L, i);
}
}
}
_addWatchers() {
const e = setTimeout(() => {
this._closeWidgetWithError(400, "Connection timeout");
}, 6e5), t = setInterval(() => {
this._widgetActive ? this.widget.closed && this._closeWidgetWithError(400, "Connection closed") : (this._removeListeners(), clearInterval(t), clearTimeout(e), this._closeWidget());
}, 1e3);
}
// eslint-disable-next-line camelcase
_closeWidgetWithError(e, t) {
this._closeWidget(), this._triggerCallback(v, { error_type: e, message: t });
}
_closeWidget() {
this._widgetActive = !1, this.widget && !this.widget.closed && this.widget.close(), this.iframe && this.iframe.remove(), this.form && this.form.remove();
}
_triggerCallback(e, t) {
if ([b, v].includes(e)) {
this._widgetActive = !1, this._widgetOpened && (this._widgetOpened = !1, this[e] && this[e](t));
return;
}
if (e === L && this[e]) {
const i = t ? t.event : null, r = t ? t.data : null;
this[e](i, r);
}
}
_addListeners() {
window.addEventListener("message", this._onWidgetMessage, !1);
}
_removeListeners() {
window.removeEventListener("message", this._onWidgetMessage, !1);
}
}
class Z {
init(e = {}) {
return new P(e)._init();
}
}
const ie = new Z();
export {
ie as default
};