diff --git a/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx b/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx
index 4f09984a49..7ff178aef2 100644
--- a/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx
+++ b/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx
@@ -27,7 +27,7 @@ import {BackButton, defaultStackNavigationOptions, TxHistoryRoutes, useWalletNav
import {ReceiveScreen} from '../Receive/ReceiveScreen'
import {useSelectedWallet} from '../SelectedWallet'
import {COLORS} from '../theme'
-import {useWalletName} from '../yoroi-wallets/hooks'
+import {useStakingKey, useWalletName} from '../yoroi-wallets/hooks'
import {ModalInfo} from './ModalInfo'
import {TxDetails} from './TxDetails'
import {TxHistory} from './TxHistory'
@@ -41,11 +41,13 @@ export const TxHistoryNavigator = () => {
const [modalInfoState, setModalInfoState] = React.useState(false)
const showModalInfo = () => setModalInfoState(true)
const hideModalInfo = () => setModalInfoState(false)
+ const stakingKey = useStakingKey(wallet)
const swapStorage = makeSwapStorage()
const swapAPI = makeSwapApi({
network: 0,
- stakingKey: wallet.rewardAddressHex,
+ stakingKey,
+ primaryTokenId: wallet.primaryTokenInfo.id,
})
const swapManager = makeSwapManager(swapStorage, swapAPI)
diff --git a/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx b/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx
index 2762816069..9cf58f2ef0 100644
--- a/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx
+++ b/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx
@@ -214,6 +214,14 @@ storiesOf('Icon', module).add('Gallery', () => {
} title="Swap" />
} title="Portfolio" />
+
+ } title="MinSwap" />
+
+ } title="SundaeSwap" />
+
+ } title="MuesliSwap" />
+
+ } title="WingRiders" />
)
diff --git a/apps/wallet-mobile/src/components/Icon/MinSwap.tsx b/apps/wallet-mobile/src/components/Icon/MinSwap.tsx
new file mode 100644
index 0000000000..b6469e3443
--- /dev/null
+++ b/apps/wallet-mobile/src/components/Icon/MinSwap.tsx
@@ -0,0 +1,25 @@
+import React from 'react'
+import Svg, {Defs, Image, Path, Pattern, Use} from 'react-native-svg'
+
+type Props = {
+ size?: number
+}
+
+export const MinSwap = ({size = 36}: Props) => (
+
+)
diff --git a/apps/wallet-mobile/src/components/Icon/MuesliSwap.tsx b/apps/wallet-mobile/src/components/Icon/MuesliSwap.tsx
new file mode 100644
index 0000000000..dae3bb7846
--- /dev/null
+++ b/apps/wallet-mobile/src/components/Icon/MuesliSwap.tsx
@@ -0,0 +1,252 @@
+import React from 'react'
+import Svg, {G, Path} from 'react-native-svg'
+
+type Props = {
+ size?: number
+}
+
+export const MuesliSwap = ({size = 36}: Props) => (
+
+)
diff --git a/apps/wallet-mobile/src/components/Icon/SundaeSwap.tsx b/apps/wallet-mobile/src/components/Icon/SundaeSwap.tsx
new file mode 100644
index 0000000000..c218ef9328
--- /dev/null
+++ b/apps/wallet-mobile/src/components/Icon/SundaeSwap.tsx
@@ -0,0 +1,25 @@
+import React from 'react'
+import Svg, {Defs, Image, Path, Pattern, Use} from 'react-native-svg'
+
+type Props = {
+ size?: number
+}
+
+export const SundaeSwap = ({size = 36}: Props) => (
+
+)
diff --git a/apps/wallet-mobile/src/components/Icon/WingRiders.tsx b/apps/wallet-mobile/src/components/Icon/WingRiders.tsx
new file mode 100644
index 0000000000..2f5c43c478
--- /dev/null
+++ b/apps/wallet-mobile/src/components/Icon/WingRiders.tsx
@@ -0,0 +1,14 @@
+import React from 'react'
+import Svg, {Path} from 'react-native-svg'
+
+type Props = {
+ size?: number
+}
+export const WingRiders = ({size = 36}: Props) => (
+
+)
diff --git a/apps/wallet-mobile/src/components/Icon/index.ts b/apps/wallet-mobile/src/components/Icon/index.ts
index 054281f606..5de4930600 100644
--- a/apps/wallet-mobile/src/components/Icon/index.ts
+++ b/apps/wallet-mobile/src/components/Icon/index.ts
@@ -45,6 +45,8 @@ import {Magnify} from './Magnify'
import {Megaphone} from './Megaphone'
import {Menu} from './Menu'
import {Message} from './Message'
+import {MinSwap} from './MinSwap'
+import {MuesliSwap} from './MuesliSwap'
import {MultipleWallets} from './MultipleWallets'
import {NftAsset} from './NftAsset'
import {NoNfts} from './NoNfts'
@@ -70,6 +72,7 @@ import {StakingKeyDeregistered} from './StakingKeyDeregistered'
import {StakingKeyRegistered} from './StakingKeyRegistered'
import {StarFilled} from './StarFilled'
import {StarOutlined} from './StarOutlined'
+import {SundaeSwap} from './SundaeSwap'
import {Support} from './Support'
import {Swap} from './Swap'
import {Switch} from './Switch'
@@ -90,6 +93,7 @@ import {Wallet} from './Wallet'
import {WalletAccount} from './WalletAccount'
import {Wallets} from './Wallets'
import {WalletStack} from './WalletStack'
+import {WingRiders} from './WingRiders'
import {YoroiNightly} from './YoroiNightly'
import {YoroiWallet} from './YoroiWallet'
@@ -188,4 +192,8 @@ export const Icon = {
Switch,
Edit,
Portfolio,
+ MinSwap,
+ SundaeSwap,
+ MuesliSwap,
+ WingRiders,
}
diff --git a/apps/wallet-mobile/src/features/Swap/common/PoolIcon/PoolIcon.tsx b/apps/wallet-mobile/src/features/Swap/common/PoolIcon/PoolIcon.tsx
new file mode 100644
index 0000000000..b70b2e21a4
--- /dev/null
+++ b/apps/wallet-mobile/src/features/Swap/common/PoolIcon/PoolIcon.tsx
@@ -0,0 +1,19 @@
+import {Pool} from '@yoroi/openswap'
+import React, {FunctionComponent} from 'react'
+
+import {Icon} from '../../../../components'
+
+export const PoolIcon = ({providerId, size}: {providerId: Pool['provider']; size: number}) => {
+ const IconVariant = icons[providerId]
+ return
+}
+
+const icons: Record> = {
+ muesliswap_v1: Icon.MuesliSwap,
+ muesliswap_v2: Icon.MuesliSwap,
+ muesliswap_v3: Icon.MuesliSwap,
+ muesliswap_v4: Icon.MuesliSwap,
+ minswap: Icon.MinSwap,
+ sundaeswap: Icon.SundaeSwap,
+ wingriders: Icon.WingRiders,
+}
diff --git a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx
index b659b045bd..50324f6d75 100644
--- a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx
+++ b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.tsx
@@ -4,10 +4,11 @@ import React, {useState} from 'react'
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
-import {Icon, Spacer} from '../../../../../components'
+import {Spacer} from '../../../../../components'
import {useMetrics} from '../../../../../metrics/metricsManager'
import {COLORS} from '../../../../../theme'
import {useNavigateTo} from '../../navigation'
+import {PoolIcon} from '../../PoolIcon/PoolIcon'
import {useStrings} from '../../strings'
type Props = {
@@ -42,9 +43,8 @@ export const SelectPoolFromList = ({data = []}: Props) => {
>
handleCardSelect(pool)} style={[styles.card]}>
- {/* TODO add icons for each pool and change it depending on name */}
-
+
{protocolCapitalize(pool.provider)}
diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/CompletedOrders.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/CompletedOrders.tsx
index 92d2bd7e5d..7680f48e98 100644
--- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/CompletedOrders.tsx
+++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/CompletedOrders.tsx
@@ -1,4 +1,3 @@
-import {useOrderByStatusCompleted} from '@yoroi/swap'
import React from 'react'
import {Linking, ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native'
@@ -14,7 +13,8 @@ import {
MainInfoWrapper,
} from '../../../common/SelectPool/ExpendableCard/ExpandableInfoCard'
import {useStrings} from '../../../common/strings'
-import {mapOrders, OrderProps} from './mapOrders'
+import {OrderProps} from './mapOrders'
+import {getMockOrders} from './mocks'
export const CompletedOrders = () => {
const strings = useStrings()
@@ -26,13 +26,7 @@ export const CompletedOrders = () => {
})
const [hiddenInfoOpenId, setHiddenInfoOpenId] = React.useState(null)
- const data = useOrderByStatusCompleted({
- onError: (err) => {
- console.log(err)
- },
- })
-
- const orders = mapOrders(data).filter(
+ const orders = getMockOrders().filter(
({assetFromLabel, assetToLabel}) =>
assetFromLabel.toLocaleLowerCase().includes(search.toLocaleLowerCase()) ||
assetToLabel.toLocaleLowerCase().includes(search.toLocaleLowerCase()),
diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/OpenOrders.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/OpenOrders.tsx
index 3edf5d1219..b0c4346f95 100644
--- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/OpenOrders.tsx
+++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/OpenOrders.tsx
@@ -1,11 +1,17 @@
import {useOrderByStatusOpen} from '@yoroi/swap'
+import {uniq} from 'lodash'
import React from 'react'
+import {useIntl} from 'react-intl'
import {Linking, ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native'
-import {BottomSheetModal, Button, Icon, Spacer, Text, TextInput} from '../../../../../components'
+import {BottomSheetModal, Button, Spacer, Text, TextInput, TokenIcon} from '../../../../../components'
+import {useLanguage} from '../../../../../i18n'
import {useSearch} from '../../../../../Search/SearchContext'
+import {useSelectedWallet} from '../../../../../SelectedWallet'
import {COLORS} from '../../../../../theme'
+import {useTokenInfos, useTransactionInfos} from '../../../../../yoroi-wallets/hooks'
import {Counter} from '../../../common/Counter/Counter'
+import {PoolIcon} from '../../../common/PoolIcon/PoolIcon'
import {
BottomSheetState,
ExpandableInfoCard,
@@ -14,7 +20,7 @@ import {
MainInfoWrapper,
} from '../../../common/SelectPool/ExpendableCard/ExpandableInfoCard'
import {useStrings} from '../../../common/strings'
-import {mapOrders, OrderProps} from './mapOrders'
+import {mapOrders} from './mapOrders'
export const OpenOrders = () => {
const [bottomSheetState, setBottomSheetState] = React.useState({
@@ -22,51 +28,90 @@ export const OpenOrders = () => {
title: '',
content: '',
})
+ const wallet = useSelectedWallet()
const [hiddenInfoOpenId, setHiddenInfoOpenId] = React.useState(null)
const [confirmationModal, setConfirmationModal] = React.useState(false)
const strings = useStrings()
const [spendingPassword, setSpendingPassword] = React.useState('')
-
const {search} = useSearch()
+ const transactionsInfos = useTransactionInfos(wallet)
+ const {numberLocale} = useLanguage()
+ const intl = useIntl()
- const data = useOrderByStatusOpen({
+ const orders = useOrderByStatusOpen({
onError: (err) => {
console.log(err)
},
})
+ const tokenIds = uniq(orders.flatMap((o) => [o.from.tokenId, o.to.tokenId]))
- const orders = mapOrders(data).filter(
- ({assetFromLabel, assetToLabel}) =>
- assetFromLabel.toLocaleLowerCase().includes(search.toLocaleLowerCase()) ||
- assetToLabel.toLocaleLowerCase().includes(search.toLocaleLowerCase()),
- )
+ const tokenInfos = useTokenInfos({wallet, tokenIds: tokenIds})
+
+ const normalizedOrders = mapOrders(orders, tokenInfos, numberLocale, Object.values(transactionsInfos))
+
+ const searchLower = search.toLocaleLowerCase()
+
+ const filteredOrders = normalizedOrders.filter((order) => {
+ return (
+ order.assetFromLabel.toLocaleLowerCase().includes(searchLower) ||
+ order.assetToLabel.toLocaleLowerCase().includes(searchLower)
+ )
+ })
return (
<>
- {orders.map((order) => {
- const id = `${order.assetFromLabel}-${order.assetToLabel}-${order.date}`
+ {filteredOrders.map((order) => {
+ const fromIcon =
+ const toIcon =
+ const liquidityPoolIcon =
return (
}
- hiddenInfo={}
- mainInfo={}
+ label={
+
+ }
+ hiddenInfo={
+
+ }
+ mainInfo={
+
+ }
buttonLabel={strings.listOrdersSheetButtonText.toLocaleUpperCase()}
onPress={() => {
setBottomSheetState({
- openId: id,
+ openId: order.id,
title: strings.listOrdersSheetTitle,
content: (
+ }
+ assetToIcon={}
confirmationModal={confirmationModal}
onConfirm={() => {
setBottomSheetState({openId: null, title: '', content: ''})
@@ -130,38 +175,51 @@ export const OpenOrders = () => {
const HiddenInfo = ({
id,
- order,
setBottomSheetState,
+ total,
+ liquidityPoolIcon,
+ liquidityPoolName,
+ poolUrl,
+ date,
+ txId,
+ txLink,
}: {
id: string
- order: OrderProps
+ total: string
+ liquidityPoolIcon: React.ReactNode
+ liquidityPoolName: string
+ poolUrl: string
+ date: string
+ txId: string
+ txLink: string
setBottomSheetState: (state: BottomSheetState) => void
}) => {
+ const shortenedTxId = `${txId.substring(0, 9)}...${txId.substring(txId.length - 4, txId.length)}`
const strings = useStrings()
return (
{[
{
label: strings.listOrdersTotal,
- value: order.total,
+ value: total,
},
{
label: strings.listOrdersLiquidityPool,
value: (
),
},
{
label: strings.listOrdersTimeCreated,
- value: order.date,
+ value: date,
},
{
label: strings.listOrdersTxId,
- value: ,
+ value: ,
},
].map((item) => (
{
+const MainInfo = ({tokenPrice, tokenAmount}: {tokenPrice: string; tokenAmount: string}) => {
const strings = useStrings()
return (
{[
- {label: strings.listOrdersSheetAssetPrice, value: order.tokenPrice},
- {label: strings.listOrdersSheetAssetAmount, value: order.tokenAmount},
+ {label: strings.listOrdersSheetAssetPrice, value: tokenPrice},
+ {label: strings.listOrdersSheetAssetAmount, value: tokenAmount},
].map((item, index) => (
))}
@@ -224,10 +282,20 @@ const LiquidityPool = ({
)
}
-const Label = ({assetFromLabel, assetToLabel}: {assetFromLabel: string; assetToLabel: string}) => {
+const Label = ({
+ assetFromLabel,
+ assetFromIcon,
+ assetToIcon,
+ assetToLabel,
+}: {
+ assetFromLabel: string
+ assetToLabel: string
+ assetFromIcon: React.ReactNode
+ assetToIcon: React.ReactNode
+}) => {
return (
-
+ {assetFromIcon}
@@ -237,7 +305,7 @@ const Label = ({assetFromLabel, assetToLabel}: {assetFromLabel: string; assetToL
-
+ {assetToIcon}
diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/mapOrders.ts b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/mapOrders.ts
index 93a2296c45..46cbcc8e2d 100644
--- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/mapOrders.ts
+++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/mapOrders.ts
@@ -1,7 +1,13 @@
-import {SwapOpenOrder} from '@yoroi/types/lib/swap/order'
+import {Pool} from '@yoroi/openswap'
+import {Balance} from '@yoroi/types'
+import {SwapOrder} from '@yoroi/types/lib/swap/order'
+import {isString} from '@yoroi/wallets'
+import BigNumber from 'bignumber.js'
import React from 'react'
-import {getMockOrders} from './mocks'
+import {NumberLocale} from '../../../../../i18n/languages'
+import {TransactionInfo} from '../../../../../yoroi-wallets/types'
+import {Quantities} from '../../../../../yoroi-wallets/utils'
export type OrderProps = {
tokenPrice: string
@@ -10,10 +16,6 @@ export type OrderProps = {
assetFromIcon: React.ReactNode
assetToLabel: string
assetToIcon: React.ReactNode
- navigateTo?: () => void
- onPress?: () => void
- buttonText?: string
- withBoxShadow?: boolean
date: string
liquidityPoolIcon: React.ReactNode
liquidityPoolName: string
@@ -23,7 +25,63 @@ export type OrderProps = {
txLink: string
}
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-export const mapOrders = (orders: Array): Array => {
- return getMockOrders()
+export const mapOrders = (
+ orders: Array,
+ tokenInfos: Balance.TokenInfo[],
+ numberLocale: NumberLocale,
+ transactionInfos: TransactionInfo[],
+) => {
+ return orders.map((order) => {
+ const fromTokenInfo = tokenInfos.find((tokenInfo) => tokenInfo.id === order.from.tokenId)
+ const toTokenInfo = tokenInfos.find((tokenInfo) => tokenInfo.id === order.to.tokenId)
+ const id = `${order.from.tokenId}-${order.to.tokenId}-${order.utxo}`
+ const fromLabel = fromTokenInfo?.ticker ?? fromTokenInfo?.name ?? '-'
+ const toLabel = toTokenInfo?.ticker ?? toTokenInfo?.name ?? '-'
+ const tokenAmount = BigNumber(Quantities.denominated(order.to.quantity, toTokenInfo?.decimals ?? 0)).toFormat(
+ numberLocale,
+ )
+ const tokenPrice = BigNumber(
+ Quantities.quotient(
+ Quantities.denominated(order.from.quantity, fromTokenInfo?.decimals ?? 0),
+ Quantities.denominated(order.to.quantity, toTokenInfo?.decimals ?? 0),
+ ),
+ ).toFormat(numberLocale)
+ const txId = order.utxo.split('#')[0]
+ const total = BigNumber(Quantities.denominated(order.from.quantity, fromTokenInfo?.decimals ?? 0)).toFormat(
+ numberLocale,
+ )
+ const matchingTxInfo = transactionInfos.find((tx) => tx.id === txId)
+ const submittedAt = matchingTxInfo?.submittedAt
+ const txLink = `https://cardanoscan.io/transaction/${txId}`
+ const date = isString(submittedAt) ? new Date(submittedAt).toISOString() : ''
+ return {
+ tokenPrice,
+ tokenAmount,
+ id,
+ assetFromLabel: fromLabel,
+ assetToLabel: toLabel,
+ date,
+ txId,
+ total,
+ txLink,
+ fromTokenInfo,
+ toTokenInfo,
+ provider: order.provider,
+ poolUrl: getPoolUrl(order.provider),
+ }
+ })
+}
+
+const getPoolUrl = (provider: Pool['provider']) => {
+ return poolUrls[provider] ?? poolUrls.muesliswap_v1
+}
+
+const poolUrls: Record = {
+ minswap: 'https://minswap.org',
+ sundaeswap: 'https://sundae.fi',
+ wingriders: 'https://www.wingriders.com',
+ muesliswap_v1: 'https://muesliswap.com',
+ muesliswap_v2: 'https://muesliswap.com',
+ muesliswap_v3: 'https://muesliswap.com',
+ muesliswap_v4: 'https://muesliswap.com',
}
diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts
index c5fdaf404b..2c14d5efcf 100644
--- a/apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts
+++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts
@@ -502,7 +502,7 @@ export class ByronWallet implements YoroiWallet {
})
}
- private async getStakingKey() {
+ public async getStakingKey() {
if (this.walletImplementationId == null) throw new Error('Invalid wallet: walletImplementationId')
assert(isHaskellShelley(this.walletImplementationId), 'cannot get staking key from a byron-era wallet')
diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/shelley/ShelleyWallet.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/shelley/ShelleyWallet.ts
index 877cdbe171..1f849ed36e 100644
--- a/apps/wallet-mobile/src/yoroi-wallets/cardano/shelley/ShelleyWallet.ts
+++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/shelley/ShelleyWallet.ts
@@ -442,7 +442,7 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) =>
return Promise.resolve(result)
}
- private async getStakingKey() {
+ public async getStakingKey() {
const accountPubKey = await CardanoMobile.Bip32PublicKey.fromBytes(Buffer.from(this.publicKeyHex, 'hex'))
const stakingKey = await accountPubKey
.derive(CHIMERIC_ACCOUNT)
diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts
index 3dae9245a0..762e5f29a3 100644
--- a/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts
+++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts
@@ -120,6 +120,7 @@ export type YoroiWallet = {
getStakingInfo: () => Promise
fetchAccountState(): Promise
fetchPoolInfo(request: StakePoolInfoRequest): Promise
+ getStakingKey: () => Promise
// Password
encryptedStorage: WalletEncryptedStorage
diff --git a/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts b/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts
index 02d07fbae4..32ffb1b5a9 100644
--- a/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts
+++ b/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts
@@ -3,6 +3,7 @@ import AsyncStorage, {AsyncStorageStatic} from '@react-native-async-storage/asyn
import {useNavigation} from '@react-navigation/native'
import {Balance} from '@yoroi/types'
import {parseBoolean, useStorage} from '@yoroi/wallets'
+import {Buffer} from 'buffer'
import * as React from 'react'
import {useCallback, useMemo} from 'react'
import {
@@ -115,6 +116,18 @@ export const useUtxos = (wallet: YoroiWallet) => {
return wallet.utxos
}
+export const useStakingKey = (wallet: YoroiWallet) => {
+ const getPublicKeyHex: () => Promise = () =>
+ wallet
+ .getStakingKey()
+ .then((r) => r.hash())
+ .then((h) => h.toBytes())
+ .then((bytes) => Buffer.from(bytes).toString('hex'))
+ const result = useQuery([wallet.id, 'stakingKey'], getPublicKeyHex, {suspense: true})
+ if (!result.data) throw new Error('invalid state')
+ return result.data
+}
+
export const useAssetIds = (wallet: YoroiWallet): string[] => {
const balances = useBalances(wallet)
return Object.keys(balances).filter((id) => wallet.primaryTokenInfo.id !== id)
diff --git a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts
index 7602f6db0c..d65129d210 100644
--- a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts
+++ b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts
@@ -73,6 +73,9 @@ const wallet: YoroiWallet = {
createWithdrawalTx: () => {
throw new Error('not implemented: createWithdrawalTx')
},
+ getStakingKey: () => {
+ throw new Error('not implemented: getStakingKey')
+ },
getAllUtxosForKey: () => Promise.resolve([]),
fetchTokenInfo: (tokenId: string) => {
action('fetchTokenInfo')(tokenId)
diff --git a/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json b/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json
index 7a3ef4763d..23b9409e0a 100644
--- a/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json
+++ b/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json
@@ -4,14 +4,14 @@
"defaultMessage": "!!!Receive",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 244,
+ "line": 246,
"column": 16,
- "index": 8416
+ "index": 8497
},
"end": {
- "line": 247,
+ "line": 249,
"column": 3,
- "index": 8505
+ "index": 8586
}
},
{
@@ -19,14 +19,14 @@
"defaultMessage": "!!!Swap",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 248,
+ "line": 250,
"column": 13,
- "index": 8520
+ "index": 8601
},
"end": {
- "line": 251,
+ "line": 253,
"column": 3,
- "index": 8593
+ "index": 8674
}
},
{
@@ -34,14 +34,14 @@
"defaultMessage": "!!!Swap from",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 252,
+ "line": 254,
"column": 17,
- "index": 8612
+ "index": 8693
},
"end": {
- "line": 255,
+ "line": 257,
"column": 3,
- "index": 8689
+ "index": 8770
}
},
{
@@ -49,14 +49,14 @@
"defaultMessage": "!!!Swap to",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 256,
+ "line": 258,
"column": 15,
- "index": 8706
+ "index": 8787
},
"end": {
- "line": 259,
+ "line": 261,
"column": 3,
- "index": 8779
+ "index": 8860
}
},
{
@@ -64,14 +64,14 @@
"defaultMessage": "!!!Slippage Tolerance",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 260,
+ "line": 262,
"column": 21,
- "index": 8802
+ "index": 8883
},
"end": {
- "line": 263,
+ "line": 265,
"column": 3,
- "index": 8897
+ "index": 8978
}
},
{
@@ -79,14 +79,14 @@
"defaultMessage": "!!!Select pool",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 264,
+ "line": 266,
"column": 14,
- "index": 8913
+ "index": 8994
},
"end": {
- "line": 267,
+ "line": 269,
"column": 3,
- "index": 8994
+ "index": 9075
}
},
{
@@ -94,14 +94,14 @@
"defaultMessage": "!!!Send",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 268,
+ "line": 270,
"column": 13,
- "index": 9009
+ "index": 9090
},
"end": {
- "line": 271,
+ "line": 273,
"column": 3,
- "index": 9089
+ "index": 9170
}
},
{
@@ -109,14 +109,14 @@
"defaultMessage": "!!!Scan QR code address",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 272,
+ "line": 274,
"column": 18,
- "index": 9109
+ "index": 9190
},
"end": {
- "line": 275,
+ "line": 277,
"column": 3,
- "index": 9210
+ "index": 9291
}
},
{
@@ -124,14 +124,14 @@
"defaultMessage": "!!!Select asset",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 276,
+ "line": 278,
"column": 20,
- "index": 9232
+ "index": 9313
},
"end": {
- "line": 279,
+ "line": 281,
"column": 3,
- "index": 9321
+ "index": 9402
}
},
{
@@ -139,14 +139,14 @@
"defaultMessage": "!!!Selected tokens",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 280,
+ "line": 282,
"column": 26,
- "index": 9349
+ "index": 9430
},
"end": {
- "line": 283,
+ "line": 285,
"column": 3,
- "index": 9453
+ "index": 9534
}
},
{
@@ -154,14 +154,14 @@
"defaultMessage": "!!!Edit amount",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 284,
+ "line": 286,
"column": 19,
- "index": 9474
+ "index": 9555
},
"end": {
- "line": 287,
+ "line": 289,
"column": 3,
- "index": 9567
+ "index": 9648
}
},
{
@@ -169,14 +169,14 @@
"defaultMessage": "!!!Confirm",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 288,
+ "line": 290,
"column": 16,
- "index": 9585
+ "index": 9666
},
"end": {
- "line": 291,
+ "line": 293,
"column": 3,
- "index": 9671
+ "index": 9752
}
},
{
@@ -184,14 +184,14 @@
"defaultMessage": "!!!Share this address to receive payments. To protect your privacy, new addresses are generated automatically once you use them.",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 292,
+ "line": 294,
"column": 19,
- "index": 9692
+ "index": 9773
},
"end": {
- "line": 298,
+ "line": 300,
"column": 3,
- "index": 9930
+ "index": 10011
}
},
{
@@ -199,14 +199,14 @@
"defaultMessage": "!!!Confirm transaction",
"file": "src/TxHistory/TxHistoryNavigator.tsx",
"start": {
- "line": 299,
+ "line": 301,
"column": 27,
- "index": 9959
+ "index": 10040
},
"end": {
- "line": 302,
+ "line": 304,
"column": 3,
- "index": 10052
+ "index": 10133
}
}
]
\ No newline at end of file
diff --git a/packages/openswap/src/config.ts b/packages/openswap/src/config.ts
index 0a09aa26d2..2df50c2898 100644
--- a/packages/openswap/src/config.ts
+++ b/packages/openswap/src/config.ts
@@ -3,7 +3,7 @@ import axios from 'axios'
export const SWAP_API_ENDPOINTS = {
mainnet: {
getPools: 'https://onchain2.muesliswap.com/pools/pair',
- getOrders: 'https://onchain2.muesliswap.com/orders/all',
+ getOrders: 'https://onchain2.muesliswap.com/orders/all/',
getTokens: 'https://api.muesliswap.com/list',
constructSwapDatum: 'https://aggregator.muesliswap.com/constructSwapDatum',
cancelSwapTransaction:
@@ -11,7 +11,7 @@ export const SWAP_API_ENDPOINTS = {
},
preprod: {
getPools: 'https://preprod.pools.muesliswap.com/pools/pair',
- getOrders: 'https://preprod.pools.muesliswap.com/orders/all',
+ getOrders: 'https://preprod.pools.muesliswap.com/orders/all/',
getTokens: 'https://preprod.api.muesliswap.com/list',
constructSwapDatum:
'https://aggregator.muesliswap.com/constructTestnetSwapDatum',
diff --git a/packages/openswap/src/orders.ts b/packages/openswap/src/orders.ts
index 5f9b417c8f..d858309d2c 100644
--- a/packages/openswap/src/orders.ts
+++ b/packages/openswap/src/orders.ts
@@ -74,9 +74,8 @@ export async function getOrders(
): Promise {
const {network, client} = deps
const {stakeKeyHash} = args
- const apiUrl = SWAP_API_ENDPOINTS[network].getPools
- const response = await client.get('/', {
- baseURL: apiUrl,
+ const apiUrl = SWAP_API_ENDPOINTS[network].getOrders
+ const response = await client.get(apiUrl, {
params: {
'stake-key-hash': stakeKeyHash,
},
diff --git a/packages/openswap/src/types.ts b/packages/openswap/src/types.ts
index c29c8b571a..d13c5f6d9b 100644
--- a/packages/openswap/src/types.ts
+++ b/packages/openswap/src/types.ts
@@ -40,7 +40,15 @@ export type Order = {
utxo: string
}
-export type Protocol = 'minswap' | 'sundaeswap' | 'wingriders' | 'muesliswap'
+export type Protocol =
+ | 'minswap'
+ | 'sundaeswap'
+ | 'wingriders'
+ | 'muesliswap_v1'
+ | 'muesliswap_v2'
+ | 'muesliswap_v3'
+ | 'muesliswap_v4'
+
export type Network = 'mainnet' | 'preprod'
export type Pool = {
@@ -51,6 +59,7 @@ export type Pool = {
| 'muesliswap_v1'
| 'muesliswap_v2'
| 'muesliswap_v3'
+ | 'muesliswap_v4'
fee: string // % pool liquidity provider fee, usually 0.3.
tokenA: {
amount: string // amount of tokenA in the pool, without decimals.
diff --git a/packages/swap/src/adapters/api.ts b/packages/swap/src/adapters/api.ts
index 8c7a2832ba..28e289e2d0 100644
--- a/packages/swap/src/adapters/api.ts
+++ b/packages/swap/src/adapters/api.ts
@@ -5,28 +5,28 @@ import {
asOpenswapTokenId,
asOpenswapTokenIdHex,
asYoroiBalanceTokens,
- // asYoroiOrders,
+ asYoroiOrders,
asYoroiPools,
} from './transformers'
import {getTokensMock} from './tokens.mocks'
import {getPoolsMock} from '../adapters/pools.mocks'
-import {getOrdersMock} from '../adapters/orders.mocks'
export const makeSwapApi = (
// FIX: network Yoroi type need to bring from the wallet // chain Id
- {network /* , stakingKey */}: {network: 1 | 0 | 300; stakingKey: string},
+ {
+ network,
+ stakingKey,
+ primaryTokenId,
+ }: {network: 1 | 0 | 300; stakingKey: string; primaryTokenId: string},
deps?: {openswap?: OpenSwapApi},
): Readonly => {
const api =
deps?.openswap ?? new OpenSwapApi(network === 0 ? 'mainnet' : 'preprod')
- const getOrders: Swap.Api['getOrders'] = async (): Promise<
- Swap.OpenOrder[]
- > => {
- // return api.getOrders(stakingKey).then(asYoroiOrders)
- await new Promise((r) => setTimeout(r, 500))
-
- return getOrdersMock
+ const getOrders: Swap.Api['getOrders'] = async () => {
+ return api
+ .getOrders(stakingKey)
+ .then((orders) => asYoroiOrders(orders, primaryTokenId))
}
const createOrder: Swap.Api['createOrder'] = async (
diff --git a/packages/swap/src/adapters/orders.mocks.ts b/packages/swap/src/adapters/orders.mocks.ts
index 631ac69ff9..3a803e2c57 100644
--- a/packages/swap/src/adapters/orders.mocks.ts
+++ b/packages/swap/src/adapters/orders.mocks.ts
@@ -1,6 +1,6 @@
import {Swap} from '@yoroi/types'
-export const getOrdersMock: Array = [
+export const getOrdersMock: Array = [
{
provider: 'minswap',
from: {
@@ -14,9 +14,8 @@ export const getOrdersMock: Array = [
quantity: '123',
},
deposit: {
- tokenId:
- '648823ffdad1610b4162f4dbc87bd47f6f9cf45d772ddef661eff198.7755534443',
quantity: '123',
+ tokenId: '',
},
utxo: '1d38bea2d83eec5cca60ca2c1c3cc0db48b8e2e1a632c2d97849adb5357aca05',
},
@@ -33,9 +32,8 @@ export const getOrdersMock: Array = [
quantity: '123',
},
deposit: {
- tokenId:
- '648823ffdad1610b4162f4dbc87bd47f6f9cf45d772ddef661eff198.7755534443',
quantity: '123',
+ tokenId: '',
},
utxo: '1d38bea2d83eec5cca60ca2c1c3cc0db48b8e2e1a632c2d97849adb5357aca05',
},
diff --git a/packages/swap/src/adapters/transformers.test.ts b/packages/swap/src/adapters/transformers.test.ts
index 0565b2c749..6d12965dcd 100644
--- a/packages/swap/src/adapters/transformers.test.ts
+++ b/packages/swap/src/adapters/transformers.test.ts
@@ -66,7 +66,7 @@ describe('asYoroiOrder', () => {
provider: 'minswap',
}
- const result = asYoroiOrder(openswapOrder)
+ const result = asYoroiOrder(openswapOrder, 'primaryTokenId.1')
expect(result).toEqual({
from: {
@@ -77,10 +77,7 @@ describe('asYoroiOrder', () => {
quantity: '150',
tokenId: '656565.tokenE',
},
- deposit: {
- quantity: '100',
- tokenId: '',
- },
+ deposit: {quantity: '100', tokenId: 'primaryTokenId.1'},
provider: 'minswap',
utxo: 'utxo',
})
diff --git a/packages/swap/src/adapters/transformers.ts b/packages/swap/src/adapters/transformers.ts
index 3e180004db..5416ba046b 100644
--- a/packages/swap/src/adapters/transformers.ts
+++ b/packages/swap/src/adapters/transformers.ts
@@ -39,14 +39,13 @@ export const asOpenswapAmount = (yoroiAmount: Balance.Amount) => {
} as const
}
-export const asYoroiOrder = (openswapOrder: Order) => {
+export const asYoroiOrder = (openswapOrder: Order, primaryTokenId: string) => {
const {from, to, deposit, ...rest} = openswapOrder
return {
...rest,
from: asYoroiAmount(from),
to: asYoroiAmount(to),
- // TODO: initialize the module with the primary token
- deposit: asYoroiAmount({amount: deposit, token: ''}), // token = wallet.primaryTokenInfo['id']
+ deposit: asYoroiAmount({amount: deposit, token: primaryTokenId}),
} as const
}
@@ -133,8 +132,11 @@ export const asYoroiBalanceTokens = (
openswapTokens: Token[],
): Balance.Token[] => openswapTokens.map(asYoroiBalanceToken)
-export const asYoroiOrders = (openswapOrders: Order[]): Swap.OpenOrder[] =>
- openswapOrders.map(asYoroiOrder)
+export const asYoroiOrders = (
+ openswapOrders: Order[],
+ primaryTokenId: string,
+): Swap.Order[] =>
+ openswapOrders.map((order) => asYoroiOrder(order, primaryTokenId))
// TODO: later replace for @yoroi/utils
export const asTokenFingerprint = ({
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index a247f5284b..ea634abda3 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -9,6 +9,7 @@ import {SwapApi} from './swap/api'
import {SwapProtocol} from './swap/protocol'
import {
SwapCancelOrderData,
+ SwapCompletedOrder,
SwapCreateOrderData,
SwapCreateOrderResponse,
SwapOpenOrder,
@@ -33,6 +34,8 @@ export namespace Swap {
export type OrderType = SwapOrderType
export type Protocol = SwapProtocol
export type OpenOrder = SwapOpenOrder
+ export type CompletedOrder = SwapCompletedOrder
+ export type Order = SwapOpenOrder | SwapCompletedOrder
export type PoolPair = SwapPoolPair
export interface Api extends SwapApi {}
export type Manager = SwapManager
diff --git a/packages/types/src/swap/api.ts b/packages/types/src/swap/api.ts
index 2adc148cc8..41a42d3035 100644
--- a/packages/types/src/swap/api.ts
+++ b/packages/types/src/swap/api.ts
@@ -3,14 +3,14 @@ import {
SwapCancelOrderData,
SwapCreateOrderData,
SwapCreateOrderResponse,
- SwapOpenOrder,
+ SwapOrder,
} from './order'
import {SwapPoolPair} from './pool'
export interface SwapApi {
createOrder(orderData: SwapCreateOrderData): Promise
cancelOrder(orderData: SwapCancelOrderData): Promise
- getOrders(): Promise
+ getOrders(): Promise
getPoolPairs(args: {
tokenA: BalanceToken['info']['id']
tokenB: BalanceToken['info']['id']
diff --git a/packages/types/src/swap/order.ts b/packages/types/src/swap/order.ts
index 51aafa0b4d..9401b64e3e 100644
--- a/packages/types/src/swap/order.ts
+++ b/packages/types/src/swap/order.ts
@@ -1,6 +1,5 @@
import {BalanceAmount, BalanceQuantity} from '../balance/token'
import {SwapPoolPair} from './pool'
-import {SwapProtocol} from './protocol'
export type SwapOrderType = 'market' | 'limit'
@@ -30,9 +29,19 @@ export type SwapCreateOrderResponse = {
}
export type SwapOpenOrder = {
- provider: SwapProtocol
+ provider: SwapPoolPair['provider']
from: BalanceAmount
to: BalanceAmount
deposit: BalanceAmount
utxo: string
}
+
+export type SwapCompletedOrder = {
+ provider: SwapPoolPair['provider']
+ from: BalanceAmount
+ to: BalanceAmount
+ deposit: BalanceAmount
+ utxo: string
+}
+
+export type SwapOrder = SwapOpenOrder | SwapCompletedOrder
diff --git a/packages/types/src/swap/pool.ts b/packages/types/src/swap/pool.ts
index 8edd80c125..5087639339 100644
--- a/packages/types/src/swap/pool.ts
+++ b/packages/types/src/swap/pool.ts
@@ -8,6 +8,8 @@ export type SwapPoolPair = {
| 'muesliswap_v1'
| 'muesliswap_v2'
| 'muesliswap_v3'
+ | 'muesliswap_v4'
+
fee: string // % pool liquidity provider fee, usually 0.3.
tokenA: BalanceAmount
tokenB: BalanceAmount