Skip to content

Commit

Permalink
feat: add governance voting tab [LW-11519] (#3240)
Browse files Browse the repository at this point in the history
* feat: Add navigation with governance to voting page [LW-11519]

* feat: add delegate votes API call and integrate it with mobx voting store

* feat: Add governance voting form [LW-11519]

* feat: voting power delegation confirmation dialog

* chore: Add changelog entry [LW-11519]

* feat: useconstructTx endpoint to calculate fee and for HWs, fix validation in form, improve styling

* feat: Recognize and style voting transactions [LW-11519]

* feat: redirect the user to the wallet of coice after successfull VP delegation

* feat: add i18n to confirmation dialog and handle API error cases

* feat: Track successfully casted votes [LW-11519]

* feat: add final translations [LW-11519]

* fix: Catch send error for staking conway wallets which have not registered voting rights yet [LW-11518]

* feat: add HW support for VP delegation (#3243)

* feat: add ledger support for VP delegation

* feat: add trezor support for VP delegation

---------

Signed-off-by: Dominik Guzei <[email protected]>
Co-authored-by: Szymon Masłowski <[email protected]>
Co-authored-by: Przemysław Włodek <[email protected]>
  • Loading branch information
3 people authored Nov 27, 2024
1 parent a852174 commit ba63f08
Show file tree
Hide file tree
Showing 48 changed files with 2,113 additions and 153 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@

## vNext

### Features

- Added Cardano governance voting tab ([PR 3240](https://github.com/input-output-hk/daedalus/pull/3240))

### Chores

- Update `cardano-node` to 10.1.2 via `cardano-wallet` v2024-11-18 ([PR 3229](https://github.com/input-output-hk/daedalus/pull/3229))

### Fixes

- Handle createTransaction error when Conway era wallet has staking rewards but has not participated in governance yet ([PR 3237](https://github.com/input-output-hk/daedalus/pull/3237)

## 6.0.2

### Fixes
Expand Down
34 changes: 34 additions & 0 deletions source/common/utils/assertIsBech32WithPrefix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { bech32, Decoded } from 'bech32';

const MAX_BECH32_LENGTH_LIMIT = 1023;

const isOneOf = <T>(target: T, options: T | T[]) =>
(Array.isArray(options) && options.includes(target)) || target === options;

export const assertIsBech32WithPrefix = (
target: string,
prefix: string | string[],
expectedDecodedLength?: number | number[]
): void => {
let decoded: Decoded;
try {
decoded = bech32.decode(target, MAX_BECH32_LENGTH_LIMIT);
} catch (error) {
throw new Error(
`expected bech32-encoded string with '${prefix}' prefix; ${error}`
);
}
if (!isOneOf(decoded.prefix, prefix)) {
throw new Error(
`expected bech32 prefix '${prefix}', got '${decoded.prefix}''`
);
}
if (
expectedDecodedLength &&
!isOneOf(decoded.words.length, expectedDecodedLength)
) {
throw new Error(
`expected decoded length of '${expectedDecodedLength}', got '${decoded.words.length}'`
);
}
};
21 changes: 16 additions & 5 deletions source/renderer/app/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import VotingRegistrationPage from './containers/voting/VotingRegistrationPage';
import { IS_STAKING_INFO_PAGE_AVAILABLE } from './config/stakingConfig';
import AnalyticsConsentPage from './containers/profile/AnalyticsConsentPage';
import TrackedRoute from './analytics/TrackedRoute';
import Voting from './containers/voting/Voting';
import VotingGovernancePage from './containers/voting/VotingGovernancePage';

export const Routes = withRouter(() => (
<Route path={ROUTES.ROOT}>
Expand Down Expand Up @@ -205,11 +207,20 @@ export const Routes = withRouter(() => (
component={RedeemItnRewardsContainer}
/>
</Route>
<TrackedRoute
pageTitle="Voting Registration"
path={ROUTES.VOTING.REGISTRATION}
component={VotingRegistrationPage}
/>
<Route path={ROUTES.VOTING.ROOT}>
<Voting>
<TrackedRoute
pageTitle="Voting Registration"
path={ROUTES.VOTING.REGISTRATION}
component={VotingRegistrationPage}
/>
<TrackedRoute
pageTitle="Voting Governance"
path={ROUTES.VOTING.GOVERNANCE}
component={VotingGovernancePage}
/>
</Voting>
</Route>
</Switch>
</Root>
</Route>
Expand Down
4 changes: 2 additions & 2 deletions source/renderer/app/analytics/MatomoAnalyticsTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export class MatomoAnalyticsTracker implements AnalyticsTracker {
return this.#analyticsClient.sendPageNavigationEvent(pageTitle);
}

sendEvent(category: string, name: string, action?: string) {
return this.#analyticsClient.sendEvent(category, name, action);
sendEvent(category: string, name: string, action?: string, value?: number) {
return this.#analyticsClient.sendEvent(category, name, action, value);
}

async #enableTrackingIfAccepted() {
Expand Down
4 changes: 3 additions & 1 deletion source/renderer/app/analytics/MatomoClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,16 @@ export class MatomoClient implements AnalyticsClient {
sendEvent = async (
category: string,
action: string,
name?: string
name?: string,
value?: number
): Promise<void> => {
this.matomoTracker.track({
_id: this.userId,
ca: 1,
e_c: category,
e_a: action,
e_n: name,
e_v: value,
url: this.getAnalyticsURL(),
});
};
Expand Down
14 changes: 12 additions & 2 deletions source/renderer/app/analytics/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export interface AnalyticsClient {
sendPageNavigationEvent(pageTitle: string): Promise<void>;
sendEvent(category: string, action: string, name?: string): Promise<void>;
sendEvent(
category: string,
action: string,
name?: string,
value?: number
): Promise<void>;
}

export enum AnalyticsAcceptanceStatus {
Expand All @@ -13,7 +18,12 @@ export interface AnalyticsTracker {
enableTracking(): Promise<void>;
disableTracking(): void;
sendPageNavigationEvent(pageTitle: string): void;
sendEvent(category: EventCategories, name: string, action?: string): void;
sendEvent(
category: EventCategories,
name: string,
action?: string,
value?: number
): void;
}

export enum EventCategories {
Expand Down
Loading

0 comments on commit ba63f08

Please sign in to comment.