Skip to content
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

Migrate From ContractKit to Viem #294

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft

Migrate From ContractKit to Viem #294

wants to merge 11 commits into from

Conversation

aaronmgdr
Copy link
Member

@aaronmgdr aaronmgdr commented Sep 25, 2024

Description

Rather than use ContractKit use viem as the rpc caller / contracts library.

Changes

  • WalletSigner now takes a sign191 function instead of a contractKit instance. this makes it easy to use with whatever library you like such as viem client.signMessage or ethers.signMessage as long as they support eip191.

  • Many places that were expecting an address but typed as a regular string are now typed as 0x{string} aka Address

  • almost everywhere kit has been replaced with client and in some cases walletClient

  • @celo/phone-number-privacy-common/lib/contracts contract instances used internally (viem getContract + abi + address) getAccountsContract, getCUSDContract, getOdisPaymentsContract,

  • ContractKit is still needed for the @celo/identity/lib/offchain functions however these are not used in social connect as such ck is now a peer dependencies and marked as optional. Pottentially these offchain functions can be either deprecated or moved to a different codebase.

Tested

Needs someone who understand the system really well to really test it out.

TODO

  • need to re mock the getDataEncryptionKey method in the authentication.test in common package. one was done but the rest still need it and each seems to require different implementatation

  • try to replace contractkit with @celo/[email protected]

dont merge until we get this deployed to staging.

Related issues

Backwards compatibility

No. This is a Major Change

Documentation

documented in changesets the differences

Copy link

changeset-bot bot commented Sep 25, 2024

🦋 Changeset detected

Latest commit: cfde4ce

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages
Name Type
@celo/phone-number-privacy-monitor Major
@celo/phone-number-privacy-combiner Major
@celo/identity Major
@celo/encrypted-backup Patch
@celo/phone-number-privacy-common Major
@celo/phone-number-privacy-signer Major
odis-example-scripts Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

gitguardian bot commented Sep 25, 2024

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
10990680 Triggered Generic High Entropy Secret 4a7b2c8 packages/common/src/test/values.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link

socket-security bot commented Sep 25, 2024

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@celo/[email protected] network +2 5.2 MB app-tooling
npm/@celo/[email protected] Transitive: environment, filesystem, network +16 45.3 MB app-tooling
npm/@celo/[email protected] Transitive: environment, filesystem, network, shell +46 32.3 MB app-tooling
npm/@celo/[email protected] Transitive: environment, eval, filesystem, network, unsafe +145 9.4 MB app-tooling
npm/[email protected] network 0 12.8 MB jmoxey

🚮 Removed packages: npm/@celo/[email protected]

View full report↗︎

await selfTransferTx.sendAndWaitForReceipt({ from: account })
}

export async function registerWalletAddress(
Copy link
Member Author

Choose a reason for hiding this comment

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

a test function not used in any tests

@@ -79,7 +80,7 @@ The following steps use the Celo [ContractKit](https://docs.celo.org/developer/c
// authSigner provides information needed to authenticate with ODIS
const authSigner: AuthSigner = {
authenticationMethod: OdisUtils.Query.AuthenticationMethod.WALLET_KEY,
contractKit: kit,
sign191: ({message, account}) => viemClient.signMessage({message, account}),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: does it make sense to call this sign191 instead of just sign

@@ -52,6 +52,7 @@ This could be a node with RPC set up. Preferably this would be an node dedicated

- `BLOCKCHAIN_PROVIDER` - The blockchain node provider for chain state access. `
- `BLOCKCHAIN_API_KEY` - Optional API key to be added to the authentication header. `
- `CHAIN_ID` should be 44220 or celo or 44787 on alfajores
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
- `CHAIN_ID` should be 44220 or celo or 44787 on alfajores
- `CHAIN_ID` should be 44220 for Celo Mainnet or 44787 for Celo Alfajores

@@ -3,6 +3,7 @@ NODE_ENV=development
#SERVER_SSL_KEY_PATH=./server.key
#SERVER_SSL_CERT_PATH=./server.cert
BLOCKCHAIN_PROVIDER=https://alfajores-forno.celo-testnet.org
CHAIN_ID=42220
Copy link
Collaborator

Choose a reason for hiding this comment

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

Shouldn't this be 44787 for alfajores to be consistent with the RPC url?

async () => testPNPSignQuery(blockchainProvider.value(), contextName.value() as any),
async () =>
testPNPSignQuery(
{ rpcURL: blockchainProvider.value(), chainID: chainID.value() as 44787 },
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we casting this to a specific chain ID? What if we want to run the test on mainnet?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 it is in fact running for both networks.

const logger = rootLogger(config.serviceName)

kit = kit ?? getContractKitWithAgent(config.blockchain)
viemClient = viemClient ?? getWalletClientWithAgent(config.blockchain)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: consider naming all these "ClientAccountService" etc. to be consistent with the Signer server.ts file

contractKit.defaultAccount = ACCOUNT_ADDRESS
export const client = createWalletClient({
transport: http(DEFAULT_FORNO_URL),
chain: celo,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this needs to be configurable to be either celo or celoAlfajores

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 Perhaps getting it from the env file as well.

@alecps
Copy link
Collaborator

alecps commented Jan 28, 2025

@aaronmgdr Better late than never 😅. I haven't quite made it through the whole PR but have made a big dent and will continue to chip away at it. In general it's looking great so far. Thanks again for taking the time to do this and apologies it's taken me so long to get around to reviewing it

@alecps alecps requested review from soloseng and removed request for viral-sangani and therealharpaljadeja January 28, 2025 22:50
export function newContractKitFetcher(
contractKit: ContractKit,
export function newDEKFetcher(
viemClient: Client,
Copy link
Collaborator

@alecps alecps Jan 28, 2025

Choose a reason for hiding this comment

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

Nit: consider naming this walletClient for consistency

Copy link
Contributor

@soloseng soloseng left a comment

Choose a reason for hiding this comment

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

Sorry, this just got flagged to me.

Thanks for taking the time to work on this.

Looks good. Not sure where this sits on your priority list as of now, but made a few comments.

contractKit.defaultAccount = ACCOUNT_ADDRESS
export const client = createWalletClient({
transport: http(DEFAULT_FORNO_URL),
chain: celo,
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 Perhaps getting it from the env file as well.

async () => testPNPSignQuery(blockchainProvider.value(), contextName.value() as any),
async () =>
testPNPSignQuery(
{ rpcURL: blockchainProvider.value(), chainID: chainID.value() as 44787 },
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 it is in fact running for both networks.

let accountAddress: Address

if (useDEK) {
// im not sure why this is like this
Copy link
Contributor

Choose a reason for hiding this comment

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

This is to randomize which private key is used. It's particularly usefull during load testing when we want to have different type of request being sent.

@@ -28,31 +35,35 @@ const {
PHONE_NUMBER,
PRIVATE_KEY1,
PRIVATE_KEY2,
PRIVATE_KEY3,
// PRIVATE_KEY3,
Copy link
Contributor

Choose a reason for hiding this comment

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

can be removed if unused.

kit.addAccount(PRIVATE_KEY3)
const account1 = privateKeyToAccount(ensureLeading0x(PRIVATE_KEY1))
const account2 = privateKeyToAccount(ensureLeading0x(PRIVATE_KEY2))
// const account3 = privateKeyToAccount(ensureLeading0x(PRIVATE_KEY3))
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto


describe('Authentication test suite', () => {
describe.skip('Authentication test suite', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

is this skip intended to stay?

},
} as ContractKit
const dekFetcher = newContractKitFetcher(mockContractKit, logger)
// const mockContractKit = {
Copy link
Contributor

Choose a reason for hiding this comment

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

remove commented code

// getAccounts: async () => {
// return Promise.resolve({
// getDataEncryptionKey: async (_: string) => {
// return 'notAValidKeyEncryption'
Copy link
Contributor

Choose a reason for hiding this comment

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

Noticed that the return value is different with each mockContractKit. Is that reflected with the viem client?

// getDataEncryptionKey: async (_: string) => {
// // NOTE: elliptic is disabled elsewhere in this library to prevent
// // accidental signing of truncated messages.
// const EC = require('elliptic').ec
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

import * as crypto from 'crypto'
import { ComputationalHardeningConfig, ComputationalHardeningFunction } from './config'
import { DecryptionError, EncryptionError, PbkdfError, ScryptError } from './errors'

// NOTE: This module is intended for use within the @celo/encrypted-backup package and so is not
// exported in the index.ts file.

/** Pared down ReadOnlyWallet type that supports the required functions of EIP-712 signing. */
export type EIP712Wallet = Pick<ReadOnlyWallet, 'getAccounts' | 'hasAccount' | 'signTypedData'>
/** Pared down ReadOnlyWallet type that supports the required functions of EIP-712 signing. */ export interface EIP712Wallet {
Copy link
Contributor

Choose a reason for hiding this comment

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

move code to next line to improve readability

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace contractkit with viem
3 participants