Skip to content

Commit

Permalink
refactor: Cardano and api yoroi (#2807)
Browse files Browse the repository at this point in the history
  • Loading branch information
stackchain authored Oct 20, 2023
1 parent 72a99f6 commit 1cf980f
Show file tree
Hide file tree
Showing 68 changed files with 810 additions and 391 deletions.
2 changes: 1 addition & 1 deletion apps/wallet-mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@
"@shopify/flash-list": "^1.4.1",
"@unstoppabledomains/resolution": "6.0.3",
"@yoroi/banxa": "1.0.0",
"@yoroi/cardano": "1.0.0",
"@yoroi/api": "1.0.0",
"@yoroi/common": "1.0.0",
"@yoroi/swap": "1.0.0",
"add": "2.0.6",
Expand Down
55 changes: 33 additions & 22 deletions apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import {createStackNavigator} from '@react-navigation/stack'
import {supportedProviders, swapApiMaker, swapManagerMaker, SwapProvider, swapStorageMaker} from '@yoroi/swap'
import {
milkTokenId,
supportedProviders,
swapApiMaker,
swapManagerMaker,
SwapProvider,
swapStorageMaker,
} from '@yoroi/swap'
import {Swap} from '@yoroi/types'
import React from 'react'
import {defineMessages, useIntl} from 'react-intl'
import {StyleSheet, Text, TouchableOpacity, TouchableOpacityProps} from 'react-native'
Expand Down Expand Up @@ -29,36 +37,39 @@ import {BackButton, defaultStackNavigationOptions, TxHistoryRoutes, useWalletNav
import {ReceiveScreen} from '../Receive/ReceiveScreen'
import {useSelectedWallet} from '../SelectedWallet'
import {COLORS} from '../theme'
import {useStakingKey, useWalletName} from '../yoroi-wallets/hooks'
import {useFrontendFees, useStakingKey, useWalletName} from '../yoroi-wallets/hooks'
import {ModalInfo} from './ModalInfo'
import {TxDetails} from './TxDetails'
import {TxHistory} from './TxHistory'

const aggregator: Swap.Aggregator = 'muesliswap'

const Stack = createStackNavigator<TxHistoryRoutes>()
export const TxHistoryNavigator = () => {
const strings = useStrings()
const wallet = useSelectedWallet()

const walletName = useWalletName(wallet)
const stakingKey = useStakingKey(wallet)
const [modalInfoState, setModalInfoState] = React.useState(false)

const showModalInfo = React.useCallback(() => setModalInfoState(true), [])
const hideModalInfo = React.useCallback(() => setModalInfoState(false), [])

const swapStorage = React.useMemo(() => swapStorageMaker(), [])
const swapAPI = React.useMemo(
() =>
swapApiMaker({
isMainnet: wallet.networkId !== 300,
stakingKey,
primaryTokenId: wallet.primaryTokenInfo.id,
supportedProviders,
}),
[wallet.networkId, stakingKey, wallet.primaryTokenInfo.id],
)

const swapManager = React.useMemo(() => swapManagerMaker(swapStorage, swapAPI), [swapStorage, swapAPI])
// modal
const [isModalInfoVisible, setIsModalInfoVisible] = React.useState(false)
const showModalInfo = React.useCallback(() => setIsModalInfoVisible(true), [])
const hideModalInfo = React.useCallback(() => setIsModalInfoVisible(false), [])

// swap
const {frontendFees} = useFrontendFees(wallet)
const aggregatorTokenId = wallet.networkId !== 300 ? milkTokenId.mainnet : milkTokenId.preprod
const stakingKey = useStakingKey(wallet)
const swapManager = React.useMemo(() => {
const swapStorage = swapStorageMaker()
const swapApi = swapApiMaker({
isMainnet: wallet.networkId !== 300,
stakingKey,
primaryTokenId: wallet.primaryTokenInfo.id,
supportedProviders,
})
const frontendFeeTiers = frontendFees?.[aggregator] ?? ([] as const)
return swapManagerMaker({swapStorage, swapApi, frontendFeeTiers, aggregator, aggregatorTokenId})
}, [wallet.networkId, wallet.primaryTokenInfo.id, stakingKey, frontendFees, aggregatorTokenId])

return (
<SendProvider key={wallet.id}>
Expand Down Expand Up @@ -254,7 +265,7 @@ export const TxHistoryNavigator = () => {
/>
</Stack.Navigator>

<ModalInfo hideModalInfo={hideModalInfo} visible={modalInfoState}>
<ModalInfo hideModalInfo={hideModalInfo} visible={isModalInfoVisible}>
<Text style={styles.receiveInfoText}>{strings.receiveInfoText}</Text>
</ModalInfo>
</SwapFormProvider>
Expand Down
27 changes: 24 additions & 3 deletions apps/wallet-mobile/src/features/Swap/SwapNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {createMaterialTopTabNavigator} from '@react-navigation/material-top-tabs'
import {useSwapTokensByPairToken} from '@yoroi/swap'
import {useSwap, useSwapTokensByPairToken} from '@yoroi/swap'
import React from 'react'
import {StyleSheet} from 'react-native'
import {SafeAreaView} from 'react-native-safe-area-context'

import {StatusBar} from '../../components'
import {defaultMaterialTopTabNavigationOptions, SwapTabRoutes} from '../../navigation'
import {useSelectedWallet} from '../../SelectedWallet'
import {COLORS} from '../../theme'
import {useHideBottomTabBar} from '../../yoroi-wallets/hooks'
import {useBalance, useHideBottomTabBar} from '../../yoroi-wallets/hooks'
import {useStrings} from './common/strings'
import {CreateOrder} from './useCases/StartSwapScreen/CreateOrder/CreateOrder'
import {ListOrders} from './useCases/StartSwapScreen/ListOrders/ListOrders'
Expand All @@ -18,8 +19,28 @@ export const SwapTabNavigator = () => {

useHideBottomTabBar()

const {refetch} = useSwapTokensByPairToken('', {suspense: false, enabled: false})
// state data
const wallet = useSelectedWallet()
const {aggregatorTokenId, lpTokenHeldChanged, frontendFeeTiers, frontendFeeTiersChanged} = useSwap()
const lpTokenHeld = useBalance({wallet, tokenId: aggregatorTokenId})

// update the fee tiers
React.useEffect(() => {
frontendFeeTiersChanged(frontendFeeTiers)
}, [frontendFeeTiers, frontendFeeTiersChanged])

// update lp token balance
React.useEffect(() => {
if (aggregatorTokenId == null) return

lpTokenHeldChanged({
tokenId: aggregatorTokenId,
quantity: lpTokenHeld,
})
}, [aggregatorTokenId, lpTokenHeld, lpTokenHeldChanged])

// pre load swap tokens
const {refetch} = useSwapTokensByPairToken('', {suspense: false, enabled: false})
React.useEffect(() => {
refetch()
}, [refetch])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ export const ShowPoolActions = () => {
}
info={
<HiddenInfo
totalFees={Quantities.format(
selectedPoolCalculation.pool.batcherFee.quantity,
Number(wallet.primaryTokenInfo.decimals),
)}
totalFees={totalFees}
minReceived={Quantities.format(
selectedPoolCalculation.buyAmountWithSlippage.quantity,
buyTokenInfo.decimals ?? 0,
Expand Down
31 changes: 18 additions & 13 deletions apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {PrivateKey} from '@emurgo/cross-csl-core'
import * as yoroiLib from '@emurgo/yoroi-lib'
import {AppApi} from '@yoroi/api'
import {parseSafe} from '@yoroi/common'
import {App, Balance} from '@yoroi/types'
import assert from 'assert'
Expand Down Expand Up @@ -43,12 +44,13 @@ import {genTimeToSlot} from '../../utils/timeUtils'
import {validatePassword} from '../../utils/validators'
import {WalletMeta} from '../../walletManager'
import {Cardano, CardanoMobile} from '../../wallets'
import * as api from '../api'
import * as legacyApi from '../api'
import {encryptWithPassword} from '../catalyst/catalystCipher'
import {generatePrivateKeyForCatalyst} from '../catalyst/catalystUtils'
import {AddressChain, AddressChainJSON, Addresses, AddressGenerator} from '../chain'
import {signRawTransaction} from '../common/signatureUtils'
import {
API_ROOT,
HISTORY_REFRESH_TIME,
MAX_GENERATED_UNUSED,
PRIMARY_TOKEN,
Expand Down Expand Up @@ -124,7 +126,10 @@ export type WalletJSON = ShelleyWalletJSON | ByronWalletJSON
const networkId = NETWORK_REGISTRY.HASKELL_SHELLEY
const implementationId = WALLET_IMPLEMENTATION_REGISTRY.HASKELL_BYRON

const appApi = AppApi.appApiMaker({baseUrl: API_ROOT})

export class ByronWallet implements YoroiWallet {
readonly api: App.Api = appApi
readonly primaryToken: DefaultAsset
readonly primaryTokenInfo: Balance.TokenInfo
readonly id: string
Expand Down Expand Up @@ -917,7 +922,7 @@ export class ByronWallet implements YoroiWallet {
const absSlotNumber = new BigNumber(timeToSlotFn({time}).slot)
const changeAddr = await this.getAddressedChangeAddress()
const addressedUtxos = await this.getAddressedUtxos()
const accountState = await api.getAccountState(
const accountState = await legacyApi.getAccountState(
{addresses: [this.rewardAddressHex]},
this.getNetworkConfig().BACKEND,
)
Expand Down Expand Up @@ -1008,11 +1013,11 @@ export class ByronWallet implements YoroiWallet {
// =================== backend API =================== //

async checkServerStatus() {
return api.checkServerStatus(this.getBackendConfig())
return legacyApi.checkServerStatus(this.getBackendConfig())
}

async submitTransaction(signedTx: string) {
const response: any = await api.submitTransaction(signedTx, this.getBackendConfig())
const response: any = await legacyApi.submitTransaction(signedTx, this.getBackendConfig())
Logger.info(response)
return response as any
}
Expand Down Expand Up @@ -1078,11 +1083,11 @@ export class ByronWallet implements YoroiWallet {
}

async fetchAccountState(): Promise<AccountStateResponse> {
return api.bulkGetAccountState([this.rewardAddressHex], this.getBackendConfig())
return legacyApi.bulkGetAccountState([this.rewardAddressHex], this.getBackendConfig())
}

async fetchPoolInfo(request: PoolInfoRequest) {
return api.getPoolInfo(request, this.getBackendConfig())
return legacyApi.getPoolInfo(request, this.getBackendConfig())
}

public async signRawTx(txHex: string, pKeys: PrivateKey[]) {
Expand All @@ -1104,31 +1109,31 @@ export class ByronWallet implements YoroiWallet {
return primaryTokenInfo.testnet
}

return api.getTokenInfo(tokenId, `${apiUrl}/metadata`, this.getBackendConfig())
return legacyApi.getTokenInfo(tokenId, `${apiUrl}/metadata`, this.getBackendConfig())
}

async fetchFundInfo(): Promise<FundInfoResponse> {
return api.getFundInfo(this.getBackendConfig(), this.getNetworkConfig().IS_MAINNET)
return legacyApi.getFundInfo(this.getBackendConfig(), this.getNetworkConfig().IS_MAINNET)
}

async fetchTxStatus(request: TxStatusRequest): Promise<TxStatusResponse> {
return api.fetchTxStatus(request, this.getBackendConfig())
return legacyApi.fetchTxStatus(request, this.getBackendConfig())
}

async fetchTipStatus(): Promise<TipStatusResponse> {
return api.getTipStatus(this.getBackendConfig())
return legacyApi.getTipStatus(this.getBackendConfig())
}

async fetchCurrentPrice(symbol: CurrencySymbol): Promise<number> {
return api.fetchCurrentPrice(symbol, this.getBackendConfig())
return legacyApi.fetchCurrentPrice(symbol, this.getBackendConfig())
}

// TODO: caching
fetchNftModerationStatus(fingerprint: string): Promise<YoroiNftModerationStatus> {
const backendConfig = this.getBackendConfig()
const networkConfig = this.getNetworkConfig()
const isMainnet = networkConfig.IS_MAINNET
return api.getNFTModerationStatus(fingerprint, {...backendConfig, mainnet: isMainnet})
return legacyApi.getNFTModerationStatus(fingerprint, {...backendConfig, mainnet: isMainnet})
}

private state: WalletState = {
Expand Down Expand Up @@ -1296,7 +1301,7 @@ export class ByronWallet implements YoroiWallet {

private async discoverAddresses() {
// last chunk gap limit check
const filterFn = (addrs) => api.filterUsedAddresses(addrs, this.getBackendConfig())
const filterFn = (addrs) => legacyApi.filterUsedAddresses(addrs, this.getBackendConfig())
await Promise.all([this.internalChain.sync(filterFn), this.externalChain.sync(filterFn)])
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {PrivateKey} from '@emurgo/cross-csl-core'
import {Datum} from '@emurgo/yoroi-lib'
import {AppApi} from '@yoroi/api'
import {parseSafe} from '@yoroi/common'
import {App, Balance} from '@yoroi/types'
import assert from 'assert'
Expand Down Expand Up @@ -35,7 +36,7 @@ import {asQuantity, Quantities} from '../../utils'
import {validatePassword} from '../../utils/validators'
import {WalletMeta} from '../../walletManager'
import {Cardano, CardanoMobile} from '../../wallets'
import * as api from '../api'
import * as legacyApi from '../api'
import {encryptWithPassword} from '../catalyst/catalystCipher'
import {generatePrivateKeyForCatalyst} from '../catalyst/catalystUtils'
import {AddressChain, AddressChainJSON, Addresses, AddressGenerator} from '../chain'
Expand Down Expand Up @@ -156,7 +157,10 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) =>
},
}

const appApi = AppApi.appApiMaker({baseUrl: API_ROOT})

return class ShelleyWallet implements YoroiWallet {
readonly api: App.Api = appApi
readonly primaryToken: DefaultAsset = PRIMARY_TOKEN
readonly primaryTokenInfo: Balance.TokenInfo = PRIMARY_TOKEN_INFO
readonly walletImplementationId = WALLET_IMPLEMENTATION_ID
Expand Down Expand Up @@ -827,7 +831,7 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) =>
const absSlotNumber = new BigNumber(getTime(time).absoluteSlot)
const changeAddr = await this.getAddressedChangeAddress()
const addressedUtxos = await this.getAddressedUtxos()
const accountState = await api.getAccountState({addresses: [this.rewardAddressHex]}, BACKEND)
const accountState = await legacyApi.getAccountState({addresses: [this.rewardAddressHex]}, BACKEND)

const withdrawalTx = await Cardano.createUnsignedWithdrawalTx(
accountState,
Expand Down Expand Up @@ -947,11 +951,11 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) =>
// =================== backend API =================== //

async checkServerStatus() {
return api.checkServerStatus(BACKEND)
return legacyApi.checkServerStatus(BACKEND)
}

async submitTransaction(signedTx: string) {
const response: any = await api.submitTransaction(signedTx, BACKEND)
const response: any = await legacyApi.submitTransaction(signedTx, BACKEND)
Logger.info(response)
return response as any
}
Expand Down Expand Up @@ -1017,38 +1021,38 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) =>
}

async fetchAccountState(): Promise<AccountStateResponse> {
return api.bulkGetAccountState([this.rewardAddressHex], BACKEND)
return legacyApi.bulkGetAccountState([this.rewardAddressHex], BACKEND)
}

async fetchPoolInfo(request: PoolInfoRequest) {
return api.getPoolInfo(request, BACKEND)
return legacyApi.getPoolInfo(request, BACKEND)
}

fetchTokenInfo(tokenId: string) {
return tokenId === '' || tokenId === 'ADA'
? Promise.resolve(PRIMARY_TOKEN_INFO)
: api.getTokenInfo(tokenId, `${TOKEN_INFO_SERVICE}/metadata`, BACKEND)
: legacyApi.getTokenInfo(tokenId, `${TOKEN_INFO_SERVICE}/metadata`, BACKEND)
}

async fetchFundInfo(): Promise<FundInfoResponse> {
return api.getFundInfo(BACKEND, IS_MAINNET)
return legacyApi.getFundInfo(BACKEND, IS_MAINNET)
}

async fetchTxStatus(request: TxStatusRequest): Promise<TxStatusResponse> {
return api.fetchTxStatus(request, BACKEND)
return legacyApi.fetchTxStatus(request, BACKEND)
}

async fetchTipStatus(): Promise<TipStatusResponse> {
return api.getTipStatus(BACKEND)
return legacyApi.getTipStatus(BACKEND)
}

async fetchCurrentPrice(symbol: CurrencySymbol): Promise<number> {
return api.fetchCurrentPrice(symbol, BACKEND)
return legacyApi.fetchCurrentPrice(symbol, BACKEND)
}

// TODO: caching
fetchNftModerationStatus(fingerprint: string): Promise<YoroiNftModerationStatus> {
return api.getNFTModerationStatus(fingerprint, {...BACKEND, mainnet: true})
return legacyApi.getNFTModerationStatus(fingerprint, {...BACKEND, mainnet: true})
}

private state: WalletState = {
Expand Down Expand Up @@ -1214,7 +1218,7 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) =>

private async discoverAddresses() {
// last chunk gap limit check
const filterFn = (addrs) => api.filterUsedAddresses(addrs, BACKEND)
const filterFn = (addrs) => legacyApi.filterUsedAddresses(addrs, BACKEND)
await Promise.all([this.internalChain.sync(filterFn), this.externalChain.sync(filterFn)])
}

Expand Down
5 changes: 4 additions & 1 deletion apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
TxMetadata as TxMetadataType,
UnsignedTx as UnsignedTxType,
} from '@emurgo/yoroi-lib'
import {Balance} from '@yoroi/types'
import {App, Balance} from '@yoroi/types'
import {BigNumber} from 'bignumber.js'

import {HWDeviceInfo} from '../hw'
Expand Down Expand Up @@ -97,6 +97,9 @@ export type YoroiWallet = {
primaryToken: Readonly<DefaultAsset>
primaryTokenInfo: Readonly<Balance.TokenInfo>

// API
api: App.Api

signRawTx(txHex: string, pKeys: PrivateKey[]): Promise<Uint8Array | undefined>

// Sending
Expand Down
Loading

0 comments on commit 1cf980f

Please sign in to comment.