Skip to content

Commit

Permalink
chore: restore helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
joepegler committed Jan 14, 2025
1 parent 0c52c86 commit 0dd7c8c
Show file tree
Hide file tree
Showing 39 changed files with 1,361 additions and 295 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PRIVATE_KEY=
CHAIN_ID=84532
MAINNET_CHAIN_ID=11155111
MAINNET_CHAIN_ID=10
RPC_URL=
BUNDLER_URL=
BICONOMY_SDK_DEBUG=false
Expand Down
82 changes: 82 additions & 0 deletions src/sdk/account/decorators/getFactoryData.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
http,
type Address,
type Chain,
type LocalAccount,
type PublicClient,
type WalletClient,
createWalletClient
} from "viem"
import { afterAll, beforeAll, describe, expect, test } from "vitest"
import { toNetwork } from "../../../test/testSetup"
import {
getTestAccount,
killNetwork,
toTestClient
} from "../../../test/testUtils"
import type { MasterClient, NetworkConfig } from "../../../test/testUtils"
import {
type NexusClient,
createSmartAccountClient
} from "../../clients/createSmartAccountClient"
import {
MEE_VALIDATOR_ADDRESS,
RHINESTONE_ATTESTER_ADDRESS,
TEST_ADDRESS_K1_VALIDATOR_ADDRESS,
TEST_ADDRESS_K1_VALIDATOR_FACTORY_ADDRESS
} from "../../constants"
import type { NexusAccount } from "../toNexusAccount"
import { getK1FactoryData, getMeeFactoryData } from "./getFactoryData"

describe("nexus.account.getFactoryData", async () => {
let network: NetworkConfig
let chain: Chain
let bundlerUrl: string

// Test utils
let testClient: MasterClient
let eoaAccount: LocalAccount
let nexusAccount: NexusAccount
let walletClient: WalletClient

beforeAll(async () => {
network = await toNetwork("MAINNET_FROM_ENV_VARS")

chain = network.chain
bundlerUrl = network.bundlerUrl
eoaAccount = network.account!
testClient = toTestClient(chain, getTestAccount(5))
})
afterAll(async () => {
await killNetwork([network?.rpcPort, network?.bundlerPort])
})

test("should check factory data", async () => {
const factoryData = await getK1FactoryData({
signerAddress: eoaAccount.address,
index: 0n,
attesters: [RHINESTONE_ATTESTER_ADDRESS],
attesterThreshold: 1
})

expect(factoryData).toMatchInlineSnapshot(
`"0x0d51f0b70000000000000000000000003079b249dfde4692d7844aa261f8cf7d927a0da50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000333034e9f539ce08819e12c1b8cb29084d"`
)
})

test("should check factory data with mee", async () => {
const factoryData = await getMeeFactoryData({
signerAddress: eoaAccount.address,
index: 0n,
attesters: [MEE_VALIDATOR_ADDRESS],
attesterThreshold: 1,
validatorAddress: MEE_VALIDATOR_ADDRESS,
publicClient: testClient as unknown as PublicClient,
walletClient
})

expect(factoryData).toMatchInlineSnapshot(
`"0xea6d13ac0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000f5b753fdd20c5ca2d7c1210b3ab1ea59030000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000012401fe9ff2000000000000000000000000068ea3e30788abafdc6fd0b38d20bd38a40a2b3d00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000069e2a187aeffb852bf3ccdc95151b200000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000143079b249dfde4692d7844aa261f8cf7d927a0da50000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000068ea3e30788abafdc6fd0b38d20bd38a40a2b3d00000000000000000000000000000000000000000000000000000000"`
)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import {
parseAbi,
toHex
} from "viem"
import {
MEE_VALIDATOR_ADDRESS,
NEXUS_BOOTSTRAP_ADDRESS,
REGISTRY_ADDRESS
} from "../../constants"
import { NexusBootstrapAbi } from "../../constants/abi/NexusBootstrapAbi"

/**
Expand Down Expand Up @@ -56,11 +61,11 @@ export const getK1FactoryData = async ({
* @property {Address} bootStrapAddress - The address of the bootstrap contract
*/
export type GetMeeFactoryDataParams = GetK1FactoryDataParams & {
validatorAddress: Address
registryAddress: Address
validatorAddress?: Address
registryAddress?: Address
publicClient: PublicClient
walletClient: WalletClient
bootStrapAddress: Address
bootStrapAddress?: Address
}

/**
Expand All @@ -69,13 +74,13 @@ export type GetMeeFactoryDataParams = GetK1FactoryDataParams & {
* @returns {Promise<Hex>} Encoded function data for account creation
*/
export const getMeeFactoryData = async ({
validatorAddress,
validatorAddress = MEE_VALIDATOR_ADDRESS,
attesters,
registryAddress,
registryAddress = REGISTRY_ADDRESS,
attesterThreshold,
publicClient,
walletClient,
bootStrapAddress,
bootStrapAddress = NEXUS_BOOTSTRAP_ADDRESS,
signerAddress,
index
}: GetMeeFactoryDataParams): Promise<Hex> => {
Expand Down
73 changes: 73 additions & 0 deletions src/sdk/account/decorators/getNexusAddress.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
http,
type Address,
type Chain,
type LocalAccount,
type PublicClient,
type WalletClient,
createPublicClient
} from "viem"
import { afterAll, beforeAll, describe, expect, test } from "vitest"
import { toNetwork } from "../../../test/testSetup"
import type { NetworkConfig } from "../../../test/testUtils"
import {
MAINNET_ADDRESS_K1_VALIDATOR_FACTORY_ADDRESS,
NEXUS_ACCOUNT_FACTORY
} from "../../constants"
import { getK1NexusAddress, getMeeNexusAddress } from "./getNexusAddress"

describe("account.getNexusAddress", () => {
let network: NetworkConfig
let chain: Chain
let bundlerUrl: string

// Test utils
let publicClient: PublicClient
let eoaAccount: LocalAccount

beforeAll(async () => {
network = await toNetwork("TESTNET_FROM_ENV_VARS")

chain = network.chain
bundlerUrl = network.bundlerUrl
eoaAccount = network.account!
publicClient = createPublicClient({
chain,
transport: http(network.rpcUrl)
})
})

test("should check k1 nexus address", async () => {
const customAttesters = [
"0x1111111111111111111111111111111111111111" as Address,
"0x2222222222222222222222222222222222222222" as Address
]
const customThreshold = 2
const customIndex = 5n

const k1AddressWithParams = await getK1NexusAddress({
publicClient: publicClient as unknown as PublicClient,
signerAddress: eoaAccount.address,
attesters: customAttesters,
threshold: customThreshold,
index: customIndex
})

expect(k1AddressWithParams).toMatchInlineSnapshot(
`"0x93828A8f4405F112a65bf1732a4BE8f5B4C99322"`
)
})

test("should check mee nexus address", async () => {
const index = 1n

const meeAddress = await getMeeNexusAddress({
publicClient: publicClient as unknown as PublicClient,
signerAddress: eoaAccount.address
})

expect(meeAddress).toMatchInlineSnapshot(
`"0x1968a6Ab4a542EB22e7452AC25381AE6c0f07826"`
)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { type Address, pad, toHex } from "viem"
import type { PublicClient } from "viem"
import {
MAINNET_ADDRESS_K1_VALIDATOR_FACTORY_ADDRESS,
MOCK_ATTESTER_ADDRESS,
NEXUS_BOOTSTRAP_ADDRESS,
NEXUS_ACCOUNT_FACTORY,
RHINESTONE_ATTESTER_ADDRESS
} from "../../constants"
import { AccountFactoryAbi } from "../../constants/abi/AccountFactory"
Expand All @@ -15,7 +14,6 @@ import { K1ValidatorFactoryAbi } from "../../constants/abi/K1ValidatorFactory"
* @param publicClient - The public client to use for the read contract
* @param signerAddress - The address of the signer
* @param index - The index of the account
* @param isTestnet - Whether the network is testnet
* @param attesters - The attesters to use
* @param threshold - The threshold of the attesters
* @param factoryAddress - The factory address to use
Expand All @@ -27,38 +25,35 @@ import { K1ValidatorFactoryAbi } from "../../constants/abi/K1ValidatorFactory"
* ```
*/

type K1CounterFactualAddressParams = {
/** The public client to use for the read contract */
publicClient: PublicClient
/** The address of the signer */
signerAddress: Address
/** Whether the network is testnet */
isTestnet?: boolean
/** The index of the account */
index?: bigint
/** The attesters to use */
attesters?: Address[]
/** The threshold of the attesters */
threshold?: number
/** The factory address to use. Defaults to the mainnet factory address */
factoryAddress?: Address
}
export const getK1CounterFactualAddress = async (
params: K1CounterFactualAddressParams
type K1CounterFactualAddressParams<ExtendedPublicClient extends PublicClient> =
{
/** The public client to use for the read contract */
publicClient: ExtendedPublicClient
/** The address of the signer */
signerAddress: Address
/** The index of the account */
index?: bigint
/** The attesters to use */
attesters?: Address[]
/** The threshold of the attesters */
threshold?: number
/** The factory address to use. Defaults to the mainnet factory address */
factoryAddress?: Address
}
export const getK1NexusAddress = async <
ExtendedPublicClient extends PublicClient
>(
params: K1CounterFactualAddressParams<ExtendedPublicClient>
): Promise<Address> => {
const {
publicClient,
signerAddress,
isTestnet = false,
index = 0n,
attesters = [RHINESTONE_ATTESTER_ADDRESS],
threshold = 1,
factoryAddress = MAINNET_ADDRESS_K1_VALIDATOR_FACTORY_ADDRESS
} = params

if (isTestnet) {
attesters.push(MOCK_ATTESTER_ADDRESS)
}
return await publicClient.readContract({
address: factoryAddress,
abi: K1ValidatorFactoryAbi,
Expand All @@ -67,30 +62,24 @@ export const getK1CounterFactualAddress = async (
})
}

type MeeCounterFactualAddressParams = {
/** The public client to use for the read contract */
publicClient: PublicClient
/** The address of the signer */
signerAddress: Address
/** The salt for the account */
index: bigint
/** The factory address to use. Defaults to the mainnet factory address */
factoryAddress?: Address
}
export const getMeeCounterFactualAddress = async (
params: MeeCounterFactualAddressParams
) => {
console.log("getMeeCounterFactualAddress", params)
type MeeCounterFactualAddressParams<ExtendedPublicClient extends PublicClient> =
{
/** The public client to use for the read contract */
publicClient: ExtendedPublicClient
/** The address of the signer */
signerAddress: Address
/** The salt for the account */
index?: bigint
}

const salt = pad(toHex(params.index), { size: 32 })
const {
publicClient,
signerAddress,
factoryAddress = NEXUS_BOOTSTRAP_ADDRESS
} = params
export const getMeeNexusAddress = async (
params: MeeCounterFactualAddressParams<PublicClient>
) => {
const salt = pad(toHex(params.index ?? 0n), { size: 32 })
const { publicClient, signerAddress } = params

return await publicClient.readContract({
address: factoryAddress,
address: NEXUS_ACCOUNT_FACTORY,
abi: AccountFactoryAbi,
functionName: "computeAccountAddress",
args: [signerAddress, salt]
Expand Down
51 changes: 51 additions & 0 deletions src/sdk/account/decorators/getUnifiedERC20Balance.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Address, Chain, LocalAccount } from "viem"
import { base } from "viem/chains"
import { beforeAll, describe, expect, it } from "vitest"
import { toNetwork } from "../../../test/testSetup"
import type { NetworkConfig } from "../../../test/testUtils"
import {
type MultichainSmartAccount,
toMultichainNexusAccount
} from "../../account/toMultiChainNexusAccount"
import { type MeeClient, createMeeClient } from "../../clients/createMeeClient"
import { mcUSDC } from "../../constants/tokens"
import { getUnifiedERC20Balance } from "./getUnifiedERC20Balance"

describe("mee:getUnifiedERC20Balance", () => {
let network: NetworkConfig
let eoaAccount: LocalAccount
let paymentChain: Chain
let paymentToken: Address
let mcNexus: MultichainSmartAccount
let meeClient: MeeClient

beforeAll(async () => {
network = await toNetwork("MAINNET_FROM_ENV_VARS")

paymentChain = network.chain
paymentToken = network.paymentToken!
eoaAccount = network.account!

mcNexus = await toMultichainNexusAccount({
chains: [base, paymentChain],
signer: eoaAccount
})

meeClient = createMeeClient({ account: mcNexus })
})

it("should aggregate balances across chains correctly", async () => {
const unifiedBalance = await getUnifiedERC20Balance({
deployments: mcNexus.deployments,
mcToken: mcUSDC
})

expect(unifiedBalance.balance).toBeGreaterThan(0n)
expect(unifiedBalance.breakdown).toHaveLength(2)
expect(unifiedBalance.decimals).toBe(6)

expect(unifiedBalance.breakdown[0]).toHaveProperty("balance")
expect(unifiedBalance.breakdown[0]).toHaveProperty("decimals")
expect(unifiedBalance.breakdown[0]).toHaveProperty("chainId")
})
})
Loading

0 comments on commit 0dd7c8c

Please sign in to comment.