@meddleware/token-deployer-ui 0.0.2 → 0.0.4
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 +3 -1
- package/src/App.vue +1 -2
- package/src/component-styles.css +257 -0
- package/src/components/ConfigForm.vue +104 -93
- package/src/components/GithubPush.vue +4 -4
- package/src/components/IconPicker.vue +19 -73
- package/src/components/LicensePicker.vue +7 -9
- package/src/components/ResultPanel.vue +2 -2
- package/src/components/ReviewPanel.vue +3 -3
- package/src/components/TokenDeployerView.vue +81 -14
- package/src/components/WalletBar.vue +6 -7
- package/src/components/WalrusBlobBrowser.vue +2 -2
- package/src/components/WalrusIconUpload.vue +4 -4
- package/src/index.ts +1 -0
- package/src/main.ts +5 -1
- package/src/styles.css +3 -335
- package/src/components/AppNotice.vue +0 -15
- package/src/components/ColorModeControl.vue +0 -81
- package/src/components/FieldHint.vue +0 -79
- package/src/components/FormField.vue +0 -28
- package/src/components/FormSelect.vue +0 -43
- package/src/composables/useColorMode.ts +0 -76
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meddleware/token-deployer-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": { "default": "./src/index.ts" }
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
"verify:template": "node scripts/verify-bytecode.mjs && vitest run tests/templateArtifact.test.ts tests/templateParity.test.ts"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@meddleware/design-tokens": "^0.1.5",
|
|
34
|
+
"@meddleware/ui": "^0.1.23",
|
|
33
35
|
"@meddleware/wallet-adapter": "^0.0.7",
|
|
34
36
|
"@meddleware/walrus-relay": "^0.1.16",
|
|
35
37
|
"@mysten/bcs": "~2.1.0",
|
package/src/App.vue
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import WalletBar from './components/WalletBar.vue'
|
|
3
3
|
import TokenDeployerView from './components/TokenDeployerView.vue'
|
|
4
|
-
import ColorModeControl from '
|
|
5
|
-
import { useColorMode } from './composables/useColorMode.js'
|
|
4
|
+
import { ColorModeControl, useColorMode } from '@meddleware/ui'
|
|
6
5
|
|
|
7
6
|
const { mode: colorMode, set: setColorMode } = useColorMode('system')
|
|
8
7
|
</script>
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/* Component utility styles for TokenDeployerView and its sub-components.
|
|
2
|
+
Imported by index.ts so these are available in both standalone and library (dashboard) mode.
|
|
3
|
+
Relies on design-token CSS variables (--bg, --surface, --border, etc.) provided by the
|
|
4
|
+
consumer — either @meddleware/design-tokens (standalone) or the dashboard's own import. */
|
|
5
|
+
|
|
6
|
+
.card {
|
|
7
|
+
background: var(--surface);
|
|
8
|
+
border: 1px solid var(--border);
|
|
9
|
+
border-radius: var(--radius);
|
|
10
|
+
padding: 1.25rem;
|
|
11
|
+
margin: 1.5rem 0 1rem;
|
|
12
|
+
border-top: 2px solid var(--border);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
label {
|
|
16
|
+
display: block;
|
|
17
|
+
font-weight: 600;
|
|
18
|
+
margin: 0.9rem 0 0.3rem;
|
|
19
|
+
}
|
|
20
|
+
.hint {
|
|
21
|
+
color: var(--muted);
|
|
22
|
+
font-weight: 400;
|
|
23
|
+
font-size: 0.9rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
input,
|
|
27
|
+
select,
|
|
28
|
+
textarea {
|
|
29
|
+
width: 100%;
|
|
30
|
+
padding: 0.6rem 0.7rem;
|
|
31
|
+
font: inherit;
|
|
32
|
+
color: var(--text);
|
|
33
|
+
background: var(--bg);
|
|
34
|
+
border: 1px solid var(--border);
|
|
35
|
+
border-radius: 8px;
|
|
36
|
+
}
|
|
37
|
+
textarea {
|
|
38
|
+
min-height: 4rem;
|
|
39
|
+
resize: vertical;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
input[aria-invalid='true'],
|
|
43
|
+
select[aria-invalid='true'],
|
|
44
|
+
textarea[aria-invalid='true'] {
|
|
45
|
+
border-color: var(--danger);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.field-error {
|
|
49
|
+
color: var(--danger);
|
|
50
|
+
font-size: 0.88rem;
|
|
51
|
+
margin-top: 0.3rem;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
button {
|
|
55
|
+
font: inherit;
|
|
56
|
+
font-weight: 600;
|
|
57
|
+
padding: 0.6rem 1rem;
|
|
58
|
+
border-radius: 8px;
|
|
59
|
+
border: 1px solid var(--border);
|
|
60
|
+
background: var(--surface);
|
|
61
|
+
color: var(--text);
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
}
|
|
64
|
+
button.primary {
|
|
65
|
+
background: var(--accent);
|
|
66
|
+
color: var(--accent-contrast);
|
|
67
|
+
border-color: transparent;
|
|
68
|
+
}
|
|
69
|
+
button:disabled {
|
|
70
|
+
opacity: 0.55;
|
|
71
|
+
cursor: not-allowed;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.row {
|
|
75
|
+
display: flex;
|
|
76
|
+
gap: 0.75rem;
|
|
77
|
+
flex-wrap: wrap;
|
|
78
|
+
align-items: center;
|
|
79
|
+
}
|
|
80
|
+
.grid2 {
|
|
81
|
+
display: grid;
|
|
82
|
+
grid-template-columns: 1fr;
|
|
83
|
+
gap: 0 1rem;
|
|
84
|
+
}
|
|
85
|
+
@media (min-width: 520px) {
|
|
86
|
+
.grid2 {
|
|
87
|
+
grid-template-columns: 1fr 1fr;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fieldset {
|
|
92
|
+
background: var(--lift);
|
|
93
|
+
border: 1px solid var(--border);
|
|
94
|
+
border-radius: 8px;
|
|
95
|
+
padding: 0.5rem 1rem 1rem;
|
|
96
|
+
margin: 1rem 0;
|
|
97
|
+
}
|
|
98
|
+
legend {
|
|
99
|
+
font-weight: 700;
|
|
100
|
+
padding: 0 0.4rem;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
details {
|
|
104
|
+
margin: 1rem 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
details > summary {
|
|
108
|
+
color: var(--accent);
|
|
109
|
+
font-weight: 700;
|
|
110
|
+
margin: 0.5rem 0;
|
|
111
|
+
padding: 0.75rem;
|
|
112
|
+
background: var(--lift);
|
|
113
|
+
border-radius: 8px;
|
|
114
|
+
border: 1px solid transparent;
|
|
115
|
+
transition: border-color 0.2s ease;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
details > summary:hover {
|
|
119
|
+
border-color: var(--border);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
details[open] > summary {
|
|
123
|
+
border-color: var(--border);
|
|
124
|
+
margin-bottom: 1rem;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
details > fieldset {
|
|
128
|
+
margin-top: 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.permanent {
|
|
132
|
+
color: var(--danger);
|
|
133
|
+
font-weight: 600;
|
|
134
|
+
}
|
|
135
|
+
.mono {
|
|
136
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
137
|
+
word-break: break-all;
|
|
138
|
+
}
|
|
139
|
+
.badge {
|
|
140
|
+
display: inline-block;
|
|
141
|
+
font-size: 0.8rem;
|
|
142
|
+
padding: 0.15rem 0.5rem;
|
|
143
|
+
border-radius: 999px;
|
|
144
|
+
background: var(--border);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.visually-hidden {
|
|
148
|
+
position: absolute;
|
|
149
|
+
width: 1px;
|
|
150
|
+
height: 1px;
|
|
151
|
+
padding: 0;
|
|
152
|
+
margin: -1px;
|
|
153
|
+
overflow: hidden;
|
|
154
|
+
clip: rect(0 0 0 0);
|
|
155
|
+
white-space: nowrap;
|
|
156
|
+
border: 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.skip-link {
|
|
160
|
+
position: absolute;
|
|
161
|
+
left: 0.5rem;
|
|
162
|
+
top: -3rem;
|
|
163
|
+
z-index: 100;
|
|
164
|
+
background: var(--accent);
|
|
165
|
+
color: #fff;
|
|
166
|
+
padding: 0.5rem 0.9rem;
|
|
167
|
+
border-radius: 6px;
|
|
168
|
+
text-decoration: none;
|
|
169
|
+
transition: top 0.15s ease;
|
|
170
|
+
}
|
|
171
|
+
.skip-link:focus {
|
|
172
|
+
top: 0.5rem;
|
|
173
|
+
}
|
|
174
|
+
@media (prefers-reduced-motion: reduce) {
|
|
175
|
+
.skip-link {
|
|
176
|
+
transition: none;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.steps {
|
|
181
|
+
list-style: none;
|
|
182
|
+
padding: 0;
|
|
183
|
+
}
|
|
184
|
+
.steps li {
|
|
185
|
+
padding: 0.35rem 0;
|
|
186
|
+
color: var(--muted);
|
|
187
|
+
}
|
|
188
|
+
.steps li[data-state='active'] {
|
|
189
|
+
color: var(--text);
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
}
|
|
192
|
+
.steps li[data-state='done'] {
|
|
193
|
+
color: var(--ok);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.spinner {
|
|
197
|
+
width: 1em;
|
|
198
|
+
height: 1em;
|
|
199
|
+
border: 2px solid currentColor;
|
|
200
|
+
border-right-color: transparent;
|
|
201
|
+
border-radius: 50%;
|
|
202
|
+
display: inline-block;
|
|
203
|
+
animation: spin 0.7s linear infinite;
|
|
204
|
+
vertical-align: -0.15em;
|
|
205
|
+
}
|
|
206
|
+
@keyframes spin {
|
|
207
|
+
to {
|
|
208
|
+
transform: rotate(360deg);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
@media (prefers-reduced-motion: reduce) {
|
|
212
|
+
.spinner {
|
|
213
|
+
animation: none;
|
|
214
|
+
}
|
|
215
|
+
* {
|
|
216
|
+
scroll-behavior: auto;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
dialog {
|
|
221
|
+
background: var(--surface);
|
|
222
|
+
border: 1px solid var(--border);
|
|
223
|
+
border-radius: var(--radius);
|
|
224
|
+
padding: 1.5rem;
|
|
225
|
+
width: min(420px, 90vw);
|
|
226
|
+
max-height: 90vh;
|
|
227
|
+
overflow-y: auto;
|
|
228
|
+
color: var(--text);
|
|
229
|
+
}
|
|
230
|
+
dialog::backdrop {
|
|
231
|
+
background: rgba(0, 0, 0, 0.45);
|
|
232
|
+
-webkit-backdrop-filter: blur(2px);
|
|
233
|
+
backdrop-filter: blur(2px);
|
|
234
|
+
}
|
|
235
|
+
.dialog-header {
|
|
236
|
+
display: flex;
|
|
237
|
+
justify-content: space-between;
|
|
238
|
+
align-items: center;
|
|
239
|
+
margin-bottom: 1.25rem;
|
|
240
|
+
}
|
|
241
|
+
.dialog-header h2 {
|
|
242
|
+
margin: 0;
|
|
243
|
+
font-size: 1.1rem;
|
|
244
|
+
}
|
|
245
|
+
.wallet-list {
|
|
246
|
+
display: flex;
|
|
247
|
+
flex-direction: column;
|
|
248
|
+
gap: 0.5rem;
|
|
249
|
+
margin-top: 1rem;
|
|
250
|
+
}
|
|
251
|
+
.wallet-list button {
|
|
252
|
+
display: flex;
|
|
253
|
+
align-items: center;
|
|
254
|
+
gap: 0.6rem;
|
|
255
|
+
width: 100%;
|
|
256
|
+
justify-content: flex-start;
|
|
257
|
+
}
|
|
@@ -6,9 +6,9 @@ import { deriveStructName } from '../lib/validation.js'
|
|
|
6
6
|
import type { Network } from '../lib/types.js'
|
|
7
7
|
import LicensePicker from './LicensePicker.vue'
|
|
8
8
|
import IconPicker from './IconPicker.vue'
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
import { UiFormField, UiSelect, UiFieldHint } from '@meddleware/ui'
|
|
10
|
+
|
|
11
|
+
export type ConfigFormStep = 'identity' | 'token' | 'settings'
|
|
12
12
|
|
|
13
13
|
const props = defineProps<{
|
|
14
14
|
form: FormModel
|
|
@@ -16,8 +16,9 @@ const props = defineProps<{
|
|
|
16
16
|
canProceed: boolean
|
|
17
17
|
network: Network
|
|
18
18
|
connected: boolean
|
|
19
|
+
formStep: ConfigFormStep
|
|
19
20
|
}>()
|
|
20
|
-
const emit = defineEmits<{ (e: '
|
|
21
|
+
const emit = defineEmits<{ (e: 'next'): void; (e: 'back'): void }>()
|
|
21
22
|
|
|
22
23
|
const structPreview = computed(() => {
|
|
23
24
|
const m = props.form.moduleName.trim()
|
|
@@ -41,152 +42,162 @@ function onBlur(key: string): void {
|
|
|
41
42
|
</script>
|
|
42
43
|
|
|
43
44
|
<template>
|
|
44
|
-
<form novalidate @submit.prevent="emit('
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
</
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
</
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
45
|
+
<form novalidate @submit.prevent="emit('next')">
|
|
46
|
+
|
|
47
|
+
<!-- Step 1: Identity -->
|
|
48
|
+
<template v-if="formStep === 'identity'">
|
|
49
|
+
<fieldset>
|
|
50
|
+
<legend>Package identity <span class="permanent">(permanent)</span></legend>
|
|
51
|
+
<div class="grid2">
|
|
52
|
+
<UiFormField id="package" label="Package name" :error="visibleError('packageName')" v-slot="{ attrs }">
|
|
53
|
+
<input v-bind="attrs" v-model="form.packageName" placeholder="my_token" autocomplete="off" @blur="onBlur('packageName')" />
|
|
54
|
+
</UiFormField>
|
|
55
|
+
<UiFormField id="module" label="Module name" :error="visibleError('moduleName')" v-slot="{ attrs }">
|
|
56
|
+
<input v-bind="attrs" v-model="form.moduleName" placeholder="mytoken" autocomplete="off" @blur="onBlur('moduleName')" />
|
|
57
|
+
</UiFormField>
|
|
58
|
+
</div>
|
|
59
|
+
<p class="hint" aria-live="polite">
|
|
60
|
+
<template v-if="identifierError">
|
|
61
|
+
Fix the package and module names to preview the coin type.
|
|
62
|
+
</template>
|
|
63
|
+
<template v-else>
|
|
64
|
+
Coin type will be <span class="mono">{{ coinTypePreview }}</span
|
|
65
|
+
>. The witness struct <span class="mono">{{ structPreview }}</span> is derived from
|
|
66
|
+
the module name (a Sui requirement).
|
|
67
|
+
</template>
|
|
68
|
+
</p>
|
|
69
|
+
</fieldset>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<!-- Step 2: Token -->
|
|
73
|
+
<template v-if="formStep === 'token'">
|
|
74
|
+
<fieldset>
|
|
75
|
+
<legend>Token details</legend>
|
|
76
|
+
|
|
77
|
+
<div class="grid2">
|
|
78
|
+
<UiFormField id="name" label="Token name" :error="visibleError('name')" v-slot="{ attrs }">
|
|
79
|
+
<input v-bind="attrs" v-model="form.name" autocomplete="off" @blur="onBlur('name')" />
|
|
80
|
+
</UiFormField>
|
|
81
|
+
<UiFormField id="symbol" label="Symbol" :error="visibleError('symbol')" v-slot="{ attrs }">
|
|
82
|
+
<input v-bind="attrs" v-model="form.symbol" autocomplete="off" @blur="onBlur('symbol')" />
|
|
83
|
+
</UiFormField>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<UiFormField id="description" label="Description" :error="visibleError('description')">
|
|
87
|
+
<template #label-suffix> <span class="hint">(optional)</span></template>
|
|
88
|
+
<template #default="{ attrs }">
|
|
89
|
+
<textarea v-bind="attrs" v-model="form.description" @blur="onBlur('description')" />
|
|
90
|
+
</template>
|
|
91
|
+
</UiFormField>
|
|
92
|
+
|
|
93
|
+
<UiFormField id="decimals" label="Decimals" :error="visibleError('decimals')">
|
|
94
|
+
<template #label-suffix> <span class="permanent">(permanent)</span></template>
|
|
95
|
+
<template #default="{ attrs }">
|
|
96
|
+
<input v-bind="attrs" v-model="form.decimals" inputmode="numeric" @blur="onBlur('decimals')" />
|
|
97
|
+
</template>
|
|
98
|
+
</UiFormField>
|
|
99
|
+
|
|
100
|
+
<IconPicker
|
|
101
|
+
v-model="form.iconUrl"
|
|
102
|
+
:network="network"
|
|
103
|
+
:connected="connected"
|
|
104
|
+
:error="visibleError('iconUrl')"
|
|
105
|
+
@blur="onBlur('iconUrl')"
|
|
106
|
+
/>
|
|
107
|
+
</fieldset>
|
|
108
|
+
</template>
|
|
109
|
+
|
|
110
|
+
<!-- Step 3: Settings -->
|
|
111
|
+
<template v-if="formStep === 'settings'">
|
|
104
112
|
<fieldset>
|
|
105
|
-
<legend
|
|
113
|
+
<legend>Supply & policies</legend>
|
|
106
114
|
|
|
107
|
-
<
|
|
115
|
+
<UiFormField id="supply" label="Initial supply" :error="visibleError('initialSupply')">
|
|
108
116
|
<template #label-suffix>
|
|
109
|
-
<
|
|
117
|
+
<UiFieldHint field-id="supply">
|
|
110
118
|
The number of whole tokens to mint and send to the recipient at deployment.
|
|
111
119
|
Uses your chosen decimal precision — with 9 decimals, 1 token = 1,000,000,000 base units on-chain.
|
|
112
120
|
Enter <b>0</b> or leave blank for no initial supply.
|
|
113
121
|
You can mint more later if you choose the Mintable supply policy.
|
|
114
|
-
</
|
|
122
|
+
</UiFieldHint>
|
|
115
123
|
</template>
|
|
116
124
|
<template #default="{ attrs }">
|
|
117
125
|
<input v-bind="attrs" v-model="form.initialSupply" inputmode="numeric" placeholder="0" @blur="onBlur('initialSupply')" />
|
|
118
126
|
</template>
|
|
119
|
-
</
|
|
127
|
+
</UiFormField>
|
|
120
128
|
|
|
121
129
|
<div class="grid2">
|
|
122
|
-
<
|
|
130
|
+
<UiFormField id="supply-policy" label="Supply">
|
|
123
131
|
<template #label-suffix>
|
|
124
|
-
<
|
|
132
|
+
<UiFieldHint field-id="supply-policy">
|
|
125
133
|
<b>Mintable</b>: you keep the TreasuryCap and can mint more tokens at any time.<br />
|
|
126
134
|
<b>Fixed</b>: the TreasuryCap is frozen — the total supply is sealed at deployment.
|
|
127
|
-
</
|
|
135
|
+
</UiFieldHint>
|
|
128
136
|
</template>
|
|
129
137
|
<template #default="{ attrs }">
|
|
130
|
-
<
|
|
138
|
+
<UiSelect v-bind="attrs" v-model="form.supplyPolicy">
|
|
131
139
|
<option value="mintable">Mintable</option>
|
|
132
140
|
<option value="fixed">Fixed</option>
|
|
133
|
-
</
|
|
141
|
+
</UiSelect>
|
|
134
142
|
</template>
|
|
135
|
-
</
|
|
136
|
-
<
|
|
143
|
+
</UiFormField>
|
|
144
|
+
<UiFormField id="metadata-policy" label="Metadata">
|
|
137
145
|
<template #label-suffix>
|
|
138
|
-
<
|
|
146
|
+
<UiFieldHint field-id="metadata-policy">
|
|
139
147
|
<b>Updatable</b>: you keep the MetadataCap and can later change the name, symbol,
|
|
140
148
|
description, or icon.<br />
|
|
141
149
|
<b>Frozen</b>: the MetadataCap is discarded — all metadata is permanently locked.
|
|
142
|
-
</
|
|
150
|
+
</UiFieldHint>
|
|
143
151
|
</template>
|
|
144
152
|
<template #default="{ attrs }">
|
|
145
|
-
<
|
|
153
|
+
<UiSelect v-bind="attrs" v-model="form.metadataPolicy">
|
|
146
154
|
<option value="updatable">Updatable</option>
|
|
147
155
|
<option value="frozen">Frozen</option>
|
|
148
|
-
</
|
|
156
|
+
</UiSelect>
|
|
149
157
|
</template>
|
|
150
|
-
</
|
|
158
|
+
</UiFormField>
|
|
151
159
|
</div>
|
|
152
160
|
|
|
153
|
-
<
|
|
161
|
+
<UiFormField id="package-policy" label="Package code">
|
|
154
162
|
<template #label-suffix>
|
|
155
|
-
<
|
|
163
|
+
<UiFieldHint field-id="package-policy">
|
|
156
164
|
<b>Immutable</b>: the UpgradeCap is burned — the on-chain code is sealed.
|
|
157
165
|
Recommended for trust and auditability.<br />
|
|
158
166
|
<b>Upgradeable</b>: you keep the UpgradeCap and can push code changes to the package
|
|
159
167
|
after deployment.
|
|
160
|
-
</
|
|
168
|
+
</UiFieldHint>
|
|
161
169
|
</template>
|
|
162
170
|
<template #default="{ attrs }">
|
|
163
|
-
<
|
|
171
|
+
<UiSelect v-bind="attrs" v-model="form.packagePolicy">
|
|
164
172
|
<option value="immutable">Immutable</option>
|
|
165
173
|
<option value="upgradeable">Upgradeable</option>
|
|
166
|
-
</
|
|
174
|
+
</UiSelect>
|
|
167
175
|
</template>
|
|
168
|
-
</
|
|
176
|
+
</UiFormField>
|
|
169
177
|
|
|
170
|
-
<
|
|
178
|
+
<UiFormField id="recipient" label="Recipient" :error="visibleError('recipient')">
|
|
171
179
|
<template #label-suffix>
|
|
172
|
-
<
|
|
180
|
+
<UiFieldHint field-id="recipient">
|
|
173
181
|
The Sui address that receives the TreasuryCap, MetadataCap, UpgradeCap (if kept),
|
|
174
182
|
and any initial supply minted at deployment.
|
|
175
183
|
Leave blank to send everything to the connected wallet.
|
|
176
184
|
Enter a different address to separate the deployer wallet from the custody wallet.
|
|
177
|
-
</
|
|
185
|
+
</UiFieldHint>
|
|
178
186
|
</template>
|
|
179
187
|
<template #default="{ attrs }">
|
|
180
188
|
<input v-bind="attrs" v-model="form.recipient" placeholder="0x…" autocomplete="off" @blur="onBlur('recipient')" />
|
|
181
189
|
</template>
|
|
182
|
-
</
|
|
190
|
+
</UiFormField>
|
|
183
191
|
|
|
184
192
|
<LicensePicker v-model="form.license" @name="form.licenseName = $event" />
|
|
185
193
|
</fieldset>
|
|
186
|
-
</
|
|
194
|
+
</template>
|
|
187
195
|
|
|
188
196
|
<div class="row" style="margin-top: 1rem">
|
|
189
|
-
<button
|
|
197
|
+
<button v-if="formStep !== 'identity'" type="button" @click="emit('back')">Back</button>
|
|
198
|
+
<button type="submit" class="primary" :disabled="!canProceed">
|
|
199
|
+
{{ formStep === 'settings' ? 'Review & deploy' : 'Next' }}
|
|
200
|
+
</button>
|
|
190
201
|
</div>
|
|
191
202
|
</form>
|
|
192
203
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ref } from 'vue'
|
|
3
3
|
import type { PublishResult, TokenConfig } from '../lib/types.js'
|
|
4
|
-
import
|
|
4
|
+
import { UiNotice } from '@meddleware/ui'
|
|
5
5
|
import { buildPackageFiles } from '../lib/generatePackage.js'
|
|
6
6
|
import { fetchLicenseText } from '../lib/licenses.js'
|
|
7
7
|
import { createRepoAndPush } from '../lib/github.js'
|
|
@@ -91,10 +91,10 @@ async function push(): Promise<void> {
|
|
|
91
91
|
<span v-if="progress" class="hint" aria-live="polite">{{ progress }}</span>
|
|
92
92
|
</div>
|
|
93
93
|
|
|
94
|
-
<
|
|
95
|
-
<
|
|
94
|
+
<UiNotice v-if="error" type="error">{{ error }}</UiNotice>
|
|
95
|
+
<UiNotice v-if="doneUrl" type="ok">
|
|
96
96
|
Pushed: <a :href="doneUrl" target="_blank" rel="noopener noreferrer">{{ doneUrl }}</a>
|
|
97
|
-
</
|
|
97
|
+
</UiNotice>
|
|
98
98
|
</div>
|
|
99
99
|
</div>
|
|
100
100
|
</template>
|