@fleet-sdk/common 0.1.0-alpha.28 → 0.1.0-alpha.30
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.
- package/dist/cjs/types/boxes.d.ts +6 -5
- package/dist/cjs/utils/arrayUtils.d.ts +6 -1
- package/dist/cjs/utils/arrayUtils.js +38 -1
- package/dist/cjs/utils/arrayUtils.js.map +1 -1
- package/dist/cjs/utils/boxUtils.d.ts +12 -9
- package/dist/cjs/utils/boxUtils.js +47 -8
- package/dist/cjs/utils/boxUtils.js.map +1 -1
- package/dist/esm/types/boxes.d.ts +6 -5
- package/dist/esm/utils/arrayUtils.d.ts +6 -1
- package/dist/esm/utils/arrayUtils.js +34 -0
- package/dist/esm/utils/arrayUtils.js.map +1 -1
- package/dist/esm/utils/boxUtils.d.ts +12 -9
- package/dist/esm/utils/boxUtils.js +44 -6
- package/dist/esm/utils/boxUtils.js.map +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/types/boxes.ts +6 -5
- package/src/utils/arrayUtils.ts +57 -1
- package/src/utils/boxUtils.ts +71 -14
package/src/utils/arrayUtils.ts
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import { SortingDirection, SortingSelector } from "../types";
|
2
2
|
|
3
|
+
type ObjectSelector<T> = (item: T) => T[keyof T];
|
4
|
+
|
3
5
|
export function isEmpty<T extends object>(obj?: T): obj is undefined;
|
4
6
|
export function isEmpty<T>(array?: T[]): array is undefined;
|
5
7
|
export function isEmpty<T>(obj?: T[] | object): obj is undefined {
|
@@ -43,7 +45,7 @@ export function hasDuplicates<T>(array: T[]): boolean {
|
|
43
45
|
/**
|
44
46
|
* Check for duplicate keys in complex elements
|
45
47
|
*/
|
46
|
-
export function hasDuplicatesBy<T>(array: T[], selector:
|
48
|
+
export function hasDuplicatesBy<T>(array: T[], selector: ObjectSelector<T>): boolean {
|
47
49
|
return array.some((item, index) => {
|
48
50
|
return array.findIndex((x) => selector(x) === selector(item)) !== index;
|
49
51
|
});
|
@@ -96,6 +98,28 @@ export function areEqual<T>(array1: ArrayLike<T>, array2: ArrayLike<T>): boolean
|
|
96
98
|
return true;
|
97
99
|
}
|
98
100
|
|
101
|
+
export function areEqualBy<T>(
|
102
|
+
array1: ArrayLike<T>,
|
103
|
+
array2: ArrayLike<T>,
|
104
|
+
selector: ObjectSelector<T>
|
105
|
+
): boolean {
|
106
|
+
if (array1 === array2) {
|
107
|
+
return true;
|
108
|
+
}
|
109
|
+
|
110
|
+
if (array1.length != array2.length) {
|
111
|
+
return false;
|
112
|
+
}
|
113
|
+
|
114
|
+
for (let i = 0; i < array1.length; i++) {
|
115
|
+
if (selector(array1[i]) !== selector(array2[i])) {
|
116
|
+
return false;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
return true;
|
121
|
+
}
|
122
|
+
|
99
123
|
export function startsWith<T>(array: ArrayLike<T>, target: ArrayLike<T>): boolean {
|
100
124
|
if (array === target) {
|
101
125
|
return true;
|
@@ -133,3 +157,35 @@ export function endsWith<T>(array: ArrayLike<T>, target: ArrayLike<T>): boolean
|
|
133
157
|
|
134
158
|
return true;
|
135
159
|
}
|
160
|
+
|
161
|
+
export function uniq<T>(array: Array<T>): Array<T> {
|
162
|
+
if (isEmpty(array)) {
|
163
|
+
return array;
|
164
|
+
}
|
165
|
+
|
166
|
+
return Array.from(new Set(array));
|
167
|
+
}
|
168
|
+
|
169
|
+
export function uniqBy<T>(
|
170
|
+
array: Array<T>,
|
171
|
+
selector: ObjectSelector<T>,
|
172
|
+
selection: "keep-first" | "keep-last" = "keep-first"
|
173
|
+
): Array<T> {
|
174
|
+
if (isEmpty(array)) {
|
175
|
+
return array;
|
176
|
+
}
|
177
|
+
|
178
|
+
return Array.from(
|
179
|
+
array
|
180
|
+
.reduce((map, e) => {
|
181
|
+
const key = selector(e);
|
182
|
+
|
183
|
+
if (selection === "keep-first" && map.has(key)) {
|
184
|
+
return map;
|
185
|
+
}
|
186
|
+
|
187
|
+
return map.set(key, e);
|
188
|
+
}, new Map())
|
189
|
+
.values()
|
190
|
+
);
|
191
|
+
}
|
package/src/utils/boxUtils.ts
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
import { Amount, NonMandatoryRegisters, TokenId } from "../types";
|
1
|
+
import { Amount, AmountType, Box, NonMandatoryRegisters, TokenAmount, TokenId } from "../types";
|
2
|
+
import { isEmpty } from "./arrayUtils";
|
2
3
|
import { _0n } from "./bigIntLiterals";
|
3
4
|
import { ensureBigInt } from "./bigIntUtils";
|
4
5
|
import { isDefined, isUndefined } from "./objectUtils";
|
5
6
|
|
6
7
|
const NANOERGS_TOKEN_ID = "nanoErgs";
|
7
8
|
|
8
|
-
export function utxoSum(boxes: MinimalBoxAmounts):
|
9
|
+
export function utxoSum(boxes: MinimalBoxAmounts): BoxSummary;
|
9
10
|
export function utxoSum(boxes: MinimalBoxAmounts, tokenId: TokenId): bigint;
|
10
|
-
export function utxoSum(boxes: MinimalBoxAmounts, tokenId?: TokenId):
|
11
|
+
export function utxoSum(boxes: MinimalBoxAmounts, tokenId?: TokenId): BoxSummary | bigint {
|
11
12
|
const balances: { [tokenId: string]: bigint } = {};
|
12
13
|
|
13
14
|
for (const box of boxes) {
|
@@ -31,14 +32,15 @@ export function utxoSum(boxes: MinimalBoxAmounts, tokenId?: TokenId): BoxAmounts
|
|
31
32
|
}
|
32
33
|
|
33
34
|
return {
|
34
|
-
nanoErgs: balances[NANOERGS_TOKEN_ID],
|
35
|
+
nanoErgs: balances[NANOERGS_TOKEN_ID] || _0n,
|
35
36
|
tokens: Object.keys(balances)
|
36
37
|
.filter((x) => x !== NANOERGS_TOKEN_ID)
|
37
38
|
.map((tokenId) => ({ tokenId, amount: balances[tokenId] }))
|
38
39
|
};
|
39
40
|
}
|
40
41
|
|
41
|
-
|
42
|
+
// todo: make it accept arrays of utxos as params
|
43
|
+
export function utxoDiff(amountsA: BoxSummary, amountsB: BoxSummary): BoxSummary {
|
42
44
|
const tokens: TokenAmount<bigint>[] = [];
|
43
45
|
const nanoErgs = amountsA.nanoErgs - amountsB.nanoErgs;
|
44
46
|
|
@@ -54,14 +56,14 @@ export function utxoSumResultDiff(amountsA: BoxAmounts, amountsB: BoxAmounts): B
|
|
54
56
|
return { nanoErgs, tokens };
|
55
57
|
}
|
56
58
|
|
57
|
-
const
|
58
|
-
const
|
59
|
+
const MIN_REGISTERS = 4;
|
60
|
+
const MAX_REGISTERS = 9;
|
59
61
|
|
60
62
|
export function areRegistersDenselyPacked(registers: NonMandatoryRegisters): boolean {
|
61
63
|
let lastValueIndex = 0;
|
62
|
-
for (let i =
|
64
|
+
for (let i = MIN_REGISTERS; i <= MAX_REGISTERS; i++) {
|
63
65
|
if (registers[`R${i}` as keyof NonMandatoryRegisters]) {
|
64
|
-
if (i ===
|
66
|
+
if (i === MIN_REGISTERS) {
|
65
67
|
lastValueIndex = i;
|
66
68
|
continue;
|
67
69
|
}
|
@@ -77,17 +79,72 @@ export function areRegistersDenselyPacked(registers: NonMandatoryRegisters): boo
|
|
77
79
|
return true;
|
78
80
|
}
|
79
81
|
|
80
|
-
|
81
|
-
|
82
|
-
|
82
|
+
export function utxoFilter<T extends AmountType>(
|
83
|
+
utxos: Box<T>[],
|
84
|
+
filterParams: UTxOFilterParams<T>
|
85
|
+
) {
|
86
|
+
if (isEmpty(filterParams) || isEmpty(utxos)) {
|
87
|
+
return utxos;
|
88
|
+
}
|
89
|
+
|
90
|
+
const { by, max } = filterParams;
|
91
|
+
let filtered = utxos;
|
92
|
+
|
93
|
+
if (by) {
|
94
|
+
filtered = utxos.filter(by);
|
95
|
+
if (isEmpty(filtered)) {
|
96
|
+
return filtered;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
if (!max) {
|
101
|
+
return filtered;
|
102
|
+
}
|
103
|
+
|
104
|
+
if (isDefined(max.aggregatedDistinctTokens)) {
|
105
|
+
const tokenIds = _getDistinctTokenIds(filtered, max.aggregatedDistinctTokens);
|
106
|
+
filtered = filtered.filter(
|
107
|
+
(utxo) => isEmpty(utxo.assets) || utxo.assets.every((token) => tokenIds.has(token.tokenId))
|
108
|
+
);
|
109
|
+
}
|
110
|
+
|
111
|
+
if (isDefined(max.count) && filtered.length > max.count) {
|
112
|
+
filtered = filtered.slice(0, max.count);
|
113
|
+
}
|
114
|
+
|
115
|
+
return filtered;
|
116
|
+
}
|
117
|
+
|
118
|
+
function _getDistinctTokenIds(utxos: Box<AmountType>[], max: number): Set<string> {
|
119
|
+
const tokenIds = new Set<string>();
|
120
|
+
|
121
|
+
for (let i = 0; i < utxos.length && tokenIds.size < max; i++) {
|
122
|
+
if (isEmpty(utxos[i].assets) || utxos[i].assets.length > max) {
|
123
|
+
continue;
|
124
|
+
}
|
125
|
+
|
126
|
+
for (const token of utxos[i].assets) {
|
127
|
+
tokenIds.add(token.tokenId);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
|
131
|
+
return tokenIds;
|
132
|
+
}
|
133
|
+
|
134
|
+
export type UTxOFilterParams<T extends AmountType> = {
|
135
|
+
by?: (utxo: Box<T>) => boolean;
|
136
|
+
max?: {
|
137
|
+
count?: number;
|
138
|
+
aggregatedDistinctTokens?: number;
|
139
|
+
};
|
83
140
|
};
|
84
141
|
|
85
|
-
export type
|
142
|
+
export type BoxSummary = {
|
86
143
|
nanoErgs: bigint;
|
87
144
|
tokens: TokenAmount<bigint>[];
|
88
145
|
};
|
89
146
|
|
90
|
-
type MinimalBoxAmounts = readonly {
|
147
|
+
export type MinimalBoxAmounts = readonly {
|
91
148
|
value: Amount;
|
92
149
|
assets: TokenAmount<Amount>[];
|
93
150
|
}[];
|