@1001-digital/components 1.0.2 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1001-digital/components",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "*.css"
@@ -42,7 +42,7 @@
42
42
  :model-value="toast.progress === true ? null : toast.progress"
43
43
  />
44
44
  <ToastAction
45
- v-if="toast.action"
45
+ v-if="toast.action && !toast.action.persistent"
46
46
  :alt-text="toast.action.label"
47
47
  :as="Actions"
48
48
  class="left"
@@ -54,6 +54,17 @@
54
54
  {{ toast.action.label }}
55
55
  </Button>
56
56
  </ToastAction>
57
+ <Actions
58
+ v-if="toast.action?.persistent"
59
+ class="left"
60
+ >
61
+ <Button
62
+ class="small tertiary"
63
+ @click="toast.action!.onClick()"
64
+ >
65
+ {{ toast.action.label }}
66
+ </Button>
67
+ </Actions>
57
68
  </section>
58
69
  </ToastRoot>
59
70
 
@@ -3,6 +3,7 @@ import { ref } from 'vue'
3
3
  export interface ToastAction {
4
4
  label: string
5
5
  onClick: () => void
6
+ persistent?: boolean
6
7
  }
7
8
 
8
9
  export type ToastVariant = 'info' | 'success' | 'error'
@@ -0,0 +1,4 @@
1
+ <svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="1024" height="1024" fill="#0052FF"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M152 512C152 710.823 313.177 872 512 872C710.823 872 872 710.823 872 512C872 313.177 710.823 152 512 152C313.177 152 152 313.177 152 512ZM420 396C406.745 396 396 406.745 396 420V604C396 617.255 406.745 628 420 628H604C617.255 628 628 617.255 628 604V420C628 406.745 617.255 396 604 396H420Z" fill="white"/>
4
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="56" height="56" fill="#323232"/>
3
+ <path d="M35.5 31H35.515" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
4
+ <path d="M20.5 20.5H38.5C39.2956 20.5 40.0587 20.8161 40.6213 21.3787C41.1839 21.9413 41.5 22.7044 41.5 23.5V38.5C41.5 39.2956 41.1839 40.0587 40.6213 40.6213C40.0587 41.1839 39.2956 41.5 38.5 41.5H17.5C16.7044 41.5 15.9413 41.1839 15.3787 40.6213C14.8161 40.0587 14.5 39.2956 14.5 38.5V17.5C14.5 16.7044 14.8161 15.9413 15.3787 15.3787C15.9413 14.8161 16.7044 14.5 17.5 14.5H38.5" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
5
+ </svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" height="33" viewBox="0 0 35 33" width="35" xmlns="http://www.w3.org/2000/svg"><g stroke-linecap="round" stroke-linejoin="round" stroke-width=".25"><path d="m32.9582 1-13.1341 9.7183 2.4424-5.72731z" fill="#e17726" stroke="#e17726"/><g fill="#e27625" stroke="#e27625"><path d="m2.66296 1 13.01714 9.809-2.3254-5.81802z"/><path d="m28.2295 23.5335-3.4947 5.3386 7.4829 2.0603 2.1436-7.2823z"/><path d="m1.27281 23.6501 2.13055 7.2823 7.46994-2.0603-3.48166-5.3386z"/><path d="m10.4706 14.5149-2.0786 3.1358 7.405.3369-.2469-7.969z"/><path d="m25.1505 14.5149-5.1575-4.58704-.1688 8.05974 7.4049-.3369z"/><path d="m10.8733 28.8721 4.4819-2.1639-3.8583-3.0062z"/><path d="m20.2659 26.7082 4.4689 2.1639-.6105-5.1701z"/></g><path d="m24.7348 28.8721-4.469-2.1639.3638 2.9025-.039 1.231z" fill="#d5bfb2" stroke="#d5bfb2"/><path d="m10.8732 28.8721 4.1572 1.9696-.026-1.231.3508-2.9025z" fill="#d5bfb2" stroke="#d5bfb2"/><path d="m15.1084 21.7842-3.7155-1.0884 2.6243-1.2051z" fill="#233447" stroke="#233447"/><path d="m20.5126 21.7842 1.0913-2.2935 2.6372 1.2051z" fill="#233447" stroke="#233447"/><path d="m10.8733 28.8721.6495-5.3386-4.13117.1167z" fill="#cc6228" stroke="#cc6228"/><path d="m24.0982 23.5335.6366 5.3386 3.4946-5.2219z" fill="#cc6228" stroke="#cc6228"/><path d="m27.2291 17.6507-7.405.3369.6885 3.7966 1.0913-2.2935 2.6372 1.2051z" fill="#cc6228" stroke="#cc6228"/><path d="m11.3929 20.6958 2.6242-1.2051 1.0913 2.2935.6885-3.7966-7.40495-.3369z" fill="#cc6228" stroke="#cc6228"/><path d="m8.392 17.6507 3.1049 6.0513-.1039-3.0062z" fill="#e27525" stroke="#e27525"/><path d="m24.2412 20.6958-.1169 3.0062 3.1049-6.0513z" fill="#e27525" stroke="#e27525"/><path d="m15.797 17.9876-.6886 3.7967.8704 4.4833.1949-5.9087z" fill="#e27525" stroke="#e27525"/><path d="m19.8242 17.9876-.3638 2.3584.1819 5.9216.8704-4.4833z" fill="#e27525" stroke="#e27525"/><path d="m20.5127 21.7842-.8704 4.4834.6236.4406 3.8584-3.0062.1169-3.0062z" fill="#f5841f" stroke="#f5841f"/><path d="m11.3929 20.6958.104 3.0062 3.8583 3.0062.6236-.4406-.8704-4.4834z" fill="#f5841f" stroke="#f5841f"/><path d="m20.5906 30.8417.039-1.231-.3378-.2851h-4.9626l-.3248.2851.026 1.231-4.1572-1.9696 1.4551 1.1921 2.9489 2.0344h5.0536l2.962-2.0344 1.442-1.1921z" fill="#c0ac9d" stroke="#c0ac9d"/><path d="m20.2659 26.7082-.6236-.4406h-3.6635l-.6236.4406-.3508 2.9025.3248-.2851h4.9626l.3378.2851z" fill="#161616" stroke="#161616"/><path d="m33.5168 11.3532 1.1043-5.36447-1.6629-4.98873-12.6923 9.3944 4.8846 4.1205 6.8983 2.0085 1.52-1.7752-.6626-.4795 1.0523-.9588-.8054-.622 1.0523-.8034z" fill="#763e1a" stroke="#763e1a"/><path d="m1 5.98873 1.11724 5.36447-.71451.5313 1.06527.8034-.80545.622 1.05228.9588-.66255.4795 1.51997 1.7752 6.89835-2.0085 4.8846-4.1205-12.69233-9.3944z" fill="#763e1a" stroke="#763e1a"/><path d="m32.0489 16.5234-6.8983-2.0085 2.0786 3.1358-3.1049 6.0513 4.1052-.0519h6.1318z" fill="#f5841f" stroke="#f5841f"/><path d="m10.4705 14.5149-6.89828 2.0085-2.29944 7.1267h6.11883l4.10519.0519-3.10487-6.0513z" fill="#f5841f" stroke="#f5841f"/><path d="m19.8241 17.9876.4417-7.5932 2.0007-5.4034h-8.9119l2.0006 5.4034.4417 7.5932.1689 2.3842.013 5.8958h3.6635l.013-5.8958z" fill="#f5841f" stroke="#f5841f"/></g></svg>
@@ -0,0 +1,4 @@
1
+ <svg viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="128" height="128" fill="#AB9FF2"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M55.6416 82.1477C50.8744 89.4525 42.8862 98.6966 32.2568 98.6966C27.232 98.6966 22.4004 96.628 22.4004 87.6424C22.4004 64.7584 53.6445 29.3335 82.6339 29.3335C99.1257 29.3335 105.697 40.7755 105.697 53.7689C105.697 70.4471 94.8739 89.5171 84.1156 89.5171C80.7013 89.5171 79.0264 87.6424 79.0264 84.6688C79.0264 83.8931 79.1552 83.0527 79.4129 82.1477C75.7409 88.4182 68.6546 94.2361 62.0192 94.2361C57.1877 94.2361 54.7397 91.1979 54.7397 86.9314C54.7397 85.3799 55.0618 83.7638 55.6416 82.1477ZM80.6133 53.3182C80.6133 57.1044 78.3795 58.9975 75.8806 58.9975C73.3438 58.9975 71.1479 57.1044 71.1479 53.3182C71.1479 49.532 73.3438 47.6389 75.8806 47.6389C78.3795 47.6389 80.6133 49.532 80.6133 53.3182ZM94.8102 53.3184C94.8102 57.1046 92.5763 58.9977 90.0775 58.9977C87.5407 58.9977 85.3447 57.1046 85.3447 53.3184C85.3447 49.5323 87.5407 47.6392 90.0775 47.6392C92.5763 47.6392 94.8102 49.5323 94.8102 53.3184Z" fill="#FFFDF8"/>
4
+ </svg>
@@ -0,0 +1,24 @@
1
+ <svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M438.47 279.097C452.952 246.637 381.359 155.948 312.964 118.165C269.853 88.895 224.93 92.9162 215.832 105.768C195.865 133.972 281.948 157.871 339.518 185.759C327.143 191.152 315.481 200.83 308.623 213.207C287.16 189.697 240.052 169.451 184.777 185.759C147.528 196.749 116.571 222.658 104.606 261.791C101.699 260.495 98.4799 259.774 95.0934 259.774C82.1436 259.774 71.6456 270.308 71.6456 283.301C71.6456 296.295 82.1436 306.828 95.0934 306.828C97.4937 306.828 104.999 305.213 104.999 305.213L224.93 306.085C176.967 382.43 139.063 393.59 139.063 406.817C139.063 420.043 175.331 416.459 188.948 411.529C254.138 387.928 324.155 314.373 336.17 293.199C386.625 299.515 429.028 300.262 438.47 279.097Z" fill="url(#paint0_linear_1758_656)"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M339.513 185.763C339.516 185.764 339.519 185.766 339.522 185.767C342.191 184.712 341.759 180.758 341.026 177.652C339.342 170.515 310.284 141.724 282.997 128.829C245.815 111.257 218.435 112.163 214.39 120.262C221.964 135.837 257.077 150.461 293.748 165.733C309.394 172.249 325.323 178.883 339.519 185.76C339.517 185.761 339.515 185.762 339.513 185.763Z" fill="url(#paint1_linear_1758_656)"/>
4
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M292.329 342.523C284.809 339.64 276.315 336.994 266.658 334.594C276.955 316.108 279.115 288.74 269.391 271.437C255.743 247.153 238.612 234.228 198.802 234.228C176.907 234.228 117.955 241.628 116.909 291.006C116.799 296.187 116.906 300.935 117.28 305.301L224.93 306.084C210.417 329.185 196.825 346.318 184.926 359.345C199.213 363.019 211.003 366.103 221.828 368.934C232.098 371.62 241.499 374.079 251.339 376.598C266.182 365.748 280.135 353.917 292.329 342.523Z" fill="url(#paint2_linear_1758_656)"/>
5
+ <path d="M103.169 300.228C107.567 337.737 128.813 352.437 172.227 356.788C215.641 361.138 240.544 358.22 273.698 361.246C301.389 363.774 326.113 377.932 335.285 373.04C343.539 368.636 338.921 352.728 327.876 342.521C313.558 329.291 293.742 320.093 258.875 316.828C265.824 297.739 263.877 270.973 253.085 256.411C237.481 235.355 208.68 225.836 172.227 229.995C134.143 234.34 97.6504 253.153 103.169 300.228Z" fill="url(#paint3_linear_1758_656)"/>
6
+ <defs>
7
+ <linearGradient id="paint0_linear_1758_656" x1="180.439" y1="250.352" x2="435.479" y2="322.433" gradientUnits="userSpaceOnUse">
8
+ <stop stop-color="#8697FF"/>
9
+ <stop offset="1" stop-color="#ABB7FF"/>
10
+ </linearGradient>
11
+ <linearGradient id="paint1_linear_1758_656" x1="392.428" y1="245.489" x2="207.876" y2="61.1077" gradientUnits="userSpaceOnUse">
12
+ <stop stop-color="#8697FF"/>
13
+ <stop offset="1" stop-color="#5156D8" stop-opacity="0"/>
14
+ </linearGradient>
15
+ <linearGradient id="paint2_linear_1758_656" x1="297.446" y1="348.967" x2="120.465" y2="247.558" gradientUnits="userSpaceOnUse">
16
+ <stop stop-color="#465EED"/>
17
+ <stop offset="1" stop-color="#8697FF" stop-opacity="0"/>
18
+ </linearGradient>
19
+ <linearGradient id="paint3_linear_1758_656" x1="195.658" y1="248.443" x2="315.581" y2="400.306" gradientUnits="userSpaceOnUse">
20
+ <stop stop-color="#8898FF"/>
21
+ <stop offset="0.983895" stop-color="#6277F1"/>
22
+ </linearGradient>
23
+ </defs>
24
+ </svg>
@@ -0,0 +1,59 @@
1
+ <svg viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_8_458)">
3
+ <rect width="120" height="120" fill="url(#paint0_linear_8_458)"/>
4
+ <path d="M20 38H26C56.9279 38 82 63.0721 82 94V100H94C97.3137 100 100 97.3137 100 94C100 53.1309 66.8691 20 26 20C22.6863 20 20 22.6863 20 26V38Z" fill="url(#paint1_radial_8_458)"/>
5
+ <path d="M84 94H100C100 97.3137 97.3137 100 94 100H84V94Z" fill="url(#paint2_linear_8_458)"/>
6
+ <path d="M26 20L26 36H20L20 26C20 22.6863 22.6863 20 26 20Z" fill="url(#paint3_linear_8_458)"/>
7
+ <path d="M20 36H26C58.0325 36 84 61.9675 84 94V100H66V94C66 71.9086 48.0914 54 26 54H20V36Z" fill="url(#paint4_radial_8_458)"/>
8
+ <path d="M68 94H84V100H68V94Z" fill="url(#paint5_linear_8_458)"/>
9
+ <path d="M20 52L20 36L26 36L26 52H20Z" fill="url(#paint6_linear_8_458)"/>
10
+ <path d="M20 62C20 65.3137 22.6863 68 26 68C40.3594 68 52 79.6406 52 94C52 97.3137 54.6863 100 58 100H68V94C68 70.804 49.196 52 26 52H20V62Z" fill="url(#paint7_radial_8_458)"/>
11
+ <path d="M52 94H68V100H58C54.6863 100 52 97.3137 52 94Z" fill="url(#paint8_radial_8_458)"/>
12
+ <path d="M26 68C22.6863 68 20 65.3137 20 62L20 52L26 52L26 68Z" fill="url(#paint9_radial_8_458)"/>
13
+ </g>
14
+ <defs>
15
+ <linearGradient id="paint0_linear_8_458" x1="60" y1="0" x2="60" y2="120" gradientUnits="userSpaceOnUse">
16
+ <stop stop-color="#174299"/>
17
+ <stop offset="1" stop-color="#001E59"/>
18
+ </linearGradient>
19
+ <radialGradient id="paint1_radial_8_458" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(26 94) rotate(-90) scale(74)">
20
+ <stop offset="0.770277" stop-color="#FF4000"/>
21
+ <stop offset="1" stop-color="#8754C9"/>
22
+ </radialGradient>
23
+ <linearGradient id="paint2_linear_8_458" x1="83" y1="97" x2="100" y2="97" gradientUnits="userSpaceOnUse">
24
+ <stop stop-color="#FF4000"/>
25
+ <stop offset="1" stop-color="#8754C9"/>
26
+ </linearGradient>
27
+ <linearGradient id="paint3_linear_8_458" x1="23" y1="20" x2="23" y2="37" gradientUnits="userSpaceOnUse">
28
+ <stop stop-color="#8754C9"/>
29
+ <stop offset="1" stop-color="#FF4000"/>
30
+ </linearGradient>
31
+ <radialGradient id="paint4_radial_8_458" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(26 94) rotate(-90) scale(58)">
32
+ <stop offset="0.723929" stop-color="#FFF700"/>
33
+ <stop offset="1" stop-color="#FF9901"/>
34
+ </radialGradient>
35
+ <linearGradient id="paint5_linear_8_458" x1="68" y1="97" x2="84" y2="97" gradientUnits="userSpaceOnUse">
36
+ <stop stop-color="#FFF700"/>
37
+ <stop offset="1" stop-color="#FF9901"/>
38
+ </linearGradient>
39
+ <linearGradient id="paint6_linear_8_458" x1="23" y1="52" x2="23" y2="36" gradientUnits="userSpaceOnUse">
40
+ <stop stop-color="#FFF700"/>
41
+ <stop offset="1" stop-color="#FF9901"/>
42
+ </linearGradient>
43
+ <radialGradient id="paint7_radial_8_458" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(26 94) rotate(-90) scale(42)">
44
+ <stop offset="0.59513" stop-color="#00AAFF"/>
45
+ <stop offset="1" stop-color="#01DA40"/>
46
+ </radialGradient>
47
+ <radialGradient id="paint8_radial_8_458" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(51 97) scale(17 45.3333)">
48
+ <stop stop-color="#00AAFF"/>
49
+ <stop offset="1" stop-color="#01DA40"/>
50
+ </radialGradient>
51
+ <radialGradient id="paint9_radial_8_458" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(23 69) rotate(-90) scale(17 322.37)">
52
+ <stop stop-color="#00AAFF"/>
53
+ <stop offset="1" stop-color="#01DA40"/>
54
+ </radialGradient>
55
+ <clipPath id="clip0_8_458">
56
+ <rect width="120" height="120" fill="white"/>
57
+ </clipPath>
58
+ </defs>
59
+ </svg>
Binary file
@@ -0,0 +1 @@
1
+ <svg fill="none" height="400" viewBox="0 0 400 400" width="400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m0 0h400v400h-400z"/></clipPath><g clip-path="url(#a)"><circle cx="200" cy="200" fill="#3396ff" r="199.5" stroke="#66b1ff"/><path d="m122.519 148.965c42.791-41.729 112.171-41.729 154.962 0l5.15 5.022c2.14 2.086 2.14 5.469 0 7.555l-17.617 17.18c-1.07 1.043-2.804 1.043-3.874 0l-7.087-6.911c-29.853-29.111-78.253-29.111-108.106 0l-7.59 7.401c-1.07 1.043-2.804 1.043-3.874 0l-17.617-17.18c-2.14-2.086-2.14-5.469 0-7.555zm191.397 35.529 15.679 15.29c2.14 2.086 2.14 5.469 0 7.555l-70.7 68.944c-2.139 2.087-5.608 2.087-7.748 0l-50.178-48.931c-.535-.522-1.402-.522-1.937 0l-50.178 48.931c-2.139 2.087-5.608 2.087-7.748 0l-70.7015-68.945c-2.1396-2.086-2.1396-5.469 0-7.555l15.6795-15.29c2.1396-2.086 5.6085-2.086 7.7481 0l50.1789 48.932c.535.522 1.402.522 1.937 0l50.177-48.932c2.139-2.087 5.608-2.087 7.748 0l50.179 48.932c.535.522 1.402.522 1.937 0l50.179-48.931c2.139-2.087 5.608-2.087 7.748 0z" fill="#fff"/></g></svg>
@@ -20,8 +20,13 @@
20
20
  v-model:open="chooseModalOpen"
21
21
  @closed="onModalClosed"
22
22
  >
23
+ <EvmInAppWalletSetup
24
+ v-if="showInAppSetup"
25
+ @connected="onInAppConnected"
26
+ @back="showInAppSetup = false"
27
+ />
23
28
  <Alert
24
- v-if="errorMessage"
29
+ v-else-if="errorMessage"
25
30
  type="error"
26
31
  >
27
32
  {{ errorMessage }}
@@ -52,10 +57,8 @@
52
57
  class="choose-connector"
53
58
  >
54
59
  <img
55
- v-if="ICONS[connector.name]"
56
- :src="
57
- connector.icon || `${base}icons/wallets/${ICONS[connector.name]}`
58
- "
60
+ v-if="ICONS[connector.name] || connector.icon"
61
+ :src="ICONS[connector.name] || connector.icon"
59
62
  :alt="connector.name"
60
63
  />
61
64
  <div
@@ -72,11 +75,22 @@
72
75
  class="choose-connector"
73
76
  >
74
77
  <img
75
- :src="`${base}icons/wallets/safe.png`"
78
+ :src="safeIcon"
76
79
  alt="Safe"
77
80
  />
78
81
  <span>Safe</span>
79
82
  </Button>
83
+ <Button
84
+ v-if="inAppConnector"
85
+ @click="showInAppSetup = true"
86
+ class="choose-connector"
87
+ >
88
+ <img
89
+ :src="inAppIcon"
90
+ alt="Seed Phrase"
91
+ />
92
+ <span>In App</span>
93
+ </Button>
80
94
  <Button
81
95
  to="https://ethereum.org/wallets/"
82
96
  target="_blank"
@@ -106,16 +120,26 @@ import Loading from '../../base/components/Loading.vue'
106
120
  import EvmAccount from './EvmAccount.vue'
107
121
  import EvmMetaMaskQR from './EvmMetaMaskQR.vue'
108
122
  import EvmWalletConnectWallets from './EvmWalletConnectWallets.vue'
109
- import { useBaseURL } from '../composables/base'
123
+ import EvmInAppWalletSetup from './EvmInAppWalletSetup.vue'
124
+
125
+ import coinbaseIcon from '../assets/wallets/coinbase.svg'
126
+ import metamaskIcon from '../assets/wallets/metamask.svg'
127
+ import phantomIcon from '../assets/wallets/phantom.svg'
128
+ import rabbyIcon from '../assets/wallets/rabby.svg'
129
+ import rainbowIcon from '../assets/wallets/rainbow.svg'
130
+ import safeIcon from '../assets/wallets/safe.png'
131
+ import inAppIcon from '../assets/wallets/in-app.svg'
132
+ import walletconnectIcon from '../assets/wallets/walletconnect.svg'
110
133
 
111
134
  const ICONS: Record<string, string> = {
112
- 'Base Account': 'coinbase.svg',
113
- MetaMask: 'metamask.svg',
114
- Phantom: 'phantom.svg',
115
- 'Rabby Wallet': 'rabby.svg',
116
- Rainbow: 'rainbow.svg',
117
- Safe: 'safe.png',
118
- WalletConnect: 'walletconnect.svg',
135
+ 'Base Account': coinbaseIcon,
136
+ MetaMask: metamaskIcon,
137
+ Phantom: phantomIcon,
138
+ 'Rabby Wallet': rabbyIcon,
139
+ Rainbow: rainbowIcon,
140
+ Safe: safeIcon,
141
+ 'In App': inAppIcon,
142
+ WalletConnect: walletconnectIcon,
119
143
  }
120
144
 
121
145
  const PRIORITY: Record<string, number> = {
@@ -130,13 +154,16 @@ const emit = defineEmits<{
130
154
  connected: [{ address: `0x${string}` | undefined }]
131
155
  disconnected: []
132
156
  }>()
133
- const base = useBaseURL()
134
-
135
157
  const chainId = useChainId()
136
158
  const connectors = useConnectors()
137
159
  const { mutateAsync: connectAsync } = useConnect()
138
160
  const { address, isConnected } = useConnection()
139
161
 
162
+ const inAppConnector = computed(() =>
163
+ connectors.value.find((c) => c.type === 'inAppWallet'),
164
+ )
165
+ const showInAppSetup = ref(false)
166
+
140
167
  const showConnect = computed(() => !isConnected.value)
141
168
  const shownConnectors = computed(() => {
142
169
  const unique = Array.from(
@@ -147,8 +174,11 @@ const shownConnectors = computed(() => {
147
174
 
148
175
  const filtered =
149
176
  unique.length > 1
150
- ? unique.filter((c) => c.id !== 'injected' && c.id !== 'safe')
151
- : unique
177
+ ? unique.filter(
178
+ (c) =>
179
+ c.id !== 'injected' && c.id !== 'safe' && c.type !== 'inAppWallet',
180
+ )
181
+ : unique.filter((c) => c.type !== 'inAppWallet')
152
182
 
153
183
  return filtered.sort((a, b) => {
154
184
  const priorityA = PRIORITY[a.name] ?? 5
@@ -247,6 +277,11 @@ const login = async (connector: Connector) => {
247
277
  }
248
278
  }
249
279
 
280
+ const onInAppConnected = () => {
281
+ chooseModalOpen.value = false
282
+ showInAppSetup.value = false
283
+ }
284
+
250
285
  const onModalClosed = () => {
251
286
  errorMessage.value = ''
252
287
  isConnecting.value = false
@@ -254,6 +289,7 @@ const onModalClosed = () => {
254
289
  metaMaskUri.value = ''
255
290
  walletConnectUri.value = ''
256
291
  safeDeepLink.value = false
292
+ showInAppSetup.value = false
257
293
  }
258
294
 
259
295
  const check = () =>
@@ -276,6 +312,7 @@ onMounted(() => check())
276
312
  width: 100%;
277
313
  inline-size: auto;
278
314
  justify-content: flex-start;
315
+ padding-inline-start: var(--ui-padding-inline);
279
316
 
280
317
  img,
281
318
  .default-wallet-icon {
@@ -0,0 +1,238 @@
1
+ <template>
2
+ <div class="in-app-wallet-setup">
3
+ <!-- Step: Choose -->
4
+ <div
5
+ v-if="step === 'choose'"
6
+ class="setup-step"
7
+ >
8
+ <div class="setup-options">
9
+ <Button @click="startGenerate">
10
+ <Icon type="plus" />
11
+ <span>Create New Wallet</span>
12
+ </Button>
13
+ <Button @click="step = 'restore'">
14
+ <Icon type="key" />
15
+ <span>I Have a Seed Phrase</span>
16
+ </Button>
17
+ </div>
18
+ <Button
19
+ class="link muted small"
20
+ @click="$emit('back')"
21
+ >
22
+ <Icon type="arrow-left" />
23
+ <span>Back</span>
24
+ </Button>
25
+ </div>
26
+
27
+ <!-- Step: Generate -->
28
+ <div
29
+ v-else-if="step === 'generate'"
30
+ class="setup-step"
31
+ >
32
+ <Alert type="info">
33
+ Write down these 12 words in order. You will need them to restore your wallet. They will not be shown again.
34
+ </Alert>
35
+
36
+ <div class="generated-words">
37
+ <div
38
+ v-for="(word, i) in generatedWords"
39
+ :key="i"
40
+ class="generated-word"
41
+ >
42
+ <span class="word-number">{{ i + 1 }}</span>
43
+ <span class="word-text">{{ word }}</span>
44
+ </div>
45
+ </div>
46
+
47
+ <FormCheckbox v-model="backupConfirmed">
48
+ I've saved my seed phrase
49
+ </FormCheckbox>
50
+
51
+ <Button
52
+ :disabled="!backupConfirmed"
53
+ @click="confirmGenerated"
54
+ >
55
+ Continue
56
+ </Button>
57
+ <Button
58
+ class="link muted small"
59
+ @click="step = 'choose'"
60
+ >
61
+ <Icon type="arrow-left" />
62
+ <span>Back</span>
63
+ </Button>
64
+ </div>
65
+
66
+ <!-- Step: Restore -->
67
+ <div
68
+ v-else-if="step === 'restore'"
69
+ class="setup-step"
70
+ >
71
+ <p class="muted font-sm">Enter your 12-word seed phrase to restore your wallet.</p>
72
+
73
+ <EvmSeedPhraseInput
74
+ v-model="restorePhrase"
75
+ @valid="restoreValid = $event"
76
+ @submit="restoreWallet"
77
+ />
78
+
79
+ <Button
80
+ :disabled="!restoreValid"
81
+ @click="restoreWallet"
82
+ >
83
+ Restore Wallet
84
+ </Button>
85
+ <Button
86
+ class="link muted small"
87
+ @click="step = 'choose'"
88
+ >
89
+ <Icon type="arrow-left" />
90
+ <span>Back</span>
91
+ </Button>
92
+ </div>
93
+
94
+ <!-- Step: Connecting -->
95
+ <div
96
+ v-else-if="step === 'connecting'"
97
+ class="setup-step"
98
+ >
99
+ <Loading
100
+ txt="Connecting wallet..."
101
+ spinner
102
+ stacked
103
+ />
104
+ </div>
105
+ </div>
106
+ </template>
107
+
108
+ <script setup lang="ts">
109
+ import { ref, computed } from 'vue'
110
+ import { useConnect, useConnectors } from '@wagmi/vue'
111
+ import Button from '../../base/components/Button.vue'
112
+ import Icon from '../../base/components/Icon.vue'
113
+ import Alert from '../../base/components/Alert.vue'
114
+ import FormCheckbox from '../../base/components/FormCheckbox.vue'
115
+ import Loading from '../../base/components/Loading.vue'
116
+ import EvmSeedPhraseInput from './EvmSeedPhraseInput.vue'
117
+ import { prepareInAppWallet } from '../connectors/inAppWallet'
118
+
119
+ const emit = defineEmits<{
120
+ connected: []
121
+ back: []
122
+ }>()
123
+
124
+ const connectors = useConnectors()
125
+ const { mutateAsync: connectAsync } = useConnect()
126
+ const inAppConnector = computed(() =>
127
+ connectors.value.find((c) => c.type === 'inAppWallet'),
128
+ )
129
+
130
+ type Step = 'choose' | 'generate' | 'restore' | 'connecting'
131
+ const step = ref<Step>('choose')
132
+
133
+ // Generate state
134
+ const generatedMnemonic = ref('')
135
+ const generatedWords = ref<string[]>([])
136
+ const backupConfirmed = ref(false)
137
+
138
+ // Restore state
139
+ const restorePhrase = ref('')
140
+ const restoreValid = ref(false)
141
+
142
+ async function startGenerate() {
143
+ const { generateMnemonic, english } = await import('viem/accounts')
144
+ generatedMnemonic.value = generateMnemonic(english)
145
+ generatedWords.value = generatedMnemonic.value.split(' ')
146
+ backupConfirmed.value = false
147
+ step.value = 'generate'
148
+ }
149
+
150
+ async function connectWithMnemonic(mnemonic: string) {
151
+ await prepareInAppWallet(mnemonic)
152
+ await connectAsync({ connector: inAppConnector.value! })
153
+ }
154
+
155
+ async function confirmGenerated() {
156
+ step.value = 'connecting'
157
+ try {
158
+ await connectWithMnemonic(generatedMnemonic.value)
159
+ emit('connected')
160
+ } catch (e) {
161
+ console.error('Failed to connect in-app wallet:', e)
162
+ step.value = 'generate'
163
+ }
164
+ }
165
+
166
+ async function restoreWallet() {
167
+ if (!restoreValid.value) return
168
+ step.value = 'connecting'
169
+ try {
170
+ await connectWithMnemonic(restorePhrase.value)
171
+ emit('connected')
172
+ } catch (e) {
173
+ console.error('Failed to restore in-app wallet:', e)
174
+ step.value = 'restore'
175
+ }
176
+ }
177
+ </script>
178
+
179
+ <style scoped>
180
+ .in-app-wallet-setup {
181
+ display: grid;
182
+ gap: var(--spacer);
183
+ }
184
+
185
+ .setup-step {
186
+ display: grid;
187
+ gap: var(--spacer);
188
+ }
189
+
190
+ .setup-options {
191
+ display: grid;
192
+ gap: var(--spacer);
193
+
194
+ :deep(button),
195
+ :deep(.button) {
196
+ width: 100%;
197
+ }
198
+ }
199
+
200
+ .generated-words {
201
+ display: grid;
202
+ grid-template-columns: repeat(3, 1fr);
203
+ gap: var(--spacer-sm);
204
+ }
205
+
206
+ @media (min-width: 600px) {
207
+ .generated-words {
208
+ grid-template-columns: repeat(4, 1fr);
209
+ }
210
+ }
211
+
212
+ .generated-word {
213
+ display: flex;
214
+ align-items: center;
215
+ gap: var(--spacer-xs);
216
+ border: var(--border);
217
+ border-radius: var(--border-radius);
218
+ padding: var(--spacer-xs) var(--spacer-sm);
219
+
220
+ .word-number {
221
+ font-size: var(--font-xs);
222
+ color: var(--muted);
223
+ min-width: 1.5em;
224
+ text-align: right;
225
+ }
226
+
227
+ .word-text {
228
+ font-size: var(--font-sm);
229
+ font-family: var(--font-mono, monospace);
230
+ }
231
+ }
232
+
233
+ .link.muted {
234
+ justify-self: center;
235
+ font-size: var(--font-xs);
236
+ }
237
+
238
+ </style>
@@ -0,0 +1,196 @@
1
+ <template>
2
+ <div class="seed-phrase-input">
3
+ <div class="seed-phrase-grid">
4
+ <div
5
+ v-for="(_, i) in 12"
6
+ :key="i"
7
+ class="seed-word"
8
+ :class="{ invalid: words[i] && !isValidWord(words[i]) }"
9
+ >
10
+ <label :for="`seed-word-${i}`">{{ i + 1 }}</label>
11
+ <input
12
+ :id="`seed-word-${i}`"
13
+ :ref="(el) => { if (el) inputRefs[i] = el as HTMLInputElement }"
14
+ v-model="words[i]"
15
+ type="text"
16
+ autocomplete="off"
17
+ autocapitalize="none"
18
+ spellcheck="false"
19
+ :disabled="disabled"
20
+ @keydown="onKeydown($event, i)"
21
+ @paste="onPaste($event, i)"
22
+ @input="onInput(i)"
23
+ />
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script setup lang="ts">
30
+ import { ref, watch, computed, onMounted } from 'vue'
31
+ import { english } from 'viem/accounts'
32
+
33
+ const props = defineProps<{
34
+ modelValue?: string
35
+ disabled?: boolean
36
+ }>()
37
+
38
+ const emit = defineEmits<{
39
+ 'update:modelValue': [value: string]
40
+ valid: [isValid: boolean]
41
+ submit: []
42
+ }>()
43
+
44
+ const wordSet = new Set(english)
45
+
46
+ const words = ref<string[]>(Array.from({ length: 12 }, () => ''))
47
+ const inputRefs = ref<HTMLInputElement[]>([])
48
+
49
+ function isValidWord(word: string): boolean {
50
+ return wordSet.has(word.trim().toLowerCase())
51
+ }
52
+
53
+ const isValid = computed(() =>
54
+ words.value.every((w) => w.trim() !== '' && isValidWord(w)),
55
+ )
56
+
57
+ const phrase = computed(() =>
58
+ words.value
59
+ .map((w) => w.trim().toLowerCase())
60
+ .join(' '),
61
+ )
62
+
63
+ watch(
64
+ () => props.modelValue,
65
+ (val) => {
66
+ if (!val) return
67
+ const incoming = val.trim().split(/\s+/)
68
+ if (incoming.length === 12) {
69
+ for (let i = 0; i < 12; i++) {
70
+ words.value[i] = incoming[i]
71
+ }
72
+ }
73
+ },
74
+ { immediate: true },
75
+ )
76
+
77
+ watch(phrase, (val) => {
78
+ emit('update:modelValue', val)
79
+ })
80
+
81
+ watch(isValid, (val) => {
82
+ emit('valid', val)
83
+ })
84
+
85
+ function focusInput(index: number) {
86
+ const el = inputRefs.value[index]
87
+ if (el) {
88
+ el.focus()
89
+ el.select()
90
+ }
91
+ }
92
+
93
+ function onKeydown(event: KeyboardEvent, index: number) {
94
+ if (event.key === ' ' || (event.key === 'Enter' && index < 11)) {
95
+ event.preventDefault()
96
+ focusInput(index + 1)
97
+ } else if (event.key === 'Enter' && index === 11 && isValid.value) {
98
+ event.preventDefault()
99
+ emit('submit')
100
+ } else if (
101
+ event.key === 'Backspace' &&
102
+ words.value[index] === '' &&
103
+ index > 0
104
+ ) {
105
+ event.preventDefault()
106
+ focusInput(index - 1)
107
+ } else if (event.key === 'Tab' && !event.shiftKey && index === 11) {
108
+ // Allow natural tab out
109
+ } else if (event.key === 'Tab' && event.shiftKey && index === 0) {
110
+ // Allow natural tab out
111
+ }
112
+ }
113
+
114
+ function onPaste(event: ClipboardEvent, index: number) {
115
+ const text = event.clipboardData?.getData('text')
116
+ if (!text) return
117
+
118
+ const pasted = text.trim().split(/\s+/)
119
+ if (pasted.length > 1) {
120
+ event.preventDefault()
121
+ for (let i = 0; i < pasted.length && index + i < 12; i++) {
122
+ words.value[index + i] = pasted[i].toLowerCase()
123
+ }
124
+ const nextIndex = Math.min(index + pasted.length, 11)
125
+ focusInput(nextIndex)
126
+ }
127
+ }
128
+
129
+ function onInput(index: number) {
130
+ // Auto-advance if the word contains a space (mobile autocomplete)
131
+ const val = words.value[index]
132
+ if (val.includes(' ')) {
133
+ const parts = val.trim().split(/\s+/)
134
+ words.value[index] = parts[0]
135
+ if (parts.length > 1 && index < 11) {
136
+ for (let i = 1; i < parts.length && index + i < 12; i++) {
137
+ words.value[index + i] = parts[i]
138
+ }
139
+ focusInput(Math.min(index + parts.length, 11))
140
+ }
141
+ }
142
+ }
143
+
144
+ onMounted(() => {
145
+ if (!props.disabled) {
146
+ focusInput(0)
147
+ }
148
+ })
149
+ </script>
150
+
151
+ <style scoped>
152
+ .seed-phrase-grid {
153
+ display: grid;
154
+ grid-template-columns: repeat(3, 1fr);
155
+ gap: var(--spacer-sm);
156
+ }
157
+
158
+ @media (min-width: 600px) {
159
+ .seed-phrase-grid {
160
+ grid-template-columns: repeat(4, 1fr);
161
+ }
162
+ }
163
+
164
+ .seed-word {
165
+ display: flex;
166
+ align-items: center;
167
+ gap: var(--spacer-xs);
168
+ border: var(--border);
169
+ border-radius: var(--border-radius);
170
+ padding: var(--spacer-xs) var(--spacer-sm);
171
+ transition: border-color var(--speed);
172
+
173
+ &:focus-within {
174
+ border-color: var(--accent);
175
+ }
176
+
177
+ &.invalid {
178
+ border-color: var(--error);
179
+ }
180
+
181
+ label {
182
+ font-size: var(--font-xs);
183
+ color: var(--muted);
184
+ min-width: 1.5em;
185
+ text-align: right;
186
+ user-select: none;
187
+ }
188
+
189
+ input {
190
+ all: unset;
191
+ width: 100%;
192
+ font-size: var(--font-sm);
193
+ font-family: var(--font-mono, monospace);
194
+ }
195
+ }
196
+ </style>
@@ -261,6 +261,7 @@ const initializeRequest = async (request = cachedRequest.value) => {
261
261
  action: {
262
262
  label: 'View on Block Explorer',
263
263
  onClick: () => window.open(link, '_blank'),
264
+ persistent: true,
264
265
  },
265
266
  })
266
267
 
@@ -0,0 +1,220 @@
1
+ import { createConnector } from '@wagmi/core'
2
+ import {
3
+ type Address,
4
+ type Hex,
5
+ createPublicClient,
6
+ createWalletClient,
7
+ custom,
8
+ getAddress,
9
+ hexToBigInt,
10
+ hexToNumber,
11
+ http,
12
+ numberToHex,
13
+ } from 'viem'
14
+ import { privateKeyToAccount, type PrivateKeyAccount } from 'viem/accounts'
15
+
16
+ const STORAGE_KEY = 'evm:in-app-wallet-pk'
17
+
18
+ /**
19
+ * Derive a private key from a BIP39 mnemonic and store it in localStorage.
20
+ * Call this before `connectAsync({ connector })`.
21
+ */
22
+ export async function prepareInAppWallet(mnemonic: string): Promise<Address> {
23
+ const { mnemonicToAccount } = await import('viem/accounts')
24
+ const { bytesToHex } = await import('viem')
25
+
26
+ const normalized = mnemonic.trim().toLowerCase().replace(/\s+/g, ' ')
27
+ const hdAccount = mnemonicToAccount(normalized)
28
+ const hdKey = hdAccount.getHdKey()
29
+ const pk = bytesToHex(hdKey.privateKey!) as `0x${string}`
30
+
31
+ localStorage.setItem(STORAGE_KEY, pk)
32
+ return hdAccount.address
33
+ }
34
+
35
+ export type InAppWalletParameters = {
36
+ storageKey?: string
37
+ }
38
+
39
+ inAppWallet.type = 'inAppWallet' as const
40
+
41
+ export function inAppWallet(parameters: InAppWalletParameters = {}) {
42
+ const key = parameters.storageKey ?? STORAGE_KEY
43
+
44
+ type Provider =
45
+ ReturnType<typeof custom> extends (...args: infer A) => infer R ? R : never
46
+
47
+ return createConnector<Provider>((config) => {
48
+ let account: PrivateKeyAccount | null = null
49
+ let currentChainId: number = config.chains[0].id
50
+
51
+ function loadAccount(): PrivateKeyAccount | null {
52
+ if (typeof window === 'undefined') return null
53
+ try {
54
+ const stored = localStorage.getItem(key)
55
+ if (stored?.startsWith('0x')) {
56
+ account = privateKeyToAccount(stored as `0x${string}`)
57
+ return account
58
+ }
59
+ } catch {}
60
+ return null
61
+ }
62
+
63
+ function getChain(chainId?: number) {
64
+ return (
65
+ config.chains.find((c) => c.id === (chainId ?? currentChainId)) ??
66
+ config.chains[0]
67
+ )
68
+ }
69
+
70
+ return {
71
+ id: 'inAppWallet',
72
+ name: 'In App',
73
+ type: inAppWallet.type,
74
+
75
+ async connect({ chainId } = {}) {
76
+ const acct = account ?? loadAccount()
77
+ if (!acct) throw new Error('No in-app wallet key found in storage')
78
+
79
+ if (chainId) currentChainId = chainId
80
+
81
+ return {
82
+ accounts: [getAddress(acct.address)],
83
+ chainId: currentChainId,
84
+ }
85
+ },
86
+
87
+ async disconnect() {
88
+ account = null
89
+ if (typeof window !== 'undefined') {
90
+ localStorage.removeItem(key)
91
+ }
92
+ },
93
+
94
+ async getAccounts() {
95
+ const acct = account ?? loadAccount()
96
+ return acct ? [getAddress(acct.address)] : []
97
+ },
98
+
99
+ async getChainId() {
100
+ return currentChainId
101
+ },
102
+
103
+ async getProvider() {
104
+ const chain = getChain()
105
+ const transport = config.transports?.[chain.id] ?? http()
106
+
107
+ const request = async ({
108
+ method,
109
+ params,
110
+ }: {
111
+ method: string
112
+ params?: unknown[]
113
+ }): Promise<unknown> => {
114
+ // Account methods
115
+ if (method === 'eth_accounts' || method === 'eth_requestAccounts') {
116
+ return account ? [account.address] : []
117
+ }
118
+ if (method === 'eth_chainId') {
119
+ return numberToHex(currentChainId)
120
+ }
121
+
122
+ // Signing methods — handled locally
123
+ if (method === 'personal_sign') {
124
+ if (!account) throw new Error('Not connected')
125
+ const [data] = params as [Hex, Address]
126
+ return account.signMessage({ message: { raw: data } })
127
+ }
128
+ if (method === 'eth_signTypedData_v4') {
129
+ if (!account) throw new Error('Not connected')
130
+ const [, typedDataJson] = params as [Address, string]
131
+ const typedData = JSON.parse(typedDataJson)
132
+ return account.signTypedData(typedData)
133
+ }
134
+ if (method === 'eth_sign') {
135
+ if (!account) throw new Error('Not connected')
136
+ const [, data] = params as [Address, Hex]
137
+ return account.sign!({ hash: data })
138
+ }
139
+
140
+ // Send transaction — sign locally, broadcast via RPC
141
+ if (method === 'eth_sendTransaction') {
142
+ if (!account) throw new Error('Not connected')
143
+ const [tx] = params as [Record<string, string>]
144
+ const walletClient = createWalletClient({
145
+ account,
146
+ chain,
147
+ transport,
148
+ })
149
+ return walletClient.sendTransaction({
150
+ chain,
151
+ to: tx.to as Address,
152
+ data: tx.data as Hex | undefined,
153
+ value: tx.value ? hexToBigInt(tx.value as Hex) : undefined,
154
+ gas: tx.gas ? hexToBigInt(tx.gas as Hex) : undefined,
155
+ nonce:
156
+ tx.nonce != null ? hexToNumber(tx.nonce as Hex) : undefined,
157
+ })
158
+ }
159
+
160
+ // Chain switching
161
+ if (method === 'wallet_switchEthereumChain') {
162
+ const [{ chainId: hexChainId }] = params as [
163
+ { chainId: `0x${string}` },
164
+ ]
165
+ const newChainId = hexToNumber(hexChainId)
166
+ const chain = config.chains.find((c) => c.id === newChainId)
167
+ if (!chain) throw new Error('Chain not configured')
168
+ currentChainId = newChainId
169
+ config.emitter.emit('change', { chainId: newChainId })
170
+ return null
171
+ }
172
+
173
+ // Everything else — forward to RPC
174
+ const publicClient = createPublicClient({ chain, transport })
175
+ return (
176
+ publicClient as unknown as {
177
+ request: (args: {
178
+ method: string
179
+ params?: unknown[]
180
+ }) => Promise<unknown>
181
+ }
182
+ ).request({ method, params: params as unknown[] })
183
+ }
184
+
185
+ return custom({ request })({ retryCount: 0 })
186
+ },
187
+
188
+ async isAuthorized() {
189
+ const acct = account ?? loadAccount()
190
+ return !!acct
191
+ },
192
+
193
+ async switchChain({ chainId }) {
194
+ const chain = config.chains.find((c) => c.id === chainId)
195
+ if (!chain) throw new Error('Chain not configured')
196
+ currentChainId = chainId
197
+ config.emitter.emit('change', { chainId })
198
+ return chain
199
+ },
200
+
201
+ onAccountsChanged(accounts) {
202
+ if (accounts.length === 0) this.onDisconnect()
203
+ else
204
+ config.emitter.emit('change', {
205
+ accounts: accounts.map((a) => getAddress(a)),
206
+ })
207
+ },
208
+
209
+ onChainChanged(chain) {
210
+ const chainId = Number(chain)
211
+ config.emitter.emit('change', { chainId })
212
+ },
213
+
214
+ onDisconnect() {
215
+ config.emitter.emit('disconnect')
216
+ account = null
217
+ },
218
+ }
219
+ })
220
+ }
package/src/evm/index.ts CHANGED
@@ -34,6 +34,9 @@ export { usePriceFeed } from './composables/priceFeed'
34
34
  export { useWalletExplorer } from './composables/walletExplorer'
35
35
  export type { ExplorerWallet } from './composables/walletExplorer'
36
36
 
37
+ // Connectors
38
+ export { inAppWallet, prepareInAppWallet } from './connectors/inAppWallet'
39
+
37
40
  // Components
38
41
  export { default as EvmAccount } from './components/EvmAccount.vue'
39
42
  export { default as EvmAvatar } from './components/EvmAvatar.vue'
@@ -45,3 +48,5 @@ export { default as EvmMetaMaskQR } from './components/EvmMetaMaskQR.vue'
45
48
  export { default as EvmWalletConnectQR } from './components/EvmWalletConnectQR.vue'
46
49
  export { default as EvmWalletConnectWallets } from './components/EvmWalletConnectWallets.vue'
47
50
  export { default as EvmTransactionFlow } from './components/EvmTransactionFlow.vue'
51
+ export { default as EvmSeedPhraseInput } from './components/EvmSeedPhraseInput.vue'
52
+ export { default as EvmInAppWalletSetup } from './components/EvmInAppWalletSetup.vue'