|
2 | 2 | /* eslint-disable @typescript-eslint/no-explicit-any */
|
3 | 3 | import * as mocks from '../mocks';
|
4 | 4 | import { AddressType, GroupedAddress } from '@cardano-sdk/key-management';
|
5 |
| -import { AssetId, createStubStakePoolProvider, somePartialStakePools } from '@cardano-sdk/util-dev'; |
| 5 | +import { |
| 6 | + AssetId, |
| 7 | + createStubStakePoolProvider, |
| 8 | + generateRandomBigInt, |
| 9 | + generateRandomHexString, |
| 10 | + somePartialStakePools |
| 11 | +} from '@cardano-sdk/util-dev'; |
6 | 12 | import {
|
7 | 13 | Cardano,
|
8 | 14 | ChainHistoryProvider,
|
@@ -165,6 +171,62 @@ const assertWalletProperties2 = async (wallet: ObservableWallet) => {
|
165 | 171 | expect(rewardAccounts[0].rewardBalance).toBe(mocks.rewardAccountBalance2);
|
166 | 172 | };
|
167 | 173 |
|
| 174 | +/** |
| 175 | + * Generates a set of UTXOs matching the given parameters. |
| 176 | + * |
| 177 | + * @param utxoCount The number of UTXOs to be generated. |
| 178 | + * @param assetsPerUtxo The number of Assets per UTXO. |
| 179 | + */ |
| 180 | +const generateUtxos = (utxoCount: number, assetsPerUtxo: number): Cardano.Utxo[] => { |
| 181 | + const utxos: Cardano.Utxo[] = []; |
| 182 | + |
| 183 | + for (let utxoIndex = 0; utxoIndex < utxoCount; ++utxoIndex) { |
| 184 | + const utxo: Cardano.Utxo = [ |
| 185 | + { |
| 186 | + address, |
| 187 | + index: 0, |
| 188 | + txId: Cardano.TransactionId(generateRandomHexString(64)) |
| 189 | + }, |
| 190 | + { |
| 191 | + address, |
| 192 | + value: { |
| 193 | + assets: new Map(), |
| 194 | + coins: generateRandomBigInt(1_000_000, 9_999_999_000_000) // from 1 tADA to 9.999.999 tADA |
| 195 | + } |
| 196 | + } |
| 197 | + ]; |
| 198 | + for (let assetIndex = 0; assetIndex < assetsPerUtxo; ++assetIndex) { |
| 199 | + utxo[1].value!.assets!.set(Cardano.AssetId(generateRandomHexString(72)), generateRandomBigInt(1, 1000)); |
| 200 | + } |
| 201 | + |
| 202 | + utxos.push(utxo); |
| 203 | + } |
| 204 | + |
| 205 | + return utxos; |
| 206 | +}; |
| 207 | + |
| 208 | +/** |
| 209 | + * Gets the asset list and the total amount of lovelace on a utxo set. |
| 210 | + * |
| 211 | + * @param utxos The utxos. |
| 212 | + * @returns The total lovelace and the aggregated asset set. |
| 213 | + */ |
| 214 | +const getAssetsFromUtxos = (utxos: Cardano.Utxo[]) => { |
| 215 | + const values = utxos.map((utxo) => utxo[1].value); |
| 216 | + let totalLovelace = 0n; |
| 217 | + const totalTokens = new Map(); |
| 218 | + |
| 219 | + for (const value of values) { |
| 220 | + totalLovelace += value.coins; |
| 221 | + |
| 222 | + for (const [key, val] of value.assets!.entries()) { |
| 223 | + totalTokens.set(key, val); |
| 224 | + } |
| 225 | + } |
| 226 | + |
| 227 | + return { totalLovelace, totalTokens }; |
| 228 | +}; |
| 229 | + |
168 | 230 | describe('SingleAddressWallet load', () => {
|
169 | 231 | it('loads all properties from provider, stores them and restores on subsequent load, fetches new data', async () => {
|
170 | 232 | const stores = createInMemoryWalletStores();
|
@@ -288,3 +350,43 @@ describe('SingleAddressWallet load', () => {
|
288 | 350 | wallet.shutdown();
|
289 | 351 | });
|
290 | 352 | });
|
| 353 | + |
| 354 | +describe('SingleAddressWallet creates big UTXO', () => { |
| 355 | + it('creates an UTXO with 300 hundred mixed assets coming from several inputs', async () => { |
| 356 | + const stores = createInMemoryWalletStores(); |
| 357 | + const utxoSet = generateUtxos(30, 10); |
| 358 | + const totalAssets = getAssetsFromUtxos(utxoSet); |
| 359 | + |
| 360 | + const wallet = await createWallet(stores, { |
| 361 | + chainHistoryProvider: mocks.mockChainHistoryProvider(), |
| 362 | + networkInfoProvider: mocks.mockNetworkInfoProvider(), |
| 363 | + rewardsProvider: mocks.mockRewardsProvider(), |
| 364 | + utxoProvider: mocks.mockUtxoProvider(utxoSet) |
| 365 | + }); |
| 366 | + |
| 367 | + const txProps = { |
| 368 | + outputs: new Set([ |
| 369 | + { |
| 370 | + address, |
| 371 | + value: { |
| 372 | + assets: totalAssets.totalTokens, |
| 373 | + coins: totalAssets.totalLovelace - 10_000_000n // Leave some tADA available for fees |
| 374 | + } |
| 375 | + } |
| 376 | + ]) |
| 377 | + }; |
| 378 | + |
| 379 | + const unsignedTx = await wallet.initializeTx(txProps); |
| 380 | + |
| 381 | + const finalizeProps = { |
| 382 | + tx: unsignedTx |
| 383 | + }; |
| 384 | + |
| 385 | + const signedTx = await wallet.finalizeTx(finalizeProps); |
| 386 | + |
| 387 | + const nonChangeOutput = signedTx.body.outputs.find((out) => out.value!.assets!.size > 0); |
| 388 | + expect(nonChangeOutput!.value.assets).toBe(totalAssets.totalTokens); |
| 389 | + |
| 390 | + wallet.shutdown(); |
| 391 | + }); |
| 392 | +}); |
0 commit comments