@midnight-ntwrk/wallet-sdk-capabilities 1.0.0 → 3.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ import { CounterOffer, TransactionCostModel } from './CounterOffer.js';
2
+ import { CoinRecipe, Imbalances, TokenType, TokenValue } from './Imbalances.js';
3
+ export declare class InsufficientFundsError extends Error {
4
+ readonly tokenType: TokenType;
5
+ constructor(tokenType: TokenType);
6
+ }
7
+ export interface BalanceRecipe<TInput extends CoinRecipe, TOutput extends CoinRecipe> {
8
+ inputs: TInput[];
9
+ outputs: TOutput[];
10
+ }
11
+ export type CoinSelection<TInput extends CoinRecipe> = (coins: readonly TInput[], tokenType: TokenType, amountNeeded: TokenValue, costModel: TransactionCostModel) => TInput | undefined;
12
+ export type BalanceRecipeProps<TInput extends CoinRecipe, TOutput extends CoinRecipe> = {
13
+ coins: TInput[];
14
+ initialImbalances: Imbalances;
15
+ transactionCostModel: TransactionCostModel;
16
+ feeTokenType: string;
17
+ createOutput: (coin: CoinRecipe) => TOutput;
18
+ isCoinEqual: (a: TInput, b: TInput) => boolean;
19
+ coinSelection?: CoinSelection<TInput> | undefined;
20
+ targetImbalances?: Imbalances;
21
+ };
22
+ export declare const getBalanceRecipe: <TInput extends CoinRecipe, TOutput extends CoinRecipe>({ coins, initialImbalances, transactionCostModel, feeTokenType, createOutput, coinSelection, isCoinEqual, targetImbalances, }: BalanceRecipeProps<TInput, TOutput>) => BalanceRecipe<TInput, TOutput>;
23
+ export declare const createCounterOffer: <TInput extends CoinRecipe, TOutput extends CoinRecipe>(coins: TInput[], initialImbalances: Imbalances, transactionCostModel: TransactionCostModel, feeTokenType: string, coinSelection: CoinSelection<TInput>, createOutput: (coin: CoinRecipe) => TOutput, isCoinEqual: (a: TInput, b: TInput) => boolean, targetImbalances?: Imbalances) => CounterOffer<TInput, TOutput>;
24
+ export declare const chooseCoin: <TInput extends CoinRecipe>(coins: readonly TInput[], tokenType: TokenType) => TInput | undefined;
@@ -0,0 +1,68 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { CounterOffer } from './CounterOffer.js';
14
+ export class InsufficientFundsError extends Error {
15
+ tokenType;
16
+ constructor(tokenType) {
17
+ super(`Insufficient Funds: could not balance ${tokenType}`);
18
+ this.tokenType = tokenType;
19
+ }
20
+ }
21
+ export const getBalanceRecipe = ({ coins, initialImbalances, transactionCostModel, feeTokenType, createOutput, coinSelection, isCoinEqual, targetImbalances, }) => {
22
+ const counterOffer = createCounterOffer(coins, initialImbalances, transactionCostModel, feeTokenType, coinSelection ?? chooseCoin, createOutput, isCoinEqual, targetImbalances);
23
+ return {
24
+ inputs: counterOffer.inputs,
25
+ outputs: counterOffer.outputs,
26
+ };
27
+ };
28
+ export const createCounterOffer = (coins, initialImbalances, transactionCostModel, feeTokenType, coinSelection, createOutput, isCoinEqual, targetImbalances = new Map()) => {
29
+ const counterOffer = new CounterOffer(initialImbalances, transactionCostModel, feeTokenType, targetImbalances);
30
+ let imbalance;
31
+ while ((imbalance = counterOffer.findNonNativeImbalance())) {
32
+ coins = doBalance(imbalance, coins, counterOffer, coinSelection, createOutput, isCoinEqual);
33
+ }
34
+ while ((imbalance = counterOffer.findNativeImbalance())) {
35
+ coins = doBalance(imbalance, coins, counterOffer, coinSelection, createOutput, isCoinEqual);
36
+ }
37
+ return counterOffer;
38
+ };
39
+ const doBalance = (imbalance, coins, counterOffer, coinSelection, createOutput, isCoinEqual) => {
40
+ const [tokenType, imbalanceAmount] = imbalance;
41
+ const shouldAddOutput = (tokenType === counterOffer.feeTokenType &&
42
+ imbalanceAmount >=
43
+ counterOffer.getTargetImbalance(counterOffer.feeTokenType) +
44
+ counterOffer.transactionCostModel.outputFeeOverhead) ||
45
+ (tokenType !== counterOffer.feeTokenType && imbalanceAmount > counterOffer.getTargetImbalance(tokenType));
46
+ if (shouldAddOutput) {
47
+ const output = createOutput({
48
+ type: tokenType,
49
+ value: imbalanceAmount - counterOffer.getTargetImbalance(tokenType),
50
+ });
51
+ counterOffer.addOutput(output);
52
+ }
53
+ else {
54
+ const coin = coinSelection(coins, tokenType, imbalanceAmount, counterOffer.transactionCostModel);
55
+ if (typeof coin === 'undefined') {
56
+ throw new InsufficientFundsError(tokenType);
57
+ }
58
+ counterOffer.addInput(coin);
59
+ coins = coins.filter((c) => !isCoinEqual(c, coin));
60
+ }
61
+ return coins;
62
+ };
63
+ export const chooseCoin = (coins, tokenType) => {
64
+ return coins
65
+ .filter((coin) => coin.type === tokenType)
66
+ .sort((a, b) => Number(a.value - b.value))
67
+ .at(0);
68
+ };
@@ -0,0 +1,19 @@
1
+ import { CoinRecipe, Imbalance, Imbalances, TokenType } from './Imbalances.js';
2
+ export interface TransactionCostModel {
3
+ inputFeeOverhead: bigint;
4
+ outputFeeOverhead: bigint;
5
+ }
6
+ export declare class CounterOffer<TInput extends CoinRecipe, TOutput extends CoinRecipe> {
7
+ readonly imbalances: Imbalances;
8
+ readonly transactionCostModel: TransactionCostModel;
9
+ readonly feeTokenType: string;
10
+ readonly inputs: TInput[];
11
+ readonly outputs: TOutput[];
12
+ readonly targetImbalances: Imbalances;
13
+ constructor(imbalances: Imbalances, transactionCostModel: TransactionCostModel, feeTokenType: string, targetImbalances: Imbalances);
14
+ getTargetImbalance(tokenType: TokenType): bigint;
15
+ findNonNativeImbalance(): Imbalance | undefined;
16
+ findNativeImbalance(): Imbalance | undefined;
17
+ addInput(input: TInput): void;
18
+ addOutput(output: TOutput): void;
19
+ }
@@ -0,0 +1,65 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ import { Imbalances } from './Imbalances.js';
14
+ export class CounterOffer {
15
+ imbalances;
16
+ transactionCostModel;
17
+ feeTokenType;
18
+ inputs;
19
+ outputs;
20
+ targetImbalances;
21
+ constructor(imbalances, transactionCostModel, feeTokenType, targetImbalances) {
22
+ this.imbalances = Imbalances.ensureZerosFor(imbalances, Imbalances.typeSet(targetImbalances));
23
+ this.transactionCostModel = transactionCostModel;
24
+ this.feeTokenType = feeTokenType;
25
+ this.inputs = [];
26
+ this.outputs = [];
27
+ this.targetImbalances = targetImbalances;
28
+ }
29
+ getTargetImbalance(tokenType) {
30
+ return this.targetImbalances.get(tokenType) ?? 0n;
31
+ }
32
+ findNonNativeImbalance() {
33
+ return Array.from(this.imbalances.entries())
34
+ .filter(([tokenType]) => tokenType !== this.feeTokenType)
35
+ .find(([tokenType, value]) => value !== this.getTargetImbalance(tokenType));
36
+ }
37
+ findNativeImbalance() {
38
+ if (!this.feeTokenType) {
39
+ return undefined;
40
+ }
41
+ const nativeImbalance = this.imbalances.get(this.feeTokenType);
42
+ if (nativeImbalance !== undefined && nativeImbalance !== this.getTargetImbalance(this.feeTokenType)) {
43
+ return [this.feeTokenType, nativeImbalance];
44
+ }
45
+ return undefined;
46
+ }
47
+ addInput(input) {
48
+ this.inputs.push(input);
49
+ const imbalance = this.imbalances.get(input.type) || 0n;
50
+ this.imbalances.set(input.type, imbalance + input.value);
51
+ const nativeImbalance = this.imbalances.get(this.feeTokenType) || 0n;
52
+ this.imbalances.set(this.feeTokenType, nativeImbalance - this.transactionCostModel.inputFeeOverhead);
53
+ }
54
+ addOutput(output) {
55
+ const imbalance = this.imbalances.get(output.type) || 0n;
56
+ const subtractFee = output.type === this.feeTokenType ? this.transactionCostModel.outputFeeOverhead : 0n;
57
+ const absoluteCoinValue = output.value < 0n ? -output.value : output.value;
58
+ this.outputs.push({ ...output, type: output.type, value: absoluteCoinValue - subtractFee });
59
+ this.imbalances.set(output.type, imbalance - absoluteCoinValue);
60
+ if (output.type !== this.feeTokenType) {
61
+ const nativeImbalance = this.imbalances.get(this.feeTokenType) || 0n;
62
+ this.imbalances.set(this.feeTokenType, nativeImbalance - this.transactionCostModel.outputFeeOverhead);
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,19 @@
1
+ export type TokenType = string;
2
+ export type TokenValue = bigint;
3
+ export interface CoinRecipe {
4
+ type: TokenType;
5
+ value: TokenValue;
6
+ }
7
+ export type Imbalance = [TokenType, TokenValue];
8
+ export type Imbalances = Map<TokenType, TokenValue>;
9
+ export declare const Imbalances: {
10
+ empty: () => Imbalances;
11
+ fromEntry: (tokenType: TokenType, value: bigint) => Imbalances;
12
+ fromEntries: (entries: Iterable<readonly [TokenType, bigint]>) => Imbalances;
13
+ fromMap: (map: Map<TokenType, bigint>) => Imbalances;
14
+ fromMaybeMap: (map: Map<TokenType, bigint> | undefined) => Imbalances;
15
+ getValue: (map: Imbalances, tokenType: TokenType) => bigint;
16
+ typeSet: (map: Imbalances) => Set<TokenType>;
17
+ ensureZerosFor(map: Imbalances, types: Iterable<TokenType>): Imbalances;
18
+ merge: (a: Imbalances, b: Imbalances) => Imbalances;
19
+ };
@@ -0,0 +1,48 @@
1
+ export const Imbalances = new (class {
2
+ empty = () => {
3
+ return new Map();
4
+ };
5
+ fromEntry = (tokenType, value) => {
6
+ return new Map([[tokenType, value]]);
7
+ };
8
+ fromEntries = (entries) => {
9
+ const out = new Map();
10
+ for (const [tokenType, value] of entries) {
11
+ const existingValue = this.getValue(out, tokenType);
12
+ out.set(tokenType, value + existingValue);
13
+ }
14
+ return out;
15
+ };
16
+ fromMap = (map) => {
17
+ return this.fromEntries(map.entries());
18
+ };
19
+ fromMaybeMap = (map) => {
20
+ return this.fromMap(map ?? new Map());
21
+ };
22
+ getValue = (map, tokenType) => {
23
+ return map.get(tokenType) ?? 0n;
24
+ };
25
+ typeSet = (map) => {
26
+ return new Set(map.keys());
27
+ };
28
+ ensureZerosFor(map, types) {
29
+ const out = this.fromEntries(map.entries());
30
+ for (const tokenType of types) {
31
+ const existingValue = this.getValue(out, tokenType);
32
+ out.set(tokenType, existingValue);
33
+ }
34
+ return out;
35
+ }
36
+ merge = (a, b) => {
37
+ const allTokenTypes = this.typeSet(a).union(this.typeSet(b));
38
+ return this.fromEntries(allTokenTypes
39
+ .values()
40
+ .map((tokenType) => {
41
+ const aValue = this.getValue(a, tokenType);
42
+ const bValue = this.getValue(b, tokenType);
43
+ return [tokenType, aValue + bValue];
44
+ })
45
+ .filter(([, value]) => value !== 0n)
46
+ .toArray());
47
+ };
48
+ })();
@@ -0,0 +1,3 @@
1
+ export * from './Balancer.js';
2
+ export * from './CounterOffer.js';
3
+ export * from './Imbalances.js';
@@ -0,0 +1,15 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ export * from './Balancer.js';
14
+ export * from './CounterOffer.js';
15
+ export * from './Imbalances.js';
package/dist/index.d.ts CHANGED
@@ -1,37 +1 @@
1
- import { QualifiedCoinInfo, CoinInfo } from '@midnight-ntwrk/zswap';
2
-
3
- interface CoinRecipe {
4
- type: string;
5
- value: bigint;
6
- }
7
- type Imbalance = [string, bigint];
8
- type Imbalances = Map<string, bigint>;
9
- declare const emptyImbalances: Imbalances;
10
- declare const createImbalances: (imbalances: [string, bigint][]) => Imbalances;
11
- declare const mergeImbalances: (a: Imbalances, b: Imbalances) => Imbalances;
12
-
13
- interface TransactionCostModel {
14
- inputFeeOverhead: bigint;
15
- outputFeeOverhead: bigint;
16
- }
17
- declare class CounterOffer {
18
- readonly imbalances: Imbalances;
19
- readonly transactionCostModel: TransactionCostModel;
20
- readonly feeTokenType: string;
21
- readonly inputsRecipe: QualifiedCoinInfo[];
22
- readonly outputsRecipe: CoinInfo[];
23
- constructor(imbalances: Imbalances, transactionCostModel: TransactionCostModel, feeTokenType: string);
24
- findNonNativeImbalance(): Imbalance | undefined;
25
- findNativeImbalance(): Imbalance | undefined;
26
- addInput(input: QualifiedCoinInfo): void;
27
- addOutput(output: CoinRecipe): void;
28
- }
29
-
30
- interface BalanceRecipe {
31
- inputs: QualifiedCoinInfo[];
32
- outputs: CoinInfo[];
33
- }
34
- declare const getBalanceRecipe: (coins: QualifiedCoinInfo[], targetImbalances: Imbalances, transactionCostModel: TransactionCostModel, feeTokenType: string) => BalanceRecipe;
35
- declare const createCounterOffer: (coins: QualifiedCoinInfo[], targetImbalances: Imbalances, transactionCostModel: TransactionCostModel, feeTokenType: string) => CounterOffer;
36
-
37
- export { type BalanceRecipe, type CoinRecipe, CounterOffer, type Imbalance, type Imbalances, type TransactionCostModel, createCounterOffer, createImbalances, emptyImbalances, getBalanceRecipe, mergeImbalances };
1
+ export * from './balancer/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ // This file is part of MIDNIGHT-WALLET-SDK.
2
+ // Copyright (C) 2025 Midnight Foundation
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // You may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ export * from './balancer/index.js';
package/package.json CHANGED
@@ -1,39 +1,51 @@
1
1
  {
2
2
  "name": "@midnight-ntwrk/wallet-sdk-capabilities",
3
- "version": "1.0.0",
3
+ "version": "3.0.0-beta.8",
4
4
  "type": "module",
5
- "main": "./dist/index.cjs",
6
- "module": "./dist/index.mjs",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
- "author": "IOHK",
8
+ "author": "Midnight Foundation",
9
9
  "license": "Apache-2.0",
10
10
  "publishConfig": {
11
11
  "registry": "https://npm.pkg.github.com/"
12
12
  },
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/midnight-ntwrk/artifacts.git"
16
- },
17
13
  "files": [
18
14
  "dist/"
19
15
  ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/midnight-ntwrk/artifacts.git"
19
+ },
20
20
  "exports": {
21
21
  ".": {
22
- "import": "./dist/index.mjs",
23
- "require": "./dist/index.cjs",
24
- "types": "./dist/index.d.ts"
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js"
25
24
  }
26
25
  },
27
- "peerDependencies": {
28
- "@midnight-ntwrk/zswap": "^3.0.6"
26
+ "dependencies": {
27
+ "@midnight-ntwrk/wallet-sdk-address-format": "3.0.0-beta.8",
28
+ "@midnight-ntwrk/wallet-sdk-hd": "3.0.0-beta.7",
29
+ "effect": "^3.17.3"
29
30
  },
30
31
  "devDependencies": {
31
- "@midnight-ntwrk/zswap": "^3.0.6"
32
+ "@midnight-ntwrk/ledger-v6": "6.1.0-alpha.5",
33
+ "eslint": "^9.37.0",
34
+ "fast-check": "^4.2.0",
35
+ "publint": "~0.3.14",
36
+ "rimraf": "^6.0.1",
37
+ "typescript": "^5.9.3",
38
+ "vitest": "^3.2.4"
32
39
  },
33
40
  "scripts": {
34
41
  "typecheck": "tsc -b ./tsconfig.json --noEmit",
35
- "test": "NODE_OPTIONS='--experimental-vm-modules' jest --silent=false",
36
- "lint": "eslint",
37
- "dist:prebuild": "rollup -c ./rollup.config.mjs"
42
+ "test": "vitest run",
43
+ "lint": "eslint --max-warnings 0",
44
+ "format": "prettier --write \"**/*.{ts,js,json,yaml,yml}\"",
45
+ "format:check": "prettier --check \"**/*.{ts,js,json,yaml,yml}\"",
46
+ "dist": "tsc -b ./tsconfig.build.json",
47
+ "dist:publish": "tsc -b ./tsconfig.publish.json",
48
+ "clean": "rimraf --glob dist 'tsconfig.*.tsbuildinfo' && date +%s > .clean-timestamp",
49
+ "publint": "publint --strict"
38
50
  }
39
- }
51
+ }
package/dist/index.cjs DELETED
@@ -1,131 +0,0 @@
1
- 'use strict';
2
-
3
- var zswap = require('@midnight-ntwrk/zswap');
4
-
5
- class CounterOffer {
6
- imbalances;
7
- transactionCostModel;
8
- feeTokenType;
9
- inputsRecipe;
10
- outputsRecipe;
11
- constructor(imbalances, transactionCostModel, feeTokenType) {
12
- this.imbalances = imbalances;
13
- this.transactionCostModel = transactionCostModel;
14
- this.feeTokenType = feeTokenType;
15
- this.inputsRecipe = [];
16
- this.outputsRecipe = [];
17
- }
18
- findNonNativeImbalance() {
19
- for (const [tokenType, value] of this.imbalances) {
20
- if (tokenType !== this.feeTokenType && value !== 0n) {
21
- return [tokenType, value];
22
- }
23
- }
24
- return undefined;
25
- }
26
- findNativeImbalance() {
27
- const nativeImbalance = this.imbalances.get(this.feeTokenType);
28
- if (nativeImbalance !== undefined && nativeImbalance !== 0n) {
29
- return [this.feeTokenType, nativeImbalance];
30
- }
31
- return undefined;
32
- }
33
- addInput(input) {
34
- this.inputsRecipe.push(input);
35
- const imbalance = this.imbalances.get(input.type) || 0n;
36
- this.imbalances.set(input.type, imbalance + input.value);
37
- const nativeImbalance = this.imbalances.get(this.feeTokenType) || 0n;
38
- this.imbalances.set(this.feeTokenType, nativeImbalance - this.transactionCostModel.inputFeeOverhead);
39
- }
40
- addOutput(output) {
41
- const imbalance = this.imbalances.get(output.type) || 0n;
42
- const subtractFee = output.type === this.feeTokenType ? this.transactionCostModel.outputFeeOverhead : 0n;
43
- const absoluteCoinValue = output.value < 0n ? -output.value : output.value;
44
- this.outputsRecipe.push(zswap.createCoinInfo(output.type, absoluteCoinValue - subtractFee));
45
- this.imbalances.set(output.type, imbalance - absoluteCoinValue);
46
- if (output.type !== this.feeTokenType) {
47
- const nativeImbalance = this.imbalances.get(this.feeTokenType) || 0n;
48
- this.imbalances.set(this.feeTokenType, nativeImbalance - this.transactionCostModel.outputFeeOverhead);
49
- }
50
- }
51
- }
52
-
53
- const getBalanceRecipe = (coins, targetImbalances, transactionCostModel, feeTokenType) => {
54
- const counterOffer = createCounterOffer(coins, targetImbalances, transactionCostModel, feeTokenType);
55
- return {
56
- inputs: counterOffer.inputsRecipe,
57
- outputs: counterOffer.outputsRecipe,
58
- };
59
- };
60
- const createCounterOffer = (coins, targetImbalances, transactionCostModel, feeTokenType) => {
61
- // 1. Create an empty offer
62
- // 2. Calculate total fees to be paid for the unbalanced transaction and the offer
63
- // 3. Calculate resulting imbalances by merging ones from the unbalanced transaction, the offer and target imbalances
64
- const counterOffer = new CounterOffer(targetImbalances, transactionCostModel, feeTokenType);
65
- let imbalance;
66
- // 4. Verify if target imbalances are met. If they are, create transaction from the offer, merge with the unbalanced transaction, and return
67
- // 5. Sort token types present in result imbalances in a way, that DUST is left last and select first token type
68
- while ((imbalance = counterOffer.findNonNativeImbalance())) {
69
- coins = doBalance(imbalance, coins, counterOffer);
70
- }
71
- while ((imbalance = counterOffer.findNativeImbalance())) {
72
- coins = doBalance(imbalance, coins, counterOffer);
73
- }
74
- return counterOffer;
75
- };
76
- const doBalance = (imbalance, coins, counterOffer) => {
77
- const [tokenType, imbalanceAmount] = imbalance;
78
- // 6a. If the imbalance is positive and greater than the output fee,
79
- // create an output for self with the amount equal to imbalance
80
- const shouldAddOutput = (tokenType === counterOffer.feeTokenType &&
81
- imbalanceAmount >= counterOffer.transactionCostModel.outputFeeOverhead) ||
82
- (tokenType !== counterOffer.feeTokenType && imbalanceAmount > 0n);
83
- if (shouldAddOutput) {
84
- counterOffer.addOutput({ type: tokenType, value: imbalanceAmount });
85
- }
86
- else {
87
- // 6b. If the imbalance is negative, select a single coin of the selected type, and create an input
88
- const coin = chooseCoin(coins, { type: tokenType});
89
- if (typeof coin === 'undefined') {
90
- throw new Error(tokenType);
91
- }
92
- counterOffer.addInput(coin);
93
- coins = coins.filter((c) => c !== coin);
94
- }
95
- return coins;
96
- };
97
- const chooseCoin = (coins, coinToChoose) => {
98
- const filteredAndSortedCoins = coins
99
- .filter((coin) => coin.type === coinToChoose.type)
100
- .sort((a, b) => Number(a.value - b.value));
101
- return filteredAndSortedCoins[0] ?? undefined;
102
- };
103
-
104
- const emptyImbalances = new Map();
105
- const createImbalances = (imbalances) => {
106
- const mappedImbalances = new Map();
107
- imbalances.forEach(([tokenType, value]) => {
108
- if (mappedImbalances.has(tokenType)) {
109
- mappedImbalances.set(tokenType, mappedImbalances.get(tokenType) + value);
110
- }
111
- else {
112
- mappedImbalances.set(tokenType, value);
113
- }
114
- });
115
- return mappedImbalances;
116
- };
117
- const mergeImbalances = (a, b) => {
118
- b.forEach((valueB, tokenType) => {
119
- const valueA = a.get(tokenType) || 0n;
120
- a.set(tokenType, valueA + valueB);
121
- });
122
- return a;
123
- };
124
-
125
- exports.CounterOffer = CounterOffer;
126
- exports.createCounterOffer = createCounterOffer;
127
- exports.createImbalances = createImbalances;
128
- exports.emptyImbalances = emptyImbalances;
129
- exports.getBalanceRecipe = getBalanceRecipe;
130
- exports.mergeImbalances = mergeImbalances;
131
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/balancer/CounterOffer.ts","../src/balancer/Balancer.ts","../src/balancer/Imbalances.ts"],"sourcesContent":[null,null,null],"names":["createCoinInfo"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
package/dist/index.mjs DELETED
@@ -1,124 +0,0 @@
1
- import { createCoinInfo } from '@midnight-ntwrk/zswap';
2
-
3
- class CounterOffer {
4
- imbalances;
5
- transactionCostModel;
6
- feeTokenType;
7
- inputsRecipe;
8
- outputsRecipe;
9
- constructor(imbalances, transactionCostModel, feeTokenType) {
10
- this.imbalances = imbalances;
11
- this.transactionCostModel = transactionCostModel;
12
- this.feeTokenType = feeTokenType;
13
- this.inputsRecipe = [];
14
- this.outputsRecipe = [];
15
- }
16
- findNonNativeImbalance() {
17
- for (const [tokenType, value] of this.imbalances) {
18
- if (tokenType !== this.feeTokenType && value !== 0n) {
19
- return [tokenType, value];
20
- }
21
- }
22
- return undefined;
23
- }
24
- findNativeImbalance() {
25
- const nativeImbalance = this.imbalances.get(this.feeTokenType);
26
- if (nativeImbalance !== undefined && nativeImbalance !== 0n) {
27
- return [this.feeTokenType, nativeImbalance];
28
- }
29
- return undefined;
30
- }
31
- addInput(input) {
32
- this.inputsRecipe.push(input);
33
- const imbalance = this.imbalances.get(input.type) || 0n;
34
- this.imbalances.set(input.type, imbalance + input.value);
35
- const nativeImbalance = this.imbalances.get(this.feeTokenType) || 0n;
36
- this.imbalances.set(this.feeTokenType, nativeImbalance - this.transactionCostModel.inputFeeOverhead);
37
- }
38
- addOutput(output) {
39
- const imbalance = this.imbalances.get(output.type) || 0n;
40
- const subtractFee = output.type === this.feeTokenType ? this.transactionCostModel.outputFeeOverhead : 0n;
41
- const absoluteCoinValue = output.value < 0n ? -output.value : output.value;
42
- this.outputsRecipe.push(createCoinInfo(output.type, absoluteCoinValue - subtractFee));
43
- this.imbalances.set(output.type, imbalance - absoluteCoinValue);
44
- if (output.type !== this.feeTokenType) {
45
- const nativeImbalance = this.imbalances.get(this.feeTokenType) || 0n;
46
- this.imbalances.set(this.feeTokenType, nativeImbalance - this.transactionCostModel.outputFeeOverhead);
47
- }
48
- }
49
- }
50
-
51
- const getBalanceRecipe = (coins, targetImbalances, transactionCostModel, feeTokenType) => {
52
- const counterOffer = createCounterOffer(coins, targetImbalances, transactionCostModel, feeTokenType);
53
- return {
54
- inputs: counterOffer.inputsRecipe,
55
- outputs: counterOffer.outputsRecipe,
56
- };
57
- };
58
- const createCounterOffer = (coins, targetImbalances, transactionCostModel, feeTokenType) => {
59
- // 1. Create an empty offer
60
- // 2. Calculate total fees to be paid for the unbalanced transaction and the offer
61
- // 3. Calculate resulting imbalances by merging ones from the unbalanced transaction, the offer and target imbalances
62
- const counterOffer = new CounterOffer(targetImbalances, transactionCostModel, feeTokenType);
63
- let imbalance;
64
- // 4. Verify if target imbalances are met. If they are, create transaction from the offer, merge with the unbalanced transaction, and return
65
- // 5. Sort token types present in result imbalances in a way, that DUST is left last and select first token type
66
- while ((imbalance = counterOffer.findNonNativeImbalance())) {
67
- coins = doBalance(imbalance, coins, counterOffer);
68
- }
69
- while ((imbalance = counterOffer.findNativeImbalance())) {
70
- coins = doBalance(imbalance, coins, counterOffer);
71
- }
72
- return counterOffer;
73
- };
74
- const doBalance = (imbalance, coins, counterOffer) => {
75
- const [tokenType, imbalanceAmount] = imbalance;
76
- // 6a. If the imbalance is positive and greater than the output fee,
77
- // create an output for self with the amount equal to imbalance
78
- const shouldAddOutput = (tokenType === counterOffer.feeTokenType &&
79
- imbalanceAmount >= counterOffer.transactionCostModel.outputFeeOverhead) ||
80
- (tokenType !== counterOffer.feeTokenType && imbalanceAmount > 0n);
81
- if (shouldAddOutput) {
82
- counterOffer.addOutput({ type: tokenType, value: imbalanceAmount });
83
- }
84
- else {
85
- // 6b. If the imbalance is negative, select a single coin of the selected type, and create an input
86
- const coin = chooseCoin(coins, { type: tokenType});
87
- if (typeof coin === 'undefined') {
88
- throw new Error(tokenType);
89
- }
90
- counterOffer.addInput(coin);
91
- coins = coins.filter((c) => c !== coin);
92
- }
93
- return coins;
94
- };
95
- const chooseCoin = (coins, coinToChoose) => {
96
- const filteredAndSortedCoins = coins
97
- .filter((coin) => coin.type === coinToChoose.type)
98
- .sort((a, b) => Number(a.value - b.value));
99
- return filteredAndSortedCoins[0] ?? undefined;
100
- };
101
-
102
- const emptyImbalances = new Map();
103
- const createImbalances = (imbalances) => {
104
- const mappedImbalances = new Map();
105
- imbalances.forEach(([tokenType, value]) => {
106
- if (mappedImbalances.has(tokenType)) {
107
- mappedImbalances.set(tokenType, mappedImbalances.get(tokenType) + value);
108
- }
109
- else {
110
- mappedImbalances.set(tokenType, value);
111
- }
112
- });
113
- return mappedImbalances;
114
- };
115
- const mergeImbalances = (a, b) => {
116
- b.forEach((valueB, tokenType) => {
117
- const valueA = a.get(tokenType) || 0n;
118
- a.set(tokenType, valueA + valueB);
119
- });
120
- return a;
121
- };
122
-
123
- export { CounterOffer, createCounterOffer, createImbalances, emptyImbalances, getBalanceRecipe, mergeImbalances };
124
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/balancer/CounterOffer.ts","../src/balancer/Balancer.ts","../src/balancer/Imbalances.ts"],"sourcesContent":[null,null,null],"names":[],"mappings":"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"}