Skip to content

feat(frontend): integrate pow into loader and guard logic #5890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 108 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
17b07aa
feat: integrate pow into loader and guard logic (scope 7)
DecentAgeCoder Apr 16, 2025
362ae5c
🤖 Apply formatting changes
github-actions[bot] Apr 16, 2025
5e97ad9
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder Apr 25, 2025
042e19c
Replaced `POW_ENABLED` with `POW_FEATURE_ENABLED` for clarity and con…
DecentAgeCoder Apr 25, 2025
f029811
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder Apr 25, 2025
80a3ff7
Merge branch 'main' into feat/frontend/pow/protect-allow-signing-7
AntonioVentilii Apr 25, 2025
af63801
Merge branch 'main' into feat/frontend/pow/protect-allow-signing-7
DecentAgeCoder Apr 28, 2025
ea2f451
Merge remote-tracking branch 'refs/remotes/origin/main' into feat/fro…
DecentAgeCoder Apr 28, 2025
322700c
Merge branch 'refs/heads/main' into feat/frontend/pow/protect-allow-s…
DecentAgeCoder Apr 29, 2025
79a1d16
Renamed POW_ENABLED to POW_FEATURE_ENABLED
DecentAgeCoder Apr 29, 2025
b5e5713
Using the re-factored parseBoolEnvVar(..) function
DecentAgeCoder Apr 29, 2025
014881b
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder Apr 30, 2025
366aaa8
Merge branch 'refs/heads/main' into feat/frontend/pow/protect-allow-s…
DecentAgeCoder May 1, 2025
0c9e0ab
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 8, 2025
2487440
Integrated `hasRequiredCycles` function to ensure users meet the mini…
DecentAgeCoder May 8, 2025
ae12b8a
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 8, 2025
38ac281
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 8, 2025
3a17a06
Merged conflicts
DecentAgeCoder May 8, 2025
193d70a
Merged conflicts
DecentAgeCoder May 8, 2025
b8f5fdb
Merged changes
DecentAgeCoder May 9, 2025
e8cc92a
Working version
DecentAgeCoder May 9, 2025
379896e
Integrated storing post messages
DecentAgeCoder May 11, 2025
016268a
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 11, 2025
b141790
Integrated storing post messages
DecentAgeCoder May 12, 2025
053c4f3
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 12, 2025
5f1a6c6
🤖 Updated i18n files
github-actions[bot] May 12, 2025
aead0b6
Merge branch 'main' into feat/frontend/pow/protect-allow-signing-7
DecentAgeCoder May 12, 2025
1eb81bf
🤖 Apply formatting changes
github-actions[bot] May 12, 2025
69672b7
Merge branch 'main' into feat/frontend/pow/protect-allow-signing-7
DecentAgeCoder May 12, 2025
614abfc
Merge branch 'main' into feat/frontend/pow/protect-allow-signing-7
DecentAgeCoder May 12, 2025
1967a64
Updated
DecentAgeCoder May 12, 2025
9582595
Merge remote-tracking branch 'origin/feat/frontend/pow/protect-allow-…
DecentAgeCoder May 12, 2025
269e29f
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 12, 2025
f1fd625
Remove uncommented code
DecentAgeCoder May 12, 2025
846ab2d
Improved error handling
DecentAgeCoder May 13, 2025
552da7c
Merge branch 'refs/heads/main' into feat/frontend/pow/protect-allow-s…
DecentAgeCoder May 13, 2025
bff80c3
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 13, 2025
7835081
Updated
DecentAgeCoder May 13, 2025
b674013
Integrated the cycles canister into the build scripts
DecentAgeCoder May 14, 2025
7670708
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder May 19, 2025
c8ddea6
Merged PR's
DecentAgeCoder May 19, 2025
9ad8c66
🤖 Apply formatting changes
github-actions[bot] May 19, 2025
26236bf
Fixed linter issue: Use an `interface` instead of a `type`
DecentAgeCoder May 19, 2025
42ce7f9
Merge remote-tracking branch 'origin/feat/frontend/pow/protect-allow-…
DecentAgeCoder May 19, 2025
872ef2c
Merge remote-tracking branch 'origin/main' into feat/frontend/cycles-…
DecentAgeCoder May 19, 2025
865ca68
Fixed incorrect jq mapping for WASM_FILE
DecentAgeCoder May 20, 2025
d1a85c3
initial implementation of the cycles ledger api
DecentAgeCoder May 20, 2025
5d5798d
Added deployment of cycles_ledger to main deployment
DecentAgeCoder May 20, 2025
0e2245c
Updated the dfx canister definition for cycles_ledger
DecentAgeCoder May 20, 2025
9b7b0ba
Initial implementation for mapping the cycles ledger errors
DecentAgeCoder May 20, 2025
351639d
Initial implementation of the cycles ledger canister
DecentAgeCoder May 20, 2025
c717633
Updated cycles ledger build
DecentAgeCoder May 20, 2025
b013885
Updated
DecentAgeCoder May 20, 2025
62698e2
Merge remote-tracking branch 'origin/main' into feat/frontend/cycles-…
DecentAgeCoder May 23, 2025
54c0d9e
Merge remote-tracking branch 'origin/main' into feat/frontend/cycles-…
DecentAgeCoder May 23, 2025
87599c0
Merge remote-tracking branch 'refs/remotes/origin/main' into feat/fro…
DecentAgeCoder May 24, 2025
c122f0f
Updated scripts
DecentAgeCoder May 26, 2025
d4bda2b
Merge branch 'refs/heads/main' into feat/frontend/cycles-ledger/integ…
DecentAgeCoder May 28, 2025
3e3eda5
Updated scripts
DecentAgeCoder May 28, 2025
5fb187c
Merge branch 'refs/heads/main' into feat/frontend/cycles-ledger/integ…
DecentAgeCoder Jun 2, 2025
e51836c
Fixed cycles ledger deployment
DecentAgeCoder Jun 2, 2025
7a3ab64
Merge branch 'refs/heads/main' into feat/frontend/pow/protect-allow-s…
DecentAgeCoder Jun 2, 2025
81523ba
🤖 Updated i18n files
github-actions[bot] Jun 2, 2025
7a93fca
🤖 Apply formatting changes
github-actions[bot] Jun 2, 2025
70ca063
Merge branch 'refs/heads/main' into feat/frontend/cycles-ledger/integ…
DecentAgeCoder Jun 2, 2025
9995872
Merge branch 'refs/heads/main' into feat/frontend/pow/protect-allow-s…
DecentAgeCoder Jun 2, 2025
9549924
Generated candid files for cycles_ledger
DecentAgeCoder Jun 2, 2025
e68d50d
Fixed call
DecentAgeCoder Jun 3, 2025
28723ae
Cleanup
DecentAgeCoder Jun 3, 2025
91f8a5f
Improved and enhanced API and canister interface for cycles ledger en…
DecentAgeCoder Jun 3, 2025
1ac22c6
Merge branch 'refs/heads/main' into feat/frontend/cycles-ledger/integ…
DecentAgeCoder Jun 3, 2025
6922cf3
🤖 Apply formatting changes
github-actions[bot] Jun 3, 2025
952901f
Merge branch 'main' into feat/frontend/cycles-ledger/integrate-cycles…
DecentAgeCoder Jun 3, 2025
6400fe5
Changed order of cycles_ledger's config properties
DecentAgeCoder Jun 4, 2025
5c179b9
Added a second mock principal that can be used in tests that require …
DecentAgeCoder Jun 5, 2025
f285da2
Added allowance utility function to access the icrc_2_allowance endpoint
DecentAgeCoder Jun 5, 2025
3c30935
Implemented a convient function to get a sub-account for a principal
DecentAgeCoder Jun 5, 2025
d2c4e38
Created vario9us tests to test the behavior of the allowance API
DecentAgeCoder Jun 5, 2025
61f3ef7
Added hard-coded env sourced variables for the cycles ledger canister id
DecentAgeCoder Jun 5, 2025
47a0a19
Merge remote-tracking branch 'origin/main' into feat/frontend/cycles-…
DecentAgeCoder Jun 5, 2025
f2ad8d7
Removed cycles ledger integration since we are using the ledger-icrc …
DecentAgeCoder Jun 5, 2025
20b9aaa
🤖 Apply formatting changes
github-actions[bot] Jun 5, 2025
3f8afa0
Removed cycles ledger api since we want to relay on a the icrc-ledger…
DecentAgeCoder Jun 5, 2025
2e5cb6f
Merge remote-tracking branch 'origin/feat/frontend/cycles-ledger/inte…
DecentAgeCoder Jun 5, 2025
8445de8
Add doc to the allowance API function
DecentAgeCoder Jun 5, 2025
d9adbee
Reformated
DecentAgeCoder Jun 5, 2025
029bbfc
This error mapping is not required anymore
DecentAgeCoder Jun 5, 2025
39fd5c5
Removed the candid files since we relay on the icrc-ledger API
DecentAgeCoder Jun 5, 2025
55a768d
Deregistered cycles_ledger since we relay on the icrc-ledger API
DecentAgeCoder Jun 5, 2025
7c70759
Removed the dependency to the cycles ledger canidid files
DecentAgeCoder Jun 5, 2025
b25e1f3
🤖 Apply formatting changes
github-actions[bot] Jun 5, 2025
9a6656b
Merge branch 'main' into feat/frontend/cycles-ledger/integrate-cycles…
DecentAgeCoder Jun 5, 2025
2275a90
Merge branch 'main' into feat/frontend/cycles-ledger/integrate-cycles…
DecentAgeCoder Jun 5, 2025
767a6cb
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder Jun 5, 2025
2302fab
Removed legacy allowance integration
DecentAgeCoder Jun 5, 2025
f57a02b
Merge remote-tracking branch 'origin/main' into feat/frontend/cycles-…
DecentAgeCoder Jun 5, 2025
5624d9b
Merge branch 'feat/frontend/cycles-ledger/integrate-cycles-ledger-can…
DecentAgeCoder Jun 5, 2025
815e4c7
Updated
DecentAgeCoder Jun 6, 2025
2509520
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder Jun 18, 2025
c889f52
Reverted merged cycles ledger canister integration
DecentAgeCoder Jun 18, 2025
cf1500b
Merge branch 'refs/heads/main' into feat/frontend/pow/protect-allow-s…
DecentAgeCoder Jun 19, 2025
ccedec9
we do not need to start the PoW if the user has enough cycles
DecentAgeCoder Jun 19, 2025
a9e4464
🤖 Apply formatting changes
github-actions[bot] Jun 19, 2025
46aee82
Fixed getIcrcSubaccount() sub account conversion
DecentAgeCoder Jun 19, 2025
0c35c45
Set correct constant for ledgerCanisterId
DecentAgeCoder Jun 19, 2025
3533338
POW_ENABLED must be disabled since trhe frontend settings in github m…
DecentAgeCoder Jun 19, 2025
d5df840
Merge remote-tracking branch 'origin/main' into feat/frontend/pow/pro…
DecentAgeCoder Jun 19, 2025
ab99449
🤖 Updated i18n files
github-actions[bot] Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/frontend/src/icp/schedulers/pow-protection.scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { allowSigning, createPowChallenge } from '$lib/api/backend.api';
import { CreateChallengeEnum, PowCreateChallengeError } from '$lib/canisters/backend.errors';
import { POW_CHALLENGE_INTERVAL_MILLIS } from '$lib/constants/pow.constants';
import { SchedulerTimer, type Scheduler, type SchedulerJobData } from '$lib/schedulers/scheduler';
import { hasRequiredCycles } from '$lib/services/loader.services';
import type {
PostMessageDataRequest,
PostMessageDataResponsePowProtectorNextAllowance,
Expand Down Expand Up @@ -44,6 +45,11 @@ export class PowProtectionScheduler implements Scheduler<PostMessageDataRequest>
* @throws Errors if any step with no specific error handling in the sequence fails.
*/
private requestSignerCycles = async ({ identity }: SchedulerJobData<PostMessageDataRequest>) => {
if (await hasRequiredCycles()) {
// we do not need to start the PoW if the user has enough cycles
return;
}

// Step 1: Request creation of the Proof-of-Work (PoW) challenge (throws when unsuccessful).
this.postMessagePowProgress({ progress: 'REQUEST_CHALLENGE' });
try {
Expand Down
40 changes: 40 additions & 0 deletions src/frontend/src/icp/services/pow-protector-listener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
powProtectoreNextAllowanceStore,
powProtectoreProgressStore,
type PowProtectorNextAllowanceData,
type PowProtectorProgressData
} from '$lib/stores/pow-protection.store';
import type {
PostMessageDataResponsePowProtectorNextAllowance,
PostMessageDataResponsePowProtectorProgress
} from '$lib/types/post-message';

export interface PowProtectorWorkerInitResult {
start: () => void;
stop: () => void;
trigger: () => void;
}

export type PowProtectorWorker = () => Promise<PowProtectorWorkerInitResult>;

export const syncPowProgress = ({
data
}: {
data: PostMessageDataResponsePowProtectorProgress;
}) => {
const mappedData: PowProtectorProgressData = {
progress: data.progress
};
powProtectoreProgressStore.setPowProtectorProgressData(mappedData);
};

export const syncPowNextAllowance = ({
data
}: {
data: PostMessageDataResponsePowProtectorNextAllowance;
}) => {
const mappedData: PowProtectorNextAllowanceData = {
nextAllowanceMs: data.nextAllowanceMs
};
powProtectoreNextAllowanceStore.setPowProtectorNextAllowanceData(mappedData);
};
48 changes: 43 additions & 5 deletions src/frontend/src/icp/services/worker.pow-protection.services.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,54 @@
import {
syncPowNextAllowance,
syncPowProgress,
type PowProtectorWorker,
type PowProtectorWorkerInitResult
} from '$icp/services/pow-protector-listener';
import type {
PowProtectorWorker,
PowProtectorWorkerInitResult
} from '$icp/types/pow-protector-listener';
import type { PostMessage, PostMessageDataResponse } from '$lib/types/post-message';
PostMessage,
PostMessageDataResponseError,
PostMessageDataResponsePowProtectorNextAllowance,
PostMessageDataResponsePowProtectorProgress
} from '$lib/types/post-message';

// TODO: add tests for POW worker/scheduler
export const initPowProtectorWorker: PowProtectorWorker =
async (): Promise<PowProtectorWorkerInitResult> => {
const PowWorker = await import('$lib/workers/workers?worker');
const worker: Worker = new PowWorker.default();

worker.onmessage = ({ data: _data }: MessageEvent<PostMessage<PostMessageDataResponse>>) => {};
worker.onmessage = ({
data
}: MessageEvent<
PostMessage<
| PostMessageDataResponsePowProtectorProgress
| PostMessageDataResponsePowProtectorNextAllowance
| PostMessageDataResponseError
>
>) => {
const { msg } = data;

switch (msg) {
case 'syncPowProgress': {
// Check if data.data exists and has proper structure
if (data.data && 'progress' in data.data) {
syncPowProgress({
data: data.data
});
}
return;
}
case 'syncPowNextAllowance': {
// Check if data.data exists and has proper structure
if (data.data && 'nextAllowanceMs' in data.data) {
syncPowNextAllowance({
data: data.data
});
}
return;
}
}
};

return {
start: () => {
Expand Down
7 changes: 0 additions & 7 deletions src/frontend/src/icp/types/pow-protector-listener.ts

This file was deleted.

15 changes: 10 additions & 5 deletions src/frontend/src/icp/utils/icrc-account.utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { decodeIcrcAccount, type IcrcAccount } from '@dfinity/ledger-icrc';
import { AccountIdentifier } from '@dfinity/ledger-icp';
import { decodeIcrcAccount, type IcrcAccount, type IcrcSubaccount } from '@dfinity/ledger-icrc';
import type { Principal } from '@dfinity/principal';
import { isNullish } from '@dfinity/utils';
import { sha256 } from '@noble/hashes/sha256';

export const getIcrcAccount = (principal: Principal): IcrcAccount => ({ owner: principal });

Expand All @@ -10,9 +10,14 @@ export const getIcrcAccount = (principal: Principal): IcrcAccount => ({ owner: p
* @param principal The principal to derive the subaccount from
* @returns A 32-byte Uint8Array to be used as an ICRC subaccount
*/
export const getIcrcSubaccount = (principal: Principal): Uint8Array => {
const principalBytes = principal.toUint8Array();
return sha256(principalBytes);
export const getIcrcSubaccount = (principal: Principal): IcrcSubaccount => {
const accountIdentifier = AccountIdentifier.fromPrincipal({
principal,
subAccount: undefined
});

// Convert to Uint8Array (the bytes of the account identifier)
return accountIdentifier.toUint8Array();
};

export const isIcrcAddress = (address: string | undefined): boolean => {
Expand Down
12 changes: 7 additions & 5 deletions src/frontend/src/lib/components/guard/AddressGuard.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { validateBtcAddressMainnet } from '$btc/services/btc-address.services';
import { POW_FEATURE_ENABLED } from '$env/pow.env';
import { validateEthAddress } from '$eth/services/eth-address.services';
import {
networkBitcoinMainnetEnabled,
Expand All @@ -18,13 +19,14 @@
let signerAllowanceLoaded = false;

const loadSignerAllowanceAndValidateAddresses = async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe now can be renamed?

Copy link
Collaborator Author

@DecentAgeCoder DecentAgeCoder Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the pow environment naming has been fixed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i mean, if you are going to remove the signer allowance, you can rename this function no?

My understanding is that once the feature is complete, the feature flag is gone, so that part inside the IF condition disappear. Or not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to leave the Feature flag, so that we can disable it quickly if there are issues with the PoW in production (e.g. to much CPU overhead, or not enough Cycles per time period are allowance (fine-tuning of settings)).

const { success: initSignerAllowanceSuccess } = await initSignerAllowance();
if (!POW_FEATURE_ENABLED) {
const { success: initSignerAllowanceSuccess } = await initSignerAllowance();

if (!initSignerAllowanceSuccess) {
// Sign-out is handled within the service.
return;
if (!initSignerAllowanceSuccess) {
// Sign-out is handled within the service.
return;
}
}

signerAllowanceLoaded = true;

await validateAddresses();
Expand Down
49 changes: 26 additions & 23 deletions src/frontend/src/lib/components/loaders/Loaders.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,36 @@
import LoaderMetamask from '$lib/components/loaders/LoaderMetamask.svelte';
import LoaderUserProfile from '$lib/components/loaders/LoaderUserProfile.svelte';
import LoaderWallets from '$lib/components/loaders/LoaderWallets.svelte';
import PowProtector from '$lib/components/pow/PowProtector.svelte';
import UserSnapshotWorker from '$lib/components/rewards/UserSnapshotWorker.svelte';
</script>

<LoaderUserProfile>
<AddressGuard>
<Loader>
<UrlGuard>
<ShortcutGuard>
<RewardGuard>
<LoaderEthBalances>
<LoaderWallets>
<ExchangeWorker>
<LoaderMetamask>
<UserSnapshotWorker>
<LoaderContacts>
<slot />
</LoaderContacts>
</UserSnapshotWorker>
</LoaderMetamask>
</ExchangeWorker>
</LoaderWallets>
</LoaderEthBalances>
</RewardGuard>
</ShortcutGuard>
</UrlGuard>
</Loader>
</AddressGuard>
<PowProtector>
<AddressGuard>
<Loader>
<UrlGuard>
<ShortcutGuard>
<RewardGuard>
<LoaderEthBalances>
<LoaderWallets>
<ExchangeWorker>
<LoaderMetamask>
<UserSnapshotWorker>
<LoaderContacts>
<slot />
</LoaderContacts>
</UserSnapshotWorker>
</LoaderMetamask>
</ExchangeWorker>
</LoaderWallets>
</LoaderEthBalances>
</RewardGuard>
</ShortcutGuard>
</UrlGuard>
</Loader>
</AddressGuard>
</PowProtector>
</LoaderUserProfile>

<!-- This listener is kept outside of the Loaders tree to prevent slow page loading on localhost/e2e -->
Expand Down
Loading
Loading