@meshconnect/uwc-react 0.2.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 +222 -0
- package/dist/hooks/index.d.ts +9 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +9 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useConnection.d.ts +22 -0
- package/dist/hooks/useConnection.d.ts.map +1 -0
- package/dist/hooks/useConnection.js +98 -0
- package/dist/hooks/useConnection.js.map +1 -0
- package/dist/hooks/useDisconnect.d.ts +27 -0
- package/dist/hooks/useDisconnect.d.ts.map +1 -0
- package/dist/hooks/useDisconnect.js +44 -0
- package/dist/hooks/useDisconnect.js.map +1 -0
- package/dist/hooks/useNetworks.d.ts +16 -0
- package/dist/hooks/useNetworks.d.ts.map +1 -0
- package/dist/hooks/useNetworks.js +23 -0
- package/dist/hooks/useNetworks.js.map +1 -0
- package/dist/hooks/useSession.d.ts +18 -0
- package/dist/hooks/useSession.d.ts.map +1 -0
- package/dist/hooks/useSession.js +33 -0
- package/dist/hooks/useSession.js.map +1 -0
- package/dist/hooks/useSignMessage.d.ts +22 -0
- package/dist/hooks/useSignMessage.d.ts.map +1 -0
- package/dist/hooks/useSignMessage.js +61 -0
- package/dist/hooks/useSignMessage.js.map +1 -0
- package/dist/hooks/useSwitchNetwork.d.ts +28 -0
- package/dist/hooks/useSwitchNetwork.d.ts.map +1 -0
- package/dist/hooks/useSwitchNetwork.js +68 -0
- package/dist/hooks/useSwitchNetwork.js.map +1 -0
- package/dist/hooks/useTransaction.d.ts +25 -0
- package/dist/hooks/useTransaction.d.ts.map +1 -0
- package/dist/hooks/useTransaction.js +64 -0
- package/dist/hooks/useTransaction.js.map +1 -0
- package/dist/hooks/useWallets.d.ts +16 -0
- package/dist/hooks/useWallets.d.ts.map +1 -0
- package/dist/hooks/useWallets.js +23 -0
- package/dist/hooks/useWallets.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/ConnectionProvider.d.ts +21 -0
- package/dist/providers/ConnectionProvider.d.ts.map +1 -0
- package/dist/providers/ConnectionProvider.js +31 -0
- package/dist/providers/ConnectionProvider.js.map +1 -0
- package/dist/providers/index.d.ts +2 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.js.map +1 -0
- package/package.json +43 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useConnection.ts +123 -0
- package/src/hooks/useDisconnect.ts +52 -0
- package/src/hooks/useNetworks.ts +26 -0
- package/src/hooks/useSession.ts +37 -0
- package/src/hooks/useSignMessage.ts +69 -0
- package/src/hooks/useSwitchNetwork.ts +84 -0
- package/src/hooks/useTransaction.ts +79 -0
- package/src/hooks/useWallets.ts +26 -0
- package/src/index.ts +2 -0
- package/src/providers/ConnectionProvider.tsx +76 -0
- package/src/providers/index.ts +1 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useContext, useCallback, useState } from 'react'
|
|
2
|
+
import { ConnectionContext } from '../providers/ConnectionProvider'
|
|
3
|
+
import type { UseSignMessageReturn, WalletError } from '@meshconnect/uwc-types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook for signing messages with the connected wallet
|
|
7
|
+
* @returns Object containing signMessage function, loading state, and last signature
|
|
8
|
+
* @throws Error if used outside of ConnectionProvider
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* const { signMessage, isLoading, signature } = useSignMessage()
|
|
12
|
+
*
|
|
13
|
+
* const handleSign = async () => {
|
|
14
|
+
* try {
|
|
15
|
+
* const sig = await signMessage('Hello World')
|
|
16
|
+
* console.log('Signature:', sig)
|
|
17
|
+
* // signature state will also be updated with the result
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* console.error('Failed to sign:', error)
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function useSignMessage(): UseSignMessageReturn {
|
|
25
|
+
const context = useContext(ConnectionContext)
|
|
26
|
+
|
|
27
|
+
if (!context) {
|
|
28
|
+
throw new Error('useSignMessage must be used within a ConnectionProvider')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const { connector, session } = context
|
|
32
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
33
|
+
const [signature, setSignature] = useState<string | undefined>()
|
|
34
|
+
const [error, setError] = useState<WalletError | undefined>()
|
|
35
|
+
|
|
36
|
+
const signMessage = useCallback(
|
|
37
|
+
async (message: string): Promise<string> => {
|
|
38
|
+
if (!session.activeAddress) {
|
|
39
|
+
throw new Error('No wallet connected')
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!message) {
|
|
43
|
+
throw new Error('Message is required')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setIsLoading(true)
|
|
47
|
+
setError(undefined)
|
|
48
|
+
try {
|
|
49
|
+
const sig = await connector.signMessage(message)
|
|
50
|
+
setSignature(sig)
|
|
51
|
+
return sig
|
|
52
|
+
} catch (err) {
|
|
53
|
+
const walletError = err as WalletError
|
|
54
|
+
setError(walletError)
|
|
55
|
+
throw err
|
|
56
|
+
} finally {
|
|
57
|
+
setIsLoading(false)
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[connector, session.activeAddress]
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
signMessage,
|
|
65
|
+
isLoading,
|
|
66
|
+
signature,
|
|
67
|
+
error
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { useContext, useCallback, useState, useEffect } from 'react'
|
|
2
|
+
import { ConnectionContext } from '../providers/ConnectionProvider'
|
|
3
|
+
import type {
|
|
4
|
+
NetworkId,
|
|
5
|
+
UseSwitchNetworkReturn,
|
|
6
|
+
WalletError
|
|
7
|
+
} from '@meshconnect/uwc-types'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Hook for switching networks on the connected wallet
|
|
11
|
+
* @returns Network switching function and loading states
|
|
12
|
+
* @throws Error if used outside of ConnectionProvider
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const { switchNetwork, isLoading, isWaitingForUserApproval } = useSwitchNetwork()
|
|
16
|
+
*
|
|
17
|
+
* const handleSwitch = async () => {
|
|
18
|
+
* try {
|
|
19
|
+
* await switchNetwork('eip155:8453') // Switch to Base
|
|
20
|
+
* } catch (error) {
|
|
21
|
+
* console.error('Network switch failed:', error)
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* // Show loading UI
|
|
26
|
+
* if (isWaitingForUserApproval) {
|
|
27
|
+
* return <div>Please approve in your wallet...</div>
|
|
28
|
+
* }
|
|
29
|
+
* if (isLoading) {
|
|
30
|
+
* return <div>Switching network...</div>
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function useSwitchNetwork(): UseSwitchNetworkReturn {
|
|
35
|
+
const context = useContext(ConnectionContext)
|
|
36
|
+
|
|
37
|
+
if (!context) {
|
|
38
|
+
throw new Error('useSwitchNetwork must be used within a ConnectionProvider')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const { connector } = context
|
|
42
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
43
|
+
const [isWaitingForUserApproval, setIsWaitingForUserApproval] =
|
|
44
|
+
useState(false)
|
|
45
|
+
const [error, setError] = useState<WalletError | undefined>()
|
|
46
|
+
|
|
47
|
+
// Subscribe to loading state changes from the core
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const updateLoadingState = () => {
|
|
50
|
+
const state = connector.getNetworkSwitchLoadingState()
|
|
51
|
+
setIsLoading(state.isLoading)
|
|
52
|
+
setIsWaitingForUserApproval(state.isWaitingForUserApproval)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Check initial state
|
|
56
|
+
updateLoadingState()
|
|
57
|
+
|
|
58
|
+
// Subscribe to changes
|
|
59
|
+
const unsubscribe = connector.subscribe(updateLoadingState)
|
|
60
|
+
|
|
61
|
+
return unsubscribe
|
|
62
|
+
}, [connector])
|
|
63
|
+
|
|
64
|
+
const switchNetwork = useCallback(
|
|
65
|
+
async (networkId: NetworkId) => {
|
|
66
|
+
setError(undefined)
|
|
67
|
+
try {
|
|
68
|
+
await connector.switchNetwork(networkId)
|
|
69
|
+
} catch (err) {
|
|
70
|
+
const walletError = err as WalletError
|
|
71
|
+
setError(walletError)
|
|
72
|
+
throw err
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
[connector]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
switchNetwork,
|
|
80
|
+
isLoading,
|
|
81
|
+
isWaitingForUserApproval,
|
|
82
|
+
error
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { useContext, useCallback, useState } from 'react'
|
|
2
|
+
import { ConnectionContext } from '../providers/ConnectionProvider'
|
|
3
|
+
import type {
|
|
4
|
+
TransactionRequest,
|
|
5
|
+
TransactionResult,
|
|
6
|
+
UseTransactionReturn,
|
|
7
|
+
WalletError
|
|
8
|
+
} from '@meshconnect/uwc-types'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Hook for sending transactions with the connected wallet
|
|
12
|
+
* @returns Object containing sendTransaction function, loading state, and transaction result
|
|
13
|
+
* @throws Error if used outside of ConnectionProvider
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* const { sendTransaction, isLoading, transactionResult } = useTransaction()
|
|
17
|
+
*
|
|
18
|
+
* const handleSend = async () => {
|
|
19
|
+
* try {
|
|
20
|
+
* const result = await sendTransaction({
|
|
21
|
+
* to: '0x...',
|
|
22
|
+
* amount: BigInt('1000000000000000000'),
|
|
23
|
+
* from: session.activeAddress
|
|
24
|
+
* })
|
|
25
|
+
* console.log('Transaction hash:', result.hash)
|
|
26
|
+
* } catch (error) {
|
|
27
|
+
* console.error('Transaction failed:', error)
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function useTransaction(): UseTransactionReturn {
|
|
33
|
+
const context = useContext(ConnectionContext)
|
|
34
|
+
|
|
35
|
+
if (!context) {
|
|
36
|
+
throw new Error('useTransaction must be used within a ConnectionProvider')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { connector, session } = context
|
|
40
|
+
const [isLoading, setIsLoading] = useState(false)
|
|
41
|
+
const [transactionResult, setTransactionResult] = useState<
|
|
42
|
+
TransactionResult | undefined
|
|
43
|
+
>()
|
|
44
|
+
const [error, setError] = useState<WalletError | undefined>()
|
|
45
|
+
|
|
46
|
+
const sendTransaction = useCallback(
|
|
47
|
+
async (request: TransactionRequest): Promise<TransactionResult> => {
|
|
48
|
+
if (!session.activeAddress) {
|
|
49
|
+
throw new Error('No wallet connected')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!request) {
|
|
53
|
+
throw new Error('Transaction request is required')
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setIsLoading(true)
|
|
57
|
+
setError(undefined)
|
|
58
|
+
try {
|
|
59
|
+
const result = await connector.sendTransaction(request)
|
|
60
|
+
setTransactionResult(result)
|
|
61
|
+
return result
|
|
62
|
+
} catch (err) {
|
|
63
|
+
const walletError = err as WalletError
|
|
64
|
+
setError(walletError)
|
|
65
|
+
throw err
|
|
66
|
+
} finally {
|
|
67
|
+
setIsLoading(false)
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
[connector, session.activeAddress]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
sendTransaction,
|
|
75
|
+
isLoading,
|
|
76
|
+
transactionResult,
|
|
77
|
+
error
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useContext } from 'react'
|
|
2
|
+
import { ConnectionContext } from '../providers/ConnectionProvider'
|
|
3
|
+
import type { WalletMetadata } from '@meshconnect/uwc-types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook for accessing the list of configured wallets
|
|
7
|
+
* @returns Array of wallet metadata including names, IDs, and supported networks
|
|
8
|
+
* @throws Error if used outside of ConnectionProvider
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* const wallets = useWallets()
|
|
12
|
+
*
|
|
13
|
+
* wallets.forEach(wallet => {
|
|
14
|
+
* console.log(`${wallet.name}: ${wallet.id}`)
|
|
15
|
+
* })
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function useWallets(): WalletMetadata[] {
|
|
19
|
+
const context = useContext(ConnectionContext)
|
|
20
|
+
|
|
21
|
+
if (!context) {
|
|
22
|
+
throw new Error('useWallets must be used within a ConnectionProvider')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return context.wallets
|
|
26
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { createContext, useEffect, useState, useRef } from 'react'
|
|
2
|
+
import { UniversalWalletConnector } from '@meshconnect/uwc-core'
|
|
3
|
+
import type {
|
|
4
|
+
Session,
|
|
5
|
+
Network,
|
|
6
|
+
WalletMetadata,
|
|
7
|
+
WalletConnectConfig
|
|
8
|
+
} from '@meshconnect/uwc-types'
|
|
9
|
+
|
|
10
|
+
interface ConnectionContextValue {
|
|
11
|
+
connector: UniversalWalletConnector
|
|
12
|
+
session: Session
|
|
13
|
+
wallets: WalletMetadata[]
|
|
14
|
+
networks: Network[]
|
|
15
|
+
isReady: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ConnectionContext = createContext<ConnectionContextValue | null>(null)
|
|
19
|
+
|
|
20
|
+
interface ConnectionProviderProps {
|
|
21
|
+
children: React.ReactNode
|
|
22
|
+
networks: Network[]
|
|
23
|
+
wallets: WalletMetadata[]
|
|
24
|
+
usingIntegratedBrowser?: boolean
|
|
25
|
+
walletConnectConfig?: WalletConnectConfig
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function ConnectionProvider({
|
|
29
|
+
children,
|
|
30
|
+
networks,
|
|
31
|
+
wallets,
|
|
32
|
+
usingIntegratedBrowser = false,
|
|
33
|
+
walletConnectConfig
|
|
34
|
+
}: ConnectionProviderProps) {
|
|
35
|
+
// Create the connector instance only once using useRef
|
|
36
|
+
const connectorRef = useRef<UniversalWalletConnector | null>(null)
|
|
37
|
+
|
|
38
|
+
if (!connectorRef.current) {
|
|
39
|
+
connectorRef.current = new UniversalWalletConnector(
|
|
40
|
+
networks,
|
|
41
|
+
wallets,
|
|
42
|
+
usingIntegratedBrowser,
|
|
43
|
+
walletConnectConfig
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const connector = connectorRef.current
|
|
48
|
+
|
|
49
|
+
const [session, setSession] = useState<Session>(() => connector.getSession())
|
|
50
|
+
const [isReady, setIsReady] = useState(() => connector.isReady())
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const unsubscribe = connector.subscribe(() => {
|
|
54
|
+
setSession(connector.getSession())
|
|
55
|
+
setIsReady(connector.isReady())
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
return unsubscribe
|
|
59
|
+
}, [connector])
|
|
60
|
+
|
|
61
|
+
const value: ConnectionContextValue = {
|
|
62
|
+
connector,
|
|
63
|
+
session,
|
|
64
|
+
wallets: connector.getWallets(),
|
|
65
|
+
networks: connector.getNetworks(),
|
|
66
|
+
isReady
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<ConnectionContext.Provider value={value}>
|
|
71
|
+
{children}
|
|
72
|
+
</ConnectionContext.Provider>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { ConnectionContext }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ConnectionProvider'
|