@fivebinaries/coin-selection
Advanced tools
Comparing version 0.0.1-beta.2 to 0.0.1-beta.3
@@ -18,2 +18,15 @@ export declare const dummyAddress = "addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp"; | ||
}; | ||
export declare const MIN_UTXO_VALUE = "1000000"; | ||
export declare const CARDANO_PARAMS: { | ||
readonly PROTOCOL_MAGICS: { | ||
readonly mainnet: number; | ||
readonly testnet: number; | ||
}; | ||
readonly NETWORK_IDS: { | ||
readonly mainnet: number; | ||
readonly testnet: number; | ||
}; | ||
readonly MIN_UTXO_VALUE: "1000000"; | ||
readonly MAX_TX_SIZE: 16384; | ||
readonly MAX_VALUE_SIZE: 5000; | ||
}; | ||
export declare const MAX_TOKENS_PER_OUTPUT = 50; |
@@ -0,1 +1,2 @@ | ||
import { NetworkInfo } from '@emurgo/cardano-serialization-lib-nodejs'; | ||
export const dummyAddress = 'addr_test1qz2fxv2umyhttkxyxp8x0dlpdt3k6cwng5pxj3jhsydzer3jcu5d8ps7zex2k2xt3uqxgjqnnj83ws8lhrn648jjxtwq2ytjqp'; | ||
@@ -18,2 +19,18 @@ export const CertificateType = { | ||
}; | ||
export const MIN_UTXO_VALUE = '1000000'; | ||
export const CARDANO_PARAMS = { | ||
PROTOCOL_MAGICS: { | ||
mainnet: NetworkInfo.mainnet().protocol_magic(), | ||
testnet: NetworkInfo.testnet().protocol_magic(), | ||
}, | ||
NETWORK_IDS: { | ||
mainnet: NetworkInfo.mainnet().network_id(), | ||
testnet: NetworkInfo.testnet().network_id(), | ||
}, | ||
MIN_UTXO_VALUE: '1000000', | ||
MAX_TX_SIZE: 16384, | ||
MAX_VALUE_SIZE: 5000, | ||
}; | ||
// https://github.com/vacuumlabs/adalite/blob/d8ba3bb1ff439ae8e02abd99163435a989d97961/app/frontend/wallet/shelley/transaction/constants.ts | ||
// policyId is 28 bytes, assetName max 32 bytes, together with quantity makes | ||
// max token size about 70 bytes, max output size is 4000 => 4000 / 70 ~ 50 | ||
export const MAX_TOKENS_PER_OUTPUT = 50; |
import { ERROR } from '../constants'; | ||
import * as CardanoWasm from '@emurgo/cardano-serialization-lib-browser'; | ||
import { bigNumFromStr, calculateRequiredDeposit, getAssetAmount, getInputCost, getOutputCost, prepareCertificates, prepareChangeOutput, prepareWithdrawals, setMinUtxoValueForOutputs, sortUtxos, getTxBuilder, assetsAmountSatisfied, getInitialUtxoSet, setMaxOutput, getTotalUserOutputsAmount, multiAssetToArray, buildTxInput, buildTxOutput, } from '../utils/common'; | ||
import { bigNumFromStr, calculateRequiredDeposit, getAssetAmount, getOutputCost, prepareCertificates, prepareChangeOutput, prepareWithdrawals, setMinUtxoValueForOutputs, sortUtxos, getTxBuilder, getInitialUtxoSet, setMaxOutput, getTotalUserOutputsAmount, multiAssetToArray, buildTxInput, buildTxOutput, getUnsatisfiedAssets, splitChangeOutput, } from '../utils/common'; | ||
import { CoinSelectionError } from '../utils/errors'; | ||
@@ -8,3 +8,3 @@ export const largestFirst = (utxos, outputs, changeAddress, certificates, withdrawals, accountPubKey, options) => { | ||
const txBuilder = getTxBuilder((_a = options === null || options === void 0 ? void 0 : options.feeParams) === null || _a === void 0 ? void 0 : _a.a); | ||
let usedUtxos = []; | ||
const usedUtxos = []; | ||
let sortedUtxos = sortUtxos(utxos); | ||
@@ -32,13 +32,16 @@ const accountKey = CardanoWasm.Bip32PublicKey.from_bytes(Buffer.from(accountPubKey, 'hex')); | ||
const preparedOutputs = setMinUtxoValueForOutputs(txBuilder, outputs); | ||
const addUtxoToSelection = (utxo) => { | ||
const { input, address, amount } = buildTxInput(utxo); | ||
const fee = txBuilder.fee_for_input(address, input, amount); | ||
txBuilder.add_input(address, input, amount); | ||
usedUtxos.push(utxo); | ||
totalFeesAmount = totalFeesAmount.checked_add(fee); | ||
utxosTotalAmount = utxosTotalAmount.checked_add(bigNumFromStr(getAssetAmount(utxo))); | ||
}; | ||
// set initial utxos set for setMax functionality | ||
const maxOutput = preparedOutputs[outputs.findIndex(o => !!o.setMax)]; | ||
const maxOutputIndex = outputs.findIndex(o => !!o.setMax); | ||
const maxOutput = preparedOutputs[maxOutputIndex]; | ||
const { used, remaining } = getInitialUtxoSet(sortedUtxos, maxOutput); | ||
usedUtxos = used; | ||
sortedUtxos = remaining; | ||
usedUtxos.forEach(utxo => { | ||
// this should really be a function | ||
const { inputFee } = getInputCost(txBuilder, utxo); | ||
totalFeesAmount = totalFeesAmount.checked_add(inputFee); | ||
utxosTotalAmount = utxosTotalAmount.checked_add(bigNumFromStr(getAssetAmount(utxo))); | ||
}); | ||
used.forEach(utxo => addUtxoToSelection(utxo)); | ||
// Calculate fee and minUtxoValue for all external outputs | ||
@@ -49,56 +52,54 @@ const outputsCost = preparedOutputs.map(output => getOutputCost(txBuilder, output)); | ||
totalFeesAmount = totalFeesAmount.checked_add(totalOutputsFee); | ||
let totalUserOutputsAmount = getTotalUserOutputsAmount(preparedOutputs, deposit); | ||
let changeOutput = null; | ||
let sufficientUtxos = false; | ||
let totalUserOutputsAmount = getTotalUserOutputsAmount(preparedOutputs, deposit); | ||
let forceAnotherRound = false; | ||
while (!sufficientUtxos) { | ||
if (maxOutput) { | ||
// reset previously computed maxOutput in order to correctly calculate a potential change output | ||
preparedOutputs[maxOutputIndex] = setMinUtxoValueForOutputs(txBuilder, [ | ||
maxOutput, | ||
])[0]; | ||
} | ||
// Calculate change output | ||
let preparedChangeOutput = prepareChangeOutput(txBuilder, usedUtxos, preparedOutputs, changeAddress, utxosTotalAmount, getTotalUserOutputsAmount(preparedOutputs, deposit), totalFeesAmount); | ||
let singleChangeOutput = prepareChangeOutput(txBuilder, usedUtxos, preparedOutputs, changeAddress, utxosTotalAmount, getTotalUserOutputsAmount(preparedOutputs, deposit), totalFeesAmount); | ||
if (maxOutput) { | ||
// set amount for the max output | ||
const { changeOutput: newChangeOutput } = setMaxOutput(maxOutput, preparedChangeOutput); | ||
// set amount for a max output from a changeOutput calculated above | ||
const { changeOutput: newChangeOutput, maxOutput: newMaxOutput } = setMaxOutput(maxOutput, singleChangeOutput); | ||
// change output may be completely removed if all ADA are consumed by max output | ||
preparedChangeOutput = newChangeOutput; | ||
singleChangeOutput = newChangeOutput; | ||
preparedOutputs[maxOutputIndex] = newMaxOutput; | ||
// recalculate total user outputs amount | ||
totalUserOutputsAmount = getTotalUserOutputsAmount(preparedOutputs, deposit); | ||
} | ||
const changeOutputs = singleChangeOutput | ||
? splitChangeOutput(txBuilder, singleChangeOutput, changeAddress, options === null || options === void 0 ? void 0 : options._maxTokensPerOutput) | ||
: []; | ||
let requiredAmount = totalFeesAmount.checked_add(totalUserOutputsAmount); | ||
if (preparedChangeOutput) { | ||
changeOutputs.forEach(changeOutput => { | ||
// we need to cover amounts and fees for change outputs | ||
requiredAmount = requiredAmount | ||
.checked_add(preparedChangeOutput.output.amount().coin()) | ||
.checked_add(preparedChangeOutput.outputFee); | ||
} | ||
// console.log('----CURRENT UTXO SELECTION ITERATION----'); | ||
// console.log('usedUtxos', usedUtxos); | ||
// console.log( | ||
// 'utxosTotalAmount (ADA amount that needs to be spent (sum of utxos = outputs - fee))', | ||
// utxosTotalAmount.to_str(), | ||
// ); | ||
// console.log( | ||
// 'requiredAmount to cover fees for all inputs, outputs (including additional change output if needed) and output amounts themselves', | ||
// requiredAmount.to_str(), | ||
// ); | ||
// console.log( | ||
// `CHANGE OUTPUT (already included in requiredAmount above): amount: ${ | ||
// preparedChangeOutput?.output.amount | ||
// } fe: ${preparedChangeOutput?.outputFee.to_str()}`, | ||
// ); | ||
// console.log('addAnotherUtxo', addAnotherUtxo); | ||
.checked_add(changeOutput.output.amount().coin()) | ||
.checked_add(changeOutput.outputFee); | ||
}); | ||
// List of tokens for which we don't have enough utxos | ||
const unsatisfiedAssets = getUnsatisfiedAssets(usedUtxos, preparedOutputs); | ||
if (utxosTotalAmount.compare(requiredAmount) >= 0 && | ||
assetsAmountSatisfied(usedUtxos, preparedOutputs) && | ||
unsatisfiedAssets.length === 0 && | ||
usedUtxos.length > 0 && // TODO: force at least 1 utxo, otherwise withdrawal tx is composed without utxo if rewards > tx cost | ||
!forceAnotherRound) { | ||
// we are done. we have enough utxos to cover fees + minUtxoValue for each output. now we can add the cost of the change output to total fees | ||
if (preparedChangeOutput) { | ||
totalFeesAmount = totalFeesAmount.checked_add(preparedChangeOutput.outputFee); | ||
if (changeOutputs.length > 0) { | ||
changeOutputs.forEach(changeOutput => { | ||
totalFeesAmount = totalFeesAmount.checked_add(changeOutput.outputFee); | ||
}); | ||
// set change output | ||
changeOutput = { | ||
changeOutput = changeOutputs.map(change => ({ | ||
isChange: true, | ||
amount: preparedChangeOutput.output.amount().coin().to_str(), | ||
amount: change.output.amount().coin().to_str(), | ||
address: changeAddress, | ||
assets: multiAssetToArray(preparedChangeOutput.output.amount().multiasset()), | ||
}; | ||
assets: multiAssetToArray(change.output.amount().multiasset()), | ||
})); | ||
} | ||
else { | ||
const unspendableChangeAmount = utxosTotalAmount.clamped_sub(totalFeesAmount.checked_add(totalUserOutputsAmount)); | ||
if (sortedUtxos.length > 0) { | ||
@@ -110,6 +111,4 @@ // In current iteration we don't have enough utxo to meet min utxo value for an output, | ||
} | ||
// console.warn( | ||
// `Change output would be inefficient. Burning ${UnspendableChangeAmount.to_str()} as fee`, | ||
// ); | ||
// Since we didn't add a change output we can burn its value + fee we would pay for it. That's equal to initial placeholderChangeOutputAmount | ||
// Change output would be inefficient., we can burn its value + fee we would pay for it | ||
const unspendableChangeAmount = utxosTotalAmount.clamped_sub(totalFeesAmount.checked_add(totalUserOutputsAmount)); | ||
totalFeesAmount = totalFeesAmount.checked_add(unspendableChangeAmount); | ||
@@ -120,13 +119,12 @@ } | ||
else { | ||
if (unsatisfiedAssets.length > 0) { | ||
sortedUtxos = sortUtxos(sortedUtxos, unsatisfiedAssets[0]); | ||
} | ||
else { | ||
sortedUtxos = sortUtxos(sortedUtxos); | ||
} | ||
const utxo = sortedUtxos.shift(); | ||
if (!utxo) | ||
break; | ||
usedUtxos.push(utxo); | ||
const { input, address, amount } = buildTxInput(utxo); | ||
const inputFee = txBuilder.fee_for_input(address, input, amount); | ||
txBuilder.add_input(address, input, amount); | ||
// const { inputFee } = getInputCost(txBuilder, utxo); | ||
// add input fee to total | ||
totalFeesAmount = totalFeesAmount.checked_add(inputFee); | ||
utxosTotalAmount = utxosTotalAmount.checked_add(bigNumFromStr(getAssetAmount(utxo))); | ||
addUtxoToSelection(utxo); | ||
forceAnotherRound = false; | ||
@@ -145,4 +143,6 @@ } | ||
if (changeOutput) { | ||
finalOutputs.push(changeOutput); | ||
txBuilder.add_output(buildTxOutput(changeOutput)); | ||
changeOutput.forEach(change => { | ||
finalOutputs.push(change); | ||
txBuilder.add_output(buildTxOutput(change)); | ||
}); | ||
} | ||
@@ -154,11 +154,3 @@ txBuilder.set_fee(totalFeesAmount); | ||
const totalSpent = totalUserOutputsAmount.checked_add(totalFeesAmount); | ||
// console.log('FINAL RESULT START=========='); | ||
// console.log('inputs', usedUtxos); | ||
// console.log('outputs', finalOutputs); | ||
// console.log('totalOutputAmount', totalOutputAmount.to_str()); | ||
// console.log('utxosTotalAmount', utxosTotalAmount.to_str()); | ||
// console.log('totalSpent', totalSpent.to_str()); | ||
// console.log('deposit', deposit.to_str()); | ||
// console.log('withdrawal', totalWithdrawal.to_str()); | ||
// console.log('FINAL RESULT END'); | ||
// Set max property with the value of an output which has setMax=true | ||
let max; | ||
@@ -178,5 +170,5 @@ if (maxOutput) { | ||
withdrawal: totalWithdrawal.to_str(), | ||
tx: { body: txBodyHex, hash: txHash }, | ||
tx: { body: txBodyHex, hash: txHash, size: txBuilder.full_size() }, | ||
max, | ||
}; | ||
}; |
@@ -64,2 +64,3 @@ import * as CardanoWasm from '@emurgo/cardano-serialization-lib-browser'; | ||
hash: string; | ||
size: number; | ||
}; | ||
@@ -104,2 +105,3 @@ inputs: Utxo[]; | ||
}; | ||
_maxTokensPerOutput?: number; | ||
} |
import * as CardanoWasm from '@emurgo/cardano-serialization-lib-browser'; | ||
import { CARDANO_PARAMS } from '../constants'; | ||
import { Certificate, Output, Utxo, Withdrawal, OutputCost, UserOutput, Asset } from '../types/types'; | ||
export declare const CARDANO: { | ||
readonly PROTOCOL_MAGICS: { | ||
readonly mainnet: 764824073; | ||
readonly testnet: 1097911063; | ||
}; | ||
readonly NETWORK_IDS: { | ||
readonly mainnet: 1; | ||
readonly testnet: 0; | ||
}; | ||
readonly ADDRESS_TYPE: { | ||
readonly Base: 0; | ||
readonly Pointer: 4; | ||
readonly Enterprise: 6; | ||
readonly Byron: 8; | ||
readonly Reward: 14; | ||
}; | ||
readonly CERTIFICATE_TYPE: { | ||
readonly StakeRegistration: 0; | ||
readonly StakeDeregistration: 1; | ||
readonly StakeDelegation: 2; | ||
readonly StakePoolRegistration: 3; | ||
}; | ||
}; | ||
export declare const bigNumFromStr: (num: string) => CardanoWasm.BigNum; | ||
export declare const getProtocolMagic: (tesnet?: boolean | undefined) => typeof CARDANO.PROTOCOL_MAGICS['mainnet'] | typeof CARDANO.PROTOCOL_MAGICS['testnet']; | ||
export declare const getNetworkId: (testnet?: boolean | undefined) => typeof CARDANO.NETWORK_IDS['mainnet'] | typeof CARDANO.NETWORK_IDS['testnet']; | ||
export declare const getProtocolMagic: (tesnet?: boolean | undefined) => typeof CARDANO_PARAMS.PROTOCOL_MAGICS['mainnet'] | typeof CARDANO_PARAMS.PROTOCOL_MAGICS['testnet']; | ||
export declare const getNetworkId: (testnet?: boolean | undefined) => typeof CARDANO_PARAMS.NETWORK_IDS['mainnet'] | typeof CARDANO_PARAMS.NETWORK_IDS['testnet']; | ||
export declare const parseAsset: (hex: string) => { | ||
@@ -45,6 +23,2 @@ policyId: string; | ||
}; | ||
export declare const getInputCost: (txBuilder: CardanoWasm.TransactionBuilder, utxo: Utxo) => { | ||
input: CardanoWasm.TransactionInput; | ||
inputFee: CardanoWasm.BigNum; | ||
}; | ||
export declare const buildTxOutput: (output: Output) => CardanoWasm.TransactionOutput; | ||
@@ -56,5 +30,6 @@ export declare const getOutputCost: (txBuilder: CardanoWasm.TransactionBuilder, output: Output) => OutputCost; | ||
export declare const setMinUtxoValueForOutputs: (txBuilder: CardanoWasm.TransactionBuilder, outputs: UserOutput[]) => UserOutput[]; | ||
export declare const splitChangeOutput: (txBuilder: CardanoWasm.TransactionBuilder, singleChangeOutput: OutputCost, changeAddress: string, maxTokensPerOutput?: number) => OutputCost[]; | ||
export declare const prepareChangeOutput: (txBuilder: CardanoWasm.TransactionBuilder, usedUtxos: Utxo[], preparedOutputs: Output[], changeAddress: string, utxosTotalAmount: CardanoWasm.BigNum, totalOutputAmount: CardanoWasm.BigNum, totalFeesAmount: CardanoWasm.BigNum) => OutputCost | null; | ||
export declare const getTxBuilder: (a?: string) => CardanoWasm.TransactionBuilder; | ||
export declare const assetsAmountSatisfied: (utxos: Utxo[], outputs: Output[]) => boolean; | ||
export declare const getUnsatisfiedAssets: (utxos: Utxo[], outputs: Output[]) => string[]; | ||
export declare const getInitialUtxoSet: (utxos: Utxo[], maxOutput: UserOutput | undefined) => { | ||
@@ -61,0 +36,0 @@ used: Utxo[]; |
import * as CardanoWasm from '@emurgo/cardano-serialization-lib-browser'; | ||
import { CertificateType, dummyAddress, ERROR, MIN_UTXO_VALUE, } from '../constants'; | ||
import { CARDANO_PARAMS, CertificateType, dummyAddress, ERROR, MAX_TOKENS_PER_OUTPUT, } from '../constants'; | ||
import { CoinSelectionError } from './errors'; | ||
export const CARDANO = { | ||
PROTOCOL_MAGICS: { | ||
mainnet: 764824073, | ||
testnet: 1097911063, | ||
}, | ||
NETWORK_IDS: { | ||
mainnet: 1, | ||
testnet: 0, | ||
}, | ||
ADDRESS_TYPE: { | ||
Base: 0, | ||
Pointer: 4, | ||
Enterprise: 6, | ||
Byron: 8, | ||
Reward: 14, | ||
}, | ||
CERTIFICATE_TYPE: { | ||
StakeRegistration: 0, | ||
StakeDeregistration: 1, | ||
StakeDelegation: 2, | ||
StakePoolRegistration: 3, | ||
}, | ||
}; | ||
export const bigNumFromStr = (num) => CardanoWasm.BigNum.from_str(num); | ||
export const getProtocolMagic = (tesnet) => tesnet ? CARDANO.PROTOCOL_MAGICS.testnet : CARDANO.PROTOCOL_MAGICS.mainnet; | ||
export const getNetworkId = (testnet) => testnet ? CARDANO.NETWORK_IDS.testnet : CARDANO.NETWORK_IDS.mainnet; | ||
export const getProtocolMagic = (tesnet) => tesnet | ||
? CARDANO_PARAMS.PROTOCOL_MAGICS.testnet | ||
: CARDANO_PARAMS.PROTOCOL_MAGICS.mainnet; | ||
export const getNetworkId = (testnet) => testnet | ||
? CARDANO_PARAMS.NETWORK_IDS.testnet | ||
: CARDANO_PARAMS.NETWORK_IDS.mainnet; | ||
export const parseAsset = (hex) => { | ||
@@ -77,3 +58,3 @@ const policyIdSize = 56; | ||
export const getMinAdaRequired = (multiAsset) => { | ||
const minUtxoValue = bigNumFromStr(MIN_UTXO_VALUE); | ||
const minUtxoValue = bigNumFromStr(CARDANO_PARAMS.MIN_UTXO_VALUE); | ||
if (!multiAsset) | ||
@@ -106,14 +87,5 @@ return minUtxoValue; | ||
}; | ||
export const getInputCost = (txBuilder, utxo) => { | ||
// Calculate additional fee required to add utxo to a transaction | ||
const { input, address, amount } = buildTxInput(utxo); | ||
const inputFee = txBuilder.fee_for_input(address, input, amount); // does utxoAddr make sense here? | ||
return { | ||
input: input, | ||
inputFee, | ||
}; | ||
}; | ||
export const buildTxOutput = (output) => { | ||
var _a; | ||
const minUtxoValue = bigNumFromStr(MIN_UTXO_VALUE); | ||
const minUtxoValue = bigNumFromStr(CARDANO_PARAMS.MIN_UTXO_VALUE); | ||
// this will set required minUtxoValue even if output.amount === 0 | ||
@@ -137,3 +109,3 @@ const outputAmount = output.amount && minUtxoValue.compare(bigNumFromStr(output.amount)) < 0 | ||
export const getOutputCost = (txBuilder, output) => { | ||
const minUtxoValue = bigNumFromStr(MIN_UTXO_VALUE); | ||
const minUtxoValue = bigNumFromStr(CARDANO_PARAMS.MIN_UTXO_VALUE); | ||
const txOutput = buildTxOutput(output); | ||
@@ -215,2 +187,42 @@ const outputFee = txBuilder.fee_for_output(txOutput); | ||
}; | ||
export const splitChangeOutput = (txBuilder, singleChangeOutput, changeAddress, maxTokensPerOutput = MAX_TOKENS_PER_OUTPUT) => { | ||
if (!singleChangeOutput.output.amount().multiasset()) { | ||
return [singleChangeOutput]; | ||
} | ||
let lovelaceAvailable = singleChangeOutput.output | ||
.amount() | ||
.coin() | ||
.checked_add(txBuilder.fee_for_output(singleChangeOutput.output)); | ||
const allAssets = multiAssetToArray(singleChangeOutput.output.amount().multiasset()); | ||
const nAssetBundles = Math.ceil(allAssets.length / maxTokensPerOutput); | ||
const changeOutputs = []; | ||
// split change output to multiple outputs, where each bundle has maximum of maxTokensPerOutput assets | ||
for (let i = 0; i < nAssetBundles; i++) { | ||
const assetsBundle = allAssets.slice(i * maxTokensPerOutput, (i + 1) * maxTokensPerOutput); | ||
const minAdaRequired = getMinAdaRequired(buildMultiAsset(assetsBundle)); | ||
changeOutputs.push({ | ||
isChange: true, | ||
address: changeAddress, | ||
amount: minAdaRequired.to_str(), | ||
assets: assetsBundle, | ||
}); | ||
} | ||
const changeOutputsCost = changeOutputs.map((partialChange, i) => { | ||
let changeOutputCost = getOutputCost(txBuilder, partialChange); | ||
lovelaceAvailable = lovelaceAvailable.clamped_sub(bigNumFromStr(partialChange.amount).checked_add(changeOutputCost.outputFee)); | ||
if (i === changeOutputs.length - 1) { | ||
// add all unused ADA to the last change output | ||
let changeOutputAmount = lovelaceAvailable.checked_add(bigNumFromStr(partialChange.amount)); | ||
if (changeOutputAmount.compare(changeOutputCost.minOutputAmount) < 0) { | ||
// computed change amount would be below minUtxoValue | ||
// set change output amount to met minimum requirements for minUtxoValue | ||
changeOutputAmount = changeOutputCost.minOutputAmount; | ||
} | ||
partialChange.amount = changeOutputAmount.to_str(); | ||
changeOutputCost = getOutputCost(txBuilder, partialChange); | ||
} | ||
return changeOutputCost; | ||
}); | ||
return changeOutputsCost; | ||
}; | ||
export const prepareChangeOutput = (txBuilder, usedUtxos, preparedOutputs, changeAddress, utxosTotalAmount, totalOutputAmount, totalFeesAmount) => { | ||
@@ -275,9 +287,9 @@ // change output amount should be lowered by the cost of the change output (fee + minUtxoVal) | ||
}; | ||
export const getTxBuilder = (a = '44') => CardanoWasm.TransactionBuilder.new(CardanoWasm.LinearFee.new(bigNumFromStr(a), bigNumFromStr('155381')), bigNumFromStr(MIN_UTXO_VALUE), | ||
export const getTxBuilder = (a = '44') => CardanoWasm.TransactionBuilder.new(CardanoWasm.LinearFee.new(bigNumFromStr(a), bigNumFromStr('155381')), bigNumFromStr(CARDANO_PARAMS.MIN_UTXO_VALUE), | ||
// pool deposit | ||
bigNumFromStr('500000000'), | ||
// key deposit | ||
bigNumFromStr('2000000')); | ||
export const assetsAmountSatisfied = (utxos, outputs) => { | ||
let assetsAmountSatisfied = true; | ||
bigNumFromStr('2000000'), CARDANO_PARAMS.MAX_VALUE_SIZE, CARDANO_PARAMS.MAX_TX_SIZE); | ||
export const getUnsatisfiedAssets = (utxos, outputs) => { | ||
const assets = []; | ||
outputs.forEach(output => { | ||
@@ -288,7 +300,7 @@ if (output.assets.length > 0) { | ||
if (assetAmountInUtxos.compare(bigNumFromStr(asset.quantity)) < 0) { | ||
assetsAmountSatisfied = false; | ||
assets.push(asset.unit); | ||
} | ||
} | ||
}); | ||
return assetsAmountSatisfied; | ||
return assets; | ||
}; | ||
@@ -295,0 +307,0 @@ export const getInitialUtxoSet = (utxos, maxOutput) => { |
{ | ||
"name": "@fivebinaries/coin-selection", | ||
"version": "0.0.1-beta.2", | ||
"version": "0.0.1-beta.3", | ||
"description": "", | ||
@@ -24,3 +24,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"@emurgo/cardano-serialization-lib-nodejs": "^8.1.0", | ||
"@emurgo/cardano-serialization-lib-nodejs": "^9.1.0", | ||
"@swc-node/jest": "^1.3.1", | ||
@@ -48,4 +48,4 @@ "@types/jest": "^26.0.24", | ||
"dependencies": { | ||
"@emurgo/cardano-serialization-lib-browser": "^8.1.0" | ||
"@emurgo/cardano-serialization-lib-browser": "^9.1.0" | ||
} | ||
} |
48678
23
1000
+ Added@emurgo/cardano-serialization-lib-browser@9.1.4(transitive)
- Removed@emurgo/cardano-serialization-lib-browser@8.1.0(transitive)