@zerodev/wallet-react-ui 0.0.7 → 0.0.9

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 (62) hide show
  1. package/README.md +20 -5
  2. package/dist/_types/auth/components/WalletGridSheet/index.d.ts +15 -0
  3. package/dist/_types/auth/components/WalletGridSheet/index.d.ts.map +1 -0
  4. package/dist/_types/auth/index.d.ts.map +1 -1
  5. package/dist/_types/auth/pages/SignUp/InstalledWallets.d.ts +12 -0
  6. package/dist/_types/auth/pages/SignUp/InstalledWallets.d.ts.map +1 -0
  7. package/dist/_types/auth/pages/SignUp/MoreWallets.d.ts +5 -0
  8. package/dist/_types/auth/pages/SignUp/MoreWallets.d.ts.map +1 -0
  9. package/dist/_types/auth/pages/SignUp/Wallet.d.ts +7 -0
  10. package/dist/_types/auth/pages/SignUp/Wallet.d.ts.map +1 -0
  11. package/dist/_types/auth/pages/SignUp/context.d.ts +5 -0
  12. package/dist/_types/auth/pages/SignUp/context.d.ts.map +1 -1
  13. package/dist/_types/auth/pages/SignUp/index.d.ts +6 -0
  14. package/dist/_types/auth/pages/SignUp/index.d.ts.map +1 -1
  15. package/dist/_types/auth/types.d.ts +2 -2
  16. package/dist/_types/auth/types.d.ts.map +1 -1
  17. package/dist/_types/auth/utils/isCancellationError.d.ts.map +1 -1
  18. package/dist/_types/auth/walletGuide.d.ts +108 -0
  19. package/dist/_types/auth/walletGuide.d.ts.map +1 -0
  20. package/dist/_types/history/components/TxHistoryItem/index.d.ts +21 -0
  21. package/dist/_types/history/components/TxHistoryItem/index.d.ts.map +1 -0
  22. package/dist/_types/history/mocks.d.ts +8 -0
  23. package/dist/_types/history/mocks.d.ts.map +1 -0
  24. package/dist/_types/history/pages/History.d.ts +10 -0
  25. package/dist/_types/history/pages/History.d.ts.map +1 -0
  26. package/dist/_types/history/pages/index.d.ts +24 -0
  27. package/dist/_types/history/pages/index.d.ts.map +1 -0
  28. package/dist/_types/history/types.d.ts +29 -0
  29. package/dist/_types/history/types.d.ts.map +1 -0
  30. package/dist/_types/history/utils/groupByDay.d.ts +13 -0
  31. package/dist/_types/history/utils/groupByDay.d.ts.map +1 -0
  32. package/dist/_types/index.d.ts +3 -0
  33. package/dist/_types/index.d.ts.map +1 -1
  34. package/dist/_types/shared/components/TokenSummary/index.d.ts +18 -0
  35. package/dist/_types/shared/components/TokenSummary/index.d.ts.map +1 -0
  36. package/dist/index.cjs +3 -3
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.mjs +974 -483
  39. package/dist/index.mjs.map +1 -1
  40. package/dist/styles.css +1 -1
  41. package/package.json +4 -4
  42. package/src/auth/components/WalletGridSheet/index.tsx +77 -0
  43. package/src/auth/index.tsx +0 -13
  44. package/src/auth/pages/SignUp/InstalledWallets.tsx +95 -0
  45. package/src/auth/pages/SignUp/MoreWallets.tsx +105 -0
  46. package/src/auth/pages/SignUp/Wallet.tsx +81 -0
  47. package/src/auth/pages/SignUp/context.tsx +5 -0
  48. package/src/auth/pages/SignUp/index.tsx +30 -4
  49. package/src/auth/types.ts +1 -2
  50. package/src/auth/utils/isCancellationError.ts +2 -0
  51. package/src/auth/walletGuide.ts +132 -0
  52. package/src/history/components/TxHistoryItem/index.tsx +108 -0
  53. package/src/history/mocks.ts +80 -0
  54. package/src/history/pages/History.tsx +69 -0
  55. package/src/history/pages/index.tsx +69 -0
  56. package/src/history/types.ts +29 -0
  57. package/src/history/utils/groupByDay.ts +47 -0
  58. package/src/index.ts +9 -0
  59. package/src/shared/components/TokenSummary/index.tsx +50 -0
  60. package/dist/_types/auth/pages/WalletSelection.d.ts +0 -2
  61. package/dist/_types/auth/pages/WalletSelection.d.ts.map +0 -1
  62. package/src/auth/pages/WalletSelection.tsx +0 -61
package/src/auth/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type AuthMethod = 'email' | 'google' | 'passkey'
1
+ export type AuthMethod = 'email' | 'google' | 'passkey' | 'external-wallet'
2
2
 
3
3
  export type AuthStep =
4
4
  | 'sign-up'
@@ -7,7 +7,6 @@ export type AuthStep =
7
7
  | 'verifying-otp'
8
8
  | 'passkey-prompt'
9
9
  | 'oauth-in-progress'
10
- | 'wallet-selection'
11
10
  | 'authenticated'
12
11
  | 'error'
13
12
 
@@ -2,6 +2,8 @@ export function isCancellationError(err: unknown): boolean {
2
2
  if (!(err instanceof Error)) return false
3
3
  // WebAuthn / passkey
4
4
  if (err.name === 'AbortError' || err.name === 'NotAllowedError') return true
5
+ // EIP-1193 user rejection (external-wallet connect), via viem
6
+ if (err.name === 'UserRejectedRequestError') return true
5
7
  // OAuth (existing logic, message-based)
6
8
  const msg = err.message.toLowerCase()
7
9
  return msg.includes('oauth popup was closed')
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Static wallet metadata ("wallet guide") for the external-wallet auth flow:
3
+ * `rdns` matches EIP-6963 announcements, `mobileLink` builds WalletConnect
4
+ * mobile deep links, `icon`/`downloadUrl` brand rows for wallets that are not
5
+ * installed. Self-contained — no runtime registry fetch.
6
+ *
7
+ * Wallet names and logos are trademarks of their respective owners.
8
+ */
9
+
10
+ export type WalletGuideEntry = {
11
+ id: string
12
+ name: string
13
+ /**
14
+ * EIP-6963 identifier used to match announced (installed) providers.
15
+ * Absent for wallets that never announce (mobile-app-only wallets).
16
+ */
17
+ rdns?: string
18
+ /** Self-contained `data:image/svg+xml` URI. */
19
+ icon: string
20
+ /**
21
+ * WalletConnect mobile deep-link prefix — append `encodeURIComponent(wcUri)`.
22
+ * Absent when the wallet has no WC deep link (SDK- or extension-only).
23
+ */
24
+ mobileLink?: string
25
+ /** Vendor download page, for "get the wallet" fallbacks. */
26
+ downloadUrl: string
27
+ }
28
+
29
+ /**
30
+ * A live connector "claims" a guide wallet by rdns: announced (6963)
31
+ * connectors carry `id === rdns`, explicit ones (e.g. `metaMask()`) declare
32
+ * `rdns` as a string or array.
33
+ */
34
+ export function matchesWallet(
35
+ connector: { id: string; rdns?: string | readonly string[] | undefined },
36
+ wallet: WalletGuideEntry,
37
+ ): boolean {
38
+ return (
39
+ !!wallet.rdns &&
40
+ (connector.id === wallet.rdns ||
41
+ (Array.isArray(connector.rdns)
42
+ ? connector.rdns.includes(wallet.rdns)
43
+ : connector.rdns === wallet.rdns))
44
+ )
45
+ }
46
+
47
+ const guide = [
48
+ {
49
+ id: 'metamask',
50
+ name: 'MetaMask',
51
+ rdns: 'io.metamask',
52
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2228%22%20height%3D%2228%22%20fill%3D%22none%22%20viewBox%3D%220%200%2028%2028%22%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cg%20clip-path%3D%22url(%23a)%22%3E%3Cpath%20fill%3D%22%23ff5c16%22%20d%3D%22m24.024%2023.824-4.846-1.434-3.655%202.172-2.55-.001-3.656-2.171-4.844%201.434L3%2018.88l1.473-5.488L3%208.751%204.473%203l7.569%204.496h4.413L24.024%203l1.473%205.751-1.473%204.64%201.473%205.488z%22%2F%3E%3Cpath%20fill%3D%22%23ff5c16%22%20d%3D%22m4.474%203%207.57%204.499-.302%203.087zm4.844%2015.881%203.33%202.522-3.33.987zm3.064-4.17-.64-4.123-4.097%202.804h-.002v.001l.013%202.886%201.661-1.567zM24.024%203l-7.57%204.499.3%203.087zM19.18%2018.881l-3.33%202.522%203.33.987zm1.674-5.488v-.002zl-4.097-2.804-.64%204.124h3.064l1.662%201.567z%22%2F%3E%3Cpath%20fill%3D%22%23e34807%22%20d%3D%22m9.317%2022.39-4.844%201.434L3%2018.881h6.317zm3.064-7.68.925%205.962-1.282-3.315-4.37-1.078%201.662-1.568zm6.799%207.68%204.844%201.434%201.473-4.943H19.18zm-3.064-7.68-.925%205.962%201.282-3.315%204.37-1.078-1.663-1.568z%22%2F%3E%3Cpath%20fill%3D%22%23ff8d5d%22%20d%3D%22m3%2018.88%201.473-5.489h3.169l.012%202.887%204.37%201.078%201.282%203.314-.659.73-3.33-2.522H3zm22.497%200-1.473-5.489h-3.17l-.01%202.887-4.371%201.078-1.282%203.314.659.73%203.33-2.522h6.317zM16.455%207.495h-4.413l-.3%203.087%201.565%2010.084h1.884l1.565-10.084z%22%2F%3E%3Cpath%20fill%3D%22%23661800%22%20d%3D%22M4.473%203%203%208.751l1.473%204.64h3.169l4.1-2.805zm6.992%2012.908H10.03l-.781.761%202.776.685-.56-1.447M24.024%203l1.473%205.751-1.473%204.64h-3.17l-4.098-2.805zm-6.99%2012.908h1.437l.782.762-2.78.686.56-1.45zm-1.512%206.687.328-1.193-.66-.73h-1.885l-.659.73.327%201.192%22%2F%3E%3Cpath%20fill%3D%22%23c0c4cd%22%20d%3D%22M15.522%2022.594v1.969h-2.548v-1.969z%22%2F%3E%3Cpath%20fill%3D%22%23e7ebf6%22%20d%3D%22m9.318%2022.388%203.658%202.174v-1.969l-.328-1.192zm9.862%200-3.658%202.174v-1.969l.328-1.192z%22%2F%3E%3C%2Fg%3E%3Cdefs%3E%3CclipPath%20id%3D%22a%22%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M3%203h22.5v21.563H3z%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3C%2Fsvg%3E',
53
+ mobileLink: 'https://metamask.app.link/wc?uri=',
54
+ downloadUrl: 'https://metamask.io/download',
55
+ },
56
+ {
57
+ id: 'trust',
58
+ name: 'Trust Wallet',
59
+ rdns: 'com.trustwallet.app',
60
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20width%3D%2228%22%20height%3D%2228%22%20viewBox%3D%220%200%2028%2028%22%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cpath%20fill%3D%22%230500FF%22%20d%3D%22M6%207.583%2013.53%205v17.882C8.15%2020.498%206%2015.928%206%2013.345V7.583Z%22%2F%3E%3Cpath%20fill%3D%22url(%23a)%22%20d%3D%22M22%207.583%2013.53%205v17.882c6.05-2.384%208.47-6.954%208.47-9.537V7.583Z%22%2F%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22a%22%20x1%3D%2219.768%22%20x2%3D%2214.072%22%20y1%3D%223.753%22%20y2%3D%2222.853%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%22.02%22%20stop-color%3D%22%2300F%22%2F%3E%3Cstop%20offset%3D%22.08%22%20stop-color%3D%22%230094FF%22%2F%3E%3Cstop%20offset%3D%22.16%22%20stop-color%3D%22%2348FF91%22%2F%3E%3Cstop%20offset%3D%22.42%22%20stop-color%3D%22%230094FF%22%2F%3E%3Cstop%20offset%3D%22.68%22%20stop-color%3D%22%230038FF%22%2F%3E%3Cstop%20offset%3D%22.9%22%20stop-color%3D%22%230500FF%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3C%2Fsvg%3E',
61
+ mobileLink: 'trust://wc?uri=',
62
+ downloadUrl: 'https://trustwallet.com/download',
63
+ },
64
+ {
65
+ id: 'coinbase',
66
+ name: 'Coinbase Wallet',
67
+ rdns: 'com.coinbase.wallet',
68
+ icon: 'data:image/svg+xml,%3Csvg%20width%3D%2228%22%20height%3D%2228%22%20viewBox%3D%220%200%2028%2028%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Crect%20width%3D%2228%22%20height%3D%2228%22%20fill%3D%22%232C5FF6%22%2F%3E%0A%3Cpath%20fill-rule%3D%22evenodd%22%20clip-rule%3D%22evenodd%22%20d%3D%22M14%2023.8C19.4124%2023.8%2023.8%2019.4124%2023.8%2014C23.8%208.58761%2019.4124%204.2%2014%204.2C8.58761%204.2%204.2%208.58761%204.2%2014C4.2%2019.4124%208.58761%2023.8%2014%2023.8ZM11.55%2010.8C11.1358%2010.8%2010.8%2011.1358%2010.8%2011.55V16.45C10.8%2016.8642%2011.1358%2017.2%2011.55%2017.2H16.45C16.8642%2017.2%2017.2%2016.8642%2017.2%2016.45V11.55C17.2%2011.1358%2016.8642%2010.8%2016.45%2010.8H11.55Z%22%20fill%3D%22white%22%2F%3E%0A%3C%2Fsvg%3E',
69
+ downloadUrl: 'https://coinbase.com/wallet/downloads',
70
+ },
71
+ {
72
+ id: 'rainbow',
73
+ name: 'Rainbow',
74
+ rdns: 'me.rainbow',
75
+ icon: 'data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20viewBox%3D%220%200%20120%20120%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Crect%20width%3D%22120%22%20height%3D%22120%22%20fill%3D%22url(%23paint0_linear_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M20%2038H26C56.9279%2038%2082%2063.0721%2082%2094V100H94C97.3137%20100%20100%2097.3137%20100%2094C100%2053.1309%2066.8691%2020%2026%2020C22.6863%2020%2020%2022.6863%2020%2026V38Z%22%20fill%3D%22url(%23paint1_radial_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M84%2094H100C100%2097.3137%2097.3137%20100%2094%20100H84V94Z%22%20fill%3D%22url(%23paint2_linear_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M26%2020L26%2036H20L20%2026C20%2022.6863%2022.6863%2020%2026%2020Z%22%20fill%3D%22url(%23paint3_linear_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M20%2036H26C58.0325%2036%2084%2061.9675%2084%2094V100H66V94C66%2071.9086%2048.0914%2054%2026%2054H20V36Z%22%20fill%3D%22url(%23paint4_radial_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M68%2094H84V100H68V94Z%22%20fill%3D%22url(%23paint5_linear_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M20%2052L20%2036L26%2036L26%2052H20Z%22%20fill%3D%22url(%23paint6_linear_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M20%2062C20%2065.3137%2022.6863%2068%2026%2068C40.3594%2068%2052%2079.6406%2052%2094C52%2097.3137%2054.6863%20100%2058%20100H68V94C68%2070.804%2049.196%2052%2026%2052H20V62Z%22%20fill%3D%22url(%23paint7_radial_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M52%2094H68V100H58C54.6863%20100%2052%2097.3137%2052%2094Z%22%20fill%3D%22url(%23paint8_radial_62_329)%22%2F%3E%0A%3Cpath%20d%3D%22M26%2068C22.6863%2068%2020%2065.3137%2020%2062L20%2052L26%2052L26%2068Z%22%20fill%3D%22url(%23paint9_radial_62_329)%22%2F%3E%0A%3Cdefs%3E%0A%3ClinearGradient%20id%3D%22paint0_linear_62_329%22%20x1%3D%2260%22%20y1%3D%220%22%20x2%3D%2260%22%20y2%3D%22120%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%0A%3Cstop%20stop-color%3D%22%23174299%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23001E59%22%2F%3E%0A%3C%2FlinearGradient%3E%0A%3CradialGradient%20id%3D%22paint1_radial_62_329%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientUnits%3D%22userSpaceOnUse%22%20gradientTransform%3D%22translate(26%2094)%20rotate(-90)%20scale(74)%22%3E%0A%3Cstop%20offset%3D%220.770277%22%20stop-color%3D%22%23FF4000%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%238754C9%22%2F%3E%0A%3C%2FradialGradient%3E%0A%3ClinearGradient%20id%3D%22paint2_linear_62_329%22%20x1%3D%2283%22%20y1%3D%2297%22%20x2%3D%22100%22%20y2%3D%2297%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%0A%3Cstop%20stop-color%3D%22%23FF4000%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%238754C9%22%2F%3E%0A%3C%2FlinearGradient%3E%0A%3ClinearGradient%20id%3D%22paint3_linear_62_329%22%20x1%3D%2223%22%20y1%3D%2220%22%20x2%3D%2223%22%20y2%3D%2237%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%0A%3Cstop%20stop-color%3D%22%238754C9%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23FF4000%22%2F%3E%0A%3C%2FlinearGradient%3E%0A%3CradialGradient%20id%3D%22paint4_radial_62_329%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientUnits%3D%22userSpaceOnUse%22%20gradientTransform%3D%22translate(26%2094)%20rotate(-90)%20scale(58)%22%3E%0A%3Cstop%20offset%3D%220.723929%22%20stop-color%3D%22%23FFF700%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23FF9901%22%2F%3E%0A%3C%2FradialGradient%3E%0A%3ClinearGradient%20id%3D%22paint5_linear_62_329%22%20x1%3D%2268%22%20y1%3D%2297%22%20x2%3D%2284%22%20y2%3D%2297%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%0A%3Cstop%20stop-color%3D%22%23FFF700%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23FF9901%22%2F%3E%0A%3C%2FlinearGradient%3E%0A%3ClinearGradient%20id%3D%22paint6_linear_62_329%22%20x1%3D%2223%22%20y1%3D%2252%22%20x2%3D%2223%22%20y2%3D%2236%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%0A%3Cstop%20stop-color%3D%22%23FFF700%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23FF9901%22%2F%3E%0A%3C%2FlinearGradient%3E%0A%3CradialGradient%20id%3D%22paint7_radial_62_329%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientUnits%3D%22userSpaceOnUse%22%20gradientTransform%3D%22translate(26%2094)%20rotate(-90)%20scale(42)%22%3E%0A%3Cstop%20offset%3D%220.59513%22%20stop-color%3D%22%2300AAFF%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2301DA40%22%2F%3E%0A%3C%2FradialGradient%3E%0A%3CradialGradient%20id%3D%22paint8_radial_62_329%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientUnits%3D%22userSpaceOnUse%22%20gradientTransform%3D%22translate(51%2097)%20scale(17%2045.3333)%22%3E%0A%3Cstop%20stop-color%3D%22%2300AAFF%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2301DA40%22%2F%3E%0A%3C%2FradialGradient%3E%0A%3CradialGradient%20id%3D%22paint9_radial_62_329%22%20cx%3D%220%22%20cy%3D%220%22%20r%3D%221%22%20gradientUnits%3D%22userSpaceOnUse%22%20gradientTransform%3D%22translate(23%2069)%20rotate(-90)%20scale(17%20322.37)%22%3E%0A%3Cstop%20stop-color%3D%22%2300AAFF%22%2F%3E%0A%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2301DA40%22%2F%3E%0A%3C%2FradialGradient%3E%0A%3C%2Fdefs%3E%0A%3C%2Fsvg%3E',
76
+ mobileLink: 'rainbow://wc?uri=',
77
+ downloadUrl: 'https://rainbow.download',
78
+ },
79
+ {
80
+ id: 'rabby',
81
+ name: 'Rabby Wallet',
82
+ rdns: 'io.rabby',
83
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20viewBox%3D%220%200%2028%2028%22%3E%3Cg%20clip-path%3D%22url(%23a)%22%3E%3Cpath%20fill%3D%22%238697FF%22%20d%3D%22M28%200H0v28h28V0Z%22%2F%3E%3Cpath%20fill%3D%22url(%23b)%22%20d%3D%22M22.54%2015.078c.677-1.514-2.673-5.744-5.874-7.506-2.017-1.365-4.12-1.178-4.545-.579-.935%201.316%203.094%202.43%205.788%203.731-.58.252-1.125.703-1.446%201.28-1.004-1.096-3.209-2.04-5.796-1.28-1.743.513-3.191%201.721-3.751%203.546a1.097%201.097%200%201%200-.445%202.1c.112%200%20.463-.075.463-.075l5.612.041c-2.244%203.56-4.018%204.081-4.018%204.698s1.697.45%202.335.22c3.05-1.1%206.327-4.531%206.89-5.519%202.36.295%204.345.33%204.786-.657Z%22%2F%3E%3Cpath%20fill%3D%22url(%23c)%22%20fill-rule%3D%22evenodd%22%20d%3D%22m17.885%2010.713.025.01c.125-.049.105-.233.07-.378-.078-.333-1.438-1.676-2.715-2.277-1.743-.82-3.025-.777-3.212-.398.356.726%201.998%201.408%203.714%202.12.723.3%201.46.606%202.118.923Z%22%20clip-rule%3D%22evenodd%22%2F%3E%3Cpath%20fill%3D%22url(%23d)%22%20fill-rule%3D%22evenodd%22%20d%3D%22M15.701%2018.036a10.296%2010.296%200%200%200-1.2-.37c.482-.862.583-2.138.128-2.945-.639-1.133-1.44-1.736-3.304-1.736-1.024%200-3.783.346-3.832%202.648-.005.242%200%20.464.017.667l5.036.037a17.264%2017.264%200%200%201-1.871%202.483c.669.172%201.221.316%201.728.448.48.125.92.24%201.38.357a21.003%2021.003%200%200%200%201.918-1.59Z%22%20clip-rule%3D%22evenodd%22%2F%3E%3Cpath%20fill%3D%22url(%23e)%22%20d%3D%22M6.848%2016.063c.206%201.75%201.2%202.435%203.232%202.638%202.032.203%203.197.067%204.749.208%201.296.118%202.453.778%202.882.55.386-.205.17-.947-.347-1.423-.67-.617-1.597-1.046-3.229-1.199.325-.89.234-2.138-.27-2.817-.731-.982-2.079-1.426-3.785-1.232-1.782.202-3.49%201.08-3.232%203.275Z%22%2F%3E%3C%2Fg%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22b%22%20x1%3D%2210.464%22%20x2%3D%2222.394%22%20y1%3D%2213.737%22%20y2%3D%2217.12%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%23fff%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22c%22%20x1%3D%2220.386%22%20x2%3D%2211.779%22%20y1%3D%2213.509%22%20y2%3D%224.879%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%237258DC%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23797DEA%22%20stop-opacity%3D%220%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22d%22%20x1%3D%2215.94%22%20x2%3D%227.673%22%20y1%3D%2218.337%22%20y2%3D%2213.584%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%237461EA%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23BFC2FF%22%20stop-opacity%3D%220%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22e%22%20x1%3D%2211.177%22%20x2%3D%2216.765%22%20y1%3D%2213.648%22%20y2%3D%2220.749%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%23fff%22%2F%3E%3Cstop%20offset%3D%22.984%22%20stop-color%3D%22%23D5CEFF%22%2F%3E%3C%2FlinearGradient%3E%3CclipPath%20id%3D%22a%22%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3C%2Fsvg%3E',
84
+ downloadUrl: 'https://rabby.io',
85
+ },
86
+ {
87
+ id: 'okx',
88
+ name: 'OKX Wallet',
89
+ rdns: 'com.okex.wallet',
90
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20viewBox%3D%220%200%2028%2028%22%3E%3Cpath%20fill%3D%22%23000%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%20d%3D%22M10.819%205.556H5.93a.376.376%200%200%200-.375.375v4.888c0%20.207.168.375.375.375h4.888a.376.376%200%200%200%20.375-.376V5.932a.376.376%200%200%200-.376-.375Zm5.64%205.638h-4.886a.376.376%200%200%200-.376.376v4.887c0%20.208.168.376.376.376h4.887a.376.376%200%200%200%20.376-.375V11.57a.376.376%200%200%200-.376-.377Zm.75-5.638h4.887c.208%200%20.376.168.376.375v4.888a.376.376%200%200%201-.376.375H17.21a.376.376%200%200%201-.376-.376V5.933c0-.208.169-.376.376-.376Zm-6.39%2011.277H5.93a.376.376%200%200%200-.375.376v4.887c0%20.208.168.376.375.376h4.888a.376.376%200%200%200%20.375-.376V17.21a.376.376%200%200%200-.376-.376Zm6.39%200h4.887c.208%200%20.376.169.376.376v4.887a.376.376%200%200%201-.376.376H17.21a.376.376%200%200%201-.376-.376V17.21c0-.207.169-.376.376-.376Z%22%20clip-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E',
91
+ mobileLink: 'okex://main/wc?uri=',
92
+ downloadUrl: 'https://okx.com/download',
93
+ },
94
+ {
95
+ id: 'zerion',
96
+ name: 'Zerion',
97
+ rdns: 'io.zerion.wallet',
98
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20fill%3D%22none%22%20viewBox%3D%220%200%2028%2028%22%3E%3Cpath%20fill%3D%22%232962EF%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M6.073%207c-.48%200-.665.593-.262.841l10.073%206.074a.577.577%200%200%200%20.758-.139l4.43-5.814c.3-.404-.004-.962-.525-.962H6.073ZM21.904%2021c.48%200%20.67-.596.267-.844l-10.075-6.073a.569.569%200%200%200-.751.146l-4.437%205.813c-.301.404.012.958.534.958h14.462Z%22%2F%3E%3C%2Fsvg%3E',
99
+ mobileLink: 'zerion://wc?uri=',
100
+ downloadUrl: 'https://zerion.io',
101
+ },
102
+ {
103
+ id: 'uniswap',
104
+ name: 'Uniswap',
105
+ rdns: 'org.uniswap.app',
106
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2228%22%20height%3D%2228%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22%23FFD8EA%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cg%20fill%3D%22%23FF007A%22%20clip-path%3D%22url(%23a)%22%3E%3Cpath%20d%3D%22M9.635%206.068c-.255-.039-.266-.043-.145-.06.23-.035.773.012%201.148.099.874.202%201.67.722%202.519%201.646l.225.246.323-.051c1.36-.213%202.741-.044%203.899.477.319.144.821.43.882.503.022.024.058.173.082.335.086.557.044.982-.13%201.301-.096.173-.101.228-.037.377a.367.367%200%200%200%20.334.206c.287%200%20.597-.454.74-1.086l.056-.252.113.126c.62.685%201.106%201.618%201.189%202.282l.021.174-.103-.158a1.966%201.966%200%200%200-.59-.604c-.415-.268-.855-.36-2.017-.42-1.05-.053-1.645-.141-2.234-.329-1.003-.32-1.508-.744-2.699-2.27-.53-.678-.855-1.053-1.18-1.354-.74-.687-1.466-1.047-2.396-1.187v-.001Z%22%2F%3E%3Cpath%20d%3D%22M18.725%207.581c.026-.453.088-.753.216-1.026.028-.07.063-.136.104-.198a.69.69%200%200%201-.049.178c-.092.266-.108.629-.043%201.052.081.536.126.613.706%201.192.273.272.589.613.704.761l.21.267-.21-.191c-.255-.233-.841-.69-.972-.755-.086-.042-.1-.042-.153.01-.05.048-.06.12-.068.461-.01.532-.084.873-.263%201.213-.096.187-.111.147-.025-.062.066-.155.072-.224.072-.739%200-1.033-.127-1.283-.864-1.707a8.169%208.169%200%200%200-.684-.346%202.614%202.614%200%200%201-.334-.16c.02-.02.74.185%201.029.293.431.163.502.183.555.164.034-.013.051-.113.068-.407h.001Zm-8.595%201.77c-.517-.696-.838-1.764-.768-2.563l.02-.247.119.02c.222.04.603.179.783.286.49.29.703.673.918%201.657.064.288.147.613.185.725.061.178.294.592.483.862.136.194.046.286-.255.26-.46-.04-1.083-.46-1.485-1Zm7.965%205.182c-2.42-.95-3.273-1.777-3.273-3.17%200-.206.007-.374.016-.374.008%200%20.102.067.208.151.491.384%201.04.548%202.563.765.896.128%201.398.231%201.864.382%201.48.478%202.392%201.449%202.61%202.773.063.384.028%201.104-.076%201.484-.082.3-.329.84-.394.861-.019.007-.037-.061-.04-.154-.025-.496-.283-.98-.715-1.343-.49-.412-1.15-.741-2.763-1.375Zm-1.699.396a4.13%204.13%200%200%200-.117-.5l-.062-.18.115.127c.16.173.285.396.391.693.082.227.09.294.09.662%200%20.361-.011.437-.087.64-.104.3-.28.572-.51.794-.443.44-1.011.683-1.833.784-.142.018-.557.047-.922.066-.922.046-1.529.144-2.073.33a.446.446%200%200%201-.156.036c-.021-.021.35-.237.656-.381.431-.204.861-.315%201.825-.47.475-.078.968-.173%201.093-.21%201.178-.352%201.784-1.263%201.59-2.39Z%22%2F%3E%3Cpath%20d%3D%22M17.506%2016.855c-.321-.675-.396-1.327-.22-1.935.02-.067.05-.119.068-.119a.64.64%200%200%201%20.169.09c.149.097.445.261%201.237.682.988.527%201.553.934%201.936%201.4.335.407.542.872.643%201.438.057.32.023%201.093-.061%201.416-.266%201.018-.882%201.818-1.764%202.285a2.129%202.129%200%200%201-.258.124c-.013%200%20.035-.116.104-.259.297-.605.331-1.193.107-1.848-.138-.401-.418-.89-.982-1.718-.657-.96-.817-1.218-.979-1.556Zm-9.095%203.644c.9-.742%202.016-1.267%203.036-1.43a4.85%204.85%200%200%201%201.575.06c.652.163%201.235.528%201.538.962.296.425.423.794.556%201.618.052.324.109.651.125.724.1.427.293.768.532.939.38.272%201.037.29%201.682.044a.853.853%200%200%201%20.21-.064c.023.023-.301.235-.53.347-.27.141-.572.213-.879.208-.59%200-1.08-.294-1.49-.891a7.027%207.027%200%200%201-.402-.784c-.431-.961-.644-1.253-1.145-1.575-.437-.28-1-.329-1.424-.126-.556.266-.71.96-.312%201.4.187.189.43.313.695.354a.75.75%200%200%200%20.589-.174.728.728%200%200%200%20.251-.551c0-.29-.114-.453-.4-.581-.392-.172-.812.029-.81.388%200%20.153.069.249.226.32.1.044.103.046.02.03-.358-.073-.442-.496-.154-.776.347-.336%201.064-.188%201.31.272.103.194.115.578.025.81-.203.52-.79.793-1.387.644-.407-.102-.571-.211-1.06-.703-.852-.856-1.182-1.023-2.408-1.21l-.237-.035.268-.22Z%22%2F%3E%3Cpath%20fill-rule%3D%22evenodd%22%20d%3D%22M4.418%205.179c2.842%203.368%204.8%204.757%205.017%205.05.18.243.112.462-.195.632a1.899%201.899%200%200%201-.699.191c-.2%200-.269-.075-.269-.075-.115-.106-.18-.088-.773-1.116A176.911%20176.911%200%200%200%205.968%207.56c-.044-.04-.042-.04%201.448%202.564.24.543.047.741.047.819%200%20.157-.044.24-.242.457-.332.36-.48.765-.587%201.604-.12.94-.456%201.604-1.39%202.741-.545.666-.635.787-.773%201.056-.174.338-.221.527-.24.952a2.9%202.9%200%200%200%20.16%201.174c.122.378.252.626.582%201.125.285.43.448.75.448.876%200%20.099.019.099.461.001%201.054-.232%201.91-.64%202.392-1.142.298-.311.367-.482.37-.907.002-.277-.008-.336-.085-.496-.125-.26-.353-.477-.855-.813-.66-.44-.942-.794-1.018-1.28-.065-.4.01-.682.373-1.427.377-.773.47-1.103.535-1.88.04-.503.096-.701.244-.861.155-.166.293-.222.676-.272.623-.084%201.018-.24%201.343-.534a1.14%201.14%200%200%200%20.421-.869l.014-.28-.16-.179C9.563%209.34%204.036%204.667%204%204.667c-.007%200%20.18.23.418.512Zm1.325%2013.086a.486.486%200%200%200-.157-.652c-.203-.133-.522-.069-.522.103%200%20.053.03.092.098.125.114.058.122.122.032.254s-.082.248.02.328c.168.126.404.057.529-.158ZM10.683%2012c-.29.086-.575.389-.664.706-.053.194-.022.534.058.638.13.169.255.213.596.212.665-.004%201.243-.283%201.311-.632.054-.286-.2-.68-.55-.855a1.33%201.33%200%200%200-.75-.07Zm.78.593c.102-.143.057-.296-.118-.4-.331-.199-.835-.035-.835.272%200%20.153.262.32.502.32.16%200%20.38-.093.45-.192Z%22%20clip-rule%3D%22evenodd%22%2F%3E%3C%2Fg%3E%3Cdefs%3E%3CclipPath%20id%3D%22a%22%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M4%204h19v20H4z%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3C%2Fsvg%3E',
107
+ mobileLink: 'uniswap://wc?uri=',
108
+ downloadUrl: 'https://wallet.uniswap.org',
109
+ },
110
+ {
111
+ id: 'ledger',
112
+ name: 'Ledger',
113
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2228%22%20height%3D%2228%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22%23000%22%20d%3D%22M0%200h28v28H0z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%20d%3D%22M11.65%204.4H4.4V9h1.1V5.5l6.15-.04V4.4Zm.05%205.95v7.25h4.6v-1.1h-3.5l-.04-6.15H11.7ZM4.4%2023.6h7.25v-1.06L5.5%2022.5V19H4.4v4.6ZM16.35%204.4h7.25V9h-1.1V5.5l-6.15-.04V4.4Zm7.25%2019.2h-7.25v-1.06l6.15-.04V19h1.1v4.6Z%22%20clip-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E',
114
+ mobileLink: 'ledgerlive://wc?uri=',
115
+ downloadUrl: 'https://www.ledger.com/ledger-live',
116
+ },
117
+ {
118
+ id: 'binance',
119
+ name: 'Binance Wallet',
120
+ rdns: 'com.binance.wallet',
121
+ icon: 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22130%22%20height%3D%22130%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22%23000%22%20d%3D%22M0%200h130v130H0z%22%2F%3E%3Cpath%20fill%3D%22%23F3BA2F%22%20d%3D%22M45.587%2057.02%2065.01%2037.606l19.43%2019.43%2011.295-11.303L65.01%2015%2034.284%2045.725zM15%2065.004l11.299-11.299%2011.298%2011.299L26.3%2076.302zM45.587%2072.983%2065.01%2092.406l19.43-19.43%2011.303%2011.287-.008.007-30.725%2030.734-30.725-30.718-.016-.016zM92.403%2065.006%20103.7%2053.708%20115%2065.006l-11.299%2011.299z%22%2F%3E%3Cpath%20fill%3D%22%23F3BA2F%22%20d%3D%22m76.471%2064.998-11.46-11.469-8.476%208.475-.98.972-2.005%202.006-.016.016.016.024%2011.46%2011.453%2011.461-11.47.008-.007z%22%2F%3E%3C%2Fsvg%3E',
122
+ mobileLink: 'bnc://app.binance.com/cedefi/wc?uri=',
123
+ downloadUrl: 'https://www.binance.com/en/download',
124
+ },
125
+ ] as const satisfies readonly WalletGuideEntry[]
126
+
127
+ /** Valid `walletId` values for `<SignUp.Wallet>` — the guide's wallet ids. */
128
+ export type WalletId = (typeof guide)[number]['id']
129
+
130
+ // Widened so entries have a uniform shape (`rdns` et al. always accessible);
131
+ // `guide` stays literal only to derive `WalletId`.
132
+ export const WALLET_GUIDE: readonly WalletGuideEntry[] = guide
@@ -0,0 +1,108 @@
1
+ import { cn, Icon, type IconName, Text } from '@zerodev/react-ui'
2
+
3
+ export type TxHistoryStatus = 'Pending' | 'Success' | 'Failed'
4
+
5
+ const STATUS_COLOR: Record<TxHistoryStatus, string> = {
6
+ Pending: 'zd:text-solarOrange',
7
+ Success: 'zd:text-positive',
8
+ Failed: 'zd:text-negative',
9
+ }
10
+
11
+ export interface TxHistoryItemProps {
12
+ /** Leading glyph for the activity kind, e.g. `'arrowSwapHorizontalOutline'`
13
+ * for swaps, `'lighting'` for staking/yield, `'imageFill'` for NFTs. */
14
+ icon: IconName
15
+ /** Activity label, e.g. `"Swapped ETH → USD₮0"`. Never truncated. */
16
+ title: string
17
+ /** Pre-formatted outcome, e.g. `"2,343 ETH"`. Truncates when long. */
18
+ value: string
19
+ /** Chain the transaction ran on (source chain for cross-chain rows). */
20
+ chainName: string
21
+ chainIconUrl?: string
22
+ /** Destination chain. When present the row renders `chain → destChain`. */
23
+ destChainName?: string
24
+ destChainIconUrl?: string
25
+ status: TxHistoryStatus
26
+ className?: string
27
+ }
28
+
29
+ export function TxHistoryItem({
30
+ icon,
31
+ title,
32
+ value,
33
+ chainName,
34
+ chainIconUrl,
35
+ destChainName,
36
+ destChainIconUrl,
37
+ status,
38
+ className,
39
+ }: TxHistoryItemProps) {
40
+ return (
41
+ <div
42
+ className={cn(
43
+ 'zd:flex zd:w-full zd:items-center zd:gap-2 zd:p-2',
44
+ className,
45
+ )}
46
+ >
47
+ <div className="zd:flex zd:size-11 zd:shrink-0 zd:items-center zd:justify-center zd:rounded-xl zd:bg-white">
48
+ <Icon name={icon} className="zd:size-5" />
49
+ </div>
50
+
51
+ <div className="zd:flex zd:min-w-0 zd:flex-1 zd:flex-col zd:gap-2">
52
+ <div className="zd:flex zd:w-full zd:items-center zd:justify-between zd:gap-2">
53
+ <Text className="zd:shrink-0 zd:whitespace-nowrap zd:text-body1">
54
+ {title}
55
+ </Text>
56
+ <Text className="zd:min-w-0 zd:truncate zd:text-right zd:text-body1">
57
+ {value}
58
+ </Text>
59
+ </div>
60
+
61
+ <div className="zd:flex zd:w-full zd:items-center zd:justify-between zd:gap-2">
62
+ <div className="zd:flex zd:min-w-0 zd:items-center zd:gap-2">
63
+ <ChainTag
64
+ name={chainName}
65
+ {...(chainIconUrl && { iconUrl: chainIconUrl })}
66
+ />
67
+ {destChainName && (
68
+ <>
69
+ <Icon
70
+ name="arrowRightFill"
71
+ aria-hidden
72
+ className="zd:size-3 zd:shrink-0 zd:opacity-30"
73
+ />
74
+ <ChainTag
75
+ name={destChainName}
76
+ {...(destChainIconUrl && { iconUrl: destChainIconUrl })}
77
+ />
78
+ </>
79
+ )}
80
+ </div>
81
+ <Text
82
+ className={cn('zd:shrink-0 zd:text-body3', STATUS_COLOR[status])}
83
+ >
84
+ {status}
85
+ </Text>
86
+ </div>
87
+ </div>
88
+ </div>
89
+ )
90
+ }
91
+
92
+ function ChainTag({ name, iconUrl }: { name: string; iconUrl?: string }) {
93
+ return (
94
+ <div className="zd:flex zd:min-w-0 zd:items-center zd:gap-[5px]">
95
+ {iconUrl && (
96
+ <span className="zd:size-3 zd:shrink-0 zd:overflow-hidden zd:rounded-full zd:bg-white">
97
+ <img
98
+ src={iconUrl}
99
+ alt=""
100
+ aria-hidden
101
+ className="zd:size-full zd:object-cover"
102
+ />
103
+ </span>
104
+ )}
105
+ <Text className="zd:truncate zd:text-body3">{name}</Text>
106
+ </div>
107
+ )
108
+ }
@@ -0,0 +1,80 @@
1
+ import type { TxHistoryEntry } from './types'
2
+
3
+ const ARB_ICON =
4
+ 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/arbitrum/info/logo.png'
5
+ const BASE_ICON =
6
+ 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/base/info/logo.png'
7
+
8
+ const HOUR = 60 * 60 * 1000
9
+
10
+ /**
11
+ * Placeholder feed mirroring the Figma history screen (`15873:58582`) until
12
+ * the real activity source lands. Timestamps are relative to module load:
13
+ * a "Today" section and an older fixed-looking section two weeks back.
14
+ */
15
+ export const MOCK_HISTORY: TxHistoryEntry[] = [
16
+ {
17
+ id: 'mock-1',
18
+ icon: 'arrowSwapHorizontalOutline',
19
+ title: 'Swapped ETH → USD₮0',
20
+ value: '2,343 ETH',
21
+ chainName: 'Arbitrum One',
22
+ chainIconUrl: ARB_ICON,
23
+ destChainName: 'Base',
24
+ destChainIconUrl: BASE_ICON,
25
+ status: 'Pending',
26
+ timestamp: Date.now() - 1 * HOUR,
27
+ },
28
+ {
29
+ id: 'mock-2',
30
+ icon: 'arrowSwapHorizontalOutline',
31
+ title: 'Swapped ETH → USD₮0',
32
+ value: '2,343 ETH',
33
+ chainName: 'Arbitrum One',
34
+ chainIconUrl: ARB_ICON,
35
+ destChainName: 'Base',
36
+ destChainIconUrl: BASE_ICON,
37
+ status: 'Pending',
38
+ timestamp: Date.now() - 2 * HOUR,
39
+ },
40
+ {
41
+ id: 'mock-3',
42
+ icon: 'lighting',
43
+ title: 'Fixed Yield',
44
+ value: '2,323 PT wstETH (25 Jan 2026)',
45
+ chainName: 'Arbitrum One',
46
+ chainIconUrl: ARB_ICON,
47
+ status: 'Success',
48
+ timestamp: Date.now() - 3 * HOUR,
49
+ },
50
+ {
51
+ id: 'mock-4',
52
+ icon: 'imageFill',
53
+ title: 'Received NFT',
54
+ value: 'Bored Ape Yacht Club',
55
+ chainName: 'Arbitrum One',
56
+ chainIconUrl: ARB_ICON,
57
+ status: 'Success',
58
+ timestamp: Date.now() - 4 * HOUR,
59
+ },
60
+ {
61
+ id: 'mock-5',
62
+ icon: 'lighting',
63
+ title: 'Collateral Used',
64
+ value: 'Collateralization enabled for USD₮0',
65
+ chainName: 'Arbitrum One',
66
+ chainIconUrl: ARB_ICON,
67
+ status: 'Success',
68
+ timestamp: Date.now() - 14 * 24 * HOUR,
69
+ },
70
+ {
71
+ id: 'mock-6',
72
+ icon: 'lighting',
73
+ title: 'Liquid Staked ETH',
74
+ value: '2,323 PT wstETH (25 Jan 2026)',
75
+ chainName: 'Arbitrum One',
76
+ chainIconUrl: ARB_ICON,
77
+ status: 'Success',
78
+ timestamp: Date.now() - 14 * 24 * HOUR - 1 * HOUR,
79
+ },
80
+ ]
@@ -0,0 +1,69 @@
1
+ import { Text, Wrapper } from '@zerodev/react-ui'
2
+ import { Fragment } from 'react'
3
+ import { TxHistoryItem } from '../components/TxHistoryItem'
4
+ import { MOCK_HISTORY } from '../mocks'
5
+ import type { TxHistoryEntry } from '../types'
6
+ import { groupByDay } from '../utils/groupByDay'
7
+
8
+ export interface HistoryProps {
9
+ /** Activity feed, newest anywhere (sorted internally). Defaults to the
10
+ * mock feed until the real activity source lands. */
11
+ entries?: TxHistoryEntry[]
12
+ /** Fired when a row is tapped. Rows are inert when omitted. */
13
+ onSelectEntry?: (entry: TxHistoryEntry) => void
14
+ }
15
+
16
+ export function History({
17
+ entries = MOCK_HISTORY,
18
+ onSelectEntry,
19
+ }: HistoryProps) {
20
+ const groups = groupByDay(entries)
21
+
22
+ return (
23
+ <div className="zd:flex zd:h-full zd:w-full zd:flex-col zd:gap-1 zd:pt-2 zd:pb-4">
24
+ <Wrapper
25
+ variant="ghost"
26
+ className="zd:flex zd:w-full zd:flex-1 zd:flex-col zd:gap-1 zd:overflow-y-auto zd:rounded-2xl zd:p-2"
27
+ >
28
+ {groups.map((group) => (
29
+ <Fragment key={group.label}>
30
+ <div className="zd:flex zd:w-full zd:items-center zd:py-2 zd:pr-2">
31
+ <Text className="zd:text-body3">{group.label}</Text>
32
+ </div>
33
+ {group.entries.map((entry) =>
34
+ onSelectEntry ? (
35
+ <button
36
+ key={entry.id}
37
+ type="button"
38
+ onClick={() => onSelectEntry(entry)}
39
+ className="zd:w-full zd:cursor-pointer zd:text-left"
40
+ >
41
+ <EntryRow entry={entry} />
42
+ </button>
43
+ ) : (
44
+ <EntryRow key={entry.id} entry={entry} />
45
+ ),
46
+ )}
47
+ </Fragment>
48
+ ))}
49
+ </Wrapper>
50
+ </div>
51
+ )
52
+ }
53
+
54
+ function EntryRow({ entry }: { entry: TxHistoryEntry }) {
55
+ return (
56
+ <TxHistoryItem
57
+ icon={entry.icon}
58
+ title={entry.title}
59
+ value={entry.value}
60
+ chainName={entry.chainName}
61
+ {...(entry.chainIconUrl && { chainIconUrl: entry.chainIconUrl })}
62
+ {...(entry.destChainName && { destChainName: entry.destChainName })}
63
+ {...(entry.destChainIconUrl && {
64
+ destChainIconUrl: entry.destChainIconUrl,
65
+ })}
66
+ status={entry.status}
67
+ />
68
+ )
69
+ }
@@ -0,0 +1,69 @@
1
+ import { Screen, TopNav } from '@zerodev/react-ui'
2
+ import { useState } from 'react'
3
+ import type { TxHistoryEntry } from '../types'
4
+ import { History } from './History'
5
+
6
+ /** Current page within the history flow. Single page for now — a
7
+ * transaction-details step slots in beside it later. */
8
+ export type TxHistoryStep = 'history'
9
+
10
+ const TITLE_BY_STEP: Record<TxHistoryStep, string> = {
11
+ history: 'History',
12
+ }
13
+
14
+ export interface TxHistoryProps {
15
+ /** Called when the top-right × close button is clicked. */
16
+ onClose: () => void
17
+ /** Activity feed; defaults to the mock feed until a real source lands. */
18
+ entries?: TxHistoryEntry[] | undefined
19
+ /** Fired when a row is tapped. Rows are inert when omitted. */
20
+ onSelectEntry?: ((entry: TxHistoryEntry) => void) | undefined
21
+ className?: string | undefined
22
+ size?: 'sm' | 'md' | 'lg' | undefined
23
+ }
24
+
25
+ /**
26
+ * Transaction history widget.
27
+ *
28
+ * Owns the shared `Screen` + `TopNav` chrome and delegates the body to the
29
+ * current page in this directory — mirrors the layout of
30
+ * `smart-routing-address-react-ui`'s `pages/index.tsx`. Navigation is owned
31
+ * here: pages get callbacks, never the step setter.
32
+ */
33
+ export function TxHistory({
34
+ onClose,
35
+ entries,
36
+ onSelectEntry,
37
+ className,
38
+ size,
39
+ }: TxHistoryProps) {
40
+ // Single step today, so the setter is unused; destructure it back in when
41
+ // the first sub-page (transaction details) lands.
42
+ const [step] = useState<TxHistoryStep>('history')
43
+
44
+ const renderStep = () => {
45
+ switch (step) {
46
+ case 'history':
47
+ return (
48
+ <History
49
+ {...(entries && { entries })}
50
+ {...(onSelectEntry && { onSelectEntry })}
51
+ />
52
+ )
53
+ }
54
+ }
55
+
56
+ // Sub-pages will swap the left slot for a back chevron returning to the
57
+ // parent step (see SRA's pages/index.tsx); the root step has none.
58
+ return (
59
+ <Screen
60
+ {...(className && { className })}
61
+ {...(size && { size })}
62
+ topNav={
63
+ <TopNav title={TITLE_BY_STEP[step]} onRightButtonClick={onClose} />
64
+ }
65
+ >
66
+ {renderStep()}
67
+ </Screen>
68
+ )
69
+ }
@@ -0,0 +1,29 @@
1
+ import type { IconName } from '@zerodev/react-ui'
2
+ import type { TxHistoryStatus } from './components/TxHistoryItem'
3
+
4
+ /**
5
+ * One row of the history feed, presentation-ready. This is the mock-stage
6
+ * shape: display strings are pre-built and only `timestamp` is raw (day
7
+ * grouping is a relationship with "now", so it can't be pre-formatted).
8
+ * When the real activity source lands, its domain model maps into this via
9
+ * a `toTxHistoryEntry`-style adapter rather than reshaping the components.
10
+ */
11
+ export interface TxHistoryEntry {
12
+ /** Stable key — backend id, or `${txHash}-${logIndex}` when derived. */
13
+ id: string
14
+ /** Leading glyph for the activity kind. */
15
+ icon: IconName
16
+ /** Row title, e.g. `"Swapped ETH → USD₮0"`. */
17
+ title: string
18
+ /** Trailing amount/outcome, e.g. `"2,343 ETH"`. */
19
+ value: string
20
+ /** Chain the activity ran on (source side for cross-chain rows). */
21
+ chainName: string
22
+ chainIconUrl?: string
23
+ /** Destination chain — cross-chain rows only. */
24
+ destChainName?: string
25
+ destChainIconUrl?: string
26
+ status: TxHistoryStatus
27
+ /** Unix epoch milliseconds — drives sorting and day grouping. */
28
+ timestamp: number
29
+ }
@@ -0,0 +1,47 @@
1
+ import type { TxHistoryEntry } from '../types'
2
+
3
+ export interface DayGroup {
4
+ /** Section header: "Today", "Yesterday", or e.g. "August 12, 2025". */
5
+ label: string
6
+ entries: TxHistoryEntry[]
7
+ }
8
+
9
+ /** Local-midnight day index for a timestamp — calendar-day identity. */
10
+ function dayKey(timestamp: number): string {
11
+ const d = new Date(timestamp)
12
+ return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`
13
+ }
14
+
15
+ function dayLabel(timestamp: number, now: number): string {
16
+ const key = dayKey(timestamp)
17
+ if (key === dayKey(now)) return 'Today'
18
+ if (key === dayKey(now - 24 * 60 * 60 * 1000)) return 'Yesterday'
19
+ return new Intl.DateTimeFormat('en-US', {
20
+ month: 'long',
21
+ day: 'numeric',
22
+ year: 'numeric',
23
+ }).format(new Date(timestamp))
24
+ }
25
+
26
+ /**
27
+ * Newest-first entries bucketed by local calendar day, ready to render as
28
+ * header + rows sections. `now` is injectable so tests (and midnight
29
+ * boundaries) are deterministic.
30
+ */
31
+ export function groupByDay(
32
+ entries: TxHistoryEntry[],
33
+ now: number = Date.now(),
34
+ ): DayGroup[] {
35
+ const sorted = [...entries].sort((a, b) => b.timestamp - a.timestamp)
36
+ const groups: DayGroup[] = []
37
+ let currentKey: string | null = null
38
+ for (const entry of sorted) {
39
+ const key = dayKey(entry.timestamp)
40
+ if (key !== currentKey) {
41
+ currentKey = key
42
+ groups.push({ label: dayLabel(entry.timestamp, now), entries: [] })
43
+ }
44
+ groups[groups.length - 1]?.entries.push(entry)
45
+ }
46
+ return groups
47
+ }
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export { ConnectWallet } from './auth'
8
8
  export { useAuth } from './auth/hooks/useAuth'
9
9
  export { SignUp } from './auth/pages/SignUp'
10
10
  export type { AuthMethod, AuthStep, EmailAuthMethod } from './auth/types'
11
+ export type { WalletId } from './auth/walletGuide'
11
12
 
12
13
  // Connector
13
14
  export type {
@@ -16,6 +17,14 @@ export type {
16
17
  } from './connector.js'
17
18
  export { zeroDevWallet } from './connector.js'
18
19
 
20
+ // History
21
+ export {
22
+ TxHistory,
23
+ type TxHistoryProps,
24
+ type TxHistoryStep,
25
+ } from './history/pages'
26
+ export type { TxHistoryEntry } from './history/types'
27
+
19
28
  // Signing
20
29
  // export type { SignatureRequestProps } from './signing'
21
30
  // export { SignatureRequest } from './signing'
@@ -0,0 +1,50 @@
1
+ import { cn, Text, Wrapper } from '@zerodev/react-ui'
2
+
3
+ export interface TokenSummaryProps {
4
+ /** Token logo URL, shown in the tile floating over the card's top edge.
5
+ * The tile renders empty (neutral background) when omitted. */
6
+ tokenLogoUrl?: string
7
+ /** Pre-formatted fiat value, e.g. `"+$170.27"`. */
8
+ fiatValue: string
9
+ /** Pre-formatted token amount, e.g. `"0.0652 ETH"`. */
10
+ cryptoAmount: string
11
+ className?: string
12
+ }
13
+
14
+ /**
15
+ * Portfolio-value hero (Figma "Portfolio Value", `15873:58532`): a card
16
+ * headed by a token logo tile that overhangs the top edge, with the fiat
17
+ * value large and the crypto amount beneath. The overhang headroom is part
18
+ * of the component, so consumers can stack it without clipping the tile.
19
+ */
20
+ export function TokenSummary({
21
+ tokenLogoUrl,
22
+ fiatValue,
23
+ cryptoAmount,
24
+ className,
25
+ }: TokenSummaryProps) {
26
+ return (
27
+ <div className={cn('zd:relative zd:w-full zd:pt-7', className)}>
28
+ <Wrapper
29
+ variant="ghost"
30
+ className="zd:flex zd:w-full zd:flex-col zd:items-center zd:gap-2 zd:rounded-2xl zd:px-2 zd:pt-16 zd:pb-2"
31
+ >
32
+ <Text className="zd:whitespace-nowrap zd:text-h1">{fiatValue}</Text>
33
+ <Text className="zd:whitespace-nowrap zd:text-center zd:text-h3">
34
+ {cryptoAmount}
35
+ </Text>
36
+ </Wrapper>
37
+ {/* Token tile — straddles the card's top edge, centred. */}
38
+ <div className="zd:absolute zd:top-0 zd:left-1/2 zd:flex zd:size-18.5 zd:-translate-x-1/2 zd:items-center zd:justify-center zd:rounded-3xl zd:border zd:border-white/20 zd:bg-offWhite/80 zd:backdrop-blur-[15px]">
39
+ {tokenLogoUrl && (
40
+ <img
41
+ src={tokenLogoUrl}
42
+ alt=""
43
+ aria-hidden
44
+ className="zd:size-10.5 zd:object-contain"
45
+ />
46
+ )}
47
+ </div>
48
+ </div>
49
+ )
50
+ }