From b15b94a0b5b466436d6e4df66ab0e27e6dd5d152 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 24 Jun 2024 17:46:36 -0700 Subject: [PATCH] Make getMaxSpendable reusable --- .../currency/wallet/currency-wallet-api.ts | 66 +++------------- src/core/currency/wallet/max-spend.ts | 78 +++++++++++++++++++ 2 files changed, 87 insertions(+), 57 deletions(-) create mode 100644 src/core/currency/wallet/max-spend.ts diff --git a/src/core/currency/wallet/currency-wallet-api.ts b/src/core/currency/wallet/currency-wallet-api.ts index c652a7d2..e62df42f 100644 --- a/src/core/currency/wallet/currency-wallet-api.ts +++ b/src/core/currency/wallet/currency-wallet-api.ts @@ -1,4 +1,4 @@ -import { add, div, eq, lte, mul, sub } from 'biggystring' +import { div, eq, mul } from 'biggystring' import { Disklet } from 'disklet' import { bridgifyObject, onMethod, watchMethod } from 'yaob' @@ -55,6 +55,7 @@ import { } from './currency-wallet-files' import { CurrencyWalletInput } from './currency-wallet-pixie' import { MergedTransaction } from './currency-wallet-reducer' +import { getMaxSpendableInner } from './max-spend' import { mergeMetadata } from './metadata' import { upgradeMemos } from './upgrade-memos' @@ -388,62 +389,13 @@ export function makeCurrencyWalletApi( return await engine.broadcastTx(tx, { privateKeys }) }, async getMaxSpendable(spendInfo: EdgeSpendInfo): Promise { - spendInfo = upgradeMemos(spendInfo, plugin.currencyInfo) - // Figure out which asset this is: - const upgradedCurrency = upgradeCurrencyCode({ - allTokens: input.props.state.accounts[accountId].allTokens[pluginId], - currencyInfo: plugin.currencyInfo, - tokenId: spendInfo.tokenId - }) - - if (typeof engine.getMaxSpendable === 'function') { - // Only provide wallet info if currency requires it: - const privateKeys = unsafeMakeSpend ? walletInfo.keys : undefined - - return await engine.getMaxSpendable( - { ...spendInfo, ...upgradedCurrency }, - { privateKeys } - ) - } - - const { networkFeeOption, customNetworkFee } = spendInfo - const balance = engine.getBalance(upgradedCurrency) - - // Copy all the spend targets, setting the amounts to 0 - // but keeping all other information so we can get accurate fees: - const spendTargets = spendInfo.spendTargets.map(spendTarget => { - return { ...spendTarget, nativeAmount: '0' } - }) - - // The range of possible values includes `min`, but not `max`. - function getMax(min: string, max: string): Promise { - const diff = sub(max, min) - if (lte(diff, '1')) { - return Promise.resolve(min) - } - const mid = add(min, div(diff, '2')) - - // Try the average: - spendTargets[0].nativeAmount = mid - - // Only provide wallet info if currency requires it: - const privateKeys = unsafeMakeSpend ? walletInfo.keys : undefined - - return engine - .makeSpend( - { - ...upgradedCurrency, - spendTargets, - networkFeeOption, - customNetworkFee - }, - { privateKeys } - ) - .then(() => getMax(mid, max)) - .catch(() => getMax(min, mid)) - } - - return await getMax('0', add(balance, '1')) + return await getMaxSpendableInner( + spendInfo, + plugin, + engine, + input.props.state.accounts[accountId].allTokens[pluginId], + walletInfo + ) }, async getPaymentProtocolInfo( paymentProtocolUrl: string diff --git a/src/core/currency/wallet/max-spend.ts b/src/core/currency/wallet/max-spend.ts new file mode 100644 index 00000000..28d31db9 --- /dev/null +++ b/src/core/currency/wallet/max-spend.ts @@ -0,0 +1,78 @@ +import { add, div, lte, sub } from 'biggystring' + +import { + EdgeCurrencyEngine, + EdgeCurrencyPlugin, + EdgeSpendInfo, + EdgeTokenMap, + EdgeWalletInfo +} from '../../../browser' +import { upgradeCurrencyCode } from '../../../types/type-helpers' +import { upgradeMemos } from './upgrade-memos' + +export const getMaxSpendableInner = async ( + spendInfo: EdgeSpendInfo, + plugin: EdgeCurrencyPlugin, + engine: EdgeCurrencyEngine, + allTokens: EdgeTokenMap, + walletInfo: EdgeWalletInfo +): Promise => { + spendInfo = upgradeMemos(spendInfo, plugin.currencyInfo) + // Figure out which asset this is: + const upgradedCurrency = upgradeCurrencyCode({ + allTokens, + currencyInfo: plugin.currencyInfo, + tokenId: spendInfo.tokenId + }) + + const unsafeMakeSpend = plugin.currencyInfo.unsafeMakeSpend ?? false + + if (typeof engine.getMaxSpendable === 'function') { + // Only provide wallet info if currency requires it: + const privateKeys = unsafeMakeSpend ? walletInfo.keys : undefined + + return await engine.getMaxSpendable( + { ...spendInfo, ...upgradedCurrency }, + { privateKeys } + ) + } + + const { networkFeeOption, customNetworkFee } = spendInfo + const balance = engine.getBalance(upgradedCurrency) + + // Copy all the spend targets, setting the amounts to 0 + // but keeping all other information so we can get accurate fees: + const spendTargets = spendInfo.spendTargets.map(spendTarget => { + return { ...spendTarget, nativeAmount: '0' } + }) + + // The range of possible values includes `min`, but not `max`. + function getMax(min: string, max: string): Promise { + const diff = sub(max, min) + if (lte(diff, '1')) { + return Promise.resolve(min) + } + const mid = add(min, div(diff, '2')) + + // Try the average: + spendTargets[0].nativeAmount = mid + + // Only provide wallet info if currency requires it: + const privateKeys = unsafeMakeSpend ? walletInfo.keys : undefined + + return engine + .makeSpend( + { + ...upgradedCurrency, + spendTargets, + networkFeeOption, + customNetworkFee + }, + { privateKeys } + ) + .then(() => getMax(mid, max)) + .catch(() => getMax(min, mid)) + } + + return await getMax('0', add(balance, '1')) +}