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

Mintbase / mintbase-js / 5927493979

21 Aug 2023 02:19PM UTC coverage: 83.826% (-0.09%) from 83.916%
5927493979

push

github

rubenmarcus
revert wallet context

609 of 827 branches covered (73.64%)

Branch coverage included in aggregate %.

894 of 966 relevant lines covered (92.55%)

4.84 hits per line

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

89.66
/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 type {
20
  WalletSelector,
21
  AccountState,
22
  VerifiedOwner,
23
  VerifyOwnerParams,
24
  WalletModuleFactory,
25
} from '@near-wallet-selector/core';
26
import type { WalletSelectorModal } from '@near-wallet-selector/modal-ui';
27
import type { Network } from '@mintbase-js/sdk';
28
import { mbjs } from '@mintbase-js/sdk';
1✔
29

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

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

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

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

67
  const selectedNetwork =   network || mbjs.keys.network;
13✔
68
  const selectedContract = contractAddress || mbjs.keys.contractAddress;
13✔
69

70
  const setup = useCallback(async () => {
13✔
71
    const components = await setupWalletSelectorComponents(
3✔
72
      selectedNetwork,
73
      selectedContract,
74
      {
75
        additionalWallets,
76
      },
77
    );
78

79
    setIsWalletSelectorSetup(true);
3✔
80
    setComponents(components);
3✔
81
  }, []);
82

83
  const onCloseModal = (): void => {
13✔
84
    setIsWaitingForConnection(false);
×
85
  };
86

87
  const setupWallet = async () => {
13✔
88
    const components = await setupWalletSelectorComponents(
3✔
89
      selectedNetwork,
90
      selectedContract,
91
      {
92
        additionalWallets,
93
      },
94
    );
95
    return components;
3✔
96
  };
97

98
  // call setup on wallet selector
99
  useEffect(() => {
13✔
100
    setupWallet();
3✔
101

102
    setup().catch((err: Error) => {
3✔
103
      if (err || err.message.length > 0) {
×
104
        setErrorMessage((err as Error).message);
×
105
      }
106
    });
107

108
    // Add the event listener here
109
    const closeButton = document?.getElementsByClassName('close-button')[0];
3!
110
    closeButton?.addEventListener('click', onCloseModal);
3!
111

112
    // Cleanup the event listener on unmount
113
    return () => {
3✔
114
      closeButton?.removeEventListener('click', onCloseModal);
3!
115
    };
116
  }, [setup]);
117

118
  // subscribe to account state changes
119
  useEffect(() => {
13✔
120
    if (!components) {
6✔
121
      return undefined;
3✔
122
    }
123

124
    const subscription = registerWalletAccountsSubscriber(
3✔
125
      (accounts: AccountState[]) => {
126
        setAccounts(accounts);
3✔
127
      },
128
    );
129

130
    return (): void => {
3✔
131
      subscription.unsubscribe();
3✔
132
    };
133
  }, [components]);
134

135
  const { selector, modal } = components || {};
13✔
136

137
  const connect = async (): Promise<void> => {
13✔
138
    setIsWaitingForConnection(true);
2✔
139

140
    setErrorMessage(null);
2✔
141
    connectWalletSelector();
2✔
142

143
    try {
2✔
144
      const accounts = await pollForWalletConnection();
2✔
145
      setIsWaitingForConnection(false);
1✔
146
      setAccounts(accounts);
1✔
147
    } catch (err: unknown) {
148
      if (err) {
1✔
149
        setErrorMessage((err as Error).message);
1✔
150
      }
151
    }
152
  };
153

154
  const disconnect = async (): Promise<void> => {
13✔
155
    await disconnectFromWalletSelector();
1✔
156
    setIsWaitingForConnection(false);
1✔
157
  };
158

159
  const walletSelectorContextValue = useMemo<WalletContext>(
13✔
160
    () => ({
10✔
161
      selector: selector,
162
      modal: modal,
163
      accounts: accounts,
164
      activeAccountId:
165
        accounts.find((account) => account.active)?.accountId || null,
4✔
166
      isConnected: accounts && accounts.length > 0,
20✔
167
      isWaitingForConnection: isWaitingForConnection,
168
      isWalletSelectorSetup: isWalletSelectorSetup,
169
      errorMessage: errorMessage,
170
      connect,
171
      disconnect,
172
      signMessage,
173
    }),
174
    [selector, modal, accounts],
175
  );
176

177
  return (
13✔
178
    <WalletContext.Provider value={walletSelectorContextValue}>
179
      {children}
180
    </WalletContext.Provider>
181
  );
182
};
183

184
export const useWallet = (): WalletContext => useContext(WalletContext);
10✔
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