@cardano-sdk/wallet 0.1.4 → 0.1.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.
Files changed (169) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +5 -0
  3. package/README.md +8 -0
  4. package/dist/KeyManagement/InMemoryKeyManager.d.ts +9 -0
  5. package/dist/KeyManagement/InMemoryKeyManager.d.ts.map +1 -0
  6. package/dist/KeyManagement/InMemoryKeyManager.js +94 -0
  7. package/dist/KeyManagement/InMemoryKeyManager.js.map +1 -0
  8. package/dist/KeyManagement/errors/InvalidMnemonic.d.ts +5 -0
  9. package/dist/KeyManagement/errors/InvalidMnemonic.d.ts.map +1 -0
  10. package/dist/KeyManagement/errors/InvalidMnemonic.js +13 -0
  11. package/dist/KeyManagement/errors/InvalidMnemonic.js.map +1 -0
  12. package/{src/KeyManagement/errors/index.ts → dist/KeyManagement/errors/index.d.ts} +1 -0
  13. package/dist/KeyManagement/errors/index.d.ts.map +1 -0
  14. package/dist/KeyManagement/errors/index.js +6 -0
  15. package/dist/KeyManagement/errors/index.js.map +1 -0
  16. package/{src/KeyManagement/index.ts → dist/KeyManagement/index.d.ts} +1 -0
  17. package/dist/KeyManagement/index.d.ts.map +1 -0
  18. package/dist/KeyManagement/index.js +30 -0
  19. package/dist/KeyManagement/index.js.map +1 -0
  20. package/dist/KeyManagement/types.d.ts +30 -0
  21. package/dist/KeyManagement/types.d.ts.map +1 -0
  22. package/dist/KeyManagement/types.js +15 -0
  23. package/dist/KeyManagement/types.js.map +1 -0
  24. package/dist/KeyManagement/util.d.ts +6 -0
  25. package/dist/KeyManagement/util.d.ts.map +1 -0
  26. package/dist/KeyManagement/util.js +31 -0
  27. package/dist/KeyManagement/util.js.map +1 -0
  28. package/dist/SingleAddressWallet.d.ts +45 -0
  29. package/dist/SingleAddressWallet.d.ts.map +1 -0
  30. package/dist/SingleAddressWallet.js +158 -0
  31. package/dist/SingleAddressWallet.js.map +1 -0
  32. package/dist/Transaction/computeImplicitCoin.d.ts +4 -0
  33. package/dist/Transaction/computeImplicitCoin.d.ts.map +1 -0
  34. package/dist/Transaction/computeImplicitCoin.js +21 -0
  35. package/dist/Transaction/computeImplicitCoin.js.map +1 -0
  36. package/dist/Transaction/createTransactionInternals.d.ts +16 -0
  37. package/dist/Transaction/createTransactionInternals.d.ts.map +1 -0
  38. package/dist/Transaction/createTransactionInternals.js +28 -0
  39. package/dist/Transaction/createTransactionInternals.js.map +1 -0
  40. package/dist/Transaction/ensureValidityInterval.d.ts +3 -0
  41. package/dist/Transaction/ensureValidityInterval.d.ts.map +1 -0
  42. package/dist/Transaction/ensureValidityInterval.js +6 -0
  43. package/dist/Transaction/ensureValidityInterval.js.map +1 -0
  44. package/dist/Transaction/index.d.ts +4 -0
  45. package/dist/Transaction/index.d.ts.map +1 -0
  46. package/dist/Transaction/index.js +16 -0
  47. package/dist/Transaction/index.js.map +1 -0
  48. package/dist/index.d.ts +6 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +31 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/services/AssetsTracker.d.ts +16 -0
  53. package/dist/services/AssetsTracker.d.ts.map +1 -0
  54. package/dist/services/AssetsTracker.js +13 -0
  55. package/dist/services/AssetsTracker.js.map +1 -0
  56. package/dist/services/BalanceTracker.d.ts +5 -0
  57. package/dist/services/BalanceTracker.d.ts.map +1 -0
  58. package/dist/services/BalanceTracker.js +43 -0
  59. package/dist/services/BalanceTracker.js.map +1 -0
  60. package/dist/services/DelegationTracker/DelegationTracker.d.ts +26 -0
  61. package/dist/services/DelegationTracker/DelegationTracker.d.ts.map +1 -0
  62. package/dist/services/DelegationTracker/DelegationTracker.js +39 -0
  63. package/dist/services/DelegationTracker/DelegationTracker.js.map +1 -0
  64. package/dist/services/DelegationTracker/RewardAccounts.d.ts +36 -0
  65. package/dist/services/DelegationTracker/RewardAccounts.d.ts.map +1 -0
  66. package/dist/services/DelegationTracker/RewardAccounts.js +86 -0
  67. package/dist/services/DelegationTracker/RewardAccounts.js.map +1 -0
  68. package/dist/services/DelegationTracker/RewardsHistory.d.ts +14 -0
  69. package/dist/services/DelegationTracker/RewardsHistory.d.ts.map +1 -0
  70. package/dist/services/DelegationTracker/RewardsHistory.js +27 -0
  71. package/dist/services/DelegationTracker/RewardsHistory.js.map +1 -0
  72. package/dist/services/DelegationTracker/index.d.ts +5 -0
  73. package/dist/services/DelegationTracker/index.d.ts.map +1 -0
  74. package/dist/services/DelegationTracker/index.js +17 -0
  75. package/dist/services/DelegationTracker/index.js.map +1 -0
  76. package/dist/services/DelegationTracker/transactionCertificates.d.ts +9 -0
  77. package/dist/services/DelegationTracker/transactionCertificates.d.ts.map +1 -0
  78. package/dist/services/DelegationTracker/transactionCertificates.js +33 -0
  79. package/dist/services/DelegationTracker/transactionCertificates.js.map +1 -0
  80. package/dist/services/DelegationTracker/types.d.ts +6 -0
  81. package/dist/services/DelegationTracker/types.d.ts.map +1 -0
  82. package/dist/services/DelegationTracker/types.js +3 -0
  83. package/dist/services/DelegationTracker/types.js.map +1 -0
  84. package/dist/services/TransactionError.d.ts +15 -0
  85. package/dist/services/TransactionError.d.ts.map +1 -0
  86. package/dist/services/TransactionError.js +23 -0
  87. package/dist/services/TransactionError.js.map +1 -0
  88. package/dist/services/TransactionsTracker.d.ts +22 -0
  89. package/dist/services/TransactionsTracker.d.ts.map +1 -0
  90. package/dist/services/TransactionsTracker.js +75 -0
  91. package/dist/services/TransactionsTracker.js.map +1 -0
  92. package/dist/services/UtxoTracker.d.ts +18 -0
  93. package/dist/services/UtxoTracker.d.ts.map +1 -0
  94. package/dist/services/UtxoTracker.js +20 -0
  95. package/dist/services/UtxoTracker.js.map +1 -0
  96. package/dist/services/index.d.ts +9 -0
  97. package/dist/services/index.d.ts.map +1 -0
  98. package/dist/services/index.js +21 -0
  99. package/dist/services/index.js.map +1 -0
  100. package/dist/services/types.d.ts +81 -0
  101. package/dist/services/types.d.ts.map +1 -0
  102. package/dist/services/types.js +16 -0
  103. package/dist/services/types.js.map +1 -0
  104. package/dist/services/util/SyncableIntervalTrackerSubject.d.ts +19 -0
  105. package/dist/services/util/SyncableIntervalTrackerSubject.d.ts.map +1 -0
  106. package/dist/services/util/SyncableIntervalTrackerSubject.js +30 -0
  107. package/dist/services/util/SyncableIntervalTrackerSubject.js.map +1 -0
  108. package/dist/services/util/TrackerSubject.d.ts +14 -0
  109. package/dist/services/util/TrackerSubject.d.ts.map +1 -0
  110. package/dist/services/util/TrackerSubject.js +46 -0
  111. package/dist/services/util/TrackerSubject.js.map +1 -0
  112. package/dist/services/util/coldObservableProvider.d.ts +4 -0
  113. package/dist/services/util/coldObservableProvider.d.ts.map +1 -0
  114. package/dist/services/util/coldObservableProvider.js +14 -0
  115. package/dist/services/util/coldObservableProvider.js.map +1 -0
  116. package/dist/services/util/equals.d.ts +9 -0
  117. package/dist/services/util/equals.d.ts.map +1 -0
  118. package/dist/services/util/equals.js +19 -0
  119. package/dist/services/util/equals.js.map +1 -0
  120. package/dist/services/util/index.d.ts +6 -0
  121. package/dist/services/util/index.d.ts.map +1 -0
  122. package/dist/services/util/index.js +18 -0
  123. package/dist/services/util/index.js.map +1 -0
  124. package/dist/services/util/trigger.d.ts +5 -0
  125. package/dist/services/util/trigger.d.ts.map +1 -0
  126. package/dist/services/util/trigger.js +9 -0
  127. package/dist/services/util/trigger.js.map +1 -0
  128. package/dist/types.d.ts +35 -0
  129. package/dist/types.d.ts.map +1 -0
  130. package/dist/types.js +3 -0
  131. package/dist/types.js.map +1 -0
  132. package/package.json +17 -8
  133. package/jest.config.js +0 -1
  134. package/src/Address.ts +0 -12
  135. package/src/BalanceTracker.ts +0 -62
  136. package/src/InMemoryTransactionTracker.ts +0 -87
  137. package/src/InMemoryUtxoRepository.ts +0 -192
  138. package/src/KeyManagement/InMemoryKeyManager.ts +0 -67
  139. package/src/KeyManagement/errors/InvalidMnemonic.ts +0 -9
  140. package/src/KeyManagement/types.ts +0 -15
  141. package/src/KeyManagement/util.ts +0 -14
  142. package/src/SingleAddressWallet.ts +0 -120
  143. package/src/Transaction/CertificateFactory.ts +0 -154
  144. package/src/Transaction/computeImplicitCoin.ts +0 -36
  145. package/src/Transaction/createTransactionInternals.ts +0 -60
  146. package/src/Transaction/index.ts +0 -5
  147. package/src/Transaction/types.ts +0 -12
  148. package/src/Transaction/withdrawal.ts +0 -17
  149. package/src/TransactionError.ts +0 -17
  150. package/src/index.ts +0 -9
  151. package/src/tsconfig.json +0 -11
  152. package/src/types.ts +0 -56
  153. package/test/.eslintrc.js +0 -7
  154. package/test/BalanceTracker.test.ts +0 -44
  155. package/test/InMemoryTransactionTracker.test.ts +0 -108
  156. package/test/InMemoryUtxoRepository.test.ts +0 -242
  157. package/test/KeyManagement/InMemoryKeyManager.test.ts +0 -39
  158. package/test/SingleAddressWallet.test.ts +0 -87
  159. package/test/Transaction/CertificateFactory.test.ts +0 -89
  160. package/test/Transaction/computeImplicitCoin.test.ts +0 -26
  161. package/test/Transaction/createTransactionInternals.test.ts +0 -84
  162. package/test/Transaction/withdrawal.test.ts +0 -13
  163. package/test/integration/withdrawal.test.ts +0 -108
  164. package/test/mocks/MockTransactionTracker.ts +0 -8
  165. package/test/mocks/MockUtxoRepository.ts +0 -13
  166. package/test/mocks/ProviderStub.ts +0 -151
  167. package/test/mocks/index.ts +0 -4
  168. package/test/mocks/testKeyManager.ts +0 -10
  169. package/test/tsconfig.json +0 -12
@@ -1,17 +0,0 @@
1
- import { Cardano, CardanoSerializationLib, CSL, Ogmios } from '@cardano-sdk/core';
2
- import { KeyManager } from '../KeyManagement';
3
-
4
- export type Withdrawal = {
5
- address: CSL.RewardAddress;
6
- quantity: CSL.BigNum;
7
- };
8
-
9
- export const withdrawal = (
10
- csl: CardanoSerializationLib,
11
- keyManager: KeyManager,
12
- quantity: Ogmios.Lovelace,
13
- network: number = Cardano.NetworkId.mainnet
14
- ): Withdrawal => ({
15
- address: csl.RewardAddress.new(network, csl.StakeCredential.from_keyhash(keyManager.stakeKey.hash())),
16
- quantity: csl.BigNum.from_str(quantity.toString())
17
- });
@@ -1,17 +0,0 @@
1
- import { CustomError } from 'ts-custom-error';
2
-
3
- export enum TransactionFailure {
4
- InvalidTransaction = 'INVALID_TRANSACTION',
5
- FailedToSubmit = 'FAILED_TO_SUBMIT',
6
- Unknown = 'UNKNOWN',
7
- CannotTrack = 'CANNOT_TRACK',
8
- Timeout = 'TIMEOUT'
9
- }
10
-
11
- const formatDetail = (detail?: string) => (detail ? ` (${detail})` : '');
12
-
13
- export class TransactionError extends CustomError {
14
- constructor(public reason: TransactionFailure, public innerError?: unknown, public detail?: string) {
15
- super(`Transaction failed: ${reason}${formatDetail(detail)}`);
16
- }
17
- }
package/src/index.ts DELETED
@@ -1,9 +0,0 @@
1
- export * as Address from './Address';
2
- export * as Transaction from './Transaction';
3
- export * from './InMemoryUtxoRepository';
4
- export * from './InMemoryTransactionTracker';
5
- export * as KeyManagement from './KeyManagement';
6
- export * from './SingleAddressWallet';
7
- export * from './types';
8
- export * from './TransactionError';
9
- export * from './BalanceTracker';
package/src/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../dist/",
5
- "rootDir": "."
6
- },
7
- "references": [
8
- { "path": "../../cip2/src" },
9
- { "path": "../../core/src" }
10
- ]
11
- }
package/src/types.ts DELETED
@@ -1,56 +0,0 @@
1
- import Schema from '@cardano-ogmios/schema';
2
- import { ImplicitCoin, SelectionConstraints, SelectionResult } from '@cardano-sdk/cip2';
3
- import { CSL, Ogmios } from '@cardano-sdk/core';
4
- import Emittery from 'emittery';
5
-
6
- export enum UtxoRepositoryEvent {
7
- Changed = 'changed',
8
- OutOfSync = 'out-of-sync'
9
- }
10
-
11
- export interface UtxoRepositoryFields {
12
- allUtxos: Schema.Utxo;
13
- availableUtxos: Schema.Utxo;
14
- allRewards: Ogmios.Lovelace | null;
15
- availableRewards: Ogmios.Lovelace | null;
16
- delegation: Schema.PoolId | null;
17
- }
18
-
19
- export type UtxoRepositoryEvents = {
20
- changed: UtxoRepositoryFields;
21
- 'out-of-sync': void;
22
- 'transaction-untracked': CSL.Transaction;
23
- };
24
- export type UtxoRepository = {
25
- sync: () => Promise<void>;
26
- selectInputs: (
27
- outputs: Set<CSL.TransactionOutput>,
28
- constraints: SelectionConstraints,
29
- implicitCoin?: ImplicitCoin
30
- ) => Promise<SelectionResult>;
31
- } & UtxoRepositoryFields &
32
- Emittery<UtxoRepositoryEvents>;
33
-
34
- export interface OnTransactionArgs {
35
- transaction: CSL.Transaction;
36
- /**
37
- * Resolves when transaction is confirmed.
38
- * Rejects if transaction fails to submit or validate.
39
- */
40
- confirmed: Promise<void>;
41
- }
42
-
43
- export enum TransactionTrackerEvent {
44
- NewTransaction = 'new-transaction'
45
- }
46
-
47
- export type TransactionTrackerEvents = { 'new-transaction': OnTransactionArgs };
48
- export interface TransactionTracker extends Emittery<TransactionTrackerEvents> {
49
- /**
50
- * Track a new transaction.
51
- *
52
- * @param {CSL.Transaction} transaction transaction to track.
53
- * @param {Promise<void>} submitted defer checking for transaction confirmation until this resolves.
54
- */
55
- track(transaction: CSL.Transaction, submitted?: Promise<void>): Promise<void>;
56
- }
package/test/.eslintrc.js DELETED
@@ -1,7 +0,0 @@
1
- module.exports = {
2
- "extends": ["../../../test/.eslintrc.js"],
3
- "parserOptions": {
4
- "project": "./tsconfig.json",
5
- "tsconfigRootDir": __dirname
6
- }
7
- }
@@ -1,44 +0,0 @@
1
- import { Ogmios } from '@cardano-sdk/core';
2
- import { MockUtxoRepository } from './mocks';
3
- import { BalanceTracker, UtxoRepositoryEvent, UtxoRepositoryFields } from '../src';
4
-
5
- const numAssets = (tokenMap?: Ogmios.TokenMap) => Object.keys(tokenMap || {}).length;
6
-
7
- describe('BalanceTracker', () => {
8
- let balanceTracker: BalanceTracker;
9
- let utxoRepository: MockUtxoRepository;
10
-
11
- beforeEach(() => {
12
- utxoRepository = new MockUtxoRepository();
13
- balanceTracker = new BalanceTracker(utxoRepository);
14
- });
15
-
16
- it('constructor sets balances from utxo repository', () => {
17
- expect(balanceTracker.total.coins).toBeGreaterThan(0n);
18
- expect(balanceTracker.total.assets).toBeTruthy();
19
- expect(balanceTracker.total.rewards).toBeGreaterThan(0n);
20
- });
21
-
22
- it('updates balances on UtxoRepositoryEvent.Changed', async () => {
23
- const totalBefore = balanceTracker.total;
24
-
25
- const allRewards = utxoRepository.allRewards - 1n;
26
- const availableRewards = utxoRepository.allRewards - 2n;
27
- await utxoRepository.emit(UtxoRepositoryEvent.Changed, {
28
- allUtxos: utxoRepository.allUtxos.slice(1),
29
- availableUtxos: utxoRepository.allUtxos.slice(2),
30
- allRewards,
31
- availableRewards,
32
- delegation: null
33
- } as UtxoRepositoryFields);
34
-
35
- expect(balanceTracker.total.coins).toBeLessThan(totalBefore.coins);
36
- expect(balanceTracker.total.coins).toBeGreaterThan(balanceTracker.available.coins);
37
-
38
- expect(numAssets(balanceTracker.total.assets)).toBeLessThan(numAssets(totalBefore.assets));
39
- expect(numAssets(balanceTracker.total.assets)).toBeGreaterThan(numAssets(balanceTracker.available.assets));
40
-
41
- expect(balanceTracker.total.rewards).toBe(allRewards);
42
- expect(balanceTracker.available.rewards).toBe(availableRewards);
43
- });
44
- });
@@ -1,108 +0,0 @@
1
- import { CardanoSerializationLib, CSL, ProviderError, ProviderFailure } from '@cardano-sdk/core';
2
- import { dummyLogger } from 'ts-log';
3
- import { ledgerTip, providerStub, ProviderStub, queryTransactionsResult } from './mocks';
4
- import mockDelay from 'delay';
5
- import { TransactionTrackerEvent, InMemoryTransactionTracker, TransactionFailure } from '../src';
6
-
7
- jest.mock('delay', () => jest.fn().mockResolvedValue(void 0));
8
-
9
- describe('InMemoryTransactionTracker', () => {
10
- const POLL_INTERVAL = 1000;
11
- let ledgerTipSlot: number;
12
- let provider: ProviderStub;
13
- let txTracker: InMemoryTransactionTracker;
14
- let hash_transaction: jest.Mock;
15
-
16
- const mockHashTransactionReturn = (resultHash: string) => {
17
- hash_transaction.mockReturnValue({
18
- to_bytes() {
19
- return Buffer.from(resultHash);
20
- }
21
- });
22
- };
23
-
24
- beforeEach(() => {
25
- provider = providerStub();
26
- provider.queryTransactionsByHashes.mockReturnValue([queryTransactionsResult[0]]);
27
- hash_transaction = jest.fn();
28
- mockHashTransactionReturn('some-hash');
29
- txTracker = new InMemoryTransactionTracker({
30
- provider,
31
- csl: { hash_transaction } as unknown as CardanoSerializationLib,
32
- logger: dummyLogger,
33
- pollInterval: POLL_INTERVAL
34
- });
35
- ledgerTipSlot = ledgerTip.slot;
36
- (mockDelay as unknown as jest.Mock).mockReset();
37
- });
38
-
39
- describe('track', () => {
40
- let onTransaction: jest.Mock;
41
-
42
- beforeEach(() => {
43
- onTransaction = jest.fn();
44
- txTracker.on(TransactionTrackerEvent.NewTransaction, onTransaction);
45
- });
46
-
47
- it('cannot track transactions that have no validity interval', async () => {
48
- await expect(() =>
49
- txTracker.track({
50
- body: () => ({
51
- ttl: () => void 0
52
- })
53
- } as unknown as CSL.Transaction)
54
- ).rejects.toThrowError(TransactionFailure.CannotTrack);
55
- });
56
-
57
- describe('valid transaction', () => {
58
- let transaction: CSL.Transaction;
59
-
60
- beforeEach(async () => {
61
- transaction = {
62
- body: () => ({
63
- ttl: () => ledgerTipSlot
64
- })
65
- } as unknown as CSL.Transaction;
66
- });
67
-
68
- it('throws CannotTrack on ledger tip fetch error', async () => {
69
- provider.queryTransactionsByHashes.mockResolvedValueOnce([]);
70
- provider.ledgerTip.mockRejectedValueOnce(new ProviderError(ProviderFailure.Unknown));
71
- await expect(txTracker.track(transaction)).rejects.toThrowError(TransactionFailure.CannotTrack);
72
- expect(provider.ledgerTip).toBeCalledTimes(1);
73
- expect(provider.queryTransactionsByHashes).toBeCalledTimes(1);
74
- });
75
-
76
- it('polls provider at "pollInterval" until it returns the transaction', async () => {
77
- // resolve [] or reject with 404 should be treated the same
78
- provider.queryTransactionsByHashes.mockResolvedValueOnce([]);
79
- provider.queryTransactionsByHashes.mockRejectedValueOnce(new ProviderError(ProviderFailure.NotFound));
80
- await txTracker.track(transaction);
81
- expect(provider.queryTransactionsByHashes).toBeCalledTimes(3);
82
- expect(mockDelay).toBeCalledTimes(3);
83
- expect(mockDelay).toBeCalledWith(POLL_INTERVAL);
84
- });
85
-
86
- it('throws after timeout', async () => {
87
- provider.queryTransactionsByHashes.mockResolvedValueOnce([]);
88
- provider.ledgerTip.mockResolvedValueOnce({ slot: ledgerTipSlot + 1 });
89
- await expect(txTracker.track(transaction)).rejects.toThrowError(TransactionFailure.Timeout);
90
- });
91
-
92
- it('emits "transaction" event for tracked transactions, returns promise unique per pending tx', async () => {
93
- const promise1 = txTracker.track(transaction);
94
- const promise2 = txTracker.track(transaction);
95
- await promise1;
96
- await promise2;
97
- mockHashTransactionReturn('other-hash');
98
- await txTracker.track(transaction);
99
- expect(provider.queryTransactionsByHashes).toBeCalledTimes(2);
100
- expect(onTransaction).toBeCalledTimes(2);
101
- // assert it clears cache
102
- await txTracker.track(transaction);
103
- expect(provider.queryTransactionsByHashes).toBeCalledTimes(3);
104
- expect(onTransaction).toBeCalledTimes(3);
105
- });
106
- });
107
- });
108
- });
@@ -1,242 +0,0 @@
1
- /* eslint-disable unicorn/consistent-function-scoping */
2
- /* eslint-disable promise/param-names */
3
- import { roundRobinRandomImprove, InputSelector } from '@cardano-sdk/cip2';
4
- import { loadCardanoSerializationLib, CardanoSerializationLib, CSL, Ogmios, Cardano } from '@cardano-sdk/core';
5
- import { flushPromises, SelectionConstraints } from '@cardano-sdk/util-dev';
6
- import {
7
- providerStub,
8
- delegate,
9
- rewards,
10
- ProviderStub,
11
- utxo,
12
- delegationAndRewards,
13
- MockTransactionTracker
14
- } from './mocks';
15
- import {
16
- InMemoryUtxoRepository,
17
- KeyManagement,
18
- TransactionTrackerEvent,
19
- UtxoRepository,
20
- UtxoRepositoryEvent,
21
- UtxoRepositoryFields
22
- } from '../src';
23
- import { ogmiosToCsl } from '@cardano-sdk/core/src/Ogmios';
24
- import { TxIn, TxOut } from '@cardano-ogmios/schema';
25
- import { TransactionError, TransactionFailure } from '../src/TransactionError';
26
-
27
- const addresses = [
28
- 'addr_test1qq585l3hyxgj3nas2v3xymd23vvartfhceme6gv98aaeg9muzcjqw982pcftgx53fu5527z2cj2tkx2h8ux2vxsg475q2g7k3g'
29
- ];
30
-
31
- describe('InMemoryUtxoRepository', () => {
32
- let utxoRepository: UtxoRepository;
33
- let provider: ProviderStub;
34
- let inputSelector: InputSelector;
35
- let csl: CardanoSerializationLib;
36
- let keyManager: KeyManagement.KeyManager;
37
- let outputs: Set<CSL.TransactionOutput>;
38
- let txTracker: MockTransactionTracker;
39
-
40
- beforeEach(async () => {
41
- provider = providerStub();
42
- csl = await loadCardanoSerializationLib();
43
- inputSelector = roundRobinRandomImprove(csl);
44
- keyManager = KeyManagement.createInMemoryKeyManager({
45
- csl,
46
- mnemonicWords: KeyManagement.util.generateMnemonicWords(),
47
- networkId: 0,
48
- password: '123'
49
- });
50
- outputs = new Set([
51
- Ogmios.ogmiosToCsl(csl).txOut({
52
- address: addresses[0],
53
- value: { coins: 4_000_000 }
54
- }),
55
- Ogmios.ogmiosToCsl(csl).txOut({
56
- address: addresses[0],
57
- value: { coins: 2_000_000 }
58
- })
59
- ]);
60
- txTracker = new MockTransactionTracker();
61
- utxoRepository = new InMemoryUtxoRepository({
62
- csl,
63
- provider,
64
- keyManager,
65
- inputSelector,
66
- txTracker
67
- });
68
- });
69
-
70
- test('constructed state', async () => {
71
- expect(utxoRepository.allUtxos.length).toBe(0);
72
- expect(utxoRepository.allRewards).toBe(null);
73
- expect(utxoRepository.delegation).toBe(null);
74
- });
75
-
76
- test('sync', async () => {
77
- const syncedHandler = jest.fn();
78
- utxoRepository.on(UtxoRepositoryEvent.Changed, syncedHandler);
79
- await utxoRepository.sync();
80
- const expectedFields: UtxoRepositoryFields = {
81
- allUtxos: utxo,
82
- availableUtxos: utxo,
83
- allRewards: rewards,
84
- availableRewards: rewards,
85
- delegation: delegate
86
- };
87
- expect(utxoRepository).toMatchObject(expectedFields);
88
- expect(syncedHandler).toBeCalledTimes(1);
89
- expect(syncedHandler).toBeCalledWith(expectedFields);
90
- const identicalUtxo = [{ ...utxo[1][0] }, { ...utxo[1][1] }] as const; // clone UTxO
91
- provider.utxoDelegationAndRewards.mockResolvedValueOnce({
92
- utxo: [utxo[0], identicalUtxo],
93
- delegationAndRewards
94
- });
95
- await utxoRepository.sync();
96
- expect(utxoRepository.allUtxos.length).toBe(2);
97
- // Verify we're not replacing the object with an identical one in the UTxO set
98
- expect(utxoRepository.allUtxos).not.toContain(identicalUtxo);
99
- expect(utxoRepository.allUtxos).toContain(utxo[1]);
100
- expect(syncedHandler).toBeCalledTimes(2);
101
- });
102
-
103
- describe('selectInputs', () => {
104
- it('can be called without explicitly syncing', async () => {
105
- const result = await utxoRepository.selectInputs(outputs, SelectionConstraints.NO_CONSTRAINTS);
106
- expect(utxoRepository.allUtxos.length).toBe(3);
107
- expect(utxoRepository.allRewards).toBe(rewards);
108
- expect(utxoRepository.delegation).toBe(delegate);
109
- expect(result.selection.inputs.size).toBeGreaterThan(0);
110
- expect(result.selection.outputs).toBe(outputs);
111
- expect(result.selection.change.size).toBe(2);
112
- });
113
- });
114
-
115
- describe('availableUtxos and availableRewards', () => {
116
- let transactionUtxo: [TxIn, TxOut];
117
- let transaction: CSL.Transaction;
118
- let numUtxoPreTransaction: number;
119
- let rewardsPreTransaction: bigint;
120
- let onOutOfSync: jest.Mock;
121
- let completeConfirmation: Function;
122
- const transactionWithdrawal = 1n;
123
-
124
- const trackTransaction = async (confirmed: Promise<void>) => {
125
- const syncedHandler = jest.fn();
126
- utxoRepository.on(UtxoRepositoryEvent.Changed, syncedHandler);
127
- await txTracker.emit(TransactionTrackerEvent.NewTransaction, {
128
- transaction,
129
- confirmed
130
- });
131
- // transaction not yet confirmed
132
- expect(utxoRepository.availableUtxos).toHaveLength(utxoRepository.allUtxos.length - 1);
133
- expect(utxoRepository.availableUtxos).not.toContain(transactionUtxo);
134
- expect(syncedHandler).toBeCalledTimes(1);
135
- expect(syncedHandler).toBeCalledWith({
136
- allUtxos: utxo,
137
- availableUtxos: utxo.slice(1),
138
- allRewards: rewards,
139
- availableRewards: rewards - transactionWithdrawal,
140
- delegation: delegate
141
- } as UtxoRepositoryFields);
142
- };
143
-
144
- const assertThereAreNoPendingTransactionsOrRewards = () => {
145
- expect(utxoRepository.availableUtxos).toHaveLength(utxoRepository.allUtxos.length);
146
- expect(utxoRepository.allRewards).toBe(utxoRepository.availableRewards);
147
- };
148
-
149
- beforeEach(async () => {
150
- transactionUtxo = utxo[0];
151
- transaction = {
152
- body: () => ({
153
- inputs: () => ({
154
- len: () => 1,
155
- get: () => ogmiosToCsl(csl).txIn(transactionUtxo[0])
156
- }),
157
- withdrawals: () => ({
158
- keys: () => ({
159
- len: () => 1,
160
- get: () =>
161
- csl.RewardAddress.new(
162
- Cardano.NetworkId.testnet,
163
- csl.StakeCredential.from_keyhash(keyManager.stakeKey.hash())
164
- )
165
- }),
166
- len: () => 1,
167
- get: () => csl.BigNum.from_str(transactionWithdrawal.toString())
168
- })
169
- })
170
- } as unknown as CSL.Transaction;
171
- await utxoRepository.sync();
172
- numUtxoPreTransaction = utxoRepository.allUtxos.length;
173
- rewardsPreTransaction = utxoRepository.allRewards!;
174
- onOutOfSync = jest.fn();
175
- utxoRepository.on(UtxoRepositoryEvent.OutOfSync, onOutOfSync);
176
- });
177
-
178
- it('preconditions', () => {
179
- expect(utxoRepository.availableUtxos).toHaveLength(utxoRepository.allUtxos.length);
180
- expect(utxoRepository.availableUtxos).toContain(transactionUtxo);
181
- expect(utxoRepository.availableRewards).toBe(rewardsPreTransaction);
182
- });
183
-
184
- describe('sync success', () => {
185
- beforeEach(() => {
186
- // Simulate spent utxo and rewards
187
- expect(provider.utxoDelegationAndRewards).toBeCalledTimes(1);
188
- provider.utxoDelegationAndRewards.mockResolvedValueOnce({
189
- utxo: utxo.slice(1),
190
- delegationAndRewards: {
191
- ...delegationAndRewards,
192
- rewards: rewards - transactionWithdrawal
193
- }
194
- });
195
- });
196
-
197
- const confirmTxAndAssertUtxoRepositorySynced = async () => {
198
- await completeConfirmation!();
199
- await flushPromises();
200
- // Assert values from provider sync
201
- expect(provider.utxoDelegationAndRewards).toBeCalledTimes(2);
202
- expect(utxoRepository.availableUtxos).toHaveLength(numUtxoPreTransaction - 1);
203
- expect(utxoRepository.availableUtxos).not.toContain(transactionUtxo);
204
- expect(utxoRepository.availableRewards).toBe(rewardsPreTransaction - transactionWithdrawal);
205
- expect(onOutOfSync).not.toBeCalled();
206
- };
207
-
208
- it('transaction confirmed', async () => {
209
- await trackTransaction(new Promise<void>((resolve) => (completeConfirmation = resolve)));
210
- await confirmTxAndAssertUtxoRepositorySynced();
211
- assertThereAreNoPendingTransactionsOrRewards();
212
- });
213
-
214
- it('transaction confirmation failed', async () => {
215
- // setup for transaction to timeout
216
- await trackTransaction(
217
- new Promise<void>(
218
- (_, reject) => (completeConfirmation = () => reject(new TransactionError(TransactionFailure.Timeout)))
219
- )
220
- );
221
- await confirmTxAndAssertUtxoRepositorySynced();
222
- assertThereAreNoPendingTransactionsOrRewards();
223
- });
224
- });
225
-
226
- it('emits OutOfSync on sync failure', async () => {
227
- provider.utxoDelegationAndRewards.mockRejectedValueOnce(new Error('any error'));
228
-
229
- const confirmed = new Promise<void>((resolve) => (completeConfirmation = resolve));
230
- await trackTransaction(confirmed);
231
-
232
- // transaction confirmed
233
- await completeConfirmation!();
234
- await flushPromises();
235
- expect(utxoRepository.availableUtxos).toHaveLength(numUtxoPreTransaction);
236
- expect(utxoRepository.availableUtxos).toContain(transactionUtxo);
237
- expect(utxoRepository.allRewards).toBe(rewardsPreTransaction);
238
- expect(onOutOfSync).toBeCalledTimes(1);
239
- assertThereAreNoPendingTransactionsOrRewards();
240
- });
241
- });
242
- });
@@ -1,39 +0,0 @@
1
- import { Cardano, CardanoSerializationLib, loadCardanoSerializationLib } from '@cardano-sdk/core';
2
- import { Buffer } from 'buffer';
3
- import { KeyManagement } from '../../src';
4
-
5
- describe('InMemoryKeyManager', () => {
6
- let keyManager: KeyManagement.KeyManager;
7
- let csl: CardanoSerializationLib;
8
-
9
- beforeEach(async () => {
10
- csl = await loadCardanoSerializationLib();
11
- const mnemonicWords = KeyManagement.util.generateMnemonicWords();
12
- keyManager = KeyManagement.createInMemoryKeyManager({
13
- csl,
14
- mnemonicWords,
15
- networkId: Cardano.NetworkId.testnet,
16
- password: '123'
17
- });
18
- expect(keyManager.publicKey).toBeInstanceOf(csl.PublicKey);
19
- });
20
-
21
- test('initial state publicKey', async () => {
22
- expect(keyManager.publicKey).toBeDefined();
23
- expect(keyManager.publicParentKey).toBeDefined();
24
- });
25
-
26
- test('deriveAddress', async () => {
27
- const address = await keyManager.deriveAddress(0, 0);
28
- expect(address).toBeDefined();
29
- expect(keyManager.publicParentKey).toBeDefined();
30
- });
31
-
32
- test('signTransaction', async () => {
33
- const txHash = csl.TransactionHash.from_bytes(
34
- Buffer.from('8561258e210352fba2ac0488afed67b3427a27ccf1d41ec030c98a8199bc22ec', 'hex')
35
- );
36
- const witnessSet = await keyManager.signTransaction(txHash);
37
- expect(witnessSet).toBeInstanceOf(csl.TransactionWitnessSet);
38
- });
39
- });
@@ -1,87 +0,0 @@
1
- /* eslint-disable max-len */
2
- import { loadCardanoSerializationLib, CardanoSerializationLib, Cardano } from '@cardano-sdk/core';
3
- import { InputSelector, roundRobinRandomImprove } from '@cardano-sdk/cip2';
4
- import { ProviderStub, providerStub, txTracker } from './mocks';
5
- import {
6
- BalanceTracker,
7
- createSingleAddressWallet,
8
- InMemoryUtxoRepository,
9
- KeyManagement,
10
- SingleAddressWallet,
11
- SingleAddressWalletDependencies,
12
- UtxoRepository
13
- } from '../src';
14
-
15
- describe('Wallet', () => {
16
- const name = 'Test Wallet';
17
- let csl: CardanoSerializationLib;
18
- let inputSelector: InputSelector;
19
- let keyManager: KeyManagement.KeyManager;
20
- let provider: ProviderStub;
21
- let utxoRepository: UtxoRepository;
22
- let walletDependencies: SingleAddressWalletDependencies;
23
-
24
- beforeEach(async () => {
25
- csl = await loadCardanoSerializationLib();
26
- keyManager = KeyManagement.createInMemoryKeyManager({
27
- csl,
28
- mnemonicWords: KeyManagement.util.generateMnemonicWords(),
29
- networkId: Cardano.NetworkId.testnet,
30
- password: '123'
31
- });
32
- provider = providerStub();
33
- inputSelector = roundRobinRandomImprove(csl);
34
- utxoRepository = new InMemoryUtxoRepository({ csl, provider, keyManager, inputSelector, txTracker });
35
- walletDependencies = { csl, keyManager, provider, utxoRepository, txTracker };
36
- });
37
-
38
- test('createWallet', async () => {
39
- const wallet = await createSingleAddressWallet({ name }, walletDependencies);
40
- expect(wallet.address).toBeDefined();
41
- expect(wallet.name).toBe(name);
42
- expect(typeof wallet.initializeTx).toBe('function');
43
- expect(typeof wallet.signTx).toBe('function');
44
- expect(wallet.balance).toBeInstanceOf(BalanceTracker);
45
- });
46
-
47
- describe('wallet behaviour', () => {
48
- let wallet: SingleAddressWallet;
49
- const props = {
50
- outputs: new Set([
51
- {
52
- address:
53
- 'addr_test1qpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5ewvxwdrt70qlcpeeagscasafhffqsxy36t90ldv06wqrk2qum8x5w',
54
- value: { coins: 11_111_111 }
55
- }
56
- ])
57
- };
58
-
59
- beforeEach(async () => {
60
- wallet = await createSingleAddressWallet({ name }, walletDependencies);
61
- });
62
-
63
- test('initializeTx', async () => {
64
- const txInternals = await wallet.initializeTx(props);
65
- expect(txInternals.body).toBeInstanceOf(csl.TransactionBody);
66
- expect(txInternals.hash).toBeInstanceOf(csl.TransactionHash);
67
- });
68
-
69
- test('signTx', async () => {
70
- const { body, hash } = await wallet.initializeTx(props);
71
- const tx = await wallet.signTx(body, hash);
72
- await expect(tx.body().outputs().len()).toBe(2);
73
- await expect(tx.body().inputs().len()).toBeGreaterThan(0);
74
- });
75
-
76
- test('submitTx', async () => {
77
- const { body, hash } = await wallet.initializeTx(props);
78
- const tx = await wallet.signTx(body, hash);
79
- const { submitted, confirmed } = wallet.submitTx(tx);
80
- await confirmed;
81
- expect(provider.submitTx).toBeCalledTimes(1);
82
- expect(provider.submitTx).toBeCalledWith(tx);
83
- expect(txTracker.track).toBeCalledTimes(1);
84
- expect(txTracker.track).toBeCalledWith(tx, submitted);
85
- });
86
- });
87
- });