fix(receive): avoid 'Mint info not initialized' when source mint is offline#1029
fix(receive): avoid 'Mint info not initialized' when source mint is offline#1029gudnuf wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
| }); | ||
|
|
||
| // wallet.purpose throws when offline (mint info wasn't loaded). | ||
| const purpose = isOnline ? wallet.purpose : 'transactional'; |
There was a problem hiding this comment.
is it safe to default to transactional? can this cause some issues?
There was a problem hiding this comment.
hmm maybe not. My thinking at first was that it doesn't matter because the account is offline.
I asked claude and it pointed out that we would also need to handle the wallet being offline when checking canSendToLightning and canReceiveFromLightning because those use the mint info to check if nuts 4 or 5 are supported.
I think it might be better to check when receiving a token if the mint is offline and then throw and handle that error rather than trying to set a fake purpose and chasing down everywhere that relies on the wallet being online, wdyt?
There was a problem hiding this comment.
I think what would be safest is to introduce purpose unknown or something like that which will force us to handle it explicitly
314f0fb to
22cde9d
Compare
22cde9d to
8d5359a
Compare
8d5359a to
24819ff
Compare
beea25a to
91df2f5
Compare
Pasting a Cashu token whose source mint is unreachable was crashing the /receive/cashu/token flow with "Mint info not initialized; call loadMint or loadMintFromCache first" (Sentry: AGICASH-9S, 9Y, 93, 7G, 7F). buildAccountForMint read wallet.purpose before the !isOnline early return. The purpose getter calls getMintInfo() internally, which throws when mint info wasn't loaded. Add an 'unknown' AccountPurpose value (in-memory only — DB enum unchanged) and use it as the local purpose when offline. canSendToLightning then short-circuits correctly via its existing `purpose !== 'transactional'` guard, so no further changes to the lightning capability checks are needed.
decodeCashuToken unconditionally fetched the mint's keyset list to resolve v2 truncated keyset IDs, then handed them to getDecodedToken. For tokens with v1 keysets (full IDs embedded in the token) the network call is unnecessary, and when the mint is offline it caused decode to fail and the route loader to redirect away from /receive/cashu/token before the receive page could render. Try the bare decode first — succeeds for v1 keysets without any network. Only fall back to fetching keysets when the bare decode throws (the v2 truncated-ID case). Combined with the 'unknown' purpose fix in the previous commit, pasting a v1-keyset token from an offline mint now reaches the receive page, where useCashuTokenWithClaimableProofs already surfaces "The mint that issued this ecash is offline" via TokenErrorDisplay.
91df2f5 to
bde9b36
Compare
|
@jbojcic1 when I was testing this I realized there are more place we need to handle the source account being offline. This PR handles offline mints where the token has V1 keysets, but it throws on V2 keysets because our current code tries to decode them which requires the keys to be laoded. I think this PR is more complex than its worth, so I opened an alternative in #1036 |
what is the purpose of #1029 then? Should I review that one too? |
Oh sorry, I meant #1037 is the alternative to this one #1029. If you agree that checking if the mint is online in the loader before loading the receve-cashu-token components, then we can close this one |
| export type AccountState = 'active' | 'expired'; | ||
|
|
||
| export const AccountPurposeSchema = z.enum([ | ||
| export const StoredAccountPurposeSchema = z.enum([ |
There was a problem hiding this comment.
I am not sure this is needed. We could just keep the same schema
| } | ||
|
|
||
| if (receiveAccount.isUnknown && receiveAccount.type === 'cashu') { | ||
| if (!receiveAccount.isOnline || receiveAccount.purpose === 'unknown') { |
There was a problem hiding this comment.
is it even possible that account has isOnline true and purpose unknown?
|
closing in favor of #1037 which checks if the mint can be reached in the loader so we don't have to change the receive flow |
Summary
Pasting a Cashu token whose source mint is unreachable currently crashes the
/receive/cashu/tokenflow withMint info not initialized; call loadMint or loadMintFromCache first.buildAccountForMintreadswallet.purposebefore the existing!isOnlineearly-return. When the mint is unreachable,getInitializedCashuWalletreturns the wallet without callingloadMintFromCache, so thepurposegetter throws viagetMintInfo(). Defaultpurposeto'transactional'when offline so the function reaches its offline placeholder branch as intended.Recurring in production — Sentry issues AGICASH-9S, 9Y, 93, 7G, 7F, all on
/receive/cashu/token.Test plan
/receive/cashu/token. Should show the offline placeholder ("can't receive") rather than crashing the page.