mirror of
https://github.com/dergigi/boris.git
synced 2025-12-26 19:14:52 +01:00
refactor: simplify bunker implementation following applesauce patterns
- Remove bunkerFixVersion migration logic - Simplify account loading to match applesauce examples - Simplify reconnectBunkerSigner (no waiting, no complex logging) - Direct nip04/nip44 exposure from signer (like ExtensionAccount) - Clean up bookmark service account checking - Keep debug logs for now until verified working
This commit is contained in:
47
src/App.tsx
47
src/App.tsx
@@ -199,34 +199,15 @@ function App() {
|
||||
|
||||
pool.group(RELAYS)
|
||||
|
||||
// Load persisted accounts from localStorage
|
||||
try {
|
||||
const accountsJson = localStorage.getItem('accounts')
|
||||
if (accountsJson) {
|
||||
const parsed = JSON.parse(accountsJson)
|
||||
|
||||
// Clear old bunker accounts (they were created with wrong setup)
|
||||
const bunkerFixVersion = localStorage.getItem('bunkerFixVersion')
|
||||
if (bunkerFixVersion !== '1') {
|
||||
console.log('[bunker] Clearing old bunker accounts (need to reconnect with fixed setup)')
|
||||
const nonBunkerAccounts = parsed.filter((acc: any) => acc.type !== 'nostr-connect')
|
||||
if (nonBunkerAccounts.length > 0) {
|
||||
await accounts.fromJSON(nonBunkerAccounts)
|
||||
}
|
||||
localStorage.setItem('bunkerFixVersion', '1')
|
||||
localStorage.removeItem('active')
|
||||
} else {
|
||||
await accounts.fromJSON(parsed)
|
||||
|
||||
// Restore active account
|
||||
const activeId = localStorage.getItem('active')
|
||||
if (activeId && accounts.getAccount(activeId)) {
|
||||
accounts.setActive(activeId)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[bunker] Failed to restore accounts:', err)
|
||||
// Load persisted accounts from localStorage (per applesauce examples)
|
||||
const savedAccounts = JSON.parse(localStorage.getItem('accounts') || '[]')
|
||||
await accounts.fromJSON(savedAccounts)
|
||||
|
||||
// Restore active account
|
||||
const activeAccountId = localStorage.getItem('active')
|
||||
if (activeAccountId) {
|
||||
const account = accounts.getAccount(activeAccountId)
|
||||
if (account) accounts.setActive(account)
|
||||
}
|
||||
|
||||
// Persist accounts to localStorage
|
||||
@@ -242,18 +223,12 @@ function App() {
|
||||
}
|
||||
})
|
||||
|
||||
// Reconnect bunker signers on page load
|
||||
// Reconnect bunker signers on page load (per applesauce pattern)
|
||||
const reconnectedAccounts = new Set<string>()
|
||||
const bunkerReconnectSub = accounts.active$.subscribe(async (account) => {
|
||||
if (account?.type === 'nostr-connect' && !reconnectedAccounts.has(account.id)) {
|
||||
reconnectedAccounts.add(account.id)
|
||||
|
||||
try {
|
||||
await reconnectBunkerSigner(account as Accounts.NostrConnectAccount<unknown>, pool)
|
||||
console.log('[bunker] Reconnected to bunker signer')
|
||||
} catch (error) {
|
||||
console.error('[bunker] Failed to reconnect signer:', error)
|
||||
}
|
||||
await reconnectBunkerSigner(account as Accounts.NostrConnectAccount<unknown>, pool)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -83,49 +83,16 @@ export const fetchBookmarks = async (
|
||||
// Keep existing bookmarks visible; do not clear list if nothing new found
|
||||
return
|
||||
}
|
||||
// Aggregate across events
|
||||
// Get account with signer for decryption
|
||||
const maybeAccount = activeAccount as AccountWithExtension
|
||||
console.log('[bunker] 🔐 Account object:', {
|
||||
hasSignEvent: typeof maybeAccount?.signEvent === 'function',
|
||||
hasSigner: !!maybeAccount?.signer,
|
||||
accountType: maybeAccount?.type || typeof maybeAccount,
|
||||
accountKeys: maybeAccount ? Object.keys(maybeAccount) : []
|
||||
})
|
||||
|
||||
// For ExtensionAccount, we need a signer with nip04/nip44 for decrypting hidden content
|
||||
// The ExtensionAccount itself has nip04/nip44 getters that proxy to the signer
|
||||
let signerCandidate: unknown = maybeAccount
|
||||
|
||||
// Fallback to raw signer if account doesn't expose nip04/nip44
|
||||
const hasNip04Prop = (signerCandidate as { nip04?: unknown })?.nip04 !== undefined
|
||||
const hasNip44Prop = (signerCandidate as { nip44?: unknown })?.nip44 !== undefined
|
||||
|
||||
console.log('[bunker] 🔍 Account nip04/nip44 check:', {
|
||||
hasNip04Prop,
|
||||
hasNip44Prop,
|
||||
nip04Type: typeof (signerCandidate as { nip04?: unknown })?.nip04,
|
||||
nip44Type: typeof (signerCandidate as { nip44?: unknown })?.nip44
|
||||
})
|
||||
|
||||
if (signerCandidate && !hasNip04Prop && !hasNip44Prop && maybeAccount?.signer) {
|
||||
// Fallback to the raw signer if account doesn't have nip04/nip44
|
||||
console.log('[bunker] ⚠️ Account missing nip04/nip44, falling back to signer')
|
||||
signerCandidate = maybeAccount.signer
|
||||
|
||||
const signerHasNip04 = (signerCandidate as { nip04?: unknown })?.nip04 !== undefined
|
||||
const signerHasNip44 = (signerCandidate as { nip44?: unknown })?.nip44 !== undefined
|
||||
console.log('[bunker] 🔍 Signer nip04/nip44 check:', {
|
||||
signerHasNip04,
|
||||
signerHasNip44,
|
||||
nip04Type: typeof (signerCandidate as { nip04?: unknown })?.nip04,
|
||||
nip44Type: typeof (signerCandidate as { nip44?: unknown })?.nip44
|
||||
})
|
||||
}
|
||||
|
||||
console.log('[bunker] 🔑 Final signer candidate:', {
|
||||
exists: !!signerCandidate,
|
||||
type: typeof signerCandidate,
|
||||
hasNip04: hasNip04Decrypt(signerCandidate),
|
||||
hasNip44: hasNip44Decrypt(signerCandidate)
|
||||
})
|
||||
const { publicItemsAll, privateItemsAll, newestCreatedAt, latestContent, allTags } = await collectBookmarksFromEvents(
|
||||
bookmarkListEvents,
|
||||
activeAccount,
|
||||
|
||||
@@ -28,102 +28,31 @@ export function getDefaultBunkerPermissions(): string[] {
|
||||
|
||||
/**
|
||||
* Reconnect a bunker signer after page load
|
||||
* Ensures the signer is listening and connected to the correct relays
|
||||
* Ensures the signer is listening and ready for signing/decryption
|
||||
*/
|
||||
export async function reconnectBunkerSigner(
|
||||
account: Accounts.NostrConnectAccount<unknown>,
|
||||
pool: RelayPool
|
||||
): Promise<void> {
|
||||
// Add bunker relays to pool for signing communication
|
||||
// Add bunker relays to pool
|
||||
if (account.signer.relays) {
|
||||
const bunkerRelays = account.signer.relays
|
||||
pool.group(bunkerRelays)
|
||||
|
||||
// Wait for at least one bunker relay to be connected
|
||||
// This ensures signing/decryption requests can be sent
|
||||
console.log('[bunker] Waiting for relay connections...', bunkerRelays)
|
||||
await new Promise<void>((resolve) => {
|
||||
const checkInterval = setInterval(() => {
|
||||
const connectedRelays = bunkerRelays.filter(url => {
|
||||
const relay = pool.relays.get(url)
|
||||
return relay?.connected
|
||||
})
|
||||
|
||||
if (connectedRelays.length > 0) {
|
||||
console.log('[bunker] ✅ Connected to', connectedRelays.length, 'bunker relay(s)')
|
||||
clearInterval(checkInterval)
|
||||
resolve()
|
||||
}
|
||||
}, 100)
|
||||
|
||||
// Timeout after 5 seconds
|
||||
setTimeout(() => {
|
||||
clearInterval(checkInterval)
|
||||
console.warn('[bunker] ⚠️ Timeout waiting for relay connections, proceeding anyway')
|
||||
resolve()
|
||||
}, 5000)
|
||||
})
|
||||
pool.group(account.signer.relays)
|
||||
}
|
||||
|
||||
// Open signer subscription if not already listening
|
||||
// Open signer subscription for NIP-46 responses
|
||||
if (!account.signer.listening) {
|
||||
console.log('[bunker] Opening signer subscription for NIP-46 responses...')
|
||||
await account.signer.open()
|
||||
console.log('[bunker] ✅ Signer subscription active, listening for bunker responses')
|
||||
} else {
|
||||
console.log('[bunker] Signer already listening')
|
||||
}
|
||||
|
||||
// Mark as connected (bunker remembers permissions from initial connection)
|
||||
account.signer.isConnected = true
|
||||
console.log('[bunker] Signer marked as connected, ready for signing/decryption')
|
||||
|
||||
// Expose nip04/nip44 at account level for compatibility with logging
|
||||
// Cache wrapped methods to ensure they're used consistently
|
||||
// Expose nip04/nip44 at account level (like ExtensionAccount does)
|
||||
if (!('nip04' in account)) {
|
||||
const nip04Wrapped = {
|
||||
encrypt: async (pubkey: string, plaintext: string) => {
|
||||
console.log('[bunker] 🔐 nip04.encrypt called', { pubkey: pubkey.slice(0, 8) })
|
||||
const result = await account.signer.nip04!.encrypt(pubkey, plaintext)
|
||||
console.log('[bunker] ✅ nip04.encrypt completed')
|
||||
return result
|
||||
},
|
||||
decrypt: async (pubkey: string, ciphertext: string) => {
|
||||
console.log('[bunker] 🔓 nip04.decrypt called', { pubkey: pubkey.slice(0, 8), ciphertextLength: ciphertext.length })
|
||||
try {
|
||||
const result = await account.signer.nip04!.decrypt(pubkey, ciphertext)
|
||||
console.log('[bunker] ✅ nip04.decrypt completed')
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error('[bunker] ❌ nip04.decrypt failed:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
};
|
||||
(account as any).nip04 = nip04Wrapped
|
||||
(account as any).nip04 = account.signer.nip04
|
||||
}
|
||||
|
||||
if (!('nip44' in account)) {
|
||||
const nip44Wrapped = {
|
||||
encrypt: async (pubkey: string, plaintext: string) => {
|
||||
console.log('[bunker] 🔐 nip44.encrypt called', { pubkey: pubkey.slice(0, 8) })
|
||||
const result = await account.signer.nip44!.encrypt(pubkey, plaintext)
|
||||
console.log('[bunker] ✅ nip44.encrypt completed')
|
||||
return result
|
||||
},
|
||||
decrypt: async (pubkey: string, ciphertext: string) => {
|
||||
console.log('[bunker] 🔓 nip44.decrypt called', { pubkey: pubkey.slice(0, 8), ciphertextLength: ciphertext.length })
|
||||
try {
|
||||
const result = await account.signer.nip44!.decrypt(pubkey, ciphertext)
|
||||
console.log('[bunker] ✅ nip44.decrypt completed', { plaintextLength: result.length })
|
||||
return result
|
||||
} catch (err) {
|
||||
console.error('[bunker] ❌ nip44.decrypt failed:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
};
|
||||
(account as any).nip44 = nip44Wrapped
|
||||
(account as any).nip44 = account.signer.nip44
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user