@matchain/matchid-sdk-react 0.1.42-alpha.1 → 0.1.42-alpha.11

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.
Files changed (71) hide show
  1. package/dist/assets/icon/index.d.mts +1 -1
  2. package/dist/assets/icon/index.d.ts +1 -1
  3. package/dist/chunk-HJ337PTX.mjs +4662 -0
  4. package/dist/chunk-HJ337PTX.mjs.map +1 -0
  5. package/dist/{chunk-U5KWO2YJ.mjs → chunk-PBNKRURB.mjs} +2 -2
  6. package/dist/chunk-SQIJR7RA.mjs +29 -0
  7. package/dist/chunk-SQIJR7RA.mjs.map +1 -0
  8. package/dist/components/index.d.mts +3 -2
  9. package/dist/components/index.d.ts +3 -2
  10. package/dist/components/index.js +676 -453
  11. package/dist/components/index.js.map +1 -1
  12. package/dist/components/index.mjs +4 -1
  13. package/dist/hooks/api/index.d.mts +2 -2
  14. package/dist/hooks/api/index.d.ts +2 -2
  15. package/dist/hooks/api/index.js +120 -76
  16. package/dist/hooks/api/index.js.map +1 -1
  17. package/dist/hooks/api/index.mjs +3 -2
  18. package/dist/hooks/index.d.mts +5 -2
  19. package/dist/hooks/index.d.ts +5 -2
  20. package/dist/hooks/index.js +328 -145
  21. package/dist/hooks/index.js.map +1 -1
  22. package/dist/hooks/index.mjs +2 -1
  23. package/dist/index-B2B4VJ-u.d.mts +139 -0
  24. package/dist/index-Bhnio7tx.d.ts +139 -0
  25. package/dist/index-BxS06a5O.d.ts +50 -0
  26. package/dist/{index-Dq9Swg8r.d.ts → index-Ca9nh_8s.d.ts} +1 -1
  27. package/dist/{index-COlsBC-b.d.mts → index-CmH9iRLd.d.mts} +25 -12
  28. package/dist/{index-C3KZYrtu.d.mts → index-DFZpfAfc.d.mts} +1 -1
  29. package/dist/{index-fS75Swm8.d.ts → index-DY_ReBra.d.ts} +25 -12
  30. package/dist/index-q5XDobUF.d.mts +50 -0
  31. package/dist/index.css +84 -4
  32. package/dist/index.d.mts +9 -4
  33. package/dist/index.d.ts +9 -4
  34. package/dist/index.js +1100 -614
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.mjs +6 -2
  37. package/dist/mpc-CTbBWHld.d.mts +20 -0
  38. package/dist/mpc-CTbBWHld.d.ts +20 -0
  39. package/dist/types/index.d.mts +3 -0
  40. package/dist/types/index.d.ts +3 -0
  41. package/dist/types/index.js +44 -0
  42. package/dist/types/index.js.map +1 -0
  43. package/dist/types/index.mjs +10 -0
  44. package/dist/types/index.mjs.map +1 -0
  45. package/dist/types-CVwZEgQ0.d.mts +244 -0
  46. package/dist/types-CVwZEgQ0.d.ts +244 -0
  47. package/example/package.json +1 -0
  48. package/example/src/App.tsx +56 -27
  49. package/example/src/abi/erc20.json +222 -0
  50. package/example/src/components/ButtonGroup/index.tsx +10 -0
  51. package/example/src/components/Login/index.tsx +2 -2
  52. package/example/src/components/RoutePrivate/index.tsx +4 -3
  53. package/example/src/config/chains/index.ts +2 -0
  54. package/example/src/config/chains/matchMain.ts +27 -0
  55. package/example/src/config/chains/matchTest.ts +33 -0
  56. package/example/src/config/index.ts +6 -2
  57. package/example/src/pages/User/components/BindListModal.tsx +10 -0
  58. package/example/src/pages/User/components/PohListModal.tsx +10 -0
  59. package/example/src/pages/User/components/QueryDisplay.tsx +25 -0
  60. package/example/src/pages/{User.tsx → User/index.tsx} +55 -84
  61. package/example/src/pages/Wallet.tsx +258 -43
  62. package/example/src/store/useLocalStore.ts +51 -0
  63. package/example/tsconfig.json +1 -0
  64. package/package.json +7 -2
  65. package/dist/chunk-SBOIXOAW.mjs +0 -4197
  66. package/dist/chunk-SBOIXOAW.mjs.map +0 -1
  67. package/dist/index-BrdP6eg5.d.ts +0 -93
  68. package/dist/index-D7bNSBwl.d.mts +0 -93
  69. package/dist/types.d-CLO_WLka.d.mts +0 -176
  70. package/dist/types.d-CLO_WLka.d.ts +0 -176
  71. /package/dist/{chunk-U5KWO2YJ.mjs.map → chunk-PBNKRURB.mjs.map} +0 -0
@@ -1,47 +1,18 @@
1
- import {Hooks, Components, Api} from "@matchain/matchid-sdk-react"
2
- import React from "react";
3
- import RoutePrivate from "../components/RoutePrivate";
4
- import {CEXList, LOGIN_METHOD_MAP, LoginMethod, WalletMethod} from "@/config";
5
- import {CEXType, LoginMethodType} from "../../../src/types/types";
6
-
7
- const {useMatchEvents, useUserInfo, useWallet} = Hooks
8
- const {
1
+ import React, {useState} from "react";
2
+ import {CEXList, LOGIN_METHOD_MAP, LoginMethod, LoginMethodList, RecommendLoginMethodList, WalletList} from "@/config";
3
+ import {CEXType, LoginMethodType} from "@matchain/matchid-sdk-react/types";
4
+ import {useMatchEvents, useUserInfo, useWallet} from "@matchain/matchid-sdk-react/hooks";
5
+ import {
9
6
  LoginButton,
10
7
  UsernameModal,
11
8
  PasswordModal,
12
- Button,
13
- } = Components
14
-
15
- function QueryDisplay(
16
- {
17
- name,
18
- query
19
- }: {
20
- name: string
21
- query: any
22
- }
23
- ) {
24
- const keys = Object.keys(query)
25
- return <div>
26
- <div className={`font-bold text-lg`}>{name}</div>
27
- {keys.map((key) => {
28
- return <div key={key} className={`flex gap-[20px]`}>
29
- <div className={"w-[200px]"}>{key}</div>
30
- <div className={`flex-1 flex-wrap break-all`}>{
31
- typeof query[key] === 'function' ? <Button size="sm" onClick={() => {
32
- query[key]()
33
- }}>Run</Button> :
34
- JSON.stringify(query[key])}</div>
35
- </div>
36
- })}
37
- </div>
9
+ } from "@matchain/matchid-sdk-react/components";
10
+ import BindListModal from "@/pages/User/components/BindListModal";
11
+ import PohListModal from "@/pages/User/components/PohListModal";
12
+ import ButtonGroup from "@/components/ButtonGroup";
38
13
 
39
- }
40
14
 
41
15
  function LoginContent() {
42
- const bindListQuery = Api.bind.useBindList()
43
- const pohListQuery = Api.poh.usePohList()
44
-
45
16
  const {
46
17
  token,
47
18
  logout,
@@ -54,8 +25,9 @@ function LoginContent() {
54
25
  bindCex,
55
26
  getAuthInfo
56
27
  } = useUserInfo();
57
- const [usernameOpen, setUsernameOpen] = React.useState(false)
58
- const [passwordOpen, setPasswordOpen] = React.useState(false)
28
+ const [usernameOpen, setUsernameOpen] = useState(false)
29
+ const [passwordOpen, setPasswordOpen] = useState(false)
30
+ const [modal, setModal] = useState<'bindList' | 'pohList' | ''>('')
59
31
  const refreshOv = async () => {
60
32
  await refreshOverview()
61
33
  alert('refreshed')
@@ -70,25 +42,30 @@ function LoginContent() {
70
42
  }
71
43
  }
72
44
 
73
- const onGetInfo = async (method: string) => {
74
- try {
75
- const res = await getAuthInfo(method)
76
- console.log('getAuthInfo', res)
77
- } catch (e) {
78
- console.error('getAuthInfo', e)
79
- }
80
- }
81
-
82
45
  return <div className={`flex flex-col gap-[10px]`}>
83
46
  <h1 className={`text-2xl`}>You are already logged in</h1>
84
47
  <div className={`text-ellipsis break-words`}>token:{token}</div>
85
48
  <div className={`text-ellipsis break-words`}>username:{username}</div>
86
49
  <div className={`text-ellipsis break-words`}>did:{did}</div>
87
50
  <div className={`text-ellipsis break-words`}>address:{address}</div>
88
- <div className={`flex gap-[20px]`}>
51
+
52
+ <ButtonGroup title={"User"}>
89
53
  <button className={`bg-gray-300 p-1 rounded`}
90
54
  onClick={() => setUsernameOpen(true)}>Set username
91
55
  </button>
56
+
57
+ <button className={`bg-gray-300 p-1 rounded mr-5`}
58
+ onClick={() => setPasswordOpen(true)}>Set Password
59
+ </button>
60
+ <button className={`bg-gray-300 p-1 rounded`}
61
+ onClick={onAuth}>Third party auth
62
+ </button>
63
+ <button className={`bg-gray-300 p-1 rounded`}
64
+ onClick={refreshOv}>Refresh Overview
65
+ </button>
66
+ <button className={`bg-gray-300 p-1 rounded`}
67
+ onClick={logout}>Logout
68
+ </button>
92
69
  <UsernameModal isOpen={usernameOpen} onClose={() => setUsernameOpen(false)} onBack={() => {
93
70
  console.log('set username modal back event')
94
71
  setUsernameOpen(false)
@@ -96,9 +73,6 @@ function LoginContent() {
96
73
  alert('set username success')
97
74
  setUsernameOpen(false)
98
75
  }}/>
99
- <button className={`bg-gray-300 p-1 rounded mr-5`}
100
- onClick={() => setPasswordOpen(true)}>Set Password
101
- </button>
102
76
  <PasswordModal isOpen={passwordOpen} onClose={() => setPasswordOpen(false)} onBack={() => {
103
77
  console.log('set password modal back event')
104
78
  setPasswordOpen(false)
@@ -106,11 +80,8 @@ function LoginContent() {
106
80
  alert('set password success')
107
81
  setPasswordOpen(false)
108
82
  }}/>
109
- </div>
110
- <div className={`flex gap-[20px] flex-wrap`}>
111
- <div>
112
- Bind
113
- </div>
83
+ </ButtonGroup>
84
+ <ButtonGroup title={"Bind"}>
114
85
  {
115
86
  LoginMethod.map((method) => {
116
87
  return <button key={method} className={`bg-gray-300 p-1 capitalize rounded`}
@@ -118,41 +89,37 @@ function LoginContent() {
118
89
  </button>
119
90
  })
120
91
  }
121
- </div>
122
- <div className={`flex gap-[20px] flex-wrap`}>
123
- <div>
124
- GetAuthInfo
125
- </div>
92
+ </ButtonGroup>
93
+ <ButtonGroup title={"Bind CEX"}>
126
94
  {
127
- Object.keys(LOGIN_METHOD_MAP).map((method:string ) => {
128
- return <button key={method} className={`bg-gray-300 p-1 rounded`}
129
- onClick={async() => onGetInfo(LOGIN_METHOD_MAP[method as keyof typeof LOGIN_METHOD_MAP])}>{method}</button>
95
+ CEXList.map((method) => {
96
+ return <button key={method} className={`bg-gray-300 p-1 capitalize rounded`}
97
+ onClick={() => bindCex(method as CEXType)}>CEX {method}
98
+ </button>
130
99
  })
131
100
  }
132
- </div>
133
- <div className={`flex gap-[20px] flex-wrap`}>
101
+ </ButtonGroup>
102
+ <ButtonGroup title={"getAuthInfo"}>
134
103
  {
135
- CEXList.map((method) => {
104
+ Object.keys(LOGIN_METHOD_MAP).map((method) => {
136
105
  return <button key={method} className={`bg-gray-300 p-1 capitalize rounded`}
137
- onClick={() => bindCex(method as CEXType)}>CEX {method}
106
+ onClick={() => getAuthInfo(method as keyof typeof LOGIN_METHOD_MAP)}>{LOGIN_METHOD_MAP[method as keyof typeof LOGIN_METHOD_MAP]}
138
107
  </button>
139
108
  })
140
109
  }
141
- </div>
142
- <div className={`flex gap-[20px]`}>
143
- <button className={`bg-gray-300 p-1 rounded`}
144
- onClick={onAuth}>Third party auth
145
- </button>
110
+ </ButtonGroup>
111
+
112
+ <ButtonGroup title={"QueryList"}>
146
113
  <button className={`bg-gray-300 p-1 rounded`}
147
- onClick={refreshOv}>Refresh Overview
114
+ onClick={() => setModal('bindList')}>BindList
148
115
  </button>
149
116
  <button className={`bg-gray-300 p-1 rounded`}
150
- onClick={logout}>Logout
117
+ onClick={() => setModal('pohList')}>PohList
151
118
  </button>
152
- </div>
119
+ </ButtonGroup>
153
120
 
154
- <QueryDisplay query={bindListQuery} name={"BindListQuery"}/>
155
- <QueryDisplay query={pohListQuery} name={"PohListQuery"}/>
121
+ <BindListModal isOpen={modal == 'bindList'} onClose={() => setModal('')}/>
122
+ <PohListModal isOpen={modal == 'pohList'} onClose={() => setModal('')}/>
156
123
  </div>
157
124
 
158
125
  }
@@ -174,11 +141,15 @@ export default function User() {
174
141
  <div className={`font-bold text-lg`}>LoginButton</div>
175
142
 
176
143
  <div className={`bg-gray-100 p-5 mt-5`}>
177
- <LoginButton methods={[ "twitter", 'facebook',"discord","github","youtube","telegram"]} popoverPosition={"left"} walletMethods={WalletMethod}/>
144
+ <LoginButton
145
+ methods={LoginMethodList}
146
+ recommendMethods={RecommendLoginMethodList}
147
+ popoverPosition={"left"}
148
+ walletMethods={WalletList}
149
+ />
178
150
  </div>
179
- <RoutePrivate>
180
- <LoginContent/>
181
- </RoutePrivate>
151
+
152
+ <LoginContent/>
182
153
 
183
154
 
184
155
  </div>
@@ -1,23 +1,92 @@
1
- import {Hooks} from "@matchain/matchid-sdk-react"
2
- import React, {useState} from "react";
3
- import {createPublicClient, http, formatUnits, parseUnits, createWalletClient, parseGwei, Account} from "viem";
1
+ import {useWallet} from "@matchain/matchid-sdk-react/hooks"
2
+ import {Input, Button} from "@matchain/matchid-sdk-react/components"
3
+ import React, {useEffect, useMemo, useState} from "react";
4
+ import {
5
+ createPublicClient,
6
+ formatUnits,
7
+ parseUnits,
8
+ parseGwei,
9
+ Account,
10
+ Transport,
11
+ HttpTransportConfig, http, TransactionSerializable
12
+ } from "viem";
4
13
  import {useQuery} from "@tanstack/react-query";
5
- import {bscTestnet} from 'viem/chains';
14
+ import {
15
+ mainnet,
16
+ arbitrum,
17
+ arbitrumGoerli,
18
+ arbitrumNova,
19
+ arbitrumSepolia,
20
+ avalanche,
21
+ base,
22
+ baseSepolia,
23
+ baseGoerli,
24
+ bsc,
25
+ bscTestnet,
26
+ goerli,
27
+ linea,
28
+ lineaGoerli,
29
+ lineaSepolia,
30
+ sepolia,
31
+ polygonMumbai,
32
+ polygon,
33
+ polygonAmoy,
34
+ zkSync,
35
+ } from 'viem/chains';
36
+ import {matchMain, matchTest} from "@/config/chains";
37
+ import useLocalStore from "@/store/useLocalStore";
38
+ import ButtonGroup from "@/components/ButtonGroup";
39
+ import Erc20Abi from "@/abi/erc20.json";
40
+ import type {Abi} from "abitype";
6
41
 
7
- const {useWallet} = Hooks
42
+ const chainList = [
43
+ mainnet,
44
+ bsc,
45
+ bscTestnet,
46
+ matchMain,
47
+ matchTest,
48
+ arbitrum,
49
+ arbitrumGoerli,
50
+ arbitrumNova,
51
+ arbitrumSepolia,
52
+ avalanche,
53
+ base,
54
+ baseSepolia,
55
+ baseGoerli,
56
+ goerli,
57
+ linea,
58
+ lineaGoerli,
59
+ lineaSepolia,
60
+ sepolia,
61
+ polygonMumbai,
62
+ polygon,
63
+ polygonAmoy,
64
+ zkSync,
65
+ ]
8
66
 
9
67
  export default function Wallet() {
68
+
69
+ const {initChainId, setInitChainId} = useLocalStore()
70
+
10
71
  const [message, setMessage] = useState('hello')
11
72
  const [toAddress, setToAddress] = useState('')
12
73
  const [toAmount, setToAmount] = useState('0.0001')
13
74
  const [data, setToData] = useState('0x')
14
- const {address, evmAccount} = useWallet()
15
- const chain = bscTestnet
75
+ const {address, evmAccount, createWalletClient, walletReady} = useWallet()
76
+ const chain = chainList.find((chain) => chain.id === initChainId)
77
+
16
78
  const walletClient = createWalletClient({
17
79
  chain: chain,
18
80
  transport: http(),
81
+ // account:evmAccount
19
82
  })
20
83
 
84
+ useEffect(() => {
85
+ if (address && !toAddress) {
86
+ setToAddress(address)
87
+ }
88
+ }, [address, toAddress]);
89
+
21
90
 
22
91
  const [hash, setHash] = useState('')
23
92
  const [transactionSign, setTransactionSign] = useState('')
@@ -25,7 +94,7 @@ export default function Wallet() {
25
94
 
26
95
  const publicClient = createPublicClient({
27
96
  chain: chain,
28
- transport: http(),
97
+ transport: http() as Transport,
29
98
  });
30
99
 
31
100
  const balanceQuery = useQuery({
@@ -46,7 +115,13 @@ export default function Wallet() {
46
115
  }
47
116
  })
48
117
 
118
+ useEffect(() => {
119
+ gasPriceQuery.refetch()
120
+ balanceQuery.refetch()
121
+ }, [chain]);
122
+
49
123
  const onSign = async () => {
124
+ if (!walletClient) return;
50
125
  const res = await walletClient.signMessage({
51
126
  message,
52
127
  account: evmAccount as Account
@@ -55,43 +130,62 @@ export default function Wallet() {
55
130
  }
56
131
 
57
132
  const onSignTransaction = async () => {
58
- const transaction = {
59
- account:evmAccount as Account,
60
- to: toAddress as `0x${string}`,
61
- value: parseUnits(toAmount, 18),
62
- data: data as `0x${string}`,
133
+ if (!walletClient || !evmAccount) return
134
+ try {
135
+
136
+ const transaction = {
137
+ to: toAddress as `0x${string}`,
138
+ value: parseUnits(toAmount, 18),
139
+ data: data as `0x${string}`,
140
+ chain: chain
141
+ }
142
+ const request = await walletClient.prepareTransactionRequest(transaction)
143
+ const res = await evmAccount.signTransaction!(request as TransactionSerializable)
144
+ setTransactionSign(res)
145
+ } catch (e) {
146
+ console.error(e)
63
147
  }
64
- const request = await walletClient.prepareTransactionRequest(transaction)
65
- const res = await walletClient.signTransaction(request)
66
- setTransactionSign(res)
67
148
  }
68
149
 
69
150
  const onSendTransaction = async () => {
151
+ if (!walletClient) return
70
152
  const res = await walletClient.sendTransaction({
71
- account:evmAccount as Account,
153
+ // account:evmAccount as Account,
72
154
  to: toAddress as `0x${string}`,
73
155
  value: parseUnits(toAmount, 18),
74
156
  data: data as `0x${string}`,
157
+ chain: chain
75
158
  })
76
159
  setHash(res)
77
160
  }
78
161
 
79
162
 
80
163
  return <div>
81
- <div className={`text-ellipsis break-words`}>Chain:{chain.name}</div>
82
- <div className={`text-ellipsis break-words`}>address:{address}</div>
164
+ <ButtonGroup title={"Wallet Ready"}>
165
+ {walletReady ? 'Ready' : 'Not Ready'}
166
+ </ButtonGroup>
167
+ <ButtonGroup title={"CreateWalletClient Chain"}>
168
+ <select value={initChainId} onChange={(e) => setInitChainId(parseInt(e.target.value))}>
169
+ {chainList.map((chain, index) => {
170
+ return <option key={index} value={chain.id}>{chain.name}({chain.id})</option>
171
+ })}
172
+ </select>
173
+ </ButtonGroup>
174
+ <ButtonGroup title={"Ethereum address"}>
175
+ <div className={`flex-1 flex-wrap break-all`}>{address}</div>
176
+ </ButtonGroup>
177
+ <ButtonGroup title={"Signature Message"}>
178
+ <input className="border px-[8px]" type={'text'} placeholder={'message'} value={message}
179
+ onChange={(e) => setMessage(e.target.value)}/>
180
+ <Button onClick={onSign} size={"sm"} disabled={!walletReady}>Sign message</Button>
181
+ </ButtonGroup>
182
+ <ButtonGroup title={"Signature Result"}>
183
+ <div className={`flex-1 flex-wrap break-all`}>{signature || '-'}</div>
184
+ </ButtonGroup>
185
+
83
186
  <div className={`text-ellipsis break-words`}>balance:{balanceQuery.data?.toString()} wei/{balanceEth} eth</div>
84
187
  <div className={`text-ellipsis break-words`}>gas price:{gasPriceQuery.data?.toString()} wei</div>
85
- <div className={`flex gap-[20px]`}>
86
- <input className="border" type={'text'} placeholder={'message'} value={message}
87
- onChange={(e) => setMessage(e.target.value)}/>
88
- <button className={`bg-gray-300 p-1 rounded`}
89
- onClick={onSign}>Sign message
90
- </button>
91
- </div>
92
- <div>
93
- Signature:{signature}
94
- </div>
188
+
95
189
  <div className="text-bold">
96
190
  Send Transaction
97
191
  </div>
@@ -110,21 +204,142 @@ export default function Wallet() {
110
204
  <input className="border" type={'text'} placeholder={'data'} value={data}
111
205
  onChange={(e) => setToData(e.target.value)}/>
112
206
  </div>
113
- <div className={`flex gap-[20px]`}>
114
- <button className={`bg-gray-300 p-1 rounded`}
115
- onClick={onSignTransaction}>Sign
116
- </button>
117
- <button className={`bg-gray-300 p-1 rounded`}
118
- onClick={onSendTransaction}>Send
119
- </button>
120
- </div>
121
- <div>
122
- Sign:{transactionSign}
123
- </div>
124
- <div>
125
- TxHash:{hash}
126
- </div>
207
+ <ButtonGroup>
208
+ <Button onClick={onSignTransaction} size={"sm"} disabled={!walletReady}>Sign</Button>
209
+ <Button onClick={onSendTransaction} size={"sm"} disabled={!walletReady}>Send</Button>
210
+ </ButtonGroup>
211
+ <ButtonGroup title={"TxSignature"}>
212
+ <div className={`flex-1 flex-wrap break-all`}>{transactionSign || '-'}</div>
213
+ </ButtonGroup>
214
+ <ButtonGroup title={"TxHash"}>
215
+ <div className={`flex-1 flex-wrap break-all`}>{hash || '-'}</div>
216
+ </ButtonGroup>
217
+ <ERC20/>
218
+ </div>
219
+ }
127
220
 
221
+ function ERC20() {
222
+ const {initChainId, erc20Address, setErc20Address} = useLocalStore()
223
+ const [hash, setHash] = useState('')
224
+ const [amount, setAmount] = useState('1')
225
+ const [to, setTo] = useState('')
226
+ const {address, evmAccount, createWalletClient, walletReady} = useWallet()
227
+ const [loading,setLoading] = useState(false)
228
+ const chain = chainList.find((chain) => chain.id === initChainId)
229
+ const publicClient = createPublicClient({
230
+ chain: chain,
231
+ transport: http() as Transport,
232
+ });
233
+
234
+ const decimalsQuery = useQuery({
235
+ queryKey: ['erc20decimals', erc20Address],
236
+ queryFn: async () => {
237
+ return await publicClient.readContract({
238
+ abi: Erc20Abi,
239
+ address: erc20Address as `0x${string}`,
240
+ functionName: 'decimals',
241
+ args: []
242
+ }) as number
243
+ },
244
+ enabled:!!erc20Address
245
+ })
246
+
247
+ const symbolQuery = useQuery({
248
+ queryKey: ['erc20symbol', erc20Address],
249
+ queryFn: async () => {
250
+ return await publicClient.readContract({
251
+ abi: Erc20Abi,
252
+ address: erc20Address as `0x${string}`,
253
+ functionName: 'symbol',
254
+ args: []
255
+ }) as string
256
+ },
257
+ enabled:!!erc20Address
258
+ })
259
+
260
+ const balanceQuery = useQuery({
261
+ queryKey: ['erc20balance', address],
262
+ refetchInterval: 15_000,
263
+ queryFn: async () => {
264
+ return await publicClient.readContract({
265
+ abi:Erc20Abi,
266
+ address:erc20Address as `0x${string}`,
267
+ functionName:'balanceOf',
268
+ args:[address]
269
+ }) as bigint
270
+ },
271
+ enabled:!!erc20Address&&!!address
272
+ })
273
+
274
+ const balanceUnit = useMemo(()=>{
275
+ if(!decimalsQuery.data) return ''
276
+ if(!balanceQuery.data) return ''
277
+
278
+ return formatUnits(balanceQuery.data,decimalsQuery.data)
279
+ },[balanceQuery.data,decimalsQuery.data])
280
+
281
+ console.log(balanceQuery,symbolQuery,decimalsQuery)
282
+ const onSend = async()=>{
283
+ try{
284
+ setLoading(true)
285
+ if(!walletReady) throw new Error('wallet not ready')
286
+ if(!evmAccount) throw new Error('account not ready')
287
+ if(!erc20Address) throw new Error('erc20Address not ready')
288
+ if(!to) throw new Error('to not ready')
289
+ if(!amount) throw new Error('amount not ready')
128
290
 
291
+ const walletClient = createWalletClient({
292
+ chain:chain,
293
+ transport:http(),
294
+ })
295
+ if(walletClient){
296
+
297
+ const hash = await walletClient?.writeContract({
298
+ address:erc20Address as `0x${string}`,
299
+ abi:Erc20Abi as any,
300
+ functionName:'transfer',
301
+ args:[to,parseUnits(amount,decimalsQuery.data||18)],
302
+ })
303
+ setHash(hash)
304
+ }
305
+
306
+
307
+ }catch(error:any){
308
+ console.error(error)
309
+ alert(error.message)
310
+ }finally {
311
+ setLoading(false)
312
+ }
313
+ }
314
+ return <div>
315
+ <ButtonGroup title={"ERC20"}></ButtonGroup>
316
+ <ButtonGroup title={"Contract Address"}>
317
+ <input className="border px-[8px]" type={'text'} placeholder={'contact'} value={erc20Address}
318
+ onChange={(e) => setErc20Address(e.target.value)}/>
319
+ </ButtonGroup>
320
+ <ButtonGroup title={"Info"}>
321
+ <div className={`flex-1 flex-wrap break-all`}>Symbol:{symbolQuery.data}</div>
322
+ <div className={`flex-1 flex-wrap break-all`}>Decimals:{decimalsQuery.data}</div>
323
+ </ButtonGroup>
324
+ <ButtonGroup title={"Balance"}>
325
+ <div className={`flex-1 flex-wrap break-all`}>{balanceQuery.data?.toString()}</div>
326
+ <div className={`flex-1 flex-wrap break-all`}>{balanceUnit} {symbolQuery.data}</div>
327
+ </ButtonGroup>
328
+ <ButtonGroup title={"Send"}>
329
+ <div className={`flex-1 flex-wrap break-all`}>
330
+ To Address:
331
+ <input className="border px-[8px]" type={'text'} placeholder={'address'} value={to}
332
+ onChange={(e) => setTo(e.target.value)}/>
333
+ </div>
334
+ <div className={`flex-1 flex-wrap break-all`}>
335
+ Amount:
336
+ <input className="border px-[8px]" type={'text'} placeholder={'amount'} value={amount}
337
+ onChange={(e) => setAmount(e.target.value)}/>
338
+ </div>
339
+ <Button size={"sm"} loading={loading} onClick={onSend} disabled={!to||!amount}>Send</Button>
340
+ </ButtonGroup>
341
+ <ButtonGroup title={"Hash"}>
342
+ <div className={`flex-1 flex-wrap break-all`}>{hash}</div>
343
+ </ButtonGroup>
129
344
  </div>
130
345
  }
@@ -0,0 +1,51 @@
1
+ import {create} from 'zustand';
2
+ import {devtools, persist} from 'zustand/middleware';
3
+ import {LocaleType} from "@matchain/matchid-sdk-react/types";
4
+
5
+ interface StoreState {
6
+ appid: string
7
+ endpoints: {
8
+ back: string;
9
+ auth: string;
10
+ }
11
+ locale: LocaleType;
12
+
13
+
14
+ setAppid: (appid: string) => void;
15
+ setEndpoints: (endpoints: StoreState['endpoints']) => void
16
+ setLocale: (locale: LocaleType) => void
17
+
18
+ initChainId: number;
19
+ setInitChainId: (initChainId: number) => void
20
+
21
+ erc20Address: string;
22
+ setErc20Address: (erc20Address: string) => void;
23
+
24
+ }
25
+
26
+ const persistedState = persist<StoreState>(
27
+ set => ({
28
+ appid: '',
29
+ endpoints: {
30
+ back: "https://api.matchid.ai/",
31
+ auth: "https://auth.matchid.ai/"
32
+ },
33
+ locale: 'en',
34
+ setAppid: (appid: string) => set({appid: appid}),
35
+ setEndpoints: (endpoints: StoreState['endpoints']) => set({endpoints}),
36
+ setLocale: (locale: LocaleType) => set({locale}),
37
+
38
+ initChainId:1,
39
+ setInitChainId: (initChainId: number) => set({initChainId}),
40
+
41
+ erc20Address: '',
42
+ setErc20Address: (erc20Address: string) => set({erc20Address})
43
+ }),
44
+ {name: 'match-example-local'}
45
+ );
46
+
47
+ const useLocalStore = create(devtools(persistedState));
48
+
49
+ export const localStore = useLocalStore;
50
+
51
+ export default useLocalStore;
@@ -10,6 +10,7 @@
10
10
  "moduleResolution": "node", // 使用 Node.js 风格的模块解析
11
11
  "esModuleInterop": true,
12
12
  "skipLibCheck": true,
13
+ "resolveJsonModule": true,
13
14
  "forceConsistentCasingInFileNames": true,
14
15
  "baseUrl": "./",
15
16
  "paths": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matchain/matchid-sdk-react",
3
- "version": "0.1.42-alpha.1",
3
+ "version": "0.1.42-alpha.11",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -28,6 +28,10 @@
28
28
  "import": "./dist/assets/icon/index.mjs",
29
29
  "require": "./dist/assets/icon/index.js"
30
30
  },
31
+ "./types": {
32
+ "import": "./dist/types/index.mjs",
33
+ "require": "./dist/types/index.js"
34
+ },
31
35
  "./index.css": "./dist/index.css"
32
36
  },
33
37
  "scripts": {
@@ -81,6 +85,7 @@
81
85
  "chokidar": "^4.0.3",
82
86
  "npm-run-all": "^4.1.5",
83
87
  "tsup": "^8.3.5",
84
- "typescript": "^5.6.3"
88
+ "typescript": "^5.6.3",
89
+ "url-loader": "^4.1.1"
85
90
  }
86
91
  }