diff --git a/packages/module/src/common/helpers/index.ts b/packages/module/src/common/helpers/index.ts index c71746fe1..574918c2f 100644 --- a/packages/module/src/common/helpers/index.ts +++ b/packages/module/src/common/helpers/index.ts @@ -1,4 +1,2 @@ export * from './generateNonce'; -export * from './mergeSignatures'; export * from './readPlutusData'; -export * from './readTransaction'; diff --git a/packages/module/src/common/helpers/readTransaction.ts b/packages/module/src/common/helpers/readTransaction.ts deleted file mode 100644 index 71a1e00fb..000000000 --- a/packages/module/src/common/helpers/readTransaction.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { csl } from '@mesh/core'; -import { deserializeTx } from '@mesh/common/utils'; - -export const readTransaction = (tx: string): csl.TransactionJSON => { - return deserializeTx(tx).to_js_value(); -}; diff --git a/packages/module/src/core/CPS-009.ts b/packages/module/src/core/CPS0009.ts similarity index 96% rename from packages/module/src/core/CPS-009.ts rename to packages/module/src/core/CPS0009.ts index 2cd0d9c22..cc03c8f06 100644 --- a/packages/module/src/core/CPS-009.ts +++ b/packages/module/src/core/CPS0009.ts @@ -1,130 +1,130 @@ -import type { Quantity, UTxO, Unit } from '@mesh/common/types'; - -export const selectUtxos = ( - inputs: UTxO[], - requiredAssets: Map, - threshold: Quantity -): UTxO[] => { - const totalRequiredAssets = new Map(requiredAssets); - totalRequiredAssets.set( - 'lovelace', - String(Number(totalRequiredAssets.get('lovelace')) + Number(threshold)) - ); - const utxoMap = new Map(); - for (let i = 0; i < inputs.length; i++) { - utxoMap.set(i, inputs[i]); - } - const selectedInputs = new Set(); - const onlyLovelace = new Set(); - const singletons = new Set(); - const pairs = new Set(); - const rest = new Set(); - for (let i = 0; i < inputs.length; i++) { - switch (inputs[i].output.amount.length) { - case 1: { - onlyLovelace.add(i); - break; - } - case 2: { - singletons.add(i); - break; - } - case 3: { - pairs.add(i); - break; - } - default: { - rest.add(i); - break; - } - } - } - - const addUtxoWithAssetAmount = ( - inputIndex: number, - assetUnit: string, - set: Set - ) => { - const utxo = utxoMap.get(inputIndex); - if (!utxo) return; - - const amount = getAssetAmount(utxo, assetUnit); - if (Number(amount) > 0) { - selectedInputs.add(inputIndex); - set.delete(inputIndex); - for (const asset of utxo.output.amount) { - totalRequiredAssets.set( - asset.unit, - String( - Number(totalRequiredAssets.get(asset.unit)) - Number(asset.quantity) - ) - ); - } - } - }; - - for (const assetUnit of totalRequiredAssets.keys()) { - if (assetUnit == 'lovelace') continue; - for (const inputIndex of singletons) { - const assetRequired = totalRequiredAssets.get(assetUnit); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, assetUnit, singletons); - } - - for (const inputIndex of pairs) { - const assetRequired = totalRequiredAssets.get(assetUnit); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, assetUnit, pairs); - } - - for (const inputIndex of rest) { - const assetRequired = totalRequiredAssets.get(assetUnit); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, assetUnit, rest); - } - } - - for (const inputIndex of onlyLovelace) { - const assetRequired = totalRequiredAssets.get('lovelace'); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, 'lovelace', onlyLovelace); - } - - for (const inputIndex of singletons) { - const assetRequired = totalRequiredAssets.get('lovelace'); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, 'lovelace', singletons); - } - - for (const inputIndex of pairs) { - const assetRequired = totalRequiredAssets.get('lovelace'); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, 'lovelace', pairs); - } - - for (const inputIndex of rest) { - const assetRequired = totalRequiredAssets.get('lovelace'); - if (!assetRequired || Number(assetRequired) <= 0) break; - addUtxoWithAssetAmount(inputIndex, 'lovelace', rest); - } - - for (const assetUnit of totalRequiredAssets.keys()) { - if (Number(totalRequiredAssets.get(assetUnit)) > 0) return []; - } - - const selectedUtxos: UTxO[] = []; - for (const inputIndex of selectedInputs) { - const utxo = utxoMap.get(inputIndex); - if (utxo) { - selectedUtxos.push(utxo); - } - } - return selectedUtxos; -}; - -const getAssetAmount = (utxo: UTxO, assetUnit: string): string => { - for (const utxoAsset of utxo.output.amount) { - if (utxoAsset.unit == assetUnit) return utxoAsset.quantity; - } - return '0'; -}; +import type { Quantity, UTxO, Unit } from '@mesh/common/types'; + +export const selectUtxos = ( + inputs: UTxO[], + requiredAssets: Map, + threshold: Quantity +): UTxO[] => { + const totalRequiredAssets = new Map(requiredAssets); + totalRequiredAssets.set( + 'lovelace', + String(Number(totalRequiredAssets.get('lovelace')) + Number(threshold)) + ); + const utxoMap = new Map(); + for (let i = 0; i < inputs.length; i++) { + utxoMap.set(i, inputs[i]); + } + const selectedInputs = new Set(); + const onlyLovelace = new Set(); + const singletons = new Set(); + const pairs = new Set(); + const rest = new Set(); + for (let i = 0; i < inputs.length; i++) { + switch (inputs[i].output.amount.length) { + case 1: { + onlyLovelace.add(i); + break; + } + case 2: { + singletons.add(i); + break; + } + case 3: { + pairs.add(i); + break; + } + default: { + rest.add(i); + break; + } + } + } + + const addUtxoWithAssetAmount = ( + inputIndex: number, + assetUnit: string, + set: Set + ) => { + const utxo = utxoMap.get(inputIndex); + if (!utxo) return; + + const amount = getAssetAmount(utxo, assetUnit); + if (Number(amount) > 0) { + selectedInputs.add(inputIndex); + set.delete(inputIndex); + for (const asset of utxo.output.amount) { + totalRequiredAssets.set( + asset.unit, + String( + Number(totalRequiredAssets.get(asset.unit)) - Number(asset.quantity) + ) + ); + } + } + }; + + for (const assetUnit of totalRequiredAssets.keys()) { + if (assetUnit == 'lovelace') continue; + for (const inputIndex of singletons) { + const assetRequired = totalRequiredAssets.get(assetUnit); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, assetUnit, singletons); + } + + for (const inputIndex of pairs) { + const assetRequired = totalRequiredAssets.get(assetUnit); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, assetUnit, pairs); + } + + for (const inputIndex of rest) { + const assetRequired = totalRequiredAssets.get(assetUnit); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, assetUnit, rest); + } + } + + for (const inputIndex of onlyLovelace) { + const assetRequired = totalRequiredAssets.get('lovelace'); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, 'lovelace', onlyLovelace); + } + + for (const inputIndex of singletons) { + const assetRequired = totalRequiredAssets.get('lovelace'); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, 'lovelace', singletons); + } + + for (const inputIndex of pairs) { + const assetRequired = totalRequiredAssets.get('lovelace'); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, 'lovelace', pairs); + } + + for (const inputIndex of rest) { + const assetRequired = totalRequiredAssets.get('lovelace'); + if (!assetRequired || Number(assetRequired) <= 0) break; + addUtxoWithAssetAmount(inputIndex, 'lovelace', rest); + } + + for (const assetUnit of totalRequiredAssets.keys()) { + if (Number(totalRequiredAssets.get(assetUnit)) > 0) return []; + } + + const selectedUtxos: UTxO[] = []; + for (const inputIndex of selectedInputs) { + const utxo = utxoMap.get(inputIndex); + if (utxo) { + selectedUtxos.push(utxo); + } + } + return selectedUtxos; +}; + +const getAssetAmount = (utxo: UTxO, assetUnit: string): string => { + for (const utxoAsset of utxo.output.amount) { + if (utxoAsset.unit == assetUnit) return utxoAsset.quantity; + } + return '0'; +}; diff --git a/packages/module/src/core/index.ts b/packages/module/src/core/index.ts index 3b78e74df..0f4a13eab 100644 --- a/packages/module/src/core/index.ts +++ b/packages/module/src/core/index.ts @@ -6,4 +6,5 @@ export * from './CIP27'; export * from './CIP1852'; export * from './CIP1853'; export * from './CIP1855'; +export * from './CPS0009'; export * from './CSL'; diff --git a/packages/module/src/index.ts b/packages/module/src/index.ts index 3a857be49..450c2d8ac 100644 --- a/packages/module/src/index.ts +++ b/packages/module/src/index.ts @@ -1,10 +1,6 @@ export * from './common/contracts'; export * from './common/types'; -export { - generateNonce, - readPlutusData, - readTransaction, -} from './common/helpers'; +export { generateNonce, readPlutusData } from './common/helpers'; export * from './common/utils/resolver'; export * from './common/utils/parser'; export * from './core/CIP2'; diff --git a/packages/module/src/serializer/index.ts b/packages/module/src/serializer/index.ts new file mode 100644 index 000000000..7f69aae9d --- /dev/null +++ b/packages/module/src/serializer/index.ts @@ -0,0 +1 @@ +export * from './signatures'; diff --git a/packages/module/src/common/helpers/mergeSignatures.ts b/packages/module/src/serializer/signatures.ts similarity index 82% rename from packages/module/src/common/helpers/mergeSignatures.ts rename to packages/module/src/serializer/signatures.ts index 696b81d96..25e43aa34 100644 --- a/packages/module/src/common/helpers/mergeSignatures.ts +++ b/packages/module/src/serializer/signatures.ts @@ -1,10 +1,9 @@ import { csl } from '@mesh/core'; -import type { - TransactionWitnessSet, Vkeywitnesses, -} from '@mesh/core'; +import type { TransactionWitnessSet, Vkeywitnesses } from '@mesh/core'; export const mergeSignatures = ( - txWitnessSet: TransactionWitnessSet, newSignatures: Vkeywitnesses, + txWitnessSet: TransactionWitnessSet, + newSignatures: Vkeywitnesses ) => { const txSignatures = txWitnessSet.vkeys(); diff --git a/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts b/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts index fa6b6f58f..f48132dce 100644 --- a/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts +++ b/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts @@ -39,7 +39,7 @@ import { Certificate, TxInParameter, } from './type'; -import { selectUtxos } from '@mesh/core/CPS-009'; +import { selectUtxos } from '@mesh/core'; import JSONbig from 'json-bigint'; export class MeshTxBuilderCore { diff --git a/packages/module/src/wallet/app.service.ts b/packages/module/src/wallet/app.service.ts index 7015d04ee..c0cdcdb3b 100644 --- a/packages/module/src/wallet/app.service.ts +++ b/packages/module/src/wallet/app.service.ts @@ -6,7 +6,7 @@ import { ISigner, ISubmitter, } from '@mesh/common/contracts'; -import { mergeSignatures } from '@mesh/common/helpers'; +import { mergeSignatures } from '@mesh/serializer'; import { deserializeTx, toAddress, diff --git a/packages/module/src/wallet/browser.service.ts b/packages/module/src/wallet/browser.service.ts index c9dcb85d1..1b24aab9b 100644 --- a/packages/module/src/wallet/browser.service.ts +++ b/packages/module/src/wallet/browser.service.ts @@ -5,7 +5,7 @@ import { SUPPORTED_WALLETS, } from '@mesh/common/constants'; import { IInitiator, ISigner, ISubmitter } from '@mesh/common/contracts'; -import { mergeSignatures } from '@mesh/common/helpers'; +import { mergeSignatures } from '@mesh/serializer'; import { deserializeAddress, deserializeTx,