Skip to content

Commit

Permalink
add SPX6900 token (#752)
Browse files Browse the repository at this point in the history
* add SPX6900 token

the entire stock market for the people

* try to patch CI

* usdc, eth, spx, send

* enable corepack

* do not enable corepack
  • Loading branch information
0xBigBoss authored Oct 10, 2024
1 parent ee4e449 commit fd29d2a
Show file tree
Hide file tree
Showing 15 changed files with 1,955 additions and 65 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ jobs:
- name: Install Tilt
id: tilt
shell: bash
run: curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
run: |
cd /tmp
curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
- name: Add hosts to /etc/hosts
run: |
sudo su
Expand Down Expand Up @@ -114,7 +116,9 @@ jobs:
- name: Install Tilt
id: tilt
shell: bash
run: curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
run: |
cd /tmp
curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
- name: Add hosts to /etc/hosts
run: |
sudo su
Expand Down
4 changes: 4 additions & 0 deletions packages/app/__mocks__/@my/wagmi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ const mockMyWagmi = {
sendTokenAddress: {
845337: '0x3f14920c99BEB920Afa163031c4e47a3e03B3e4A',
},
spx6900Address: {
845337: '0x50dA645f148798F68EF2d7dB7C1CB22A6819bb2C',
},
tokenPaymasterAddress: {
845337: '0x5e421172B27658f2bD83BCBD13738ADdE00E7CA9',
},
Expand Down Expand Up @@ -73,6 +76,7 @@ export const baseMainnetClient = mockMyWagmi.baseMainnetClient
export const baseMainnet = mockMyWagmi.baseMainnet
export const usdcAddress = mockMyWagmi.usdcAddress
export const sendTokenAddress = mockMyWagmi.sendTokenAddress
export const spx6900Address = mockMyWagmi.spx6900Address
export const tokenPaymasterAddress = mockMyWagmi.tokenPaymasterAddress
export const entryPointAddress = mockMyWagmi.entryPointAddress
export const sendVerifierAbi = mockMyWagmi.sendVerifierAbi
Expand Down
2 changes: 2 additions & 0 deletions packages/app/components/icons/IconCoin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import type { coin } from 'app/data/coins'
import { IconEthereum } from './IconEthereum'
import { IconSend } from './IconSend'
import { IconUSDC } from './IconUSDC'
import { IconSPX6900 } from './IconSPX6900'

const coinSymbolToIcons: Record<coin['symbol'], JSX.Element> = {
USDC: <IconUSDC size={'$2.5'} />,
ETH: <IconEthereum size={'$2.5'} />,
SEND: <IconSend size={'$2.5'} />,
SPX: <IconSPX6900 size={'$2.5'} />,
}

export const IconCoin = ({ coin }: { coin: coin }) => {
Expand Down
121 changes: 121 additions & 0 deletions packages/app/components/icons/IconSPX6900.tsx

Large diffs are not rendered by default.

26 changes: 20 additions & 6 deletions packages/app/data/coins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
baseMainnet,
usdcAddress as usdcAddresses,
sendTokenAddress as sendAddresses,
spx6900Address as spx6900Addresses,
} from '@my/wagmi'
import { z } from 'zod'

Expand Down Expand Up @@ -38,15 +39,28 @@ export const sendCoin = {
coingeckoTokenId: 'send-token',
} as const

export const coins = [usdcCoin, ethCoin, sendCoin] as const
export const spx6900Coin = {
label: 'SPX',
symbol: 'SPX',
token: spx6900Addresses[baseMainnet.id],
decimals: 8,
coingeckoTokenId: 'spx6900',
} as const

/**
* The coins (tokens) array that are supported by Send App.
*/
export const coins = [usdcCoin, ethCoin, spx6900Coin, sendCoin] as const
export type coins = typeof coins

type CoinsDict = { [key in coins[number]['token']]: coins[number] }

export const coinsDict = {
[usdcCoin.token]: usdcCoin,
[ethCoin.token]: ethCoin,
[sendCoin.token]: sendCoin,
} as const as CoinsDict
/**
* A dictionary of coins (tokens) by token address.
*/
export const coinsDict = coins.reduce((acc, coin) => {
acc[coin.token] = coin
return acc
}, {} as CoinsDict)

export type coinsDict = typeof coinsDict
1,033 changes: 1,033 additions & 0 deletions packages/app/features/home/__snapshots__/screen.test.tsx.snap

Large diffs are not rendered by default.

21 changes: 20 additions & 1 deletion packages/app/features/secret-shop/screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import {
} from '@my/ui'
import { useSendAccounts } from 'app/utils/send-accounts'
import { setERC20Balance } from 'app/utils/useSetErc20Balance'
import { baseMainnet, baseMainnetClient, sendTokenAddress, usdcAddress } from '@my/wagmi'
import {
baseMainnet,
baseMainnetClient,
sendTokenAddress,
spx6900Address,
usdcAddress,
} from '@my/wagmi'
import { api } from 'app/utils/api'
import {
createTestClient,
Expand Down Expand Up @@ -120,6 +126,19 @@ export function SecretShopScreen() {
>
Fund with 1M Send
</Button>
<Button
onPress={async () => {
await setERC20Balance({
client: testClient,
address: sendAcct.address,
tokenAddress: spx6900Address[baseMainnetClient.chain.id],
value: BigInt(6900 * 1e8),
})
toast.show('Funded with 69K SPX6900')
}}
>
Fund with 69K SPX6900
</Button>
</>
) : (
<YStack>
Expand Down
107 changes: 55 additions & 52 deletions packages/app/utils/useSendAccountBalances.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
import {
baseMainnet,
usdcAddress as usdcAddresses,
sendTokenAddress as sendAddresses,
sendTokenAbi,
usdcAbi,
} from '@my/wagmi'
import { baseMainnet, erc20Abi } from '@my/wagmi'
import { useBalance, useReadContracts } from 'wagmi'
import { useSendAccount } from './send-accounts'
import { useTokenPrices } from './useTokenPrices'
import { convertBalanceToFiat } from './convertBalanceToUSD'
import { coins } from '../data/coins'

const usdcBaseContract = {
address: usdcAddresses[baseMainnet.id],
abi: usdcAbi,
chainId: baseMainnet.id,
} as const

const sendBaseContract = {
address: sendAddresses[baseMainnet.id],
abi: sendTokenAbi,
chainId: baseMainnet.id,
} as const
type BalanceOfResult =
| {
error?: undefined
result: string | number | bigint
status: 'success'
}
| {
error: Error
result?: undefined
status: 'failure'
}
| undefined

export const useSendAccountBalances = () => {
const { data: tokenPrices } = useTokenPrices()
const { data: sendAccount } = useSendAccount()

const tokenContracts = coins
.filter((coin) => coin.token !== 'eth')
.map((coin) => ({
address: coin.token,
abi: erc20Abi,
chainId: baseMainnet.id,
functionName: 'balanceOf',
args: sendAccount?.address && [sendAccount?.address],
}))

const { data: tokenBalances, isLoading: isLoadingTokenBalances } = useReadContracts({
query: { enabled: !!sendAccount },
contracts: [
{
...usdcBaseContract,
functionName: 'balanceOf',
args: sendAccount?.address && [sendAccount?.address],
},
{
...sendBaseContract,
functionName: 'balanceOf',
args: sendAccount?.address && [sendAccount?.address],
},
],
contracts: tokenContracts,
})

const unpackResult = (result: BalanceOfResult): bigint | undefined => {
if (result && result.status === 'success' && BigInt(result.result) > 0n) {
return BigInt(result.result)
}
return undefined
}

const { data: ethBalanceOnBase, isLoading: isLoadingEthBalanceOnBase } = useBalance({
address: sendAccount?.address,
query: { enabled: !!sendAccount },
Expand All @@ -52,33 +54,34 @@ export const useSendAccountBalances = () => {

const balances = isLoading
? undefined
: {
ETH: ethBalanceOnBase?.value,
USDC: tokenBalances?.[0].result,
SEND: tokenBalances?.[1].result,
}
: coins.reduce(
(acc, coin) => {
if (coin.token === 'eth') {
acc[coin.symbol] = ethBalanceOnBase?.value
console.log
return acc
}
const idx = tokenContracts.findIndex((c) => c.address === coin.token)
if (idx === -1) {
console.error('No token contract found for coin', coin)
return acc
}
const tokenBal = tokenBalances?.[idx]
acc[coin.symbol] = unpackResult(tokenBal)
return acc
},
{} as Record<string, bigint | undefined>
)

if (!tokenPrices) {
return { balances, isLoading, totalBalance: undefined }
}
const usdcBalanceInUsd =
convertBalanceToFiat(
usdcBaseContract.address,
tokenBalances?.[0].result ?? 0n,
tokenPrices['usd-coin'].usd
) ?? 0

const sendBalanceInUsd =
convertBalanceToFiat(
sendBaseContract.address,
tokenBalances?.[1].result ?? 0n,
tokenPrices['send-token'].usd
) ?? 0

const ethBalanceInUsd =
convertBalanceToFiat('eth', ethBalanceOnBase?.value ?? 0n, tokenPrices.ethereum.usd) ?? 0

const totalBalance = usdcBalanceInUsd + sendBalanceInUsd + ethBalanceInUsd
const totalBalance = coins.reduce((total, coin) => {
const balance = coin.token === 'eth' ? ethBalanceOnBase?.value : balances?.[coin.symbol]
const price = tokenPrices[coin.coingeckoTokenId].usd
return total + (convertBalanceToFiat(coin.token, balance ?? 0n, price) ?? 0)
}, 0)

return { balances, totalBalance, isLoading }
}
3 changes: 2 additions & 1 deletion packages/app/utils/useTokenPrices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const TokenPricesSchema = z.object({
ethereum: TokenPriceSchema,
'send-token': TokenPriceSchema,
'usd-coin': TokenPriceSchema,
spx6900: TokenPriceSchema,
})

export const useTokenPrices = (): UseQueryResult<z.infer<typeof TokenPricesSchema>, Error> => {
Expand All @@ -17,7 +18,7 @@ export const useTokenPrices = (): UseQueryResult<z.infer<typeof TokenPricesSchem
gcTime: 1000 * 60 * 5,
queryFn: async () => {
const res = await fetch(
'https://api.coingecko.com/api/v3/simple/price?ids=ethereum,usd-coin,send-token&vs_currencies=usd'
'https://api.coingecko.com/api/v3/simple/price?ids=ethereum,usd-coin,send-token,spx6900&vs_currencies=usd'
)
if (!res.ok) {
throw new Error(`Failed to fetch token prices. Status: ${res.status}`)
Expand Down
9 changes: 8 additions & 1 deletion packages/playwright/tests/send.onboarded.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,14 @@ async function handleTokenTransfer({
profile?: { id: string; send_id?: number }
}): Promise<void> {
const isETH = token.symbol === 'ETH'
const decimalAmount = (Math.random() * 1000).toFixed(token.decimals).toString()
const decimalAmount: string = (() => {
const amt = (Math.random() * 1000).toFixed(token.decimals).toString()
if (token.decimals > 0) {
// trailing zeros are not allowed in the decimal part
return amt.replace(/0+$/, '')
}
return amt
})()
const transferAmount = parseUnits(decimalAmount, token.decimals)
const balanceBefore = transferAmount * 10n // padding

Expand Down
4 changes: 3 additions & 1 deletion packages/shovel/etc/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@
"0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
"0x3f14920c99BEB920Afa163031c4e47a3e03B3e4A",
"0x50dA645f148798F68EF2d7dB7C1CB22A6819bb2C",
"0x7cEfbe54c37a35dCdaD29b86373ca8353a2F4680",
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"0xE0f63A424a4439cBE457D80E4f4b51aD25b2c56C"
]
}
],
Expand Down
3 changes: 2 additions & 1 deletion packages/shovel/src/integrations/send-account-transfers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { BlockData, Column, Integration, Table } from '@indexsupply/shovel-config'
// import { sendAccountFactorySenderFilterRef, sendAcctFactoryTable } from './send-account-deployed'
import { sendTokenAddress, usdcAddress } from '@my/wagmi'
import { sendTokenAddress, spx6900Address, usdcAddress } from '@my/wagmi'
import { sendAccountFactorySenderFilterRef } from './send-account-created'

export const transfersTable: Table = {
Expand Down Expand Up @@ -40,6 +40,7 @@ export const integration: Omit<Integration, 'sources'> = {
filter_arg: [
...new Set(Object.values(sendTokenAddress)),
...new Set(Object.values(usdcAddress)),
...new Set(Object.values(spx6900Address)),
].sort(),
},
] as BlockData[],
Expand Down
2 changes: 2 additions & 0 deletions packages/shovel/test/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ exports[`shovel config 1`] = `
"0x036CbD53842c5426634e7929541eC2318f3dCF7e",
"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
"0x3f14920c99BEB920Afa163031c4e47a3e03B3e4A",
"0x50dA645f148798F68EF2d7dB7C1CB22A6819bb2C",
"0x7cEfbe54c37a35dCdaD29b86373ca8353a2F4680",
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"0xE0f63A424a4439cBE457D80E4f4b51aD25b2c56C",
],
"filter_op": "contains",
"name": "log_addr",
Expand Down
Loading

0 comments on commit fd29d2a

Please sign in to comment.