Skip to content

Commit

Permalink
feat(wallet): add Wallet.timeSettings$
Browse files Browse the repository at this point in the history
add integration test as example of computing tx date
  • Loading branch information
mkazlauskas committed Jan 18, 2022
1 parent 898b0d5 commit 14467e7
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 10 deletions.
1 change: 1 addition & 0 deletions packages/wallet/.env.example
@@ -1,5 +1,6 @@
WALLET_PROVIDER=blockfrost
STAKE_POOL_SEARCH_PROVIDER=stub
TIME_SETTINGS_PROVIDER=stub_testnet
BLOCKFROST_API_KEY=testnetNElagmhpQDubE6Ic4XBUVJjV5DROyijO
NETWORK_ID=0
MNEMONIC_WORDS="actor scout worth mansion thumb device mass pave gospel secret height document merge text broom kind lesson invest across estate erase interest end century"
Expand Down
8 changes: 8 additions & 0 deletions packages/wallet/src/SingleAddressWallet.ts
Expand Up @@ -6,6 +6,8 @@ import {
NetworkInfo,
ProtocolParametersRequiredByWallet,
StakePoolSearchProvider,
TimeSettings,
TimeSettingsProvider,
WalletProvider,
coreToCsl
} from '@cardano-sdk/core';
Expand Down Expand Up @@ -56,6 +58,7 @@ export interface SingleAddressWalletDependencies {
readonly walletProvider: WalletProvider;
readonly stakePoolSearchProvider: StakePoolSearchProvider;
readonly assetProvider: AssetProvider;
readonly timeSettingsProvider: TimeSettingsProvider;
readonly inputSelector?: InputSelector;
readonly logger?: Logger;
}
Expand All @@ -80,6 +83,7 @@ export class SingleAddressWallet implements Wallet {
addresses$: TrackerSubject<GroupedAddress[]>;
protocolParameters$: TrackerSubject<ProtocolParametersRequiredByWallet>;
genesisParameters$: TrackerSubject<Cardano.CompactGenesis>;
timeSettings$: TrackerSubject<TimeSettings[]>;
assets$: TrackerSubject<Assets>;
name: string;

Expand All @@ -98,6 +102,7 @@ export class SingleAddressWallet implements Wallet {
stakePoolSearchProvider,
keyAgent,
assetProvider,
timeSettingsProvider,
logger = dummyLogger,
inputSelector = roundRobinRandomImprove()
}: SingleAddressWalletDependencies
Expand All @@ -117,6 +122,9 @@ export class SingleAddressWallet implements Wallet {
coldObservableProvider(walletProvider.networkInfo, retryBackoffConfig, tipBlockHeight$, isEqual)
);
const epoch$ = distinctEpoch(this.networkInfo$);
this.timeSettings$ = new TrackerSubject(
coldObservableProvider(timeSettingsProvider, retryBackoffConfig, epoch$, isEqual)
);
this.protocolParameters$ = new TrackerSubject(
coldObservableProvider(walletProvider.currentWalletProtocolParameters, retryBackoffConfig, epoch$, isEqual)
);
Expand Down
3 changes: 2 additions & 1 deletion packages/wallet/src/types.ts
@@ -1,5 +1,5 @@
import { Balance, BehaviorObservable, DelegationTracker, TransactionalTracker, TransactionsTracker } from './services';
import { Cardano, NetworkInfo, ProtocolParametersRequiredByWallet } from '@cardano-sdk/core';
import { Cardano, NetworkInfo, ProtocolParametersRequiredByWallet, TimeSettings } from '@cardano-sdk/core';
import { GroupedAddress } from './KeyManagement';
import { NftMetadata } from './NftMetadata';
import { SelectionSkeleton } from '@cardano-sdk/cip2';
Expand Down Expand Up @@ -43,6 +43,7 @@ export interface Wallet {
readonly utxo: TransactionalTracker<Cardano.Utxo[]>;
readonly transactions: TransactionsTracker;
readonly tip$: BehaviorObservable<Cardano.Tip>;
readonly timeSettings$: BehaviorObservable<TimeSettings[]>;
readonly genesisParameters$: BehaviorObservable<Cardano.CompactGenesis>;
readonly networkInfo$: BehaviorObservable<NetworkInfo>;
readonly protocolParameters$: BehaviorObservable<ProtocolParametersRequiredByWallet>;
Expand Down
13 changes: 10 additions & 3 deletions packages/wallet/test/SingleAddressWallet.test.ts
@@ -1,7 +1,7 @@
/* eslint-disable max-len */
import * as mocks from './mocks';
import { AssetId, createStubStakePoolSearchProvider } from '@cardano-sdk/util-dev';
import { Cardano } from '@cardano-sdk/core';
import { AssetId, createStubStakePoolSearchProvider, createStubTimeSettingsProvider } from '@cardano-sdk/util-dev';
import { Cardano, testnetTimeSettings } from '@cardano-sdk/core';
import { KeyManagement, SingleAddressWallet } from '../src';
import { firstValueFrom, skip } from 'rxjs';
import { testKeyAgent } from './mocks';
Expand All @@ -20,11 +20,15 @@ describe('SingleAddressWallet', () => {
walletProvider = mocks.mockWalletProvider();
assetProvider = mocks.mockAssetProvider();
const stakePoolSearchProvider = createStubStakePoolSearchProvider();
const timeSettingsProvider = createStubTimeSettingsProvider(testnetTimeSettings);
keyAgent.deriveAddress = jest.fn().mockResolvedValue({
address,
rewardAccount
});
wallet = new SingleAddressWallet({ name }, { assetProvider, keyAgent, stakePoolSearchProvider, walletProvider });
wallet = new SingleAddressWallet(
{ name },
{ assetProvider, keyAgent, stakePoolSearchProvider, timeSettingsProvider, walletProvider }
);
});

afterEach(() => wallet.shutdown());
Expand Down Expand Up @@ -84,6 +88,9 @@ describe('SingleAddressWallet', () => {
it('"assets$"', async () => {
expect(await firstValueFrom(wallet.assets$)).toEqual(new Map([[AssetId.TSLA, mocks.asset]]));
});
it('timeSettings$', async () => {
expect(await firstValueFrom(wallet.timeSettings$)).toEqual(testnetTimeSettings);
});
});

describe('creating transactions', () => {
Expand Down
11 changes: 10 additions & 1 deletion packages/wallet/test/e2e/SingleAddressWallet/delegation.test.ts
@@ -1,6 +1,14 @@
import { Cardano } from '@cardano-sdk/core';
import { SingleAddressWallet, StakeKeyStatus, Wallet } from '../../../src';
import { assetProvider, keyAgentReady, poolId1, poolId2, stakePoolSearchProvider, walletProvider } from '../config';
import {
assetProvider,
keyAgentReady,
poolId1,
poolId2,
stakePoolSearchProvider,
timeSettingsProvider,
walletProvider
} from '../config';
import { distinctUntilChanged, filter, firstValueFrom, map, merge, mergeMap, skip, tap, timer } from 'rxjs';

const faucetAddress = Cardano.Address(
Expand Down Expand Up @@ -64,6 +72,7 @@ describe('SingleAddressWallet/delegation', () => {
assetProvider,
keyAgent: await keyAgentReady,
stakePoolSearchProvider,
timeSettingsProvider,
walletProvider
}
);
Expand Down
3 changes: 2 additions & 1 deletion packages/wallet/test/e2e/SingleAddressWallet/nft.test.ts
@@ -1,6 +1,6 @@
import { Cardano } from '@cardano-sdk/core';
import { KeyManagement, SingleAddressWallet, Wallet } from '../../../src';
import { assetProvider, keyAgentReady, stakePoolSearchProvider, walletProvider } from '../config';
import { assetProvider, keyAgentReady, stakePoolSearchProvider, timeSettingsProvider, walletProvider } from '../config';
import { combineLatest, filter, firstValueFrom, map } from 'rxjs';

describe('SingleAddressWallet/delegation', () => {
Expand All @@ -26,6 +26,7 @@ describe('SingleAddressWallet/delegation', () => {
assetProvider,
keyAgent: await keyAgentReady,
stakePoolSearchProvider,
timeSettingsProvider,
walletProvider
}
);
Expand Down
12 changes: 10 additions & 2 deletions packages/wallet/test/e2e/config.ts
@@ -1,7 +1,7 @@
import { Cardano } from '@cardano-sdk/core';
import { Cardano, testnetTimeSettings } from '@cardano-sdk/core';
import { InMemoryKeyAgent } from '../../src/KeyManagement';
import { blockfrostAssetProvider, blockfrostWalletProvider } from '@cardano-sdk/blockfrost';
import { createStubStakePoolSearchProvider } from '@cardano-sdk/util-dev';
import { createStubStakePoolSearchProvider, createStubTimeSettingsProvider } from '@cardano-sdk/util-dev';

const networkId = Number.parseInt(process.env.NETWORK_ID || '');
if (Number.isNaN(networkId)) throw new Error('NETWORK_ID not set');
Expand Down Expand Up @@ -43,6 +43,14 @@ export const stakePoolSearchProvider = (() => {
throw new Error(`STAKE_POOL_SEARCH_PROVIDER unsupported: ${stakePoolSearchProviderName}`);
})();

export const timeSettingsProvider = (() => {
const timeSettingsProviderName = process.env.TIME_SETTINGS_PROVIDER;
if (timeSettingsProviderName === 'stub_testnet') {
return createStubTimeSettingsProvider(testnetTimeSettings);
}
throw new Error(`TIME_SETTINGS_PROVIDER unsupported: ${timeSettingsProviderName}`);
})();

if (!process.env.POOL_ID_1) throw new Error('POOL_ID_1 not set');
export const poolId1 = Cardano.PoolId(process.env.POOL_ID_1!);

Expand Down
42 changes: 42 additions & 0 deletions packages/wallet/test/integration/transactionTime.test.ts
@@ -0,0 +1,42 @@
import { Cardano, createSlotTimeCalc, testnetTimeSettings } from '@cardano-sdk/core';
import { KeyManagement, SingleAddressWallet, SingleAddressWalletProps } from '../../src';
import { createStubStakePoolSearchProvider, createStubTimeSettingsProvider } from '@cardano-sdk/util-dev';
import { firstValueFrom } from 'rxjs';
import { mockAssetProvider, mockWalletProvider } from '../mocks';

const walletProps: SingleAddressWalletProps = { name: 'some-wallet' };
const networkId = Cardano.NetworkId.mainnet;
const mnemonicWords = KeyManagement.util.generateMnemonicWords();
const getPassword = async () => Buffer.from('your_password');

describe('integration/transactionTime', () => {
let keyAgent: KeyManagement.KeyAgent;
let wallet: SingleAddressWallet;

beforeAll(async () => {
keyAgent = await KeyManagement.InMemoryKeyAgent.fromBip39MnemonicWords({
getPassword,
mnemonicWords,
networkId
});
const walletProvider = mockWalletProvider();
const stakePoolSearchProvider = createStubStakePoolSearchProvider();
const timeSettingsProvider = createStubTimeSettingsProvider(testnetTimeSettings);
const assetProvider = mockAssetProvider();
wallet = new SingleAddressWallet(walletProps, {
assetProvider,
keyAgent,
stakePoolSearchProvider,
timeSettingsProvider,
walletProvider
});
});

it('provides utils necessary for computing transaction time', async () => {
const transactions = await firstValueFrom(wallet.transactions.history.incoming$);
const timeSettings = await firstValueFrom(wallet.timeSettings$);
const slotTimeCalc = createSlotTimeCalc(timeSettings);
const transactionTime = slotTimeCalc(transactions[0].blockHeader.slot);
expect(typeof transactionTime.getTime()).toBe('number');
});
});
6 changes: 4 additions & 2 deletions packages/wallet/test/integration/withdrawal.test.ts
@@ -1,6 +1,6 @@
import { Cardano } from '@cardano-sdk/core';
import { Cardano, testnetTimeSettings } from '@cardano-sdk/core';
import { KeyManagement, SingleAddressWallet, SingleAddressWalletProps, TransactionFailure } from '../../src';
import { createStubStakePoolSearchProvider } from '@cardano-sdk/util-dev';
import { createStubStakePoolSearchProvider, createStubTimeSettingsProvider } from '@cardano-sdk/util-dev';
import { firstValueFrom } from 'rxjs';
import { mockAssetProvider, mockWalletProvider } from '../mocks';

Expand All @@ -21,11 +21,13 @@ describe('integration/withdrawal', () => {
});
const walletProvider = mockWalletProvider();
const stakePoolSearchProvider = createStubStakePoolSearchProvider();
const timeSettingsProvider = createStubTimeSettingsProvider(testnetTimeSettings);
const assetProvider = mockAssetProvider();
wallet = new SingleAddressWallet(walletProps, {
assetProvider,
keyAgent,
stakePoolSearchProvider,
timeSettingsProvider,
walletProvider
});
});
Expand Down

0 comments on commit 14467e7

Please sign in to comment.