Skip to content

Commit e0c6a09

Browse files
committed
fix: consolidate viem types, typed window
1 parent fae6d29 commit e0c6a09

File tree

7 files changed

+55
-42
lines changed

7 files changed

+55
-42
lines changed

packages/rln/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
"watch:test": "mocha --watch",
4545
"prepublish": "npm run build",
4646
"reset-hard": "git clean -dfx -e .idea && git reset --hard && npm i && npm run build",
47-
"setup:contract-abi": "./generate_contract_abi.sh",
48-
"generate:contract": "npx wagmi generate"
47+
"setup:contract-abi": "./generate_contract_abi.sh"
4948
},
5049
"engines": {
5150
"node": ">=22"

packages/rln/src/contract/rln_base_contract.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import {
33
type Address,
44
decodeEventLog,
55
getContract,
6-
GetContractReturnType,
6+
type GetContractReturnType,
77
type Hash,
8-
publicActions,
9-
PublicClient,
10-
WalletClient
8+
type PublicClient,
9+
type WalletClient
1110
} from "viem";
1211

1312
import { IdentityCredential } from "../identity.js";
14-
import { DecryptedCredentials } from "../keystore/types.js";
13+
import type { DecryptedCredentials } from "../keystore/types.js";
14+
import type { RpcClient } from "../utils/index.js";
1515

1616
import {
1717
DEFAULT_RATE_LIMIT,
@@ -32,7 +32,7 @@ export class RLNBaseContract {
3232
typeof wakuRlnV2Abi,
3333
PublicClient | WalletClient
3434
>;
35-
public rpcClient: WalletClient & PublicClient;
35+
public rpcClient: RpcClient;
3636
private rateLimit: number;
3737
private minRateLimit?: number;
3838
private maxRateLimit?: number;
@@ -45,8 +45,7 @@ export class RLNBaseContract {
4545

4646
log.info("Initializing RLNBaseContract", { address, rateLimit });
4747

48-
this.rpcClient = rpcClient.extend(publicActions) as WalletClient &
49-
PublicClient;
48+
this.rpcClient = rpcClient;
5049
this.contract = getContract({
5150
address,
5251
abi: wakuRlnV2Abi,
@@ -223,15 +222,15 @@ export class RLNBaseContract {
223222
try {
224223
await this.contract.simulate.extendMemberships([[idCommitmentBigInt]], {
225224
chain: this.rpcClient.chain,
226-
account: (this.rpcClient as WalletClient).account!.address
225+
account: this.rpcClient.account.address
227226
});
228227
} catch (err) {
229228
throw new Error("Simulating extending membership failed: " + err);
230229
}
231230
const hash = await this.contract.write.extendMemberships(
232231
[[idCommitmentBigInt]],
233232
{
234-
account: this.rpcClient.account!,
233+
account: this.rpcClient.account,
235234
chain: this.rpcClient.chain
236235
}
237236
);
@@ -261,7 +260,7 @@ export class RLNBaseContract {
261260
[[idCommitmentBigInt], eraseFromMembershipSet],
262261
{
263262
chain: this.rpcClient.chain,
264-
account: (this.rpcClient as WalletClient).account!.address
263+
account: this.rpcClient.account.address
265264
}
266265
);
267266
} catch (err) {
@@ -272,7 +271,7 @@ export class RLNBaseContract {
272271
[[idCommitmentBigInt], eraseFromMembershipSet],
273272
{
274273
chain: this.rpcClient.chain,
275-
account: this.rpcClient.account!
274+
account: this.rpcClient.account
276275
}
277276
);
278277
await this.rpcClient.waitForTransactionReceipt({ hash });
@@ -301,7 +300,7 @@ export class RLNBaseContract {
301300
[idCommitmentBigInt, rateLimit, []],
302301
{
303302
chain: this.rpcClient.chain,
304-
account: (this.rpcClient as WalletClient).account!.address
303+
account: this.rpcClient.account.address
305304
}
306305
);
307306
} catch (err) {
@@ -312,7 +311,7 @@ export class RLNBaseContract {
312311
[idCommitmentBigInt, rateLimit, []],
313312
{
314313
chain: this.rpcClient.chain,
315-
account: this.rpcClient.account!
314+
account: this.rpcClient.account
316315
}
317316
);
318317
await this.rpcClient.waitForTransactionReceipt({ hash });
@@ -333,15 +332,15 @@ export class RLNBaseContract {
333332
try {
334333
await this.contract.simulate.withdraw([token as Address], {
335334
chain: this.rpcClient.chain,
336-
account: (this.rpcClient as WalletClient).account!.address
335+
account: this.rpcClient.account.address
337336
});
338337
} catch (err) {
339338
throw new Error("Error simulating withdraw: " + err);
340339
}
341340

342341
const hash = await this.contract.write.withdraw([token as Address], {
343342
chain: this.rpcClient.chain,
344-
account: this.rpcClient.account!
343+
account: this.rpcClient.account
345344
});
346345

347346
await this.rpcClient.waitForTransactionReceipt({ hash });
@@ -351,6 +350,12 @@ export class RLNBaseContract {
351350
identity: IdentityCredential
352351
): Promise<DecryptedCredentials | undefined> {
353352
try {
353+
if (!this.rpcClient.account) {
354+
throw new Error(
355+
"Failed to registerWithIdentity: no account set in wallet client"
356+
);
357+
}
358+
354359
log.info(
355360
`Registering identity with rate limit: ${this.rateLimit} messages/epoch`
356361
);
@@ -377,15 +382,15 @@ export class RLNBaseContract {
377382
[identity.IDCommitmentBigInt, this.rateLimit, []],
378383
{
379384
chain: this.rpcClient.chain,
380-
account: (this.rpcClient as WalletClient).account!.address
385+
account: this.rpcClient.account.address
381386
}
382387
);
383388

384389
const hash: Hash = await this.contract.write.register(
385390
[identity.IDCommitmentBigInt, this.rateLimit, []],
386391
{
387392
chain: this.rpcClient.chain,
388-
account: this.rpcClient.account!
393+
account: this.rpcClient.account
389394
}
390395
);
391396

packages/rln/src/contract/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { Address, WalletClient } from "viem";
1+
import { Address } from "viem";
2+
3+
import { RpcClient } from "../utils/index.js";
24

35
export type Member = {
46
idCommitment: string;
57
index: bigint;
68
};
79

810
export interface RLNContractOptions {
9-
rpcClient: WalletClient;
11+
rpcClient: RpcClient;
1012
address: Address;
1113
rateLimit?: number;
1214
}

packages/rln/src/credentials_manager.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Logger } from "@waku/utils";
2-
import { publicActions, PublicClient, WalletClient } from "viem";
2+
import { publicActions } from "viem";
33

44
import { RLN_CONTRACT } from "./contract/constants.js";
55
import { RLNBaseContract } from "./contract/rln_base_contract.js";
@@ -10,7 +10,7 @@ import type {
1010
} from "./keystore/index.js";
1111
import { KeystoreEntity, Password } from "./keystore/types.js";
1212
import { RegisterMembershipOptions, StartRLNOptions } from "./types.js";
13-
import { createViemClientFromWindow } from "./utils/index.js";
13+
import { createViemClientFromWindow, RpcClient } from "./utils/index.js";
1414
import { Zerokit } from "./zerokit.js";
1515

1616
const log = new Logger("rln:credentials");
@@ -24,7 +24,7 @@ export class RLNCredentialsManager {
2424
protected starting = false;
2525

2626
public contract: undefined | RLNBaseContract;
27-
public rpcClient: undefined | (WalletClient & PublicClient);
27+
public rpcClient: undefined | RpcClient;
2828

2929
protected keystore = Keystore.create();
3030
public credentials: undefined | DecryptedCredentials;
@@ -128,7 +128,7 @@ export class RLNCredentialsManager {
128128
protected async determineStartOptions(
129129
options: StartRLNOptions,
130130
credentials: KeystoreEntity | undefined
131-
): Promise<StartRLNOptions & { rpcClient: WalletClient & PublicClient }> {
131+
): Promise<StartRLNOptions & { rpcClient: RpcClient }> {
132132
let chainId = credentials?.membership.chainId;
133133
const address =
134134
credentials?.membership.address ||
@@ -140,11 +140,9 @@ export class RLNCredentialsManager {
140140
log.info(`Using Linea contract with chainId: ${chainId}`);
141141
}
142142

143-
let rpcClient: (WalletClient & PublicClient) | undefined =
144-
options.rpcClient?.extend(publicActions) as WalletClient & PublicClient;
145-
if (!rpcClient) {
146-
rpcClient = await createViemClientFromWindow();
147-
}
143+
const rpcClient: RpcClient = options.walletClient
144+
? options.walletClient.extend(publicActions)
145+
: await createViemClientFromWindow();
148146

149147
const currentChainId = rpcClient.chain?.id;
150148
log.info(`Current chain ID: ${currentChainId}`);

packages/rln/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export type StartRLNOptions = {
1010
/**
1111
* If not set - will attempt to create from provider injected in window.
1212
*/
13-
rpcClient?: WalletClient;
13+
walletClient?: WalletClient;
1414
/**
1515
* If not set - will use default SEPOLIA_CONTRACT address.
1616
*/

packages/rln/src/utils/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { createViemClientFromWindow } from "./walletClient.js";
1+
export { createViemClientFromWindow, RpcClient } from "./rpcClient.js";
22
export { BytesUtils } from "./bytes.js";
33
export { sha256, poseidonHash } from "./hash.js";
44
export { dateToEpoch, epochIntToBytes, epochBytesToInt } from "./epoch.js";

packages/rln/src/utils/walletClient.ts renamed to packages/rln/src/utils/rpcClient.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1+
import "viem/window";
12
import {
3+
type Address,
24
createWalletClient,
35
custom,
6+
PublicActions,
47
publicActions,
5-
PublicClient,
68
WalletClient
79
} from "viem";
810
import { lineaSepolia } from "viem/chains";
911

10-
export const createViemClientFromWindow = async (): Promise<
11-
WalletClient & PublicClient
12-
> => {
13-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
14-
const ethereum = (window as any).ethereum;
12+
export type RpcClient = WalletClient & PublicActions;
13+
14+
/**
15+
* Checks window for injected Ethereum provider, requests user to connect, and creates an RPC client object
16+
* capable of performing both read and write operations on the blockchain.
17+
*
18+
* If the wallet is not connected to the Linea Sepolia network, it will attempt to switch to it.
19+
* If the wallet does not have the Linea Sepolia network added, it will attempt to add it.
20+
*/
21+
export const createViemClientFromWindow = async (): Promise<RpcClient> => {
22+
const ethereum = window.ethereum;
1523

1624
if (!ethereum) {
1725
throw Error(
@@ -21,10 +29,10 @@ export const createViemClientFromWindow = async (): Promise<
2129

2230
const [account] = await ethereum.request({ method: "eth_requestAccounts" });
2331

24-
const rpcClient = createWalletClient({
25-
account,
32+
const rpcClient: RpcClient = createWalletClient({
33+
account: account as Address,
2634
chain: lineaSepolia,
27-
transport: custom(ethereum)
35+
transport: custom(window.ethereum!)
2836
}).extend(publicActions);
2937

3038
// Ensure wallet is connected to Linea Sepolia
@@ -39,6 +47,7 @@ export const createViemClientFromWindow = async (): Promise<
3947
error.code === 4902
4048
) {
4149
await rpcClient.addChain({ chain: lineaSepolia });
50+
await rpcClient.switchChain({ id: lineaSepolia.id });
4251
} else {
4352
throw error;
4453
}

0 commit comments

Comments
 (0)