genlayer 0.12.3 → 0.12.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/.env.example +4 -0
  2. package/CHANGELOG.md +8 -0
  3. package/dist/index.js +409 -80
  4. package/esbuild.config.dev.js +1 -2
  5. package/esbuild.config.prod.js +1 -1
  6. package/eslint.config.js +2 -1
  7. package/package.json +5 -3
  8. package/src/commands/contracts/call.ts +16 -20
  9. package/src/commands/contracts/deploy.ts +107 -25
  10. package/src/commands/contracts/index.ts +14 -3
  11. package/src/commands/general/init.ts +0 -1
  12. package/src/commands/scaffold/index.ts +16 -0
  13. package/src/commands/scaffold/new.ts +34 -0
  14. package/src/index.ts +2 -0
  15. package/src/lib/actions/BaseAction.ts +11 -6
  16. package/src/lib/config/simulator.ts +2 -2
  17. package/templates/default/LICENSE +21 -0
  18. package/templates/default/README.md +101 -0
  19. package/templates/default/__init__.py +0 -0
  20. package/templates/default/app/.env.example +2 -0
  21. package/templates/default/app/.vscode/extensions.json +3 -0
  22. package/templates/default/app/README.md +5 -0
  23. package/templates/default/app/index.html +17 -0
  24. package/templates/default/app/package-lock.json +4920 -0
  25. package/templates/default/app/package.json +23 -0
  26. package/templates/default/app/postcss.config.js +6 -0
  27. package/templates/default/app/public/favicon.png +0 -0
  28. package/templates/default/app/src/App.vue +16 -0
  29. package/templates/default/app/src/components/Address.vue +38 -0
  30. package/templates/default/app/src/components/BetsScreen.vue +329 -0
  31. package/templates/default/app/src/logic/FootballBets.js +100 -0
  32. package/templates/default/app/src/main.js +5 -0
  33. package/templates/default/app/src/services/genlayer.js +19 -0
  34. package/templates/default/app/src/style.css +3 -0
  35. package/templates/default/app/tailwind.config.js +8 -0
  36. package/templates/default/app/vite.config.js +7 -0
  37. package/templates/default/config/__init__.py +0 -0
  38. package/templates/default/config/genlayer_config.py +14 -0
  39. package/templates/default/contracts/__init__.py +0 -0
  40. package/templates/default/contracts/football_bets.py +119 -0
  41. package/templates/default/deploy/deployScript.ts +31 -0
  42. package/templates/default/package-lock.json +3231 -0
  43. package/templates/default/package.json +7 -0
  44. package/templates/default/requirements.txt +6 -0
  45. package/templates/default/test/__init__.py +0 -0
  46. package/templates/default/test/football_bets_get_contract_schema_for_code.py +124 -0
  47. package/templates/default/test/test_football_bet_success_draw.py +108 -0
  48. package/templates/default/test/test_football_bet_success_win.py +106 -0
  49. package/templates/default/test/test_football_bet_unsuccess.py +107 -0
  50. package/templates/default/tools/__init__.py +0 -0
  51. package/templates/default/tools/accounts.py +5 -0
  52. package/templates/default/tools/calldata.py +224 -0
  53. package/templates/default/tools/request.py +134 -0
  54. package/templates/default/tools/response.py +52 -0
  55. package/templates/default/tools/structure.py +39 -0
  56. package/templates/default/tools/transactions.py +28 -0
  57. package/templates/default/tools/types.py +214 -0
  58. package/templates/default/tsconfig.json +7 -0
  59. package/tests/actions/call.test.ts +38 -76
  60. package/tests/actions/deploy.test.ts +200 -30
  61. package/tests/actions/new.test.ts +80 -0
  62. package/tests/commands/call.test.ts +6 -1
  63. package/tests/commands/deploy.test.ts +12 -1
  64. package/tests/commands/new.test.ts +68 -0
  65. package/tests/index.test.ts +4 -0
  66. package/tests/libs/baseAction.test.ts +17 -0
  67. package/vitest.config.ts +1 -1
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "app",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "genlayer-js": "^0.6.4",
13
+ "lucide-vue-next": "^0.446.0",
14
+ "vue": "^3.4.37"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^5.1.2",
18
+ "autoprefixer": "^10.4.20",
19
+ "postcss": "^8.4.47",
20
+ "tailwindcss": "^3.4.13",
21
+ "vite": "^5.4.1"
22
+ }
23
+ }
@@ -0,0 +1,6 @@
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ }
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <Suspense>
3
+ <template #default>
4
+ <BetsScreen />
5
+ </template>
6
+ <template #fallback>
7
+ <div class="flex items-center justify-center h-screen">
8
+ <div class="spinner">Loading...</div>
9
+ </div>
10
+ </template>
11
+ </Suspense>
12
+ </template>
13
+
14
+ <script setup>
15
+ import BetsScreen from "./components/BetsScreen.vue";
16
+ </script>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <span :title="fullAddress">{{ shortenedAddress }}</span>
3
+ </template>
4
+
5
+ <script>
6
+ export default {
7
+ name: "Address",
8
+ props: {
9
+ address: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ maxLength: {
14
+ type: Number,
15
+ default: 12,
16
+ },
17
+ },
18
+ computed: {
19
+ fullAddress() {
20
+ return this.address;
21
+ },
22
+ shortenedAddress() {
23
+ if (!this.address) {
24
+ return "";
25
+ }
26
+ if (this.address.length <= this.maxLength) {
27
+ return this.address;
28
+ }
29
+
30
+ const halfLength = Math.floor((this.maxLength - 3) / 2);
31
+ const start = this.address.slice(0, halfLength);
32
+ const end = this.address.slice(-halfLength);
33
+
34
+ return `${start}...${end}`;
35
+ },
36
+ },
37
+ };
38
+ </script>
@@ -0,0 +1,329 @@
1
+ <template>
2
+ <div class="min-h-screen bg-gray-100 text-gray-900">
3
+ <header class="bg-white shadow flex justify-between">
4
+ <div class="max-w-7xl py-6 px-4 sm:px-6 lg:px-8">
5
+ <h1 class="text-3xl font-bold text-gray-900">GenLayer Football Bets</h1>
6
+ </div>
7
+ <div class="max-w-7xl py-6 px-4 sm:px-6 lg:px-8 text-right">
8
+ <div v-if="!userAddress">
9
+ <button
10
+ @click="createUserAccount"
11
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
12
+ >
13
+ Create Account
14
+ </button>
15
+ </div>
16
+ <div v-else>
17
+ <p class="text-lg">Your address: <Address :address="userAddress" /></p>
18
+ <p class="text-lg">Your points: {{ userPoints }}</p>
19
+ <button
20
+ @click="disconnectUserAccount"
21
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
22
+ >
23
+ Disconnect
24
+ </button>
25
+ </div>
26
+ </div>
27
+ </header>
28
+ <main class="mx-auto py-6 sm:px-6 lg:px-8">
29
+ <!-- Account Section -->
30
+
31
+ <div class="grid grid-cols-1 md:grid-cols-10 gap-8">
32
+ <!-- Bets List -->
33
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg col-span-7">
34
+ <div class="px-4 py-5 sm:px-6 flex justify-between items-center">
35
+ <h2 class="text-lg leading-6 font-medium text-gray-900">Bets</h2>
36
+ <button
37
+ @click="openCreateModal"
38
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-sm"
39
+ >
40
+ Create Bet
41
+ </button>
42
+ </div>
43
+ <div class="border-t border-gray-200">
44
+ <table class="min-w-full divide-y divide-gray-200">
45
+ <thead class="bg-gray-50">
46
+ <tr>
47
+ <th
48
+ scope="col"
49
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
50
+ >
51
+ User
52
+ </th>
53
+ <th
54
+ scope="col"
55
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
56
+ >
57
+ Game Date
58
+ </th>
59
+ <th
60
+ scope="col"
61
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
62
+ >
63
+ Team 1
64
+ </th>
65
+ <th
66
+ scope="col"
67
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
68
+ >
69
+ Team 2
70
+ </th>
71
+ <th
72
+ scope="col"
73
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
74
+ >
75
+ Predicted Winner
76
+ </th>
77
+ <th
78
+ scope="col"
79
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
80
+ >
81
+ Status
82
+ </th>
83
+ <th
84
+ scope="col"
85
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
86
+ >
87
+ Result
88
+ </th>
89
+ <th
90
+ scope="col"
91
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
92
+ >
93
+ Action
94
+ </th>
95
+ </tr>
96
+ </thead>
97
+ <tbody class="bg-white divide-y divide-gray-200">
98
+ <tr v-for="bet in bets" :key="bet.id">
99
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
100
+ <Address :address="bet.owner" />
101
+ </td>
102
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
103
+ {{ bet.game_date }}
104
+ </td>
105
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
106
+ {{ bet.team1 }}
107
+ </td>
108
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
109
+ {{ bet.team2 }}
110
+ </td>
111
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
112
+ {{ bet.predicted_winner === "0" ? "Draw" : (bet.predicted_winner === "1" ? bet.team1 : bet.team2) }}
113
+ </td>
114
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
115
+ <span :class="bet.has_resolved ? 'text-green-600' : 'text-yellow-600'">
116
+ {{ bet.has_resolved ? "Resolved" : "Unresolved" }}
117
+ </span>
118
+ </td>
119
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
120
+ <span v-if="bet.has_resolved" :class="bet.predicted_winner === String(bet.real_winner) ? 'text-green-600' : 'text-red-600'">
121
+ {{ bet.predicted_winner === String(bet.real_winner) ? "Success" : "Failure" }}
122
+ </span>
123
+ </td>
124
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
125
+ <div v-if="resolvingBet !== bet.id">
126
+ <button
127
+ v-if="bet.owner === userAddress && !bet.has_resolved"
128
+ @click="resolveBet(bet.id)"
129
+ class="text-indigo-600 hover:text-indigo-900"
130
+ >
131
+ Resolve
132
+ </button>
133
+ </div>
134
+ <div v-else>Resolving bet</div>
135
+ </td>
136
+ </tr>
137
+ </tbody>
138
+ </table>
139
+ </div>
140
+ </div>
141
+
142
+ <!-- Leaderboard -->
143
+ <div class="bg-white shadow overflow-hidden sm:rounded-lg col-span-3">
144
+ <div class="px-4 py-5 sm:px-6">
145
+ <h2 class="text-lg leading-6 font-medium text-gray-900">Leaderboard</h2>
146
+ </div>
147
+ <div class="border-t border-gray-200">
148
+ <table class="min-w-full divide-y divide-gray-200">
149
+ <thead class="bg-gray-50">
150
+ <tr>
151
+ <th
152
+ scope="col"
153
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
154
+ >
155
+ Rank
156
+ </th>
157
+ <th
158
+ scope="col"
159
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
160
+ >
161
+ Address
162
+ </th>
163
+ <th
164
+ scope="col"
165
+ class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
166
+ >
167
+ Points
168
+ </th>
169
+ </tr>
170
+ </thead>
171
+ <tbody class="bg-white divide-y divide-gray-200">
172
+ <tr v-for="(user, index) in leaderboard" :key="user.address">
173
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ index + 1 }}</td>
174
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
175
+ <Address :address="user.address" />
176
+ </td>
177
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{{ user.points }}</td>
178
+ </tr>
179
+ </tbody>
180
+ </table>
181
+ </div>
182
+ </div>
183
+ </div>
184
+
185
+ <!-- Create Bet Modal -->
186
+ <div
187
+ v-if="showCreateModal"
188
+ class="fixed inset-0 bg-gray-600 bg-opacity-75 overflow-y-auto h-full w-full flex items-center justify-center"
189
+ >
190
+ <div class="relative p-5 border w-96 shadow-lg rounded-md bg-white">
191
+ <h3 class="text-lg font-medium leading-6 text-gray-900 mb-2">Create Bet</h3>
192
+ <input
193
+ v-model="gameDate"
194
+ type="date"
195
+ class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 mb-2"
196
+ placeholder="Game Date (YYYY-MM-DD)"
197
+ />
198
+ <input
199
+ v-model="team1"
200
+ class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 mb-2"
201
+ placeholder="Team 1"
202
+ />
203
+ <input
204
+ v-model="team2"
205
+ class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 mb-2"
206
+ placeholder="Team 2"
207
+ />
208
+ <select
209
+ v-model="predictedWinner"
210
+ class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 mb-2"
211
+ >
212
+ <option value="" disabled selected>Select Predicted Winner</option>
213
+ <option value="0">Draw</option>
214
+ <option value="1">Team 1</option>
215
+ <option value="2">Team 2</option>
216
+ </select>
217
+ <div class="mt-4">
218
+ <div v-if="!creatingBet">
219
+ <button
220
+ @click="createBet"
221
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mr-2"
222
+ >
223
+ Create
224
+ </button>
225
+ <button
226
+ @click="showCreateModal = false"
227
+ class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded"
228
+ >
229
+ Cancel
230
+ </button>
231
+ </div>
232
+ <div v-else>
233
+ <div class="spinner">Creating...</div>
234
+ </div>
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </main>
239
+ </div>
240
+
241
+ <div class="flex items-center justify-center h-screen">
242
+ <div class="spinner">Loading...</div>
243
+ </div>
244
+ </template>
245
+
246
+ <script setup>
247
+ import { ref, computed, onMounted } from "vue";
248
+ import { account, createAccount, removeAccount } from "../services/genlayer";
249
+ import FootballBets from "../logic/FootballBets";
250
+ import Address from "./Address.vue";
251
+ // State
252
+ const gameDate = ref("");
253
+ const team1 = ref("");
254
+ const team2 = ref("");
255
+ const creatingBet = ref(false);
256
+ const resolvingBet = ref(0);
257
+ const predictedWinner = ref("");
258
+ const contractAddress = import.meta.env.VITE_CONTRACT_ADDRESS;
259
+ const studioUrl = import.meta.env.VITE_STUDIO_URL;
260
+ const footballBets = new FootballBets(contractAddress, account, studioUrl);
261
+ const userAccount = ref(account);
262
+ const userPoints = ref(0);
263
+ const userAddress = computed(() => userAccount.value?.address);
264
+ const bets = ref([]);
265
+ const leaderboard = ref([]);
266
+ const showCreateModal = ref(false);
267
+
268
+ // Methods
269
+ const createUserAccount = async () => {
270
+ userAccount.value = createAccount();
271
+ footballBets.updateAccount(userAccount.value);
272
+ userPoints.value = 0;
273
+ };
274
+
275
+ const disconnectUserAccount = async () => {
276
+ userAccount.value = null;
277
+ removeAccount();
278
+ userPoints.value = 0;
279
+ };
280
+
281
+ const openCreateModal = () => {
282
+ showCreateModal.value = true;
283
+ };
284
+
285
+ const loadBets = async () => {
286
+ const allBets = await footballBets.getBets();
287
+ bets.value = allBets;
288
+ };
289
+
290
+ const loadLeaderboard = async () => {
291
+ leaderboard.value = await footballBets.getLeaderboard();
292
+ };
293
+
294
+ const refreshPlayerPoints = async () => {
295
+ userPoints.value = await footballBets.getPlayerPoints(userAddress.value);
296
+ };
297
+
298
+ const createBet = async () => {
299
+ if (gameDate.value && team1.value && team2.value && predictedWinner.value) {
300
+ creatingBet.value = true;
301
+ await footballBets.createBet(gameDate.value, team1.value, team2.value, predictedWinner.value);
302
+ await loadBets();
303
+ // Reset form fields
304
+ creatingBet.value = false;
305
+ gameDate.value = "";
306
+ team1.value = "";
307
+ team2.value = "";
308
+ predictedWinner.value = "";
309
+ showCreateModal.value = false;
310
+ }
311
+ };
312
+
313
+ const resolveBet = async (betId) => {
314
+ resolvingBet.value = betId;
315
+ await footballBets.resolveBet(betId);
316
+ resolvingBet.value = 0;
317
+ await loadBets();
318
+ await loadLeaderboard();
319
+ await refreshPlayerPoints();
320
+ };
321
+
322
+
323
+ // Initialize with some sample data
324
+ onMounted(async () => {
325
+ await loadBets();
326
+ await loadLeaderboard();
327
+ await refreshPlayerPoints();
328
+ });
329
+ </script>
@@ -0,0 +1,100 @@
1
+ import { createClient } from "genlayer-js";
2
+ import { simulator } from "genlayer-js/chains";
3
+
4
+ class FootballBets {
5
+ contractAddress;
6
+ client;
7
+
8
+ constructor(contractAddress, account = null, studioUrl = null) {
9
+ this.contractAddress = contractAddress;
10
+ const config = {
11
+ chain: simulator,
12
+ ...(account ? { account } : {}),
13
+ ...(studioUrl ? { endpoint: studioUrl } : {}),
14
+ };
15
+ this.client = createClient(config);
16
+ }
17
+
18
+ updateAccount(account) {
19
+ this.client = createClient({ chain: simulator, account });
20
+ }
21
+
22
+ async getBets() {
23
+ const bets = await this.client.readContract({
24
+ address: this.contractAddress,
25
+ functionName: "get_bets",
26
+ args: [],
27
+ });
28
+ return Array.from(bets.entries()).flatMap(([owner, bet]) => {
29
+ return Array.from(bet.entries()).map(([id, betData]) => {
30
+ const betObj = Array.from(betData.entries()).reduce((obj, [key, value]) => {
31
+ obj[key] = value;
32
+ return obj;
33
+ }, {});
34
+
35
+ return {
36
+ id,
37
+ ...betObj,
38
+ owner,
39
+ };
40
+ });
41
+ });
42
+ }
43
+
44
+ async getPlayerPoints(address) {
45
+ if (!address) {
46
+ return 0;
47
+ }
48
+ const points = await this.client.readContract({
49
+ address: this.contractAddress,
50
+ functionName: "get_player_points",
51
+ args: [address],
52
+ });
53
+ return points;
54
+ }
55
+
56
+ async getLeaderboard() {
57
+ const points = await this.client.readContract({
58
+ address: this.contractAddress,
59
+ functionName: "get_points",
60
+ args: [],
61
+ });
62
+ return Array.from(points.entries())
63
+ .map(([address, points]) => ({
64
+ address,
65
+ points: Number(points),
66
+ }))
67
+ .sort((a, b) => b.points - a.points);
68
+ }
69
+
70
+ async createBet(gameDate, team1, team2, predictedWinner) {
71
+ const txHash = await this.client.writeContract({
72
+ address: this.contractAddress,
73
+ functionName: "create_bet",
74
+ args: [gameDate, team1, team2, predictedWinner],
75
+ });
76
+ const receipt = await this.client.waitForTransactionReceipt({
77
+ hash: txHash,
78
+ status: "FINALIZED",
79
+ interval: 10000,
80
+ });
81
+ return receipt;
82
+ }
83
+
84
+ async resolveBet(betId) {
85
+ const txHash = await this.client.writeContract({
86
+ address: this.contractAddress,
87
+ functionName: "resolve_bet",
88
+ args: [betId],
89
+ });
90
+ const receipt = await this.client.waitForTransactionReceipt({
91
+ hash: txHash,
92
+ status: "FINALIZED",
93
+ interval: 10000,
94
+ retries: 20,
95
+ });
96
+ return receipt;
97
+ }
98
+ }
99
+
100
+ export default FootballBets;
@@ -0,0 +1,5 @@
1
+ import { createApp } from 'vue'
2
+ import './style.css'
3
+ import App from './App.vue'
4
+
5
+ createApp(App).mount('#app')
@@ -0,0 +1,19 @@
1
+ import { createClient, createAccount as createGenLayerAccount, generatePrivateKey } from "genlayer-js";
2
+ import { simulator } from "genlayer-js/chains";
3
+
4
+ const accountPrivateKey = localStorage.getItem("accountPrivateKey")
5
+ ? localStorage.getItem("accountPrivateKey")
6
+ : null;
7
+ export const account = accountPrivateKey ? createGenLayerAccount(accountPrivateKey) : null;
8
+
9
+ export const createAccount = () => {
10
+ const newAccountPrivateKey = generatePrivateKey();
11
+ localStorage.setItem("accountPrivateKey", newAccountPrivateKey);
12
+ return createGenLayerAccount(newAccountPrivateKey);
13
+ };
14
+
15
+ export const removeAccount = () => {
16
+ localStorage.removeItem("accountPrivateKey");
17
+ };
18
+
19
+ export const client = createClient({ chain: simulator, account });
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -0,0 +1,8 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
4
+ theme: {
5
+ extend: {},
6
+ },
7
+ plugins: [],
8
+ };
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ // https://vitejs.dev/config/
5
+ export default defineConfig({
6
+ plugins: [vue()],
7
+ })
File without changes
@@ -0,0 +1,14 @@
1
+ import os
2
+
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+
8
+ def get_config() -> dict:
9
+ config = {
10
+ "rpc_protocol": os.environ["RPCPROTOCOL"],
11
+ "rpc_host": os.environ["RPCHOST"],
12
+ "rpc_port": os.environ["RPCPORT"],
13
+ }
14
+ return config
File without changes