feat(access): Bolt Card tap-to-enter access gate (ADR-003) #86

Merged
padreug merged 11 commits from feat/access-control-skeleton into dev 2026-09-20 13:16:22 +00:00
Showing only changes of commit 44a5ebbd12 - Show all commits

fix(access): reset router to home on re-lock so the reopened gate lands on idle

After a transaction with the gate enabled, the machine re-locks (cashOut/
cashIn → locked, not idle), so the view's isIdle watch never fires and the
router stays on /cash-out|/cash-in. When the next tap reopens the gate to
idle, the stale transaction view showed (e.g. a completed sell's collect
screen, stuck). Reset the route to / while locked (router-view hidden under
LockedView) so idle renders IdleView.
Patrick Mulligan 2026-08-06 22:58:49 +02:00 • committed by Padreug

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { onMounted, onUnmounted, ref, computed, watch } from 'vue'
import { useRoute } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import { useAtmStore } from '@/stores/atm'
import { useTheme } from '@/composables/useTheme'
import { setBranding } from '@/composables/useBranding'
@ -13,7 +13,21 @@ import ColorModeToggle from '@/components/ColorModeToggle.vue'
const atmStore = useAtmStore()
const route = useRoute()
const router = useRouter()
const { current: currentTheme, themes, colorMode } = useTheme()
// When the machine re-locks after a transaction (access gate enabled), the
// router is still on /cash-in or /cash-out under the LockedView overlay. Reset
// it to home so that when the gate reopens to `idle`, IdleView shows — not the
// stale transaction view (e.g. a completed cash-out's collect screen). Runs
// while locked, so the router-view is hidden; no flicker. The disabled-gate path
// (never dwells in `locked`) still returns home via each view's isIdle watch.
watch(
() => atmStore.isLocked,
(locked) => {
if (locked && route.path !== '/') void router.push('/')
}
)
const debugExpanded = ref(false)
const isSupport = computed(() => route.path === '/support')
// Network detected dynamically from Lightning invoice prefix
@ -111,9 +125,7 @@ onMounted(async () => {
// Same env → pairing-seed precedence as lightning.ts: on a blank-.env
// seed-driven machine the relay comes from the pairing transport, not env.
const relayUrl =
config?.relayUrl ||
import.meta.env.VITE_RELAY_URL ||
resolved?.transport?.relays?.[0]
config?.relayUrl || import.meta.env.VITE_RELAY_URL || resolved?.transport?.relays?.[0]
if (signer && relayUrl) {
const client = new NostrClient({ relays: [{ url: relayUrl }], signer })
await client.connect()