UNPKG

vezgo-sdk-js

Version:

Official Vezgo JS SDK for the Browser & NodeJS

2 lines (1 loc) 11.9 kB
"use strict";const O=require("apisauce"),D=require("jsonwebtoken"),U="https://api.vezgo.com",V="https://connect.vezgo.com",j="v1",B=`${U}/${j}`,q=()=>typeof window<"u"&&Object.prototype.toString.call(window)==="[object Window]"&&!window.Deno,x=()=>typeof global<"u"&&Object.prototype.toString.call(global)==="[object global]",K=()=>typeof Deno<"u",M=()=>x()||K(),G=()=>typeof navigator<"u"&&navigator.product==="ReactNative";function F(){const s="vezgo-connect-widget",t=document.createElement("iframe");return t.name=s,t.frameBorder=0,t.allow="clipboard-read *; clipboard-write *",t.setAttribute("style",["width:100%; height:100%;","position:fixed;","top:0; left:0; right:0; bottom:0;","z-index:2147483647;"].join(" ")),document.body.appendChild(t),t.style.display="block",t}function Q({url:s,token:t,iframe:e}){const i=document.createElement("form");i.target=e.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=t,i.appendChild(r),document.body.appendChild(i),i}const d=(s={})=>{const t=new URLSearchParams;return Object.keys(s).forEach(e=>{t.append(e,s[e])}),t.toString()};class A extends Error{constructor({message:t,existing_institution_id:e}={}){super(t||"This connection is already linked to your account."),this.name="DuplicateConnectionError",this.existing_institution_id=e}}function g(s){if(!s.ok)throw s.status===409?new A(s.data||{}):s.originalError}class J{constructor(t){this.api=t.userApi}async getList(t={}){let e="/accounts";const i=d(t);i&&(e=`${e}?${i}`);const r=await this.api.get(e);return g(r),r.data}async getOne(t,e={}){if(!t||typeof t!="string")throw new Error("Please provide a valid Vezgo account id.");let i=`/accounts/${t}`;const r=d(e);r&&(i=`${i}?${r}`);const o=await this.api.get(i);return g(o),o.data}async sync(t){if(!t||typeof t!="string")throw new Error("Please provide a valid Vezgo account id.");const e=await this.api.post(`/accounts/${t}/sync`,{});return g(e),e.data}async getKYCData(t){if(!t||typeof t!="string")throw new Error("Please provide a valid Vezgo account id.");const e=await this.api.get(`/accounts/${t}/kyc-data`);return e.status===404?null:(g(e),e.data)}async remove(t){if(!t||typeof t!="string")throw new Error("Please provide a valid Vezgo account id.");const e=await this.api.delete(`/accounts/${t}`);g(e)}}class Y{constructor(t){this.api=t.userApi}async getList(t={}){const{accountId:e,...i}=t;if(!e||typeof e!="string")throw new Error("Please provide a valid Vezgo account id.");let r=`/accounts/${e}/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 H{constructor(t){this.api=t.api}async getList(t={}){let e="/providers";const i=d(t);i&&(e=`${e}?${i}`);const r=await this.api.get(e);if(!r.ok)throw r.originalError;return r.data}async getOne(t){if(!t||typeof t!="string")throw new Error("Please provide a valid Vezgo provider id.");const e=await this.api.get(`/providers/${t}`);if(!e.ok)throw e.originalError;return e.data}}class X{constructor(t){this.api=t.api,this.clientId=t.config.clientId}async info(){const t=await this.api.get(`/teams/info?client_id=${this.clientId}`);if(!t.ok)throw t.originalError;return t.data}}class Z{constructor(t){this.api=t.userApi}async getList(t={}){const{accountId:e,...i}=t;if(!e||typeof e!="string")throw new Error("Please provide a valid Vezgo account id.");let r=`/accounts/${e}/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(t={}){const{accountId:e,txId:i,...r}=t;if(!e||typeof e!="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/${e}/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 tt{constructor(t){this.api=t.userApi}async getList(t={}){const{accountId:e,...i}=t;if(!e||typeof e!="string")throw new Error("Please provide a valid Vezgo account id.");let r=`/accounts/${e}/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(t={}){const{accountId:e,orderId:i,...r}=t;if(!e||typeof e!="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/${e}/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 et={accounts:J,history:Y,providers:H,teams:X,transactions:Z,orders:tt};function b(s,t){return t.reduce((e,i)=>(e[i]=new et[i](s),e),{})}const L="_onConnection",p="_onError",E="_onEvent",it=["DUPLICATE_CONNECTION","CLIENT_ID_REQUIRED","WRONG_CLIENT_ID","INVALID_ORIGIN","TOKEN_REQUIRED","WRONG_REDIRECT_URI","INVALID_ACCOUNT_ID","PAGE_NOT_FOUND","SESSION_EXPIRED","INVALID_TOKEN"];class N{constructor(t){this.config={...t},this.config.baseURL=this.config.baseURL||B,this.config.connectURL=this.config.connectURL||V;const{clientId:e,secret:i}=this.config;if(this.isBrowser=q(),this.isNodeOrSimilar=M(),this.isReactNative=G(),this.isClient=this.isBrowser||this.isReactNative,!e||typeof e!="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=t.auth||{};this.config.authEndpoint=this.config.authEndpoint||"/vezgo/auth",this.config.auth={params:r.params||{},headers:r.headers||{}},this.authApi=O.create({headers:this.config.auth.headers})}this._token={},this._onWidgetMessage=this._onMessage.bind(this),this._widgetOpened=!1,this._widgetActive=!1}_init(){const{loginName:t,baseURL:e}=this.config;this.api=O.create({baseURL:e});const i=b(this,["providers","teams"]);return Object.assign(this,i),t?this.login(t):this}login(t){if(this.isNodeOrSimilar&&(!t||typeof t!="string"))throw new Error("Please provide a valid loginName.");const{baseURL:e}=this.config,i=new N({...this.config,loginName:null});i._init(),i.userApi=O.create({baseURL:e}),i.userApi.addAsyncRequestTransform(async o=>(o.headers.Authorization=`Bearer ${await i.getToken()}`,o));const r=b(i,["accounts","history","transactions"]);return Object.assign(i,r),i.config.loginName=t,i}async getToken(t={}){const e=new Date().valueOf(),{payload:i}=this._token;let{token:r}=this._token;return(!i||e>(i.exp-(t.minimumLifetime||10))*1e3)&&(r=await this.fetchToken()),r}async fetchToken(){const t=await(this.isClient?this._fetchTokenClient():this._fetchTokenNode());if(!t.ok&&!t.token)throw t.originalError;const{token:e}=t.data||t,i=D.decode(e);return this._token={token:e,payload:i},this._token.token}_fetchTokenNode(){const{clientId:t,secret:e,loginName:i}=this.config;return this.api.post("/auth/token",{clientId:t,secret:e},{headers:{loginName:i}})}_fetchTokenClient(){const{auth:t,authEndpoint:e,authorizer:i}=this.config,{params:r}=t;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(e,r)}getTeam(){return this.teams.info()}async getConnectData(t={}){const{provider:e,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:w,providersPerLine:f,features:C,multiWallet:m,hideWalletConnectWallets:v,providersPreferences:T}=t,{clientId:z,connectURL:I}=this.config;let R=e;if(e&&!r){if(!this.cachedProviders)try{this.cachedProviders=await this.providers.getList()}catch(k){throw console.error(k),new Error("Failed to fetch providers list.")}const h=this.cachedProviders.find(k=>k.name===e);if(!h)throw new Error("Provider not found.");h.alternate_names&&(R=h.alternate_names[h.alternate_names.length-1])}const W=await this.getToken({minimumLifetime:600}),_={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:!e&&Array.isArray(l)&&l.length?l.join(","):void 0,providers:!e&&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(w)?w:"light",providers_per_line:f&&["1","2"].includes(f.toString())?f.toString():"2",features:C,multi_wallet:m,hide_wallet_connect_wallets:v,providers_preferences:JSON.stringify(T)};Object.keys(_).forEach(h=>[void 0,null,""].includes(_[h])&&delete _[h]);const S=new URLSearchParams(_).toString();let $=R?`${I}/connect/${R}`:`${I}/connect`;return r&&($=`${I}/reconnect/${r}`),{url:`${$}?${S}`,token:W}}connect(t={}){return this._connect(t),this}reconnect(t,e={}){if(!t||typeof t!="string")throw new Error("Please provide a valid accountId.");return this._connect({accountId:t,...e}),this}onConnection(t){if(typeof t!="function")throw new Error("Callback must be a function.");return this[L]=t.bind(this),this}onError(t){if(typeof t!="function")throw new Error("Callback must be a function.");return this[p]=t.bind(this),this}onEvent(t){if(typeof t!="function")throw new Error("Callback must be a function.");return this[E]=t.bind(this),this}_connect(t={}){if(!this.isBrowser)throw new Error("Only supported in Browser.");(async()=>{try{this._widgetOpened=!0;const{provider:e,providers:i,disabledProviders:r,providerCategories:o,accountId:n,lang:a,theme:c,providersPerLine:y,syncNfts:l,features:u,multiWallet:w,hideWalletConnectWallets:f,providersPreferences:C}=t,{url:m,token:v}=await this.getConnectData({provider:e,providers:i,disabledProviders:r,providerCategories:o,accountId:n,lang:a,theme:c,providersPerLine:y,syncNfts:l,features:u,multiWallet:w,hideWalletConnectWallets:f,providersPreferences:C});this.iframe=F(),t.connectionType==="GET"?this.widget=window.open(`${m}&token=${v}`,this.iframe.name):(this.widget=window.open("",this.iframe.name),this.form=Q({url:m,token:v,iframe:this.iframe}),this.form.submit()),this.widget.focus(),this._widgetActive=!0,this._addListeners(),this._addWatchers()}catch{this._closeWidgetWithError(500,"Connection refused")}})()}_onMessage({origin:t,data:e}){let i=e;try{i=JSON.parse(e)}catch{}if(i.vezgo){if(t!==this.config.connectURL&&!/\.vezgo\.com$/.test(new URL(t).hostname))throw new Error(`Calling Vezgo from unauthorized origin ${t}`);switch(i.event){case"success":{this._triggerCallback(L,i.account);break}case"error":{this._triggerCallback(p,i.error);break}case"ERROR":{it.includes(i.data&&i.data.type)?this._triggerCallback(p,i.data):this._triggerCallback(E,i);break}case"close":{this._closeWidgetWithError(400,"Connection closed");break}default:this._triggerCallback(E,i)}}}_addWatchers(){const t=setTimeout(()=>{this._closeWidgetWithError(400,"Connection timeout")},6e5),e=setInterval(()=>{this._widgetActive?this.widget.closed&&this._closeWidgetWithError(400,"Connection closed"):(this._removeListeners(),clearInterval(e),clearTimeout(t),this._closeWidget())},1e3)}_closeWidgetWithError(t,e){this._closeWidget(),this._triggerCallback(p,{error_type:t,message:e})}_closeWidget(){this._widgetActive=!1,this.widget&&!this.widget.closed&&this.widget.close(),this.iframe&&this.iframe.remove(),this.form&&this.form.remove()}_triggerCallback(t,e){if([L,p].includes(t)){this._widgetActive=!1,this._widgetOpened&&(this._widgetOpened=!1,this[t]&&this[t](e));return}if(t===E&&this[t]){const i=e?e.event:null,r=e?e.data:null;this[t](i,r)}}_addListeners(){window.addEventListener("message",this._onWidgetMessage,!1)}_removeListeners(){window.removeEventListener("message",this._onWidgetMessage,!1)}}class rt{init(t={}){return new N(t)._init()}}const P=new rt;P.DuplicateConnectionError=A;module.exports=P;