Files
hanzo.ai/e2e/unit/wallet.spec.ts
zeekay a46eaec8fb sign-in: the wallet never holds the page, counts only once it signs
A wallet whose prompt never answers no longer locks the sign-in: the
other ways in stay open while it waits, any other press supersedes it,
and after a minute it is let go and said so. signup_submitted is sent
once the wallet has signed, not on the press. A second factor's header
names the way in that holds it (the wallet, the number), never an
address typed beside it. The gate's challenge names hanzo.ai, as IAM
v1.34.171 does for a page at one of the client's registered origins.

/login still sends no verify method: that needs @hanzo/iam 0.21.38
(loginWithWallet's `method`, hanzo-js/iam branch wallet-method).
2026-10-27 01:23:17 -07:00

48 lines
2.2 KiB
TypeScript

import { test, expect } from '@playwright/test'
import { declined, injected, Silent, WAIT, wallets, within } from '../../lib/auth/wallet'
test('a wallet that never answers is let go after a minute; one that answers or refuses is heard', async () => {
expect(WAIT).toBe(60_000)
await expect(within(new Promise(() => {}), 20)).rejects.toBeInstanceOf(Silent)
await expect(within(Promise.resolve('to'), 20)).resolves.toBe('to')
const no = Object.assign(new Error('User rejected the request.'), { code: 4001 })
await expect(within(Promise.reject(no), 20)).rejects.toBe(no)
})
test('a wallet is offered only where the browser injects one that takes requests', () => {
expect(injected({ ethereum: { request: () => Promise.resolve([]) } })).toBe(true)
expect(injected({})).toBe(false)
expect(injected({ ethereum: {} })).toBe(false)
expect(injected({ ethereum: { request: 'eth_requestAccounts' } })).toBe(false)
expect(injected(undefined)).toBe(false)
})
test('the person saying no in the wallet is EIP-1193 4001, and nothing else is', () => {
expect(declined({ code: 4001, message: 'User rejected the request.' })).toBe(true)
expect(declined(Object.assign(new Error('MetaMask: User denied message signature.'), { code: 4001 }))).toBe(true)
expect(declined({ code: -32603, message: 'Internal error' })).toBe(false)
expect(declined(new Error('web3: verification failed: bad-signature'))).toBe(false)
expect(declined(null)).toBe(false)
expect(declined('4001')).toBe(false)
})
test('the wallets claim is read in IAM order, and nothing that is not a chain and an address', () => {
const claims = {
wallets: [
{ chain: 'evm', address: '0x2c7536e3605d9c16a7a3d7b1898e529396a65c23' },
{ chain: 'solana', address: '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK' },
{ chain: 'evm' },
{ chain: '', address: '0x00' },
null,
'evm:0x00',
],
}
expect(wallets(claims)).toEqual([
{ chain: 'evm', address: '0x2c7536e3605d9c16a7a3d7b1898e529396a65c23' },
{ chain: 'solana', address: '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK' },
])
expect(wallets({ wallets: 'evm' })).toEqual([])
expect(wallets({})).toEqual([])
expect(wallets(null)).toEqual([])
})