Files
trumpsignal-monorepo/apps/web/lib/walletError.ts
T

43 lines
1.7 KiB
TypeScript

/**
* MetaMask / EIP-1193 wallet error helpers.
*
* Previously the codebase detected user rejections by string-matching the
* error message for "reject" or "denied". That breaks when MetaMask's UI
* language is set to anything other than English (the message is translated
* but our match string isn't). The reliable signal is the EIP-1193 error
* code: 4001 = "User rejected the request".
*
* Wagmi sometimes wraps the underlying provider error inside `.cause`, so we
* walk that chain too.
*/
interface WithCode {
code?: number | string
cause?: unknown
}
export function isUserRejection(err: unknown): boolean {
// Walk a small depth of .cause chains since wagmi/viem wrap provider errors
let cur: unknown = err
for (let i = 0; i < 4 && cur; i++) {
const c = (cur as WithCode)?.code
if (c === 4001 || c === 'ACTION_REJECTED' || c === 'USER_REJECTED') return true
cur = (cur as WithCode)?.cause
}
// Last-resort string fallback for providers that don't expose a code field.
// Kept narrow — "reject" + "denied" + a couple of locale variants we've
// actually seen from MetaMask zh-CN ("拒绝") and Rabby ("rejected by user").
const m = err instanceof Error ? err.message : ''
return /reject|denied|cancell|拒绝|已取消/i.test(m)
}
/**
* Convenience: return either a friendly cancellation label or a truncated
* version of the real error message — never raw user-facing crash text.
*/
export function walletErrorLabel(err: unknown, cancelledLabel = 'Cancelled', maxLen = 110): string {
if (isUserRejection(err)) return cancelledLabel
const m = err instanceof Error ? err.message : String(err ?? '')
return m.slice(0, maxLen) || 'unknown error'
}