diff --git a/apps/wallet-mobile/.storybook/storybook.requires.js b/apps/wallet-mobile/.storybook/storybook.requires.js index 242a8c4a84..b791c34815 100644 --- a/apps/wallet-mobile/.storybook/storybook.requires.js +++ b/apps/wallet-mobile/.storybook/storybook.requires.js @@ -69,8 +69,6 @@ const getStories = () => { "./src/components/AmountItem/AmountItem.stories.tsx": require("../src/components/AmountItem/AmountItem.stories.tsx"), "./src/components/Analytics/Analytics.stories.tsx": require("../src/components/Analytics/Analytics.stories.tsx"), "./src/components/BlueCheckbox/BlueCheckbox.stories.tsx": require("../src/components/BlueCheckbox/BlueCheckbox.stories.tsx"), - "./src/components/BottomSheet/BottomSheet.stories.tsx": require("../src/components/BottomSheet/BottomSheet.stories.tsx"), - "./src/components/BottomSheetModal/BottomSheetModal.stories.tsx": require("../src/components/BottomSheetModal/BottomSheetModal.stories.tsx"), "./src/components/Boundary/Boundary.stories.tsx": require("../src/components/Boundary/Boundary.stories.tsx"), "./src/components/Button/Button.stories.tsx": require("../src/components/Button/Button.stories.tsx"), "./src/components/Checkbox/Checkbox.stories.tsx": require("../src/components/Checkbox/Checkbox.stories.tsx"), @@ -87,7 +85,6 @@ const getStories = () => { "./src/components/LanguagePicker/LanguagePickerWarning.stories.tsx": require("../src/components/LanguagePicker/LanguagePickerWarning.stories.tsx"), "./src/components/Link/Link.stories.tsx": require("../src/components/Link/Link.stories.tsx"), "./src/components/LoadingOverlay/LoadingOverlay.stories.tsx": require("../src/components/LoadingOverlay/LoadingOverlay.stories.tsx"), - "./src/components/Modal/Modal.stories.tsx": require("../src/components/Modal/Modal.stories.tsx"), "./src/components/NftImageGallery/NftImageGallery.stories.tsx": require("../src/components/NftImageGallery/NftImageGallery.stories.tsx"), "./src/components/NftPreview/NftPreview.stories.tsx": require("../src/components/NftPreview/NftPreview.stories.tsx"), "./src/components/QRCodeScanner/QRCodeScanner.stories.tsx": require("../src/components/QRCodeScanner/QRCodeScanner.stories.tsx"), @@ -168,6 +165,9 @@ const getStories = () => { "./src/HW/LedgerConnect/DeviceItem/DeviceItem.stories.tsx": require("../src/HW/LedgerConnect/DeviceItem/DeviceItem.stories.tsx"), "./src/HW/LedgerConnect/LedgerConnect.stories.tsx": require("../src/HW/LedgerConnect/LedgerConnect.stories.tsx"), "./src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.stories.tsx": require("../src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.stories.tsx"), + "./src/legacy/BottomSheet/BottomSheet.stories.tsx": require("../src/legacy/BottomSheet/BottomSheet.stories.tsx"), + "./src/legacy/BottomSheetModal/BottomSheetModal.stories.tsx": require("../src/legacy/BottomSheetModal/BottomSheetModal.stories.tsx"), + "./src/legacy/Modal/Modal.stories.tsx": require("../src/legacy/Modal/Modal.stories.tsx"), "./src/Legal/PrivacyPolicy/PrivacyPolicy.stories.tsx": require("../src/Legal/PrivacyPolicy/PrivacyPolicy.stories.tsx"), "./src/metrics/metrics.stories.tsx": require("../src/metrics/metrics.stories.tsx"), "./src/NftDetails/NftDetails.stories.tsx": require("../src/NftDetails/NftDetails.stories.tsx"), diff --git a/apps/wallet-mobile/package.json b/apps/wallet-mobile/package.json index dece8d55bb..2727ff2b50 100644 --- a/apps/wallet-mobile/package.json +++ b/apps/wallet-mobile/package.json @@ -110,7 +110,7 @@ "@emurgo/csl-mobile-bridge": "^5.1.2", "@emurgo/react-native-blockies-svg": "^0.0.2", "@emurgo/react-native-hid": "^5.15.6", - "@emurgo/yoroi-lib": "^0.9.8", + "@emurgo/yoroi-lib": "^0.10.1", "@formatjs/intl-datetimeformat": "^6.7.0", "@formatjs/intl-getcanonicallocales": "^2.1.0", "@formatjs/intl-locale": "^3.2.1", diff --git a/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTx.tsx b/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTx.tsx index 3685037542..94e7faa18c 100644 --- a/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTx.tsx +++ b/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTx.tsx @@ -5,11 +5,17 @@ import {ConfirmRawTxWithHW} from './ConfirmRawTxWithHW' import {ConfirmRawTxWithOs} from './ConfirmRawTxWithOs' import {ConfirmRawTxWithPassword} from './ConfirmRawTxWithPassword' -export const ConfirmRawTx = ({onConfirm}: {onConfirm?: (rootKey: string) => Promise}) => { +export const ConfirmRawTx = ({ + onConfirm, + onHWConfirm, +}: { + onConfirm?: (rootKey: string) => Promise + onHWConfirm?: ({useUSB}: {useUSB: boolean}) => Promise +}) => { const wallet = useSelectedWallet() if (wallet.isHW) { - return + return } if (wallet.isEasyConfirmationEnabled) { diff --git a/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTxWithHW.tsx b/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTxWithHW.tsx index 56697d7792..1be393b00d 100644 --- a/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTxWithHW.tsx +++ b/apps/wallet-mobile/src/features/Swap/common/ConfirmRawTx/ConfirmRawTxWithHW.tsx @@ -1,4 +1,57 @@ -export const ConfirmRawTxWithHW = () => { - // TODO: Needs to be implemented - return null +import React, {useState} from 'react' +import {ActivityIndicator, ScrollView} from 'react-native' + +import {LedgerConnect} from '../../../../HW' +import {useSelectedWallet} from '../../../../SelectedWallet' +import {DeviceId, DeviceObj, withBLE, withUSB} from '../../../../yoroi-wallets/hw' +import {walletManager} from '../../../../yoroi-wallets/walletManager' +import {LedgerTransportSwitch} from '../../useCases/ConfirmTxScreen/LedgerTransportSwitch' + +type TransportType = 'USB' | 'BLE' +type Step = 'select-transport' | 'connect-transport' | 'loading' + +type Props = { + onConfirm?: (options: {useUSB: boolean}) => void +} + +export const ConfirmRawTxWithHW = ({onConfirm}: Props) => { + const [transportType, setTransportType] = useState('USB') + const [step, setStep] = useState('select-transport') + const wallet = useSelectedWallet() + + const onSelectTransport = (transportType: TransportType) => { + setTransportType(transportType) + setStep('connect-transport') + } + + const onConnectBLE = async (deviceId: DeviceId) => { + await walletManager.updateHWDeviceInfo(wallet, withBLE(wallet, deviceId)) + onConfirm?.({useUSB: false}) + setStep('loading') + } + + const onConnectUSB = async (deviceObj: DeviceObj) => { + await walletManager.updateHWDeviceInfo(wallet, withUSB(wallet, deviceObj)) + onConfirm?.({useUSB: true}) + setStep('loading') + } + + if (step === 'select-transport') { + return ( + onSelectTransport('BLE')} + onSelectUSB={() => onSelectTransport('USB')} + /> + ) + } + + if (step === 'connect-transport') { + return ( + + + + ) + } + + return } 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 47221c5c15..50ae7bd8de 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 @@ -1,14 +1,13 @@ -import {getPairPriceInPtTerms, useSwap} from '@yoroi/swap' -import {Balance, Swap} from '@yoroi/types' +import {useSwap} from '@yoroi/swap' +import {Swap} from '@yoroi/types' import React, {useState} from 'react' import {StyleSheet, Text, TouchableOpacity, View} from 'react-native' import LinearGradient from 'react-native-linear-gradient' -import {Boundary, Spacer} from '../../../../../components' +import {Spacer} from '../../../../../components' import {useMetrics} from '../../../../../metrics/metricsManager' import {useSelectedWallet} from '../../../../../SelectedWallet' import {COLORS} from '../../../../../theme' -import {YoroiWallet} from '../../../../../yoroi-wallets/cardano/types' import {useTokenInfo} from '../../../../../yoroi-wallets/hooks' import {Quantities} from '../../../../../yoroi-wallets/utils' import {useNavigateTo} from '../../navigation' @@ -16,6 +15,8 @@ import {PoolIcon} from '../../PoolIcon/PoolIcon' import {useStrings} from '../../strings' import {useSwapTouched} from '../../SwapFormProvider' +const PRECISION = 14 + type Props = { pools?: ReadonlyArray } @@ -28,6 +29,10 @@ export const SelectPoolFromList = ({pools = []}: Props) => { const navigate = useNavigateTo() const {track} = useMetrics() + const sellTokenInfo = useTokenInfo({wallet, tokenId: orderData.amounts.sell.tokenId}) + const buyTokenInfo = useTokenInfo({wallet, tokenId: orderData.amounts.buy.tokenId}) + const denomination = (sellTokenInfo.decimals ?? 0) - (buyTokenInfo.decimals ?? 0) + const handleOnPoolSelection = (pool: Swap.Pool) => { track.swapPoolChanged() selectedPoolChanged(pool.poolId) @@ -69,9 +74,17 @@ export const SelectPoolFromList = ({pools = []}: Props) => { - - - + + {strings.price} + + + {Quantities.format( + orderData.selectedPoolCalculation?.prices.market ?? Quantities.zero, + denomination, + PRECISION, + )} + + @@ -116,32 +129,6 @@ export const SelectPoolFromList = ({pools = []}: Props) => { ) } -type PriceInAdaProps = {pool: Swap.Pool; wallet: YoroiWallet; sell: Balance.Amount} -const PriceInAda = ({pool, wallet, sell}: PriceInAdaProps) => { - const strings = useStrings() - const {ptPriceTokenA, ptPriceTokenB, tokenA, tokenB} = pool - - const {decimals: decimalsA = 0} = useTokenInfo({wallet, tokenId: tokenA.tokenId}) - const {decimals: decimalsB = 0} = useTokenInfo({wallet, tokenId: tokenB.tokenId}) - - const {ptPriceAB} = getPairPriceInPtTerms({ - amountA: tokenA, - decimalsA, - decimalsB, - ptPriceTokenA, - ptPriceTokenB, - sell, - }) - - return ( - - {strings.price} - - {ptPriceAB} - - ) -} - const styles = StyleSheet.create({ container: { paddingHorizontal: 16, diff --git a/apps/wallet-mobile/src/features/Swap/common/helpers.ts b/apps/wallet-mobile/src/features/Swap/common/helpers.ts index f095b15c9f..4ad44c6095 100644 --- a/apps/wallet-mobile/src/features/Swap/common/helpers.ts +++ b/apps/wallet-mobile/src/features/Swap/common/helpers.ts @@ -3,7 +3,6 @@ import {Swap} from '@yoroi/types' import {YoroiWallet} from '../../../yoroi-wallets/cardano/types' import {YoroiEntry} from '../../../yoroi-wallets/types' import {Quantities} from '../../../yoroi-wallets/utils' - export const createYoroiEntry = ( createOrder: Swap.CreateOrderData, address: string, diff --git a/apps/wallet-mobile/src/features/Swap/common/strings.ts b/apps/wallet-mobile/src/features/Swap/common/strings.ts index 6a55e3dfa4..d9e8f98400 100644 --- a/apps/wallet-mobile/src/features/Swap/common/strings.ts +++ b/apps/wallet-mobile/src/features/Swap/common/strings.ts @@ -1,6 +1,6 @@ import {defineMessages, useIntl} from 'react-intl' -import globalMessages, {errorMessages} from '../../../i18n/global-messages' +import globalMessages, {errorMessages, ledgerMessages} from '../../../i18n/global-messages' export const useStrings = () => { const intl = useIntl() @@ -91,6 +91,7 @@ export const useStrings = () => { limitPriceWarningBack: intl.formatMessage(messages.limitPriceWarningBack), limitPriceWarningConfirm: intl.formatMessage(messages.limitPriceWarningConfirm), error: intl.formatMessage(globalMessages.error), + rejectedByUser: intl.formatMessage(ledgerMessages.rejectedByUserError), usbExplanation: intl.formatMessage(messages.usbExplanation), usbButton: intl.formatMessage(messages.usbButton), usbConnectionIsBlocked: intl.formatMessage(messages.usbConnectionIsBlocked), diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditLimitPrice.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditLimitPrice.tsx index 74ae20f445..f40705a7d3 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditLimitPrice.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/CreateOrder/EditLimitPrice.tsx @@ -12,7 +12,7 @@ import {useStrings} from '../../../common/strings' import {useSwapTouched} from '../../../common/SwapFormProvider' const BORDER_SIZE = 1 -const PRECISION = 10 +const PRECISION = 14 export const EditLimitPrice = () => { const strings = useStrings() 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 2de27c4ede..27a0a10e77 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 @@ -27,15 +27,19 @@ import {useWalletNavigation} from '../../../../../navigation' import {useSearch} from '../../../../../Search/SearchContext' import {useSelectedWallet} from '../../../../../SelectedWallet' import {COLORS} from '../../../../../theme' +import { + convertBech32ToHex, + getMuesliSwapTransactionAndSigners, +} from '../../../../../yoroi-wallets/cardano/common/signatureUtils' import {createRawTxSigningKey, generateCIP30UtxoCbor} from '../../../../../yoroi-wallets/cardano/utils' import {useTokenInfos, useTransactionInfos} from '../../../../../yoroi-wallets/hooks' +import {RejectedByUserError} from '../../../../../yoroi-wallets/hw' import {ConfirmRawTx} from '../../../common/ConfirmRawTx/ConfirmRawTx' import {Counter} from '../../../common/Counter/Counter' -import {useNavigateTo} from '../../../common/navigation' import {PoolIcon} from '../../../common/PoolIcon/PoolIcon' import {useStrings} from '../../../common/strings' -import {convertBech32ToHex, getMuesliSwapTransactionAndSigners, useCancellationOrderFee} from './helpers' -import {mapOpenOrders, MappedOpenOrder} from './mapOrders' +import {useCancellationOrderFee} from './helpers' +import {mapOrders, MappedOrder} from './mapOrders' export const OpenOrders = () => { const [bottomSheetState, setBottomSheetState] = React.useState({ @@ -49,7 +53,7 @@ export const OpenOrders = () => { const intl = useIntl() const wallet = useSelectedWallet() const {order: swapApiOrder} = useSwap() - const {navigateToCollateralSettings} = useWalletNavigation() + const {navigateToCollateralSettings, navigateToTxHistory} = useWalletNavigation() const bottomSheetRef = React.useRef(null) const orders = useSwapOrdersByStatusOpen() @@ -58,12 +62,11 @@ export const OpenOrders = () => { const transactionsInfos = useTransactionInfos(wallet) const tokenInfos = useTokenInfos({wallet, tokenIds}) const normalizedOrders = React.useMemo( - () => mapOpenOrders(orders, tokenInfos, numberLocale, Object.values(transactionsInfos)), + () => mapOrders(orders, tokenInfos, numberLocale, Object.values(transactionsInfos)), [orders, tokenInfos, numberLocale, transactionsInfos], ) const {search} = useSearch() - const swapNavigation = useNavigateTo() const filteredOrders = React.useMemo( () => @@ -85,7 +88,7 @@ export const OpenOrders = () => { }, [track]), ) - const trackCancellationSubmitted = (order: MappedOpenOrder) => { + const trackCancellationSubmitted = (order: MappedOrder) => { track.swapCancelationSubmitted({ from_amount: Number(order.from.quantity) ?? 0, to_amount: Number(order.to.quantity) ?? 0, @@ -115,15 +118,50 @@ export const OpenOrders = () => { await wallet.submitTransaction(tx.txBase64) trackCancellationSubmitted(order) closeBottomSheet() - swapNavigation.submittedTx() + navigateToTxHistory() + } + + const onRawTxHwConfirm = async ({useUSB, orderId}: {useUSB: boolean; orderId: string}) => { + try { + const order = normalizedOrders.find((o) => o.id === orderId) + if (!order || order.owner === undefined || order.utxo === undefined) return + const {utxo, owner: bech32Address} = order + const collateralUtxo = await getCollateralUtxo() + const addressHex = await convertBech32ToHex(bech32Address) + const originalCbor = await swapApiOrder.cancel({ + utxos: {collateral: collateralUtxo, order: utxo}, + address: addressHex, + }) + const {cbor} = await getMuesliSwapTransactionAndSigners(originalCbor, wallet) + await wallet.signSwapCancellationWithLedger(cbor, useUSB) + + closeBottomSheet() + navigateToTxHistory() + } catch (e) { + if (e instanceof RejectedByUserError) { + Alert.alert(strings.error, strings.rejectedByUser) + closeBottomSheet() + return + } + + if (e instanceof Error) { + Alert.alert(strings.error, e.message) + closeBottomSheet() + } + } } const onOrderCancelConfirm = (id: string) => { setBottomSheetState({ openId: id, title: strings.signTransaction, - content: onRawTxConfirm(rootKey, id)} />, - height: 350, + content: ( + onRawTxConfirm(rootKey, id)} + onHWConfirm={({useUSB}) => onRawTxHwConfirm({useUSB, orderId: id})} + /> + ), + height: 400, }) } @@ -166,7 +204,7 @@ export const OpenOrders = () => { return {txBase64: hexBase64} } - const openBottomSheet = async (order: MappedOpenOrder) => { + const openBottomSheet = async (order: MappedOrder) => { if (order.owner === undefined || order.utxo === undefined) return const { utxo, @@ -696,4 +734,4 @@ const styles = StyleSheet.create({ alignSelf: 'stretch', paddingHorizontal: 16, }, -}) +}) \ No newline at end of file diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/helpers.ts b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/helpers.ts index 14a6ed9c2b..7d49f4392f 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/helpers.ts +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartSwapScreen/ListOrders/helpers.ts @@ -1,17 +1,10 @@ -import * as CSL_TYPES from '@emurgo/cross-csl-core' import {useSwap} from '@yoroi/swap' import {BalanceQuantity} from '@yoroi/types/src/balance/token' import {Buffer} from 'buffer' -import _ from 'lodash' import {useCallback} from 'react' import {useQuery} from 'react-query' import {useSelectedWallet} from '../../../../../SelectedWallet' -import {HARD_DERIVATION_START} from '../../../../../yoroi-wallets/cardano/constants/common' -import {NUMBERS} from '../../../../../yoroi-wallets/cardano/numbers' -import {YoroiWallet} from '../../../../../yoroi-wallets/cardano/types' -import {isHaskellShelley} from '../../../../../yoroi-wallets/cardano/utils' -import {RawUtxo} from '../../../../../yoroi-wallets/types' import {Quantities} from '../../../../../yoroi-wallets/utils' import {CardanoMobile} from '../../../../../yoroi-wallets/wallets' @@ -53,549 +46,3 @@ export const useCancellationOrderFee = (options: Options) => { if (!result.data) throw new Error('invalid state') return result.data } - -export const convertBech32ToHex = async (bech32Address: string) => { - const address = await CardanoMobile.Address.fromBech32(bech32Address) - const bytes = await address.toBytes() - return new Buffer(bytes).toString('hex') -} - -export const harden = (num: number) => HARD_DERIVATION_START + num - -export const getCostModel = async () => { - const babbageCostModels = await CardanoMobile.Costmdls.new() - const v1CostModel = await CardanoMobile.CostModel.new() - await Promise.all( - operations1.map(async (cost, operation) => v1CostModel.set(operation, await CardanoMobile.Int.newI32(cost))), - ) - - const v2CostModel = await CardanoMobile.CostModel.new() - await Promise.all( - operations2.map(async (cost, operation) => v2CostModel.set(operation, await CardanoMobile.Int.newI32(cost))), - ) - - await babbageCostModels.insert(await CardanoMobile.Language.newPlutusV1(), v1CostModel) - await babbageCostModels.insert(await CardanoMobile.Language.newPlutusV2(), v2CostModel) - - return babbageCostModels -} - -const bigNumFromStr = async (str: string) => { - const bigNum = await CardanoMobile.BigNum.fromStr(str) - if (!bigNum) throw new Error('Could not parse big number from string ' + str) - return bigNum -} - -export const getTransactionBuilder = async () => { - const linearFee = await CardanoMobile.LinearFee.new(await bigNumFromStr('44'), await bigNumFromStr('155381')) - - const exUnitPrices = await CardanoMobile.ExUnitPrices.new( - await CardanoMobile.UnitInterval.new(await bigNumFromStr('577'), await bigNumFromStr('10000')), - await CardanoMobile.UnitInterval.new(await bigNumFromStr('721'), await bigNumFromStr('10000000')), - ) - - const txBuilderCfg = await CardanoMobile.TransactionBuilderConfigBuilder.new() - .then((builder) => builder.feeAlgo(linearFee)) - .then(async (builder) => builder.poolDeposit(await bigNumFromStr('500000000'))) - .then(async (builder) => builder.keyDeposit(await bigNumFromStr('2000000'))) - .then((builder) => builder.maxValueSize(4000)) - .then((builder) => builder.maxTxSize(8000)) - .then(async (builder) => builder.coinsPerUtxoWord(await bigNumFromStr('34482'))) - .then(async (builder) => builder.exUnitPrices(exUnitPrices).then((builder) => builder.build())) - - return CardanoMobile.TransactionBuilder.new(assertRequired(txBuilderCfg, 'Could not build transaction builder')) -} - -const operations1 = Object.values({ - 'addInteger-cpu-arguments-intercept': 205665, - 'addInteger-cpu-arguments-slope': 812, - 'addInteger-memory-arguments-intercept': 1, - 'addInteger-memory-arguments-slope': 1, - 'appendByteString-cpu-arguments-intercept': 1000, - 'appendByteString-cpu-arguments-slope': 571, - 'appendByteString-memory-arguments-intercept': 0, - 'appendByteString-memory-arguments-slope': 1, - 'appendString-cpu-arguments-intercept': 1000, - 'appendString-cpu-arguments-slope': 24177, - 'appendString-memory-arguments-intercept': 4, - 'appendString-memory-arguments-slope': 1, - 'bData-cpu-arguments': 1000, - 'bData-memory-arguments': 32, - 'blake2b_256-cpu-arguments-intercept': 117366, - 'blake2b_256-cpu-arguments-slope': 10475, - 'blake2b_256-memory-arguments': 4, - 'cekApplyCost-exBudgetCPU': 23000, - 'cekApplyCost-exBudgetMemory': 100, - 'cekBuiltinCost-exBudgetCPU': 23000, - 'cekBuiltinCost-exBudgetMemory': 100, - 'cekConstCost-exBudgetCPU': 23000, - 'cekConstCost-exBudgetMemory': 100, - 'cekDelayCost-exBudgetCPU': 23000, - 'cekDelayCost-exBudgetMemory': 100, - 'cekForceCost-exBudgetCPU': 23000, - 'cekForceCost-exBudgetMemory': 100, - 'cekLamCost-exBudgetCPU': 23000, - 'cekLamCost-exBudgetMemory': 100, - 'cekStartupCost-exBudgetCPU': 100, - 'cekStartupCost-exBudgetMemory': 100, - 'cekVarCost-exBudgetCPU': 23000, - 'cekVarCost-exBudgetMemory': 100, - 'chooseData-cpu-arguments': 19537, - 'chooseData-memory-arguments': 32, - 'chooseList-cpu-arguments': 175354, - 'chooseList-memory-arguments': 32, - 'chooseUnit-cpu-arguments': 46417, - 'chooseUnit-memory-arguments': 4, - 'consByteString-cpu-arguments-intercept': 221973, - 'consByteString-cpu-arguments-slope': 511, - 'consByteString-memory-arguments-intercept': 0, - 'consByteString-memory-arguments-slope': 1, - 'constrData-cpu-arguments': 89141, - 'constrData-memory-arguments': 32, - 'decodeUtf8-cpu-arguments-intercept': 497525, - 'decodeUtf8-cpu-arguments-slope': 14068, - 'decodeUtf8-memory-arguments-intercept': 4, - 'decodeUtf8-memory-arguments-slope': 2, - 'divideInteger-cpu-arguments-constant': 196500, - 'divideInteger-cpu-arguments-model-arguments-intercept': 453240, - 'divideInteger-cpu-arguments-model-arguments-slope': 220, - 'divideInteger-memory-arguments-intercept': 0, - 'divideInteger-memory-arguments-minimum': 1, - 'divideInteger-memory-arguments-slope': 1, - 'encodeUtf8-cpu-arguments-intercept': 1000, - 'encodeUtf8-cpu-arguments-slope': 28662, - 'encodeUtf8-memory-arguments-intercept': 4, - 'encodeUtf8-memory-arguments-slope': 2, - 'equalsByteString-cpu-arguments-constant': 245000, - 'equalsByteString-cpu-arguments-intercept': 216773, - 'equalsByteString-cpu-arguments-slope': 62, - 'equalsByteString-memory-arguments': 1, - 'equalsData-cpu-arguments-intercept': 1060367, - 'equalsData-cpu-arguments-slope': 12586, - 'equalsData-memory-arguments': 1, - 'equalsInteger-cpu-arguments-intercept': 208512, - 'equalsInteger-cpu-arguments-slope': 421, - 'equalsInteger-memory-arguments': 1, - 'equalsString-cpu-arguments-constant': 187000, - 'equalsString-cpu-arguments-intercept': 1000, - 'equalsString-cpu-arguments-slope': 52998, - 'equalsString-memory-arguments': 1, - 'fstPair-cpu-arguments': 80436, - 'fstPair-memory-arguments': 32, - 'headList-cpu-arguments': 43249, - 'headList-memory-arguments': 32, - 'iData-cpu-arguments': 1000, - 'iData-memory-arguments': 32, - 'ifThenElse-cpu-arguments': 80556, - 'ifThenElse-memory-arguments': 1, - 'indexByteString-cpu-arguments': 57667, - 'indexByteString-memory-arguments': 4, - 'lengthOfByteString-cpu-arguments': 1000, - 'lengthOfByteString-memory-arguments': 10, - 'lessThanByteString-cpu-arguments-intercept': 197145, - 'lessThanByteString-cpu-arguments-slope': 156, - 'lessThanByteString-memory-arguments': 1, - 'lessThanEqualsByteString-cpu-arguments-intercept': 197145, - 'lessThanEqualsByteString-cpu-arguments-slope': 156, - 'lessThanEqualsByteString-memory-arguments': 1, - 'lessThanEqualsInteger-cpu-arguments-intercept': 204924, - 'lessThanEqualsInteger-cpu-arguments-slope': 473, - 'lessThanEqualsInteger-memory-arguments': 1, - 'lessThanInteger-cpu-arguments-intercept': 208896, - 'lessThanInteger-cpu-arguments-slope': 511, - 'lessThanInteger-memory-arguments': 1, - 'listData-cpu-arguments': 52467, - 'listData-memory-arguments': 32, - 'mapData-cpu-arguments': 64832, - 'mapData-memory-arguments': 32, - 'mkCons-cpu-arguments': 65493, - 'mkCons-memory-arguments': 32, - 'mkNilData-cpu-arguments': 22558, - 'mkNilData-memory-arguments': 32, - 'mkNilPairData-cpu-arguments': 16563, - 'mkNilPairData-memory-arguments': 32, - 'mkPairData-cpu-arguments': 76511, - 'mkPairData-memory-arguments': 32, - 'modInteger-cpu-arguments-constant': 196500, - 'modInteger-cpu-arguments-model-arguments-intercept': 453240, - 'modInteger-cpu-arguments-model-arguments-slope': 220, - 'modInteger-memory-arguments-intercept': 0, - 'modInteger-memory-arguments-minimum': 1, - 'modInteger-memory-arguments-slope': 1, - 'multiplyInteger-cpu-arguments-intercept': 69522, - 'multiplyInteger-cpu-arguments-slope': 11687, - 'multiplyInteger-memory-arguments-intercept': 0, - 'multiplyInteger-memory-arguments-slope': 1, - 'nullList-cpu-arguments': 60091, - 'nullList-memory-arguments': 32, - 'quotientInteger-cpu-arguments-constant': 196500, - 'quotientInteger-cpu-arguments-model-arguments-intercept': 453240, - 'quotientInteger-cpu-arguments-model-arguments-slope': 220, - 'quotientInteger-memory-arguments-intercept': 0, - 'quotientInteger-memory-arguments-minimum': 1, - 'quotientInteger-memory-arguments-slope': 1, - 'remainderInteger-cpu-arguments-constant': 196500, - 'remainderInteger-cpu-arguments-model-arguments-intercept': 453240, - 'remainderInteger-cpu-arguments-model-arguments-slope': 220, - 'remainderInteger-memory-arguments-intercept': 0, - 'remainderInteger-memory-arguments-minimum': 1, - 'remainderInteger-memory-arguments-slope': 1, - 'sha2_256-cpu-arguments-intercept': 806990, - 'sha2_256-cpu-arguments-slope': 30482, - 'sha2_256-memory-arguments': 4, - 'sha3_256-cpu-arguments-intercept': 1927926, - 'sha3_256-cpu-arguments-slope': 82523, - 'sha3_256-memory-arguments': 4, - 'sliceByteString-cpu-arguments-intercept': 265318, - 'sliceByteString-cpu-arguments-slope': 0, - 'sliceByteString-memory-arguments-intercept': 4, - 'sliceByteString-memory-arguments-slope': 0, - 'sndPair-cpu-arguments': 85931, - 'sndPair-memory-arguments': 32, - 'subtractInteger-cpu-arguments-intercept': 205665, - 'subtractInteger-cpu-arguments-slope': 812, - 'subtractInteger-memory-arguments-intercept': 1, - 'subtractInteger-memory-arguments-slope': 1, - 'tailList-cpu-arguments': 41182, - 'tailList-memory-arguments': 32, - 'trace-cpu-arguments': 212342, - 'trace-memory-arguments': 32, - 'unBData-cpu-arguments': 31220, - 'unBData-memory-arguments': 32, - 'unConstrData-cpu-arguments': 32696, - 'unConstrData-memory-arguments': 32, - 'unIData-cpu-arguments': 43357, - 'unIData-memory-arguments': 32, - 'unListData-cpu-arguments': 32247, - 'unListData-memory-arguments': 32, - 'unMapData-cpu-arguments': 38314, - 'unMapData-memory-arguments': 32, - 'verifyEd25519Signature-cpu-arguments-intercept': 57996947, - 'verifyEd25519Signature-cpu-arguments-slope': 18975, - 'verifyEd25519Signature-memory-arguments': 10, -}) - -const operations2 = Object.values({ - 'addInteger-cpu-arguments-intercept': 205665, - 'addInteger-cpu-arguments-slope': 812, - 'addInteger-memory-arguments-intercept': 1, - 'addInteger-memory-arguments-slope': 1, - 'appendByteString-cpu-arguments-intercept': 1000, - 'appendByteString-cpu-arguments-slope': 571, - 'appendByteString-memory-arguments-intercept': 0, - 'appendByteString-memory-arguments-slope': 1, - 'appendString-cpu-arguments-intercept': 1000, - 'appendString-cpu-arguments-slope': 24177, - 'appendString-memory-arguments-intercept': 4, - 'appendString-memory-arguments-slope': 1, - 'bData-cpu-arguments': 1000, - 'bData-memory-arguments': 32, - 'blake2b_256-cpu-arguments-intercept': 117366, - 'blake2b_256-cpu-arguments-slope': 10475, - 'blake2b_256-memory-arguments': 4, - 'cekApplyCost-exBudgetCPU': 23000, - 'cekApplyCost-exBudgetMemory': 100, - 'cekBuiltinCost-exBudgetCPU': 23000, - 'cekBuiltinCost-exBudgetMemory': 100, - 'cekConstCost-exBudgetCPU': 23000, - 'cekConstCost-exBudgetMemory': 100, - 'cekDelayCost-exBudgetCPU': 23000, - 'cekDelayCost-exBudgetMemory': 100, - 'cekForceCost-exBudgetCPU': 23000, - 'cekForceCost-exBudgetMemory': 100, - 'cekLamCost-exBudgetCPU': 23000, - 'cekLamCost-exBudgetMemory': 100, - 'cekStartupCost-exBudgetCPU': 100, - 'cekStartupCost-exBudgetMemory': 100, - 'cekVarCost-exBudgetCPU': 23000, - 'cekVarCost-exBudgetMemory': 100, - 'chooseData-cpu-arguments': 19537, - 'chooseData-memory-arguments': 32, - 'chooseList-cpu-arguments': 175354, - 'chooseList-memory-arguments': 32, - 'chooseUnit-cpu-arguments': 46417, - 'chooseUnit-memory-arguments': 4, - 'consByteString-cpu-arguments-intercept': 221973, - 'consByteString-cpu-arguments-slope': 511, - 'consByteString-memory-arguments-intercept': 0, - 'consByteString-memory-arguments-slope': 1, - 'constrData-cpu-arguments': 89141, - 'constrData-memory-arguments': 32, - 'decodeUtf8-cpu-arguments-intercept': 497525, - 'decodeUtf8-cpu-arguments-slope': 14068, - 'decodeUtf8-memory-arguments-intercept': 4, - 'decodeUtf8-memory-arguments-slope': 2, - 'divideInteger-cpu-arguments-constant': 196500, - 'divideInteger-cpu-arguments-model-arguments-intercept': 453240, - 'divideInteger-cpu-arguments-model-arguments-slope': 220, - 'divideInteger-memory-arguments-intercept': 0, - 'divideInteger-memory-arguments-minimum': 1, - 'divideInteger-memory-arguments-slope': 1, - 'encodeUtf8-cpu-arguments-intercept': 1000, - 'encodeUtf8-cpu-arguments-slope': 28662, - 'encodeUtf8-memory-arguments-intercept': 4, - 'encodeUtf8-memory-arguments-slope': 2, - 'equalsByteString-cpu-arguments-constant': 245000, - 'equalsByteString-cpu-arguments-intercept': 216773, - 'equalsByteString-cpu-arguments-slope': 62, - 'equalsByteString-memory-arguments': 1, - 'equalsData-cpu-arguments-intercept': 1060367, - 'equalsData-cpu-arguments-slope': 12586, - 'equalsData-memory-arguments': 1, - 'equalsInteger-cpu-arguments-intercept': 208512, - 'equalsInteger-cpu-arguments-slope': 421, - 'equalsInteger-memory-arguments': 1, - 'equalsString-cpu-arguments-constant': 187000, - 'equalsString-cpu-arguments-intercept': 1000, - 'equalsString-cpu-arguments-slope': 52998, - 'equalsString-memory-arguments': 1, - 'fstPair-cpu-arguments': 80436, - 'fstPair-memory-arguments': 32, - 'headList-cpu-arguments': 43249, - 'headList-memory-arguments': 32, - 'iData-cpu-arguments': 1000, - 'iData-memory-arguments': 32, - 'ifThenElse-cpu-arguments': 80556, - 'ifThenElse-memory-arguments': 1, - 'indexByteString-cpu-arguments': 57667, - 'indexByteString-memory-arguments': 4, - 'lengthOfByteString-cpu-arguments': 1000, - 'lengthOfByteString-memory-arguments': 10, - 'lessThanByteString-cpu-arguments-intercept': 197145, - 'lessThanByteString-cpu-arguments-slope': 156, - 'lessThanByteString-memory-arguments': 1, - 'lessThanEqualsByteString-cpu-arguments-intercept': 197145, - 'lessThanEqualsByteString-cpu-arguments-slope': 156, - 'lessThanEqualsByteString-memory-arguments': 1, - 'lessThanEqualsInteger-cpu-arguments-intercept': 204924, - 'lessThanEqualsInteger-cpu-arguments-slope': 473, - 'lessThanEqualsInteger-memory-arguments': 1, - 'lessThanInteger-cpu-arguments-intercept': 208896, - 'lessThanInteger-cpu-arguments-slope': 511, - 'lessThanInteger-memory-arguments': 1, - 'listData-cpu-arguments': 52467, - 'listData-memory-arguments': 32, - 'mapData-cpu-arguments': 64832, - 'mapData-memory-arguments': 32, - 'mkCons-cpu-arguments': 65493, - 'mkCons-memory-arguments': 32, - 'mkNilData-cpu-arguments': 22558, - 'mkNilData-memory-arguments': 32, - 'mkNilPairData-cpu-arguments': 16563, - 'mkNilPairData-memory-arguments': 32, - 'mkPairData-cpu-arguments': 76511, - 'mkPairData-memory-arguments': 32, - 'modInteger-cpu-arguments-constant': 196500, - 'modInteger-cpu-arguments-model-arguments-intercept': 453240, - 'modInteger-cpu-arguments-model-arguments-slope': 220, - 'modInteger-memory-arguments-intercept': 0, - 'modInteger-memory-arguments-minimum': 1, - 'modInteger-memory-arguments-slope': 1, - 'multiplyInteger-cpu-arguments-intercept': 69522, - 'multiplyInteger-cpu-arguments-slope': 11687, - 'multiplyInteger-memory-arguments-intercept': 0, - 'multiplyInteger-memory-arguments-slope': 1, - 'nullList-cpu-arguments': 60091, - 'nullList-memory-arguments': 32, - 'quotientInteger-cpu-arguments-constant': 196500, - 'quotientInteger-cpu-arguments-model-arguments-intercept': 453240, - 'quotientInteger-cpu-arguments-model-arguments-slope': 220, - 'quotientInteger-memory-arguments-intercept': 0, - 'quotientInteger-memory-arguments-minimum': 1, - 'quotientInteger-memory-arguments-slope': 1, - 'remainderInteger-cpu-arguments-constant': 196500, - 'remainderInteger-cpu-arguments-model-arguments-intercept': 453240, - 'remainderInteger-cpu-arguments-model-arguments-slope': 220, - 'remainderInteger-memory-arguments-intercept': 0, - 'remainderInteger-memory-arguments-minimum': 1, - 'remainderInteger-memory-arguments-slope': 1, - 'serialiseData-cpu-arguments-intercept': 1159724, - 'serialiseData-cpu-arguments-slope': 392670, - 'serialiseData-memory-arguments-intercept': 0, - 'serialiseData-memory-arguments-slope': 2, - 'sha2_256-cpu-arguments-intercept': 806990, - 'sha2_256-cpu-arguments-slope': 30482, - 'sha2_256-memory-arguments': 4, - 'sha3_256-cpu-arguments-intercept': 1927926, - 'sha3_256-cpu-arguments-slope': 82523, - 'sha3_256-memory-arguments': 4, - 'sliceByteString-cpu-arguments-intercept': 265318, - 'sliceByteString-cpu-arguments-slope': 0, - 'sliceByteString-memory-arguments-intercept': 4, - 'sliceByteString-memory-arguments-slope': 0, - 'sndPair-cpu-arguments': 85931, - 'sndPair-memory-arguments': 32, - 'subtractInteger-cpu-arguments-intercept': 205665, - 'subtractInteger-cpu-arguments-slope': 812, - 'subtractInteger-memory-arguments-intercept': 1, - 'subtractInteger-memory-arguments-slope': 1, - 'tailList-cpu-arguments': 41182, - 'tailList-memory-arguments': 32, - 'trace-cpu-arguments': 212342, - 'trace-memory-arguments': 32, - 'unBData-cpu-arguments': 31220, - 'unBData-memory-arguments': 32, - 'unConstrData-cpu-arguments': 32696, - 'unConstrData-memory-arguments': 32, - 'unIData-cpu-arguments': 43357, - 'unIData-memory-arguments': 32, - 'unListData-cpu-arguments': 32247, - 'unListData-memory-arguments': 32, - 'unMapData-cpu-arguments': 38314, - 'unMapData-memory-arguments': 32, - 'verifyEcdsaSecp256k1Signature-cpu-arguments': 35892428, - 'verifyEcdsaSecp256k1Signature-memory-arguments': 10, - 'verifyEd25519Signature-cpu-arguments-intercept': 57996947, - 'verifyEd25519Signature-cpu-arguments-slope': 18975, - 'verifyEd25519Signature-memory-arguments': 10, - 'verifySchnorrSecp256k1Signature-cpu-arguments-intercept': 38887044, - 'verifySchnorrSecp256k1Signature-cpu-arguments-slope': 32947, - 'verifySchnorrSecp256k1Signature-memory-arguments': 10, -}) - -export const assertRequired = (value: T | undefined, message: string): T => { - if (value === undefined) throw new Error(message) - return value -} - -export const fixScriptHash = async (tx: CSL_TYPES.Transaction) => { - const builder = await getTransactionBuilder() - - const witnessSet = await tx.witnessSet() - - const plutusScripts = assertRequired(await witnessSet.plutusScripts(), 'Transaction does not contain plutus scripts') - const plutusData = assertRequired(await witnessSet.plutusData(), 'Transaction does not contain plutus data') - const redeemers = assertRequired(await witnessSet.redeemers(), 'Transaction does not contain redeemers') - const placeholderAddress = assertRequired( - await CardanoMobile.Address.fromBech32(DUMMY_ADDRESS), - 'Could not parse placeholder address', - ) - - const input = await (await (await tx.body()).inputs()).get(0) - const amount = await CardanoMobile.Value.new(await bigNumFromStr('5000000')) - const script = await plutusScripts.get(0) - const data = await plutusData.get(0) - const redeemer = await redeemers.get(0) - - const plutusWitness = await CardanoMobile.PlutusWitness.new(script, data, redeemer) - - await builder.addPlutusScriptInput(plutusWitness, input, amount) - - await builder.calcScriptDataHash(await getCostModel()) - - await builder.addChangeIfNeeded(placeholderAddress) - - const dummyTxForCalculatingScriptHash = assertRequired( - await builder.build(), - 'Could not build placeholder transaction', - ) - const correctScriptHash = assertRequired( - await dummyTxForCalculatingScriptHash.scriptDataHash(), - 'Script hash is empty', - ) - - const body = await tx.body() - await body.setScriptDataHash(correctScriptHash) - return body -} - -const DUMMY_ADDRESS = - 'addr1q9l0qrhrvu3nq92ns23g2atns690ge4c325vgzqlg4vru9uym9vrnx7vuq6q9lv984p6feekdusp3yewttl5a65sg6fs9r9gw5' - -export const getRequiredSigners = async (tx: CSL_TYPES.Transaction, wallet: YoroiWallet) => { - const utxos = wallet.allUtxos - const body = await tx.body() - const inputs = await body.inputs() - const purpose = isHaskellShelley(wallet.walletImplementationId) - ? NUMBERS.WALLET_TYPE_PURPOSE.CIP1852 - : NUMBERS.WALLET_TYPE_PURPOSE.BIP44 - const signers = [[purpose, harden(1815), harden(0), 0, 0]] - - const inputUtxos: RawUtxo[] = [] - - for (let i = 0; i < (await inputs.len()); i++) { - const input = await inputs.get(i) - const txId = await input.transactionId().then((t) => t.toHex()) - const txIndex = await input.index() - const matchingUtxo = utxos.find((utxo) => utxo.tx_hash === txId && utxo.tx_index === txIndex) - if (!matchingUtxo) continue - inputUtxos.push(matchingUtxo) - } - - inputUtxos.forEach((utxo) => { - signers.push(getDerivationPathForAddress(utxo.receiver, wallet, purpose)) - }) - - const requiredSigners = assertRequired(await body.requiredSigners(), 'Transaction does not contain required signers') - - const txRequiredAddresses: string[] = [] - for (let i = 0; i < (await requiredSigners.len()); i++) { - const signer = await requiredSigners.get(i) - const hex = await signer.toHex() - - const allAddresses = [...wallet.externalAddresses, ...wallet.internalAddresses] - await Promise.all( - allAddresses.map(async (bech32Address) => { - const parsedAddress = await CardanoMobile.Address.fromBech32(bech32Address) - const baseAddr = await CardanoMobile.BaseAddress.fromAddress(parsedAddress) - const paymentCred = await baseAddr.paymentCred() - const keyHash = await paymentCred.toKeyhash() - const hexKeyHash = await keyHash.toBytes().then((b) => Buffer.from(b).toString('hex')) - if (hex === hexKeyHash) { - txRequiredAddresses.push(bech32Address) - } - }), - ) - } - - txRequiredAddresses.forEach((address) => { - signers.push(getDerivationPathForAddress(address, wallet, purpose)) - }) - - const collateralInputs = assertRequired(await body.collateral(), 'Transaction does not contain collateral inputs') - - const firstCollateral = await collateralInputs.get(0) - const txId = await firstCollateral.transactionId().then((t) => t.toHex()) - const txIndex = await firstCollateral.index() - - const matchingUtxo = utxos.find((utxo) => utxo.tx_hash === txId && utxo.tx_index === txIndex) - if (!matchingUtxo) throw new Error('Could not find matching utxo') - - const {receiver} = matchingUtxo - signers.push(getDerivationPathForAddress(receiver, wallet, purpose)) - - return getUniquePaths(signers) -} - -const getUniquePaths = (paths: number[][]) => { - return _.uniqWith(paths, arePathsEqual) -} - -const arePathsEqual = (path1: number[], path2: number[]) => { - return path1.every((value, index) => value === path2[index]) && path1.length === path2.length -} - -const getDerivationPathForAddress = (address: string, wallet: YoroiWallet, purpose: number) => { - const internalIndex = wallet.internalAddresses.indexOf(address) - const externalIndex = wallet.externalAddresses.indexOf(address) - if (internalIndex === -1 && externalIndex === -1) throw new Error('Could not find matching address') - - const role = internalIndex > -1 ? 1 : 0 - const index = Math.max(internalIndex, externalIndex) - - return [purpose, harden(1815), harden(0), role, index] -} - -export const getMuesliSwapTransactionAndSigners = async (cbor: string, wallet: YoroiWallet) => { - const originalTx = assertRequired( - await CardanoMobile.Transaction.fromHex(cbor), - 'Could not parse transaction from cbor', - ) - const fixedTxBody = await fixScriptHash(originalTx) - - const txWithFixedBody = await CardanoMobile.Transaction.new(fixedTxBody, await originalTx.witnessSet(), undefined) - const newCbor = Buffer.from(await txWithFixedBody.toBytes()).toString('hex') - - const signers = await getRequiredSigners(txWithFixedBody, wallet) - return {cbor: newCbor, signers} -} 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 2c8565395b..5f88fb5472 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/byron/ByronWallet.ts @@ -705,6 +705,10 @@ export class ByronWallet implements YoroiWallet { } } + signSwapCancellationWithLedger(): Promise { + return Promise.reject(new Error('Method not implemented.')) + } + async signTx(unsignedTx: YoroiUnsignedTx, decryptedMasterKey: string, datum?: {data: string}) { const masterKey = await CardanoMobile.Bip32PrivateKey.fromBytes(Buffer.from(decryptedMasterKey, 'hex')) const accountPrivateKey = await masterKey @@ -801,7 +805,7 @@ export class ByronWallet implements YoroiWallet { return Cardano.Wasm.BaseAddress.fromAddress(addr) } - async ledgerSupportsCIP36(useUSB): Promise { + async ledgerSupportsCIP36(useUSB: boolean): Promise { if (!this.hwDeviceInfo) throw new Error('Invalid wallet state') return doesCardanoAppVersionSupportCIP36(await getCardanoAppMajorVersion(this.hwDeviceInfo, useUSB)) } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts index 6d2a4d843c..f1383951c9 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts @@ -1,10 +1,20 @@ -import {PrivateKey} from '@emurgo/cross-csl-core' +import {SignTransactionRequest} from '@cardano-foundation/ledgerjs-hw-app-cardano' +import * as CSL_TYPES from '@emurgo/cross-csl-core' +import {Bip32PublicKey, PrivateKey} from '@emurgo/cross-csl-core' +import {Addressing, createLedgerPlutusPayload} from '@emurgo/yoroi-lib' import blake2b from 'blake2b' +import {Buffer} from 'buffer' +import _ from 'lodash' +import {RawUtxo} from '../../types' import {CardanoMobile} from '../../wallets' +import {HARD_DERIVATION_START} from '../constants/common' +import {NUMBERS} from '../numbers' +import {YoroiWallet} from '../types' +import {isHaskellShelley} from '../utils' -export const signRawTransaction = async (txHex: string, pKeys: PrivateKey[]): Promise => { - const fixedTx = await CardanoMobile.FixedTransaction.fromHex(txHex) +export const signRawTransaction = async (cbor: string, pKeys: PrivateKey[]): Promise => { + const fixedTx = await CardanoMobile.FixedTransaction.fromHex(cbor) if (!fixedTx) throw new Error('invalid tx hex') const rawBody = await fixedTx.rawBody() const txHash = await CardanoMobile.TransactionHash.fromBytes(blake2b(32).update(rawBody).digest('binary')) @@ -24,3 +34,652 @@ export const signRawTransaction = async (txHex: string, pKeys: PrivateKey[]): Pr return fixedTx.toBytes() } + +export const createSignedLedgerSwapCancellationTx = async ( + cbor: string, + witnesses: Array<{path: number[]; witnessSignatureHex: string}>, + purpose: number, + publicKeyHex: string, +): Promise => { + const fixedBodyCbor = await getMuesliSwapFixedCbor(cbor) + const fixedTx = await CardanoMobile.FixedTransaction.fromHex(fixedBodyCbor) + if (!fixedTx) throw new Error('invalid tx hex') + const rawBody = await fixedTx.rawBody() + const txHash = await CardanoMobile.TransactionHash.fromBytes(blake2b(32).update(rawBody).digest('binary')) + if (!txHash) throw new Error('invalid tx hex, could not generate tx hash') + + const witSet = await fixedTx.witnessSet() + const vkeys = await CardanoMobile.Vkeywitnesses.new() + + const addressing = { + path: [ + purpose, + 2147485463, // CARDANO + 2147483648, + ], + startLevel: 1, + } + + const key = await CardanoMobile.Bip32PublicKey.fromBytes(Buffer.from(publicKeyHex, 'hex')) + const keyLevel = addressing.startLevel + addressing.path.length - 1 + + for (let i = 0; i < witnesses.length; i++) { + const addressKey = await derivePublicByAddressing( + {startLevel: 1, path: witnesses[i].path}, + { + level: keyLevel, + key, + }, + ) + const witness = await CardanoMobile.Vkeywitness.new( + await CardanoMobile.Vkey.new(await addressKey.toRawKey()), + await CardanoMobile.Ed25519Signature.fromBytes(Buffer.from(witnesses[i].witnessSignatureHex, 'hex')), + ) + if (!witness) throw new Error('invalid tx hex, could not generate vkey witness') + await vkeys.add(witness) + } + + await witSet.setVkeys(vkeys) + await fixedTx.setWitnessSet(await witSet.toBytes()) + + return fixedTx.toBytes() +} + +export const derivePublicByAddressing = async ( + addressing: Addressing, + startingFrom: { + key: Bip32PublicKey + level: number + }, +) => { + if (startingFrom.level + 1 < addressing.startLevel) { + throw new Error('derivePublicByAddressing: keyLevel < startLevel') + } + + let derivedKey = startingFrom.key + + for (let i = startingFrom.level - addressing.startLevel + 1; i < addressing.path.length; i++) { + derivedKey = await derivedKey.derive(addressing.path[i]) + } + + return derivedKey +} + +export const createSwapCancellationLedgerPayload = async ( + cbor: string, + wallet: YoroiWallet, + networkId: number, + protocolMagic: number, + getAddressing: (address: string) => Addressing, + stakeVKHash: CSL_TYPES.Ed25519KeyHash, +): Promise => { + const changeAddrs = [...wallet.internalAddresses, ...wallet.internalAddresses].map((address) => ({ + addressing: getAddressing(address), + address, + })) + const getAddressingByTxIdAndIndex = (txId: string, index: number) => { + const utxo = wallet.allUtxos.find((utxo) => utxo.tx_hash === txId && utxo.tx_index === index) + return utxo ? getAddressing(utxo.receiver) : null + } + return createLedgerPlutusPayload({ + wasm: CardanoMobile, + cbor: await getMuesliSwapFixedCbor(cbor), + addresses: changeAddrs, + networkId, + protocolMagic, + purpose: harden(1852), + stakeVKHash, + getUtxoAddressing: getAddressingByTxIdAndIndex, + getAddressAddressing: getAddressing, + }) +} + +export const convertBech32ToHex = async (bech32Address: string) => { + const address = await CardanoMobile.Address.fromBech32(bech32Address) + const bytes = await address.toBytes() + return new Buffer(bytes).toString('hex') +} + +export const harden = (num: number) => HARD_DERIVATION_START + num + +export const getCostModel = async () => { + const babbageCostModels = await CardanoMobile.Costmdls.new() + const v1CostModel = await CardanoMobile.CostModel.new() + await Promise.all( + operations1.map(async (cost, operation) => v1CostModel.set(operation, await CardanoMobile.Int.newI32(cost))), + ) + + const v2CostModel = await CardanoMobile.CostModel.new() + await Promise.all( + operations2.map(async (cost, operation) => v2CostModel.set(operation, await CardanoMobile.Int.newI32(cost))), + ) + + await babbageCostModels.insert(await CardanoMobile.Language.newPlutusV1(), v1CostModel) + await babbageCostModels.insert(await CardanoMobile.Language.newPlutusV2(), v2CostModel) + + return babbageCostModels +} + +const bigNumFromStr = async (str: string) => { + const bigNum = await CardanoMobile.BigNum.fromStr(str) + if (!bigNum) throw new Error('Could not parse big number from string ' + str) + return bigNum +} + +export const getTransactionBuilder = async () => { + const linearFee = await CardanoMobile.LinearFee.new(await bigNumFromStr('44'), await bigNumFromStr('155381')) + + const exUnitPrices = await CardanoMobile.ExUnitPrices.new( + await CardanoMobile.UnitInterval.new(await bigNumFromStr('577'), await bigNumFromStr('10000')), + await CardanoMobile.UnitInterval.new(await bigNumFromStr('721'), await bigNumFromStr('10000000')), + ) + + const txBuilderCfg = await CardanoMobile.TransactionBuilderConfigBuilder.new() + .then((builder) => builder.feeAlgo(linearFee)) + .then(async (builder) => builder.poolDeposit(await bigNumFromStr('500000000'))) + .then(async (builder) => builder.keyDeposit(await bigNumFromStr('2000000'))) + .then((builder) => builder.maxValueSize(4000)) + .then((builder) => builder.maxTxSize(8000)) + .then(async (builder) => builder.coinsPerUtxoWord(await bigNumFromStr('34482'))) + .then(async (builder) => builder.exUnitPrices(exUnitPrices).then((builder) => builder.build())) + + return CardanoMobile.TransactionBuilder.new(assertRequired(txBuilderCfg, 'Could not build transaction builder')) +} + +const operations1 = Object.values({ + 'addInteger-cpu-arguments-intercept': 205665, + 'addInteger-cpu-arguments-slope': 812, + 'addInteger-memory-arguments-intercept': 1, + 'addInteger-memory-arguments-slope': 1, + 'appendByteString-cpu-arguments-intercept': 1000, + 'appendByteString-cpu-arguments-slope': 571, + 'appendByteString-memory-arguments-intercept': 0, + 'appendByteString-memory-arguments-slope': 1, + 'appendString-cpu-arguments-intercept': 1000, + 'appendString-cpu-arguments-slope': 24177, + 'appendString-memory-arguments-intercept': 4, + 'appendString-memory-arguments-slope': 1, + 'bData-cpu-arguments': 1000, + 'bData-memory-arguments': 32, + 'blake2b_256-cpu-arguments-intercept': 117366, + 'blake2b_256-cpu-arguments-slope': 10475, + 'blake2b_256-memory-arguments': 4, + 'cekApplyCost-exBudgetCPU': 23000, + 'cekApplyCost-exBudgetMemory': 100, + 'cekBuiltinCost-exBudgetCPU': 23000, + 'cekBuiltinCost-exBudgetMemory': 100, + 'cekConstCost-exBudgetCPU': 23000, + 'cekConstCost-exBudgetMemory': 100, + 'cekDelayCost-exBudgetCPU': 23000, + 'cekDelayCost-exBudgetMemory': 100, + 'cekForceCost-exBudgetCPU': 23000, + 'cekForceCost-exBudgetMemory': 100, + 'cekLamCost-exBudgetCPU': 23000, + 'cekLamCost-exBudgetMemory': 100, + 'cekStartupCost-exBudgetCPU': 100, + 'cekStartupCost-exBudgetMemory': 100, + 'cekVarCost-exBudgetCPU': 23000, + 'cekVarCost-exBudgetMemory': 100, + 'chooseData-cpu-arguments': 19537, + 'chooseData-memory-arguments': 32, + 'chooseList-cpu-arguments': 175354, + 'chooseList-memory-arguments': 32, + 'chooseUnit-cpu-arguments': 46417, + 'chooseUnit-memory-arguments': 4, + 'consByteString-cpu-arguments-intercept': 221973, + 'consByteString-cpu-arguments-slope': 511, + 'consByteString-memory-arguments-intercept': 0, + 'consByteString-memory-arguments-slope': 1, + 'constrData-cpu-arguments': 89141, + 'constrData-memory-arguments': 32, + 'decodeUtf8-cpu-arguments-intercept': 497525, + 'decodeUtf8-cpu-arguments-slope': 14068, + 'decodeUtf8-memory-arguments-intercept': 4, + 'decodeUtf8-memory-arguments-slope': 2, + 'divideInteger-cpu-arguments-constant': 196500, + 'divideInteger-cpu-arguments-model-arguments-intercept': 453240, + 'divideInteger-cpu-arguments-model-arguments-slope': 220, + 'divideInteger-memory-arguments-intercept': 0, + 'divideInteger-memory-arguments-minimum': 1, + 'divideInteger-memory-arguments-slope': 1, + 'encodeUtf8-cpu-arguments-intercept': 1000, + 'encodeUtf8-cpu-arguments-slope': 28662, + 'encodeUtf8-memory-arguments-intercept': 4, + 'encodeUtf8-memory-arguments-slope': 2, + 'equalsByteString-cpu-arguments-constant': 245000, + 'equalsByteString-cpu-arguments-intercept': 216773, + 'equalsByteString-cpu-arguments-slope': 62, + 'equalsByteString-memory-arguments': 1, + 'equalsData-cpu-arguments-intercept': 1060367, + 'equalsData-cpu-arguments-slope': 12586, + 'equalsData-memory-arguments': 1, + 'equalsInteger-cpu-arguments-intercept': 208512, + 'equalsInteger-cpu-arguments-slope': 421, + 'equalsInteger-memory-arguments': 1, + 'equalsString-cpu-arguments-constant': 187000, + 'equalsString-cpu-arguments-intercept': 1000, + 'equalsString-cpu-arguments-slope': 52998, + 'equalsString-memory-arguments': 1, + 'fstPair-cpu-arguments': 80436, + 'fstPair-memory-arguments': 32, + 'headList-cpu-arguments': 43249, + 'headList-memory-arguments': 32, + 'iData-cpu-arguments': 1000, + 'iData-memory-arguments': 32, + 'ifThenElse-cpu-arguments': 80556, + 'ifThenElse-memory-arguments': 1, + 'indexByteString-cpu-arguments': 57667, + 'indexByteString-memory-arguments': 4, + 'lengthOfByteString-cpu-arguments': 1000, + 'lengthOfByteString-memory-arguments': 10, + 'lessThanByteString-cpu-arguments-intercept': 197145, + 'lessThanByteString-cpu-arguments-slope': 156, + 'lessThanByteString-memory-arguments': 1, + 'lessThanEqualsByteString-cpu-arguments-intercept': 197145, + 'lessThanEqualsByteString-cpu-arguments-slope': 156, + 'lessThanEqualsByteString-memory-arguments': 1, + 'lessThanEqualsInteger-cpu-arguments-intercept': 204924, + 'lessThanEqualsInteger-cpu-arguments-slope': 473, + 'lessThanEqualsInteger-memory-arguments': 1, + 'lessThanInteger-cpu-arguments-intercept': 208896, + 'lessThanInteger-cpu-arguments-slope': 511, + 'lessThanInteger-memory-arguments': 1, + 'listData-cpu-arguments': 52467, + 'listData-memory-arguments': 32, + 'mapData-cpu-arguments': 64832, + 'mapData-memory-arguments': 32, + 'mkCons-cpu-arguments': 65493, + 'mkCons-memory-arguments': 32, + 'mkNilData-cpu-arguments': 22558, + 'mkNilData-memory-arguments': 32, + 'mkNilPairData-cpu-arguments': 16563, + 'mkNilPairData-memory-arguments': 32, + 'mkPairData-cpu-arguments': 76511, + 'mkPairData-memory-arguments': 32, + 'modInteger-cpu-arguments-constant': 196500, + 'modInteger-cpu-arguments-model-arguments-intercept': 453240, + 'modInteger-cpu-arguments-model-arguments-slope': 220, + 'modInteger-memory-arguments-intercept': 0, + 'modInteger-memory-arguments-minimum': 1, + 'modInteger-memory-arguments-slope': 1, + 'multiplyInteger-cpu-arguments-intercept': 69522, + 'multiplyInteger-cpu-arguments-slope': 11687, + 'multiplyInteger-memory-arguments-intercept': 0, + 'multiplyInteger-memory-arguments-slope': 1, + 'nullList-cpu-arguments': 60091, + 'nullList-memory-arguments': 32, + 'quotientInteger-cpu-arguments-constant': 196500, + 'quotientInteger-cpu-arguments-model-arguments-intercept': 453240, + 'quotientInteger-cpu-arguments-model-arguments-slope': 220, + 'quotientInteger-memory-arguments-intercept': 0, + 'quotientInteger-memory-arguments-minimum': 1, + 'quotientInteger-memory-arguments-slope': 1, + 'remainderInteger-cpu-arguments-constant': 196500, + 'remainderInteger-cpu-arguments-model-arguments-intercept': 453240, + 'remainderInteger-cpu-arguments-model-arguments-slope': 220, + 'remainderInteger-memory-arguments-intercept': 0, + 'remainderInteger-memory-arguments-minimum': 1, + 'remainderInteger-memory-arguments-slope': 1, + 'sha2_256-cpu-arguments-intercept': 806990, + 'sha2_256-cpu-arguments-slope': 30482, + 'sha2_256-memory-arguments': 4, + 'sha3_256-cpu-arguments-intercept': 1927926, + 'sha3_256-cpu-arguments-slope': 82523, + 'sha3_256-memory-arguments': 4, + 'sliceByteString-cpu-arguments-intercept': 265318, + 'sliceByteString-cpu-arguments-slope': 0, + 'sliceByteString-memory-arguments-intercept': 4, + 'sliceByteString-memory-arguments-slope': 0, + 'sndPair-cpu-arguments': 85931, + 'sndPair-memory-arguments': 32, + 'subtractInteger-cpu-arguments-intercept': 205665, + 'subtractInteger-cpu-arguments-slope': 812, + 'subtractInteger-memory-arguments-intercept': 1, + 'subtractInteger-memory-arguments-slope': 1, + 'tailList-cpu-arguments': 41182, + 'tailList-memory-arguments': 32, + 'trace-cpu-arguments': 212342, + 'trace-memory-arguments': 32, + 'unBData-cpu-arguments': 31220, + 'unBData-memory-arguments': 32, + 'unConstrData-cpu-arguments': 32696, + 'unConstrData-memory-arguments': 32, + 'unIData-cpu-arguments': 43357, + 'unIData-memory-arguments': 32, + 'unListData-cpu-arguments': 32247, + 'unListData-memory-arguments': 32, + 'unMapData-cpu-arguments': 38314, + 'unMapData-memory-arguments': 32, + 'verifyEd25519Signature-cpu-arguments-intercept': 57996947, + 'verifyEd25519Signature-cpu-arguments-slope': 18975, + 'verifyEd25519Signature-memory-arguments': 10, +}) + +const operations2 = Object.values({ + 'addInteger-cpu-arguments-intercept': 205665, + 'addInteger-cpu-arguments-slope': 812, + 'addInteger-memory-arguments-intercept': 1, + 'addInteger-memory-arguments-slope': 1, + 'appendByteString-cpu-arguments-intercept': 1000, + 'appendByteString-cpu-arguments-slope': 571, + 'appendByteString-memory-arguments-intercept': 0, + 'appendByteString-memory-arguments-slope': 1, + 'appendString-cpu-arguments-intercept': 1000, + 'appendString-cpu-arguments-slope': 24177, + 'appendString-memory-arguments-intercept': 4, + 'appendString-memory-arguments-slope': 1, + 'bData-cpu-arguments': 1000, + 'bData-memory-arguments': 32, + 'blake2b_256-cpu-arguments-intercept': 117366, + 'blake2b_256-cpu-arguments-slope': 10475, + 'blake2b_256-memory-arguments': 4, + 'cekApplyCost-exBudgetCPU': 23000, + 'cekApplyCost-exBudgetMemory': 100, + 'cekBuiltinCost-exBudgetCPU': 23000, + 'cekBuiltinCost-exBudgetMemory': 100, + 'cekConstCost-exBudgetCPU': 23000, + 'cekConstCost-exBudgetMemory': 100, + 'cekDelayCost-exBudgetCPU': 23000, + 'cekDelayCost-exBudgetMemory': 100, + 'cekForceCost-exBudgetCPU': 23000, + 'cekForceCost-exBudgetMemory': 100, + 'cekLamCost-exBudgetCPU': 23000, + 'cekLamCost-exBudgetMemory': 100, + 'cekStartupCost-exBudgetCPU': 100, + 'cekStartupCost-exBudgetMemory': 100, + 'cekVarCost-exBudgetCPU': 23000, + 'cekVarCost-exBudgetMemory': 100, + 'chooseData-cpu-arguments': 19537, + 'chooseData-memory-arguments': 32, + 'chooseList-cpu-arguments': 175354, + 'chooseList-memory-arguments': 32, + 'chooseUnit-cpu-arguments': 46417, + 'chooseUnit-memory-arguments': 4, + 'consByteString-cpu-arguments-intercept': 221973, + 'consByteString-cpu-arguments-slope': 511, + 'consByteString-memory-arguments-intercept': 0, + 'consByteString-memory-arguments-slope': 1, + 'constrData-cpu-arguments': 89141, + 'constrData-memory-arguments': 32, + 'decodeUtf8-cpu-arguments-intercept': 497525, + 'decodeUtf8-cpu-arguments-slope': 14068, + 'decodeUtf8-memory-arguments-intercept': 4, + 'decodeUtf8-memory-arguments-slope': 2, + 'divideInteger-cpu-arguments-constant': 196500, + 'divideInteger-cpu-arguments-model-arguments-intercept': 453240, + 'divideInteger-cpu-arguments-model-arguments-slope': 220, + 'divideInteger-memory-arguments-intercept': 0, + 'divideInteger-memory-arguments-minimum': 1, + 'divideInteger-memory-arguments-slope': 1, + 'encodeUtf8-cpu-arguments-intercept': 1000, + 'encodeUtf8-cpu-arguments-slope': 28662, + 'encodeUtf8-memory-arguments-intercept': 4, + 'encodeUtf8-memory-arguments-slope': 2, + 'equalsByteString-cpu-arguments-constant': 245000, + 'equalsByteString-cpu-arguments-intercept': 216773, + 'equalsByteString-cpu-arguments-slope': 62, + 'equalsByteString-memory-arguments': 1, + 'equalsData-cpu-arguments-intercept': 1060367, + 'equalsData-cpu-arguments-slope': 12586, + 'equalsData-memory-arguments': 1, + 'equalsInteger-cpu-arguments-intercept': 208512, + 'equalsInteger-cpu-arguments-slope': 421, + 'equalsInteger-memory-arguments': 1, + 'equalsString-cpu-arguments-constant': 187000, + 'equalsString-cpu-arguments-intercept': 1000, + 'equalsString-cpu-arguments-slope': 52998, + 'equalsString-memory-arguments': 1, + 'fstPair-cpu-arguments': 80436, + 'fstPair-memory-arguments': 32, + 'headList-cpu-arguments': 43249, + 'headList-memory-arguments': 32, + 'iData-cpu-arguments': 1000, + 'iData-memory-arguments': 32, + 'ifThenElse-cpu-arguments': 80556, + 'ifThenElse-memory-arguments': 1, + 'indexByteString-cpu-arguments': 57667, + 'indexByteString-memory-arguments': 4, + 'lengthOfByteString-cpu-arguments': 1000, + 'lengthOfByteString-memory-arguments': 10, + 'lessThanByteString-cpu-arguments-intercept': 197145, + 'lessThanByteString-cpu-arguments-slope': 156, + 'lessThanByteString-memory-arguments': 1, + 'lessThanEqualsByteString-cpu-arguments-intercept': 197145, + 'lessThanEqualsByteString-cpu-arguments-slope': 156, + 'lessThanEqualsByteString-memory-arguments': 1, + 'lessThanEqualsInteger-cpu-arguments-intercept': 204924, + 'lessThanEqualsInteger-cpu-arguments-slope': 473, + 'lessThanEqualsInteger-memory-arguments': 1, + 'lessThanInteger-cpu-arguments-intercept': 208896, + 'lessThanInteger-cpu-arguments-slope': 511, + 'lessThanInteger-memory-arguments': 1, + 'listData-cpu-arguments': 52467, + 'listData-memory-arguments': 32, + 'mapData-cpu-arguments': 64832, + 'mapData-memory-arguments': 32, + 'mkCons-cpu-arguments': 65493, + 'mkCons-memory-arguments': 32, + 'mkNilData-cpu-arguments': 22558, + 'mkNilData-memory-arguments': 32, + 'mkNilPairData-cpu-arguments': 16563, + 'mkNilPairData-memory-arguments': 32, + 'mkPairData-cpu-arguments': 76511, + 'mkPairData-memory-arguments': 32, + 'modInteger-cpu-arguments-constant': 196500, + 'modInteger-cpu-arguments-model-arguments-intercept': 453240, + 'modInteger-cpu-arguments-model-arguments-slope': 220, + 'modInteger-memory-arguments-intercept': 0, + 'modInteger-memory-arguments-minimum': 1, + 'modInteger-memory-arguments-slope': 1, + 'multiplyInteger-cpu-arguments-intercept': 69522, + 'multiplyInteger-cpu-arguments-slope': 11687, + 'multiplyInteger-memory-arguments-intercept': 0, + 'multiplyInteger-memory-arguments-slope': 1, + 'nullList-cpu-arguments': 60091, + 'nullList-memory-arguments': 32, + 'quotientInteger-cpu-arguments-constant': 196500, + 'quotientInteger-cpu-arguments-model-arguments-intercept': 453240, + 'quotientInteger-cpu-arguments-model-arguments-slope': 220, + 'quotientInteger-memory-arguments-intercept': 0, + 'quotientInteger-memory-arguments-minimum': 1, + 'quotientInteger-memory-arguments-slope': 1, + 'remainderInteger-cpu-arguments-constant': 196500, + 'remainderInteger-cpu-arguments-model-arguments-intercept': 453240, + 'remainderInteger-cpu-arguments-model-arguments-slope': 220, + 'remainderInteger-memory-arguments-intercept': 0, + 'remainderInteger-memory-arguments-minimum': 1, + 'remainderInteger-memory-arguments-slope': 1, + 'serialiseData-cpu-arguments-intercept': 1159724, + 'serialiseData-cpu-arguments-slope': 392670, + 'serialiseData-memory-arguments-intercept': 0, + 'serialiseData-memory-arguments-slope': 2, + 'sha2_256-cpu-arguments-intercept': 806990, + 'sha2_256-cpu-arguments-slope': 30482, + 'sha2_256-memory-arguments': 4, + 'sha3_256-cpu-arguments-intercept': 1927926, + 'sha3_256-cpu-arguments-slope': 82523, + 'sha3_256-memory-arguments': 4, + 'sliceByteString-cpu-arguments-intercept': 265318, + 'sliceByteString-cpu-arguments-slope': 0, + 'sliceByteString-memory-arguments-intercept': 4, + 'sliceByteString-memory-arguments-slope': 0, + 'sndPair-cpu-arguments': 85931, + 'sndPair-memory-arguments': 32, + 'subtractInteger-cpu-arguments-intercept': 205665, + 'subtractInteger-cpu-arguments-slope': 812, + 'subtractInteger-memory-arguments-intercept': 1, + 'subtractInteger-memory-arguments-slope': 1, + 'tailList-cpu-arguments': 41182, + 'tailList-memory-arguments': 32, + 'trace-cpu-arguments': 212342, + 'trace-memory-arguments': 32, + 'unBData-cpu-arguments': 31220, + 'unBData-memory-arguments': 32, + 'unConstrData-cpu-arguments': 32696, + 'unConstrData-memory-arguments': 32, + 'unIData-cpu-arguments': 43357, + 'unIData-memory-arguments': 32, + 'unListData-cpu-arguments': 32247, + 'unListData-memory-arguments': 32, + 'unMapData-cpu-arguments': 38314, + 'unMapData-memory-arguments': 32, + 'verifyEcdsaSecp256k1Signature-cpu-arguments': 35892428, + 'verifyEcdsaSecp256k1Signature-memory-arguments': 10, + 'verifyEd25519Signature-cpu-arguments-intercept': 57996947, + 'verifyEd25519Signature-cpu-arguments-slope': 18975, + 'verifyEd25519Signature-memory-arguments': 10, + 'verifySchnorrSecp256k1Signature-cpu-arguments-intercept': 38887044, + 'verifySchnorrSecp256k1Signature-cpu-arguments-slope': 32947, + 'verifySchnorrSecp256k1Signature-memory-arguments': 10, +}) + +export const assertRequired = (value: T | undefined, message: string): T => { + if (value === undefined) throw new Error(message) + return value +} + +export const fixScriptHash = async (tx: CSL_TYPES.Transaction) => { + const builder = await getTransactionBuilder() + + const witnessSet = await tx.witnessSet() + + const plutusScripts = assertRequired(await witnessSet.plutusScripts(), 'Transaction does not contain plutus scripts') + const plutusData = assertRequired(await witnessSet.plutusData(), 'Transaction does not contain plutus data') + const redeemers = assertRequired(await witnessSet.redeemers(), 'Transaction does not contain redeemers') + const placeholderAddress = assertRequired( + await CardanoMobile.Address.fromBech32(DUMMY_ADDRESS), + 'Could not parse placeholder address', + ) + + const input = await (await (await tx.body()).inputs()).get(0) + const amount = await CardanoMobile.Value.new(await bigNumFromStr('5000000')) + const script = await plutusScripts.get(0) + const data = await plutusData.get(0) + const redeemer = await redeemers.get(0) + + const plutusWitness = await CardanoMobile.PlutusWitness.new(script, data, redeemer) + + await builder.addPlutusScriptInput(plutusWitness, input, amount) + + await builder.calcScriptDataHash(await getCostModel()) + + await builder.addChangeIfNeeded(placeholderAddress) + + const dummyTxForCalculatingScriptHash = assertRequired( + await builder.build(), + 'Could not build placeholder transaction', + ) + const correctScriptHash = assertRequired( + await dummyTxForCalculatingScriptHash.scriptDataHash(), + 'Script hash is empty', + ) + + const body = await tx.body() + await body.setScriptDataHash(correctScriptHash) + return body +} + +const DUMMY_ADDRESS = + 'addr1q9l0qrhrvu3nq92ns23g2atns690ge4c325vgzqlg4vru9uym9vrnx7vuq6q9lv984p6feekdusp3yewttl5a65sg6fs9r9gw5' + +export const getRequiredSigners = async (tx: CSL_TYPES.Transaction, wallet: YoroiWallet) => { + const utxos = wallet.allUtxos + const body = await tx.body() + const inputs = await body.inputs() + const purpose = isHaskellShelley(wallet.walletImplementationId) + ? NUMBERS.WALLET_TYPE_PURPOSE.CIP1852 + : NUMBERS.WALLET_TYPE_PURPOSE.BIP44 + const signers = [[purpose, harden(1815), harden(0), 0, 0]] + + const inputUtxos: RawUtxo[] = [] + + for (let i = 0; i < (await inputs.len()); i++) { + const input = await inputs.get(i) + const txId = await input.transactionId().then((t) => t.toHex()) + const txIndex = await input.index() + const matchingUtxo = utxos.find((utxo) => utxo.tx_hash === txId && utxo.tx_index === txIndex) + if (!matchingUtxo) continue + inputUtxos.push(matchingUtxo) + } + + inputUtxos.forEach((utxo) => { + signers.push(getDerivationPathForAddress(utxo.receiver, wallet, purpose)) + }) + + const requiredSigners = assertRequired(await body.requiredSigners(), 'Transaction does not contain required signers') + + const txRequiredAddresses: string[] = [] + for (let i = 0; i < (await requiredSigners.len()); i++) { + const signer = await requiredSigners.get(i) + const hex = await signer.toHex() + + const allAddresses = [...wallet.externalAddresses, ...wallet.internalAddresses] + await Promise.all( + allAddresses.map(async (bech32Address) => { + const parsedAddress = await CardanoMobile.Address.fromBech32(bech32Address) + const baseAddr = await CardanoMobile.BaseAddress.fromAddress(parsedAddress) + const paymentCred = await baseAddr.paymentCred() + const keyHash = await paymentCred.toKeyhash() + const hexKeyHash = await keyHash.toBytes().then((b) => Buffer.from(b).toString('hex')) + if (hex === hexKeyHash) { + txRequiredAddresses.push(bech32Address) + } + }), + ) + } + + txRequiredAddresses.forEach((address) => { + signers.push(getDerivationPathForAddress(address, wallet, purpose)) + }) + + const collateralInputs = assertRequired(await body.collateral(), 'Transaction does not contain collateral inputs') + + const firstCollateral = await collateralInputs.get(0) + const txId = await firstCollateral.transactionId().then((t) => t.toHex()) + const txIndex = await firstCollateral.index() + + const matchingUtxo = utxos.find((utxo) => utxo.tx_hash === txId && utxo.tx_index === txIndex) + if (!matchingUtxo) throw new Error('Could not find matching utxo') + + const {receiver} = matchingUtxo + signers.push(getDerivationPathForAddress(receiver, wallet, purpose)) + + return getUniquePaths(signers) +} + +const getUniquePaths = (paths: number[][]) => { + return _.uniqWith(paths, arePathsEqual) +} + +const arePathsEqual = (path1: number[], path2: number[]) => { + return path1.every((value, index) => value === path2[index]) && path1.length === path2.length +} + +const getDerivationPathForAddress = (address: string, wallet: YoroiWallet, purpose: number) => { + const internalIndex = wallet.internalAddresses.indexOf(address) + const externalIndex = wallet.externalAddresses.indexOf(address) + if (internalIndex === -1 && externalIndex === -1) throw new Error('Could not find matching address') + + const role = internalIndex > -1 ? 1 : 0 + const index = Math.max(internalIndex, externalIndex) + + return [purpose, harden(1815), harden(0), role, index] +} + +export const getMuesliSwapTransactionAndSigners = async (cbor: string, wallet: YoroiWallet) => { + const newCbor = await getMuesliSwapFixedCbor(cbor) + const tx = await CardanoMobile.Transaction.fromHex(newCbor) + const signers = await getRequiredSigners(tx, wallet) + return {cbor: newCbor, signers} +} + +export const getMuesliSwapFixedCbor = async (cbor: string) => { + const originalTx = assertRequired( + await CardanoMobile.Transaction.fromHex(cbor), + 'Could not parse transaction from cbor', + ) + const fixedTxBody = await fixScriptHash(originalTx) + + const txWithFixedBody = await CardanoMobile.Transaction.new(fixedTxBody, await originalTx.witnessSet(), undefined) + return Buffer.from(await txWithFixedBody.toBytes()).toString('hex') +} 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 f974a5d172..61087fa63c 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/shelley/ShelleyWallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/shelley/ShelleyWallet.ts @@ -39,7 +39,11 @@ import * as api 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 { + createSignedLedgerSwapCancellationTx, + createSwapCancellationLedgerPayload, + signRawTransaction, +} from '../common/signatureUtils' import * as MAINNET from '../constants/mainnet/constants' import * as TESTNET from '../constants/testnet/constants' import {CardanoError} from '../errors' @@ -859,11 +863,37 @@ export const makeShelleyWallet = (constants: typeof MAINNET | typeof TESTNET) => }) } - async ledgerSupportsCIP36(useUSB): Promise { + async ledgerSupportsCIP36(useUSB: boolean): Promise { if (!this.hwDeviceInfo) throw new Error('Invalid wallet state') return doesCardanoAppVersionSupportCIP36(await getCardanoAppMajorVersion(this.hwDeviceInfo, useUSB)) } + async signSwapCancellationWithLedger(cbor: string, useUSB: boolean): Promise { + if (!this.hwDeviceInfo) throw new Error('Invalid wallet state') + + const stakeVkeyHash = await this.getStakingKey().then((key) => key.hash()) + const payload = await createSwapCancellationLedgerPayload( + cbor, + this, + NETWORK_ID, + PROTOCOL_MAGIC, + (address: string) => this.getAddressing(address), + stakeVkeyHash, + ) + + const signedLedgerTx = await signTxWithLedger(payload, this.hwDeviceInfo, useUSB) + + const bytes = await createSignedLedgerSwapCancellationTx( + cbor, + signedLedgerTx.witnesses, + PURPOSE, + this.publicKeyHex, + ) + + const base64 = Buffer.from(bytes).toString('base64') + await this.submitTransaction(base64) + } + async signTxWithLedger(unsignedTx: YoroiUnsignedTx, useUSB: boolean): Promise { if (!this.hwDeviceInfo) throw new Error('Invalid wallet state') diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts index d566644288..d373b9526e 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts @@ -119,6 +119,9 @@ export type YoroiWallet = { // CIP36 ledgerSupportsCIP36(useUSB: boolean): Promise + // Ledger + signSwapCancellationWithLedger(cbor: string, useUSB: boolean): Promise + // Staking rewardAddressHex: string createDelegationTx(poolRequest: string, valueInAccount: BigNumber): Promise diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts index 8b34eed576..45b143474a 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts @@ -339,7 +339,7 @@ export const createRawTxSigningKey = async (rootKey: string, derivationPath: num const rawKey = await accountPrivateKey.toRawKey() const bech32 = await rawKey.toBech32() - const pkey = await CardanoMobile.PrivateKey.fromBech32(bech32) // TODO: Check this + const pkey = await CardanoMobile.PrivateKey.fromBech32(bech32) if (!pkey) throw new Error('Invalid private key') return pkey } diff --git a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts index 6adf04435b..5dd81102d7 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts @@ -82,6 +82,9 @@ const wallet: YoroiWallet = { collateralId: '22d391c7a97559cb4784bd975214919618acce75cde573a7150a176700e76181:2', } }, + signSwapCancellationWithLedger: async () => { + throw new Error('not implemented: signSwapCancellationWithLedger') + }, setCollateralId: () => { throw new Error('not implemented: createUnsignedTx') }, diff --git a/apps/wallet-mobile/translations/messages/src/Catalyst/VotingRegistrationBackupCheckModal.json b/apps/wallet-mobile/translations/messages/src/Catalyst/VotingRegistrationBackupCheckModal.json index 863618f8c9..828fc8ca01 100644 --- a/apps/wallet-mobile/translations/messages/src/Catalyst/VotingRegistrationBackupCheckModal.json +++ b/apps/wallet-mobile/translations/messages/src/Catalyst/VotingRegistrationBackupCheckModal.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!I have written down my Catalyst PIN which I obtained in previous steps.", "file": "src/Catalyst/VotingRegistrationBackupCheckModal.tsx", "start": { - "line": 58, + "line": 59, "column": 15, - "index": 1752 + "index": 1783 }, "end": { - "line": 61, + "line": 62, "column": 3, - "index": 1923 + "index": 1954 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!I have taken a screenshot of my QR code and saved my Catalyst secret code as a fallback.", "file": "src/Catalyst/VotingRegistrationBackupCheckModal.tsx", "start": { - "line": 62, + "line": 63, "column": 18, - "index": 1943 + "index": 1974 }, "end": { - "line": 65, + "line": 66, "column": 3, - "index": 2134 + "index": 2165 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!I understand that if I did not save my Catalyst PIN and QR code (or secret code) I will not be able to register and vote for Catalystproposals.", "file": "src/Catalyst/VotingRegistrationBackupCheckModal.tsx", "start": { - "line": 66, + "line": 67, "column": 24, - "index": 2160 + "index": 2191 }, "end": { - "line": 72, + "line": 73, "column": 3, - "index": 2440 + "index": 2471 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/Dashboard/Dashboard.json b/apps/wallet-mobile/translations/messages/src/Dashboard/Dashboard.json index e69f495efc..1bc5f0509e 100644 --- a/apps/wallet-mobile/translations/messages/src/Dashboard/Dashboard.json +++ b/apps/wallet-mobile/translations/messages/src/Dashboard/Dashboard.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Go to Staking Center", "file": "src/Dashboard/Dashboard.tsx", "start": { - "line": 219, + "line": 220, "column": 23, - "index": 6904 + "index": 6935 }, "end": { - "line": 222, + "line": 223, "column": 3, - "index": 7037 + "index": 7068 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.json b/apps/wallet-mobile/translations/messages/src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.json index cfd4974484..9483b3905a 100644 --- a/apps/wallet-mobile/translations/messages/src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.json +++ b/apps/wallet-mobile/translations/messages/src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Choose Connection Method", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 99, + "line": 100, "column": 9, - "index": 2829 + "index": 2863 }, "end": { - "line": 102, + "line": 103, "column": 3, - "index": 2947 + "index": 2981 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Choose this option if you want to connect to a Ledger Nano model X or S using an on-the-go USB cable adaptor:", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 103, + "line": 104, "column": 18, - "index": 2967 + "index": 3001 }, "end": { - "line": 108, + "line": 109, "column": 3, - "index": 3196 + "index": 3230 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Connect with USB", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 109, + "line": 110, "column": 13, - "index": 3211 + "index": 3245 }, "end": { - "line": 112, + "line": 113, "column": 3, - "index": 3325 + "index": 3359 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Connect with USB\n(Not supported)", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 113, + "line": 114, "column": 25, - "index": 3352 + "index": 3386 }, "end": { - "line": 116, + "line": 117, "column": 3, - "index": 3495 + "index": 3529 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Connect with USB\n(Blocked by Apple for iOS)", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 117, + "line": 118, "column": 21, - "index": 3518 + "index": 3552 }, "end": { - "line": 120, + "line": 121, "column": 3, - "index": 3668 + "index": 3702 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Choose this option if you want to connect to a Ledger Nano model X through Bluetooth:", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 121, + "line": 122, "column": 24, - "index": 3694 + "index": 3728 }, "end": { - "line": 124, + "line": 125, "column": 3, - "index": 3888 + "index": 3922 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Connect with Bluetooth", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 125, + "line": 126, "column": 19, - "index": 3909 + "index": 3943 }, "end": { - "line": 128, + "line": 129, "column": 3, - "index": 4035 + "index": 4069 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Connect with Bluetooth", "file": "src/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.tsx", "start": { - "line": 129, + "line": 130, "column": 18, - "index": 4055 + "index": 4089 }, "end": { - "line": 132, + "line": 133, "column": 3, - "index": 4165 + "index": 4199 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/Receive/AddressModal.json b/apps/wallet-mobile/translations/messages/src/Receive/AddressModal.json index 90ce87838a..4f42a1ae12 100644 --- a/apps/wallet-mobile/translations/messages/src/Receive/AddressModal.json +++ b/apps/wallet-mobile/translations/messages/src/Receive/AddressModal.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Your wallet address", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 147, + "line": 148, "column": 17, - "index": 3742 + "index": 3773 }, "end": { - "line": 150, + "line": 151, "column": 3, - "index": 3850 + "index": 3881 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!BIP32 path:", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 151, + "line": 152, "column": 13, - "index": 3865 + "index": 3896 }, "end": { - "line": 154, + "line": 155, "column": 3, - "index": 3961 + "index": 3992 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Copy address", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 155, + "line": 156, "column": 13, - "index": 3976 + "index": 4007 }, "end": { - "line": 158, + "line": 159, "column": 3, - "index": 4073 + "index": 4104 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Spending", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 159, + "line": 160, "column": 12, - "index": 4087 + "index": 4118 }, "end": { - "line": 162, + "line": 163, "column": 3, - "index": 4186 + "index": 4217 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Staking", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 163, + "line": 164, "column": 11, - "index": 4199 + "index": 4230 }, "end": { - "line": 166, + "line": 167, "column": 3, - "index": 4296 + "index": 4327 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Title", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 167, + "line": 168, "column": 9, - "index": 4307 + "index": 4338 }, "end": { - "line": 170, + "line": 171, "column": 3, - "index": 4393 + "index": 4424 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Verify Address on Ledger", "file": "src/Receive/AddressModal.tsx", "start": { - "line": 171, + "line": 172, "column": 15, - "index": 4410 + "index": 4441 }, "end": { - "line": 174, + "line": 175, "column": 3, - "index": 4521 + "index": 4552 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/Staking/PoolWarningModal/PoolWarningModal.json b/apps/wallet-mobile/translations/messages/src/Staking/PoolWarningModal/PoolWarningModal.json index 8ecd7fe493..d6cece9179 100644 --- a/apps/wallet-mobile/translations/messages/src/Staking/PoolWarningModal/PoolWarningModal.json +++ b/apps/wallet-mobile/translations/messages/src/Staking/PoolWarningModal/PoolWarningModal.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Attention", "file": "src/Staking/PoolWarningModal/PoolWarningModal.tsx", "start": { - "line": 123, + "line": 124, "column": 9, - "index": 3232 + "index": 3266 }, "end": { - "line": 126, + "line": 127, "column": 3, - "index": 3332 + "index": 3366 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Based on network activity, it seems this pool:", "file": "src/Staking/PoolWarningModal/PoolWarningModal.tsx", "start": { - "line": 127, + "line": 128, "column": 10, - "index": 3344 + "index": 3378 }, "end": { - "line": 130, + "line": 131, "column": 3, - "index": 3482 + "index": 3516 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Creates multiple blocks in the same slot (purposely causing forks)", "file": "src/Staking/PoolWarningModal/PoolWarningModal.tsx", "start": { - "line": 131, + "line": 132, "column": 14, - "index": 3498 + "index": 3532 }, "end": { - "line": 134, + "line": 135, "column": 3, - "index": 3660 + "index": 3694 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Purposely excludes transactions from blocks (censoring the network)", "file": "src/Staking/PoolWarningModal/PoolWarningModal.tsx", "start": { - "line": 135, + "line": 136, "column": 16, - "index": 3678 + "index": 3712 }, "end": { - "line": 138, + "line": 139, "column": 3, - "index": 3843 + "index": 3877 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!We suggest contacting the pool owner through the stake pool's webpage to ask about their behavior. Remember, you can change your delegation at any time without any interruptions in rewards.", "file": "src/Staking/PoolWarningModal/PoolWarningModal.tsx", "start": { - "line": 139, + "line": 140, "column": 13, - "index": 3858 + "index": 3892 }, "end": { - "line": 145, + "line": 146, "column": 3, - "index": 4170 + "index": 4204 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Causes some unknown issue (look online for more info)", "file": "src/Staking/PoolWarningModal/PoolWarningModal.tsx", "start": { - "line": 146, + "line": 147, "column": 11, - "index": 4183 + "index": 4217 }, "end": { - "line": 149, + "line": 150, "column": 3, - "index": 4329 + "index": 4363 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/TxHistory/ModalInfo/ModalInfo.json b/apps/wallet-mobile/translations/messages/src/TxHistory/ModalInfo/ModalInfo.json index ee1a17c7b5..ca45dce0a0 100644 --- a/apps/wallet-mobile/translations/messages/src/TxHistory/ModalInfo/ModalInfo.json +++ b/apps/wallet-mobile/translations/messages/src/TxHistory/ModalInfo/ModalInfo.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Info", "file": "src/TxHistory/ModalInfo/ModalInfo.tsx", "start": { - "line": 31, + "line": 32, "column": 13, - "index": 744 + "index": 778 }, "end": { - "line": 34, + "line": 35, "column": 3, - "index": 803 + "index": 837 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.json b/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.json index 8bd3c15132..a41400d103 100644 --- a/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.json +++ b/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Recovery phrase", "file": "src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.tsx", "start": { - "line": 50, + "line": 51, "column": 9, - "index": 1522 + "index": 1556 }, "end": { - "line": 53, + "line": 54, "column": 3, - "index": 1651 + "index": 1685 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!I understand that my secret keys are held securely on this device only, not on the company`s servers", "file": "src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.tsx", "start": { - "line": 54, + "line": 55, "column": 23, - "index": 1676 + "index": 1710 }, "end": { - "line": 58, + "line": 59, "column": 3, - "index": 1910 + "index": 1944 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!I understand that if this application is moved to another device or deleted, my money can be only recovered with the backup phrase that I have written down and saved in a secure place.", "file": "src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.tsx", "start": { - "line": 59, + "line": 60, "column": 29, - "index": 1941 + "index": 1975 }, "end": { - "line": 65, + "line": 66, "column": 3, - "index": 2287 + "index": 2321 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!I understand", "file": "src/WalletInit/MnemonicBackupModal/MnemonicBackupImportanceModal.tsx", "start": { - "line": 66, + "line": 67, "column": 22, - "index": 2311 + "index": 2345 }, "end": { - "line": 69, + "line": 70, "column": 3, - "index": 2450 + "index": 2484 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.json b/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.json index d4e7868170..27d3995111 100644 --- a/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.json +++ b/apps/wallet-mobile/translations/messages/src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!On the following screen, you will see a set of 15 random words. This is your **wallet recovery phrase**. It can be entered in any version of Yoroi in order to back up or restore your wallet`s funds and private key.", "file": "src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.tsx", "start": { - "line": 41, + "line": 42, "column": 14, - "index": 1180 + "index": 1214 }, "end": { - "line": 47, + "line": 48, "column": 3, - "index": 1536 + "index": 1570 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Make sure **nobody looks into your screen** unless you want them to have access to your funds.", "file": "src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.tsx", "start": { - "line": 48, + "line": 49, "column": 14, - "index": 1552 + "index": 1586 }, "end": { - "line": 51, + "line": 52, "column": 3, - "index": 1760 + "index": 1794 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!I understand", "file": "src/WalletInit/MnemonicExplanationModal/MnemonicExplanationModal.tsx", "start": { - "line": 52, + "line": 53, "column": 14, - "index": 1776 + "index": 1810 }, "end": { - "line": 55, + "line": 56, "column": 3, - "index": 1902 + "index": 1936 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/WalletInit/WalletInit/WalletInitScreen.json b/apps/wallet-mobile/translations/messages/src/WalletInit/WalletInit/WalletInitScreen.json index e3c5294a93..d79b9643c4 100644 --- a/apps/wallet-mobile/translations/messages/src/WalletInit/WalletInit/WalletInitScreen.json +++ b/apps/wallet-mobile/translations/messages/src/WalletInit/WalletInit/WalletInitScreen.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Create wallet", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 129, + "line": 130, "column": 22, - "index": 5036 + "index": 5070 }, "end": { - "line": 132, + "line": 133, "column": 3, - "index": 5150 + "index": 5184 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Restore wallet", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 133, + "line": 134, "column": 23, - "index": 5175 + "index": 5209 }, "end": { - "line": 136, + "line": 137, "column": 3, - "index": 5291 + "index": 5325 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!15-word Wallet", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 137, + "line": 138, "column": 28, - "index": 5321 + "index": 5355 }, "end": { - "line": 140, + "line": 141, "column": 3, - "index": 5442 + "index": 5476 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!24-word Wallet", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 141, + "line": 142, "column": 28, - "index": 5472 + "index": 5506 }, "end": { - "line": 144, + "line": 145, "column": 3, - "index": 5593 + "index": 5627 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!If you have a recovery phrase consisting of {mnemonicLength} words, choose this option to restore your wallet.", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 145, + "line": 146, "column": 33, - "index": 5628 + "index": 5662 }, "end": { - "line": 150, + "line": 151, "column": 3, - "index": 5867 + "index": 5901 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Read-only wallet", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 151, + "line": 152, "column": 29, - "index": 5898 + "index": 5932 }, "end": { - "line": 154, + "line": 155, "column": 3, - "index": 6022 + "index": 6056 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!The Yoroi extension allows you to export any of your wallets' public keys in a QR code. Choose this option to import a wallet from a QR code in read-only mode.", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 155, + "line": 156, "column": 35, - "index": 6059 + "index": 6093 }, "end": { - "line": 161, + "line": 162, "column": 3, - "index": 6361 + "index": 6395 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Connect to Ledger Nano", "file": "src/WalletInit/WalletInit/WalletInitScreen.tsx", "start": { - "line": 162, + "line": 163, "column": 32, - "index": 6395 + "index": 6429 }, "end": { - "line": 165, + "line": 166, "column": 3, - "index": 6528 + "index": 6562 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/components/ErrorModal/ErrorModal.json b/apps/wallet-mobile/translations/messages/src/components/ErrorModal/ErrorModal.json index c907b8bb28..ab3fd386bc 100644 --- a/apps/wallet-mobile/translations/messages/src/components/ErrorModal/ErrorModal.json +++ b/apps/wallet-mobile/translations/messages/src/components/ErrorModal/ErrorModal.json @@ -6,12 +6,12 @@ "start": { "line": 147, "column": 13, - "index": 4022 + "index": 4032 }, "end": { "line": 150, "column": 3, - "index": 4122 + "index": 4132 } }, { @@ -21,12 +21,12 @@ "start": { "line": 151, "column": 13, - "index": 4137 + "index": 4147 }, "end": { "line": 154, "column": 3, - "index": 4237 + "index": 4247 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/features/Swap/common/strings.json b/apps/wallet-mobile/translations/messages/src/features/Swap/common/strings.json index 34cf1ca96a..58c1b80f34 100644 --- a/apps/wallet-mobile/translations/messages/src/features/Swap/common/strings.json +++ b/apps/wallet-mobile/translations/messages/src/features/Swap/common/strings.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Incorrect password.", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 120, + "line": 121, "column": 24, - "index": 7514 + "index": 7606 }, "end": { - "line": 123, + "line": 124, "column": 3, - "index": 7623 + "index": 7715 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Swap", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 124, + "line": 125, "column": 13, - "index": 7638 + "index": 7730 }, "end": { - "line": 127, + "line": 128, "column": 3, - "index": 7711 + "index": 7803 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Token swap", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 128, + "line": 129, "column": 13, - "index": 7726 + "index": 7818 }, "end": { - "line": 131, + "line": 132, "column": 3, - "index": 7808 + "index": 7900 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 132, + "line": 133, "column": 13, - "index": 7823 + "index": 7915 }, "end": { - "line": 135, + "line": 136, "column": 3, - "index": 7902 + "index": 7994 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Market Button", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 136, + "line": 137, "column": 16, - "index": 7920 + "index": 8012 }, "end": { - "line": 139, + "line": 140, "column": 3, - "index": 8005 + "index": 8097 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Limit", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 140, + "line": 141, "column": 15, - "index": 8022 + "index": 8114 }, "end": { - "line": 143, + "line": 144, "column": 3, - "index": 8098 + "index": 8190 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Swap from", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 144, + "line": 145, "column": 12, - "index": 8112 + "index": 8204 }, "end": { - "line": 147, + "line": 148, "column": 3, - "index": 8189 + "index": 8281 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Swap to", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 148, + "line": 149, "column": 10, - "index": 8201 + "index": 8293 }, "end": { - "line": 151, + "line": 152, "column": 3, - "index": 8274 + "index": 8366 } }, { @@ -124,14 +124,14 @@ "defaultMessage": "!!!Current Balance", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 152, + "line": 153, "column": 18, - "index": 8294 + "index": 8386 }, "end": { - "line": 155, + "line": 156, "column": 3, - "index": 8383 + "index": 8475 } }, { @@ -139,14 +139,14 @@ "defaultMessage": "!!!Balance", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 156, + "line": 157, "column": 11, - "index": 8396 + "index": 8488 }, "end": { - "line": 159, + "line": 160, "column": 3, - "index": 8470 + "index": 8562 } }, { @@ -154,14 +154,14 @@ "defaultMessage": "!!!Select Token", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 160, + "line": 161, "column": 15, - "index": 8487 + "index": 8579 }, "end": { - "line": 163, + "line": 164, "column": 3, - "index": 8570 + "index": 8662 } }, { @@ -169,14 +169,14 @@ "defaultMessage": "!!!Market Price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 164, + "line": 165, "column": 15, - "index": 8587 + "index": 8679 }, "end": { - "line": 167, + "line": 168, "column": 3, - "index": 8670 + "index": 8762 } }, { @@ -184,14 +184,14 @@ "defaultMessage": "!!!Limit Price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 168, + "line": 169, "column": 14, - "index": 8686 + "index": 8778 }, "end": { - "line": 171, + "line": 172, "column": 3, - "index": 8767 + "index": 8859 } }, { @@ -199,14 +199,14 @@ "defaultMessage": "!!!Slippage Tolerance", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 172, + "line": 173, "column": 21, - "index": 8790 + "index": 8882 }, "end": { - "line": 175, + "line": 176, "column": 3, - "index": 8885 + "index": 8977 } }, { @@ -214,14 +214,14 @@ "defaultMessage": "!!!Slippage must be a number between 0 and 100 and have up to 1 decimal", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 176, + "line": 177, "column": 26, - "index": 8913 + "index": 9005 }, "end": { - "line": 179, + "line": 180, "column": 3, - "index": 9063 + "index": 9155 } }, { @@ -229,14 +229,14 @@ "defaultMessage": "!!!Slippage Tolerance Info", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 180, + "line": 181, "column": 25, - "index": 9090 + "index": 9182 }, "end": { - "line": 183, + "line": 184, "column": 3, - "index": 9194 + "index": 9286 } }, { @@ -244,14 +244,14 @@ "defaultMessage": "!!!Verified by {pool}", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 184, + "line": 185, "column": 14, - "index": 9210 + "index": 9302 }, "end": { - "line": 187, + "line": 188, "column": 3, - "index": 9298 + "index": 9390 } }, { @@ -259,14 +259,14 @@ "defaultMessage": "!!!This asset is in my portfolio", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 188, + "line": 189, "column": 12, - "index": 9312 + "index": 9404 }, "end": { - "line": 191, + "line": 192, "column": 3, - "index": 9409 + "index": 9501 } }, { @@ -274,14 +274,14 @@ "defaultMessage": "!!!Default Slippage Tolerance", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 192, + "line": 193, "column": 19, - "index": 9430 + "index": 9522 }, "end": { - "line": 195, + "line": 196, "column": 3, - "index": 9531 + "index": 9623 } }, { @@ -289,14 +289,14 @@ "defaultMessage": "!!!Slippage tolerance is set as a percentage of the total swap value.", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 196, + "line": 197, "column": 16, - "index": 9549 + "index": 9641 }, "end": { - "line": 199, + "line": 200, "column": 3, - "index": 9687 + "index": 9779 } }, { @@ -304,14 +304,14 @@ "defaultMessage": "!!!(auto)", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 200, + "line": 201, "column": 12, - "index": 9701 + "index": 9793 }, "end": { - "line": 203, + "line": 204, "column": 3, - "index": 9775 + "index": 9867 } }, { @@ -319,14 +319,14 @@ "defaultMessage": "!!!change pool", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 204, + "line": 205, "column": 14, - "index": 9791 + "index": 9883 }, "end": { - "line": 207, + "line": 208, "column": 3, - "index": 9872 + "index": 9964 } }, { @@ -334,14 +334,14 @@ "defaultMessage": "!!!Min-ADA is the minimum ADA amount required to be contained when holding or sending Cardano native tokens.", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 208, + "line": 209, "column": 14, - "index": 9888 + "index": 9980 }, "end": { - "line": 212, + "line": 213, "column": 3, - "index": 10069 + "index": 10161 } }, { @@ -349,14 +349,14 @@ "defaultMessage": "!!!Min ADA", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 213, + "line": 214, "column": 19, - "index": 10090 + "index": 10182 }, "end": { - "line": 216, + "line": 217, "column": 3, - "index": 10172 + "index": 10264 } }, { @@ -364,14 +364,14 @@ "defaultMessage": "!!!Swap fees include the following:\n • Matchmaker Fee\n • Frontend Fee\n • Liquidity Provider Fee", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 217, + "line": 218, "column": 12, - "index": 10186 + "index": 10278 }, "end": { - "line": 220, + "line": 221, "column": 3, - "index": 10349 + "index": 10441 } }, { @@ -379,14 +379,14 @@ "defaultMessage": "!!!Fees", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 221, + "line": 222, "column": 17, - "index": 10368 + "index": 10460 }, "end": { - "line": 224, + "line": 225, "column": 3, - "index": 10445 + "index": 10537 } }, { @@ -394,14 +394,14 @@ "defaultMessage": "!!!Liquidity provider fee ({fee}%)", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 225, + "line": 226, "column": 20, - "index": 10467 + "index": 10559 }, "end": { - "line": 228, + "line": 229, "column": 3, - "index": 10574 + "index": 10666 } }, { @@ -409,14 +409,14 @@ "defaultMessage": "!!!Minimum amount of tokens you can get because of the slippage tolerance.", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 229, + "line": 230, "column": 19, - "index": 10595 + "index": 10687 }, "end": { - "line": 232, + "line": 233, "column": 3, - "index": 10741 + "index": 10833 } }, { @@ -424,14 +424,14 @@ "defaultMessage": "!!!Min Received", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 233, + "line": 234, "column": 24, - "index": 10767 + "index": 10859 }, "end": { - "line": 236, + "line": 237, "column": 3, - "index": 10859 + "index": 10951 } }, { @@ -439,14 +439,14 @@ "defaultMessage": "!!!Enter a value from 0% to 100%. You can also enter up to 1 decimal", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 237, + "line": 238, "column": 17, - "index": 10878 + "index": 10970 }, "end": { - "line": 240, + "line": 241, "column": 3, - "index": 11016 + "index": 11108 } }, { @@ -454,14 +454,14 @@ "defaultMessage": "!!!{pool} verification", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 241, + "line": 242, "column": 20, - "index": 11038 + "index": 11130 }, "end": { - "line": 244, + "line": 245, "column": 3, - "index": 11133 + "index": 11225 } }, { @@ -469,14 +469,14 @@ "defaultMessage": "!!!Volume, 24h", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 245, + "line": 246, "column": 10, - "index": 11145 + "index": 11237 }, "end": { - "line": 248, + "line": 249, "column": 3, - "index": 11222 + "index": 11314 } }, { @@ -484,14 +484,14 @@ "defaultMessage": "!!!Cardano projects that list their own tokens can apply for an additional {pool} verification. This verification is a manual validation that {pool} team performs with the help of Cardano Foundation.", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 249, + "line": 250, "column": 24, - "index": 11248 + "index": 11340 }, "end": { - "line": 253, + "line": 254, "column": 3, - "index": 11530 + "index": 11622 } }, { @@ -499,14 +499,14 @@ "defaultMessage": "!!! Price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 254, + "line": 255, "column": 9, - "index": 11541 + "index": 11633 }, "end": { - "line": 257, + "line": 258, "column": 3, - "index": 11603 + "index": 11695 } }, { @@ -514,14 +514,14 @@ "defaultMessage": "!!!No assets found for this pair", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 258, + "line": 259, "column": 17, - "index": 11622 + "index": 11714 }, "end": { - "line": 261, + "line": 262, "column": 3, - "index": 11724 + "index": 11816 } }, { @@ -529,14 +529,14 @@ "defaultMessage": "!!!No assets found for \"{search}\"", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 262, + "line": 263, "column": 20, - "index": 11746 + "index": 11838 }, "end": { - "line": 265, + "line": 266, "column": 3, - "index": 11852 + "index": 11944 } }, { @@ -544,14 +544,14 @@ "defaultMessage": "!!!Each verified tokens gets", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 266, + "line": 267, "column": 21, - "index": 11875 + "index": 11967 }, "end": { - "line": 269, + "line": 270, "column": 3, - "index": 11977 + "index": 12069 } }, { @@ -559,14 +559,14 @@ "defaultMessage": "!!!verified badge", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 270, + "line": 271, "column": 17, - "index": 11996 + "index": 12088 }, "end": { - "line": 273, + "line": 274, "column": 3, - "index": 12083 + "index": 12175 } }, { @@ -574,14 +574,14 @@ "defaultMessage": "!!!Open orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 274, + "line": 275, "column": 14, - "index": 12099 + "index": 12191 }, "end": { - "line": 277, + "line": 278, "column": 3, - "index": 12180 + "index": 12272 } }, { @@ -589,14 +589,14 @@ "defaultMessage": "!!!Completed orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 278, + "line": 279, "column": 19, - "index": 12201 + "index": 12293 }, "end": { - "line": 281, + "line": 282, "column": 3, - "index": 12292 + "index": 12384 } }, { @@ -604,14 +604,14 @@ "defaultMessage": "!!!TVL", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 282, + "line": 283, "column": 7, - "index": 12301 + "index": 12393 }, "end": { - "line": 285, + "line": 286, "column": 3, - "index": 12367 + "index": 12459 } }, { @@ -619,14 +619,14 @@ "defaultMessage": "!!! Pool Fee", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 286, + "line": 287, "column": 11, - "index": 12380 + "index": 12472 }, "end": { - "line": 289, + "line": 290, "column": 3, - "index": 12456 + "index": 12548 } }, { @@ -634,14 +634,14 @@ "defaultMessage": "!!! Batcher Fee", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 290, + "line": 291, "column": 14, - "index": 12472 + "index": 12564 }, "end": { - "line": 293, + "line": 294, "column": 3, - "index": 12554 + "index": 12646 } }, { @@ -649,14 +649,14 @@ "defaultMessage": "!!!Limit price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 294, + "line": 295, "column": 26, - "index": 12582 + "index": 12674 }, "end": { - "line": 297, + "line": 298, "column": 3, - "index": 12675 + "index": 12767 } }, { @@ -664,14 +664,14 @@ "defaultMessage": "!!!Are you sure you want to proceed this order with the limit price that is 10% or more higher than the\nmarket price?", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 298, + "line": 299, "column": 32, - "index": 12709 + "index": 12801 }, "end": { - "line": 303, + "line": 304, "column": 3, - "index": 12929 + "index": 13021 } }, { @@ -679,14 +679,14 @@ "defaultMessage": "!!!Your limit price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 304, + "line": 305, "column": 30, - "index": 12961 + "index": 13053 }, "end": { - "line": 307, + "line": 308, "column": 3, - "index": 13063 + "index": 13155 } }, { @@ -694,14 +694,14 @@ "defaultMessage": "!!!Market price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 308, + "line": 309, "column": 32, - "index": 13097 + "index": 13189 }, "end": { - "line": 311, + "line": 312, "column": 3, - "index": 13197 + "index": 13289 } }, { @@ -709,14 +709,14 @@ "defaultMessage": "!!!Back", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 312, + "line": 313, "column": 25, - "index": 13224 + "index": 13316 }, "end": { - "line": 315, + "line": 316, "column": 3, - "index": 13309 + "index": 13401 } }, { @@ -724,14 +724,14 @@ "defaultMessage": "!!!Swap", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 316, + "line": 317, "column": 28, - "index": 13339 + "index": 13431 }, "end": { - "line": 319, + "line": 320, "column": 3, - "index": 13427 + "index": 13519 } }, { @@ -739,14 +739,14 @@ "defaultMessage": "!!!Transaction signed", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 320, + "line": 321, "column": 21, - "index": 13450 + "index": 13542 }, "end": { - "line": 323, + "line": 324, "column": 3, - "index": 13545 + "index": 13637 } }, { @@ -754,14 +754,14 @@ "defaultMessage": "!!!Your transactions will be displayed both in the list of transaction and Open swap orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 324, + "line": 325, "column": 22, - "index": 13569 + "index": 13661 }, "end": { - "line": 327, + "line": 328, "column": 3, - "index": 13735 + "index": 13827 } }, { @@ -769,14 +769,14 @@ "defaultMessage": "!!! dex", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 328, + "line": 329, "column": 7, - "index": 13744 + "index": 13836 }, "end": { - "line": 331, + "line": 332, "column": 3, - "index": 13811 + "index": 13903 } }, { @@ -784,14 +784,14 @@ "defaultMessage": "!!!see on explorer", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 332, + "line": 333, "column": 17, - "index": 13830 + "index": 13922 }, "end": { - "line": 335, + "line": 336, "column": 3, - "index": 13918 + "index": 14010 } }, { @@ -799,14 +799,14 @@ "defaultMessage": "!!!GO to Orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 336, + "line": 337, "column": 14, - "index": 13934 + "index": 14026 }, "end": { - "line": 339, + "line": 340, "column": 3, - "index": 14016 + "index": 14108 } }, { @@ -814,14 +814,14 @@ "defaultMessage": "!!!Asset", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 340, + "line": 341, "column": 9, - "index": 14027 + "index": 14119 }, "end": { - "line": 343, + "line": 344, "column": 3, - "index": 14100 + "index": 14192 } }, { @@ -829,14 +829,14 @@ "defaultMessage": "!!!Clear", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 344, + "line": 345, "column": 9, - "index": 14111 + "index": 14203 }, "end": { - "line": 347, + "line": 348, "column": 3, - "index": 14172 + "index": 14264 } }, { @@ -844,14 +844,14 @@ "defaultMessage": "!!!Sign transaction", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 348, + "line": 349, "column": 19, - "index": 14193 + "index": 14285 }, "end": { - "line": 351, + "line": 352, "column": 3, - "index": 14275 + "index": 14367 } }, { @@ -859,14 +859,14 @@ "defaultMessage": "!!!Spending Password", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 352, + "line": 353, "column": 20, - "index": 14297 + "index": 14389 }, "end": { - "line": 355, + "line": 356, "column": 3, - "index": 14381 + "index": 14473 } }, { @@ -874,14 +874,14 @@ "defaultMessage": "!!!Enter spending password to sign this transaction", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 356, + "line": 357, "column": 25, - "index": 14408 + "index": 14500 }, "end": { - "line": 359, + "line": 360, "column": 3, - "index": 14528 + "index": 14620 } }, { @@ -889,14 +889,14 @@ "defaultMessage": "!!!Sign", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 360, + "line": 361, "column": 8, - "index": 14538 + "index": 14630 }, "end": { - "line": 363, + "line": 364, "column": 3, - "index": 14597 + "index": 14689 } }, { @@ -904,14 +904,14 @@ "defaultMessage": "!!!Swap", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 364, + "line": 365, "column": 14, - "index": 14613 + "index": 14705 }, "end": { - "line": 367, + "line": 368, "column": 3, - "index": 14672 + "index": 14764 } }, { @@ -919,14 +919,14 @@ "defaultMessage": "!!!completed orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 368, + "line": 369, "column": 23, - "index": 14697 + "index": 14789 }, "end": { - "line": 371, + "line": 372, "column": 3, - "index": 14782 + "index": 14874 } }, { @@ -934,14 +934,14 @@ "defaultMessage": "!!!open orders", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 372, + "line": 373, "column": 18, - "index": 14802 + "index": 14894 }, "end": { - "line": 375, + "line": 376, "column": 3, - "index": 14877 + "index": 14969 } }, { @@ -949,14 +949,14 @@ "defaultMessage": "!!!Confirm order cancelation", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 376, + "line": 377, "column": 24, - "index": 14903 + "index": 14995 }, "end": { - "line": 379, + "line": 380, "column": 3, - "index": 14999 + "index": 15091 } }, { @@ -964,14 +964,14 @@ "defaultMessage": "!!!Cancel order", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 380, + "line": 381, "column": 29, - "index": 15030 + "index": 15122 }, "end": { - "line": 383, + "line": 384, "column": 3, - "index": 15117 + "index": 15209 } }, { @@ -979,14 +979,14 @@ "defaultMessage": "!!!Are you sure you want to cancel this order?", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 384, + "line": 385, "column": 31, - "index": 15150 + "index": 15242 }, "end": { - "line": 387, + "line": 388, "column": 3, - "index": 15271 + "index": 15363 } }, { @@ -994,14 +994,14 @@ "defaultMessage": "!!!Learn more about swap orders in Yoroi", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 388, + "line": 389, "column": 23, - "index": 15296 + "index": 15388 }, "end": { - "line": 391, + "line": 392, "column": 3, - "index": 15403 + "index": 15495 } }, { @@ -1009,14 +1009,14 @@ "defaultMessage": "!!!Asset price", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 392, + "line": 393, "column": 29, - "index": 15434 + "index": 15526 }, "end": { - "line": 395, + "line": 396, "column": 3, - "index": 15521 + "index": 15613 } }, { @@ -1024,14 +1024,14 @@ "defaultMessage": "!!!Asset amount", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 396, + "line": 397, "column": 30, - "index": 15553 + "index": 15645 }, "end": { - "line": 399, + "line": 400, "column": 3, - "index": 15642 + "index": 15734 } }, { @@ -1039,14 +1039,14 @@ "defaultMessage": "!!!Total returned", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 400, + "line": 401, "column": 32, - "index": 15676 + "index": 15768 }, "end": { - "line": 403, + "line": 404, "column": 3, - "index": 15769 + "index": 15861 } }, { @@ -1054,14 +1054,14 @@ "defaultMessage": "!!!Cancellation Fee", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 404, + "line": 405, "column": 34, - "index": 15805 + "index": 15897 }, "end": { - "line": 407, + "line": 408, "column": 3, - "index": 15902 + "index": 15994 } }, { @@ -1069,14 +1069,14 @@ "defaultMessage": "!!!Confirm", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 408, + "line": 409, "column": 26, - "index": 15930 + "index": 16022 }, "end": { - "line": 411, + "line": 412, "column": 3, - "index": 16010 + "index": 16102 } }, { @@ -1084,14 +1084,14 @@ "defaultMessage": "!!!Back", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 412, + "line": 413, "column": 23, - "index": 16035 + "index": 16127 }, "end": { - "line": 415, + "line": 416, "column": 3, - "index": 16109 + "index": 16201 } }, { @@ -1099,14 +1099,14 @@ "defaultMessage": "!!!Total", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 416, + "line": 417, "column": 19, - "index": 16130 + "index": 16222 }, "end": { - "line": 419, + "line": 420, "column": 3, - "index": 16200 + "index": 16292 } }, { @@ -1114,14 +1114,14 @@ "defaultMessage": "!!!Liquidity Pool", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 420, + "line": 421, "column": 27, - "index": 16229 + "index": 16321 }, "end": { - "line": 423, + "line": 424, "column": 3, - "index": 16316 + "index": 16408 } }, { @@ -1129,14 +1129,14 @@ "defaultMessage": "!!!Time Created", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 424, + "line": 425, "column": 25, - "index": 16343 + "index": 16435 }, "end": { - "line": 427, + "line": 428, "column": 3, - "index": 16426 + "index": 16518 } }, { @@ -1144,14 +1144,14 @@ "defaultMessage": "!!!Transaction ID", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 428, + "line": 429, "column": 18, - "index": 16446 + "index": 16538 }, "end": { - "line": 431, + "line": 432, "column": 3, - "index": 16524 + "index": 16616 } }, { @@ -1159,14 +1159,14 @@ "defaultMessage": "!!!Choose Connection Method", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 432, + "line": 433, "column": 26, - "index": 16552 + "index": 16644 }, "end": { - "line": 435, + "line": 436, "column": 3, - "index": 16670 + "index": 16762 } }, { @@ -1174,14 +1174,14 @@ "defaultMessage": "!!!Choose this option if you want to connect to a Ledger Nano model X or S using an on-the-go USB cable adaptor:", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 436, + "line": 437, "column": 18, - "index": 16690 + "index": 16782 }, "end": { - "line": 441, + "line": 442, "column": 3, - "index": 16919 + "index": 17011 } }, { @@ -1189,14 +1189,14 @@ "defaultMessage": "!!!Connect with USB", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 442, + "line": 443, "column": 13, - "index": 16934 + "index": 17026 }, "end": { - "line": 445, + "line": 446, "column": 3, - "index": 17048 + "index": 17140 } }, { @@ -1204,14 +1204,14 @@ "defaultMessage": "!!! USB connection is blocked by iOS devices", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 446, + "line": 447, "column": 26, - "index": 17076 + "index": 17168 }, "end": { - "line": 449, + "line": 450, "column": 3, - "index": 17228 + "index": 17320 } }, { @@ -1219,14 +1219,14 @@ "defaultMessage": "!!!Choose this option if you want to connect to a Ledger Nano model X through Bluetooth:", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 450, + "line": 451, "column": 24, - "index": 17254 + "index": 17346 }, "end": { - "line": 453, + "line": 454, "column": 3, - "index": 17448 + "index": 17540 } }, { @@ -1234,14 +1234,14 @@ "defaultMessage": "!!!Connect with Bluetooth", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 454, + "line": 455, "column": 19, - "index": 17469 + "index": 17561 }, "end": { - "line": 457, + "line": 458, "column": 3, - "index": 17595 + "index": 17687 } }, { @@ -1249,14 +1249,14 @@ "defaultMessage": "!!!Connect with Bluetooth", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 458, + "line": 459, "column": 18, - "index": 17615 + "index": 17707 }, "end": { - "line": 461, + "line": 462, "column": 3, - "index": 17725 + "index": 17817 } }, { @@ -1264,14 +1264,14 @@ "defaultMessage": "!!!You have", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 464, + "line": 465, "column": 11, - "index": 17784 + "index": 17876 }, "end": { - "line": 467, + "line": 468, "column": 3, - "index": 17879 + "index": 17971 } }, { @@ -1279,14 +1279,14 @@ "defaultMessage": "!!!No assets found", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 468, + "line": 469, "column": 12, - "index": 17893 + "index": 17985 }, "end": { - "line": 471, + "line": 472, "column": 3, - "index": 17996 + "index": 18088 } }, { @@ -1294,14 +1294,14 @@ "defaultMessage": "!!!found", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 472, + "line": 473, "column": 9, - "index": 18007 + "index": 18099 }, "end": { - "line": 475, + "line": 476, "column": 3, - "index": 18097 + "index": 18189 } }, { @@ -1309,14 +1309,14 @@ "defaultMessage": "!!!Search tokens", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 476, + "line": 477, "column": 16, - "index": 18115 + "index": 18207 }, "end": { - "line": 479, + "line": 480, "column": 3, - "index": 18211 + "index": 18303 } }, { @@ -1324,14 +1324,14 @@ "defaultMessage": "!!!Select asset", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 480, + "line": 481, "column": 20, - "index": 18233 + "index": 18325 }, "end": { - "line": 483, + "line": 484, "column": 3, - "index": 18322 + "index": 18414 } }, { @@ -1339,14 +1339,14 @@ "defaultMessage": "!!!Confirm", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 484, + "line": 485, "column": 11, - "index": 18335 + "index": 18427 }, "end": { - "line": 487, + "line": 488, "column": 3, - "index": 18429 + "index": 18521 } }, { @@ -1354,14 +1354,14 @@ "defaultMessage": "!!!Assign collateral", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 488, + "line": 489, "column": 20, - "index": 18451 + "index": 18543 }, "end": { - "line": 491, + "line": 492, "column": 3, - "index": 18558 + "index": 18650 } }, { @@ -1369,14 +1369,14 @@ "defaultMessage": "!!!Collateral not found", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 492, + "line": 493, "column": 22, - "index": 18582 + "index": 18674 }, "end": { - "line": 495, + "line": 496, "column": 3, - "index": 18694 + "index": 18786 } }, { @@ -1384,14 +1384,14 @@ "defaultMessage": "!!!You don't have an active collateral utxo", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 496, + "line": 497, "column": 22, - "index": 18718 + "index": 18810 }, "end": { - "line": 499, + "line": 500, "column": 3, - "index": 18850 + "index": 18942 } }, { @@ -1399,14 +1399,14 @@ "defaultMessage": "!!!Transaction failed", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 500, + "line": 501, "column": 17, - "index": 18869 + "index": 18961 }, "end": { - "line": 503, + "line": 504, "column": 3, - "index": 18971 + "index": 19063 } }, { @@ -1414,14 +1414,14 @@ "defaultMessage": "!!!Your transaction has not been processed properly due to technical issues", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 504, + "line": 505, "column": 16, - "index": 18989 + "index": 19081 }, "end": { - "line": 507, + "line": 508, "column": 3, - "index": 19144 + "index": 19236 } }, { @@ -1429,14 +1429,14 @@ "defaultMessage": "!!!Try again", "file": "src/features/Swap/common/strings.ts", "start": { - "line": 508, + "line": 509, "column": 18, - "index": 19164 + "index": 19256 }, "end": { - "line": 511, + "line": 512, "column": 3, - "index": 19258 + "index": 19350 } } ] \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8e297dce93..87cabf102e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1635,7 +1635,6 @@ hoist-non-react-statics "^3.3.0" "@cardano-foundation/ledgerjs-hw-app-cardano@^5.0.0": - name "@cardano-foundation/ledgerjs-hw-app-cardanoV5" version "5.1.0" resolved "https://registry.yarnpkg.com/@cardano-foundation/ledgerjs-hw-app-cardano/-/ledgerjs-hw-app-cardano-5.1.0.tgz#69b94f7c5055bdb19aa719ff277fa5f683d11067" integrity sha512-ucuz/XbS/0ZD0Bal/GI/kiTm9jDIl8J+A7ypEqcAcBDGicFsyWmtPotOTwuDovTsiM8+eA/5OGTFX0oRqzxstQ== @@ -2017,10 +2016,10 @@ "@ledgerhq/logs" "^5.15.0" rxjs "^6.5.5" -"@emurgo/yoroi-lib@^0.9.8": - version "0.9.8" - resolved "https://registry.yarnpkg.com/@emurgo/yoroi-lib/-/yoroi-lib-0.9.8.tgz#977f81ba6dbeea11e64f0b56068c2a66d02a43f4" - integrity sha512-Hk//6ZYsPdNjpqmlcFkW6ZQrxravS/vAx5JGbUai5mrSPDNdjCBOqIlamUf0h4YKbVLB0dnlF7Uxu1+/c8vc6g== +"@emurgo/yoroi-lib@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@emurgo/yoroi-lib/-/yoroi-lib-0.10.1.tgz#1c794311a0e07e9eed7f06010a0a77dd2b43f48a" + integrity sha512-g4azRsP8BbdVT6ibZ0BdtBtrn2jED172Zw7CwWhr5J6PNXptuv907zTGWGIFUHrrovKvYx0S6BBuM1lIIFsoKQ== dependencies: "@cardano-foundation/ledgerjs-hw-app-cardano" "^6.0.0" "@emurgo/cross-csl-core" "3.1.0"