@privy-io/wagmi-connector
Version:
A connector for Privy <> WAGMI.sh
2 lines (1 loc) • 6.05 kB
JavaScript
import{Connector as U,ChainNotConfiguredError as k,ConnectorNotFoundError as m}from"wagmi";import{getAddress as f,createWalletClient as F,custom as L,numberToHex as _,UserRejectedRequestError as w,SwitchChainError as D}from"viem";function W(r){return typeof r=="string"?Number.parseInt(r,r.trim().substring(0,2)==="0x"?16:10):typeof r=="bigint"?Number(r):r}var l=class extends U{id="privy";name="Privy";activeWallet;provider;logoutFromPrivy;constructor({logout:e,chains:t,activeWallet:n}){super({chains:t,options:void 0}),this.logoutFromPrivy=e,this.activeWallet=n}get ready(){return!!this.activeWallet}getActiveWallet(){return this.activeWallet}async setActiveWallet(e){this.activeWallet=e;let t=await this.getChainId();await this.#t();let n=await this.getChainId();if(t&&t!==n)try{await this.switchChain(t)}catch{console.warn("Unable to switch new active wallet to the network of previously active wallet.")}this.onAccountsChanged([this.activeWallet.address])}async connect({chainId:e}={}){this.emit("message",{type:"connecting"});let t=await this.getAccount();await this.#t();let n=await this.getChainId(),o=this.isChainUnsupported(n);return e&&n!==e&&(n=(await this.switchChain(e)).id,o=this.isChainUnsupported(n)),{account:t,chain:{id:n,unsupported:o}}}async disconnect(){this.provider&&this.#e(this.provider)}async getAccount(){if(!this.activeWallet)throw new m;return f(this.activeWallet.address)}async getChainId(){let t=await(await this.getProvider()).request({method:"eth_chainId"});return W(t)}async getProvider(){if(!this.activeWallet)throw new m;if(!this.provider)try{let e=await this.activeWallet.getEthereumProvider();this.provider=e}catch{throw new m}return this.provider}async getWalletClient({chainId:e}={}){let[t,n]=await Promise.all([this.getProvider(),this.getAccount()]),o=this.chains.find(i=>i.id===e);return F({account:n,chain:o,transport:L(t)})}async isAuthorized(){let[e,t,n]=await Promise.all([this.getProvider(),this.getAccount(),this.activeWallet?.isConnected()]);return!!t&&!!e&&!!n}async switchChain(e){let t=await this.getProvider(),n=_(e);try{let o=new Promise(i=>{let a=({chain:c})=>{c?.id===e&&(this.off("change",a),i())};this.on("change",a)});return await Promise.all([o,t.request({method:"wallet_switchEthereumChain",params:[{chainId:n.toString()}]})]),this.chains.find(i=>i.id===e)??{id:e,name:`Chain ${n}`,network:`${n}`,nativeCurrency:{name:"Ether",decimals:18,symbol:"ETH"},rpcUrls:{default:{http:[""]},public:{http:[""]}}}}catch(o){let i=this.chains.find(a=>a.id===e);if(!i)throw new k({chainId:e,connectorId:this.id});if(o.code===4902)try{return await t.request({method:"wallet_addEthereumChain",params:[{chainId:n,chainName:i.name,nativeCurrency:i.nativeCurrency,rpcUrls:[i.rpcUrls.public?.http[0]??""],blockExplorerUrls:this.getBlockExplorerUrls(i)}]}),i}catch(a){throw new w(a)}throw this.#r(o)?new w(o):new D(o)}}onAccountsChanged(e){e.length===0?this.emit("disconnect"):this.emit("change",{account:f(this.activeWallet.address)})}onChainChanged=e=>{let t=W(e),n=this.isChainUnsupported(t);this.emit("change",{chain:{id:t,unsupported:n}})};async onDisconnect(e){e?.code===1013&&await this.getProvider()&&await this.getAccount()||this.emit("disconnect")}#r(e){return/(user rejected)/i.test(e.message)}#n(e){e.on("accountsChanged",this.onAccountsChanged.bind(this)),e.on("chainChanged",this.onChainChanged),e.on("disconnect",this.onDisconnect.bind(this))}#e(e){e.removeListener("accountsChanged",this.onAccountsChanged.bind(this)),e.removeListener("chainChanged",this.onChainChanged),e.removeListener("disconnect",this.onDisconnect.bind(this))}async#t(){let e=this.provider;this.provider=void 0;let t=await this.getProvider();e&&this.#e(e),this.#n(t)}};import{createContext as J,useContext as R,useMemo as x,useState as K,useEffect as T,useCallback as $}from"react";import{createConfig as j,WagmiConfig as V,useSwitchNetwork as Q}from"wagmi";import{usePrivy as X,useWallets as Z}from"@privy-io/react-auth";import{useEffect as q}from"react";import{useAccount as z,useConnect as M,useWalletClient as O}from"wagmi";import{Fragment as Y,jsx as B}from"react/jsx-runtime";var P=({children:r})=>{let{connector:e}=S(),{refetch:t}=O(),{isConnected:n}=z(),{connect:o,connectors:i,isLoading:a}=M({connector:e});return q(()=>{!n&&!a&&i.length&&e?.activeWallet&&o(),t()},[e?.activeWallet]),B(Y,{children:r})};var p="privy:wagmi:selected-wallet",v="privy:wagmi:selected-wallet-timestamp",G=r=>JSON.stringify({address:r.address,walletClientType:r.walletClientType,connectorType:r.connectorType}),H=r=>{try{return JSON.parse(r)}catch{return null}},E=(r,e=localStorage)=>{e.setItem(p,G(r)),e.setItem(v,Date.now().toString())},A=(r=localStorage)=>{r.removeItem(p),r.removeItem(v)},b=(r=localStorage)=>{let e=r.getItem(p),t=r.getItem(v);if(!e||!t)return null;let n=H(e);return n?{value:n,storedAt:Number(t)}:null};import{jsx as C}from"react/jsx-runtime";var ee=()=>{throw new Error("You must wrap your application with the `PrivyWagmiConnector` to invoke `setActiveWallet`")},g=J({setActiveWallet:ee}),S=()=>{let{connector:r}=R(g);return{connector:r}},te=({wagmiChainsConfig:{chains:r,publicClient:e},privyConnectorOverride:t,children:n})=>{let{logout:o}=X(),{wallets:i}=Z(),[a,c]=K(),y=$(s=>{s?(E(s),c(s)):(A(),c(void 0))},[c]);T(()=>{let s=b();if(!s)return;if(a&&i[0]&&s.storedAt<i[0].connectedAt){y(void 0);return}let N=i.find(u=>u.address===s.value.address&&u.connectorType===s.value.connectorType&&u.walletClientType===s.value.walletClientType);c(N)},[i]);let d=a??i[0],h=x(()=>t instanceof l?t:new l({logout:o,chains:r}),[t]),I=x(()=>j({autoConnect:!0,connectors:[h],publicClient:e}),[h]);return T(()=>{d&&h.setActiveWallet(d)},[d]),C(g.Provider,{value:{connector:h,activeWallet:d,setActiveWallet:y},children:C(V,{config:I,children:C(P,{children:n})})})},re=()=>{let{connector:r,activeWallet:e,setActiveWallet:t}=R(g);return{ready:r.ready,wallet:e,setActiveWallet:t}},ne=(r={})=>Q({throwForSwitchChainNotSupported:!0,...r});export{l as PrivyConnector,te as PrivyWagmiConnector,re as usePrivyWagmi,ne as useSwitchNetwork};