@tuwaio/satellite-evm 0.3.9 → 0.4.0
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 +9 -51
- package/dist/index.d.mts +15 -11
- package/dist/index.d.ts +15 -11
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -110,77 +110,35 @@ function AppProviders({ children }: { children: React.ReactNode }) {
|
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
|
-
## 🔐 Sign-In
|
|
113
|
+
## 🔐 Sign-In With X (SIWX) Session Integration
|
|
114
114
|
|
|
115
|
-
The `
|
|
116
|
-
|
|
117
|
-
This ensures that the SIWE flow is automatically triggered after a successful wallet connection.
|
|
115
|
+
The `EVMConnectorsWatcher` component accepts a `siwx` prop directly compatible with `@tuwaio/siwx-react`. It monitors session status and automatically handles wallet disconnections if the user switches accounts or chains without an active SIWX session.
|
|
118
116
|
|
|
119
117
|
```tsx
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
import { useSiweAuth, SiweNextAuthProvider } from '@tuwaio/satellite-siwe-next-auth';
|
|
118
|
+
import { useSiwxSession } from '@tuwaio/siwx-react';
|
|
123
119
|
import { SatelliteConnectProvider } from '@tuwaio/satellite-react';
|
|
124
120
|
import { EVMConnectorsWatcher } from '@tuwaio/satellite-react/evm';
|
|
125
121
|
import { satelliteEVMAdapter } from '@tuwaio/satellite-evm';
|
|
126
|
-
import { WagmiProvider } from 'wagmi';
|
|
127
|
-
import { wagmiConfig } from './your-wagmi-config'; // Your Wagmi config
|
|
128
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
129
|
-
import { ReactNode, useState } from 'react';
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// Get SIWE auth state and methods from the provider above
|
|
134
|
-
const { signInWithSiwe, enabled: siweEnabled, isRejected, isSignedIn } = useSiweAuth();
|
|
123
|
+
function AppProviders({ children }: { children: ReactNode }) {
|
|
124
|
+
const siwxSession = useSiwxSession();
|
|
135
125
|
|
|
136
126
|
return (
|
|
137
|
-
<SatelliteConnectProvider
|
|
138
|
-
|
|
139
|
-
adapter={satelliteEVMAdapter(wagmiConfig, appEVMChains, siweEnabled ? signInWithSiwe : undefined)}
|
|
140
|
-
autoConnect={true}
|
|
141
|
-
>
|
|
142
|
-
{/* Pass SIWE state to watcher for handling disconnections on SIWE rejection */}
|
|
143
|
-
<EVMConnectorsWatcher wagmiConfig={wagmiConfig} siwe={{ isSignedIn, isRejected, enabled: siweEnabled }} />
|
|
127
|
+
<SatelliteConnectProvider adapter={satelliteEVMAdapter(wagmiConfig, appEVMChains)} autoConnect={true}>
|
|
128
|
+
<EVMConnectorsWatcher wagmiConfig={wagmiConfig} siwx={siwxSession} />
|
|
144
129
|
{children}
|
|
145
130
|
</SatelliteConnectProvider>
|
|
146
131
|
);
|
|
147
132
|
}
|
|
148
|
-
|
|
149
|
-
// Step 2: Compose all providers in the correct order
|
|
150
|
-
// Create QueryClient
|
|
151
|
-
const queryClient = new QueryClient();
|
|
152
|
-
|
|
153
|
-
function Providers({ children }: { children: ReactNode }) {
|
|
154
|
-
return (
|
|
155
|
-
<WagmiProvider config={wagmiConfig}>
|
|
156
|
-
<QueryClientProvider client={queryClient}>
|
|
157
|
-
{/* SIWE Provider must wrap SatelliteSiweProvider to provide context */}
|
|
158
|
-
<SiweNextAuthProvider wagmiConfig={wagmiConfig} enabled={true}>
|
|
159
|
-
<SatelliteSiweProvider>{children}</SatelliteSiweProvider>
|
|
160
|
-
</SiweNextAuthProvider>
|
|
161
|
-
</QueryClientProvider>
|
|
162
|
-
</WagmiProvider>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Step 3: Use Providers in your application layout
|
|
167
|
-
function RootLayout({ children }: { children: React.ReactNode }) {
|
|
168
|
-
return (
|
|
169
|
-
<Providers>
|
|
170
|
-
{/* Your application components */}
|
|
171
|
-
{children}
|
|
172
|
-
</Providers>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
133
|
```
|
|
176
134
|
|
|
177
135
|
---
|
|
178
136
|
|
|
179
|
-
|
|
137
|
+
## 🛠️ Core Utilities
|
|
180
138
|
|
|
181
139
|
- **`createDefaultTransports`**: Helper to create default `http` transports for each chain in your `wagmiConfig`.
|
|
182
140
|
- **`checkIsWalletAddressContract`**: Utility to check if a connected address is a smart contract address. The result is cached in memory.
|
|
183
|
-
- **`createEVMConnectionsWatcher`**: Framework-agnostic utility to monitor wagmi connection changes and synchronize them with the global state store. Handles account switches, network changes, disconnections, and optional
|
|
141
|
+
- **`createEVMConnectionsWatcher`**: Framework-agnostic utility to monitor wagmi connection changes and synchronize them with the global state store. Handles account switches, network changes, disconnections, and optional SIWX session rejection scenarios. Returns a cleanup function.
|
|
184
142
|
|
|
185
143
|
---
|
|
186
144
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseConnector, SatelliteAdapter } from '@tuwaio/satellite-core';
|
|
1
|
+
import { BaseConnector, SatelliteAdapter, SatelliteSiwxState } from '@tuwaio/satellite-core';
|
|
2
2
|
import * as _wagmi_core from '@wagmi/core';
|
|
3
3
|
import { Connector, CreateConnectorFn, Config, CreateConfigParameters } from '@wagmi/core';
|
|
4
4
|
import { Chain } from 'viem/chains';
|
|
@@ -39,7 +39,7 @@ interface EVMConnection extends BaseConnector {
|
|
|
39
39
|
* const evmAdapter = satelliteEVMAdapter(config, chains);
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
|
-
declare function satelliteEVMAdapter(config: Config, chains: readonly [Chain, ...Chain[]]
|
|
42
|
+
declare function satelliteEVMAdapter(config: Config, chains: readonly [Chain, ...Chain[]]): SatelliteAdapter<ConnectorEVM, EVMConnection>;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Configuration parameters for impersonated wallet connector
|
|
@@ -145,14 +145,13 @@ interface EVMWatcherCallbacks {
|
|
|
145
145
|
interface EVMWatcherConfig {
|
|
146
146
|
/** Wagmi configuration object required for connection monitoring */
|
|
147
147
|
wagmiConfig: Config;
|
|
148
|
-
/** Optional Sign-In With
|
|
148
|
+
/** Optional Sign-In With X (SIWX) session state */
|
|
149
|
+
siwx?: SatelliteSiwxState;
|
|
150
|
+
/** @deprecated Legacy SIWE prop alias for backwards compatibility */
|
|
149
151
|
siwe?: {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
isSignedIn: boolean;
|
|
154
|
-
/** Whether the user has rejected the SIWE signature request */
|
|
155
|
-
isRejected: boolean;
|
|
152
|
+
enabled?: boolean;
|
|
153
|
+
isSignedIn?: boolean;
|
|
154
|
+
isRejected?: boolean;
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
/**
|
|
@@ -162,20 +161,25 @@ interface EVMWatcherConfig {
|
|
|
162
161
|
* This function provides a pure, framework-agnostic way to watch EVM connections
|
|
163
162
|
* without being tied to React hooks or components.
|
|
164
163
|
*
|
|
165
|
-
* @param config - Configuration object containing wagmi config and optional
|
|
164
|
+
* @param config - Configuration object containing wagmi config and optional SIWX session settings
|
|
166
165
|
* @param callbacks - Callback functions for interacting with the global state
|
|
167
166
|
* @returns A cleanup function to stop watching connections
|
|
168
167
|
*
|
|
169
168
|
* @example
|
|
170
169
|
* ```typescript
|
|
171
170
|
* const unwatch = createEVMConnectionsWatcher(
|
|
172
|
-
* { wagmiConfig,
|
|
171
|
+
* { wagmiConfig, siwx: { enabled: true, isSignedIn: true, isRejected: false } },
|
|
173
172
|
* { activeConnection, disconnect, connectionError, updateActiveConnection }
|
|
174
173
|
* );
|
|
175
174
|
*
|
|
176
175
|
* // Later, when you need to stop watching:
|
|
177
176
|
* unwatch();
|
|
178
177
|
* ```
|
|
178
|
+
*
|
|
179
|
+
* @remarks
|
|
180
|
+
* Evaluates session parity on account and network switches. If `siwx` is enabled and
|
|
181
|
+
* the active session address or chainId does not match the newly connected wallet state,
|
|
182
|
+
* it automatically triggers a `disconnect()` to prevent stale session attacks.
|
|
179
183
|
*/
|
|
180
184
|
declare function createEVMConnectionsWatcher(config: EVMWatcherConfig, callbacks: EVMWatcherCallbacks): () => void;
|
|
181
185
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseConnector, SatelliteAdapter } from '@tuwaio/satellite-core';
|
|
1
|
+
import { BaseConnector, SatelliteAdapter, SatelliteSiwxState } from '@tuwaio/satellite-core';
|
|
2
2
|
import * as _wagmi_core from '@wagmi/core';
|
|
3
3
|
import { Connector, CreateConnectorFn, Config, CreateConfigParameters } from '@wagmi/core';
|
|
4
4
|
import { Chain } from 'viem/chains';
|
|
@@ -39,7 +39,7 @@ interface EVMConnection extends BaseConnector {
|
|
|
39
39
|
* const evmAdapter = satelliteEVMAdapter(config, chains);
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
|
-
declare function satelliteEVMAdapter(config: Config, chains: readonly [Chain, ...Chain[]]
|
|
42
|
+
declare function satelliteEVMAdapter(config: Config, chains: readonly [Chain, ...Chain[]]): SatelliteAdapter<ConnectorEVM, EVMConnection>;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Configuration parameters for impersonated wallet connector
|
|
@@ -145,14 +145,13 @@ interface EVMWatcherCallbacks {
|
|
|
145
145
|
interface EVMWatcherConfig {
|
|
146
146
|
/** Wagmi configuration object required for connection monitoring */
|
|
147
147
|
wagmiConfig: Config;
|
|
148
|
-
/** Optional Sign-In With
|
|
148
|
+
/** Optional Sign-In With X (SIWX) session state */
|
|
149
|
+
siwx?: SatelliteSiwxState;
|
|
150
|
+
/** @deprecated Legacy SIWE prop alias for backwards compatibility */
|
|
149
151
|
siwe?: {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
isSignedIn: boolean;
|
|
154
|
-
/** Whether the user has rejected the SIWE signature request */
|
|
155
|
-
isRejected: boolean;
|
|
152
|
+
enabled?: boolean;
|
|
153
|
+
isSignedIn?: boolean;
|
|
154
|
+
isRejected?: boolean;
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
/**
|
|
@@ -162,20 +161,25 @@ interface EVMWatcherConfig {
|
|
|
162
161
|
* This function provides a pure, framework-agnostic way to watch EVM connections
|
|
163
162
|
* without being tied to React hooks or components.
|
|
164
163
|
*
|
|
165
|
-
* @param config - Configuration object containing wagmi config and optional
|
|
164
|
+
* @param config - Configuration object containing wagmi config and optional SIWX session settings
|
|
166
165
|
* @param callbacks - Callback functions for interacting with the global state
|
|
167
166
|
* @returns A cleanup function to stop watching connections
|
|
168
167
|
*
|
|
169
168
|
* @example
|
|
170
169
|
* ```typescript
|
|
171
170
|
* const unwatch = createEVMConnectionsWatcher(
|
|
172
|
-
* { wagmiConfig,
|
|
171
|
+
* { wagmiConfig, siwx: { enabled: true, isSignedIn: true, isRejected: false } },
|
|
173
172
|
* { activeConnection, disconnect, connectionError, updateActiveConnection }
|
|
174
173
|
* );
|
|
175
174
|
*
|
|
176
175
|
* // Later, when you need to stop watching:
|
|
177
176
|
* unwatch();
|
|
178
177
|
* ```
|
|
178
|
+
*
|
|
179
|
+
* @remarks
|
|
180
|
+
* Evaluates session parity on account and network switches. If `siwx` is enabled and
|
|
181
|
+
* the active session address or chainId does not match the newly connected wallet state,
|
|
182
|
+
* it automatically triggers a `disconnect()` to prevent stale session attacks.
|
|
179
183
|
*/
|
|
180
184
|
declare function createEVMConnectionsWatcher(config: EVMWatcherConfig, callbacks: EVMWatcherCallbacks): () => void;
|
|
181
185
|
|
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
|
|
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 y=new Map;async function A({config:o,address:s,chainId:e,chains:n}){if(y.has(s))return y.get(s);if(orbitEvm.createViemClient(e,n)){let r=!!await core.getBytecode(o,{address:s});return y.set(s,r),r}else return false}function Ie(o,s){if(!o)throw new Error("Satellite EVM adapter requires a wagmi config object.");return {key:orbitCore.OrbitAdapter.EVM,connect:async({connectorType:e,chainId:n})=>{let a=core.getConnectors(o).find(r=>orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,orbitCore.formatConnectorName(r.name))===e);if(!a)throw new Error("Cannot find connector with this wallet type");try{await core.connect(o,{connector:a,chainId:n});let r=core.getConnection(o);return {connectorType:e,address:r.address??viem.zeroAddress,chainId:r.chainId??chains.mainnet.id,rpcURL:r.chain?.rpcUrls.default.http[0]??chains.mainnet.rpcUrls.default.http[0],isConnected:r.isConnected,isContractAddress:!1,icon:a?.icon?.trim(),connector:a,signMessage:c=>core.signMessage(o,{message:c})}}catch(r){throw new Error(r instanceof Error?r.message:String(r),{cause:r})}},disconnect:async e=>{if(e&&e.isConnected)await core.disconnect(o,{connector:e?.connector});else {let n=core.getConnectors(o);await Promise.allSettled(n.map(async t=>{await core.disconnect(o,{connector:t});}));}},getConnectors:()=>{let e=core.getConnectors(o);return {adapter:orbitCore.OrbitAdapter.EVM,connectors:e.map(n=>n)}},checkAndSwitchNetwork:async e=>await orbitEvm.checkAndSwitchChain(Number(e),o),getBalance:async(e,n)=>{let t=await core.getBalance(o,{address:e,chainId:Number(n)});return {value:viem.formatUnits(t.value,t.decimals),symbol:t.symbol}},getExplorerUrl:e=>{let{chain:n}=core.getConnection(o),t=n?.blockExplorers?.default.url;return e?`${t}/${e}`:t},getName:e=>orbitEvm.getName(e,s),getAvatar:e=>orbitEvm.getAvatar(e,s),getAddress:e=>orbitEvm.getAddress(e,s),checkIsContractAddress:async({address:e,chainId:n})=>{let t=core.getChains(o);return await A({config:o,address:e,chainId:n,chains:t})},getSafeConnectorChainId:async()=>{let n=core.getConnectors(o).find(t=>t.name==="Safe");if(n)return await n.getChainId()},switchConnection:async e=>{let t=core.getConnectors(o).find(a=>orbitCore.getConnectorTypeFromName(orbitCore.OrbitAdapter.EVM,orbitCore.formatConnectorName(a.name))===e);if(!t)throw new Error(`Cannot find connector with type: ${e}`);try{await core.switchConnection(o,{connector:t});}catch(a){throw new Error(`Failed to switch to connector ${e}: ${a instanceof Error?a.message:String(a)}`,{cause:a})}}}}q.type="impersonated";function q(o){let s=o.features??{},e=false,n,t;return core.createConnector(a=>({id:"impersonated",name:"Impersonated Connector",type:q.type,async setup(){n=a.chains[0].id;},async connect({chainId:r}={}){if(s.connectError)throw typeof s.connectError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to connect.")):s.connectError;let{request:c}=await this.getProvider(),p=await c({method:"eth_requestAccounts"}),u=await this.getChainId();return r&&u!==r&&(u=(await this.switchChain({chainId:r})).id),e=true,{accounts:p,chainId:u}},async disconnect(){e=false,t=void 0;},async getAccounts(){if(!e)throw new Error("Not connected connector");let{request:r}=await this.getProvider();return (await r({method:"eth_accounts"})).map(viem.getAddress)},async getChainId(){let{request:r}=await this.getProvider(),c=await r({method:"eth_chainId"});return viem.fromHex(c,"number")},async isAuthorized(){return e?!!(await this.getAccounts()).length:false},async switchChain({chainId:r}){let c=a.chains.find(u=>u.id===r);if(!c)throw new viem.SwitchChainError(new core.ChainNotConfiguredError);let{request:p}=await this.getProvider();return await p({method:"wallet_switchEthereumChain",params:[{chainId:viem.numberToHex(r)}]}),c},onAccountsChanged(r){r.length===0?this.onDisconnect():a.emitter.emit("change",{accounts:r.map(viem.getAddress)});},onChainChanged(r){let c=Number(r);a.emitter.emit("change",{chainId:c});},async onDisconnect(){a.emitter.emit("disconnect"),e=false,t=void 0;},async getProvider({chainId:r}={}){t=orbitCore.impersonatedHelpers?.getImpersonated()?[orbitCore.impersonatedHelpers.getImpersonated()||viem.zeroAddress]:void 0;let p=(a.chains.find(h=>h.id===r)??a.chains[0]).rpcUrls.default.http[0];return viem.custom({request:async({method:h,params:d})=>{if(h==="eth_chainId")return viem.numberToHex(n);if(h==="eth_requestAccounts")return t;if(h==="eth_signTypedData_v4"&&s.signTypedDataError)throw typeof s.signTypedDataError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to sign typed data.")):s.signTypedDataError;if(h==="wallet_switchEthereumChain"){if(s.switchChainError)throw typeof s.switchChainError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to switch chain.")):s.switchChainError;n=viem.fromHex(d[0].chainId,"number"),this.onChainChanged(n.toString());return}if(h==="personal_sign"){if(s.signMessageError)throw typeof s.signMessageError=="boolean"?new viem.UserRejectedRequestError(new Error("Failed to sign message.")):s.signMessageError;h="eth_sign",d=[d[1],d[0]];}let i={method:h,params:d},{error:m,result:l}=await utils.rpc.http(p,{body:i});if(m)throw new viem.RpcRequestError({body:i,error:m,url:p});return l}})({retryCount:1})}}))}var Pe={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false};var Ne=o=>o.reduce((s,e)=>{let n=e.id;return s[n]=viem.http(),s},{});function je(o,s){let{wagmiConfig:e}=o,n=o.siwx??(o.siwe?{enabled:o.siwe.enabled,isSignedIn:o.siwe.isSignedIn,isRejected:o.siwe.isRejected}:void 0),{activeConnection:t,disconnect:a,connectionError:r,updateActiveConnection:c}=s,p=()=>{let d=n?.isRejected||n?.status==="error",i=n?.isSignedIn??n?.isAuthenticated??false;n?.enabled!==false&&!i&&d&&t&&a(t.connectorType);},u=d=>{if(t&&orbitCore.getAdapterFromConnectorType(t.connectorType)!==orbitCore.OrbitAdapter.EVM)return;if(d.length===0){t&&a(t.connectorType);return}let i=core.getConnection(e);if(t&&orbitCore.getAdapterFromConnectorType(t.connectorType)!==orbitCore.OrbitAdapter.EVM||!i||r)return;let m=n?.address??n?.session?.address,l=n?.chainId??n?.session?.chainId;if((n?.isSignedIn??n?.isAuthenticated??false)&&t){let E=i.address&&m&&i.address.toLowerCase()!==m.toLowerCase()&&!m.toLowerCase().endsWith(i.address.toLowerCase()),_=i.chainId&&l&&String(i.chainId)!==String(l)&&!l.endsWith(`:${i.chainId}`);if(E||_){a(t.connectorType);return}}let I=i.connector,$={connectorType:I?`${orbitCore.OrbitAdapter.EVM}:${orbitCore.formatConnectorName(I.name)}`:t?.connectorType,address:i.address,chainId:i.chainId,rpcURL:i?.chain?.rpcUrls.default.http[0],isConnected:true,signMessage:E=>core.signMessage(e,{message:E})};c($);};if(p(),t&&orbitCore.getAdapterFromConnectorType(t.connectorType)===orbitCore.OrbitAdapter.EVM){let d=core.getConnection(e);d&&d.isConnected&&c({signMessage:i=>core.signMessage(e,{message:i})});}return core.watchConnections(e,{onChange:u})}exports.checkIsWalletAddressContract=A;exports.createDefaultTransports=Ne;exports.createEVMConnectionsWatcher=je;exports.impersonated=q;exports.safeSdkOptions=Pe;exports.satelliteEVMAdapter=Ie;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {OrbitAdapter,getConnectorTypeFromName,formatConnectorName,
|
|
1
|
+
import {OrbitAdapter,getConnectorTypeFromName,formatConnectorName,impersonatedHelpers,getAdapterFromConnectorType}from'@tuwaio/orbit-core';import {createViemClient,getAddress,getAvatar,getName,checkAndSwitchChain}from'@tuwaio/orbit-evm';import {getBytecode,getConnectors,switchConnection,getChains,getConnection,getBalance,disconnect,connect,signMessage,createConnector,ChainNotConfiguredError,watchConnections}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 y=new Map;async function A({config:o,address:s,chainId:e,chains:n}){if(y.has(s))return y.get(s);if(createViemClient(e,n)){let r=!!await getBytecode(o,{address:s});return y.set(s,r),r}else return false}function Ie(o,s){if(!o)throw new Error("Satellite EVM adapter requires a wagmi config object.");return {key:OrbitAdapter.EVM,connect:async({connectorType:e,chainId:n})=>{let a=getConnectors(o).find(r=>getConnectorTypeFromName(OrbitAdapter.EVM,formatConnectorName(r.name))===e);if(!a)throw new Error("Cannot find connector with this wallet type");try{await connect(o,{connector:a,chainId:n});let r=getConnection(o);return {connectorType:e,address:r.address??zeroAddress,chainId:r.chainId??mainnet.id,rpcURL:r.chain?.rpcUrls.default.http[0]??mainnet.rpcUrls.default.http[0],isConnected:r.isConnected,isContractAddress:!1,icon:a?.icon?.trim(),connector:a,signMessage:c=>signMessage(o,{message:c})}}catch(r){throw new Error(r instanceof Error?r.message:String(r),{cause:r})}},disconnect:async e=>{if(e&&e.isConnected)await disconnect(o,{connector:e?.connector});else {let n=getConnectors(o);await Promise.allSettled(n.map(async t=>{await disconnect(o,{connector:t});}));}},getConnectors:()=>{let e=getConnectors(o);return {adapter:OrbitAdapter.EVM,connectors:e.map(n=>n)}},checkAndSwitchNetwork:async e=>await checkAndSwitchChain(Number(e),o),getBalance:async(e,n)=>{let t=await getBalance(o,{address:e,chainId:Number(n)});return {value:formatUnits(t.value,t.decimals),symbol:t.symbol}},getExplorerUrl:e=>{let{chain:n}=getConnection(o),t=n?.blockExplorers?.default.url;return e?`${t}/${e}`:t},getName:e=>getName(e,s),getAvatar:e=>getAvatar(e,s),getAddress:e=>getAddress(e,s),checkIsContractAddress:async({address:e,chainId:n})=>{let t=getChains(o);return await A({config:o,address:e,chainId:n,chains:t})},getSafeConnectorChainId:async()=>{let n=getConnectors(o).find(t=>t.name==="Safe");if(n)return await n.getChainId()},switchConnection:async e=>{let t=getConnectors(o).find(a=>getConnectorTypeFromName(OrbitAdapter.EVM,formatConnectorName(a.name))===e);if(!t)throw new Error(`Cannot find connector with type: ${e}`);try{await switchConnection(o,{connector:t});}catch(a){throw new Error(`Failed to switch to connector ${e}: ${a instanceof Error?a.message:String(a)}`,{cause:a})}}}}q.type="impersonated";function q(o){let s=o.features??{},e=false,n,t;return createConnector(a=>({id:"impersonated",name:"Impersonated Connector",type:q.type,async setup(){n=a.chains[0].id;},async connect({chainId:r}={}){if(s.connectError)throw typeof s.connectError=="boolean"?new UserRejectedRequestError(new Error("Failed to connect.")):s.connectError;let{request:c}=await this.getProvider(),p=await c({method:"eth_requestAccounts"}),u=await this.getChainId();return r&&u!==r&&(u=(await this.switchChain({chainId:r})).id),e=true,{accounts:p,chainId:u}},async disconnect(){e=false,t=void 0;},async getAccounts(){if(!e)throw new Error("Not connected connector");let{request:r}=await this.getProvider();return (await r({method:"eth_accounts"})).map(getAddress$1)},async getChainId(){let{request:r}=await this.getProvider(),c=await r({method:"eth_chainId"});return fromHex(c,"number")},async isAuthorized(){return e?!!(await this.getAccounts()).length:false},async switchChain({chainId:r}){let c=a.chains.find(u=>u.id===r);if(!c)throw new SwitchChainError(new ChainNotConfiguredError);let{request:p}=await this.getProvider();return await p({method:"wallet_switchEthereumChain",params:[{chainId:numberToHex(r)}]}),c},onAccountsChanged(r){r.length===0?this.onDisconnect():a.emitter.emit("change",{accounts:r.map(getAddress$1)});},onChainChanged(r){let c=Number(r);a.emitter.emit("change",{chainId:c});},async onDisconnect(){a.emitter.emit("disconnect"),e=false,t=void 0;},async getProvider({chainId:r}={}){t=impersonatedHelpers?.getImpersonated()?[impersonatedHelpers.getImpersonated()||zeroAddress]:void 0;let p=(a.chains.find(h=>h.id===r)??a.chains[0]).rpcUrls.default.http[0];return custom({request:async({method:h,params:d})=>{if(h==="eth_chainId")return numberToHex(n);if(h==="eth_requestAccounts")return t;if(h==="eth_signTypedData_v4"&&s.signTypedDataError)throw typeof s.signTypedDataError=="boolean"?new UserRejectedRequestError(new Error("Failed to sign typed data.")):s.signTypedDataError;if(h==="wallet_switchEthereumChain"){if(s.switchChainError)throw typeof s.switchChainError=="boolean"?new UserRejectedRequestError(new Error("Failed to switch chain.")):s.switchChainError;n=fromHex(d[0].chainId,"number"),this.onChainChanged(n.toString());return}if(h==="personal_sign"){if(s.signMessageError)throw typeof s.signMessageError=="boolean"?new UserRejectedRequestError(new Error("Failed to sign message.")):s.signMessageError;h="eth_sign",d=[d[1],d[0]];}let i={method:h,params:d},{error:m,result:l}=await rpc.http(p,{body:i});if(m)throw new RpcRequestError({body:i,error:m,url:p});return l}})({retryCount:1})}}))}var Pe={allowedDomains:[/gnosis-safe.io$/,/app.safe.global$/,/metissafe.tech$/],debug:false};var Ne=o=>o.reduce((s,e)=>{let n=e.id;return s[n]=http(),s},{});function je(o,s){let{wagmiConfig:e}=o,n=o.siwx??(o.siwe?{enabled:o.siwe.enabled,isSignedIn:o.siwe.isSignedIn,isRejected:o.siwe.isRejected}:void 0),{activeConnection:t,disconnect:a,connectionError:r,updateActiveConnection:c}=s,p=()=>{let d=n?.isRejected||n?.status==="error",i=n?.isSignedIn??n?.isAuthenticated??false;n?.enabled!==false&&!i&&d&&t&&a(t.connectorType);},u=d=>{if(t&&getAdapterFromConnectorType(t.connectorType)!==OrbitAdapter.EVM)return;if(d.length===0){t&&a(t.connectorType);return}let i=getConnection(e);if(t&&getAdapterFromConnectorType(t.connectorType)!==OrbitAdapter.EVM||!i||r)return;let m=n?.address??n?.session?.address,l=n?.chainId??n?.session?.chainId;if((n?.isSignedIn??n?.isAuthenticated??false)&&t){let E=i.address&&m&&i.address.toLowerCase()!==m.toLowerCase()&&!m.toLowerCase().endsWith(i.address.toLowerCase()),_=i.chainId&&l&&String(i.chainId)!==String(l)&&!l.endsWith(`:${i.chainId}`);if(E||_){a(t.connectorType);return}}let I=i.connector,$={connectorType:I?`${OrbitAdapter.EVM}:${formatConnectorName(I.name)}`:t?.connectorType,address:i.address,chainId:i.chainId,rpcURL:i?.chain?.rpcUrls.default.http[0],isConnected:true,signMessage:E=>signMessage(e,{message:E})};c($);};if(p(),t&&getAdapterFromConnectorType(t.connectorType)===OrbitAdapter.EVM){let d=getConnection(e);d&&d.isConnected&&c({signMessage:i=>signMessage(e,{message:i})});}return watchConnections(e,{onChange:u})}export{A as checkIsWalletAddressContract,Ne as createDefaultTransports,je as createEVMConnectionsWatcher,q as impersonated,Pe as safeSdkOptions,Ie as satelliteEVMAdapter};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuwaio/satellite-evm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Oleksandr Tkach",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -51,19 +51,18 @@
|
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@wagmi/core": "^3.6.4",
|
|
53
53
|
"@tuwaio/orbit-core": "^0.2.15",
|
|
54
|
-
"@tuwaio/orbit-evm": "^0.2.
|
|
55
|
-
"immer": "^11.1.
|
|
56
|
-
"jsdom": "^29.1.1",
|
|
54
|
+
"@tuwaio/orbit-evm": "^0.2.22",
|
|
55
|
+
"immer": "^11.1.16",
|
|
57
56
|
"tsup": "^8.5.1",
|
|
58
57
|
"typescript": "^6.0.3",
|
|
59
|
-
"viem": "^2.55.
|
|
58
|
+
"viem": "^2.55.11",
|
|
60
59
|
"vitest": "^4.1.10",
|
|
61
60
|
"zustand": "^5.0.14",
|
|
62
|
-
"@tuwaio/satellite-core": "^0.
|
|
61
|
+
"@tuwaio/satellite-core": "^0.4.0"
|
|
63
62
|
},
|
|
64
63
|
"scripts": {
|
|
65
64
|
"start": "tsup src/index.ts --watch",
|
|
66
65
|
"build": "tsup",
|
|
67
|
-
"test": "vitest"
|
|
66
|
+
"test": "vitest run --passWithNoTests"
|
|
68
67
|
}
|
|
69
68
|
}
|