Skip to content

Commit

Permalink
Merge pull request #52 from zerodevapp/feat/kernel-v2.2-support
Browse files Browse the repository at this point in the history
feat: added kernel v2.2 support and paymaster error log improvement
  • Loading branch information
SahilVasava authored Oct 27, 2023
2 parents 8723ac4 + 8824651 commit 911a5e7
Show file tree
Hide file tree
Showing 15 changed files with 355 additions and 182 deletions.
16 changes: 7 additions & 9 deletions .github/workflows/on-pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Run checks on Pull Requests
on:
pull_request:
workflow_dispatch:

jobs:
enforce_title:
Expand All @@ -25,19 +26,22 @@ jobs:
name: Lint and Build and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: true

- name: Setup Node.js
- name: Setup Node.js 18.x
uses: actions/setup-node@v1
with:
node-version: "18.13"
cache: "yarn"

- name: Install dependencies
- name: Install SDK dependencies
run: yarn install --frozen-lockfile

- name: Lint SDK
run: yarn lint:check

- name: Build SDK
run: yarn build

Expand All @@ -49,11 +53,5 @@ jobs:

- name: E2E tests
env:
API_URL: ${{ secrets.API_URL }}
API_KEY: ${{ secrets.API_KEY }}
TEAM_ID: ${{ secrets.TEAM_ID }}
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
run: yarn --cwd e2e-tests test:e2e

# - name: Unit Test
# run: yarn test
115 changes: 86 additions & 29 deletions packages/accounts/src/kernel-zerodev/__tests__/kernel-account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import {
parseAbiParameters,
encodeFunctionData,
type Hash,
createPublicClient,
http,
} from "viem";
import { polygonMumbai } from "viem/chains";
import { generatePrivateKey } from "viem/accounts";
import { LocalAccountSigner } from "@alchemy/aa-core";
import { TEST_ERC20Abi } from "../abis/Test_ERC20Abi.js";
import { ECDSAProvider } from "../validator-provider/index.js";
import { CHAIN_ID_TO_NODE } from "../constants.js";

export const config = {
privateKey: (process.env.PRIVATE_KEY as Hex) ?? generatePrivateKey(),
Expand All @@ -36,6 +39,10 @@ describe("Kernel Account Tests", () => {
"0x022430a80f723d8789f0d4fb346bdd013b546e4b96fcacf8aceca2b1a65a19dc";
const mockOwner =
LocalAccountSigner.privateKeyToAccountSigner(dummyPrivateKey);
const client = createPublicClient({
chain: polygonMumbai,
transport: http(CHAIN_ID_TO_NODE[polygonMumbai.id]),
});

it(
"getAddress returns valid counterfactual address",
Expand Down Expand Up @@ -132,7 +139,7 @@ describe("Kernel Account Tests", () => {
const ownerSignedMessage =
"0xdad9efc9364e94756f6b16380b7d60c24a14526946ddaa52ef181e7ad065eaa146c9125b7ee62258caad708f57344cfc80d74bd69c0c1e95d75e7c7645c71e401b";
const factoryCode =
"0x296601cd000000000000000000000000f048ad83cb2dfd6037a43902a2a5be04e53cd2eb0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000084d1f57894000000000000000000000000d9ab5096a832b9ce79914329daee236f8eea039000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000014abcfC3DB1e0f5023F5a4f40c03D149f316E6A5cc00000000000000000000000000000000000000000000000000000000000000000000000000000000";
"0x296601cd0000000000000000000000000da6a956b9488ed4dd761e59f52fdc6c8068e6b50000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000084d1f57894000000000000000000000000d9ab5096a832b9ce79914329daee236f8eea039000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000014abcfC3DB1e0f5023F5a4f40c03D149f316E6A5cc00000000000000000000000000000000000000000000000000000000000000000000000000000000";
const signature =
encodeAbiParameters(parseAbiParameters("address, bytes, bytes"), [
config.accountFactoryAddress,
Expand Down Expand Up @@ -172,37 +179,41 @@ describe("Kernel Account Tests", () => {
{ timeout: 100000 }
);

it("signMessage should correctly sign the message", async () => {
const messageToBeSigned: Hex =
"0xa70d0af2ebb03a44dcd0714a8724f622e3ab876d0aa312f0ee04823285d6fb1b";
it(
"signMessage should correctly sign the message",
async () => {
const messageToBeSigned: Hex =
"0xa70d0af2ebb03a44dcd0714a8724f622e3ab876d0aa312f0ee04823285d6fb1b";

let ecdsaProvider = await ECDSAProvider.init({
projectId: config.projectId,
owner: mockOwner,
});
let ecdsaProvider = await ECDSAProvider.init({
projectId: config.projectId,
owner: mockOwner,
});

const signer = ecdsaProvider.getAccount();
const signer = ecdsaProvider.getAccount();

expect(await signer.signMessage(messageToBeSigned)).toBe(
"0x002e1c0f007a5d2723b28da3165ee45c6fc49bf1fdf3cfeaef66de31dd90248647781142beadcb8524bd5a9be0da455881bfa003e3334fffd2ee6d648a78e06d1c"
);
expect(await signer.signMessage(messageToBeSigned)).toBe(
"0x002e1c0f007a5d2723b28da3165ee45c6fc49bf1fdf3cfeaef66de31dd90248647781142beadcb8524bd5a9be0da455881bfa003e3334fffd2ee6d648a78e06d1c"
);

ecdsaProvider = await ECDSAProvider.init({
projectId: config.projectId,
owner: mockOwner,
opts: {
accountConfig: {
index: 1000n,
ecdsaProvider = await ECDSAProvider.init({
projectId: config.projectId,
owner: mockOwner,
opts: {
accountConfig: {
index: 1000n,
},
},
},
});
});

const signer2 = ecdsaProvider.getAccount();
const signer2 = ecdsaProvider.getAccount();

expect(await signer2.signMessage(messageToBeSigned)).toBe(
"0x002e1c0f007a5d2723b28da3165ee45c6fc49bf1fdf3cfeaef66de31dd90248647781142beadcb8524bd5a9be0da455881bfa003e3334fffd2ee6d648a78e06d1c"
);
});
expect(await signer2.signMessage(messageToBeSigned)).toBe(
"0x002e1c0f007a5d2723b28da3165ee45c6fc49bf1fdf3cfeaef66de31dd90248647781142beadcb8524bd5a9be0da455881bfa003e3334fffd2ee6d648a78e06d1c"
);
},
{ timeout: 100000 }
);

// NOTE - this test case will fail if the gas fee is sponsored
it(
Expand Down Expand Up @@ -289,9 +300,20 @@ describe("Kernel Account Tests", () => {
//to fix bug in old versions
await ecdsaProvider.getAccount().getInitCode();

const mintData = encodeFunctionData({
abi: TEST_ERC20Abi,
args: [await ecdsaProvider.getAddress(), 700000000000000000n],
functionName: "mint",
});
const balanceBefore = await client.readContract({
address: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
abi: TEST_ERC20Abi,
functionName: "balanceOf",
args: [await ecdsaProvider.getAddress()],
});
const result = ecdsaProvider.sendUserOperation({
target: "0xA02CDdFa44B8C01b4257F54ac1c43F75801E8175",
data: "0x",
target: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
data: mintData,
value: 0n,
});
await expect(result).resolves.not.toThrowError();
Expand All @@ -300,6 +322,13 @@ describe("Kernel Account Tests", () => {
await result
).hash as Hash
);
const balanceAfter = await client.readContract({
address: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
abi: TEST_ERC20Abi,
functionName: "balanceOf",
args: [await ecdsaProvider.getAddress()],
});
expect(balanceAfter).to.eq(balanceBefore + 700000000000000000n);
},
{ timeout: 100000 }
);
Expand All @@ -325,9 +354,13 @@ describe("Kernel Account Tests", () => {
},
},
});
//to fix bug in old versions
await ecdsaProvider.getAccount().getInitCode();

const balanceBefore = await client.readContract({
address: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
abi: TEST_ERC20Abi,
functionName: "balanceOf",
args: [await ecdsaProvider.getAddress()],
});
const mintData = encodeFunctionData({
abi: TEST_ERC20Abi,
args: [await ecdsaProvider.getAddress(), 700000000000000000n],
Expand All @@ -346,6 +379,15 @@ describe("Kernel Account Tests", () => {
await result
).hash as Hash
);
const balanceAfter = await client.readContract({
address: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
abi: TEST_ERC20Abi,
functionName: "balanceOf",
args: [await ecdsaProvider.getAddress()],
});
expect(balanceAfter.toString(16)).to.not.eq(
(balanceBefore + 700000000000000000n).toString(16)
);
},
{ timeout: 100000 }
);
Expand Down Expand Up @@ -385,6 +427,12 @@ describe("Kernel Account Tests", () => {
args: [await owner.getAddress(), 133700000000n],
functionName: "transfer",
});
const balanceBefore = await client.readContract({
address: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
abi: TEST_ERC20Abi,
functionName: "balanceOf",
args: [await ecdsaProvider.getAddress()],
});
const result = ecdsaProvider.sendUserOperation([
{
target: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
Expand All @@ -398,6 +446,15 @@ describe("Kernel Account Tests", () => {
},
]);
await expect(result).resolves.not.toThrowError();
const balanceAfter = await client.readContract({
address: "0x3870419Ba2BBf0127060bCB37f69A1b1C090992B",
abi: TEST_ERC20Abi,
functionName: "balanceOf",
args: [await ecdsaProvider.getAddress()],
});
expect(Number(balanceAfter.toString())).to.lt(
Number((balanceBefore + 700000000000000000n - 133700000000n).toString())
);
},
{ timeout: 100000 }
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { polygonMumbai } from "viem/chains";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { config } from "./kernel-account.test.js";
import { ECDSAProvider } from "../validator-provider/index.js";
import { TOKEN_ACTION } from "../constants.js";
import { CHAIN_ID_TO_NODE, TOKEN_ACTION } from "../constants.js";
import { ValidatorMode } from "../validator/base.js";
import { Test_ERC721Abi } from "../abis/Test_ERC721Abi.js";
import { ERC165SessionKeyProvider } from "../validator-provider/erc165-session-key-provider.js";
Expand All @@ -34,12 +34,12 @@ describe("Kernel ERC165SessionKey Provider Test", async () => {

const client = createPublicClient({
chain: polygonMumbai,
transport: http("https://rpc.ankr.com/polygon_mumbai"),
transport: http(CHAIN_ID_TO_NODE[polygonMumbai.id]),
});
const walletClient = createWalletClient({
account: privateKeyToAccount(config.privateKey),
chain: polygonMumbai,
transport: http("https://rpc.ankr.com/polygon_mumbai"),
transport: http(CHAIN_ID_TO_NODE[polygonMumbai.id]),
});
const selector = getFunctionSelector(
"transferERC721Action(address, uint256, address)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ describe("Kernel Recovery Provider Test", async () => {

const client = createPublicClient({
chain: polygonMumbai,
// transport: http("https://rpc.ankr.com/polygon_mumbai"),
transport: http(CHAIN_ID_TO_NODE[polygonMumbai.id]),
});
let accountAddress: Hex = "0x";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { config } from "./kernel-account.test.js";
import { LocalAccountSigner } from "@alchemy/aa-core";
import { generatePrivateKey } from "viem/accounts";
import { ECDSAProvider } from "../validator-provider/index.js";
import { CHAIN_ID_TO_NODE } from "../constants.js";

// [TODO] - Organize the test code properly
describe("Kernel Validator Provider Test", async () => {
Expand All @@ -15,7 +16,7 @@ describe("Kernel Validator Provider Test", async () => {

const client = createPublicClient({
chain: polygonMumbai,
transport: http("https://rpc.ankr.com/polygon_mumbai"),
transport: http(CHAIN_ID_TO_NODE[polygonMumbai.id]),
});

let accountAddress: Hex = "0x";
Expand Down
57 changes: 53 additions & 4 deletions packages/accounts/src/kernel-zerodev/abis/KernelAccountAbi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,25 @@ export const KernelAccountAbi = [
name: "ExecutionChanged",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "sender",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "amount",
type: "uint256",
},
],
name: "Received",
type: "event",
},
{
anonymous: false,
inputs: [
Expand Down Expand Up @@ -179,7 +198,7 @@ export const KernelAccountAbi = [
},
{
internalType: "enum Operation",
name: "operation",
name: "",
type: "uint8",
},
],
Expand All @@ -188,6 +207,36 @@ export const KernelAccountAbi = [
stateMutability: "payable",
type: "function",
},
{
inputs: [
{
components: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "value",
type: "uint256",
},
{
internalType: "bytes",
name: "data",
type: "bytes",
},
],
internalType: "struct Call[]",
name: "calls",
type: "tuple[]",
},
],
name: "executeBatch",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "getDefaultValidator",
Expand Down Expand Up @@ -503,12 +552,12 @@ export const KernelAccountAbi = [
type: "address",
},
{
internalType: "uint48",
internalType: "ValidUntil",
name: "_validUntil",
type: "uint48",
},
{
internalType: "uint48",
internalType: "ValidAfter",
name: "_validAfter",
type: "uint48",
},
Expand Down Expand Up @@ -597,7 +646,7 @@ export const KernelAccountAbi = [
},
],
internalType: "struct UserOperation",
name: "userOp",
name: "_userOp",
type: "tuple",
},
{
Expand Down
Loading

0 comments on commit 911a5e7

Please sign in to comment.