sattle: Quasar PWA scaffold with lnurlcash-kit protocol core

M1: Quasar 2 / Vue 3 / TS / Pinia / i18n / PWA app shell in the lnurl-wallet
palette (#002222/#004444/#55ffcc, Noto Sans). Protocol layer is the external
lnurlcash-kit library (git dependency on the fork until upstream merges the
prepare fix / publishes to npm); keys.ts + receive.ts vendored from
lnurl-wallet with the derivation domain renamed to 'sattle'. Nix dev shell,
ci workflow (typecheck, vitest, pwa build).
This commit is contained in:
2026-08-19 13:29:34 +02:00
commit 54d6112414
60 changed files with 14447 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
<template>
<div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
<div>
<div style="font-size: 30vh">404</div>
<div class="text-h2" style="opacity: 0.4">Oops. Nothing here...</div>
<q-btn
class="q-mt-xl"
color="white"
text-color="blue"
unelevated
to="/"
label="Go Home"
no-caps
/>
</div>
</div>
</template>
+95
View File
@@ -0,0 +1,95 @@
<template>
<q-page class="column items-center q-pa-md">
<!-- balance hero: placeholder until M2 wires the note store -->
<q-card class="sattle-card balance-card full-width q-mt-xl q-pa-lg text-center">
<div class="text-h2 text-weight-bold text-primary">0</div>
<div class="text-subtitle1 text-grey-5">sats</div>
</q-card>
<div class="col" />
<!-- primary actions: visual only, protocol flows land in M2 -->
<div class="row full-width justify-center items-center q-gutter-md q-mb-xl">
<q-btn
unelevated
color="secondary"
text-color="primary"
icon="call_received"
label="Receive"
class="action-btn"
@click="showReceive = true"
/>
<q-btn
fab
color="primary"
text-color="dark"
icon="qr_code_scanner"
aria-label="Scan"
class="scan-btn"
@click="showScan = true"
/>
<q-btn
unelevated
color="secondary"
text-color="primary"
icon="call_made"
label="Send"
class="action-btn"
@click="showSend = true"
/>
</div>
<q-dialog v-model="showReceive">
<q-card class="sattle-card q-pa-lg">
<div class="text-h6">Receive</div>
<div class="text-grey-5 q-mt-sm">Coming in milestone M2.</div>
<q-card-actions align="right">
<q-btn v-close-popup flat label="Close" color="primary" />
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog v-model="showSend">
<q-card class="sattle-card q-pa-lg">
<div class="text-h6">Send</div>
<div class="text-grey-5 q-mt-sm">Coming in milestone M2.</div>
<q-card-actions align="right">
<q-btn v-close-popup flat label="Close" color="primary" />
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog v-model="showScan">
<q-card class="sattle-card q-pa-lg">
<div class="text-h6">Scan</div>
<div class="text-grey-5 q-mt-sm">Coming in milestone M2.</div>
<q-card-actions align="right">
<q-btn v-close-popup flat label="Close" color="primary" />
</q-card-actions>
</q-card>
</q-dialog>
</q-page>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const showReceive = ref(false);
const showSend = ref(false);
const showScan = ref(false);
</script>
<style lang="scss" scoped>
.balance-card {
max-width: 420px;
}
.action-btn {
min-width: 120px;
border-radius: 8px;
}
.scan-btn {
margin: 0 8px;
}
</style>
+37
View File
@@ -0,0 +1,37 @@
<template>
<q-page class="q-pa-md">
<div class="text-h5 text-weight-bold q-mb-md">Settings</div>
<!-- group shells only - entries are placeholders until their milestone
lands (see project plan: M2 flows, M3 mints, M4 backup/security,
M5 NWC) -->
<q-list
v-for="group in groups"
:key="group.label"
class="sattle-card q-mb-md"
bordered
separator
>
<q-item-label header class="text-primary text-weight-bold">
{{ group.label }}
</q-item-label>
<q-item v-for="item in group.items" :key="item" disable>
<q-item-section>{{ item }}</q-item-section>
</q-item>
</q-list>
</q-page>
</template>
<script setup lang="ts">
const groups: { label: string; items: string[] }[] = [
{ label: 'Wallet', items: ['Backup', 'Security'] },
{ label: 'Connections', items: ['Nostr Wallet Connect', 'Nostr'] },
{ label: 'Mints', items: ['Manage mints', 'Move funds'] },
{ label: 'Preferences', items: ['Appearance', 'Language', 'Fiat unit'] },
{
label: 'Advanced',
items: ['Notes', 'Offline mode', 'Activity log', 'Export / import', 'Developer'],
},
{ label: 'About', items: ['Docs', 'Protocol'] },
];
</script>
+34
View File
@@ -0,0 +1,34 @@
<template>
<q-page class="column items-center justify-center q-pa-md">
<div class="text-h3 text-weight-bold text-primary">sattle</div>
<div class="text-subtitle1 text-grey-5 q-mt-sm q-mb-xl text-center">
A wallet for lnurlcash bearer notes.
</div>
<!-- onboarding placeholder: create/restore flows land in M4 -->
<q-btn
unelevated
color="secondary"
text-color="primary"
label="Create wallet"
class="full-width q-mb-sm onboarding-btn"
disable
/>
<q-btn
outline
color="primary"
label="Restore wallet"
class="full-width onboarding-btn"
disable
/>
</q-page>
</template>
<script setup lang="ts"></script>
<style lang="scss" scoped>
.onboarding-btn {
max-width: 320px;
border-radius: 8px;
}
</style>