UNPKG

vezgo-sdk-js

Version:

Official Vezgo JS SDK for the Browser & NodeJS

428 lines (427 loc) 14.9 kB
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 };