Skip to content

Commit

Permalink
chore(pilot-app): load available safes through ser-kit (#805)
Browse files Browse the repository at this point in the history
Part of #775
  • Loading branch information
frontendphil authored Feb 10, 2025
1 parent e9f60db commit 0de754d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 24 deletions.
26 changes: 21 additions & 5 deletions deployables/app/app/routes/$address.$chainId/available-safes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,47 @@ import { validateAddress } from '@/utils'
import { invariantResponse } from '@epic-web/invariant'
import { verifyChainId } from '@zodiac/chains'
import { getOptionalString } from '@zodiac/form-data'
import { initSafeApiKit } from '@zodiac/safe'
import type { ShouldRevalidateFunctionArgs } from 'react-router'
import { queryAvatars, splitPrefixedAddress, unprefixAddress } from 'ser-kit'
import { Intent } from '../edit/intents'
import type { Route } from './+types/available-safes'

export const loader = async ({ params }: Route.LoaderArgs) => {
const { chainId, address } = params
const { address, chainId } = params

const safeService = initSafeApiKit(verifyChainId(parseInt(chainId)))
const verifiedChainId = verifyChainId(parseInt(chainId))
const validatedAddress = validateAddress(address)

invariantResponse(validatedAddress != null, `Invalid address: ${address}`)

try {
const { safes } = await safeService.getSafesByOwner(validatedAddress)
const routes = await queryAvatars(validatedAddress)

return Response.json(safes)
const possibleRoutes = routes.filter((route) => {
const [chainId] = splitPrefixedAddress(route.avatar)

return chainId === verifiedChainId
})

return Response.json(
Array.from(
new Set(possibleRoutes.map((route) => unprefixAddress(route.avatar))),
),
)
} catch {
return Response.json([])
}
}

export const shouldRevalidate = ({
formData,
currentParams,
nextParams,
}: ShouldRevalidateFunctionArgs) => {
if (currentParams.chainId !== nextParams.chainId) {
return true
}

if (formData == null) {
return false
}
Expand Down
34 changes: 15 additions & 19 deletions deployables/app/app/routes/edit/edit-route.$data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
updateAvatar,
updateRoleId,
} from '@zodiac/modules'
import type { initSafeApiKit } from '@zodiac/safe'
import { encode } from '@zodiac/schema'
import {
createMockEndWaypoint,
Expand All @@ -24,30 +23,21 @@ import {
randomAddress,
randomPrefixedAddress,
} from '@zodiac/test-utils'
import { prefixAddress, type ChainId } from 'ser-kit'
import { prefixAddress, queryAvatars, type ChainId } from 'ser-kit'
import { beforeEach, describe, expect, it, vi } from 'vitest'

const { mockGetSafesByOwner } = vi.hoisted(() => ({
mockGetSafesByOwner: vi
.fn<ReturnType<typeof initSafeApiKit>['getSafesByOwner']>()
.mockResolvedValue({ safes: [] }),
}))

vi.mock('@zodiac/safe', async (importOriginal) => {
const module = await importOriginal<typeof import('@zodiac/safe')>()
vi.mock('ser-kit', async (importOriginal) => {
const module = await importOriginal<typeof import('ser-kit')>()

return {
...module,

initSafeApiKit: (chainId: ChainId) => {
return {
...module.initSafeApiKit(chainId),
getSafesByOwner: mockGetSafesByOwner,
}
},
queryAvatars: vi.fn(),
}
})

const mockQueryAvatars = vi.mocked(queryAvatars)

vi.mock('@zodiac/modules', async (importOriginal) => {
const module = await importOriginal<typeof import('@zodiac/modules')>()

Expand Down Expand Up @@ -162,7 +152,10 @@ describe('Edit route', () => {
it('offers safes that are owned by the user', async () => {
const safe = randomAddress()

mockGetSafesByOwner.mockResolvedValue({ safes: [safe] })
mockQueryAvatars.mockResolvedValue([
// @ts-expect-error Some weird clash in a union
createMockExecutionRoute({ avatar: prefixAddress(Chain.ETH, safe) }),
])

const route = createMockExecutionRoute({
initiator: randomPrefixedAddress(),
Expand All @@ -181,7 +174,10 @@ describe('Edit route', () => {
it('is possible to select a safe from the list', async () => {
const safe = randomAddress()

mockGetSafesByOwner.mockResolvedValue({ safes: [safe] })
mockQueryAvatars.mockResolvedValue([
// @ts-expect-error Some weird clash in a union
createMockExecutionRoute({ avatar: prefixAddress(Chain.ETH, safe) }),
])

const route = createMockExecutionRoute({
initiator: randomPrefixedAddress(),
Expand Down Expand Up @@ -213,7 +209,7 @@ describe('Edit route', () => {
it('is possible to type in an address', async () => {
const safe = randomAddress()

mockGetSafesByOwner.mockResolvedValue({ safes: [] })
mockQueryAvatars.mockResolvedValue([])

const route = createMockExecutionRoute()

Expand Down

0 comments on commit 0de754d

Please sign in to comment.