@xyo-network/react-wallet 7.5.4 → 7.5.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/react-wallet",
3
- "version": "7.5.4",
3
+ "version": "7.5.6",
4
4
  "description": "Common React library for all XYO projects that use React",
5
5
  "keywords": [
6
6
  "xyo",
@@ -44,42 +44,42 @@
44
44
  ],
45
45
  "dependencies": {
46
46
  "@scure/bip39": "~2.0.1",
47
- "@xylabs/eth-address": "~5.0.79",
48
- "@xylabs/react-button": "~7.1.15",
49
- "@xylabs/react-crypto": "~7.1.15",
50
- "@xylabs/react-flexbox": "~7.1.15",
51
- "@xylabs/react-hooks": "~7.1.15",
52
- "@xylabs/react-number-status": "~7.1.15",
53
- "@xylabs/react-promise": "~7.1.15",
54
- "@xylabs/react-select": "~7.1.15",
55
- "@xylabs/react-shared": "~7.1.15",
56
- "@xyo-network/account-model": "~5.3.5",
57
- "@xyo-network/react-address-render": "7.5.4",
58
- "@xyo-network/react-network": "7.5.4",
59
- "@xyo-network/wallet": "~5.3.5",
60
- "@xyo-network/wallet-model": "~5.3.5",
47
+ "@xylabs/eth-address": "~5.0.90",
48
+ "@xylabs/react-button": "~7.1.17",
49
+ "@xylabs/react-crypto": "~7.1.17",
50
+ "@xylabs/react-flexbox": "~7.1.17",
51
+ "@xylabs/react-hooks": "~7.1.17",
52
+ "@xylabs/react-number-status": "~7.1.17",
53
+ "@xylabs/react-promise": "~7.1.17",
54
+ "@xylabs/react-select": "~7.1.17",
55
+ "@xylabs/react-shared": "~7.1.17",
56
+ "@xyo-network/account-model": "~5.3.17",
57
+ "@xyo-network/react-address-render": "7.5.6",
58
+ "@xyo-network/react-network": "7.5.6",
59
+ "@xyo-network/wallet": "~5.3.17",
60
+ "@xyo-network/wallet-model": "~5.3.17",
61
61
  "async-mutex": "~0.5.0"
62
62
  },
63
63
  "devDependencies": {
64
- "@microsoft/api-extractor": "~7.56.3",
65
- "@mui/icons-material": "~7.3.8",
66
- "@mui/material": "~7.3.8",
67
- "@storybook/react-vite": "~10.2.9",
64
+ "@microsoft/api-extractor": "~7.57.7",
65
+ "@mui/icons-material": "~7.3.9",
66
+ "@mui/material": "~7.3.9",
67
+ "@storybook/react-vite": "~10.3.3",
68
68
  "@types/react": "^19.2.14",
69
- "@xylabs/react-identicon": "~7.1.15",
70
- "@xylabs/react-quick-tip-button": "~7.1.15",
71
- "@xylabs/sdk-js": "~5.0.79",
72
- "@xylabs/ts-scripts-yarn3": "~7.3.2",
73
- "@xylabs/tsconfig": "~7.3.2",
74
- "@xylabs/tsconfig-dom": "~7.3.2",
75
- "@xylabs/tsconfig-react": "~7.3.2",
76
- "@xyo-network/react-storybook": "7.5.4",
69
+ "@xylabs/react-identicon": "~7.1.17",
70
+ "@xylabs/react-quick-tip-button": "~7.1.17",
71
+ "@xylabs/sdk-js": "~5.0.90",
72
+ "@xylabs/ts-scripts-yarn3": "~7.5.6",
73
+ "@xylabs/tsconfig": "~7.5.6",
74
+ "@xylabs/tsconfig-dom": "~7.5.6",
75
+ "@xylabs/tsconfig-react": "~7.5.6",
76
+ "@xyo-network/react-storybook": "7.5.6",
77
77
  "react": "^19.2.4",
78
78
  "react-dom": "^19.2.4",
79
- "react-router-dom": "^7.13.0",
80
- "storybook": "~10.2.9",
79
+ "react-router-dom": "^7.13.2",
80
+ "storybook": "~10.3.3",
81
81
  "typescript": "^5.9.3",
82
- "vite": "~7.3.1",
82
+ "vite": "~8.0.3",
83
83
  "zod": "^4.3.6"
84
84
  },
85
85
  "peerDependencies": {
@@ -3,8 +3,9 @@ import {
3
3
  } from '@mui/material'
4
4
  import { generateMnemonic } from '@scure/bip39'
5
5
  import { wordlist } from '@scure/bip39/wordlists/english.js'
6
+ import { isUndefinedOrNull } from '@xylabs/sdk-js'
6
7
  import type { PropsWithChildren } from 'react'
7
- import React, { useMemo, useState } from 'react'
8
+ import React, { useState } from 'react'
8
9
 
9
10
  /** @public */
10
11
  export interface DefaultSeedPhraseProps extends PropsWithChildren {
@@ -18,14 +19,15 @@ export const DefaultSeedPhrase: React.FC<DefaultSeedPhraseProps> = ({
18
19
  changeSeedPhrase, children, hideDefaultSeedPhraseMessage, seedPhrase,
19
20
  }) => {
20
21
  const [showSnackBar, setShowSnackBar] = useState(false)
21
-
22
- useMemo(() => {
23
- if (!seedPhrase) {
22
+ const [previousSeedPhrase, setPreviousSeedPhrase] = useState<string | undefined>()
23
+ if (seedPhrase !== previousSeedPhrase) {
24
+ setPreviousSeedPhrase(seedPhrase)
25
+ if (isUndefinedOrNull(previousSeedPhrase) && !isUndefinedOrNull(seedPhrase)) {
24
26
  const mnemonic = generateMnemonic(wordlist, 256)
25
27
  changeSeedPhrase?.(mnemonic)
26
28
  setShowSnackBar(true)
27
29
  }
28
- }, [changeSeedPhrase, seedPhrase])
30
+ }
29
31
 
30
32
  return (
31
33
  <>
@@ -6,7 +6,7 @@ import {
6
6
  useTheme,
7
7
  } from '@mui/material'
8
8
  import { FlexRow } from '@xylabs/react-flexbox'
9
- import React, { useMemo, useState } from 'react'
9
+ import React, { useState } from 'react'
10
10
 
11
11
  import { useSeedPhrase } from '../../../../../contexts/index.ts'
12
12
  import { InvalidPhraseTypography, PhraseHeaderBox } from './validation-messages/index.ts'
@@ -29,9 +29,11 @@ export const SavedPhraseTextField: React.FC<SavedPhraseTextFieldProps> = ({
29
29
 
30
30
  const [visible, setVisible] = useState(visibleProp)
31
31
 
32
- useMemo(() => {
32
+ const [previousVisibleProp, setPreviousVisibleProp] = useState(visibleProp)
33
+ if (visibleProp !== previousVisibleProp) {
34
+ setPreviousVisibleProp(visibleProp)
33
35
  setVisible(visibleProp)
34
- }, [visibleProp])
36
+ }
35
37
 
36
38
  const [copied, setCopied] = useState(false)
37
39
  const onCopyPhrase = async () => {
@@ -1,12 +1,10 @@
1
1
  import type { SelectProps } from '@mui/material'
2
- import { CircularProgress, MenuItem } from '@mui/material'
2
+ import { CircularProgress } from '@mui/material'
3
3
  import { SelectEx } from '@xylabs/react-select'
4
4
  import type { AddressRenderRowBoxProps } from '@xyo-network/react-address-render'
5
- import { AddressRenderRowBox } from '@xyo-network/react-address-render'
6
5
  import React from 'react'
7
6
 
8
7
  import { useWalletContext } from '../../contexts/index.ts'
9
- import { useWallet } from '../../hooks/index.ts'
10
8
  import { RenderedAccountMenuItem } from './RenderedMenuItem.tsx'
11
9
 
12
10
  type SharedAddressRenderRowBoxProps = Pick<AddressRenderRowBoxProps, 'iconOnly' | 'iconSize' | 'icons' | 'showFavorite'>
@@ -66,32 +64,18 @@ export const WalletAccountSelect: React.FC<WalletAccountSelectProps> = ({
66
64
  variant={variant}
67
65
  {...props}
68
66
  >
69
- {rootWallet && arrayRange(maxAccounts).map((index) => {
70
- const [account] = useWallet({ path: index.toString(), wallet: rootWallet })
71
- const customName = account ? addressNames?.[account.address] : undefined
72
- const favorite = !!account && account.address in (addressNames ?? {})
73
- return (
74
- <MenuItem
75
- key={account?.address}
76
- value={index}
77
- sx={{
78
- minHeight: 0, paddingBottom: 0, paddingTop: 0,
79
- }}
80
- >
81
- <AddressRenderRowBox
82
- disableSharedRef={true}
83
- flexGrow={1}
84
- address={account?.address}
85
- favorite={favorite}
86
- iconOnly={iconOnly}
87
- iconSize={iconSize}
88
- icons={icons}
89
- name={customName}
90
- showFavorite={showFavorite}
91
- />
92
- </MenuItem>
93
- )
94
- })}
67
+ {rootWallet && arrayRange(maxAccounts).map(index => (
68
+ <RenderedAccountMenuItem
69
+ key={index}
70
+ addressNames={addressNames}
71
+ iconOnly={iconOnly}
72
+ iconSize={iconSize}
73
+ icons={icons}
74
+ rootWallet={rootWallet}
75
+ selectedAccountIndex={index}
76
+ showFavorite={showFavorite}
77
+ />
78
+ ))}
95
79
  </SelectEx>
96
80
  )
97
81
  : <CircularProgress size={24} />}
@@ -1,7 +1,7 @@
1
1
  import type { Decorator } from '@storybook/react-vite'
2
2
  import { DefaultSeedPhrase } from '@xyo-network/react-storybook'
3
3
  import type { WalletInstance } from '@xyo-network/wallet-model'
4
- import React, { useMemo, useState } from 'react'
4
+ import React, { useEffect, useState } from 'react'
5
5
 
6
6
  import { WalletProvider } from '../../../contexts/index.ts'
7
7
  import { useWallet } from '../../../hooks/index.ts'
@@ -10,12 +10,18 @@ export const WalletProviderDecorator: Decorator = (Story, context) => {
10
10
  const [rootWallet] = useWallet({ mnemonic: DefaultSeedPhrase })
11
11
  const [wallet, setWallet] = useState<WalletInstance>()
12
12
 
13
- useMemo(() => {
13
+ useEffect(() => {
14
+ let timeout: ReturnType<typeof setTimeout>
14
15
  if (rootWallet) {
15
- setTimeout(() => {
16
+ timeout = setTimeout(() => {
16
17
  setWallet(rootWallet)
17
18
  }, 1000)
18
19
  }
20
+ return () => {
21
+ if (timeout) {
22
+ clearTimeout(timeout)
23
+ }
24
+ }
19
25
  }, [rootWallet])
20
26
  return (
21
27
  <WalletProvider rootWallet={wallet}>
@@ -47,7 +47,7 @@ export const SeedPhraseProvider: React.FC<SeedPhraseProviderProps> = ({
47
47
  const mnemonic = generateMnemonic(wordlist, 256)
48
48
  setPhrase?.(mnemonic)
49
49
  setOverwriteWarning?.(false)
50
- }, [])
50
+ }, [setPhrase])
51
51
 
52
52
  const handleCancelOverwrite = useCallback(() => {
53
53
  setOverwriteWarning(false)
@@ -91,19 +91,7 @@ export const SeedPhraseProvider: React.FC<SeedPhraseProviderProps> = ({
91
91
  validPhrase,
92
92
  validSeedPhrase,
93
93
  validate,
94
- }), [handleCancelOverwrite,
95
- handleChangeSeedPhrase,
96
- handleClear,
97
- handleGenerate,
98
- handleSave,
99
- overwriteWarning,
100
- phrase,
101
- seedPhrase,
102
- setOverwriteWarning,
103
- setPhrase,
104
- validPhrase,
105
- validSeedPhrase,
106
- validate])
94
+ }), [handleCancelOverwrite, handleChangeSeedPhrase, handleClear, handleGenerate, handleSave, overwriteWarning, phrase, seedPhrase, setOverwriteWarning, setPhrase, validPhrase, validSeedPhrase])
107
95
 
108
96
  return (
109
97
  <SeedPhraseContext
@@ -1,87 +0,0 @@
1
- // Inspired from https://github.com/bsonntag/react-use-promise
2
-
3
- import type { EnumValue } from '@xylabs/sdk-js'
4
- import { Enum } from '@xylabs/sdk-js'
5
- import { Mutex } from 'async-mutex'
6
- import type { DependencyList } from 'react'
7
- import {
8
- useEffect, useMemo, useState,
9
- } from 'react'
10
-
11
- export const State = Enum({
12
- pending: 'pending',
13
- rejected: 'rejected',
14
- resolved: 'resolved',
15
- })
16
-
17
- export type State = EnumValue<typeof State>
18
-
19
- /**
20
- * usePromise -
21
- */
22
- export const usePromise = <TResult>(
23
- promise: () => Promise<TResult | undefined>,
24
- dependencies: DependencyList,
25
- debug: string | undefined = undefined,
26
- ): [TResult | undefined, Error | undefined, State | undefined] => {
27
- const [result, setResult] = useState<TResult>()
28
- const [error, setError] = useState<Error>()
29
- const [state, setState] = useState<State>(State.pending)
30
- const mutex = useMemo(() => {
31
- return new Mutex()
32
- }, [])
33
-
34
- if (debug) console.log(`usePromise [${debug}]: started [${typeof promise}]`)
35
-
36
- const promiseMemo: Promise<TResult | undefined> | undefined = useMemo(() => {
37
- try {
38
- if (debug) console.log(`usePromise [${debug}]: re-memo [${typeof promise}]`)
39
- setState(State.pending)
40
- return promise?.()
41
- } catch (e) {
42
- if (debug) console.log(`usePromise [${debug}]: useMemo rejection [${typeof promise}]`)
43
- setResult(undefined)
44
- setError(e as Error)
45
- setState(State.rejected)
46
- }
47
- }, dependencies)
48
-
49
- if (debug) console.log(`usePromise [${debug}] Main Function`)
50
-
51
- useEffect(() => {
52
- if (debug) console.log(`usePromise [${debug}] useEffect`)
53
- mutex
54
- ?.acquire()
55
- .then(() => {
56
- promiseMemo
57
- ?.then((payload) => {
58
- if (debug) console.log(`usePromise [${debug}] then`)
59
- setResult(payload)
60
- setError(undefined)
61
- setState(State.resolved)
62
- mutex?.release()
63
- })
64
- .catch((e) => {
65
- const error = e as Error
66
- console.error(`usePromise: ${error.message}`)
67
- setResult(undefined)
68
- setError(error)
69
- setState(State.rejected)
70
- mutex?.release()
71
- })
72
- })
73
- .catch((e) => {
74
- const error = e as Error
75
- console.error(`usePromise: ${error.message}`)
76
- setResult(undefined)
77
- setError(error)
78
- setState(State.rejected)
79
- mutex?.release()
80
- })
81
- return () => {
82
- if (debug) console.log(`usePromise [${debug}] useEffect callback`)
83
- }
84
- }, [...dependencies, promiseMemo])
85
- if (debug) console.log(`usePromise [${debug}] returning ${JSON.stringify([result, error, state], null, 2)}`)
86
- return [result, error, state]
87
- }