UNPKG

unich-web3-sdk

Version:

Web3 SDK for DEX applications with multi-chain support

6 lines (5 loc) 11 kB
"use client"; "use strict"; import w from'eventemitter3';import'viem';import'viem/chains';import'@solana/web3.js';var c=class{constructor(e,t,n,r,s){this._status="disconnected";this._error=null;this._account=null;this._chainId=null;this._eventEmitter=new w,this.id=e,this.name=t,this.type=n,this.icon=r,this.supportedChains=s;}isConnected(){return this._status==="connected"}getStatus(){return this._status}getError(){return this._error}getAccount(){return this._account}getChainId(){return this._chainId}on(e,t){this._eventEmitter.on(e,t);}off(e,t){this._eventEmitter.off(e,t);}removeAllListeners(e){e?this._eventEmitter.removeAllListeners(e):this._eventEmitter.removeAllListeners();}updateStatus(e){this._status=e;}updateError(e){this._error=e,e&&this._eventEmitter.emit("error",e);}updateAccount(e){let t=this._account;this._account=e,e&&e!==t&&this._eventEmitter.emit("accountChanged",e);}updateChainId(e){let t=this._chainId;this._chainId=e,e&&e!==t&&this._eventEmitter.emit("chainChanged",e);}};var B={id:1,name:"Ethereum",type:"evm",networkType:"mainnet",rpcUrls:["https://eth-mainnet.g.alchemy.com/v2/your-api-key","https://mainnet.infura.io/v3/your-api-key"],nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},blockExplorerUrls:["https://etherscan.io"],iconUrl:"https://cryptologos.cc/logos/ethereum-eth-logo.png"},V={id:137,name:"Polygon",type:"evm",networkType:"mainnet",rpcUrls:["https://polygon-rpc.com","https://polygon-mainnet.g.alchemy.com/v2/your-api-key"],nativeCurrency:{name:"MATIC",symbol:"MATIC",decimals:18},blockExplorerUrls:["https://polygonscan.com"],iconUrl:"https://cryptologos.cc/logos/polygon-matic-logo.png"},L={id:42161,name:"Arbitrum",type:"evm",networkType:"mainnet",rpcUrls:["https://arb1.arbitrum.io/rpc","https://arb-mainnet.g.alchemy.com/v2/your-api-key"],nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},blockExplorerUrls:["https://arbiscan.io"],iconUrl:"https://cryptologos.cc/logos/arbitrum-arb-logo.png"},H={id:10,name:"Optimism",type:"evm",networkType:"mainnet",rpcUrls:["https://mainnet.optimism.io","https://opt-mainnet.g.alchemy.com/v2/your-api-key"],nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},blockExplorerUrls:["https://optimistic.etherscan.io"],iconUrl:"https://cryptologos.cc/logos/optimism-op-logo.png"},G={id:56,name:"BNB Smart Chain",type:"evm",networkType:"mainnet",rpcUrls:["https://bsc-dataseed.binance.org","https://bsc-dataseed1.defibit.io"],nativeCurrency:{name:"BNB",symbol:"BNB",decimals:18},blockExplorerUrls:["https://bscscan.com"],iconUrl:"https://cryptologos.cc/logos/bnb-bnb-logo.png"},E=[B,V,L,H,G];var j={id:"mainnet-beta",name:"Solana",type:"svm",networkType:"mainnet",rpcUrls:["https://api.mainnet-beta.solana.com","https://solana-api.projectserum.com"],nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},blockExplorerUrls:["https://explorer.solana.com"],iconUrl:"https://cryptologos.cc/logos/solana-sol-logo.png"},F={id:"devnet",name:"Solana Devnet",type:"svm",networkType:"devnet",rpcUrls:["https://api.devnet.solana.com"],nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},blockExplorerUrls:["https://explorer.solana.com/?cluster=devnet"],iconUrl:"https://cryptologos.cc/logos/solana-sol-logo.png"},$={id:"testnet",name:"Solana Testnet",type:"svm",networkType:"testnet",rpcUrls:["https://api.testnet.solana.com"],nativeCurrency:{name:"Solana",symbol:"SOL",decimals:9},blockExplorerUrls:["https://explorer.solana.com/?cluster=testnet"],iconUrl:"https://cryptologos.cc/logos/solana-sol-logo.png"},f=[j,F,$];function W(){return [...E,...f]}function y(a){return W().find(e=>e.id===a)||null}var i=false,o=null,d=class extends c{constructor(){super("metamask","MetaMask","injected","https://metamask.io/images/metamask-fox.svg",["evm"]),this.boundAccountsChanged=this.handleAccountsChanged.bind(this),this.boundChainChanged=this.handleChainChanged.bind(this),this.boundDisconnect=this.handleDisconnect.bind(this);}isAvailable(){return typeof window<"u"&&!!window.ethereum}async connect(e){if(!this.isAvailable()){let n={code:"wallet_unavailable",message:"MetaMask is not installed"};throw this.updateError(n),this.updateStatus("error"),n}if(localStorage.getItem("metamask_disconnected")==="true"){let n={code:"user_disconnected",message:"User has explicitly disconnected. Please connect manually."};throw this.updateError(n),this.updateStatus("error"),n}if(i){let n={code:"request_pending",message:"A wallet connection request is already pending. Please check your wallet extension."};throw this.updateError(n),this.updateStatus("error"),n}try{this.updateStatus("connecting"),i=!0,o&&clearTimeout(o),o=setTimeout(()=>{i=!1;},3e4);let n=await window.ethereum.request({method:"eth_requestAccounts"});o&&(clearTimeout(o),o=null),i=!1;let r=n[0],s=await window.ethereum.request({method:"eth_chainId"}),u=parseInt(s,16);return e&&u!==e&&await this.switchChain(e),this.setupEventListeners(),this.updateAccount(r),this.updateChainId(u),this.updateStatus("connected"),this.updateError(null),localStorage.removeItem("metamask_disconnected"),this._eventEmitter.emit("connect",r),r}catch(n){if(o&&(clearTimeout(o),o=null),i=false,n.code===-32002){let s={code:"request_already_pending",message:"A wallet connection request is already pending. Please check your MetaMask extension and approve or reject the request.",details:n};throw this.updateError(s),this.updateStatus("error"),s}let r={code:n.code||"connection_error",message:n.message||"Failed to connect to MetaMask",details:n};throw this.updateError(r),this.updateStatus("error"),r}}async disconnect(){this._status!=="disconnected"&&(localStorage.setItem("metamask_disconnected","true"),this.removeAllListeners(),this.removeEventListeners(),this.updateAccount(null),this.updateChainId(null),this.updateStatus("disconnected"),this.updateError(null),this._eventEmitter.emit("disconnect"));}async switchChain(e){if(!this.isAvailable()||!this.isConnected()){let t={code:"not_connected",message:"Not connected to MetaMask"};throw this.updateError(t),t}if(i){let t={code:"request_pending",message:"A wallet request is already pending. Please check your wallet extension."};throw this.updateError(t),t}try{i=!0,o&&clearTimeout(o),o=setTimeout(()=>{i=!1;},3e4);let t=typeof e=="number"?`0x${e.toString(16)}`:e;await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:t}]}),o&&(clearTimeout(o),o=null),i=!1,this.updateChainId(e);}catch(t){if(o&&(clearTimeout(o),o=null),i=false,t.code===-32002){let n={code:"request_already_pending",message:"A wallet request is already pending. Please check your MetaMask extension and approve or reject the request.",details:t};throw this.updateError(n),n}if(t.code===4902){let n=y(e);if(n)await this.addChain(n);else throw {code:"chain_not_found",message:`Chain with ID ${e} not found`}}else {let n={code:t.code||"chain_switch_error",message:t.message||"Failed to switch chain",details:t};throw this.updateError(n),n}}}async addChain(e){if(i){let t={code:"request_pending",message:"A wallet request is already pending. Please check your wallet extension."};throw this.updateError(t),t}try{i=!0,o&&clearTimeout(o),o=setTimeout(()=>{i=!1;},3e4),await window.ethereum.request({method:"wallet_addEthereumChain",params:[{chainId:typeof e.id=="number"?`0x${e.id.toString(16)}`:e.id,chainName:e.name,nativeCurrency:e.nativeCurrency,rpcUrls:e.rpcUrls,blockExplorerUrls:e.blockExplorerUrls}]}),o&&(clearTimeout(o),o=null),i=!1;}catch(t){if(o&&(clearTimeout(o),o=null),i=false,t.code===-32002){let r={code:"request_already_pending",message:"A wallet request is already pending. Please check your MetaMask extension and approve or reject the request.",details:t};throw this.updateError(r),r}let n={code:t.code||"add_chain_error",message:t.message||"Failed to add chain",details:t};throw this.updateError(n),n}}setupEventListeners(){window.ethereum&&(window.ethereum.on("accountsChanged",this.boundAccountsChanged),window.ethereum.on("chainChanged",this.boundChainChanged),window.ethereum.on("disconnect",this.boundDisconnect));}removeEventListeners(){window.ethereum&&(window.ethereum.removeListener("accountsChanged",this.boundAccountsChanged),window.ethereum.removeListener("chainChanged",this.boundChainChanged),window.ethereum.removeListener("disconnect",this.boundDisconnect));}handleAccountsChanged(e){e.length===0?this.disconnect():this.updateAccount(e[0]);}handleChainChanged(e){let t=parseInt(e,16);this.updateChainId(t);}handleDisconnect(){this.updateStatus("disconnected"),this.updateAccount(null),this.updateChainId(null),this.updateError(null),this.removeEventListeners();}};var p=class extends c{constructor(){super("phantom","Phantom","injected","https://phantom.app/img/logo.png",["svm"]);}isAvailable(){return typeof window<"u"&&!!window.phantom?.solana?.isPhantom}async connect(e){if(!this.isAvailable()){let t={code:"wallet_unavailable",message:"Phantom is not installed"};throw this.updateError(t),this.updateStatus("error"),t}try{this.updateStatus("connecting");let t=window.phantom?.solana;if(!t)throw new Error("Phantom solana provider not found");let r=(await t.connect()).publicKey.toString();this.setupEventListeners(),this.updateAccount(r);let s=e||"mainnet-beta";return this.updateChainId(s),this.updateStatus("connected"),this.updateError(null),this._eventEmitter.emit("connect",r),r}catch(t){let n={code:t.code||"connection_error",message:t.message||"Failed to connect to Phantom",details:t};throw this.updateError(n),this.updateStatus("error"),n}}async disconnect(){if(this.isAvailable())try{let e=window.phantom?.solana;e&&await e.disconnect();}catch(e){console.error("Error disconnecting from Phantom:",e);}this.removeEventListeners(),this.updateAccount(null),this.updateChainId(null),this.updateStatus("disconnected"),this.updateError(null),this._eventEmitter.emit("disconnect");}async switchChain(e){if(!this.isAvailable()||!this.isConnected()){let t={code:"not_connected",message:"Not connected to Phantom"};throw this.updateError(t),t}try{this.updateChainId(e),console.warn("Please switch to the desired network manually in your Phantom wallet.");}catch(t){let n={code:t.code||"chain_switch_error",message:t.message||"Failed to switch chain",details:t};throw this.updateError(n),n}}setupEventListeners(){let e=window.phantom?.solana;e&&(e.on("accountChanged",this.handleAccountChanged.bind(this)),e.on("disconnect",this.handleDisconnect.bind(this)));}removeEventListeners(){let e=window.phantom?.solana;e&&(e.off("accountChanged",this.handleAccountChanged.bind(this)),e.off("disconnect",this.handleDisconnect.bind(this)));}handleAccountChanged(e){e?this.updateAccount(e.toString()):this.disconnect();}handleDisconnect(){this.disconnect();}};var v=[new d,new p];function fe(){return typeof window>"u"?[]:v.filter(a=>"isAvailable"in a&&typeof a.isAvailable=="function"?a.isAvailable():true)}function ye(a){return v.find(e=>e.id===a)} export{c as BaseConnector,d as MetaMaskConnector,p as PhantomConnector,fe as getAvailableConnectors,ye as getConnectorById};//# sourceMappingURL=index.mjs.map //# sourceMappingURL=index.mjs.map