Skip to content

Commit faf4bcd

Browse files
committed
fix suggested changes
1 parent 248714a commit faf4bcd

5 files changed

Lines changed: 102 additions & 634 deletions

File tree

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/**
2+
* helios-verifier.ts
3+
*
4+
* Experimental light-client verification layer using Helios (@a16z/helios).
5+
* Only active on Ethereum mainnet (chainId 0x1).
6+
*/
7+
18
export interface VerificationResult {
29
verified: boolean;
310
tampered: boolean;
@@ -7,26 +14,70 @@ export interface VerificationResult {
714

815
const SKIP: VerificationResult = { verified: false, tampered: false, message: '' };
916
const MAINNET_CHAIN_ID = '0x1';
17+
const DEFAULT_CONSENSUS_RPC = 'https://ethereum.operationsolarstorm.org';
18+
const CHECKPOINT_FETCH_TIMEOUT_MS = 5_000;
1019

11-
// DEMO MODE: simulate Helios detecting a lying RPC
12-
let heliosProvider: any = {
13-
waitSynced: () => Promise.resolve(),
14-
request: async (args: any) => {
15-
if (args.method === 'eth_call') {
16-
return '0x0000000000000000000000000000000000000000000000000000000000000001';
17-
}
18-
return '0x0';
19-
}
20-
};
20+
let heliosProvider: any = null;
2121
let initInProgress = false;
22-
let isSynced = true;
22+
let isSynced = false;
23+
let currentExecutionRpc = '';
24+
25+
async function fetchFreshCheckpoint(consensusRpc: string): Promise<string | undefined> {
26+
const url = `${consensusRpc.replace(/\/$/, '')}/eth/v1/beacon/headers/finalized`;
27+
const controller = new AbortController();
28+
const timer = setTimeout(() => controller.abort(), CHECKPOINT_FETCH_TIMEOUT_MS);
29+
try {
30+
const res = await fetch(url, { signal: controller.signal });
31+
if (!res.ok) return undefined;
32+
const json = (await res.json()) as { data?: { root?: string } };
33+
const root = json?.data?.root;
34+
if (typeof root === 'string' && root.startsWith('0x')) return root;
35+
return undefined;
36+
} catch {
37+
return undefined;
38+
} finally {
39+
clearTimeout(timer);
40+
}
41+
}
2342

24-
export async function initHelios(executionRpc: string, consensusRpc?: string): Promise<void> {
25-
return;
43+
export async function initHelios(
44+
executionRpc: string,
45+
consensusRpc: string = DEFAULT_CONSENSUS_RPC,
46+
): Promise<void> {
47+
if (initInProgress) return;
48+
if (heliosProvider && currentExecutionRpc === executionRpc) return;
49+
initInProgress = true;
50+
heliosProvider = null;
51+
isSynced = false;
52+
currentExecutionRpc = executionRpc;
53+
try {
54+
const checkpoint = await fetchFreshCheckpoint(consensusRpc);
55+
const { createHeliosProvider } = await import('@a16z/helios');
56+
const config: Record<string, string> = {
57+
executionRpc,
58+
consensusRpc,
59+
network: 'mainnet',
60+
};
61+
if (checkpoint) config['checkpoint'] = checkpoint;
62+
heliosProvider = await createHeliosProvider(config, 'ethereum');
63+
heliosProvider
64+
.waitSynced()
65+
.then(() => { isSynced = true; console.log('[helios-verifier] synced and ready'); })
66+
.catch((err: unknown) => { console.warn('[helios-verifier] sync failed:', err); resetHelios(); });
67+
} catch (err) {
68+
console.warn('[helios-verifier] failed to initialise:', err);
69+
heliosProvider = null;
70+
currentExecutionRpc = '';
71+
} finally {
72+
initInProgress = false;
73+
}
2674
}
2775

2876
export function resetHelios(): void {
29-
return;
77+
heliosProvider = null;
78+
isSynced = false;
79+
initInProgress = false;
80+
currentExecutionRpc = '';
3081
}
3182

3283
function encodeBalanceOf(address: string): string {
@@ -47,36 +98,29 @@ export async function verifyErc20Balance(
4798
chainId: string,
4899
executionRpc: string,
49100
): Promise<VerificationResult> {
50-
console.log('[helios-verifier] chainId check:', chainId, MAINNET_CHAIN_ID);
51101
if (chainId.toLowerCase() !== MAINNET_CHAIN_ID) return SKIP;
102+
if (!heliosProvider && !initInProgress) void initHelios(executionRpc);
52103
if (!isSynced || !heliosProvider) return SKIP;
53-
54104
let heliosBalanceHex: string;
55105
try {
56106
heliosBalanceHex = (await heliosProvider.request({
57107
method: 'eth_call',
58108
params: [{ to: contractAddress, data: encodeBalanceOf(walletAddress) }, 'latest'],
59109
})) as string;
60110
} catch (err) {
61-
console.warn('[helios-verifier] eth_call via Helios failed:', err);
111+
console.warn('[helios-verifier] eth_call failed:', err);
62112
return SKIP;
63113
}
64-
65114
const rpcValue = decodeUint256(rpcBalance);
66115
const heliosValue = decodeUint256(heliosBalanceHex);
67-
68-
console.log('[helios-verifier] rpcValue:', rpcValue.toString(), 'heliosValue:', heliosValue.toString());
69-
70116
if (rpcValue === heliosValue) {
71117
return { verified: true, tampered: false, message: 'Balance verified by Helios light client.', provenBalance: heliosBalanceHex };
72118
}
73-
74-
console.error('[helios-verifier] MISMATCH DETECTED - RPC is lying!');
75-
119+
console.error(`[helios-verifier] MISMATCH: RPC=${rpcValue} Helios=${heliosValue}`);
76120
return {
77121
verified: false,
78122
tampered: true,
79-
message: `Your RPC provider returned a balance of ${rpcValue.toString()} but the Helios light client cryptographically proved the real on-chain balance is ${heliosValue.toString()}. Your RPC provider may be lying. Consider switching to a trusted provider.`,
123+
message: `Your RPC provider returned ${rpcValue.toString()} but Helios proved the real balance is ${heliosValue.toString()}. Your RPC provider may be lying.`,
80124
provenBalance: heliosBalanceHex,
81125
};
82126
}

packages/extension/src/providers/ethereum/types/erc20-token.ts.bak

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)