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

Mintbase / mintbase-js / 10668820689

02 Sep 2024 02:16PM UTC coverage: 72.702%. First build
10668820689

Pull #534

github

rubenmarcus
react package
Pull Request #534: remove browser wallet check

877 of 1390 branches covered (63.09%)

Branch coverage included in aggregate %.

1195 of 1460 relevant lines covered (81.85%)

13.35 hits per line

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

24.55
/packages/react/src/wallet/wallet.ts
1
import {
3✔
2
  setupWalletSelector,
3
  VerifiedOwner,
4
  VerifyOwnerParams,
5
  Wallet,
6
} from '@near-wallet-selector/core';
7
import { setupModal } from '@near-wallet-selector/modal-ui';
3✔
8
import { distinctUntilChanged, map, Subscription } from 'rxjs';
3✔
9

10
import {
3✔
11
  WALLET_CONNECTION_POLL_INTERVAL,
12
  WALLET_CONNECTION_TIMEOUT,
13
} from './constants';
14

15
import { setupHereWallet } from '@near-wallet-selector/here-wallet';
3✔
16
import { setupMeteorWallet } from '@near-wallet-selector/meteor-wallet';
3✔
17
import { setupMyNearWallet } from '@near-wallet-selector/my-near-wallet';
3✔
18

19

20
import { setupBitteWallet, setupMintbaseWallet } from '@mintbase-js/wallet';
3✔
21
import type {
22
  AccountState,
23
  WalletModuleFactory,
24
  WalletSelector,
25
} from '@near-wallet-selector/core';
26
import type { WalletSelectorModal } from '@near-wallet-selector/modal-ui';
27

28
// error messages
29
const SUPPORT = '- further help available on our telegram channel: https://t.me/mintdev';
3✔
30

31
export const ERROR_MESSAGES =  {
3✔
32
  WALLET_SETUP_NOT_CALLED_ERROR : `Call and await setupWalletSelectorComponents() before registering a subscriber - ${SUPPORT}`,
33
  WALLET_CONNECTION_NOT_FOUND:  `Wallet connection not received after ${WALLET_CONNECTION_TIMEOUT}ms - ${SUPPORT}`,
34
};
35

36
export const SUPPORTED_NEAR_WALLETS: Array<WalletModuleFactory> =[
3✔
37
  setupMeteorWallet(),
38
  setupMyNearWallet(),
39
  setupHereWallet(),
40
];
41

42
// mintbase SDK wallet functionality wraps
43
// Near Wallet Selector lib, provided by NEAR Protocol
44
// https://github.com/near/wallet-selector/
45

46
export type WalletSelectorComponents = {
47
  selector: WalletSelector;
48
  modal: WalletSelectorModal;
49
}
50

51
// wallet components are held and exposed as a singleton reference
52
// this way they can be more easily passed to other components vs composing calls.
53
export let walletSelectorComponents: WalletSelectorComponents = {
3✔
54
  selector: null,
55
  modal: null,
56
};
57

58
/**
59
 * Set up wallet selector components. Returns the modal
60
 * See also docs on {@link https://github.com/near/wallet-selector/ | near wallet selector}
61
 */
62

63
const walletUrls = {
3✔
64
  testnet: 'https://testnet.wallet.mintbase.xyz/',
65
  mainnet: 'https://wallet.mintbase.xyz',
66
};
67

68
const BitteWalletUrls = {
3✔
69
  testnet: 'https://testnet.wallet.bitte.ai/',
70
  mainnet: 'https://wallet.bitte.ai/',
71
};
72

73
// eslint-disable-next-line max-len
74
export const setupMintbaseWalletSelector = async (
3✔
75
  callbackUrl,
76
  onlyMbWallet = false,
×
77
  network?,
78
  contractAddress?,
79
  options?: { additionalWallets?: Array<WalletModuleFactory> },
80
  successUrl?: string,
81
  failureUrl?: string,
82
): Promise<WalletSelectorComponents> => {
×
83

84

85
  const BitteModuleWallet = {
×
86
    walletUrl: BitteWalletUrls[network],
87
    callbackUrl: callbackUrl,
88
    contractId: contractAddress,
89
  };
90

91
  const MbModuleWallet = {
×
92
    walletUrl: walletUrls[network],
93
    callbackUrl: callbackUrl,
94
    contractId: contractAddress,
95
  };
96

97
  if (onlyMbWallet === false) {
×
98
    const moduleWallet = {
×
99
      ...MbModuleWallet,
100
      successUrl: successUrl || window.location.href,
×
101
      failureUrl: successUrl || window.location.href,
×
102
    };
103

104
    walletSelectorComponents.selector = await setupWalletSelector({
×
105
      network: network,
106
      modules: [
107
        setupBitteWallet(BitteModuleWallet),
108
        setupMintbaseWallet(moduleWallet),
109
        ...(options?.additionalWallets || []),
×
110
        ...SUPPORTED_NEAR_WALLETS,
111
      ],
112
    });
113
  } else {
114
    walletSelectorComponents.selector = await setupWalletSelector({
×
115
      network: network,
116
      modules: [
117
        setupBitteWallet(
118
          BitteModuleWallet,
119
        ),
120
        setupMintbaseWallet(
121
          MbModuleWallet,
122
        ),
123
        ...(options?.additionalWallets || []),
×
124
      ],
125
    });
126
  }
127

128
  walletSelectorComponents.modal = setupModal(walletSelectorComponents.selector, {
×
129
    contractId: contractAddress,
130
  });
131

132
  return walletSelectorComponents;
×
133
};
134

135
export const setupWalletSelectorComponents = async (
3✔
136
  network?,
137
  contractAddress?,
138
  options?: { additionalWallets?: Array<WalletModuleFactory> },
139
): Promise<WalletSelectorComponents> => {
×
140
  const selector = await setupWalletSelector({
×
141
    network: network,
142
    modules: [
143
      ...SUPPORTED_NEAR_WALLETS,
144
      ...(options?.additionalWallets || []),
×
145
    ],
146
  });
147

148
  const modal = setupModal(selector, {
×
149
    contractId: contractAddress,
150
  });
151

152
  walletSelectorComponents = {
×
153
    selector,
154
    modal,
155
  };
156
  return walletSelectorComponents;
×
157
};
158

159
export class SetupNotCalledError extends Error {
3✔
160
  message: string
161
}
162

163
export class ConnectionTimeoutError extends Error {
3✔
164
  message: string
165
}
166

167
const validateWalletComponentsAreSetup = (): void => {
3✔
168
  if (!walletSelectorComponents.selector) {
×
169
    throw new SetupNotCalledError(ERROR_MESSAGES.WALLET_SETUP_NOT_CALLED_ERROR);
×
170
  }
171
};
172

173
export const registerWalletAccountsSubscriber = (
3✔
174
  callback: (accounts: AccountState[]) => void,
175
): Subscription => {
176
  validateWalletComponentsAreSetup();
×
177

178
  return walletSelectorComponents.selector.store.observable
×
179
    .pipe(
180
      map((state) => state.accounts),
×
181
      distinctUntilChanged(),
182
    )
183
    .subscribe(callback);
184
};
185

186
// scoped to module and cleared since pollForWalletConnection might
187
// get called repeatedly in react enviroments
188
let timerReference = null;
3✔
189

190
export const pollForWalletConnection = async (): Promise<AccountState[]> => {
3✔
191
  validateWalletComponentsAreSetup();
×
192
  // clear any existing timer
193
  clearTimeout(timerReference);
×
194

195
  const tryToResolveAccountsFromState = (
×
196
    resolve: (value: AccountState[]) => void,
197
    reject: (err: ConnectionTimeoutError) => void,
198
    elapsed = 0,
×
199
  ): void => {
200
    const { accounts } =
201
      walletSelectorComponents.selector.store.getState() || {};
×
202

203
    // accounts present in state
204
    if (accounts) {
×
205
      resolve(accounts);
×
206
    }
207

208
    // timed out
209
    if (elapsed > WALLET_CONNECTION_TIMEOUT) {
×
210
      reject(
×
211
        new ConnectionTimeoutError(ERROR_MESSAGES.WALLET_CONNECTION_NOT_FOUND),
212
      );
213
    }
214

215
    // try again
216
    clearTimeout(timerReference);
×
217
    timerReference = setTimeout(
×
218
      () =>
219
        tryToResolveAccountsFromState(
×
220
          resolve,
221
          reject,
222
          elapsed + WALLET_CONNECTION_POLL_INTERVAL,
223
        ),
224
      WALLET_CONNECTION_POLL_INTERVAL,
225
    );
226
  };
227

228
  return new Promise((resolve, reject) =>
×
229
    tryToResolveAccountsFromState(resolve, reject),
×
230
  );
231
};
232

233
export const getWallet = async (): Promise<Wallet> => {
3✔
234
  validateWalletComponentsAreSetup();
×
235

236
  return await walletSelectorComponents.selector.wallet();
×
237
};
238

239
export const connectWalletSelector = (): void => {
3✔
240
  validateWalletComponentsAreSetup();
×
241

242
  walletSelectorComponents.modal.show();
×
243
};
244

245
export const disconnectFromWalletSelector = async (): Promise<void> => {
3✔
246
  validateWalletComponentsAreSetup();
×
247

248
  const wallet = await walletSelectorComponents.selector.wallet();
×
249
  wallet.signOut();
×
250
};
251

252
export const getVerifiedOwner = async (
3✔
253
  params: VerifyOwnerParams,
254
): Promise<VerifiedOwner | undefined> => {
×
255
  validateWalletComponentsAreSetup();
×
256

257
  const { message, callbackUrl, meta } = params;
×
258

259
  const wallet = await walletSelectorComponents.selector.wallet();
×
260

261
  const owner = (await wallet.verifyOwner({
×
262
    message: message,
263
    callbackUrl: callbackUrl,
264
    meta: meta,
265
  })) as VerifiedOwner;
266

267
  return owner;
×
268
};
269

270
// returns a signature of message
271
export const signMessage = async (
3✔
272
  params: VerifyOwnerParams,
273
): Promise<VerifiedOwner> => {
×
274
  const owner = await getVerifiedOwner(params);
×
275

276
  return owner;
×
277
};
278

279

280
//  https://www.npmjs.com/package/bs58
281
// https://github.com/feross/buffer
282
// https://github.com/near/wallet-selector/issues/434
283
// export const verifyMessage = async (signature: string): Promise<boolean> => {
284

285
//   // const owner = await getVerifiedOwner(signature);
286

287
//   // const publicKeyString = `ed25519:${BinaryToBase58(Buffer.from(owner.publicKey, 'base64'))}`;
288

289
//   // const createdPublicKey = utils.PublicKey.from(publicKeyString);
290

291
//   // const stringified = JSON.stringify(owner);
292

293
//   // const verified = createdPublicKey.verify(new Uint8Array(sha256.array(stringified)), Buffer.from(signature, 'base64'));
294

295
//   return false;
296
// };
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