@xyo-network/react-wallet 2.41.46 → 2.41.47

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.
Files changed (150) hide show
  1. package/dist/cjs/components/SeedPhrase/SeedPhraseIconButton.js +15 -0
  2. package/dist/cjs/components/SeedPhrase/SeedPhraseIconButton.js.map +1 -0
  3. package/dist/cjs/components/SeedPhrase/dialog/SeedPhraseDialog.js +20 -0
  4. package/dist/cjs/components/SeedPhrase/dialog/SeedPhraseDialog.js.map +1 -0
  5. package/dist/cjs/components/SeedPhrase/dialog/components/DialogActionButtons.js +19 -0
  6. package/dist/cjs/components/SeedPhrase/dialog/components/DialogActionButtons.js.map +1 -0
  7. package/dist/cjs/components/SeedPhrase/dialog/components/OverwriteWarning.js +13 -0
  8. package/dist/cjs/components/SeedPhrase/dialog/components/OverwriteWarning.js.map +1 -0
  9. package/dist/cjs/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.js +13 -0
  10. package/dist/cjs/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.js.map +1 -0
  11. package/dist/cjs/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.js +15 -0
  12. package/dist/cjs/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.js.map +1 -0
  13. package/dist/cjs/components/SeedPhrase/dialog/components/fields/index.js +6 -0
  14. package/dist/cjs/components/SeedPhrase/dialog/components/fields/index.js.map +1 -0
  15. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.js +8 -0
  16. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.js.map +1 -0
  17. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.js +35 -0
  18. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.js.map +1 -0
  19. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.js +15 -0
  20. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.js.map +1 -0
  21. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/index.js +7 -0
  22. package/dist/cjs/components/SeedPhrase/dialog/components/fields/validation-messages/index.js.map +1 -0
  23. package/dist/cjs/components/SeedPhrase/dialog/components/index.js +7 -0
  24. package/dist/cjs/components/SeedPhrase/dialog/components/index.js.map +1 -0
  25. package/dist/cjs/components/SeedPhrase/dialog/index.js +5 -0
  26. package/dist/cjs/components/SeedPhrase/dialog/index.js.map +1 -0
  27. package/dist/cjs/components/SeedPhrase/index.js +6 -0
  28. package/dist/cjs/components/SeedPhrase/index.js.map +1 -0
  29. package/dist/cjs/components/index.js +1 -0
  30. package/dist/cjs/components/index.js.map +1 -1
  31. package/dist/cjs/contexts/SeedPhrase/Context.js +6 -0
  32. package/dist/cjs/contexts/SeedPhrase/Context.js.map +1 -0
  33. package/dist/cjs/contexts/SeedPhrase/Provider.js +73 -0
  34. package/dist/cjs/contexts/SeedPhrase/Provider.js.map +1 -0
  35. package/dist/cjs/contexts/SeedPhrase/State.js +3 -0
  36. package/dist/cjs/contexts/SeedPhrase/State.js.map +1 -0
  37. package/dist/cjs/contexts/SeedPhrase/index.js +8 -0
  38. package/dist/cjs/contexts/SeedPhrase/index.js.map +1 -0
  39. package/dist/cjs/contexts/SeedPhrase/use.js +8 -0
  40. package/dist/cjs/contexts/SeedPhrase/use.js.map +1 -0
  41. package/dist/cjs/contexts/index.js +1 -0
  42. package/dist/cjs/contexts/index.js.map +1 -1
  43. package/dist/docs.json +2252 -1121
  44. package/dist/esm/components/SeedPhrase/SeedPhraseIconButton.js +10 -0
  45. package/dist/esm/components/SeedPhrase/SeedPhraseIconButton.js.map +1 -0
  46. package/dist/esm/components/SeedPhrase/dialog/SeedPhraseDialog.js +13 -0
  47. package/dist/esm/components/SeedPhrase/dialog/SeedPhraseDialog.js.map +1 -0
  48. package/dist/esm/components/SeedPhrase/dialog/components/DialogActionButtons.js +13 -0
  49. package/dist/esm/components/SeedPhrase/dialog/components/DialogActionButtons.js.map +1 -0
  50. package/dist/esm/components/SeedPhrase/dialog/components/OverwriteWarning.js +9 -0
  51. package/dist/esm/components/SeedPhrase/dialog/components/OverwriteWarning.js.map +1 -0
  52. package/dist/esm/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.js +9 -0
  53. package/dist/esm/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.js.map +1 -0
  54. package/dist/esm/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.js +11 -0
  55. package/dist/esm/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.js.map +1 -0
  56. package/dist/esm/components/SeedPhrase/dialog/components/fields/index.js +3 -0
  57. package/dist/esm/components/SeedPhrase/dialog/components/fields/index.js.map +1 -0
  58. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.js +4 -0
  59. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.js.map +1 -0
  60. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.js +29 -0
  61. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.js.map +1 -0
  62. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.js +11 -0
  63. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.js.map +1 -0
  64. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/index.js +4 -0
  65. package/dist/esm/components/SeedPhrase/dialog/components/fields/validation-messages/index.js.map +1 -0
  66. package/dist/esm/components/SeedPhrase/dialog/components/index.js +4 -0
  67. package/dist/esm/components/SeedPhrase/dialog/components/index.js.map +1 -0
  68. package/dist/esm/components/SeedPhrase/dialog/index.js +2 -0
  69. package/dist/esm/components/SeedPhrase/dialog/index.js.map +1 -0
  70. package/dist/esm/components/SeedPhrase/index.js +3 -0
  71. package/dist/esm/components/SeedPhrase/index.js.map +1 -0
  72. package/dist/esm/components/index.js +1 -0
  73. package/dist/esm/components/index.js.map +1 -1
  74. package/dist/esm/contexts/SeedPhrase/Context.js +3 -0
  75. package/dist/esm/contexts/SeedPhrase/Context.js.map +1 -0
  76. package/dist/esm/contexts/SeedPhrase/Provider.js +69 -0
  77. package/dist/esm/contexts/SeedPhrase/Provider.js.map +1 -0
  78. package/dist/esm/contexts/SeedPhrase/State.js +2 -0
  79. package/dist/esm/contexts/SeedPhrase/State.js.map +1 -0
  80. package/dist/esm/contexts/SeedPhrase/index.js +5 -0
  81. package/dist/esm/contexts/SeedPhrase/index.js.map +1 -0
  82. package/dist/esm/contexts/SeedPhrase/use.js +4 -0
  83. package/dist/esm/contexts/SeedPhrase/use.js.map +1 -0
  84. package/dist/esm/contexts/index.js +1 -0
  85. package/dist/esm/contexts/index.js.map +1 -1
  86. package/dist/types/components/SeedPhrase/SeedPhraseIconButton.d.ts +4 -0
  87. package/dist/types/components/SeedPhrase/SeedPhraseIconButton.d.ts.map +1 -0
  88. package/dist/types/components/SeedPhrase/dialog/SeedPhraseDialog.d.ts +9 -0
  89. package/dist/types/components/SeedPhrase/dialog/SeedPhraseDialog.d.ts.map +1 -0
  90. package/dist/types/components/SeedPhrase/dialog/components/DialogActionButtons.d.ts +8 -0
  91. package/dist/types/components/SeedPhrase/dialog/components/DialogActionButtons.d.ts.map +1 -0
  92. package/dist/types/components/SeedPhrase/dialog/components/OverwriteWarning.d.ts +3 -0
  93. package/dist/types/components/SeedPhrase/dialog/components/OverwriteWarning.d.ts.map +1 -0
  94. package/dist/types/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.d.ts +4 -0
  95. package/dist/types/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.d.ts.map +1 -0
  96. package/dist/types/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.d.ts +4 -0
  97. package/dist/types/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.d.ts.map +1 -0
  98. package/dist/types/components/SeedPhrase/dialog/components/fields/index.d.ts +3 -0
  99. package/dist/types/components/SeedPhrase/dialog/components/fields/index.d.ts.map +1 -0
  100. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.d.ts +4 -0
  101. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.d.ts.map +1 -0
  102. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.d.ts +9 -0
  103. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.d.ts.map +1 -0
  104. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.d.ts +2 -0
  105. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.d.ts.map +1 -0
  106. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/index.d.ts +4 -0
  107. package/dist/types/components/SeedPhrase/dialog/components/fields/validation-messages/index.d.ts.map +1 -0
  108. package/dist/types/components/SeedPhrase/dialog/components/index.d.ts +4 -0
  109. package/dist/types/components/SeedPhrase/dialog/components/index.d.ts.map +1 -0
  110. package/dist/types/components/SeedPhrase/dialog/index.d.ts +2 -0
  111. package/dist/types/components/SeedPhrase/dialog/index.d.ts.map +1 -0
  112. package/dist/types/components/SeedPhrase/index.d.ts +3 -0
  113. package/dist/types/components/SeedPhrase/index.d.ts.map +1 -0
  114. package/dist/types/components/index.d.ts +1 -0
  115. package/dist/types/components/index.d.ts.map +1 -1
  116. package/dist/types/contexts/SeedPhrase/Context.d.ts +4 -0
  117. package/dist/types/contexts/SeedPhrase/Context.d.ts.map +1 -0
  118. package/dist/types/contexts/SeedPhrase/Provider.d.ts +12 -0
  119. package/dist/types/contexts/SeedPhrase/Provider.d.ts.map +1 -0
  120. package/dist/types/contexts/SeedPhrase/State.d.ts +18 -0
  121. package/dist/types/contexts/SeedPhrase/State.d.ts.map +1 -0
  122. package/dist/types/contexts/SeedPhrase/index.d.ts +5 -0
  123. package/dist/types/contexts/SeedPhrase/index.d.ts.map +1 -0
  124. package/dist/types/contexts/SeedPhrase/use.d.ts +2 -0
  125. package/dist/types/contexts/SeedPhrase/use.d.ts.map +1 -0
  126. package/dist/types/contexts/index.d.ts +1 -0
  127. package/dist/types/contexts/index.d.ts.map +1 -1
  128. package/package.json +15 -14
  129. package/src/components/SeedPhrase/SeedPhraseIconButton.tsx +50 -0
  130. package/src/components/SeedPhrase/dialog/SeedPhraseDialog.stories.tsx +35 -0
  131. package/src/components/SeedPhrase/dialog/SeedPhraseDialog.tsx +41 -0
  132. package/src/components/SeedPhrase/dialog/components/DialogActionButtons.tsx +29 -0
  133. package/src/components/SeedPhrase/dialog/components/OverwriteWarning.tsx +26 -0
  134. package/src/components/SeedPhrase/dialog/components/fields/NewPhraseTextField.tsx +37 -0
  135. package/src/components/SeedPhrase/dialog/components/fields/SavedPhraseTextField.tsx +34 -0
  136. package/src/components/SeedPhrase/dialog/components/fields/index.ts +2 -0
  137. package/src/components/SeedPhrase/dialog/components/fields/validation-messages/InvalidPhrase.tsx +10 -0
  138. package/src/components/SeedPhrase/dialog/components/fields/validation-messages/PhraseHeaderBox.tsx +40 -0
  139. package/src/components/SeedPhrase/dialog/components/fields/validation-messages/colorParser.ts +10 -0
  140. package/src/components/SeedPhrase/dialog/components/fields/validation-messages/index.ts +3 -0
  141. package/src/components/SeedPhrase/dialog/components/index.ts +3 -0
  142. package/src/components/SeedPhrase/dialog/index.ts +1 -0
  143. package/src/components/SeedPhrase/index.ts +2 -0
  144. package/src/components/index.ts +1 -0
  145. package/src/contexts/SeedPhrase/Context.ts +5 -0
  146. package/src/contexts/SeedPhrase/Provider.tsx +100 -0
  147. package/src/contexts/SeedPhrase/State.ts +18 -0
  148. package/src/contexts/SeedPhrase/index.ts +4 -0
  149. package/src/contexts/SeedPhrase/use.tsx +5 -0
  150. package/src/contexts/index.ts +1 -0
@@ -0,0 +1,2 @@
1
+ export declare const useSeedPhrase: () => Omit<import("./State").SeedPhraseContextState & import("@xyo-network/react-shared").ContextExState, "provided">;
2
+ //# sourceMappingURL=use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.d.ts","sourceRoot":"","sources":["../../../../src/contexts/SeedPhrase/use.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,aAAa,uHAA4D,CAAA"}
@@ -1,3 +1,4 @@
1
1
  export * from './Account';
2
+ export * from './SeedPhrase';
2
3
  export * from './Wallet';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/contexts/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/contexts/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA"}
package/package.json CHANGED
@@ -10,15 +10,16 @@
10
10
  "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/issues"
11
11
  },
12
12
  "dependencies": {
13
- "@xylabs/eth-address": "^2.6.16",
14
- "@xylabs/react-common": "^2.15.17",
15
- "@xylabs/react-crypto": "^2.15.17",
16
- "@xylabs/react-flexbox": "^2.15.17",
17
- "@xylabs/react-identicon": "^2.15.17",
18
- "@xylabs/react-number-status": "^2.15.17",
19
- "@xylabs/react-shared": "^2.15.17",
20
- "@xyo-network/react-network": "^2.41.46",
21
- "@xyo-network/react-shared": "^2.41.46"
13
+ "@scure/bip39": "^1.1.1",
14
+ "@xylabs/eth-address": "^2.7.1",
15
+ "@xylabs/react-common": "^2.16.3",
16
+ "@xylabs/react-crypto": "^2.16.3",
17
+ "@xylabs/react-flexbox": "^2.16.3",
18
+ "@xylabs/react-identicon": "^2.16.3",
19
+ "@xylabs/react-number-status": "^2.16.3",
20
+ "@xylabs/react-shared": "^2.16.3",
21
+ "@xyo-network/react-network": "^2.41.47",
22
+ "@xyo-network/react-shared": "^2.41.47"
22
23
  },
23
24
  "peerDependencies": {
24
25
  "@mui/icons-material": "^5",
@@ -32,10 +33,10 @@
32
33
  "description": "Common React library for all XYO projects that use React",
33
34
  "devDependencies": {
34
35
  "@storybook/react": "^6.5.16",
35
- "@xylabs/ts-scripts-yarn3": "^2.13.9",
36
- "@xylabs/tsconfig-react": "^2.13.9",
37
- "@xyo-network/account": "^2.43.27",
38
- "@xyo-network/wallet": "^2.43.27",
36
+ "@xylabs/ts-scripts-yarn3": "^2.14.0",
37
+ "@xylabs/tsconfig-react": "^2.14.0",
38
+ "@xyo-network/account": "^2.43.30",
39
+ "@xyo-network/wallet": "^2.43.30",
39
40
  "require-from-string": "^2.0.2",
40
41
  "typescript": "^4.9.5"
41
42
  },
@@ -81,5 +82,5 @@
81
82
  },
82
83
  "sideEffects": false,
83
84
  "types": "dist/types/index.d.ts",
84
- "version": "2.41.46"
85
+ "version": "2.41.47"
85
86
  }
@@ -0,0 +1,50 @@
1
+ import HelpOutlineIcon from '@mui/icons-material/HelpOutline'
2
+ import {
3
+ Button,
4
+ Dialog,
5
+ DialogActions,
6
+ DialogContent,
7
+ DialogTitle,
8
+ IconButton,
9
+ IconButtonProps,
10
+ Link,
11
+ List,
12
+ ListItem,
13
+ Typography,
14
+ } from '@mui/material'
15
+ import { useState } from 'react'
16
+
17
+ export const SeedPhraseIconButton: React.FC<IconButtonProps> = (props) => {
18
+ const [open, setOpen] = useState(false)
19
+ const onClose = () => setOpen(false)
20
+ return (
21
+ <>
22
+ <IconButton onClick={() => setOpen(true)} {...props}>
23
+ <HelpOutlineIcon fontSize="small" />
24
+ </IconButton>
25
+ <Dialog open={open}>
26
+ <DialogTitle>Understanding your Seed Phrase</DialogTitle>
27
+ <DialogContent>
28
+ <Typography>
29
+ Your Seed Phrase should adhere to the{' '}
30
+ <Link target={'_blank'} href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">
31
+ bip39 specification
32
+ </Link>{' '}
33
+ and is used to generate accounts which identify your data on the XYO Network.
34
+ </Typography>
35
+ <List>
36
+ <ListItem>Do not share this phrase with anyone.</ListItem>
37
+ <ListItem>Do not save it to a public computer.</ListItem>
38
+ <ListItem>Do not use a existing phrase from another wallet (i.e. Metamask).</ListItem>
39
+ <ListItem>Do not use before copying it down somewhere safe.</ListItem>
40
+ </List>
41
+ </DialogContent>
42
+ <DialogActions>
43
+ <Button onClick={onClose} variant="outlined">
44
+ OK
45
+ </Button>
46
+ </DialogActions>
47
+ </Dialog>
48
+ </>
49
+ )
50
+ }
@@ -0,0 +1,35 @@
1
+ import { Button, Typography } from '@mui/material'
2
+ import { generateMnemonic } from '@scure/bip39'
3
+ // eslint-disable-next-line import/no-internal-modules
4
+ import { wordlist } from '@scure/bip39/wordlists/english'
5
+ import { ComponentStory, Meta } from '@storybook/react'
6
+ import { FlexCol } from '@xylabs/react-flexbox'
7
+ import { useState } from 'react'
8
+
9
+ import { SeedPhraseDialog } from './SeedPhraseDialog'
10
+
11
+ // eslint-disable-next-line import/no-default-export
12
+ export default {
13
+ component: SeedPhraseDialog,
14
+ title: 'Wallet/SeedPhraseDialog',
15
+ } as Meta
16
+
17
+ const Template: ComponentStory<typeof SeedPhraseDialog> = (props) => {
18
+ const mnemonic = generateMnemonic(wordlist, 256)
19
+ const [seedPhrase, setSeedPhrase] = useState(mnemonic)
20
+ const [open, setOpen] = useState(false)
21
+ return (
22
+ <FlexCol rowGap={3}>
23
+ <Button variant={'contained'} onClick={() => setOpen(true)}>
24
+ Open Dialog
25
+ </Button>
26
+ <Typography>Seed Phrase</Typography>
27
+ <code>{seedPhrase}</code>
28
+ <SeedPhraseDialog seedPhrase={seedPhrase} changeSeedPhrase={setSeedPhrase} {...props} open={open} onClose={() => setOpen(false)} />
29
+ </FlexCol>
30
+ )
31
+ }
32
+
33
+ const Default = Template.bind({})
34
+
35
+ export { Default }
@@ -0,0 +1,41 @@
1
+ import { Dialog, DialogContent, DialogProps, DialogTitle } from '@mui/material'
2
+
3
+ import { SeedPhraseProvider, useSeedPhrase } from '../../../contexts'
4
+ import { SeedPhraseIconButton } from '../SeedPhraseIconButton'
5
+ import { DialogActionButtons, NewPhraseTextField, OverwriteWarning, SavedPhraseTextField } from './components'
6
+
7
+ export interface SeedPhraseDialogProps extends DialogProps {
8
+ changeSeedPhrase?: (value: string) => void
9
+ seedPhrase?: string
10
+ }
11
+
12
+ export const SeedPhraseDialog: React.FC<SeedPhraseDialogProps> = ({ changeSeedPhrase, seedPhrase, ...props }) => {
13
+ return (
14
+ <SeedPhraseProvider
15
+ seedPhrase={seedPhrase}
16
+ handleChangeSeedPhrase={changeSeedPhrase}
17
+ open={props.open}
18
+ saveCallback={() => props.onClose?.({}, 'escapeKeyDown')}
19
+ >
20
+ <SeedPhraseDialogInner {...props} />
21
+ </SeedPhraseProvider>
22
+ )
23
+ }
24
+
25
+ export const SeedPhraseDialogInner: React.FC<SeedPhraseDialogProps> = (props) => {
26
+ const { overwriteWarning, seedPhrase } = useSeedPhrase()
27
+
28
+ return (
29
+ <Dialog aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" fullWidth maxWidth={'sm'} {...props}>
30
+ <DialogTitle id="alert-dialog-title">
31
+ Update Your Seed Phrase <SeedPhraseIconButton />
32
+ </DialogTitle>
33
+ <DialogContent sx={{ display: 'flex', flexDirection: 'column', rowGap: 2 }}>
34
+ <NewPhraseTextField />
35
+ {seedPhrase ? <SavedPhraseTextField /> : null}
36
+ {overwriteWarning ? <OverwriteWarning /> : null}
37
+ </DialogContent>
38
+ <DialogActionButtons onClose={props.onClose} />
39
+ </Dialog>
40
+ )
41
+ }
@@ -0,0 +1,29 @@
1
+ import { Button, DialogActions, DialogActionsProps, DialogProps } from '@mui/material'
2
+ import { MouseEvent } from 'react'
3
+
4
+ import { useSeedPhrase } from '../../../../contexts'
5
+
6
+ interface DialogActionButtonsProps extends DialogActionsProps {
7
+ onClose?: DialogProps['onClose']
8
+ }
9
+
10
+ export const DialogActionButtons: React.FC<DialogActionButtonsProps> = ({ onClose, ...props }) => {
11
+ const { handleSave, setPhrase } = useSeedPhrase()
12
+
13
+ const wrappedOnClose = (e: MouseEvent<HTMLElement>) => {
14
+ // clear local copy of phrase when modal closes
15
+ setPhrase?.('')
16
+ onClose?.(e, 'escapeKeyDown')
17
+ }
18
+
19
+ return (
20
+ <DialogActions {...props}>
21
+ <Button variant="outlined" onClick={wrappedOnClose}>
22
+ Cancel
23
+ </Button>
24
+ <Button variant="outlined" onClick={handleSave}>
25
+ Save
26
+ </Button>
27
+ </DialogActions>
28
+ )
29
+ }
@@ -0,0 +1,26 @@
1
+ import { Alert, Button } from '@mui/material'
2
+ import { FlexRow } from '@xylabs/react-flexbox'
3
+
4
+ import { useSeedPhrase } from '../../../../contexts'
5
+
6
+ export const OverwriteWarning = () => {
7
+ const { handleCancelOverwrite, handleSave } = useSeedPhrase()
8
+ return (
9
+ <Alert
10
+ variant="outlined"
11
+ severity="warning"
12
+ action={
13
+ <FlexRow sx={{ columnGap: 1 }}>
14
+ <Button variant="outlined" color="inherit" size="small" onClick={handleSave}>
15
+ Overwrite
16
+ </Button>
17
+ <Button variant="outlined" color="inherit" size="small" onClick={handleCancelOverwrite}>
18
+ Cancel
19
+ </Button>
20
+ </FlexRow>
21
+ }
22
+ >
23
+ Are you sure you want to overwrite existing seed phrase? This action cannot be undone.
24
+ </Alert>
25
+ )
26
+ }
@@ -0,0 +1,37 @@
1
+ import { Button, DialogActions, FormControl, FormLabel, StandardTextFieldProps, TextField } from '@mui/material'
2
+
3
+ import { useSeedPhrase } from '../../../../../contexts'
4
+ import { colorParser, InvalidPhraseTypography, PhraseHeaderBox } from './validation-messages'
5
+
6
+ export const NewPhraseTextField: React.FC<StandardTextFieldProps> = (props) => {
7
+ const { handleClear, handleGenerate, overwriteWarning, phrase, setPhrase, validPhrase } = useSeedPhrase()
8
+ return (
9
+ <>
10
+ <FormControl fullWidth size="small" sx={{ display: 'flex', flexDirection: 'column', rowGap: 1 }}>
11
+ <FormLabel>
12
+ <PhraseHeaderBox conditional={validPhrase}>New Seed Phrase</PhraseHeaderBox>
13
+ </FormLabel>
14
+ <TextField
15
+ focused
16
+ color={colorParser(validPhrase)}
17
+ error={validPhrase === false}
18
+ helperText={validPhrase === false ? <InvalidPhraseTypography /> : null}
19
+ fullWidth
20
+ maxRows={Infinity}
21
+ multiline
22
+ onChange={(e) => setPhrase?.(e.target.value)}
23
+ value={phrase}
24
+ {...props}
25
+ />
26
+ </FormControl>
27
+ <DialogActions sx={{ justifyContent: 'center' }}>
28
+ <Button disabled={overwriteWarning} variant="outlined" onClick={handleGenerate}>
29
+ Generate
30
+ </Button>
31
+ <Button variant="outlined" onClick={handleClear}>
32
+ Clear
33
+ </Button>
34
+ </DialogActions>
35
+ </>
36
+ )
37
+ }
@@ -0,0 +1,34 @@
1
+ import { Chip, FormControl, FormLabel, StandardTextFieldProps, TextField } from '@mui/material'
2
+ import { useState } from 'react'
3
+
4
+ import { useSeedPhrase } from '../../../../../contexts'
5
+ import { InvalidPhraseTypography, PhraseHeaderBox } from './validation-messages'
6
+
7
+ export const SavedPhraseTextField: React.FC<StandardTextFieldProps> = (props) => {
8
+ const { validSeedPhrase, seedPhrase } = useSeedPhrase()
9
+
10
+ const [visible, setVisible] = useState(false)
11
+
12
+ return (
13
+ <FormControl fullWidth size="small" sx={{ display: 'flex', flexDirection: 'column', rowGap: 1 }}>
14
+ <Chip label={visible ? 'Hide Saved Seed Phrase' : 'Reveal Saved Seed Phrase'} onClick={() => setVisible(!visible)} />
15
+ {visible ? (
16
+ <>
17
+ <FormLabel>
18
+ <PhraseHeaderBox conditional={validSeedPhrase}>Saved Seed Phrase</PhraseHeaderBox>
19
+ </FormLabel>
20
+ <TextField
21
+ defaultValue={seedPhrase}
22
+ disabled
23
+ error={validSeedPhrase === false}
24
+ helperText={validSeedPhrase === false ? <InvalidPhraseTypography /> : null}
25
+ fullWidth
26
+ maxRows={Infinity}
27
+ multiline
28
+ {...props}
29
+ />
30
+ </>
31
+ ) : null}
32
+ </FormControl>
33
+ )
34
+ }
@@ -0,0 +1,2 @@
1
+ export * from './NewPhraseTextField'
2
+ export * from './SavedPhraseTextField'
@@ -0,0 +1,10 @@
1
+ import { Link, Typography, TypographyProps } from '@mui/material'
2
+
3
+ export const InvalidPhraseTypography: React.FC<TypographyProps> = (props) => (
4
+ <Typography variant={'caption'} color={'error'} {...props}>
5
+ Invalid seed phrase. See -{' '}
6
+ <Link target={'_blank'} href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">
7
+ bip39 Proposal
8
+ </Link>
9
+ </Typography>
10
+ )
@@ -0,0 +1,40 @@
1
+ import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'
2
+ import HighlightOffIcon from '@mui/icons-material/HighlightOff'
3
+ import { FlexBoxProps, FlexRow } from '@xylabs/react-flexbox'
4
+ import { WithChildren } from '@xylabs/react-shared'
5
+ import { useMemo } from 'react'
6
+
7
+ interface PhraseHeaderBox extends FlexBoxProps, WithChildren {
8
+ conditional?: boolean | null
9
+ }
10
+
11
+ export const PhraseHeaderBox: React.FC<PhraseHeaderBox> = ({ children, conditional, ...props }) => {
12
+ const state = useMemo(() => {
13
+ switch (conditional) {
14
+ case true:
15
+ return 'success'
16
+ case false:
17
+ return 'error'
18
+ default:
19
+ return null
20
+ }
21
+ }, [conditional])
22
+
23
+ const Icon = useMemo(() => {
24
+ switch (state) {
25
+ case 'success':
26
+ return <CheckCircleOutlineIcon fontSize="small" color="success" />
27
+ case 'error':
28
+ return <HighlightOffIcon fontSize="small" color="error" />
29
+ default:
30
+ return null
31
+ }
32
+ }, [state])
33
+
34
+ return (
35
+ <FlexRow justifyContent={'start'} columnGap={1} {...props}>
36
+ {Icon}
37
+ {children}
38
+ </FlexRow>
39
+ )
40
+ }
@@ -0,0 +1,10 @@
1
+ export const colorParser = (conditional?: boolean | null) => {
2
+ switch (conditional) {
3
+ case true:
4
+ return 'success'
5
+ case false:
6
+ return 'error'
7
+ default:
8
+ return undefined
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ export * from './colorParser'
2
+ export * from './InvalidPhrase'
3
+ export * from './PhraseHeaderBox'
@@ -0,0 +1,3 @@
1
+ export * from './DialogActionButtons'
2
+ export * from './fields'
3
+ export * from './OverwriteWarning'
@@ -0,0 +1 @@
1
+ export * from './SeedPhraseDialog'
@@ -0,0 +1,2 @@
1
+ export * from './dialog'
2
+ export * from './SeedPhraseIconButton'
@@ -1,2 +1,3 @@
1
+ export * from './SeedPhrase'
1
2
  export * from './WalletAccountDetails'
2
3
  export * from './WalletAccountSelect'
@@ -0,0 +1,5 @@
1
+ import { createContextEx } from '@xyo-network/react-shared'
2
+
3
+ import { SeedPhraseContextState } from './State'
4
+
5
+ export const SeedPhraseContext = createContextEx<SeedPhraseContextState>()
@@ -0,0 +1,100 @@
1
+ import { generateMnemonic, validateMnemonic } from '@scure/bip39'
2
+ // eslint-disable-next-line import/no-internal-modules
3
+ import { wordlist } from '@scure/bip39/wordlists/english'
4
+ import { WithChildren } from '@xylabs/react-shared'
5
+ import { useEffect, useMemo, useState } from 'react'
6
+
7
+ import { SeedPhraseContext } from './Context'
8
+
9
+ interface SeedPhraseProviderProps extends WithChildren {
10
+ defaultPhrase?: string
11
+ handleChangeSeedPhrase?: (phrase: string) => void
12
+ open?: boolean
13
+ saveCallback?: () => void
14
+ seedPhrase?: string
15
+ }
16
+
17
+ export const SeedPhraseProvider: React.FC<SeedPhraseProviderProps> = ({
18
+ children,
19
+ defaultPhrase,
20
+ handleChangeSeedPhrase,
21
+ saveCallback,
22
+ seedPhrase,
23
+ open,
24
+ }) => {
25
+ const [phrase, setPhrase] = useState<string | undefined>()
26
+ const [overwriteWarning, setOverwriteWarning] = useState(false)
27
+
28
+ useEffect(() => {
29
+ setPhrase(defaultPhrase)
30
+ }, [defaultPhrase])
31
+
32
+ useEffect(() => {
33
+ if (!open) {
34
+ handleCancelOverwrite()
35
+ }
36
+ }, [open])
37
+
38
+ useEffect(() => {
39
+ if (seedPhrase || open) {
40
+ setPhrase?.(seedPhrase ?? '')
41
+ }
42
+ }, [seedPhrase, open, setPhrase])
43
+
44
+ const handleGenerate = () => {
45
+ const mnemonic = generateMnemonic(wordlist, 256)
46
+ setPhrase?.(mnemonic)
47
+ setOverwriteWarning?.(false)
48
+ }
49
+
50
+ const handleCancelOverwrite = () => {
51
+ setOverwriteWarning?.(false)
52
+ }
53
+
54
+ const handleClear = () => {
55
+ setPhrase?.('')
56
+ setOverwriteWarning?.(false)
57
+ }
58
+
59
+ const handleSave = () => {
60
+ if (!overwriteWarning && seedPhrase && seedPhrase !== phrase) {
61
+ setOverwriteWarning?.(true)
62
+ } else {
63
+ handleChangeSeedPhrase?.(phrase ?? '')
64
+ saveCallback?.()
65
+ }
66
+ }
67
+
68
+ const validate = (passedPhrase?: string) => {
69
+ if (!passedPhrase) {
70
+ return null
71
+ }
72
+ return validateMnemonic(passedPhrase, wordlist)
73
+ }
74
+
75
+ const validSeedPhrase = useMemo(() => validate?.(seedPhrase), [seedPhrase])
76
+ const validPhrase = useMemo(() => validate?.(phrase), [phrase])
77
+
78
+ return (
79
+ <SeedPhraseContext.Provider
80
+ value={{
81
+ handleCancelOverwrite,
82
+ handleChangeSeedPhrase,
83
+ handleClear,
84
+ handleGenerate,
85
+ handleSave,
86
+ overwriteWarning,
87
+ phrase,
88
+ provided: true,
89
+ seedPhrase,
90
+ setOverwriteWarning,
91
+ setPhrase,
92
+ validPhrase,
93
+ validSeedPhrase,
94
+ validate,
95
+ }}
96
+ >
97
+ {children}
98
+ </SeedPhraseContext.Provider>
99
+ )
100
+ }
@@ -0,0 +1,18 @@
1
+ import { ContextExState } from '@xyo-network/react-shared'
2
+ import { Dispatch, SetStateAction } from 'react'
3
+
4
+ export interface SeedPhraseContextState extends ContextExState {
5
+ handleCancelOverwrite?: () => void
6
+ handleChangeSeedPhrase?: (value: string) => void
7
+ handleClear?: () => void
8
+ handleGenerate?: () => void
9
+ handleSave?: () => void
10
+ overwriteWarning?: boolean
11
+ phrase?: string
12
+ seedPhrase?: string
13
+ setOverwriteWarning?: Dispatch<SetStateAction<boolean>>
14
+ setPhrase?: Dispatch<SetStateAction<string | undefined>>
15
+ validPhrase?: boolean | null
16
+ validSeedPhrase?: boolean | null
17
+ validate?: (passedPhrase?: string) => boolean | null
18
+ }
@@ -0,0 +1,4 @@
1
+ export * from './Context'
2
+ export * from './Provider'
3
+ export * from './State'
4
+ export * from './use'
@@ -0,0 +1,5 @@
1
+ import { useContextEx } from '@xyo-network/react-shared'
2
+
3
+ import { SeedPhraseContext } from './Context'
4
+
5
+ export const useSeedPhrase = () => useContextEx(SeedPhraseContext, 'SeedPhrase', true)
@@ -1,2 +1,3 @@
1
1
  export * from './Account'
2
+ export * from './SeedPhrase'
2
3
  export * from './Wallet'