@tuwaio/satellite-evm 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,7 +50,7 @@ export const evmAdapter = satelliteEVMAdapter(wagmiConfig, appChains);
50
50
 
51
51
  Pass `evmAdapter` to `createSatelliteConnectStore` from [`@tuwaio/satellite-core`](https://satellite.docs.tuwa.io/packages/satellite-core) or to `SatelliteConnectProvider` from [`@tuwaio/satellite-react`](https://satellite.docs.tuwa.io/packages/satellite-react), and run the watcher next to it. The complete React setup is on the **[`@tuwaio/satellite-react`](https://satellite.docs.tuwa.io/packages/satellite-react)** page; the watcher without React is shown on the **[`createEVMConnectionsWatcher`](https://satellite.docs.tuwa.io/packages/satellite-evm/functions/createEVMConnectionsWatcher)** page.
52
52
 
53
- `ssr: true` (for Next.js and other server rendering) postpones the hydration of the wagmi config, and until it is hydrated, wagmi does not add the installed wallets found through EIP-6963 (MetaMask, Rabby…) to its connectors. `EVMConnectorsWatcher` from `@tuwaio/satellite-react/evm` hydrates the config after mount, so a React app needs no `WagmiProvider` from `wagmi`. Without React, call `hydrate(wagmiConfig, { reconnectOnMount: false }).onMount()` from `@wagmi/core` once in the browser, or create the config without `ssr: true`.
53
+ `ssr: true` (for Next.js and other server rendering) postpones the hydration of the wagmi config, and until it is hydrated, wagmi does not add the installed wallets found through EIP-6963 (MetaMask, Rabby…) to its connectors. `EVMConnectorsWatcher` from `@tuwaio/satellite-react/evm` hydrates the config after mount, so a React app needs no `WagmiProvider` from `wagmi`. Without React, call `hydrate(wagmiConfig, { reconnectOnMount: false }).onMount()` from `@wagmi/core` once in the browser, or create the config without `ssr: true`. The adapter's `watchConnectors` reports every change of the connectors of the config (wagmi's `watchConnectors`), so a wallet list that follows the store's `watchConnectors` fills in when wagmi adds these wallets, also when it was opened before.
54
54
 
55
55
  ---
56
56
 
package/dist/index.d.mts CHANGED
@@ -21,6 +21,10 @@ interface EVMConnection extends BaseConnector {
21
21
  * or `SatelliteConnectProvider` from `@tuwaio/satellite-react`). It implements `SatelliteAdapter` with `@wagmi/core`:
22
22
  * - `getConnectors` returns the connectors of `config`. A connector matches a `connectorType` such as `"evm:metamask"`
23
23
  * through `formatConnectorName` from `@tuwaio/orbit-core` (for example, the `Safe` connector is `"evm:safe"`).
24
+ * - `watchConnectors` calls `onChange` (with no arguments) on every change of the connectors of `config`, through
25
+ * wagmi's `watchConnectors`: when wagmi adds the installed EIP-6963 wallets while a config created with `ssr: true`
26
+ * is hydrated, when a wallet announces itself later, and when other code changes the connectors. It subscribes to the
27
+ * connectors store of `config` until the returned function is called.
24
28
  * - `connect` runs wagmi's `connect` with the requested chain and returns an {@link EVMConnection}: the account (the
25
29
  * zero address if wagmi reports none), the chain (`1` if unknown), the first default RPC URL of the chain, the
26
30
  * connector icon and a `signMessage` that signs with wagmi's `signMessage`. An injected wallet shows its connect
package/dist/index.d.ts CHANGED
@@ -21,6 +21,10 @@ interface EVMConnection extends BaseConnector {
21
21
  * or `SatelliteConnectProvider` from `@tuwaio/satellite-react`). It implements `SatelliteAdapter` with `@wagmi/core`:
22
22
  * - `getConnectors` returns the connectors of `config`. A connector matches a `connectorType` such as `"evm:metamask"`
23
23
  * through `formatConnectorName` from `@tuwaio/orbit-core` (for example, the `Safe` connector is `"evm:safe"`).
24
+ * - `watchConnectors` calls `onChange` (with no arguments) on every change of the connectors of `config`, through
25
+ * wagmi's `watchConnectors`: when wagmi adds the installed EIP-6963 wallets while a config created with `ssr: true`
26
+ * is hydrated, when a wallet announces itself later, and when other code changes the connectors. It subscribes to the
27
+ * connectors store of `config` until the returned function is called.
24
28
  * - `connect` runs wagmi's `connect` with the requested chain and returns an {@link EVMConnection}: the account (the
25
29
  * zero address if wagmi reports none), the chain (`1` if unknown), the first default RPC URL of the chain, the
26
30
  * connector icon and a `signMessage` that signs with wagmi's `signMessage`. An injected wallet shows its connect
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var orbitCore=require('@tuwaio/orbit-core'),orbitEvm=require('@tuwaio/orbit-evm'),core=require('@wagmi/core'),viem=require('viem'),chains=require('viem/chains'),utils=require('viem/utils');var E=new Map;async function V({config:r,address:s,chainId:d,chains:c}){let h=`${Number(d)}:${s.toLowerCase()}`;if(E.has(h))return E.get(h);if(orbitEvm.createViemClient(Number(d),c)){let u=!!await core.getBytecode(r,{address:s,chainId:Number(d)});return E.set(h,u),u}else return false}function ve(r,s){if(!r)throw new Error("Satellite EVM adapter requires a wagmi config object.");let d=t=>orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,orbitCore.formatConnectorName(t.name)),c=t=>core.getConnectors(r).find(n=>d(n)===t),h=new Set,p=()=>[...r.state.connections.values()].filter(({connector:t})=>h.has(t.uid)),a=(t,n)=>{let e=core.getConnection(r);return {connectorType:t,address:e.address??viem.zeroAddress,chainId:e.chainId??chains.mainnet.id,rpcURL:e.chain?.rpcUrls.default.http[0]??chains.mainnet.rpcUrls.default.http[0],isConnected:e.isConnected,isContractAddress:false,icon:n?.icon?.trim(),connector:n,signMessage:o=>core.signMessage(r,{message:o})}},u=async(t,n,e)=>(r.state.current!==n.uid&&await core.switchConnection(r,{connector:n}),Number(e)&&core.getConnection(r).chainId!==Number(e)&&await core.switchChain(r,{chainId:Number(e),connector:n}).catch(()=>{}),h.add(n.uid),a(t,n));return {key:orbitCore.OrbitAdapter.EVM,connect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{return r.state.connections.has(e.uid)?await u(t,e,n):(await core.connect(r,{connector:e,chainId:n}),h.add(e.uid),a(t,e))}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},reconnect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{if(!r.state.connections.has(e.uid)){if((await e.getAccounts().catch(()=>[])).length===0)return;let i={connector:e,isReconnecting:!0};r.state.connections.has(e.uid)||await core.connect(r,i);}return await u(t,e,n)}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},getLiveConnections:async()=>p().map(({connector:t,accounts:n,chainId:e})=>{let o=core.getChains(r).find(({id:i})=>i===e);return {connectorType:d(t),address:n[0]??viem.zeroAddress,chainId:e,rpcURL:o?.rpcUrls.default.http[0]??chains.mainnet.rpcUrls.default.http[0],isConnected:true,isContractAddress:false,icon:t.icon?.trim(),connector:t,signMessage:i=>core.signMessage(r,{message:i,connector:t})}}),disconnect:async t=>{if(t&&t.isConnected){let{connector:e}=t;await core.disconnect(r,{connector:e}),e&&h.delete(e.uid);return}let n=p().filter(({connector:e})=>!t||d(e)===t.connectorType);for(let{connector:e}of n){h.delete(e.uid);try{await core.disconnect(r,{connector:e});}catch{}}},getConnectors:()=>{let t=core.getConnectors(r);return {adapter:orbitCore.OrbitAdapter.EVM,connectors:t.map(n=>n)}},checkAndSwitchNetwork:async t=>await orbitEvm.checkAndSwitchChain(Number(t),r),getBalance:async(t,n)=>{let e=await core.getBalance(r,{address:t,chainId:Number(n)});return {value:viem.formatUnits(e.value,e.decimals),symbol:e.symbol}},getExplorerUrl:(t,n)=>{let o=(n===void 0?core.getConnection(r).chain:s.find(i=>i.id===Number(n))??core.getChains(r).find(i=>i.id===Number(n)))?.blockExplorers?.default.url;if(o)return t?`${o.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`:o},getName:t=>orbitEvm.getName(t,s),getAvatar:t=>orbitEvm.getAvatar(t,s),getAddress:t=>orbitEvm.getAddress(t,s),checkIsContractAddress:async({address:t,chainId:n})=>{let e=core.getChains(r);return await V({config:r,address:t,chainId:n,chains:e})},getSafeConnectorChainId:async()=>{let n=core.getConnectors(r).find(e=>e.name==="Safe");if(n)return await n.getChainId()},switchConnection:async t=>{let n=c(t);if(!n)throw new Error(`Cannot find connector with type: ${t}`);try{await core.switchConnection(r,{connector:n});}catch(e){throw new Error(`Failed to switch to connector ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}}}F.type="impersonated";function F(r){let s=r.features??{},d=false,c,h;return core.createConnector(p=>({id:"impersonated",name:"Impersonated Connector",type:F.type,async setup(){c=p.chains[0].id;},async connect({chainId:a}={}){if(s.connectError)throw typeof s.connectError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to connect.")):s.connectError;let{request:u}=await this.getProvider(),t=await u({method:"eth_requestAccounts"}),n=await this.getChainId();return a&&n!==a&&(n=(await this.switchChain({chainId:a})).id),d=true,{accounts:t,chainId:n}},async disconnect(){d=false,h=void 0;},async getAccounts(){if(!d)throw new Error("Not connected connector");let{request:a}=await this.getProvider();return (await a({method:"eth_accounts"})).map(viem.getAddress)},async getChainId(){let{request:a}=await this.getProvider(),u=await a({method:"eth_chainId"});return viem.fromHex(u,"number")},async isAuthorized(){return d?!!(await this.getAccounts()).length:false},async switchChain({chainId:a}){let u=p.chains.find(n=>n.id===a);if(!u)throw new viem.SwitchChainError(new core.ChainNotConfiguredError);let{request:t}=await this.getProvider();return await t({method:"wallet_switchEthereumChain",params:[{chainId:viem.numberToHex(a)}]}),u},onAccountsChanged(a){a.length===0?this.onDisconnect():p.emitter.emit("change",{accounts:a.map(viem.getAddress)});},onChainChanged(a){let u=Number(a);p.emitter.emit("change",{chainId:u});},async onDisconnect(){p.emitter.emit("disconnect"),d=false,h=void 0;},async getProvider({chainId:a}={}){h=orbitCore.impersonatedHelpers?.getImpersonated()?[orbitCore.impersonatedHelpers.getImpersonated()||viem.zeroAddress]:void 0;let t=(p.chains.find(e=>e.id===a)??p.chains[0]).rpcUrls.default.http[0];return viem.custom({request:async({method:e,params:o})=>{if(e==="eth_chainId")return viem.numberToHex(c);if(e==="eth_requestAccounts"||e==="eth_accounts")return h??[];if(e==="eth_signTypedData_v4"&&s.signTypedDataError)throw typeof s.signTypedDataError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to sign typed data.")):s.signTypedDataError;if(e==="wallet_switchEthereumChain"){if(s.switchChainError)throw typeof s.switchChainError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to switch chain.")):s.switchChainError;c=viem.fromHex(o[0].chainId,"number"),this.onChainChanged(c.toString());return}if(e==="personal_sign"){if(s.signMessageError)throw typeof s.signMessageError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to sign message.")):s.signMessageError;e="eth_sign",o=[o[1],o[0]];}let i={method:e,params:o},{error:C,result:m}=await utils.rpc.http(t,{body:i});if(C)throw new viem.RpcRequestError({body:i,error:C,url:t});return m}})({retryCount:1})}}))}var Ue={allowedDomains:[/^https:\/\/([a-z0-9-]+\.)*gnosis-safe\.io$/,/^https:\/\/([a-z0-9-]+\.)*app\.safe\.global$/,/^https:\/\/([a-z0-9-]+\.)*metissafe\.tech$/],debug:false};var je=r=>r.reduce((s,d)=>{let c=d.id;return s[c]=viem.http(),s},{});function Je(r,s){let{wagmiConfig:d}=r,c=r.siwx??(r.siwe?{enabled:r.siwe.enabled,isSignedIn:r.siwe.isSignedIn,isRejected:r.siwe.isRejected}:void 0),{disconnect:h,updateActiveConnection:p}=s,a=()=>s.getState?.()??s,u=()=>{let o=c?.isRejected||c?.status==="error",i=c?.isSignedIn??c?.isAuthenticated??false;if(c?.enabled!==false&&!i&&o){let{activeConnection:m}=a();m&&h(m.connectorType);}},t=o=>{let{activeConnection:i,connectionError:C}=a();if(i&&orbitCore.getAdapterFromConnectorType(i.connectorType)!==orbitCore.OrbitAdapter.EVM)return;if(o.length===0){i&&h(i.connectorType);return}let m=core.getConnection(d);if(i&&orbitCore.getAdapterFromConnectorType(i.connectorType)!==orbitCore.OrbitAdapter.EVM||!m||C)return;let g=c?.address??c?.session?.address,T=c?.chainId??c?.session?.chainId;if((c?.isSignedIn??c?.isAuthenticated??false)&&i){let l=g&&(orbitCore.parseCaip10AccountId(g)?.address??g),L=m.address&&l&&m.address.toLowerCase()!==l.toLowerCase(),O=m.chainId&&T&&orbitCore.toEvmChainId(T)!==m.chainId;if(L||O){h(i.connectorType);return}}let x=m.connector,j={connectorType:x?`${orbitCore.OrbitAdapter.EVM}:${orbitCore.formatConnectorName(x.name)}`:i?.connectorType,address:m.address,chainId:m.chainId,rpcURL:m?.chain?.rpcUrls.default.http[0],isConnected:true,signMessage:l=>core.signMessage(d,{message:l})};p(j);};u();let{activeConnection:n}=a();if(n&&orbitCore.getAdapterFromConnectorType(n.connectorType)===orbitCore.OrbitAdapter.EVM){let o=core.getConnection(d);o&&o.isConnected&&p({signMessage:i=>core.signMessage(d,{message:i})});}return core.watchConnections(d,{onChange:t})}exports.checkIsWalletAddressContract=V;exports.createDefaultTransports=je;exports.createEVMConnectionsWatcher=Je;exports.impersonated=F;exports.safeSdkOptions=Ue;exports.satelliteEVMAdapter=ve;
1
+ 'use strict';var orbitCore=require('@tuwaio/orbit-core'),orbitEvm=require('@tuwaio/orbit-evm'),core=require('@wagmi/core'),viem=require('viem'),chains=require('viem/chains'),utils=require('viem/utils');var E=new Map;async function V({config:r,address:s,chainId:d,chains:c}){let h=`${Number(d)}:${s.toLowerCase()}`;if(E.has(h))return E.get(h);if(orbitEvm.createViemClient(Number(d),c)){let u=!!await core.getBytecode(r,{address:s,chainId:Number(d)});return E.set(h,u),u}else return false}function Pe(r,s){if(!r)throw new Error("Satellite EVM adapter requires a wagmi config object.");let d=t=>orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,orbitCore.formatConnectorName(t.name)),c=t=>core.getConnectors(r).find(n=>d(n)===t),h=new Set,p=()=>[...r.state.connections.values()].filter(({connector:t})=>h.has(t.uid)),a=(t,n)=>{let e=core.getConnection(r);return {connectorType:t,address:e.address??viem.zeroAddress,chainId:e.chainId??chains.mainnet.id,rpcURL:e.chain?.rpcUrls.default.http[0]??chains.mainnet.rpcUrls.default.http[0],isConnected:e.isConnected,isContractAddress:false,icon:n?.icon?.trim(),connector:n,signMessage:o=>core.signMessage(r,{message:o})}},u=async(t,n,e)=>(r.state.current!==n.uid&&await core.switchConnection(r,{connector:n}),Number(e)&&core.getConnection(r).chainId!==Number(e)&&await core.switchChain(r,{chainId:Number(e),connector:n}).catch(()=>{}),h.add(n.uid),a(t,n));return {key:orbitCore.OrbitAdapter.EVM,connect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{return r.state.connections.has(e.uid)?await u(t,e,n):(await core.connect(r,{connector:e,chainId:n}),h.add(e.uid),a(t,e))}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},reconnect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{if(!r.state.connections.has(e.uid)){if((await e.getAccounts().catch(()=>[])).length===0)return;let i={connector:e,isReconnecting:!0};r.state.connections.has(e.uid)||await core.connect(r,i);}return await u(t,e,n)}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},getLiveConnections:async()=>p().map(({connector:t,accounts:n,chainId:e})=>{let o=core.getChains(r).find(({id:i})=>i===e);return {connectorType:d(t),address:n[0]??viem.zeroAddress,chainId:e,rpcURL:o?.rpcUrls.default.http[0]??chains.mainnet.rpcUrls.default.http[0],isConnected:true,isContractAddress:false,icon:t.icon?.trim(),connector:t,signMessage:i=>core.signMessage(r,{message:i,connector:t})}}),disconnect:async t=>{if(t&&t.isConnected){let{connector:e}=t;await core.disconnect(r,{connector:e}),e&&h.delete(e.uid);return}let n=p().filter(({connector:e})=>!t||d(e)===t.connectorType);for(let{connector:e}of n){h.delete(e.uid);try{await core.disconnect(r,{connector:e});}catch{}}},getConnectors:()=>{let t=core.getConnectors(r);return {adapter:orbitCore.OrbitAdapter.EVM,connectors:t.map(n=>n)}},watchConnectors:t=>core.watchConnectors(r,{onChange:()=>t()}),checkAndSwitchNetwork:async t=>await orbitEvm.checkAndSwitchChain(Number(t),r),getBalance:async(t,n)=>{let e=await core.getBalance(r,{address:t,chainId:Number(n)});return {value:viem.formatUnits(e.value,e.decimals),symbol:e.symbol}},getExplorerUrl:(t,n)=>{let o=(n===void 0?core.getConnection(r).chain:s.find(i=>i.id===Number(n))??core.getChains(r).find(i=>i.id===Number(n)))?.blockExplorers?.default.url;if(o)return t?`${o.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`:o},getName:t=>orbitEvm.getName(t,s),getAvatar:t=>orbitEvm.getAvatar(t,s),getAddress:t=>orbitEvm.getAddress(t,s),checkIsContractAddress:async({address:t,chainId:n})=>{let e=core.getChains(r);return await V({config:r,address:t,chainId:n,chains:e})},getSafeConnectorChainId:async()=>{let n=core.getConnectors(r).find(e=>e.name==="Safe");if(n)return await n.getChainId()},switchConnection:async t=>{let n=c(t);if(!n)throw new Error(`Cannot find connector with type: ${t}`);try{await core.switchConnection(r,{connector:n});}catch(e){throw new Error(`Failed to switch to connector ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}}}W.type="impersonated";function W(r){let s=r.features??{},d=false,c,h;return core.createConnector(p=>({id:"impersonated",name:"Impersonated Connector",type:W.type,async setup(){c=p.chains[0].id;},async connect({chainId:a}={}){if(s.connectError)throw typeof s.connectError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to connect.")):s.connectError;let{request:u}=await this.getProvider(),t=await u({method:"eth_requestAccounts"}),n=await this.getChainId();return a&&n!==a&&(n=(await this.switchChain({chainId:a})).id),d=true,{accounts:t,chainId:n}},async disconnect(){d=false,h=void 0;},async getAccounts(){if(!d)throw new Error("Not connected connector");let{request:a}=await this.getProvider();return (await a({method:"eth_accounts"})).map(viem.getAddress)},async getChainId(){let{request:a}=await this.getProvider(),u=await a({method:"eth_chainId"});return viem.fromHex(u,"number")},async isAuthorized(){return d?!!(await this.getAccounts()).length:false},async switchChain({chainId:a}){let u=p.chains.find(n=>n.id===a);if(!u)throw new viem.SwitchChainError(new core.ChainNotConfiguredError);let{request:t}=await this.getProvider();return await t({method:"wallet_switchEthereumChain",params:[{chainId:viem.numberToHex(a)}]}),u},onAccountsChanged(a){a.length===0?this.onDisconnect():p.emitter.emit("change",{accounts:a.map(viem.getAddress)});},onChainChanged(a){let u=Number(a);p.emitter.emit("change",{chainId:u});},async onDisconnect(){p.emitter.emit("disconnect"),d=false,h=void 0;},async getProvider({chainId:a}={}){h=orbitCore.impersonatedHelpers?.getImpersonated()?[orbitCore.impersonatedHelpers.getImpersonated()||viem.zeroAddress]:void 0;let t=(p.chains.find(e=>e.id===a)??p.chains[0]).rpcUrls.default.http[0];return viem.custom({request:async({method:e,params:o})=>{if(e==="eth_chainId")return viem.numberToHex(c);if(e==="eth_requestAccounts"||e==="eth_accounts")return h??[];if(e==="eth_signTypedData_v4"&&s.signTypedDataError)throw typeof s.signTypedDataError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to sign typed data.")):s.signTypedDataError;if(e==="wallet_switchEthereumChain"){if(s.switchChainError)throw typeof s.switchChainError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to switch chain.")):s.switchChainError;c=viem.fromHex(o[0].chainId,"number"),this.onChainChanged(c.toString());return}if(e==="personal_sign"){if(s.signMessageError)throw typeof s.signMessageError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to sign message.")):s.signMessageError;e="eth_sign",o=[o[1],o[0]];}let i={method:e,params:o},{error:m,result:C}=await utils.rpc.http(t,{body:i});if(m)throw new viem.RpcRequestError({body:i,error:m,url:t});return C}})({retryCount:1})}}))}var _e={allowedDomains:[/^https:\/\/([a-z0-9-]+\.)*gnosis-safe\.io$/,/^https:\/\/([a-z0-9-]+\.)*app\.safe\.global$/,/^https:\/\/([a-z0-9-]+\.)*metissafe\.tech$/],debug:false};var Le=r=>r.reduce((s,d)=>{let c=d.id;return s[c]=viem.http(),s},{});function Qe(r,s){let{wagmiConfig:d}=r,c=r.siwx??(r.siwe?{enabled:r.siwe.enabled,isSignedIn:r.siwe.isSignedIn,isRejected:r.siwe.isRejected}:void 0),{disconnect:h,updateActiveConnection:p}=s,a=()=>s.getState?.()??s,u=()=>{let o=c?.isRejected||c?.status==="error",i=c?.isSignedIn??c?.isAuthenticated??false;if(c?.enabled!==false&&!i&&o){let{activeConnection:C}=a();C&&h(C.connectorType);}},t=o=>{let{activeConnection:i,connectionError:m}=a();if(i&&orbitCore.getAdapterFromConnectorType(i.connectorType)!==orbitCore.OrbitAdapter.EVM)return;if(o.length===0){i&&h(i.connectorType);return}let C=core.getConnection(d);if(i&&orbitCore.getAdapterFromConnectorType(i.connectorType)!==orbitCore.OrbitAdapter.EVM||!C||m)return;let g=c?.address??c?.session?.address,T=c?.chainId??c?.session?.chainId;if((c?.isSignedIn??c?.isAuthenticated??false)&&i){let l=g&&(orbitCore.parseCaip10AccountId(g)?.address??g),L=C.address&&l&&C.address.toLowerCase()!==l.toLowerCase(),O=C.chainId&&T&&orbitCore.toEvmChainId(T)!==C.chainId;if(L||O){h(i.connectorType);return}}let x=C.connector,j={connectorType:x?`${orbitCore.OrbitAdapter.EVM}:${orbitCore.formatConnectorName(x.name)}`:i?.connectorType,address:C.address,chainId:C.chainId,rpcURL:C?.chain?.rpcUrls.default.http[0],isConnected:true,signMessage:l=>core.signMessage(d,{message:l})};p(j);};u();let{activeConnection:n}=a();if(n&&orbitCore.getAdapterFromConnectorType(n.connectorType)===orbitCore.OrbitAdapter.EVM){let o=core.getConnection(d);o&&o.isConnected&&p({signMessage:i=>core.signMessage(d,{message:i})});}return core.watchConnections(d,{onChange:t})}exports.checkIsWalletAddressContract=V;exports.createDefaultTransports=Le;exports.createEVMConnectionsWatcher=Qe;exports.impersonated=W;exports.safeSdkOptions=_e;exports.satelliteEVMAdapter=Pe;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import {OrbitAdapter,impersonatedHelpers,getAdapterFromConnectorType,parseCaip10AccountId,toEvmChainId,formatConnectorName,getConnectorTypeFromName}from'@tuwaio/orbit-core';import {createViemClient,getAddress,getAvatar,getName,checkAndSwitchChain}from'@tuwaio/orbit-evm';import {getBytecode,switchConnection,getConnectors,getChains,getConnection,getBalance,disconnect,signMessage,connect,createConnector,ChainNotConfiguredError,watchConnections,switchChain}from'@wagmi/core';import {formatUnits,zeroAddress,custom,numberToHex,UserRejectedRequestError,fromHex,RpcRequestError,getAddress as getAddress$1,SwitchChainError,http}from'viem';import {mainnet}from'viem/chains';import {rpc}from'viem/utils';var E=new Map;async function V({config:r,address:s,chainId:d,chains:c}){let h=`${Number(d)}:${s.toLowerCase()}`;if(E.has(h))return E.get(h);if(createViemClient(Number(d),c)){let u=!!await getBytecode(r,{address:s,chainId:Number(d)});return E.set(h,u),u}else return false}function ve(r,s){if(!r)throw new Error("Satellite EVM adapter requires a wagmi config object.");let d=t=>getConnectorTypeFromName(OrbitAdapter.EVM,formatConnectorName(t.name)),c=t=>getConnectors(r).find(n=>d(n)===t),h=new Set,p=()=>[...r.state.connections.values()].filter(({connector:t})=>h.has(t.uid)),a=(t,n)=>{let e=getConnection(r);return {connectorType:t,address:e.address??zeroAddress,chainId:e.chainId??mainnet.id,rpcURL:e.chain?.rpcUrls.default.http[0]??mainnet.rpcUrls.default.http[0],isConnected:e.isConnected,isContractAddress:false,icon:n?.icon?.trim(),connector:n,signMessage:o=>signMessage(r,{message:o})}},u=async(t,n,e)=>(r.state.current!==n.uid&&await switchConnection(r,{connector:n}),Number(e)&&getConnection(r).chainId!==Number(e)&&await switchChain(r,{chainId:Number(e),connector:n}).catch(()=>{}),h.add(n.uid),a(t,n));return {key:OrbitAdapter.EVM,connect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{return r.state.connections.has(e.uid)?await u(t,e,n):(await connect(r,{connector:e,chainId:n}),h.add(e.uid),a(t,e))}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},reconnect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{if(!r.state.connections.has(e.uid)){if((await e.getAccounts().catch(()=>[])).length===0)return;let i={connector:e,isReconnecting:!0};r.state.connections.has(e.uid)||await connect(r,i);}return await u(t,e,n)}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},getLiveConnections:async()=>p().map(({connector:t,accounts:n,chainId:e})=>{let o=getChains(r).find(({id:i})=>i===e);return {connectorType:d(t),address:n[0]??zeroAddress,chainId:e,rpcURL:o?.rpcUrls.default.http[0]??mainnet.rpcUrls.default.http[0],isConnected:true,isContractAddress:false,icon:t.icon?.trim(),connector:t,signMessage:i=>signMessage(r,{message:i,connector:t})}}),disconnect:async t=>{if(t&&t.isConnected){let{connector:e}=t;await disconnect(r,{connector:e}),e&&h.delete(e.uid);return}let n=p().filter(({connector:e})=>!t||d(e)===t.connectorType);for(let{connector:e}of n){h.delete(e.uid);try{await disconnect(r,{connector:e});}catch{}}},getConnectors:()=>{let t=getConnectors(r);return {adapter:OrbitAdapter.EVM,connectors:t.map(n=>n)}},checkAndSwitchNetwork:async t=>await checkAndSwitchChain(Number(t),r),getBalance:async(t,n)=>{let e=await getBalance(r,{address:t,chainId:Number(n)});return {value:formatUnits(e.value,e.decimals),symbol:e.symbol}},getExplorerUrl:(t,n)=>{let o=(n===void 0?getConnection(r).chain:s.find(i=>i.id===Number(n))??getChains(r).find(i=>i.id===Number(n)))?.blockExplorers?.default.url;if(o)return t?`${o.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`:o},getName:t=>getName(t,s),getAvatar:t=>getAvatar(t,s),getAddress:t=>getAddress(t,s),checkIsContractAddress:async({address:t,chainId:n})=>{let e=getChains(r);return await V({config:r,address:t,chainId:n,chains:e})},getSafeConnectorChainId:async()=>{let n=getConnectors(r).find(e=>e.name==="Safe");if(n)return await n.getChainId()},switchConnection:async t=>{let n=c(t);if(!n)throw new Error(`Cannot find connector with type: ${t}`);try{await switchConnection(r,{connector:n});}catch(e){throw new Error(`Failed to switch to connector ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}}}F.type="impersonated";function F(r){let s=r.features??{},d=false,c,h;return createConnector(p=>({id:"impersonated",name:"Impersonated Connector",type:F.type,async setup(){c=p.chains[0].id;},async connect({chainId:a}={}){if(s.connectError)throw typeof s.connectError=="boolean"?new UserRejectedRequestError(new Error("Failed to connect.")):s.connectError;let{request:u}=await this.getProvider(),t=await u({method:"eth_requestAccounts"}),n=await this.getChainId();return a&&n!==a&&(n=(await this.switchChain({chainId:a})).id),d=true,{accounts:t,chainId:n}},async disconnect(){d=false,h=void 0;},async getAccounts(){if(!d)throw new Error("Not connected connector");let{request:a}=await this.getProvider();return (await a({method:"eth_accounts"})).map(getAddress$1)},async getChainId(){let{request:a}=await this.getProvider(),u=await a({method:"eth_chainId"});return fromHex(u,"number")},async isAuthorized(){return d?!!(await this.getAccounts()).length:false},async switchChain({chainId:a}){let u=p.chains.find(n=>n.id===a);if(!u)throw new SwitchChainError(new ChainNotConfiguredError);let{request:t}=await this.getProvider();return await t({method:"wallet_switchEthereumChain",params:[{chainId:numberToHex(a)}]}),u},onAccountsChanged(a){a.length===0?this.onDisconnect():p.emitter.emit("change",{accounts:a.map(getAddress$1)});},onChainChanged(a){let u=Number(a);p.emitter.emit("change",{chainId:u});},async onDisconnect(){p.emitter.emit("disconnect"),d=false,h=void 0;},async getProvider({chainId:a}={}){h=impersonatedHelpers?.getImpersonated()?[impersonatedHelpers.getImpersonated()||zeroAddress]:void 0;let t=(p.chains.find(e=>e.id===a)??p.chains[0]).rpcUrls.default.http[0];return custom({request:async({method:e,params:o})=>{if(e==="eth_chainId")return numberToHex(c);if(e==="eth_requestAccounts"||e==="eth_accounts")return h??[];if(e==="eth_signTypedData_v4"&&s.signTypedDataError)throw typeof s.signTypedDataError=="boolean"?new UserRejectedRequestError(new Error("Failed to sign typed data.")):s.signTypedDataError;if(e==="wallet_switchEthereumChain"){if(s.switchChainError)throw typeof s.switchChainError=="boolean"?new UserRejectedRequestError(new Error("Failed to switch chain.")):s.switchChainError;c=fromHex(o[0].chainId,"number"),this.onChainChanged(c.toString());return}if(e==="personal_sign"){if(s.signMessageError)throw typeof s.signMessageError=="boolean"?new UserRejectedRequestError(new Error("Failed to sign message.")):s.signMessageError;e="eth_sign",o=[o[1],o[0]];}let i={method:e,params:o},{error:C,result:m}=await rpc.http(t,{body:i});if(C)throw new RpcRequestError({body:i,error:C,url:t});return m}})({retryCount:1})}}))}var Ue={allowedDomains:[/^https:\/\/([a-z0-9-]+\.)*gnosis-safe\.io$/,/^https:\/\/([a-z0-9-]+\.)*app\.safe\.global$/,/^https:\/\/([a-z0-9-]+\.)*metissafe\.tech$/],debug:false};var je=r=>r.reduce((s,d)=>{let c=d.id;return s[c]=http(),s},{});function Je(r,s){let{wagmiConfig:d}=r,c=r.siwx??(r.siwe?{enabled:r.siwe.enabled,isSignedIn:r.siwe.isSignedIn,isRejected:r.siwe.isRejected}:void 0),{disconnect:h,updateActiveConnection:p}=s,a=()=>s.getState?.()??s,u=()=>{let o=c?.isRejected||c?.status==="error",i=c?.isSignedIn??c?.isAuthenticated??false;if(c?.enabled!==false&&!i&&o){let{activeConnection:m}=a();m&&h(m.connectorType);}},t=o=>{let{activeConnection:i,connectionError:C}=a();if(i&&getAdapterFromConnectorType(i.connectorType)!==OrbitAdapter.EVM)return;if(o.length===0){i&&h(i.connectorType);return}let m=getConnection(d);if(i&&getAdapterFromConnectorType(i.connectorType)!==OrbitAdapter.EVM||!m||C)return;let g=c?.address??c?.session?.address,T=c?.chainId??c?.session?.chainId;if((c?.isSignedIn??c?.isAuthenticated??false)&&i){let l=g&&(parseCaip10AccountId(g)?.address??g),L=m.address&&l&&m.address.toLowerCase()!==l.toLowerCase(),O=m.chainId&&T&&toEvmChainId(T)!==m.chainId;if(L||O){h(i.connectorType);return}}let x=m.connector,j={connectorType:x?`${OrbitAdapter.EVM}:${formatConnectorName(x.name)}`:i?.connectorType,address:m.address,chainId:m.chainId,rpcURL:m?.chain?.rpcUrls.default.http[0],isConnected:true,signMessage:l=>signMessage(d,{message:l})};p(j);};u();let{activeConnection:n}=a();if(n&&getAdapterFromConnectorType(n.connectorType)===OrbitAdapter.EVM){let o=getConnection(d);o&&o.isConnected&&p({signMessage:i=>signMessage(d,{message:i})});}return watchConnections(d,{onChange:t})}export{V as checkIsWalletAddressContract,je as createDefaultTransports,Je as createEVMConnectionsWatcher,F as impersonated,Ue as safeSdkOptions,ve as satelliteEVMAdapter};
1
+ import {OrbitAdapter,impersonatedHelpers,getAdapterFromConnectorType,parseCaip10AccountId,toEvmChainId,formatConnectorName,getConnectorTypeFromName}from'@tuwaio/orbit-core';import {createViemClient,getAddress,getAvatar,getName,checkAndSwitchChain}from'@tuwaio/orbit-evm';import {getBytecode,switchConnection,getConnectors,getChains,getConnection,getBalance,watchConnectors,disconnect,signMessage,connect,createConnector,ChainNotConfiguredError,watchConnections,switchChain}from'@wagmi/core';import {formatUnits,zeroAddress,custom,numberToHex,UserRejectedRequestError,fromHex,RpcRequestError,getAddress as getAddress$1,SwitchChainError,http}from'viem';import {mainnet}from'viem/chains';import {rpc}from'viem/utils';var E=new Map;async function V({config:r,address:s,chainId:d,chains:c}){let h=`${Number(d)}:${s.toLowerCase()}`;if(E.has(h))return E.get(h);if(createViemClient(Number(d),c)){let u=!!await getBytecode(r,{address:s,chainId:Number(d)});return E.set(h,u),u}else return false}function Pe(r,s){if(!r)throw new Error("Satellite EVM adapter requires a wagmi config object.");let d=t=>getConnectorTypeFromName(OrbitAdapter.EVM,formatConnectorName(t.name)),c=t=>getConnectors(r).find(n=>d(n)===t),h=new Set,p=()=>[...r.state.connections.values()].filter(({connector:t})=>h.has(t.uid)),a=(t,n)=>{let e=getConnection(r);return {connectorType:t,address:e.address??zeroAddress,chainId:e.chainId??mainnet.id,rpcURL:e.chain?.rpcUrls.default.http[0]??mainnet.rpcUrls.default.http[0],isConnected:e.isConnected,isContractAddress:false,icon:n?.icon?.trim(),connector:n,signMessage:o=>signMessage(r,{message:o})}},u=async(t,n,e)=>(r.state.current!==n.uid&&await switchConnection(r,{connector:n}),Number(e)&&getConnection(r).chainId!==Number(e)&&await switchChain(r,{chainId:Number(e),connector:n}).catch(()=>{}),h.add(n.uid),a(t,n));return {key:OrbitAdapter.EVM,connect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{return r.state.connections.has(e.uid)?await u(t,e,n):(await connect(r,{connector:e,chainId:n}),h.add(e.uid),a(t,e))}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},reconnect:async({connectorType:t,chainId:n})=>{let e=c(t);if(!e)throw new Error("Cannot find connector with this wallet type");try{if(!r.state.connections.has(e.uid)){if((await e.getAccounts().catch(()=>[])).length===0)return;let i={connector:e,isReconnecting:!0};r.state.connections.has(e.uid)||await connect(r,i);}return await u(t,e,n)}catch(o){throw new Error(o instanceof Error?o.message:String(o),{cause:o})}},getLiveConnections:async()=>p().map(({connector:t,accounts:n,chainId:e})=>{let o=getChains(r).find(({id:i})=>i===e);return {connectorType:d(t),address:n[0]??zeroAddress,chainId:e,rpcURL:o?.rpcUrls.default.http[0]??mainnet.rpcUrls.default.http[0],isConnected:true,isContractAddress:false,icon:t.icon?.trim(),connector:t,signMessage:i=>signMessage(r,{message:i,connector:t})}}),disconnect:async t=>{if(t&&t.isConnected){let{connector:e}=t;await disconnect(r,{connector:e}),e&&h.delete(e.uid);return}let n=p().filter(({connector:e})=>!t||d(e)===t.connectorType);for(let{connector:e}of n){h.delete(e.uid);try{await disconnect(r,{connector:e});}catch{}}},getConnectors:()=>{let t=getConnectors(r);return {adapter:OrbitAdapter.EVM,connectors:t.map(n=>n)}},watchConnectors:t=>watchConnectors(r,{onChange:()=>t()}),checkAndSwitchNetwork:async t=>await checkAndSwitchChain(Number(t),r),getBalance:async(t,n)=>{let e=await getBalance(r,{address:t,chainId:Number(n)});return {value:formatUnits(e.value,e.decimals),symbol:e.symbol}},getExplorerUrl:(t,n)=>{let o=(n===void 0?getConnection(r).chain:s.find(i=>i.id===Number(n))??getChains(r).find(i=>i.id===Number(n)))?.blockExplorers?.default.url;if(o)return t?`${o.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`:o},getName:t=>getName(t,s),getAvatar:t=>getAvatar(t,s),getAddress:t=>getAddress(t,s),checkIsContractAddress:async({address:t,chainId:n})=>{let e=getChains(r);return await V({config:r,address:t,chainId:n,chains:e})},getSafeConnectorChainId:async()=>{let n=getConnectors(r).find(e=>e.name==="Safe");if(n)return await n.getChainId()},switchConnection:async t=>{let n=c(t);if(!n)throw new Error(`Cannot find connector with type: ${t}`);try{await switchConnection(r,{connector:n});}catch(e){throw new Error(`Failed to switch to connector ${t}: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}}}W.type="impersonated";function W(r){let s=r.features??{},d=false,c,h;return createConnector(p=>({id:"impersonated",name:"Impersonated Connector",type:W.type,async setup(){c=p.chains[0].id;},async connect({chainId:a}={}){if(s.connectError)throw typeof s.connectError=="boolean"?new UserRejectedRequestError(new Error("Failed to connect.")):s.connectError;let{request:u}=await this.getProvider(),t=await u({method:"eth_requestAccounts"}),n=await this.getChainId();return a&&n!==a&&(n=(await this.switchChain({chainId:a})).id),d=true,{accounts:t,chainId:n}},async disconnect(){d=false,h=void 0;},async getAccounts(){if(!d)throw new Error("Not connected connector");let{request:a}=await this.getProvider();return (await a({method:"eth_accounts"})).map(getAddress$1)},async getChainId(){let{request:a}=await this.getProvider(),u=await a({method:"eth_chainId"});return fromHex(u,"number")},async isAuthorized(){return d?!!(await this.getAccounts()).length:false},async switchChain({chainId:a}){let u=p.chains.find(n=>n.id===a);if(!u)throw new SwitchChainError(new ChainNotConfiguredError);let{request:t}=await this.getProvider();return await t({method:"wallet_switchEthereumChain",params:[{chainId:numberToHex(a)}]}),u},onAccountsChanged(a){a.length===0?this.onDisconnect():p.emitter.emit("change",{accounts:a.map(getAddress$1)});},onChainChanged(a){let u=Number(a);p.emitter.emit("change",{chainId:u});},async onDisconnect(){p.emitter.emit("disconnect"),d=false,h=void 0;},async getProvider({chainId:a}={}){h=impersonatedHelpers?.getImpersonated()?[impersonatedHelpers.getImpersonated()||zeroAddress]:void 0;let t=(p.chains.find(e=>e.id===a)??p.chains[0]).rpcUrls.default.http[0];return custom({request:async({method:e,params:o})=>{if(e==="eth_chainId")return numberToHex(c);if(e==="eth_requestAccounts"||e==="eth_accounts")return h??[];if(e==="eth_signTypedData_v4"&&s.signTypedDataError)throw typeof s.signTypedDataError=="boolean"?new UserRejectedRequestError(new Error("Failed to sign typed data.")):s.signTypedDataError;if(e==="wallet_switchEthereumChain"){if(s.switchChainError)throw typeof s.switchChainError=="boolean"?new UserRejectedRequestError(new Error("Failed to switch chain.")):s.switchChainError;c=fromHex(o[0].chainId,"number"),this.onChainChanged(c.toString());return}if(e==="personal_sign"){if(s.signMessageError)throw typeof s.signMessageError=="boolean"?new UserRejectedRequestError(new Error("Failed to sign message.")):s.signMessageError;e="eth_sign",o=[o[1],o[0]];}let i={method:e,params:o},{error:m,result:C}=await rpc.http(t,{body:i});if(m)throw new RpcRequestError({body:i,error:m,url:t});return C}})({retryCount:1})}}))}var _e={allowedDomains:[/^https:\/\/([a-z0-9-]+\.)*gnosis-safe\.io$/,/^https:\/\/([a-z0-9-]+\.)*app\.safe\.global$/,/^https:\/\/([a-z0-9-]+\.)*metissafe\.tech$/],debug:false};var Le=r=>r.reduce((s,d)=>{let c=d.id;return s[c]=http(),s},{});function Qe(r,s){let{wagmiConfig:d}=r,c=r.siwx??(r.siwe?{enabled:r.siwe.enabled,isSignedIn:r.siwe.isSignedIn,isRejected:r.siwe.isRejected}:void 0),{disconnect:h,updateActiveConnection:p}=s,a=()=>s.getState?.()??s,u=()=>{let o=c?.isRejected||c?.status==="error",i=c?.isSignedIn??c?.isAuthenticated??false;if(c?.enabled!==false&&!i&&o){let{activeConnection:C}=a();C&&h(C.connectorType);}},t=o=>{let{activeConnection:i,connectionError:m}=a();if(i&&getAdapterFromConnectorType(i.connectorType)!==OrbitAdapter.EVM)return;if(o.length===0){i&&h(i.connectorType);return}let C=getConnection(d);if(i&&getAdapterFromConnectorType(i.connectorType)!==OrbitAdapter.EVM||!C||m)return;let g=c?.address??c?.session?.address,T=c?.chainId??c?.session?.chainId;if((c?.isSignedIn??c?.isAuthenticated??false)&&i){let l=g&&(parseCaip10AccountId(g)?.address??g),L=C.address&&l&&C.address.toLowerCase()!==l.toLowerCase(),O=C.chainId&&T&&toEvmChainId(T)!==C.chainId;if(L||O){h(i.connectorType);return}}let x=C.connector,j={connectorType:x?`${OrbitAdapter.EVM}:${formatConnectorName(x.name)}`:i?.connectorType,address:C.address,chainId:C.chainId,rpcURL:C?.chain?.rpcUrls.default.http[0],isConnected:true,signMessage:l=>signMessage(d,{message:l})};p(j);};u();let{activeConnection:n}=a();if(n&&getAdapterFromConnectorType(n.connectorType)===OrbitAdapter.EVM){let o=getConnection(d);o&&o.isConnected&&p({signMessage:i=>signMessage(d,{message:i})});}return watchConnections(d,{onChange:t})}export{V as checkIsWalletAddressContract,Le as createDefaultTransports,Qe as createEVMConnectionsWatcher,W as impersonated,_e as safeSdkOptions,Pe as satelliteEVMAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/satellite-evm",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -53,11 +53,11 @@
53
53
  "devDependencies": {
54
54
  "@tuwaio/orbit-core": "^0.6.0",
55
55
  "@tuwaio/orbit-evm": "^0.4.0",
56
- "@tuwaio/satellite-core": "^0.11.1",
57
- "@wagmi/core": "^3.6.5",
56
+ "@tuwaio/satellite-core": "^0.11.2",
57
+ "@wagmi/core": "^3.6.7",
58
58
  "tsup": "^9.0.0",
59
59
  "typescript": "6.0.3",
60
- "viem": "^2.57.7",
60
+ "viem": "^2.57.12",
61
61
  "vitest": "^5.0.5"
62
62
  },
63
63
  "scripts": {