@nockchain/rose 0.1.4-nightly.5

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 (205) hide show
  1. package/.github/workflows/artifacts.yml +33 -0
  2. package/.github/workflows/ci.yml +68 -0
  3. package/.github/workflows/publish-sdk.yml +35 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierignore +5 -0
  6. package/.prettierrc +8 -0
  7. package/LICENSE +22 -0
  8. package/README.md +117 -0
  9. package/extension/background/index.ts +1500 -0
  10. package/extension/content/index.ts +59 -0
  11. package/extension/icons/rose.svg +27 -0
  12. package/extension/icons/rose128.png +0 -0
  13. package/extension/icons/rose16.png +0 -0
  14. package/extension/icons/rose256.png +0 -0
  15. package/extension/icons/rose32.png +0 -0
  16. package/extension/icons/rose48.png +0 -0
  17. package/extension/icons/rose512.png +0 -0
  18. package/extension/inpage/index.ts +86 -0
  19. package/extension/manifest.json +48 -0
  20. package/extension/popup/Popup.tsx +94 -0
  21. package/extension/popup/Router.tsx +121 -0
  22. package/extension/popup/assets/arrow-down-icon.svg +3 -0
  23. package/extension/popup/assets/arrow-left-icon.svg +3 -0
  24. package/extension/popup/assets/arrow-right-icon.svg +3 -0
  25. package/extension/popup/assets/arrow-up-icon.svg +3 -0
  26. package/extension/popup/assets/arrow-up-right-icon.svg +3 -0
  27. package/extension/popup/assets/checkmark-icon.svg +3 -0
  28. package/extension/popup/assets/checkmark-pencil-icon.svg +3 -0
  29. package/extension/popup/assets/checkmark-success-icon.svg +3 -0
  30. package/extension/popup/assets/clock-icon.svg +3 -0
  31. package/extension/popup/assets/close-x-icon.svg +3 -0
  32. package/extension/popup/assets/copy-icon.svg +6 -0
  33. package/extension/popup/assets/explorer-icon.svg +3 -0
  34. package/extension/popup/assets/eye-off-icon.svg +3 -0
  35. package/extension/popup/assets/eye-open-icon.svg +4 -0
  36. package/extension/popup/assets/feedback-icon.svg +3 -0
  37. package/extension/popup/assets/green-status-dot.svg +3 -0
  38. package/extension/popup/assets/info-icon.svg +3 -0
  39. package/extension/popup/assets/iris-logo-40.svg +27 -0
  40. package/extension/popup/assets/iris-logo-96.svg +27 -0
  41. package/extension/popup/assets/iris-logo-blue.svg +27 -0
  42. package/extension/popup/assets/iris-logo-no-eye.svg +27 -0
  43. package/extension/popup/assets/iris-logo-orange.svg +27 -0
  44. package/extension/popup/assets/iris-logo.svg +27 -0
  45. package/extension/popup/assets/key-icon.svg +3 -0
  46. package/extension/popup/assets/lock-icon-yellow.svg +3 -0
  47. package/extension/popup/assets/lock-icon.svg +3 -0
  48. package/extension/popup/assets/pencil-edit-icon.svg +3 -0
  49. package/extension/popup/assets/permissions-icon.svg +3 -0
  50. package/extension/popup/assets/receipt-icon.svg +5 -0
  51. package/extension/popup/assets/refresh-icon.svg +3 -0
  52. package/extension/popup/assets/settings-gear-icon.svg +8 -0
  53. package/extension/popup/assets/settings-icon.svg +3 -0
  54. package/extension/popup/assets/theme-icon.svg +3 -0
  55. package/extension/popup/assets/trash-bin-icon.svg +3 -0
  56. package/extension/popup/assets/trend-down-arrow.svg +5 -0
  57. package/extension/popup/assets/trend-up-arrow.svg +5 -0
  58. package/extension/popup/assets/user-account-icon.svg +3 -0
  59. package/extension/popup/assets/vector-bottom-left.svg +9 -0
  60. package/extension/popup/assets/vector-left.svg +9 -0
  61. package/extension/popup/assets/vector-right.svg +9 -0
  62. package/extension/popup/assets/vector-top-right-rotated.svg +8 -0
  63. package/extension/popup/assets/vector-top-right.svg +9 -0
  64. package/extension/popup/assets/wallet-dropdown-arrow.svg +5 -0
  65. package/extension/popup/assets/wallet-icon-style-1.svg +6 -0
  66. package/extension/popup/assets/wallet-icon-style-10.svg +8 -0
  67. package/extension/popup/assets/wallet-icon-style-11.svg +8 -0
  68. package/extension/popup/assets/wallet-icon-style-12.svg +8 -0
  69. package/extension/popup/assets/wallet-icon-style-13.svg +8 -0
  70. package/extension/popup/assets/wallet-icon-style-14.svg +8 -0
  71. package/extension/popup/assets/wallet-icon-style-15.svg +8 -0
  72. package/extension/popup/assets/wallet-icon-style-2.svg +8 -0
  73. package/extension/popup/assets/wallet-icon-style-3.svg +8 -0
  74. package/extension/popup/assets/wallet-icon-style-4.svg +8 -0
  75. package/extension/popup/assets/wallet-icon-style-5.svg +8 -0
  76. package/extension/popup/assets/wallet-icon-style-6.svg +8 -0
  77. package/extension/popup/assets/wallet-icon-style-7.svg +8 -0
  78. package/extension/popup/assets/wallet-icon-style-8.svg +8 -0
  79. package/extension/popup/assets/wallet-icon-style-9.svg +8 -0
  80. package/extension/popup/components/AccountIcon.tsx +78 -0
  81. package/extension/popup/components/AccountSelector.tsx +246 -0
  82. package/extension/popup/components/Alert.tsx +48 -0
  83. package/extension/popup/components/ConfirmModal.tsx +81 -0
  84. package/extension/popup/components/PasswordInput.tsx +49 -0
  85. package/extension/popup/components/ScreenContainer.tsx +17 -0
  86. package/extension/popup/components/SiteIcon.tsx +60 -0
  87. package/extension/popup/components/ThemeToggle.tsx +44 -0
  88. package/extension/popup/components/icons/ArrowDownLeftIcon.tsx +20 -0
  89. package/extension/popup/components/icons/ArrowUpRightIcon.tsx +20 -0
  90. package/extension/popup/components/icons/CheckIcon.tsx +20 -0
  91. package/extension/popup/components/icons/ChevronDownIcon.tsx +15 -0
  92. package/extension/popup/components/icons/ChevronLeftIcon.tsx +15 -0
  93. package/extension/popup/components/icons/ChevronRightIcon.tsx +15 -0
  94. package/extension/popup/components/icons/ChevronUpIcon.tsx +15 -0
  95. package/extension/popup/components/icons/CloseIcon.tsx +26 -0
  96. package/extension/popup/components/icons/CopyIcon.tsx +20 -0
  97. package/extension/popup/components/icons/EditIcon.tsx +20 -0
  98. package/extension/popup/components/icons/EyeIcon.tsx +13 -0
  99. package/extension/popup/components/icons/EyeOffIcon.tsx +13 -0
  100. package/extension/popup/components/icons/InfoIcon.tsx +20 -0
  101. package/extension/popup/components/icons/LockIcon.tsx +20 -0
  102. package/extension/popup/components/icons/PlusIcon.tsx +15 -0
  103. package/extension/popup/components/icons/ReceiveArrowIcon.tsx +14 -0
  104. package/extension/popup/components/icons/ReceiveCircleIcon.tsx +20 -0
  105. package/extension/popup/components/icons/SendPaperPlaneIcon.tsx +18 -0
  106. package/extension/popup/components/icons/SentArrowIcon.tsx +21 -0
  107. package/extension/popup/components/icons/SettingsIcon.tsx +26 -0
  108. package/extension/popup/components/icons/ShieldIcon.tsx +20 -0
  109. package/extension/popup/components/icons/UploadIcon.tsx +20 -0
  110. package/extension/popup/components/icons/WalletIcon.tsx +20 -0
  111. package/extension/popup/contexts/ThemeContext.tsx +105 -0
  112. package/extension/popup/hooks/useApprovalDetection.ts +128 -0
  113. package/extension/popup/hooks/useAutoFocus.ts +36 -0
  114. package/extension/popup/hooks/useAutoRejectOnClose.ts +25 -0
  115. package/extension/popup/hooks/useClickOutside.ts +33 -0
  116. package/extension/popup/hooks/useCopyToClipboard.ts +33 -0
  117. package/extension/popup/hooks/useFavicon.ts +64 -0
  118. package/extension/popup/hooks/useNumericInput.ts +93 -0
  119. package/extension/popup/index.html +13 -0
  120. package/extension/popup/index.tsx +24 -0
  121. package/extension/popup/screens/AboutScreen.tsx +118 -0
  122. package/extension/popup/screens/HomeScreen.tailwind.css +85 -0
  123. package/extension/popup/screens/HomeScreen.tsx +902 -0
  124. package/extension/popup/screens/KeySettingsPasswordScreen.tsx +164 -0
  125. package/extension/popup/screens/LockTimeScreen.tsx +155 -0
  126. package/extension/popup/screens/ReceiveScreen.tsx +149 -0
  127. package/extension/popup/screens/RecoveryPhraseScreen.tsx +183 -0
  128. package/extension/popup/screens/SendReviewScreen.tsx +308 -0
  129. package/extension/popup/screens/SendScreen.tsx +825 -0
  130. package/extension/popup/screens/SendSubmittedScreen.tsx +193 -0
  131. package/extension/popup/screens/SettingsScreen.tsx +116 -0
  132. package/extension/popup/screens/ThemeSettingsScreen.tsx +107 -0
  133. package/extension/popup/screens/TransactionDetailsScreen.tsx +346 -0
  134. package/extension/popup/screens/ViewSecretPhraseScreen.tsx +212 -0
  135. package/extension/popup/screens/WalletPermissionsScreen.tsx +123 -0
  136. package/extension/popup/screens/WalletSettingsScreen.tsx +381 -0
  137. package/extension/popup/screens/WalletStylingScreen.tsx +306 -0
  138. package/extension/popup/screens/approvals/ConnectApprovalScreen.tsx +136 -0
  139. package/extension/popup/screens/approvals/SignMessageScreen.tsx +140 -0
  140. package/extension/popup/screens/approvals/SignRawTxScreen.tsx +320 -0
  141. package/extension/popup/screens/approvals/TransactionApprovalScreen.tsx +167 -0
  142. package/extension/popup/screens/onboarding/BackupScreen.tsx +254 -0
  143. package/extension/popup/screens/onboarding/CreateScreen.tsx +273 -0
  144. package/extension/popup/screens/onboarding/ImportScreen.tsx +676 -0
  145. package/extension/popup/screens/onboarding/ImportScreenV0.tsx +678 -0
  146. package/extension/popup/screens/onboarding/ImportSuccessScreen.tsx +236 -0
  147. package/extension/popup/screens/onboarding/ResumeBackupScreen.tsx +166 -0
  148. package/extension/popup/screens/onboarding/StartScreen.tsx +142 -0
  149. package/extension/popup/screens/onboarding/SuccessScreen.tsx +193 -0
  150. package/extension/popup/screens/onboarding/VerifyScreen.tsx +220 -0
  151. package/extension/popup/screens/system/LockedScreen.tsx +288 -0
  152. package/extension/popup/screens/transactions/ReceiveScreen.tsx +84 -0
  153. package/extension/popup/screens/transactions/SentScreen.tsx +138 -0
  154. package/extension/popup/store.ts +482 -0
  155. package/extension/popup/styles.css +246 -0
  156. package/extension/popup/utils/format.ts +58 -0
  157. package/extension/popup/utils/formatWalletError.ts +36 -0
  158. package/extension/popup/utils/memo.ts +299 -0
  159. package/extension/popup/utils/messaging.ts +16 -0
  160. package/extension/shared/address-encoding.ts +69 -0
  161. package/extension/shared/balance-query.ts +123 -0
  162. package/extension/shared/constants.ts +386 -0
  163. package/extension/shared/currency.ts +128 -0
  164. package/extension/shared/first-name-derivation.ts +128 -0
  165. package/extension/shared/keyfile.ts +58 -0
  166. package/extension/shared/onboarding.ts +78 -0
  167. package/extension/shared/price-api.ts +79 -0
  168. package/extension/shared/rpc-client-browser.ts +315 -0
  169. package/extension/shared/transaction-builder.ts +443 -0
  170. package/extension/shared/types.ts +450 -0
  171. package/extension/shared/utxo-diff.ts +212 -0
  172. package/extension/shared/utxo-store.ts +548 -0
  173. package/extension/shared/utxo-sync.ts +343 -0
  174. package/extension/shared/validators.ts +26 -0
  175. package/extension/shared/vault.ts +1580 -0
  176. package/extension/shared/wallet-crypto.ts +77 -0
  177. package/extension/shared/wasm-utils.ts +76 -0
  178. package/extension/shared/webcrypto.ts +67 -0
  179. package/extension/types/wasm.d.ts +13 -0
  180. package/package.json +39 -0
  181. package/postcss.config.js +6 -0
  182. package/rose-extension-dist.zip +0 -0
  183. package/sdk/README.md +88 -0
  184. package/sdk/examples/app.ts +166 -0
  185. package/sdk/examples/index.html +51 -0
  186. package/sdk/examples/tsconfig.json +15 -0
  187. package/sdk/examples/tx-builder.html +532 -0
  188. package/sdk/examples/tx-builder.ts +1766 -0
  189. package/sdk/package-lock.json +424 -0
  190. package/sdk/package.json +68 -0
  191. package/sdk/src/constants.ts +28 -0
  192. package/sdk/src/errors.ts +74 -0
  193. package/sdk/src/hooks/index.ts +1 -0
  194. package/sdk/src/hooks/use-rose.ts +94 -0
  195. package/sdk/src/index.ts +12 -0
  196. package/sdk/src/provider.ts +396 -0
  197. package/sdk/src/transaction.ts +163 -0
  198. package/sdk/src/types/rose-wasm.d.ts +14 -0
  199. package/sdk/src/types.ts +97 -0
  200. package/sdk/src/wasm.ts +13 -0
  201. package/sdk/tsconfig.json +20 -0
  202. package/sdk/vite.config.examples.ts +32 -0
  203. package/tailwind.config.ts +38 -0
  204. package/tsconfig.json +20 -0
  205. package/vite.config.ts +60 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Import Success Screen - Wallet imported successfully
3
+ */
4
+
5
+ import { useStore } from '../../store';
6
+ import { useCopyToClipboard } from '../../hooks/useCopyToClipboard';
7
+ import checkmarkSuccessIcon from '../../assets/checkmark-success-icon.svg';
8
+ import { InfoIcon } from '../../components/icons/InfoIcon';
9
+ import { send } from '../../utils/messaging';
10
+ import { useState, useEffect } from 'react';
11
+ import { INTERNAL_METHODS } from '../../../shared/constants';
12
+
13
+ export function ImportSuccessScreen() {
14
+ const { navigate, wallet, goBack, fetchBalance } = useStore();
15
+ const { copied, copyToClipboard } = useCopyToClipboard();
16
+ const [isV0, setIsV0] = useState(false);
17
+ useEffect(() => {
18
+ (async () => {
19
+ const res = await send<{ ok?: boolean; has?: boolean; error?: unknown }>(
20
+ INTERNAL_METHODS.HAS_V0_MNEMONIC,
21
+ []
22
+ );
23
+ if (res?.ok) {
24
+ setIsV0(Boolean(res.has));
25
+ }
26
+ })();
27
+ }, []);
28
+ // Format address to show start and end with middle grayed out
29
+ function formatAddress(address: string) {
30
+ if (!address || address.length < 20) return address;
31
+ const start = address.slice(0, 6);
32
+ const middle = address.slice(6, -5);
33
+ const end = address.slice(-5);
34
+ return { start, middle, end };
35
+ }
36
+
37
+ const formattedAddress = formatAddress(wallet.address || '');
38
+
39
+ function handleStartUsing() {
40
+ // Start fetching balance in background (non-blocking)
41
+ fetchBalance();
42
+ // Navigate immediately - HomeScreen will show loading state
43
+ navigate('home');
44
+ }
45
+
46
+ return (
47
+ <div className="relative w-[357px] h-[600px] bg-[var(--color-bg)]">
48
+ {/* Header with back button */}
49
+ <div className="flex items-center justify-between h-16 px-4 py-3 border-b border-[var(--color-divider)]">
50
+ <button
51
+ onClick={goBack}
52
+ className="p-2 -ml-2 hover:opacity-70 transition-opacity"
53
+ aria-label="Go back"
54
+ >
55
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
56
+ <path
57
+ d="M10 12L6 8L10 4"
58
+ stroke="var(--color-text-primary)"
59
+ strokeWidth="2"
60
+ strokeLinecap="round"
61
+ strokeLinejoin="round"
62
+ />
63
+ </svg>
64
+ </button>
65
+ <h2
66
+ className="font-sans font-medium text-[var(--color-text-primary)]"
67
+ style={{
68
+ fontSize: 'var(--font-size-lg)',
69
+ lineHeight: 'var(--line-height-normal)',
70
+ letterSpacing: '0.01em',
71
+ }}
72
+ >
73
+ Wallet imported
74
+ </h2>
75
+ <div className="w-8" /> {/* Spacer for centering */}
76
+ </div>
77
+
78
+ {/* Main content */}
79
+ <div className="flex flex-col justify-between h-[536px]">
80
+ <div className="px-4 py-2 flex flex-col gap-8">
81
+ {/* Icon and heading */}
82
+ <div className="flex flex-col items-center gap-3">
83
+ <div className="w-10 h-10">
84
+ <img src={checkmarkSuccessIcon} alt="" className="w-full h-full" />
85
+ </div>
86
+ <div className="flex flex-col gap-2 items-center text-center w-full">
87
+ <h1
88
+ className="font-serif font-medium text-[var(--color-text-primary)]"
89
+ style={{
90
+ fontSize: 'var(--font-size-xl)',
91
+ lineHeight: 'var(--line-height-relaxed)',
92
+ letterSpacing: '-0.02em',
93
+ }}
94
+ >
95
+ {isV0 ? 'Wallet (v0) imported successfully!' : 'Wallet imported successfully!'}
96
+ </h1>
97
+ <p
98
+ className="font-sans text-[var(--color-text-muted)]"
99
+ style={{
100
+ fontSize: 'var(--font-size-sm)',
101
+ lineHeight: 'var(--line-height-snug)',
102
+ letterSpacing: '0.02em',
103
+ }}
104
+ >
105
+ {isV0
106
+ ? 'A new v1 wallet has been created for you. You can use the upgrade tool to move your v0 notes.'
107
+ : 'Your wallet is ready to use'}
108
+ </p>
109
+ </div>
110
+ </div>
111
+
112
+ {/* Address section */}
113
+ <div className="flex flex-col gap-1.5 w-full">
114
+ <p
115
+ className="font-sans font-medium text-center text-[var(--color-text-primary)]"
116
+ style={{
117
+ fontSize: 'var(--font-size-sm)',
118
+ lineHeight: 'var(--line-height-snug)',
119
+ letterSpacing: '0.02em',
120
+ }}
121
+ >
122
+ {isV0 ? 'Your NEW v1 address' : 'Your address'}
123
+ </p>
124
+ <div className="bg-[var(--color-surface-900)] rounded-lg p-3 flex flex-col gap-5 items-center">
125
+ {/* Address display */}
126
+ <p
127
+ className="font-sans font-medium text-center text-[var(--color-text-primary)] break-words w-full"
128
+ style={{
129
+ fontSize: 'var(--font-size-base)',
130
+ lineHeight: 'var(--line-height-snug)',
131
+ letterSpacing: '0.01em',
132
+ }}
133
+ >
134
+ {typeof formattedAddress === 'string' ? (
135
+ formattedAddress
136
+ ) : (
137
+ <>
138
+ {formattedAddress.start}
139
+ <span className="text-[var(--color-text-muted)]">
140
+ {formattedAddress.middle}
141
+ </span>
142
+ {formattedAddress.end}
143
+ </>
144
+ )}
145
+ </p>
146
+
147
+ {/* Copy button */}
148
+ <button
149
+ onClick={() => copyToClipboard(wallet.address || '')}
150
+ className="border border-[var(--color-text-primary)] rounded-full px-4 py-1.5 flex items-center gap-1.5 hover:opacity-80 transition-opacity"
151
+ >
152
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
153
+ <path
154
+ d="M4 4V2.66667C4 2.29848 4.29848 2 4.66667 2H13.3333C13.7015 2 14 2.29848 14 2.66667V11.3333C14 11.7015 13.7015 12 13.3333 12H12"
155
+ stroke="var(--color-text-primary)"
156
+ strokeWidth="1.5"
157
+ strokeLinecap="round"
158
+ />
159
+ <rect
160
+ x="2"
161
+ y="4"
162
+ width="10"
163
+ height="10"
164
+ rx="0.666667"
165
+ stroke="var(--color-text-primary)"
166
+ strokeWidth="1.5"
167
+ />
168
+ </svg>
169
+ <span
170
+ className="font-sans font-medium text-[var(--color-text-primary)]"
171
+ style={{
172
+ fontSize: 'var(--font-size-base)',
173
+ lineHeight: 'var(--line-height-snug)',
174
+ letterSpacing: '0.01em',
175
+ }}
176
+ >
177
+ {copied ? 'Copied!' : 'Copy address'}
178
+ </span>
179
+ </button>
180
+
181
+ {isV0 && (
182
+ <div
183
+ className="flex items-start gap-2 p-3 rounded-lg"
184
+ style={{
185
+ backgroundColor: 'var(--color-surface-800)',
186
+ border: '1px solid var(--color-surface-700)',
187
+ }}
188
+ >
189
+ <InfoIcon className="w-5 h-5 flex-shrink-0 mt-0.5 m-auto" />
190
+ <div className="flex-1">
191
+ <p
192
+ className="font-sans text-center text-[var(--color-text-muted)]"
193
+ style={{
194
+ fontSize: 'var(--font-size-sm)',
195
+ lineHeight: 'var(--line-height-snug)',
196
+ letterSpacing: '0.01em',
197
+ }}
198
+ >
199
+ Hint: Use the upgrade tool to move your v0 notes.
200
+ <br />
201
+ <a
202
+ href="https://nocknames.com/upgrade"
203
+ target="_blank"
204
+ rel="noopener noreferrer"
205
+ className="underline hover:opacity-70 text-[#37f] font-bold"
206
+ >
207
+ nocknames.com/upgrade
208
+ </a>
209
+ </p>
210
+ </div>
211
+ </div>
212
+ )}
213
+ </div>
214
+ </div>
215
+ </div>
216
+
217
+ {/* Bottom button */}
218
+ <div className="border-t border-[var(--color-surface-800)] p-3">
219
+ <button
220
+ onClick={handleStartUsing}
221
+ className="w-full h-12 px-5 py-[15px] btn-primary text-[#000000] rounded-lg flex items-center justify-center transition-opacity hover:opacity-90"
222
+ style={{
223
+ fontFamily: 'var(--font-sans)',
224
+ fontSize: 'var(--font-size-base)',
225
+ fontWeight: 500,
226
+ lineHeight: 'var(--line-height-snug)',
227
+ letterSpacing: '0.01em',
228
+ }}
229
+ >
230
+ Start using wallet
231
+ </button>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ );
236
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Resume Backup Screen
3
+ * Shown when user closed popup during onboarding and needs to complete backup
4
+ */
5
+
6
+ import { useState } from 'react';
7
+ import { useStore } from '../../store';
8
+ import { send } from '../../utils/messaging';
9
+ import { INTERNAL_METHODS } from '../../../shared/constants';
10
+ import { formatWalletError } from '../../utils/formatWalletError';
11
+ import { ScreenContainer } from '../../components/ScreenContainer';
12
+ import { Alert } from '../../components/Alert';
13
+ import { PasswordInput } from '../../components/PasswordInput';
14
+
15
+ export function ResumeBackupScreen() {
16
+ const [password, setPassword] = useState('');
17
+ const [error, setError] = useState('');
18
+ const { navigate, setOnboardingMnemonic } = useStore();
19
+
20
+ async function handleContinue() {
21
+ setError('');
22
+
23
+ if (!password) {
24
+ setError('Please enter your password');
25
+ return;
26
+ }
27
+
28
+ // Retrieve mnemonic using password
29
+ const result = await send<{
30
+ ok?: boolean;
31
+ mnemonic?: string;
32
+ error?: string;
33
+ }>(INTERNAL_METHODS.GET_MNEMONIC, [password]);
34
+
35
+ if (result?.error) {
36
+ setError(formatWalletError(result.error));
37
+ setPassword(''); // Clear password on error
38
+ } else {
39
+ // Store mnemonic in Zustand for backup flow
40
+ setOnboardingMnemonic(result.mnemonic || '');
41
+ setPassword('');
42
+ // Navigate to backup screen
43
+ navigate('onboarding-backup');
44
+ }
45
+ }
46
+
47
+ return (
48
+ <div className="relative w-[357px] h-[600px]" style={{ backgroundColor: 'var(--color-bg)' }}>
49
+ {/* Header */}
50
+ <div
51
+ className="flex items-center justify-between h-16 px-4 py-3"
52
+ style={{ borderBottom: '1px solid var(--color-divider)' }}
53
+ >
54
+ <button
55
+ onClick={() => navigate('onboarding-start')}
56
+ className="p-2 -ml-2 hover:opacity-70 transition-opacity"
57
+ aria-label="Go back"
58
+ >
59
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
60
+ <path
61
+ d="M10 12L6 8L10 4"
62
+ stroke="var(--color-text-primary)"
63
+ strokeWidth="2"
64
+ strokeLinecap="round"
65
+ strokeLinejoin="round"
66
+ />
67
+ </svg>
68
+ </button>
69
+ <h2
70
+ className="font-sans font-medium"
71
+ style={{
72
+ fontSize: 'var(--font-size-lg)',
73
+ lineHeight: 'var(--line-height-normal)',
74
+ letterSpacing: '0.01em',
75
+ color: 'var(--color-text-primary)',
76
+ }}
77
+ >
78
+ Complete Backup
79
+ </h2>
80
+ <div className="w-8" />
81
+ </div>
82
+
83
+ {/* Main content */}
84
+ <div className="flex flex-col justify-between h-[536px]">
85
+ <div className="px-4 py-2 flex flex-col gap-6">
86
+ <h1
87
+ className="font-serif font-medium text-center"
88
+ style={{
89
+ fontSize: 'var(--font-size-xl)',
90
+ lineHeight: 'var(--line-height-relaxed)',
91
+ letterSpacing: '-0.02em',
92
+ color: 'var(--color-text-primary)',
93
+ }}
94
+ >
95
+ Complete Your Backup
96
+ </h1>
97
+
98
+ <p
99
+ className="font-sans text-center"
100
+ style={{
101
+ fontSize: 'var(--font-size-sm)',
102
+ lineHeight: 'var(--line-height-snug)',
103
+ letterSpacing: '0.02em',
104
+ color: 'var(--color-text-muted)',
105
+ }}
106
+ >
107
+ You need to backup your secret phrase to secure your wallet. Enter your password to
108
+ continue.
109
+ </p>
110
+
111
+ <div className="rounded-lg p-3" style={{ backgroundColor: 'var(--color-red-light)' }}>
112
+ <p
113
+ className="font-sans font-medium text-center"
114
+ style={{
115
+ fontSize: 'var(--font-size-xs)',
116
+ lineHeight: 'var(--line-height-tight)',
117
+ letterSpacing: '0.02em',
118
+ color: 'var(--color-red)',
119
+ }}
120
+ >
121
+ <strong>Important:</strong> Without backing up your secret phrase, you risk losing
122
+ access to your wallet if you forget your password.
123
+ </p>
124
+ </div>
125
+
126
+ <PasswordInput
127
+ value={password}
128
+ onChange={value => {
129
+ setPassword(value);
130
+ setError('');
131
+ }}
132
+ placeholder="Password"
133
+ className="my-2"
134
+ onKeyDown={e => e.key === 'Enter' && handleContinue()}
135
+ autoFocus
136
+ />
137
+
138
+ {error && (
139
+ <Alert type="error" className="my-2">
140
+ {error}
141
+ </Alert>
142
+ )}
143
+ </div>
144
+
145
+ {/* Bottom button */}
146
+ <div className="px-4 py-3" style={{ borderTop: '1px solid var(--color-surface-800)' }}>
147
+ <button
148
+ onClick={handleContinue}
149
+ className="w-full h-12 px-5 py-[15px] rounded-lg flex items-center justify-center transition-opacity hover:opacity-90"
150
+ style={{
151
+ backgroundColor: 'var(--color-primary)',
152
+ color: '#000000',
153
+ fontFamily: 'var(--font-sans)',
154
+ fontSize: 'var(--font-size-base)',
155
+ fontWeight: 500,
156
+ lineHeight: 'var(--line-height-snug)',
157
+ letterSpacing: '0.01em',
158
+ }}
159
+ >
160
+ Continue Backup
161
+ </button>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ );
166
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Onboarding Start Screen - Create new or import wallet
3
+ */
4
+
5
+ import { useStore } from '../../store';
6
+ import vectorLeft from '../../assets/vector-left.svg';
7
+ import vectorRight from '../../assets/vector-right.svg';
8
+ import vectorTopRight from '../../assets/vector-top-right.svg';
9
+ import vectorTopRightRotated from '../../assets/vector-top-right-rotated.svg';
10
+ import vectorBottomLeft from '../../assets/vector-bottom-left.svg';
11
+ import RoseLogo from '../../../icons/rose.svg';
12
+
13
+ export function StartScreen() {
14
+ const { navigate } = useStore();
15
+
16
+ return (
17
+ <div className="relative w-[357px] h-[600px] bg-[var(--color-bg)] overflow-hidden">
18
+ {/* Decorative vector elements */}
19
+ <img
20
+ src={vectorLeft}
21
+ alt=""
22
+ className="absolute left-[-11px] top-[199px] w-[89px] h-[70px]"
23
+ aria-hidden="true"
24
+ />
25
+ <img
26
+ src={vectorRight}
27
+ alt=""
28
+ className="absolute left-[305px] top-[311px] w-[52px] h-[83px]"
29
+ aria-hidden="true"
30
+ />
31
+ <img
32
+ src={vectorTopRight}
33
+ alt=""
34
+ className="absolute left-[296px] top-[122px] w-[80px] h-[45px]"
35
+ aria-hidden="true"
36
+ />
37
+ <div
38
+ className="absolute"
39
+ style={{
40
+ left: 'calc(50% + 37px)',
41
+ top: 'calc(50% - 283px)',
42
+ transform: 'rotate(24.652deg)',
43
+ transformOrigin: 'center',
44
+ }}
45
+ aria-hidden="true"
46
+ >
47
+ <img src={vectorTopRightRotated} alt="" className="w-[63px] h-[67px]" />
48
+ </div>
49
+ <img
50
+ src={vectorBottomLeft}
51
+ alt=""
52
+ className="absolute left-[-23px] top-[362px] w-[64px] h-[64px]"
53
+ aria-hidden="true"
54
+ />
55
+
56
+ {/* Main content */}
57
+ <div className="flex flex-col items-center justify-between h-[600px] px-4 pt-[104px] pb-3">
58
+ {/* Top section: Logo and text */}
59
+ <div className="flex flex-col items-center gap-8 w-full">
60
+ {/* Logo */}
61
+ <img src={RoseLogo} alt="Rose Wallet" className="w-[104px] h-[104px]" />
62
+
63
+ {/* Text content */}
64
+ <div className="flex flex-col gap-2 items-center text-center w-full">
65
+ <h1
66
+ className="font-serif font-medium text-[var(--color-text-primary)]"
67
+ style={{
68
+ fontSize: 'var(--font-size-xl)',
69
+ lineHeight: 'var(--line-height-relaxed)',
70
+ letterSpacing: '-0.02em',
71
+ }}
72
+ >
73
+ Welcome to Rose
74
+ </h1>
75
+ <p
76
+ className="font-sans text-[var(--color-text-muted)]"
77
+ style={{
78
+ fontSize: 'var(--font-size-sm)',
79
+ lineHeight: 'var(--line-height-snug)',
80
+ letterSpacing: '0.02em',
81
+ }}
82
+ >
83
+ Your Nockchain companion
84
+ </p>
85
+ </div>
86
+ </div>
87
+
88
+ {/* Bottom section: Buttons */}
89
+ <div className="flex flex-col gap-4 w-full">
90
+ <button
91
+ onClick={() => navigate('onboarding-create')}
92
+ className="h-12 px-5 py-[15px] btn-primary rounded-lg flex items-center justify-center transition-opacity hover:opacity-90"
93
+ style={{
94
+ fontFamily: 'var(--font-sans)',
95
+ fontSize: 'var(--font-size-base)',
96
+ fontWeight: 500,
97
+ lineHeight: 'var(--line-height-snug)',
98
+ letterSpacing: '0.01em',
99
+ color: '#000000',
100
+ }}
101
+ >
102
+ Create new wallet
103
+ </button>
104
+
105
+ <button
106
+ onClick={() => {
107
+ navigate('onboarding-import');
108
+ }}
109
+ className="h-12 px-5 py-[15px] btn-secondary rounded-lg flex items-center justify-center transition-opacity hover:opacity-90"
110
+ style={{
111
+ fontFamily: 'var(--font-sans)',
112
+ fontSize: 'var(--font-size-base)',
113
+ fontWeight: 500,
114
+ lineHeight: 'var(--line-height-snug)',
115
+ letterSpacing: '0.01em',
116
+ color: 'var(--color-bg)',
117
+ }}
118
+ >
119
+ I have a wallet
120
+ </button>
121
+
122
+ <button
123
+ onClick={() => {
124
+ navigate('onboarding-import-v0');
125
+ }}
126
+ className="h-12 px-5 py-[15px] btn-secondary rounded-lg flex items-center justify-center transition-opacity hover:opacity-90"
127
+ style={{
128
+ fontFamily: 'var(--font-sans)',
129
+ fontSize: 'var(--font-size-base)',
130
+ fontWeight: 500,
131
+ lineHeight: 'var(--line-height-snug)',
132
+ letterSpacing: '0.01em',
133
+ color: 'var(--color-bg)',
134
+ }}
135
+ >
136
+ I have a v0 wallet
137
+ </button>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ );
142
+ }