@sei-js/create-sei 0.0.3 → 1.0.0

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 (228) hide show
  1. package/.rsyncignore +13 -0
  2. package/CHANGELOG.md +12 -0
  3. package/dist/extensions/precompiles/package.json +44 -0
  4. package/dist/extensions/precompiles/src/components/default/index.tsx +201 -0
  5. package/dist/main.js +46 -78
  6. package/dist/main.test.js +34 -0
  7. package/dist/templates/next-template/.env.example +8 -0
  8. package/dist/templates/next-template/.nvmrc +1 -0
  9. package/dist/templates/next-template/biome.json +48 -0
  10. package/{templates/next-cosmos-template → dist/templates/next-template}/next-env.d.ts +1 -1
  11. package/dist/templates/next-template/package.json +44 -0
  12. package/dist/templates/next-template/postcss.config.mjs +6 -0
  13. package/dist/templates/next-template/src/app/development/page.tsx +260 -0
  14. package/dist/templates/next-template/src/app/globals.css +14 -0
  15. package/dist/templates/next-template/src/app/layout.tsx +30 -0
  16. package/dist/templates/next-template/src/app/page.tsx +10 -0
  17. package/dist/templates/next-template/src/app/resources/page.tsx +175 -0
  18. package/dist/templates/next-template/src/app/resources/resources.ts +56 -0
  19. package/dist/templates/next-template/src/components/default/examples.ts +63 -0
  20. package/dist/templates/next-template/src/components/default/index.tsx +402 -0
  21. package/dist/templates/next-template/src/components/index.ts +3 -0
  22. package/dist/templates/next-template/src/components/landing/index.tsx +107 -0
  23. package/dist/templates/next-template/src/components/providers/index.ts +1 -0
  24. package/dist/templates/next-template/src/components/providers/providers.tsx +89 -0
  25. package/dist/templates/next-template/src/components/shell/index.ts +1 -0
  26. package/dist/templates/next-template/src/components/shell/shell.tsx +87 -0
  27. package/dist/templates/next-template/tailwind.config.js +17 -0
  28. package/{templates/next-cosmos-template → dist/templates/next-template}/tsconfig.json +2 -1
  29. package/extensions/precompiles/package.json +44 -0
  30. package/extensions/precompiles/src/components/default/index.tsx +201 -0
  31. package/jest.config.js +14 -0
  32. package/package.json +10 -5
  33. package/src/main.test.ts +38 -0
  34. package/src/main.ts +51 -90
  35. package/templates/next-template/.env.example +8 -0
  36. package/templates/next-template/.nvmrc +1 -0
  37. package/templates/next-template/biome.json +48 -0
  38. package/templates/{next-wagmi-template → next-template}/next-env.d.ts +1 -1
  39. package/templates/next-template/package.json +44 -0
  40. package/templates/next-template/postcss.config.mjs +6 -0
  41. package/templates/next-template/src/app/development/page.tsx +260 -0
  42. package/templates/next-template/src/app/globals.css +14 -0
  43. package/templates/next-template/src/app/layout.tsx +30 -0
  44. package/templates/next-template/src/app/page.tsx +10 -0
  45. package/templates/next-template/src/app/resources/page.tsx +175 -0
  46. package/templates/next-template/src/app/resources/resources.ts +56 -0
  47. package/templates/next-template/src/components/default/examples.ts +63 -0
  48. package/templates/next-template/src/components/default/index.tsx +402 -0
  49. package/templates/next-template/src/components/index.ts +3 -0
  50. package/templates/next-template/src/components/landing/index.tsx +107 -0
  51. package/templates/next-template/src/components/providers/index.ts +1 -0
  52. package/templates/next-template/src/components/providers/providers.tsx +89 -0
  53. package/templates/next-template/src/components/shell/index.ts +1 -0
  54. package/templates/next-template/src/components/shell/shell.tsx +87 -0
  55. package/templates/next-template/tailwind.config.js +17 -0
  56. package/{dist/templates/next-cosmos-template → templates/next-template}/tsconfig.json +2 -1
  57. package/tsconfig.json +1 -7
  58. package/.yarn/install-state.gz +0 -0
  59. package/dist/templates/next-cosmos-template/README.md +0 -60
  60. package/dist/templates/next-cosmos-template/next-env.d.ts +0 -5
  61. package/dist/templates/next-cosmos-template/next.config.mjs +0 -14
  62. package/dist/templates/next-cosmos-template/package.json +0 -31
  63. package/dist/templates/next-cosmos-template/public/next.svg +0 -1
  64. package/dist/templates/next-cosmos-template/public/sei-logotype.svg +0 -15
  65. package/dist/templates/next-cosmos-template/public/vercel.svg +0 -1
  66. package/dist/templates/next-cosmos-template/src/app/components/Homepage/Examples.tsx +0 -168
  67. package/dist/templates/next-cosmos-template/src/app/components/Homepage/Homepage.css +0 -154
  68. package/dist/templates/next-cosmos-template/src/app/components/Homepage/Homepage.tsx +0 -83
  69. package/dist/templates/next-cosmos-template/src/app/components/WalletConnectButton/WalletConnectButton.tsx +0 -18
  70. package/dist/templates/next-cosmos-template/src/app/components/Web3Provider.tsx +0 -35
  71. package/dist/templates/next-cosmos-template/src/app/components/index.ts +0 -3
  72. package/dist/templates/next-cosmos-template/src/app/constants/chain.ts +0 -16
  73. package/dist/templates/next-cosmos-template/src/app/constants/index.ts +0 -1
  74. package/dist/templates/next-cosmos-template/src/app/index.css +0 -184
  75. package/dist/templates/next-cosmos-template/src/app/layout.tsx +0 -21
  76. package/dist/templates/next-cosmos-template/src/app/page.tsx +0 -17
  77. package/dist/templates/next-cosmos-template/yarn.lock +0 -9814
  78. package/dist/templates/next-wagmi-template/next-env.d.ts +0 -5
  79. package/dist/templates/next-wagmi-template/package.json +0 -30
  80. package/dist/templates/next-wagmi-template/public/sei-logotype.svg +0 -15
  81. package/dist/templates/next-wagmi-template/src/app/components/Homepage/Examples.tsx +0 -257
  82. package/dist/templates/next-wagmi-template/src/app/components/Homepage/Homepage.css +0 -154
  83. package/dist/templates/next-wagmi-template/src/app/components/Homepage/Homepage.tsx +0 -87
  84. package/dist/templates/next-wagmi-template/src/app/components/Web3Provider.tsx +0 -74
  85. package/dist/templates/next-wagmi-template/src/app/components/index.ts +0 -2
  86. package/dist/templates/next-wagmi-template/src/app/constants/chain.ts +0 -7
  87. package/dist/templates/next-wagmi-template/src/app/constants/index.ts +0 -1
  88. package/dist/templates/next-wagmi-template/src/app/index.css +0 -184
  89. package/dist/templates/next-wagmi-template/src/app/layout.tsx +0 -21
  90. package/dist/templates/next-wagmi-template/src/app/page.tsx +0 -21
  91. package/dist/templates/next-wagmi-template/tsconfig.json +0 -26
  92. package/dist/templates/next-wagmi-template/yarn.lock +0 -4809
  93. package/dist/templates/vite-cosmos-template/.eslintrc.cjs +0 -11
  94. package/dist/templates/vite-cosmos-template/README.md +0 -72
  95. package/dist/templates/vite-cosmos-template/favicon.ico +0 -0
  96. package/dist/templates/vite-cosmos-template/index.html +0 -16
  97. package/dist/templates/vite-cosmos-template/package.json +0 -35
  98. package/dist/templates/vite-cosmos-template/public/sei-logotype.svg +0 -15
  99. package/dist/templates/vite-cosmos-template/src/App.tsx +0 -15
  100. package/dist/templates/vite-cosmos-template/src/assets/react.svg +0 -1
  101. package/dist/templates/vite-cosmos-template/src/components/Homepage/Examples.tsx +0 -168
  102. package/dist/templates/vite-cosmos-template/src/components/Homepage/Homepage.css +0 -154
  103. package/dist/templates/vite-cosmos-template/src/components/Homepage/Homepage.tsx +0 -77
  104. package/dist/templates/vite-cosmos-template/src/components/WalletConnectButton/WalletConnectButton.tsx +0 -18
  105. package/dist/templates/vite-cosmos-template/src/components/Web3Provider.tsx +0 -41
  106. package/dist/templates/vite-cosmos-template/src/components/index.ts +0 -4
  107. package/dist/templates/vite-cosmos-template/src/constants/chain.ts +0 -16
  108. package/dist/templates/vite-cosmos-template/src/constants/index.ts +0 -1
  109. package/dist/templates/vite-cosmos-template/src/index.css +0 -184
  110. package/dist/templates/vite-cosmos-template/src/main.tsx +0 -12
  111. package/dist/templates/vite-cosmos-template/src/vite-env.d.ts +0 -1
  112. package/dist/templates/vite-cosmos-template/tsconfig.app.json +0 -25
  113. package/dist/templates/vite-cosmos-template/tsconfig.json +0 -11
  114. package/dist/templates/vite-cosmos-template/tsconfig.node.json +0 -14
  115. package/dist/templates/vite-cosmos-template/vite.config.ts +0 -7
  116. package/dist/templates/vite-cosmos-template/yarn.lock +0 -9323
  117. package/dist/templates/vite-wagmi-template/.eslintrc.cjs +0 -11
  118. package/dist/templates/vite-wagmi-template/README.md +0 -72
  119. package/dist/templates/vite-wagmi-template/favicon.ico +0 -0
  120. package/dist/templates/vite-wagmi-template/index.html +0 -12
  121. package/dist/templates/vite-wagmi-template/package.json +0 -33
  122. package/dist/templates/vite-wagmi-template/public/sei-logotype.svg +0 -15
  123. package/dist/templates/vite-wagmi-template/src/App.tsx +0 -21
  124. package/dist/templates/vite-wagmi-template/src/assets/react.svg +0 -1
  125. package/dist/templates/vite-wagmi-template/src/components/Homepage/Examples.tsx +0 -255
  126. package/dist/templates/vite-wagmi-template/src/components/Homepage/Homepage.css +0 -154
  127. package/dist/templates/vite-wagmi-template/src/components/Homepage/Homepage.tsx +0 -81
  128. package/dist/templates/vite-wagmi-template/src/components/Web3Provider.tsx +0 -72
  129. package/dist/templates/vite-wagmi-template/src/constants/chain.ts +0 -6
  130. package/dist/templates/vite-wagmi-template/src/constants/index.ts +0 -1
  131. package/dist/templates/vite-wagmi-template/src/index.css +0 -183
  132. package/dist/templates/vite-wagmi-template/src/main.tsx +0 -12
  133. package/dist/templates/vite-wagmi-template/src/vite-env.d.ts +0 -1
  134. package/dist/templates/vite-wagmi-template/tsconfig.app.json +0 -25
  135. package/dist/templates/vite-wagmi-template/tsconfig.json +0 -11
  136. package/dist/templates/vite-wagmi-template/tsconfig.node.json +0 -14
  137. package/dist/templates/vite-wagmi-template/vite.config.ts +0 -10
  138. package/dist/templates/vite-wagmi-template/yarn.lock +0 -4603
  139. package/templates/next-cosmos-template/.eslintrc.json +0 -3
  140. package/templates/next-cosmos-template/README.md +0 -60
  141. package/templates/next-cosmos-template/next.config.mjs +0 -14
  142. package/templates/next-cosmos-template/package.json +0 -31
  143. package/templates/next-cosmos-template/public/next.svg +0 -1
  144. package/templates/next-cosmos-template/public/sei-logotype.svg +0 -15
  145. package/templates/next-cosmos-template/public/vercel.svg +0 -1
  146. package/templates/next-cosmos-template/src/app/components/Homepage/Examples.tsx +0 -168
  147. package/templates/next-cosmos-template/src/app/components/Homepage/Homepage.css +0 -154
  148. package/templates/next-cosmos-template/src/app/components/Homepage/Homepage.tsx +0 -83
  149. package/templates/next-cosmos-template/src/app/components/WalletConnectButton/WalletConnectButton.tsx +0 -18
  150. package/templates/next-cosmos-template/src/app/components/Web3Provider.tsx +0 -35
  151. package/templates/next-cosmos-template/src/app/components/index.ts +0 -3
  152. package/templates/next-cosmos-template/src/app/constants/chain.ts +0 -16
  153. package/templates/next-cosmos-template/src/app/constants/index.ts +0 -1
  154. package/templates/next-cosmos-template/src/app/favicon.ico +0 -0
  155. package/templates/next-cosmos-template/src/app/index.css +0 -184
  156. package/templates/next-cosmos-template/src/app/layout.tsx +0 -21
  157. package/templates/next-cosmos-template/src/app/page.tsx +0 -17
  158. package/templates/next-cosmos-template/yarn.lock +0 -9814
  159. package/templates/next-wagmi-template/.eslintrc.json +0 -3
  160. package/templates/next-wagmi-template/package.json +0 -30
  161. package/templates/next-wagmi-template/public/sei-logotype.svg +0 -15
  162. package/templates/next-wagmi-template/src/app/components/Homepage/Examples.tsx +0 -257
  163. package/templates/next-wagmi-template/src/app/components/Homepage/Homepage.css +0 -154
  164. package/templates/next-wagmi-template/src/app/components/Homepage/Homepage.tsx +0 -87
  165. package/templates/next-wagmi-template/src/app/components/Web3Provider.tsx +0 -74
  166. package/templates/next-wagmi-template/src/app/components/index.ts +0 -2
  167. package/templates/next-wagmi-template/src/app/constants/chain.ts +0 -7
  168. package/templates/next-wagmi-template/src/app/constants/index.ts +0 -1
  169. package/templates/next-wagmi-template/src/app/favicon.ico +0 -0
  170. package/templates/next-wagmi-template/src/app/index.css +0 -184
  171. package/templates/next-wagmi-template/src/app/layout.tsx +0 -21
  172. package/templates/next-wagmi-template/src/app/page.tsx +0 -21
  173. package/templates/next-wagmi-template/tsconfig.json +0 -26
  174. package/templates/next-wagmi-template/yarn.lock +0 -4809
  175. package/templates/vite-cosmos-template/.eslintrc.cjs +0 -11
  176. package/templates/vite-cosmos-template/README.md +0 -72
  177. package/templates/vite-cosmos-template/favicon.ico +0 -0
  178. package/templates/vite-cosmos-template/index.html +0 -16
  179. package/templates/vite-cosmos-template/package.json +0 -35
  180. package/templates/vite-cosmos-template/public/sei-logotype.svg +0 -15
  181. package/templates/vite-cosmos-template/src/App.tsx +0 -15
  182. package/templates/vite-cosmos-template/src/assets/react.svg +0 -1
  183. package/templates/vite-cosmos-template/src/components/Homepage/Examples.tsx +0 -168
  184. package/templates/vite-cosmos-template/src/components/Homepage/Homepage.css +0 -154
  185. package/templates/vite-cosmos-template/src/components/Homepage/Homepage.tsx +0 -77
  186. package/templates/vite-cosmos-template/src/components/WalletConnectButton/WalletConnectButton.tsx +0 -18
  187. package/templates/vite-cosmos-template/src/components/Web3Provider.tsx +0 -41
  188. package/templates/vite-cosmos-template/src/components/index.ts +0 -4
  189. package/templates/vite-cosmos-template/src/constants/chain.ts +0 -16
  190. package/templates/vite-cosmos-template/src/constants/index.ts +0 -1
  191. package/templates/vite-cosmos-template/src/index.css +0 -184
  192. package/templates/vite-cosmos-template/src/main.tsx +0 -12
  193. package/templates/vite-cosmos-template/src/vite-env.d.ts +0 -1
  194. package/templates/vite-cosmos-template/tsconfig.app.json +0 -25
  195. package/templates/vite-cosmos-template/tsconfig.json +0 -11
  196. package/templates/vite-cosmos-template/tsconfig.node.json +0 -14
  197. package/templates/vite-cosmos-template/vite.config.ts +0 -7
  198. package/templates/vite-cosmos-template/yarn.lock +0 -9323
  199. package/templates/vite-wagmi-template/.eslintrc.cjs +0 -11
  200. package/templates/vite-wagmi-template/README.md +0 -72
  201. package/templates/vite-wagmi-template/favicon.ico +0 -0
  202. package/templates/vite-wagmi-template/index.html +0 -12
  203. package/templates/vite-wagmi-template/package.json +0 -33
  204. package/templates/vite-wagmi-template/public/sei-logotype.svg +0 -15
  205. package/templates/vite-wagmi-template/src/App.tsx +0 -21
  206. package/templates/vite-wagmi-template/src/assets/react.svg +0 -1
  207. package/templates/vite-wagmi-template/src/components/Homepage/Examples.tsx +0 -255
  208. package/templates/vite-wagmi-template/src/components/Homepage/Homepage.css +0 -154
  209. package/templates/vite-wagmi-template/src/components/Homepage/Homepage.tsx +0 -81
  210. package/templates/vite-wagmi-template/src/components/Web3Provider.tsx +0 -72
  211. package/templates/vite-wagmi-template/src/constants/chain.ts +0 -6
  212. package/templates/vite-wagmi-template/src/constants/index.ts +0 -1
  213. package/templates/vite-wagmi-template/src/index.css +0 -183
  214. package/templates/vite-wagmi-template/src/main.tsx +0 -12
  215. package/templates/vite-wagmi-template/src/vite-env.d.ts +0 -1
  216. package/templates/vite-wagmi-template/tsconfig.app.json +0 -25
  217. package/templates/vite-wagmi-template/tsconfig.json +0 -11
  218. package/templates/vite-wagmi-template/tsconfig.node.json +0 -14
  219. package/templates/vite-wagmi-template/vite.config.ts +0 -10
  220. package/templates/vite-wagmi-template/yarn.lock +0 -4603
  221. /package/dist/templates/{next-cosmos-template → next-template}/.eslintrc.json +0 -0
  222. /package/dist/templates/{next-wagmi-template → next-template}/README.md +0 -0
  223. /package/dist/templates/{next-wagmi-template → next-template}/next.config.mjs +0 -0
  224. /package/dist/templates/{next-cosmos-template/src/app → next-template/public}/favicon.ico +0 -0
  225. /package/{dist/templates/next-wagmi-template → templates/next-template}/.eslintrc.json +0 -0
  226. /package/templates/{next-wagmi-template → next-template}/README.md +0 -0
  227. /package/templates/{next-wagmi-template → next-template}/next.config.mjs +0 -0
  228. /package/{dist/templates/next-wagmi-template/src/app → templates/next-template/public}/favicon.ico +0 -0
@@ -0,0 +1,87 @@
1
+ 'use client';
2
+
3
+ import { ActionIcon, AppShell, Container, Group } from '@mantine/core';
4
+ import { ConnectButton } from '@rainbow-me/rainbowkit';
5
+ import { IconBook, IconCode, IconLogout } from '@tabler/icons-react';
6
+ import Link from 'next/link';
7
+ import type { PropsWithChildren } from 'react';
8
+ import { useAccount, useDisconnect } from 'wagmi';
9
+
10
+ export default function Shell({ children }: PropsWithChildren) {
11
+ const { address, isConnected } = useAccount();
12
+ const { disconnect } = useDisconnect();
13
+
14
+ return (
15
+ <AppShell header={{ height: 64 }} padding="md">
16
+ <AppShell.Header>
17
+ <Container size="xl" h="100%">
18
+ <Group justify="space-between" align="center" h="100%">
19
+ <Link href="/" aria-label="Sei">
20
+ <img src="https://cdn.sei.io/assets/sei-icon.svg" alt="Sei" style={{ height: 28, display: 'block' }} />
21
+ </Link>
22
+ <Group align="center" gap="md">
23
+ <ActionIcon
24
+ component={Link}
25
+ href="/resources"
26
+ variant="light"
27
+ c="gray"
28
+ size="lg"
29
+ radius="md"
30
+ aria-label="View Resources"
31
+ style={{
32
+ transition: 'all 0.2s ease',
33
+ '&:hover': {
34
+ transform: 'translateY(-1px)',
35
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)',
36
+ },
37
+ }}
38
+ >
39
+ <IconBook size={18} />
40
+ </ActionIcon>
41
+ <ActionIcon
42
+ component={Link}
43
+ href="/development"
44
+ variant="light"
45
+ c="gray"
46
+ size="lg"
47
+ radius="md"
48
+ aria-label="View Development Guide"
49
+ style={{
50
+ transition: 'all 0.2s ease',
51
+ '&:hover': {
52
+ transform: 'translateY(-1px)',
53
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)',
54
+ },
55
+ }}
56
+ >
57
+ <IconCode size={18} />
58
+ </ActionIcon>
59
+ {isConnected && address ? (
60
+ <ActionIcon
61
+ variant="light"
62
+ c="red"
63
+ size="lg"
64
+ radius="md"
65
+ onClick={() => disconnect()}
66
+ aria-label="Disconnect Wallet"
67
+ style={{
68
+ transition: 'all 0.2s ease',
69
+ '&:hover': {
70
+ transform: 'translateY(-1px)',
71
+ boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)',
72
+ },
73
+ }}
74
+ >
75
+ <IconLogout size={18} />
76
+ </ActionIcon>
77
+ ) : (
78
+ <ConnectButton showBalance={{ smallScreen: false, largeScreen: true }} />
79
+ )}
80
+ </Group>
81
+ </Group>
82
+ </Container>
83
+ </AppShell.Header>
84
+ <AppShell.Main>{children}</AppShell.Main>
85
+ </AppShell>
86
+ );
87
+ }
@@ -0,0 +1,17 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ content: [
4
+ './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
5
+ './src/components/**/*.{js,ts,jsx,tsx,mdx}',
6
+ './src/app/**/*.{js,ts,jsx,tsx,mdx}',
7
+ ],
8
+ theme: {
9
+ extend: {
10
+ colors: {
11
+ 'sei-red': '#9E1F19',
12
+ 'sei-dark': '#1a1a1a',
13
+ },
14
+ },
15
+ },
16
+ plugins: [],
17
+ }
@@ -19,7 +19,8 @@
19
19
  ],
20
20
  "paths": {
21
21
  "@/*": ["./src/*"]
22
- }
22
+ },
23
+ "target": "ES2017"
23
24
  },
24
25
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25
26
  "exclude": ["node_modules"]
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "template-next-create-sei-app-precompiles",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "biome lint .",
10
+ "lint:fix": "biome lint --write .",
11
+ "format": "biome format --write .",
12
+ "format:check": "biome format .",
13
+ "check": "biome check .",
14
+ "check:fix": "biome check --write .",
15
+ "deploy": "vercel --prod"
16
+ },
17
+ "dependencies": {
18
+ "@mantine/code-highlight": "^8.2.5",
19
+ "@mantine/core": "^8.2.5",
20
+ "@mantine/hooks": "^8.2.5",
21
+ "@mantine/notifications": "^8.2.5",
22
+ "@rainbow-me/rainbowkit": "^2.2.8",
23
+ "@sei-js/precompiles": "^2.1.2",
24
+ "@tabler/icons-react": "^3.34.1",
25
+ "@tailwindcss/postcss": "^4.1.12",
26
+ "@tanstack/react-query": "^5.85.3",
27
+ "ethers": "^6.15.0",
28
+ "next": "15.4.7",
29
+ "pino-pretty": "^13.1.1",
30
+ "react": "^19.1.1",
31
+ "react-dom": "^19.1.1",
32
+ "viem": "^2.34.0",
33
+ "wagmi": "^2.16.4"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^24.3.0",
37
+ "@types/react": "^19.1.10",
38
+ "@types/react-dom": "^19.1.7",
39
+ "autoprefixer": "^10.4.21",
40
+ "postcss": "^8.4.45",
41
+ "tailwindcss": "^4.1.12",
42
+ "typescript": "^5.9.2"
43
+ }
44
+ }
@@ -0,0 +1,201 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { CodeHighlight } from '@mantine/code-highlight';
5
+ import { ActionIcon, Badge, Button, Card, Collapse, Container, Flex, Group, Paper, Stack, Text, ThemeIcon, Title } from '@mantine/core';
6
+ import { notifications } from '@mantine/notifications';
7
+ import { BANK_PRECOMPILE_ADDRESS, VIEM_BANK_PRECOMPILE_ABI } from '@sei-js/precompiles';
8
+ import { IconBulb, IconChevronDown, IconChevronUp, IconCopy, IconDatabase } from '@tabler/icons-react';
9
+ import { useState } from 'react';
10
+ import { type ReadContractParameters, formatEther } from 'viem';
11
+ import { useAccount, usePublicClient } from 'wagmi';
12
+
13
+ function Examples() {
14
+ const [supply, setSupply] = useState('');
15
+ const [showCode, setShowCode] = useState(false);
16
+
17
+ const publicClient = usePublicClient();
18
+ const { address } = useAccount();
19
+
20
+ const formatLargeSeiNumber = (num: string, decimals: number): string => {
21
+ if (num.length > 10) {
22
+ return `${(Number(num) / 1000000 / 1000000000).toLocaleString(navigator.language, {
23
+ minimumFractionDigits: decimals,
24
+ maximumFractionDigits: decimals
25
+ })} B`;
26
+ }
27
+ return (Number(num) / 1000000).toLocaleString(navigator.language);
28
+ };
29
+
30
+ const copyToClipboard = (text: string) => {
31
+ try {
32
+ navigator.clipboard.writeText(text).then(() => {
33
+ notifications.show({
34
+ title: 'Copied!',
35
+ message: 'Code copied to clipboard',
36
+ color: 'green'
37
+ });
38
+ });
39
+ } catch (err) {
40
+ console.error('Failed to copy text: ', err);
41
+ notifications.show({
42
+ title: 'Error',
43
+ message: 'Failed to copy to clipboard',
44
+ color: 'red'
45
+ });
46
+ }
47
+ };
48
+
49
+ const getSeiSupply = async () => {
50
+ if (!publicClient) {
51
+ return undefined;
52
+ }
53
+
54
+ const readContractParams: ReadContractParameters = {
55
+ abi: VIEM_BANK_PRECOMPILE_ABI,
56
+ address: BANK_PRECOMPILE_ADDRESS,
57
+ functionName: 'supply',
58
+ args: ['usei']
59
+ };
60
+
61
+ try {
62
+ const result = await publicClient.readContract(readContractParams);
63
+ setSupply((result as bigint).toString());
64
+ } catch (error) {
65
+ console.error('Error fetching supply:', error);
66
+ notifications.show({
67
+ title: 'Error',
68
+ message: 'Failed to fetch SEI supply',
69
+ color: 'red'
70
+ });
71
+ }
72
+ };
73
+
74
+ const codeExample = `// Sei Precompile Example - Bank Precompile
75
+ import { BANK_PRECOMPILE_ADDRESS, VIEM_BANK_PRECOMPILE_ABI } from '@sei-js/precompiles';
76
+ import { usePublicClient } from 'wagmi';
77
+
78
+ const publicClient = usePublicClient();
79
+
80
+ const getSeiSupply = async () => {
81
+ const readContractParams = {
82
+ abi: VIEM_BANK_PRECOMPILE_ABI,
83
+ address: BANK_PRECOMPILE_ADDRESS,
84
+ functionName: 'supply',
85
+ args: ['usei'],
86
+ };
87
+
88
+ const result = await publicClient?.readContract(readContractParams);
89
+ return (result as bigint).toString();
90
+ };`;
91
+
92
+ return (
93
+ <Container size="xl" py="xl" pos="relative">
94
+ <Stack gap="xl">
95
+ {/* Header */}
96
+ <div>
97
+ <Group gap="md" align="center" mb="lg">
98
+ <ThemeIcon size={48} radius="md" c="orange" variant="light">
99
+ <IconBulb size={24} />
100
+ </ThemeIcon>
101
+ <div>
102
+ <Title order={1} fw={700} c="gray.9">
103
+ Sei Precompiles
104
+ </Title>
105
+ <Text size="lg" c="gray.6" mt={4}>
106
+ Access native Sei blockchain functionality through EVM precompiles
107
+ </Text>
108
+ </div>
109
+ </Group>
110
+ </div>
111
+
112
+ {/* Precompile Example Card */}
113
+ <Card shadow="xs" p="lg" radius="md" withBorder>
114
+ <Stack gap="md">
115
+ <Flex justify="space-between" align="flex-start">
116
+ <Stack gap="xs">
117
+ <Group gap="md">
118
+ <ThemeIcon size={40} radius="md" color="orange" variant="light">
119
+ <IconDatabase size={20} />
120
+ </ThemeIcon>
121
+ <Title order={3} fw={600} c="gray.9">
122
+ Bank Precompile
123
+ </Title>
124
+ </Group>
125
+ <Text size="sm" c="gray.6">
126
+ Query total SEI supply using Sei's native{' '}
127
+ <Text component="a" href="https://www.docs.sei.io/dev-interoperability/precompiles/bank" target="_blank" c="orange" td="underline">
128
+ Bank precompile
129
+ </Text>
130
+ </Text>
131
+ </Stack>
132
+ <Badge color="orange" variant="light" size="md" radius="md">
133
+ precompiles
134
+ </Badge>
135
+ </Flex>
136
+
137
+ <Paper p="md" radius="md" withBorder bg="gray.0">
138
+ <Text size="xs" fw={500} c="gray.6">
139
+ Total Supply
140
+ </Text>
141
+ <Flex justify="space-between" align="center">
142
+ <Flex align="baseline" gap="xs">
143
+ {supply ? (
144
+ <>
145
+ <Text fw={700} size="xl" c="gray.9" ff="monospace">
146
+ {formatLargeSeiNumber(supply, 2)}
147
+ </Text>
148
+ <Text size="sm" c="gray.6" fw={500}>
149
+ SEI
150
+ </Text>
151
+ </>
152
+ ) : (
153
+ <Paper px="sm" py={4} bg="white" radius="md" withBorder>
154
+ <Flex align="baseline" gap="xs">
155
+ <Text fw={700} size="xl" c="gray.5" ff="monospace">
156
+ —
157
+ </Text>
158
+ <Text size="sm" c="gray.6" fw={500}>
159
+ SEI
160
+ </Text>
161
+ </Flex>
162
+ </Paper>
163
+ )}
164
+ </Flex>
165
+ <Button onClick={getSeiSupply} size="sm" radius="md" variant="light" color="orange" leftSection={<IconDatabase size={14} />}>
166
+ {supply ? 'Refresh' : 'Query Supply'}
167
+ </Button>
168
+ </Flex>
169
+ </Paper>
170
+
171
+ <Group justify="space-between" align="center" mt="sm">
172
+ <Button
173
+ variant="subtle"
174
+ color="gray"
175
+ size="sm"
176
+ radius="md"
177
+ leftSection={showCode ? <IconChevronUp size={14} /> : <IconChevronDown size={14} />}
178
+ onClick={() => setShowCode(!showCode)}
179
+ >
180
+ {showCode ? 'Hide' : 'View'} Implementation
181
+ </Button>
182
+ {showCode && (
183
+ <ActionIcon variant="subtle" color="gray" size="sm" radius="md" onClick={() => copyToClipboard(codeExample)}>
184
+ <IconCopy size={14} />
185
+ </ActionIcon>
186
+ )}
187
+ </Group>
188
+
189
+ <Collapse in={showCode}>
190
+ <Paper mt="sm" p="md" bg="gray.0" radius="md" withBorder>
191
+ <CodeHighlight code={codeExample} language="tsx" withCopyButton={false} expandCodeLabel="" collapseCodeLabel="" />
192
+ </Paper>
193
+ </Collapse>
194
+ </Stack>
195
+ </Card>
196
+ </Stack>
197
+ </Container>
198
+ );
199
+ }
200
+
201
+ export default Examples;
package/jest.config.js ADDED
@@ -0,0 +1,14 @@
1
+ export default {
2
+ preset: 'ts-jest',
3
+ testEnvironment: 'node',
4
+ transform: {
5
+ '^.+\\.ts$': ['ts-jest', {
6
+ useESM: true
7
+ }]
8
+ },
9
+ extensionsToTreatAsEsm: ['.ts'],
10
+ moduleNameMapper: {
11
+ '^(\\.{1,2}/.*)\\.js$': '$1'
12
+ },
13
+ testPathIgnorePatterns: ['/node_modules/', '/dist/', '/templates/', '/test-smart-contract-app/']
14
+ };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@sei-js/create-sei",
3
- "version": "0.0.3",
3
+ "version": "1.0.0",
4
4
  "module": "dist/main.js",
5
5
  "type": "module",
6
6
  "bin": "./dist/main.js",
7
7
  "scripts": {
8
- "build": "tsc && cp -r ./templates ./dist/templates",
8
+ "build": "rm -rf dist && tsc && chmod +x dist/main.js && rsync -av --exclude-from=.rsyncignore ./templates/ ./dist/templates/ && rsync -av --exclude-from=.rsyncignore ./extensions/ ./dist/extensions/",
9
9
  "dev": "node --loader ts-node/esm src/main.ts",
10
- "docs": "typedoc --out docs"
10
+ "test": "jest"
11
11
  },
12
12
  "dependencies": {
13
13
  "boxen": "^7.1.1",
@@ -15,7 +15,12 @@
15
15
  "inquirer": "^9.2.15"
16
16
  },
17
17
  "devDependencies": {
18
- "@types/boxen": "^3.0.1",
19
- "@types/inquirer": "^9.0.7"
18
+ "@jest/globals": "^29.7.0",
19
+ "@types/jest": "^29.5.12",
20
+ "@types/node": "^20.14.10",
21
+ "jest": "^29.7.0",
22
+ "ts-jest": "^29.1.2",
23
+ "ts-node": "^10.9.2",
24
+ "typescript": "^5.5.3"
20
25
  }
21
26
  }
@@ -0,0 +1,38 @@
1
+ import { describe, test, expect, beforeEach, afterEach } from '@jest/globals';
2
+ import { promises as fs } from 'node:fs';
3
+ import path from 'node:path';
4
+
5
+ describe('Extension System', () => {
6
+ const testDir = path.join(process.cwd(), 'test-output');
7
+ const extensionsDir = path.join(process.cwd(), 'extensions');
8
+
9
+ beforeEach(async () => {
10
+ // Clean up test directory
11
+ try {
12
+ await fs.rm(testDir, { recursive: true, force: true });
13
+ } catch (e) {
14
+ // Directory might not exist
15
+ }
16
+ await fs.mkdir(testDir, { recursive: true });
17
+ });
18
+
19
+ afterEach(async () => {
20
+ // Clean up test directory
21
+ try {
22
+ await fs.rm(testDir, { recursive: true, force: true });
23
+ } catch (e) {
24
+ // Directory might not exist
25
+ }
26
+ });
27
+
28
+ test('should list available extensions', async () => {
29
+ const extensionExists = await fs.access(path.join(extensionsDir, 'precompiles'))
30
+ .then(() => true)
31
+ .catch(() => false);
32
+
33
+ expect(extensionExists).toBe(true);
34
+
35
+ const extensionFiles = await fs.readdir(extensionsDir);
36
+ expect(extensionFiles).toContain('precompiles');
37
+ });
38
+ });
package/src/main.ts CHANGED
@@ -25,66 +25,11 @@ const printWelcomeMessage = () => {
25
25
  );
26
26
  };
27
27
 
28
- enum FrontendScaffolding {
29
- Vite = 'vite',
30
- Next = 'next'
31
- }
32
-
33
- export enum RPCIntegrationType {
34
- EVM = 'evm',
35
- CosmJS = 'cosmos'
36
- }
37
-
38
- export enum EVMLibrary {
39
- Wagmi = 'wagmi'
40
- }
41
-
42
28
  interface WizardOptions {
43
29
  name?: string;
44
- framework?: FrontendScaffolding;
45
- ecosystem?: RPCIntegrationType;
46
- library?: EVMLibrary;
30
+ extension?: string;
47
31
  }
48
32
 
49
- const promptFramework = async () => {
50
- const { appFramework } = await inquirer.prompt([
51
- {
52
- type: 'list',
53
- name: 'appFramework',
54
- message: 'Select an app framework to use?',
55
- choices: Object.values(FrontendScaffolding)
56
- }
57
- ]);
58
-
59
- return appFramework;
60
- };
61
-
62
- const promptRpcIntegrations = async () => {
63
- const { rpcIntegrationType } = await inquirer.prompt([
64
- {
65
- type: 'list',
66
- name: 'rpcIntegrationType',
67
- message: 'Select the wallet connection type you want to include:',
68
- choices: Object.values(RPCIntegrationType)
69
- }
70
- ]);
71
-
72
- return rpcIntegrationType;
73
- };
74
-
75
- const promptEVMLibrary = async () => {
76
- const { evmLibrary } = await inquirer.prompt([
77
- {
78
- type: 'list',
79
- name: 'evmLibrary',
80
- message: 'Choose your preferred EVM library:',
81
- choices: Object.values(EVMLibrary)
82
- }
83
- ]);
84
-
85
- return evmLibrary;
86
- };
87
-
88
33
  function isValidDirectoryName(dirName) {
89
34
  const illegalRe = /[<>:"/\\|?*]/g;
90
35
  const windowsReservedRe = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
@@ -113,32 +58,29 @@ const validateOptions = (options: WizardOptions): boolean => {
113
58
  }
114
59
  }
115
60
 
116
- if (options.framework) {
117
- const validFrameworks = Object.values(FrontendScaffolding);
118
- if (!validFrameworks.includes(options.framework)) {
119
- console.log(`Invalid Framework '${options.framework}' provided. Framework must be one of: [${validFrameworks.join(', ')}]`);
120
- valid = false;
121
- }
122
- }
61
+ return valid;
62
+ };
123
63
 
124
- if (options.ecosystem) {
125
- const validEcosystems = Object.values(RPCIntegrationType);
126
- if (!validEcosystems.includes(options.ecosystem)) {
127
- console.log(`Invalid Ecosystem '${options.ecosystem}' provided. Framework must be one of: [${validEcosystems.join(', ')}]`);
128
- valid = false;
64
+ async function listExtensions(): Promise<void> {
65
+ const extensionsPath = path.join(__dirname, 'extensions');
66
+
67
+ try {
68
+ const extensions = await fs.promises.readdir(extensionsPath, { withFileTypes: true });
69
+ const extensionDirs = extensions.filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
70
+
71
+ if (extensionDirs.length === 0) {
72
+ console.log('No extensions available.');
73
+ return;
129
74
  }
130
- }
131
75
 
132
- if (options.library) {
133
- const validEVMLibraries = Object.values(EVMLibrary);
134
- if (!validEVMLibraries.includes(options.library)) {
135
- console.log(`Invalid EVM Library '${options.library}' provided. Framework must be one of: [${validEVMLibraries.join(', ')}]`);
136
- valid = false;
76
+ console.log('Available extensions:');
77
+ for (const ext of extensionDirs) {
78
+ console.log(` - ${ext}`);
137
79
  }
80
+ } catch (error) {
81
+ console.log('No extensions directory found.');
138
82
  }
139
-
140
- return valid;
141
- };
83
+ }
142
84
 
143
85
  async function runWizard(options: WizardOptions): Promise<void> {
144
86
  if (!validateOptions(options)) {
@@ -165,28 +107,36 @@ async function runWizard(options: WizardOptions): Promise<void> {
165
107
  dAppName = promptResult.dAppName;
166
108
  }
167
109
 
168
- const appFramework = options.framework || (await promptFramework());
169
- let appConnectionType = options.ecosystem || (await promptRpcIntegrations());
170
- if (appConnectionType === RPCIntegrationType.EVM) {
171
- appConnectionType = options.library || (await promptEVMLibrary());
172
- }
173
-
174
- const templateName = `${appFramework}-${appConnectionType}-template`;
110
+ // Copy base template
111
+ const templateName = 'next-template';
175
112
  const templatePath = path.join(__dirname, 'templates', templateName);
176
113
  const dst = path.join(process.cwd(), dAppName);
177
114
  await fs.promises.cp(templatePath, dst, { recursive: true });
178
115
 
179
- console.log(`Project setup complete! Using template ${templateName}\n`);
180
- console.log(`To start your app, run: \n > cd ${dAppName} \n > yarn \n > yarn dev\n`);
116
+ // Apply extension if specified
117
+ if (options.extension) {
118
+ const extensionPath = path.join(__dirname, 'extensions', options.extension);
119
+
120
+ try {
121
+ await fs.promises.access(extensionPath);
122
+ await fs.promises.cp(extensionPath, dst, { recursive: true });
123
+ console.log(`Applied extension: ${options.extension}`);
124
+ } catch (error) {
125
+ console.log(`Warning: Extension '${options.extension}' not found. Continuing with base template.`);
126
+ }
127
+ }
128
+
129
+ const extensionText = options.extension ? ` with ${options.extension} extension` : '';
130
+ console.log(`Project setup complete! Using template ${templateName}${extensionText}\n`);
131
+ console.log(`To start your app, run: \n > cd ${dAppName} \n > pnpm \n > pnpm dev\n`);
181
132
  }
182
133
 
183
134
  program
184
135
  .command('app')
185
136
  .description('Create a new SEI dApp')
186
- .option('-n, --name <name>', 'Specify the name of your dApp. Name must be a valid package name.')
187
- .option('-f, --framework <framework>', `Specify the app framework to use: [${Object.values(FrontendScaffolding).join(', ')}]`)
188
- .option('-e, --ecosystem <ecosystem>', `Specify the ecosystem to use: [${Object.values(RPCIntegrationType).join(', ')}]`)
189
- .option('-l, --library <library>', `Specify the EVM library to use: [${Object.values(EVMLibrary).join(', ')}]. Only used if ecosystem chosen is 'EVM'`)
137
+ .option('--name <name>', 'Specify the name of your dApp. Name must be a valid package name.')
138
+ .option('--extension <extension>', 'Specify an extension to apply to the base template')
139
+
190
140
  .action(async (options: WizardOptions) => {
191
141
  try {
192
142
  await runWizard(options);
@@ -195,4 +145,15 @@ program
195
145
  }
196
146
  });
197
147
 
148
+ program
149
+ .command('list-extensions')
150
+ .description('List all available extensions')
151
+ .action(async () => {
152
+ try {
153
+ await listExtensions();
154
+ } catch (error) {
155
+ console.error('An error occurred:', error);
156
+ }
157
+ });
158
+
198
159
  program.parse(process.argv);
@@ -0,0 +1,8 @@
1
+ # Chain configuration
2
+ # Options: mainnet, testnet, devnet
3
+ # Defaults to testnet (atlantic-2) if not set
4
+ NEXT_PUBLIC_CHAIN=testnet
5
+
6
+ # WalletConnect Project ID (optional)
7
+ # Get your project ID from https://cloud.walletconnect.com
8
+ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your-project-id
@@ -0,0 +1 @@
1
+ v20