diff --git a/neode-ui/src/components/WalletSettingsModal.vue b/neode-ui/src/components/WalletSettingsModal.vue index d3e54397..a9559b46 100644 --- a/neode-ui/src/components/WalletSettingsModal.vue +++ b/neode-ui/src/components/WalletSettingsModal.vue @@ -120,6 +120,7 @@
{{ fedError }}
+
Federation joined.
@@ -178,6 +179,7 @@ const federations = ref([]) const inviteCode = ref('') const joiningFed = ref(false) const fedError = ref('') +const fedJoinedOk = ref(false) watch( () => props.show, @@ -259,18 +261,36 @@ async function loadFederations() { async function joinFederation() { if (!fedimintBackendReady || !inviteCode.value.trim()) return + const before = federations.value.length joiningFed.value = true fedError.value = '' + fedJoinedOk.value = false try { await rpcClient.call<{ federation_id: string }>({ method: 'wallet.fedimint-join', params: { invite_code: inviteCode.value.trim() }, + // Joining a federation is heavy (downloads the federation config + joins + // the consensus); it routinely takes longer than the default 15s. Give it + // headroom past the backend's own 60s clientd timeout. + timeout: 90000, }) inviteCode.value = '' await loadFederations() + fedJoinedOk.value = true emit('changed') } catch (err: unknown) { - fedError.value = err instanceof Error ? err.message : 'Failed to join federation' + // A slow join often still completes server-side after the client gives up, + // so don't cry failure blindly — re-check the list. If a new federation + // appeared, the join actually worked; surface success instead of a scary + // (and wrong) timeout error. + await loadFederations() + if (federations.value.length > before) { + inviteCode.value = '' + fedJoinedOk.value = true + emit('changed') + } else { + fedError.value = err instanceof Error ? err.message : 'Failed to join federation' + } } finally { joiningFed.value = false }