• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Mintbase / mintbase-js / 5929901851

21 Aug 2023 06:07PM UTC coverage: 83.47% (+0.2%) from 83.288%
5929901851

push

github

rubenmarcus
add extra support to wallet

613 of 835 branches covered (73.41%)

Branch coverage included in aggregate %.

11 of 11 new or added lines in 1 file covered. (100.0%)

912 of 992 relevant lines covered (91.94%)

4.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.05
/packages/react/src/WalletContext.tsx
1
/* eslint-disable @typescript-eslint/explicit-function-return-type */
2
import React, {
1✔
3
  createContext,
4
  useCallback,
5
  useContext,
6
  useEffect,
7
  useMemo,
8
  useState,
9
} from 'react';
10
import {
1✔
11
  registerWalletAccountsSubscriber,
12
  setupWalletSelectorComponents,
13
  connectWalletSelector,
14
  disconnectFromWalletSelector,
15
  pollForWalletConnection,
16
  signMessage,
17
} from '@mintbase-js/auth/lib/wallet';
18
import type { WalletSelectorComponents } from '@mintbase-js/auth/lib/wallet';
19
import {
1✔
20
  type WalletSelector,
21
  type AccountState,
22
  type VerifiedOwner,
23
  type VerifyOwnerParams,
24
  type WalletModuleFactory,
25
  setupWalletSelector,
26
} from '@near-wallet-selector/core';
27
import type { WalletSelectorModal } from '@near-wallet-selector/modal-ui';
28
import type { Network } from '@mintbase-js/sdk';
29
import { mbjs } from '@mintbase-js/sdk';
1✔
30

31
// This is heavily based on
32
// https://github.com/near/wallet-selector/blob/main/examples/react/contexts/WalletSelectorContext.tsx
33
// but uses wrappers from @mintbase-js/auth and @mintbase-js/sdk
34
export type WalletContext = {
35
  selector: WalletSelector;
36
  modal: WalletSelectorModal;
37
  accounts: AccountState[];
38
  activeAccountId: string | null;
39
  isConnected: boolean;
40
  isWaitingForConnection: boolean;
41
  isWalletSelectorSetup: boolean;
42
  errorMessage: string | null;
43
  connect: () => Promise<void>;
44
  disconnect: () => Promise<void>;
45
  signMessage: (params: VerifyOwnerParams) => Promise<VerifiedOwner>;
46
}
47

48
export type WalletSetupComponents = {
49
  selector: WalletSelector;
50
  modal: WalletSelectorModal;
51
}
52

53
export const WalletContext = createContext<WalletContext | null>(null);
1✔
54

55
export const WalletContextProvider: React.FC<{ children: React.ReactNode; network?: Network; contractAddress?: string; additionalWallets?: Array<WalletModuleFactory>; isMintbaseWallet?: boolean}> = ({
1✔
56
  children, network, contractAddress, additionalWallets, isMintbaseWallet = false,
13✔
57
}): JSX.Element => {
58
  const [errorMessage, setErrorMessage] = useState<string>('');
13✔
59
  const [components, setComponents] = useState<WalletSelectorComponents | null>(
13✔
60
    null,
61
  );
62
  const [accounts, setAccounts] = useState<AccountState[]>([]);
13✔
63
  const [isWaitingForConnection, setIsWaitingForConnection] =
64
    useState<boolean>(false);
13✔
65
  const [isWalletSelectorSetup, setIsWalletSelectorSetup] =
66
    useState<boolean>(false);
13✔
67

68
  const [mbWalletUsername, setMbWalletUsername] =
69
    useState<string>('');
13✔
70
  const [isConnected, setIsConnected] = useState(false);
13✔
71

72
  const [mbWalletSelector, setWalletMb] = useState(null);
13✔
73
  const selectedNetwork =   network || mbjs.keys.network;
13✔
74
  const selectedContract = contractAddress || mbjs.keys.contractAddress;
13✔
75

76

77

13✔
78
  const setup = useCallback(async () => {
3✔
79
    const components = await setupWalletSelectorComponents(
80
      selectedNetwork,
81
      selectedContract,
82
      {
83
        additionalWallets,
84
      },
85
    );
86

3✔
87
    setIsWalletSelectorSetup(true);
3✔
88
    setComponents(components);
89
  }, []);
90

13✔
91
  const onCloseModal = (): void => {
×
92
    setIsWaitingForConnection(false);
93
  };
94

13✔
95
  const setupWallet = async () => {
3✔
96
    const components = await setupWalletSelectorComponents(
97
      selectedNetwork,
98
      selectedContract,
99
      {
100
        additionalWallets,
101
      },
102
    );
103

3✔
104
    console.log(components, additionalWallets, 'components');
105

3✔
106
    return components;
107
  };
108

109

13✔
110
  useEffect(() => {
111

112

3✔
113
    const setupMintbaseWallet = async () => await setupWalletSelector({
114
      network: network,
115
      debug: mbjs.keys.debugMode,
116
      modules: [
117
        ...additionalWallets,
118
      ],
119
    });
120

121

3!
122
    if (isMintbaseWallet) {
123

×
124
      const mbSelector = setupMintbaseWallet();
125

×
126
      setWalletMb(mbSelector)
127
    }
128

129
  
3✔
130
    const handleUsernameChange = (event) => {
131

×
132
      console.log(event, event.detail, event.detail[0]);
×
133
      const newUsername = event.detail[0].accountId;
×
134
      setMbWalletUsername(newUsername);
×
135
      setIsConnected(true);
136

×
137
      setAccounts(event.detail[0]);
138

139
    
×
140
      console.log(isConnected, isMintbaseWallet, mbWalletUsername, accounts, 'mb wallet');
141
    };
142

143
    // Listen for the custom event
3✔
144
    window.addEventListener('mbWalletLogin', handleUsernameChange);
145

146
    // Cleanup the event listener when the component unmounts
3✔
147
    return () => {
3✔
148
      window.removeEventListener('mbWalletLogin', handleUsernameChange);
149
    };
150
  }, []);
151

152

153
  // call setup on wallet selector
13✔
154
  useEffect(() => {
3✔
155
    setupWallet();
156

3✔
157
    setup().catch((err: Error) => {
×
158
      if (err || err.message.length > 0) {
×
159
        setErrorMessage((err as Error).message);
160
      }
161
    });
162

163
    // Add the event listener here
3!
164
    const closeButton = document?.getElementsByClassName('close-button')[0];
3!
165
    closeButton?.addEventListener('click', onCloseModal);
166

167
    // Cleanup the event listener on unmount
3✔
168
    return () => {
3!
169
      closeButton?.removeEventListener('click', onCloseModal);
170
    };
171
  }, [setup]);
172

173
  // subscribe to account state changes
13✔
174
  useEffect(() => {
6✔
175
    if (!components) {
3✔
176
      return undefined;
177
    }
178

3✔
179
    const subscription = registerWalletAccountsSubscriber(
180
      (accounts: AccountState[]) => {
181

3✔
182
        console.log(accounts, 'accounts 1');
3✔
183
        setAccounts(accounts);
184
      },
185
    );
186

3✔
187
    return (): void => {
3✔
188
      subscription.unsubscribe();
189
    };
190
  }, [components]);
191

13✔
192
  const { selector, modal } = components || {};
193

13✔
194
  const connect = async (): Promise<void> => {
2✔
195
    setIsWaitingForConnection(true);
196

2✔
197
    setErrorMessage(null);
2✔
198
    connectWalletSelector();
199

2✔
200
    try {
2✔
201
      const accounts = await pollForWalletConnection();
1✔
202
      setIsWaitingForConnection(false);
1✔
203
      console.log(accounts, 'accounts 2');
1✔
204
      setAccounts(accounts);
205
    } catch (err: unknown) {
1✔
206
      if (err) {
1✔
207
        setErrorMessage((err as Error).message);
208
      }
209
    }
210
  };
211

13✔
212
  const disconnect = async (): Promise<void> => {
1✔
213
    await disconnectFromWalletSelector();
1✔
214
    setIsWaitingForConnection(false);
215
  };
216

13✔
217
  const walletSelectorContextValue = useMemo<WalletContext>(
10✔
218
    () => ({
10!
219
      selector: isMintbaseWallet? mbWalletSelector : selector,
220
      modal: modal,
221
      accounts: accounts,
10!
222
      activeAccountId: isMintbaseWallet ? mbWalletUsername :
4✔
223
        accounts.find((account) => account.active)?.accountId || null,
30!
224
      isConnected: isMintbaseWallet ? isConnected : accounts && accounts.length > 0,
225
      isWaitingForConnection: isWaitingForConnection,
226
      isWalletSelectorSetup: isWalletSelectorSetup,
227
      errorMessage: errorMessage,
228
      connect,
229
      disconnect,
230
      signMessage,
231
    }),
232
    [selector, modal, accounts, isMintbaseWallet, isConnected, mbWalletUsername],
233
  );
234

13✔
235
  return (
236
    <WalletContext.Provider value={walletSelectorContextValue}>
237
      {children}
238
    </WalletContext.Provider>
239
  );
240
};
241

10✔
242
export const useWallet = (): WalletContext => useContext(WalletContext);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc