Skip to content

Commit 6362d83

Browse files
committed
feat(wallet): implement DrepStatusTracker
DrepStatusTracker fetches DrepInfo from a DrepProvider. delegation.rewardAccounts$ drepDelegatee contains the associated DRepInfo. DrepStatusTracker refreshes the DRep info in two scenarios: 1. Voting delegations or stake deregistrations are found in transaction history. 2. Transaction builder is used to either build().inspect() or build().sign(). Refetch at this point is done to ensure the tx builder is working with up-to-date information BREAKING CHANGE: DRepDelegatee type has changed to include DrepInfo - createRewardsAccountTracker now requires a drepInfo$ dependency. - BaseWallet requires a DrepProvider as a dependency
1 parent b5a4d91 commit 6362d83

39 files changed

+811
-130
lines changed

.github/workflows/continuous-integration-blockfrost-e2e.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ env:
1414
TEST_CLIENT_ASSET_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:3015"}'
1515
TEST_CLIENT_CHAIN_HISTORY_PROVIDER: 'blockfrost'
1616
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:3015"}'
17+
TEST_CLIENT_DREP_PROVIDER: 'blockfrost'
18+
TEST_CLIENT_DREP_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:3015"}'
1719
TEST_CLIENT_HANDLE_PROVIDER: 'http'
1820
TEST_CLIENT_HANDLE_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4011/"}'
1921
TEST_CLIENT_NETWORK_INFO_PROVIDER: 'blockfrost'

.github/workflows/continuous-integration-e2e.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ env:
1414
TEST_CLIENT_ASSET_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4014/"}'
1515
TEST_CLIENT_CHAIN_HISTORY_PROVIDER: 'ws'
1616
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4000/"}'
17+
TEST_CLIENT_DREP_PROVIDER: 'blockfrost'
18+
TEST_CLIENT_DREP_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:3015"}'
1719
TEST_CLIENT_HANDLE_PROVIDER: 'http'
1820
TEST_CLIENT_HANDLE_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:4011/"}'
1921
TEST_CLIENT_NETWORK_INFO_PROVIDER: 'ws'

packages/core/src/Cardano/types/DelegationsAndRewards.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { DelegateRepresentative } from './Governance';
1+
import { AlwaysAbstain, AlwaysNoConfidence } from './Governance';
2+
import { DRepInfo } from '../../Provider';
23
import { Lovelace } from './Value';
34
import { Metadatum } from './AuxiliaryData';
45
import { PoolId, PoolIdHex, StakePool } from './StakePool';
@@ -24,7 +25,7 @@ export enum StakeCredentialStatus {
2425
Unregistered = 'UNREGISTERED'
2526
}
2627

27-
export type DRepDelegatee = { delegateRepresentative: DelegateRepresentative };
28+
export type DRepDelegatee = { delegateRepresentative: DRepInfo | AlwaysAbstain | AlwaysNoConfidence };
2829

2930
export interface RewardAccountInfo {
3031
address: RewardAccount;

packages/core/src/Cardano/types/Governance.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as Crypto from '@cardano-sdk/crypto';
22
import { Credential, CredentialType, RewardAccount } from '../Address';
3+
import { DRepInfo } from '../../Provider';
34
import { EpochNo, Fraction, ProtocolVersion, TransactionId } from '.';
45
import { Lovelace } from './Value';
56
import { ProtocolParametersUpdateConway } from './ProtocolParameters';
@@ -187,10 +188,14 @@ export type AlwaysNoConfidence = {
187188

188189
export type DelegateRepresentative = Credential | AlwaysAbstain | AlwaysNoConfidence;
189190

190-
export const isDRepCredential = (deleg: DelegateRepresentative): deleg is Credential => !('__typename' in deleg);
191+
export const isDrepInfo = (drep: DelegateRepresentative | DRepInfo): drep is DRepInfo =>
192+
'id' in drep && 'active' in drep;
191193

192-
export const isDRepAlwaysAbstain = (deleg: DelegateRepresentative): deleg is AlwaysAbstain =>
193-
!isDRepCredential(deleg) && deleg.__typename === 'AlwaysAbstain';
194+
export const isDRepCredential = (deleg: DelegateRepresentative | DRepInfo): deleg is Credential =>
195+
'type' in deleg && 'hash' in deleg;
194196

195-
export const isDRepAlwaysNoConfidence = (deleg: DelegateRepresentative): deleg is AlwaysNoConfidence =>
196-
!isDRepCredential(deleg) && deleg.__typename === 'AlwaysNoConfidence';
197+
export const isDRepAlwaysAbstain = (deleg: DelegateRepresentative | DRepInfo): deleg is AlwaysAbstain =>
198+
'__typename' in deleg && deleg.__typename === 'AlwaysAbstain';
199+
200+
export const isDRepAlwaysNoConfidence = (deleg: DelegateRepresentative | DRepInfo): deleg is AlwaysNoConfidence =>
201+
'__typename' in deleg && deleg.__typename === 'AlwaysNoConfidence';

packages/e2e/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ TEST_CLIENT_ASSET_PROVIDER=http
1414
TEST_CLIENT_ASSET_PROVIDER_PARAMS='{"baseUrl":"http://localhost:4014/"}'
1515
TEST_CLIENT_CHAIN_HISTORY_PROVIDER=ws
1616
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS='{"baseUrl":"http://localhost:4000/"}'
17+
TEST_CLIENT_DREP_PROVIDER='blockfrost'
18+
TEST_CLIENT_DREP_PROVIDER_PARAMS='{"baseUrl":"http://localhost:3015"}'
1719
TEST_CLIENT_HANDLE_PROVIDER=http
1820
TEST_CLIENT_HANDLE_PROVIDER_PARAMS='{"baseUrl":"http://localhost:4011/"}'
1921
TEST_CLIENT_NETWORK_INFO_PROVIDER=ws

packages/e2e/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ KEY_MANAGEMENT_PROVIDER=inMemory
160160
KEY_MANAGEMENT_PARAMS='{"accountIndex": 0, "chainId":{"networkId": 0, "networkMagic": 888}, "passphrase":"some_passphrase","mnemonic":""}'
161161
TEST_CLIENT_ASSET_PROVIDER=http
162162
TEST_CLIENT_ASSET_PROVIDER_PARAMS='{"baseUrl":"http://localhost:4000"}'
163+
TEST_CLIENT_DREP_PROVIDER='blockfrost'
164+
TEST_CLIENT_DREP_PROVIDER_PARAMS='{"baseUrl":"http://localhost:3015"}'
163165
TEST_CLIENT_CHAIN_HISTORY_PROVIDER=http
164166
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS='{"baseUrl":"http://localhost:4000"}'
165167
TEST_CLIENT_NETWORK_INFO_PROVIDER=http

packages/e2e/src/environment.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ const validators = {
9292
TEST_CLIENT_ASSET_PROVIDER_PARAMS: providerParams(),
9393
TEST_CLIENT_CHAIN_HISTORY_PROVIDER: str(),
9494
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS: providerParams(),
95+
TEST_CLIENT_DREP_PROVIDER: str({ choices: ['blockfrost'] }),
96+
TEST_CLIENT_DREP_PROVIDER_PARAMS: providerParams(),
9597
TEST_CLIENT_HANDLE_PROVIDER: str(),
9698
TEST_CLIENT_HANDLE_PROVIDER_PARAMS: providerParams(),
9799
TEST_CLIENT_NETWORK_INFO_PROVIDER: str(),
@@ -145,6 +147,8 @@ export const walletVariables = [
145147
'TEST_CLIENT_ASSET_PROVIDER_PARAMS',
146148
'TEST_CLIENT_CHAIN_HISTORY_PROVIDER',
147149
'TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS',
150+
'TEST_CLIENT_DREP_PROVIDER',
151+
'TEST_CLIENT_DREP_PROVIDER_PARAMS',
148152
'TEST_CLIENT_HANDLE_PROVIDER',
149153
'TEST_CLIENT_HANDLE_PROVIDER_PARAMS',
150154
'KEY_MANAGEMENT_PARAMS',

packages/e2e/src/factories.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
AssetProvider,
1919
Cardano,
2020
ChainHistoryProvider,
21+
DRepProvider,
2122
HandleProvider,
2223
NetworkInfoProvider,
2324
ProviderFactory,
@@ -39,6 +40,7 @@ import {
3940
BlockfrostAssetProvider,
4041
BlockfrostChainHistoryProvider,
4142
BlockfrostClient,
43+
BlockfrostDRepProvider,
4244
BlockfrostNetworkInfoProvider,
4345
BlockfrostRewardsProvider,
4446
BlockfrostTxSubmitProvider,
@@ -81,6 +83,7 @@ export type CreateKeyAgent = (dependencies: KeyAgentDependencies) => Promise<Asy
8183
export const keyManagementFactory = new ProviderFactory<CreateKeyAgent>();
8284
export const assetProviderFactory = new ProviderFactory<AssetProvider>();
8385
export const chainHistoryProviderFactory = new ProviderFactory<ChainHistoryProvider>();
86+
export const drepProviderFactory = new ProviderFactory<DRepProvider>();
8487
export const networkInfoProviderFactory = new ProviderFactory<NetworkInfoProvider>();
8588
export const rewardsProviderFactory = new ProviderFactory<RewardsProvider>();
8689
export const txSubmitProviderFactory = new ProviderFactory<TxSubmitProvider>();
@@ -181,6 +184,19 @@ chainHistoryProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, lo
181184
});
182185
});
183186

187+
drepProviderFactory.register(BLOCKFROST_PROVIDER, async (params: any, logger): Promise<DRepProvider> => {
188+
if (params.baseUrl === undefined) throw new Error(`${BlockfrostDRepProvider.name}: ${MISSING_URL_PARAM}`);
189+
190+
return new Promise<DRepProvider>(async (resolve) => {
191+
resolve(
192+
new BlockfrostDRepProvider(
193+
new BlockfrostClient({ baseUrl: params.baseUrl }, { rateLimiter: { schedule: (task) => task() } }),
194+
logger
195+
)
196+
);
197+
});
198+
});
199+
184200
networkInfoProviderFactory.register(
185201
HTTP_PROVIDER,
186202
async (params: any, logger: Logger): Promise<NetworkInfoProvider> => {
@@ -483,6 +499,11 @@ export const getWallet = async (props: GetWalletProps) => {
483499
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
484500
logger
485501
),
502+
drepProvider: await drepProviderFactory.create(
503+
env.TEST_CLIENT_DREP_PROVIDER,
504+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
505+
logger
506+
),
486507
handleProvider: await handleProviderFactory.create(
487508
env.TEST_CLIENT_HANDLE_PROVIDER,
488509
env.TEST_CLIENT_HANDLE_PROVIDER_PARAMS,
@@ -571,6 +592,11 @@ export const getSharedWallet = async (props: GetSharedWalletProps) => {
571592
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
572593
logger
573594
),
595+
drepProvider: await drepProviderFactory.create(
596+
env.TEST_CLIENT_DREP_PROVIDER,
597+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
598+
logger
599+
),
574600
handleProvider: await handleProviderFactory.create(
575601
env.TEST_CLIENT_HANDLE_PROVIDER,
576602
env.TEST_CLIENT_HANDLE_PROVIDER_PARAMS,

packages/e2e/src/scripts/generate-dotenv.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ TEST_CLIENT_ASSET_PROVIDER=http
4040
TEST_CLIENT_ASSET_PROVIDER_PARAMS='{\"baseUrl\":\"${url}\"}'
4141
TEST_CLIENT_CHAIN_HISTORY_PROVIDER=ws
4242
TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS='{\"baseUrl\":\"${url}\"}'
43+
TEST_CLIENT_DREP_PROVIDER: 'blockfrost'
44+
# TODO: use blockfrost URL
45+
TEST_CLIENT_DREP_PROVIDER_PARAMS: '{"baseUrl":"http://localhost:3015"}'
4346
TEST_CLIENT_HANDLE_PROVIDER=http
4447
TEST_CLIENT_HANDLE_PROVIDER_PARAMS='{\"baseUrl\":\"${url}\"}'
4548
TEST_CLIENT_NETWORK_INFO_PROVIDER=ws

packages/e2e/test/load-test-custom/wallet-init/wallet-init.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
assetProviderFactory,
1717
bip32Ed25519Factory,
1818
chainHistoryProviderFactory,
19+
drepProviderFactory,
1920
getEnv,
2021
getLoadTestScheduler,
2122
keyManagementFactory,
@@ -55,6 +56,11 @@ const getProviders = async () => ({
5556
env.TEST_CLIENT_CHAIN_HISTORY_PROVIDER_PARAMS,
5657
logger
5758
),
59+
drepProvider: await drepProviderFactory.create(
60+
env.TEST_CLIENT_DREP_PROVIDER,
61+
env.TEST_CLIENT_DREP_PROVIDER_PARAMS,
62+
logger
63+
),
5864
networkInfoProvider: await networkInfoProviderFactory.create(
5965
env.TEST_CLIENT_NETWORK_INFO_PROVIDER,
6066
env.TEST_CLIENT_NETWORK_INFO_PROVIDER_PARAMS,

0 commit comments

Comments
 (0)