vezgo-sdk-js
Version:
Official Vezgo JS SDK for the Browser & NodeJS
2 lines (1 loc) • 11.2 kB
JavaScript
"use strict";const C=require("apisauce"),N=require("jsonwebtoken"),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;"].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=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:u,theme:g,providersPerLine:f,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,demo:this.config.demo?!0:void 0,provider_categories:!t&&Array.isArray(l)&&l.length?l.join(","):void 0,providers:!t&&Array.isArray(u)&&u.length?u.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:f&&["1","2"].includes(f.toString())?f.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:u,multiWallet:g,hideWalletConnectWallets:f,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:u,multiWallet:g,hideWalletConnectWallets:f,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)}_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 ee=new Z;module.exports=ee;