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

feat: added kill switch force unblock | fix - dummy paymasterAndData #40

Merged
merged 1 commit into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/publish-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ jobs:
TEAM_ID: ${{ secrets.TEAM_ID }}
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
run: yarn test:e2e

# # Lerna publish will, compute the new version, update files, run precommit hooks, tag, publish, and push change log
# - name: Publish using Lerna
# if: inputs.publish
Expand Down
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Follow the instructions below to install the packages.
via `yarn`

```bash
yarn add @alchemy/aa-core @alchemy/aa-ethers @zerodev/sdk
yarn add @zerodev/sdk
```

via `npm`

```bash
npm i -s @alchemy/aa-core @alchemy/aa-ethers @zerodev/sdk
npm i -s @zerodev/sdk
```

## Example Usage to Interact with [Kernel Accounts](https://github.com/zerodevapp/kernel/blob/main/src/Kernel.sol)
Expand All @@ -24,11 +24,11 @@ npm i -s @alchemy/aa-core @alchemy/aa-ethers @zerodev/sdk

```ts
import { ECDSAValidator } from "@zerodev/sdk";
import { PrivateKeySigner } from "@alchemy/aa-core";
import { LocalAccountSigner } from "@alchemy/aa-core";

// 1. define the EOA owner of the Smart Account
// This is just one exapmle of how to interact with EOAs, feel free to use any other interface
const owner = PrivateKeySigner.privateKeyToAccountSigner(PRIVATE_KEY);
const owner = LocalAccountSigner.privateKeyToAccountSigner(PRIVATE_KEY);

// 2. Create a ZeroDev Provider
let ecdsaProvider = await ECDSAProvider.init({
Expand Down Expand Up @@ -324,6 +324,19 @@ await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
);
```

#### Force Unblock

```ts
let result = await sudoModeKillSwitchProvider.sendUserOperation({
target: accountAddress,
data: selector,
});

await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
result.hash as Hash
);
```

<!--
### ERC165 Session Key Validator

Expand Down
24 changes: 20 additions & 4 deletions packages/accounts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Follow the instructions below to install the packages.
via `yarn`

```bash
yarn add @alchemy/aa-core @alchemy/aa-ethers @zerodevapp/sdk
yarn add @zerodev/sdk
```

via `npm`

```bash
npm i -s @alchemy/aa-core @alchemy/aa-ethers @zerodev/sdk
npm i -s @zerodev/sdk
```

## Example Usage to Interact with [Kernel Accounts](https://github.com/zerodevapp/kernel/blob/main/src/Kernel.sol)
Expand All @@ -24,11 +24,11 @@ npm i -s @alchemy/aa-core @alchemy/aa-ethers @zerodev/sdk

```ts
import { ECDSAValidator } from "@zerodev/sdk";
import { PrivateKeySigner } from "@alchemy/aa-core";
import { LocalAccountSigner } from "@alchemy/aa-core";

// 1. define the EOA owner of the Smart Account
// This is just one exapmle of how to interact with EOAs, feel free to use any other interface
const owner = PrivateKeySigner.privateKeyToAccountSigner(PRIVATE_KEY);
const owner = LocalAccountSigner.privateKeyToAccountSigner(PRIVATE_KEY);

// 2. Create a ZeroDev Provider
let ecdsaProvider = await ECDSAProvider.init({
Expand Down Expand Up @@ -324,6 +324,20 @@ await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
);
```

#### Force Unblock

```ts
let result = await sudoModeKillSwitchProvider.sendUserOperation({
target: accountAddress,
data: selector,
});

await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
result.hash as Hash
);
```

<!--
### ERC165 Session Key Validator

```ts
Expand Down Expand Up @@ -394,6 +408,8 @@ const { hash } = await erc165SessionKeyProvider.sendUserOperation({
});
```

-->

### Session Key Validator

```ts
Expand Down
10 changes: 3 additions & 7 deletions packages/accounts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,11 @@
"test:run": "vitest run"
},
"devDependencies": {
"@alchemy/aa-core": "^0.1.0-alpha.23",
"@alchemy/aa-ethers": "^0.1.0-alpha.23",
"@turnkey/ethers": "^0.16.5",
"typescript": "^5.0.4",
"typescript-template": "*",
"vitest": "^0.31.0"
},
"peerDependencies": {
"@alchemy/aa-core": "^0.1.0-alpha.23",
"@alchemy/aa-ethers": "^0.1.0-alpha.23"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
Expand All @@ -71,6 +65,8 @@
"dependencies": {
"axios": "^1.4.0",
"merkletreejs": "^0.3.10",
"viem": "^1.5.3"
"viem": "^1.5.3",
"@alchemy/aa-core": "0.1.0-alpha.23",
"@alchemy/aa-ethers": "0.1.0-alpha.23"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@ import {
http,
type Hex,
getFunctionSelector,
encodeFunctionData,
type Hash,
zeroAddress,
} from "viem";
import { polygonMumbai } from "viem/chains";
import { config } from "./kernel-account.test.js";
import {
ECDSAProvider,
KillSwitchProvider,
} from "../validator-provider/index.js";
import {
KILL_SWITCH_ACTION,
KILL_SWITCH_VALIDATOR_ADDRESS,
} from "../constants.js";
import { KILL_SWITCH_ACTION } from "../constants.js";
import { KernelAccountAbi } from "../abis/KernelAccountAbi.js";
import { ValidatorMode } from "../validator/base.js";
import { KillSwitchValidatorAbi } from "../abis/KillSwitchValidatorAbi.js";
import { LocalAccountSigner } from "@alchemy/aa-core";

// [TODO] - Organize the test code properly
Expand Down Expand Up @@ -74,7 +68,7 @@ describe("Kernel Kill Switch Provider Test", async () => {
blockerKillSwitchProvider = await KillSwitchProvider.init({
projectId: config.projectIdWithGasSponsorship,
guardian: secondOwner,
delaySeconds: 10,
delaySeconds: 20,
opts: {
accountConfig: {
accountAddress,
Expand Down Expand Up @@ -167,51 +161,18 @@ describe("Kernel Kill Switch Provider Test", async () => {
);

it(
"should wait for the delay",
async () => {
new Promise((resolve) => setTimeout(resolve, 10000));
},
{ timeout: 1000000 }
);

it(
"should send UserOp after pauseUntil has passed",
async () => {
const result = await ecdsaProvider.sendUserOperation({
target: await owner.getAddress(),
data: "0x",
});
console.log(result);
const tx = await ecdsaProvider.waitForUserOperationTransaction(
result.hash as Hash
);
console.log(tx);
},
{ timeout: 1000000 }
);

// Test for unblocking
it(
"should make ecdsa default validator",
"should force unblock",
async () => {
const setDefValdata = encodeFunctionData({
abi: KernelAccountAbi,
functionName: "setDefaultValidator",
args: [
await ecdsaProvider.getValidator().validatorAddress,
await owner.getAddress(),
],
});
let result = await sudoModeKillSwitchProvider.sendUserOperation({
target: accountAddress,
data: setDefValdata,
data: selector,
});
console.log(result);
let tx = await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
result.hash as Hex
);
console.log("tx", tx);

const tx =
await sudoModeKillSwitchProvider.waitForUserOperationTransaction(
result.hash as Hash
);
console.log(tx);
const defaultValidator = await client.readContract({
address: accountAddress,
abi: KernelAccountAbi,
Expand All @@ -221,28 +182,6 @@ describe("Kernel Kill Switch Provider Test", async () => {
expect(defaultValidator).to.equal(
ecdsaProvider.getValidator().validatorAddress
);
},
{ timeout: 1000000 }
);

// Test for unblocking
it(
"should set default mode to 0x00000000",
async () => {
const setDefModeData = encodeFunctionData({
abi: KernelAccountAbi,
functionName: "disableMode",
args: ["0x00000000"],
});
const result = await ecdsaProvider.sendUserOperation({
target: accountAddress,
data: setDefModeData,
});
console.log(result);
const tx = await ecdsaProvider.waitForUserOperationTransaction(
result.hash as Hex
);
console.log(tx);
const disabledMode = await client.readContract({
address: accountAddress,
abi: KernelAccountAbi,
Expand All @@ -254,42 +193,36 @@ describe("Kernel Kill Switch Provider Test", async () => {
{ timeout: 1000000 }
);

// Test for unblocking
it(
"should disable KillSwitchValidator",
"should send UserOp after pauseUntil has passed",
async () => {
const disableData = encodeFunctionData({
abi: KillSwitchValidatorAbi,
functionName: "disable",
args: ["0x"],
});
const result = await ecdsaProvider.sendUserOperation({
target: KILL_SWITCH_VALIDATOR_ADDRESS,
data: disableData,
let result, tx;
try {
result = await blockerKillSwitchProvider.sendUserOperation({
target: accountAddress,
data: selector,
});
console.log(result);
tx = await blockerKillSwitchProvider.waitForUserOperationTransaction(
result.hash as Hex
);
console.log("tx", tx);
} catch (e) {
console.log(e);
}

// Wait for the delay
new Promise((resolve) => setTimeout(resolve, 20000));

result = await ecdsaProvider.sendUserOperation({
target: await owner.getAddress(),
data: "0x",
});
console.log(result);
const tx = await ecdsaProvider.waitForUserOperationTransaction(
result.hash as Hex
tx = await ecdsaProvider.waitForUserOperationTransaction(
result.hash as Hash
);
console.log(tx);
const killSwitchData = await client.readContract({
address: KILL_SWITCH_VALIDATOR_ADDRESS,
abi: KillSwitchValidatorAbi,
functionName: "killSwitchValidatorStorage",
args: [accountAddress],
});
console.log("killSwitchData", killSwitchData, [
zeroAddress,
zeroAddress,
0,
"0x00000000",
]);
expect(killSwitchData).to.eql([
zeroAddress,
zeroAddress,
0,
"0x00000000",
]);
},
{ timeout: 1000000 }
);
Expand Down
4 changes: 2 additions & 2 deletions packages/accounts/src/kernel-zerodev/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export const KERNEL_FACTORY_ADDRESS =
"0x5de4839a76cf55d0c90e2061ef4386d962E15ae3";
export const KERNEL_IMPL_ADDRESS = "0xf048AD83CB2dfd6037A43902a2A5Be04e53cd2Eb";
export const KILL_SWITCH_VALIDATOR_ADDRESS =
"0x2db0DbfDf90Dbe2859158Aa71db1FcDCb3E579c8";
export const KILL_SWITCH_ACTION = "0xf5aa34DD2cba311947e143183ED325A4A8C674Af";
"0x7393A7dA58CCfFb78f52adb09705BE6E20F704BC";
export const KILL_SWITCH_ACTION = "0x3f38e479304c7F18F988269a1bDa7d646bd48243";
export const DUMMY_ECDSA_SIG =
"0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c";
export const ERC165_SESSION_KEY_VALIDATOR_ADDRESS =
Expand Down
12 changes: 9 additions & 3 deletions packages/accounts/src/kernel-zerodev/middleware/paymaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,21 @@ export const zeroDevPaymasterAndDataMiddleware = <
);
if (
paymasterConfig.onlySendSponsoredTransaction &&
(!paymasterResp || paymasterResp.paymasterAndData === "0x")
(!paymasterResp ||
!paymasterResp.paymasterAndData ||
paymasterResp.paymasterAndData === "0x")
) {
throw new Error("Transaction is not sponsored");
}
if (
paymasterResp === undefined ||
!paymasterResp ||
!paymasterResp.paymasterAndData ||
paymasterResp.paymasterAndData === "0x"
) {
return struct;
return {
...struct,
paymasterAndData: "0x",
};
}
return {
...struct,
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/src/kernel-zerodev/paymaster/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export abstract class Paymaster {
struct: UserOperationStruct,
paymasterProvider?: PaymasterAndBundlerProviders,
shouldOverrideFee?: boolean
): Promise<UserOperationStruct>;
): Promise<UserOperationStruct | undefined>;
protected async signUserOp({
userOp,
callData,
Expand Down
Loading
Loading