Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deploy #980

Merged
merged 1 commit into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/app/components/icons/IconSPX6900.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { ColorTokens } from '@my/ui/types'
import { type IconProps, themed } from '@tamagui/helpers-icon'
import { memo } from 'react'
import { Defs, G, Path, Rect, Svg } from 'react-native-svg'
import { G, Path, Svg } from 'react-native-svg'

const SPX6900 = (props) => {
const { size, color, ...rest } = props
const { size } = props
return (
<Svg
xmlns="http://www.w3.org/2000/svg"
Expand Down
1 change: 0 additions & 1 deletion packages/app/features/home/TokenDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
AnimatePresence,
Button,
Card,
H4,
Paragraph,
Expand Down
2 changes: 1 addition & 1 deletion packages/app/features/leaderboard/screen.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Avatar, Card, H2, H3, LinearGradient, Paragraph, XStack, YStack } from '@my/ui'
import { Avatar, Card, H2, H3, Paragraph, XStack, YStack } from '@my/ui'
import { useLeaderboard } from './utils/useLeaderboard'
import type { LeaderboardEntry } from 'app/utils/zod/leaderboard'

Expand Down
65 changes: 46 additions & 19 deletions packages/app/features/send/confirm/screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
Avatar,
Button,
ButtonText,
isWeb,
Label,
LinkableAvatar,
Paragraph,
Expand Down Expand Up @@ -45,6 +46,10 @@ import { useCoinFromSendTokenParam } from 'app/utils/useCoinFromTokenParam'
import { allCoinsDict } from 'app/data/coins'
import { IconCoin } from 'app/components/icons/IconCoin'

import debug from 'debug'

const log = debug('app:features:send:confirm:screen')

export function SendConfirmScreen() {
const [queryParams] = useSendScreenParams()
const { recipient, idType, sendToken, amount } = queryParams
Expand Down Expand Up @@ -130,22 +135,17 @@ export function SendConfirm() {
mutateAsync: sendUserOp,
isPending: isTransferPending,
isError: isTransferError,
submittedAt,
} = useUserOpTransferMutation()

const [error, setError] = useState<Error>()

const {
data: transfers,
error: tokenActivityError,
dataUpdatedAt,
} = useTokenActivityFeed({
const { data: transfers, error: tokenActivityError } = useTokenActivityFeed({
address: sendToken === 'eth' ? undefined : hexToBytea(sendToken),
refetchInterval: sentTxHash ? 1000 : undefined, // refetch every second if we have sent a tx
enabled: !!sentTxHash,
})

const [dataFirstFetch, setDataFirstFetch] = useState<number>()

const hasEnoughBalance = selectedCoin?.balance && selectedCoin.balance >= BigInt(amount ?? '0')
const gas = usdcFees ? usdcFees.baseFee + usdcFees.gasFees : BigInt(Number.MAX_SAFE_INTEGER)
const hasEnoughGas =
Expand Down Expand Up @@ -187,9 +187,9 @@ export function SendConfirm() {
maxPriorityFeePerGas: feesPerGas.maxPriorityFeePerGas,
}

console.log('gasEstimate', usdcFees)
console.log('feesPerGas', feesPerGas)
console.log('userOp', _userOp)
log('gasEstimate', usdcFees)
log('feesPerGas', feesPerGas)
log('userOp', _userOp)
const receipt = await sendUserOp({
userOp: _userOp,
webauthnCreds,
Expand All @@ -209,13 +209,19 @@ export function SendConfirm() {
}

useEffect(() => {
if (!dataFirstFetch && dataUpdatedAt) {
setDataFirstFetch(dataUpdatedAt)
}
if (!dataFirstFetch) return
if (!dataUpdatedAt) return
const hasBeenLongEnough = dataUpdatedAt - dataFirstFetch > 5_000
if (!submittedAt) return

const hasBeenLongEnough = Date.now() - submittedAt > 5_000

log('check if submitted at is long enough', {
submittedAt,
sentTxHash,
hasBeenLongEnough,
isTransferPending,
})

if (sentTxHash) {
log('sent tx hash', { sentTxHash })
const tfr = transfers?.pages.some((page) =>
page.some((activity: Activity) => {
if (isSendAccountTransfersEvent(activity)) {
Expand All @@ -231,12 +237,33 @@ export function SendConfirm() {
if (tokenActivityError) {
console.error(tokenActivityError)
}
// found the transfer or we waited 5 seconds or we got an error 😢
if (tfr || tokenActivityError || hasBeenLongEnough) {
// found the transfer or we waited too long or we got an error 😢
// or we are sending eth since event logs are not always available for eth
// (when receipient is not a send account or contract)
if (tfr || tokenActivityError || hasBeenLongEnough || (sentTxHash && sendToken === 'eth')) {
router.replace({ pathname: '/', query: { token: sendToken } })
}
}
}, [sentTxHash, transfers, router, sendToken, tokenActivityError, dataFirstFetch, dataUpdatedAt])

// create a window unload event on web
const eventHandlersToRemove: (() => void)[] = []
if (isWeb) {
const unloadHandler = (e: BeforeUnloadEvent) => {
// prevent unload if we have a tx hash or a submitted at
if (submittedAt || sentTxHash) {
e.preventDefault()
}
}
window.addEventListener('beforeunload', unloadHandler)
eventHandlersToRemove.push(() => window.removeEventListener('beforeunload', unloadHandler))
}

return () => {
for (const remove of eventHandlersToRemove) {
remove()
}
}
}, [sentTxHash, transfers, router, sendToken, tokenActivityError, submittedAt, isTransferPending])

if (isSendAccountLoading || nonceIsLoading || isProfileLoading)
return <Spinner size="large" color={'$color'} />
Expand Down
2 changes: 1 addition & 1 deletion packages/app/provider/coins/CoinsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createContext, useContext, useMemo } from 'react'
import { useSendAccountBalances } from 'app/utils/useSendAccountBalances'
import type { allCoins, CoinWithBalance } from 'app/data/coins'
import { coins as coinsOg, partnerCoins } from 'app/data/coins'
import { isAddress, type zeroAddress } from 'viem'
import { isAddress } from 'viem'
import type { TokenPricesSchema } from 'app/utils/useTokenPrices'
import type { UseQueryResult } from '@tanstack/react-query'
import type { z } from 'zod'
Expand Down
4 changes: 3 additions & 1 deletion packages/app/utils/useUSDCFees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export function useUSDCFees({
const requiredUsdcBalance = await fetchRequiredUSDCBalance({
userOp,
refundPostopCost,
// @ts-expect-error dunno what happened here
client,
cachedPriceWithMarkup,
})
Expand Down Expand Up @@ -165,9 +166,10 @@ export async function fetchRequiredUSDCBalance<TTransport extends Transport, TCh
}: {
userOp: UserOperation<'v0.7'>
refundPostopCost: number
client: PublicClient<TTransport, TChain>
client: PublicClient<TTransport, TChain> | undefined
cachedPriceWithMarkup: bigint
}) {
assert(!!client?.chain?.id, 'client.chain.id is not set')
const requiredPreFund = calculatePrefund(userOp)
const addedPostOpCost = BigInt(refundPostopCost) * userOp.maxFeePerGas
const preChargeNative = requiredPreFund + addedPostOpCost
Expand Down
9 changes: 8 additions & 1 deletion packages/contracts/script/anvil-base-node.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'zx/globals'

// $.verbose = true
$.verbose = true

if (!$.env.ANVIL_BASE_FORK_URL) {
console.error(chalk.red('ANVIL_BASE_FORK_URL is not set.'))
Expand All @@ -10,6 +10,13 @@ $.env.ANVIL_BASE_BLOCK_TIME ||= '2'
$.env.ANVIL_BASE_EXTRA_ARGS ||= '--silent'
$.env.NEXT_PUBLIC_BASE_CHAIN_ID ||= '845337'

console.log(chalk.blue('Running anvil base node'), {
ANVIL_BASE_FORK_URL: $.env.ANVIL_BASE_FORK_URL,
ANVIL_BASE_BLOCK_TIME: $.env.ANVIL_BASE_BLOCK_TIME,
ANVIL_BASE_EXTRA_ARGS: $.env.ANVIL_BASE_EXTRA_ARGS,
NEXT_PUBLIC_BASE_CHAIN_ID: $.env.NEXT_PUBLIC_BASE_CHAIN_ID,
})

const baseBaseFee = await $`cast base-fee --rpc-url $ANVIL_BASE_FORK_URL`
const baseGasPrice = await $`cast gas-price --rpc-url $ANVIL_BASE_FORK_URL`

Expand Down
4 changes: 2 additions & 2 deletions packages/playwright/tests/fixtures/send/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class SendPage {
this.expect = expect
this.amountInput = page.getByLabel('amount')
this.continueButton = page.getByRole('button', { name: 'CONTINUE', exact: true })
this.sendButton = page.getByRole('button', { name: '/SEND' })
this.sendButton = page.getByRole('button', { name: 'SEND', exact: true })
this.tokenSelect = page.getByTestId('SelectCoinTrigger')
}

Expand All @@ -30,7 +30,7 @@ export class SendPage {
}

async fillAndSubmitForm(amount: string) {
await this.expect(this.page.locator('h2', { hasText: 'Recipient' })).toBeVisible()
await this.expect(this.page.locator('h2', { hasText: 'Enter Amount' })).toBeVisible()
await this.expect(this.amountInput).toBeVisible()
await this.amountInput.fill(amount)
await this.expect(this.continueButton).toBeVisible()
Expand Down
4 changes: 2 additions & 2 deletions packages/playwright/tests/profile.onboarded.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ test('can visit other user profile and send by tag', async ({ page, seed }) => {
recipient: tag.name,
idType: 'tag',
})
await expect(page.locator('h2', { hasText: 'Recipient' })).toBeVisible()
await expect(page.locator('h2', { hasText: 'Enter Amount' })).toBeVisible()

// visit another user but without a sendtag
const plan2 = await seed.users([{ ...userOnboarded, tags: [] }])
Expand All @@ -53,7 +53,7 @@ test('can visit other user profile and send by tag', async ({ page, seed }) => {
recipient: profile2?.send_id.toString(),
idType: 'sendid',
})
await expect(page.locator('h2', { hasText: 'Recipient' })).toBeVisible()
await expect(page.locator('h2', { hasText: 'Enter Amount' })).toBeVisible()

// can visit profile withouth the @ prefix
await page.goto(`/${tag.name}`)
Expand Down
15 changes: 13 additions & 2 deletions packages/playwright/tests/send.onboarded.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { isAddress, parseUnits } from 'viem'
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
import { ProfilePage } from './fixtures/profiles'
import { SendPage } from './fixtures/send'
import { testBaseClient } from './fixtures/viem'
import { lookupBalance, testBaseClient } from './fixtures/viem'

const test = mergeTests(sendAccountTest, snapletTest)

Expand Down Expand Up @@ -218,7 +218,7 @@ async function handleTokenTransfer({
return amt
})()
const transferAmount = parseUnits(decimalAmount, token.decimals)
const balanceBefore = transferAmount * 10n // padding
const balanceBefore = transferAmount * 100n // padding

const { data: sendAccount, error } = await supabase.from('send_accounts').select('*').single()
expect(error).toBeFalsy()
Expand All @@ -230,15 +230,26 @@ async function handleTokenTransfer({
address: sendAccount.address as `0x${string}`,
value: balanceBefore, // padding
})
expect(await testBaseClient.getBalance({ address: sendAccount.address as `0x${string}` })).toBe(
balanceBefore
)
} else {
await setERC20Balance({
client: testBaseClient,
address: sendAccount.address as `0x${string}`,
tokenAddress: token.token as `0x${string}`,
value: balanceBefore, // padding
})
expect(
await lookupBalance({
address: sendAccount.address as `0x${string}`,
token: token.token as `0x${string}`,
})
).toBe(balanceBefore)
}

await page.reload() // ensure balance is updated

const sendPage = new SendPage(page, expect)
await sendPage.expectTokenSelect(token.symbol)
await sendPage.fillAndSubmitForm(decimalAmount)
Expand Down
Loading
Loading