@sign-global/tokentable-wallets 1.6.3 → 2.0.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.
@@ -1,31 +1,40 @@
1
- import '@mysten/dapp-kit/dist/index.css';
2
1
  import EventEmitter from 'events';
3
- import { ReactNode, useEffect, useState } from 'react';
2
+ import { CSSProperties, ReactNode, useEffect, useState } from 'react';
4
3
  import { WalletBase } from '../../WalletBase';
5
4
  import { ISignResult } from '../../types';
6
5
  import { get4361Message, prepareSignMessage } from '../../utils';
7
- import {
8
- createNetworkConfig,
9
- SuiClientProvider,
10
- WalletProvider,
11
- ConnectModal,
12
- useCurrentAccount,
13
- useCurrentWallet
14
- } from '@mysten/dapp-kit';
15
- import { getFullnodeUrl } from '@mysten/sui/client';
6
+ import { createDAppKit, DAppKitProvider, useWalletConnection, UiWalletAccount } from '@mysten/dapp-kit-react';
7
+ import { ConnectModal } from '@mysten/dapp-kit-react/ui';
8
+ import { SuiGrpcClient } from '@mysten/sui/grpc';
9
+ import { getWallets, Wallet } from '@mysten/wallet-standard';
10
+
11
+ type SuiNetwork = 'testnet' | 'mainnet';
12
+
13
+ const createSuiDAppKit = () =>
14
+ createDAppKit({
15
+ networks: ['mainnet', 'testnet'] as SuiNetwork[],
16
+ createClient: (network) => new SuiGrpcClient({ network, baseUrl: `https://fullnode.${network}.sui.io:443` })
17
+ });
18
+
19
+ let dAppKitInstance: ReturnType<typeof createSuiDAppKit> | undefined;
20
+
21
+ // 延迟创建:createDAppKit 会触发钱包发现与自动连接,只能在浏览器端执行
22
+ const getDAppKit = () => {
23
+ if (!dAppKitInstance) {
24
+ dAppKitInstance = createSuiDAppKit();
25
+ }
26
+ return dAppKitInstance;
27
+ };
16
28
 
17
29
  interface SuiStoreType {
18
- connectModal: {
19
- open: boolean;
20
- setOpen: (open: boolean) => void;
21
- } | null;
22
- account: ReturnType<typeof useCurrentAccount> | null;
23
- wallet: ReturnType<typeof useCurrentWallet> | null;
30
+ openConnectModal: (() => void) | null;
31
+ account: UiWalletAccount | null;
32
+ wallet: Wallet | null;
24
33
  counter: number;
25
34
  }
26
35
 
27
36
  const suiStore: SuiStoreType = {
28
- connectModal: null,
37
+ openConnectModal: null,
29
38
  account: null,
30
39
  wallet: null,
31
40
  counter: 0
@@ -44,34 +53,32 @@ export class SuiWallet extends WalletBase<SuiStoreType> {
44
53
  return suiStore;
45
54
  }
46
55
  get isConnected(): boolean {
47
- return !!this.getStore().wallet?.isConnected;
56
+ return getDAppKit().stores.$connection.get().isConnected;
48
57
  }
49
58
 
50
59
  connect() {
51
- suiStore.connectModal?.setOpen(true);
60
+ suiStore.openConnectModal?.();
52
61
  }
53
62
 
54
63
  disconnect() {
55
- suiStore.wallet?.currentWallet?.features['standard:disconnect']?.disconnect();
64
+ getDAppKit().disconnectWallet();
56
65
  }
57
66
  async sign(message: string): Promise<ISignResult> {
58
- const signPersonalFeature = suiStore.wallet?.currentWallet?.features['sui:signPersonalMessage'];
59
- const res = await signPersonalFeature?.signPersonalMessage({
60
- message: new Uint8Array(Buffer.from(message)),
61
- account: suiStore.account!
67
+ const res = await getDAppKit().signPersonalMessage({
68
+ message: new Uint8Array(Buffer.from(message))
62
69
  });
63
70
 
64
71
  return {
65
72
  message: message,
66
- signature: res!.signature
73
+ signature: res.signature
67
74
  };
68
75
  }
69
76
 
70
77
  signin(statement: string, prepare = true): Promise<ISignResult> {
71
78
  return new Promise((resolve) => {
72
- const signCallback = (data: ReturnType<typeof useCurrentAccount>) => {
73
- this.publicKey = Buffer.from(data!.publicKey).toString('hex');
74
- this.address = data?.address;
79
+ const signCallback = (data: UiWalletAccount) => {
80
+ this.publicKey = Buffer.from(data.publicKey).toString('hex');
81
+ this.address = data.address;
75
82
  this.chainId = 1;
76
83
  let fullMessage = statement;
77
84
  if (prepare) {
@@ -99,41 +106,68 @@ export class SuiWallet extends WalletBase<SuiStoreType> {
99
106
  }
100
107
  }
101
108
 
109
+ // dapp-kit 组件把宿主的 --background 等同名变量当完整颜色读取,shadcn 主题存的是 HSL 通道值会让弹窗变透明,这里重置为组件默认主题
110
+ const dappKitThemeReset = Object.fromEntries(
111
+ [
112
+ 'background',
113
+ 'foreground',
114
+ 'primary',
115
+ 'primary-foreground',
116
+ 'secondary',
117
+ 'secondary-foreground',
118
+ 'border',
119
+ 'accent',
120
+ 'accent-foreground',
121
+ 'muted',
122
+ 'muted-foreground',
123
+ 'popover',
124
+ 'popover-foreground',
125
+ 'destructive',
126
+ 'positive',
127
+ 'ring',
128
+ 'input'
129
+ ].map((name) => [`--${name}`, 'initial'])
130
+ ) as CSSProperties;
131
+
102
132
  export const SuiConnector = () => {
103
- const [showModal, setShowModal] = useState(false);
104
- const account = useCurrentAccount();
105
- const wallet = useCurrentWallet();
133
+ // ConnectModal React 封装不转发 ref,用 key 重挂载来重新打开被用户关闭的弹窗
134
+ const [modalKey, setModalKey] = useState(0);
135
+ const { wallet, account, isConnected } = useWalletConnection({ dAppKit: getDAppKit() });
106
136
 
107
137
  useEffect(() => {
108
- if (wallet) {
109
- if (wallet.isConnected && account) {
110
- const eventKey = getEventKey();
111
- eventBus.emit(eventKey, account);
112
- }
138
+ if (isConnected && account) {
139
+ const eventKey = getEventKey();
140
+ eventBus.emit(eventKey, account);
113
141
  }
114
- }, [wallet, account]);
142
+ }, [isConnected, account]);
115
143
 
116
- suiStore.connectModal = {
117
- open: showModal,
118
- setOpen: setShowModal
119
- };
144
+ suiStore.openConnectModal = () => setModalKey((key) => key + 1);
120
145
  suiStore.account = account;
121
- suiStore.wallet = wallet;
122
-
123
- return <ConnectModal open={showModal} onOpenChange={(open) => setShowModal(open)} trigger={<div></div>} />;
146
+ // 还原 wallet-standard Wallet 对象,供 core 的 walletClient 使用
147
+ suiStore.wallet = wallet
148
+ ? (getWallets()
149
+ .get()
150
+ .find((w) => w.name === wallet.name) ?? null)
151
+ : null;
152
+
153
+ return modalKey > 0 ? (
154
+ <div style={dappKitThemeReset}>
155
+ <ConnectModal key={modalKey} open />
156
+ </div>
157
+ ) : null;
124
158
  };
125
159
 
126
- export const SuiProvider = ({ children, network }: { children: ReactNode; network: 'testnet' | 'mainnet' }) => {
127
- const { networkConfig } = createNetworkConfig({
128
- testnet: { url: getFullnodeUrl('testnet') },
129
- mainnet: { url: getFullnodeUrl('mainnet') }
130
- });
160
+ export const SuiProvider = ({ children, network }: { children: ReactNode; network: SuiNetwork }) => {
161
+ const dAppKit = getDAppKit();
162
+
163
+ useEffect(() => {
164
+ dAppKit.switchNetwork(network);
165
+ }, [dAppKit, network]);
166
+
131
167
  return (
132
- <SuiClientProvider networks={networkConfig} network={network}>
133
- <WalletProvider autoConnect>
134
- <SuiConnector />
135
- {children}
136
- </WalletProvider>
137
- </SuiClientProvider>
168
+ <DAppKitProvider dAppKit={dAppKit}>
169
+ <SuiConnector />
170
+ {children}
171
+ </DAppKitProvider>
138
172
  );
139
173
  };