diff options
| author | Adam Soltys <[email protected]> | 2026-08-17 11:26:04 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-17 11:26:04 -0700 |
| commit | ea588ca8553a4c83be32ad36d27dc73038b39874 (patch) | |
| tree | 5eaa76ccd4d22ad24787477c3946f38a23a5ff77 /src | |
| parent | 574cb69de872365ebd57afba0da7fa0f0c4748a7 (diff) | |
| download | coinosv3-ea588ca8553a4c83be32ad36d27dc73038b39874.tar.gz coinosv3-ea588ca8553a4c83be32ad36d27dc73038b39874.zip | |
The import pane learns the entropy trick: the same fold, the same text, the same wallet — typed entropy fills the phrase field with its derived words and clears only what it filled
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01JtaatFfAbx91Nh3xqKVqKz
Diffstat (limited to 'src')
| -rw-r--r-- | src/app.js | 60 |
1 files changed, 40 insertions, 20 deletions
@@ -817,26 +817,9 @@ function createPane() { // have to parse it. Deterministic on purpose: the typed text alone // derives the words (live, as you type), so re-typing it IS an import; // clearing the field brings the randomly generated phrase back. - h('button', { - class: 'linklike small', style: 'align-self:flex-start', - onClick: () => { ui.ownEntropyOpen = !ui.ownEntropyOpen; render(); }, - }, (ui.ownEntropyOpen ? '▾ ' : '▸ ') + t('entropyToggle')), - ui.ownEntropyOpen - ? h('div', { class: 'col gap6' }, - h('p', { class: 'small muted', style: 'margin:0' }, t('entropyHint')), - h('div', { class: 'warn-box small' }, t('entropyWarn')), - h('textarea', { - rows: '2', style: 'font-family:var(--sans)', placeholder: t('entropyPlaceholder'), - autocapitalize: 'none', autocomplete: 'off', spellcheck: 'false', - value: ui.ownEntropy || '', - onInput: (e) => { - ui.ownEntropy = e.target.value; - const txt = ui.ownEntropy.trim(); - ui.draftMnemonic = txt ? newMnemonic(128, txt) : (ui.draftRandom || ui.draftMnemonic); - render(); - }, - })) - : null, + ...entropyPanel('ownEntropyOpen', 'ownEntropy', (txt) => { + ui.draftMnemonic = txt ? newMnemonic(128, txt) : (ui.draftRandom || ui.draftMnemonic); + }), optionsPanel(), h( 'button', @@ -907,6 +890,33 @@ function pickConfirm(words) { return [...idx].sort((a, b) => a - b).map((index) => ({ index, value: '' })); } +// The BYO-entropy fold, shared by Create (re-derives the draft phrase) and +// Import (fills the phrase field): the typed text alone determines the seed, +// so the same text recreates the same wallet anywhere. +function entropyPanel(openKey, textKey, onText) { + return [ + h('button', { + class: 'linklike small', style: 'align-self:flex-start', + onClick: () => { ui[openKey] = !ui[openKey]; render(); }, + }, (ui[openKey] ? '▾ ' : '▸ ') + t('entropyToggle')), + ui[openKey] + ? h('div', { class: 'col gap6' }, + h('p', { class: 'small muted', style: 'margin:0' }, t('entropyHint')), + h('div', { class: 'warn-box small' }, t('entropyWarn')), + h('textarea', { + rows: '2', style: 'font-family:var(--sans)', placeholder: t('entropyPlaceholder'), + autocapitalize: 'none', autocomplete: 'off', spellcheck: 'false', + value: ui[textKey] || '', + onInput: (e) => { + ui[textKey] = e.target.value; + onText(ui[textKey].trim()); + render(); + }, + })) + : null, + ]; +} + function importPane() { const ta = h('textarea', { placeholder: t('importPlaceholder'), @@ -925,6 +935,16 @@ function importPane() { h('span', { class: 'lab' }, t('importLabel')), pasteInto(ta, (text) => { ta.value = text; ui.importText = text; }) ), + // A wallet born from typed entropy comes back the same way: the text + // fills the phrase field with its derived words, visibly. Clearing the + // text clears only what it filled — a pasted phrase is left alone. + ...entropyPanel('importEntropyOpen', 'importEntropy', (txt) => { + if (txt) { + ui.importText = ui._entropyFilled = newMnemonic(128, txt); + } else if (ui.importText === ui._entropyFilled) { + ui.importText = ''; + } + }), optionsPanel(), h('button', { class: 'btn-primary btn-block', onClick: () => openWallet(ui.importText) }, t('openWallet')) ); |
