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

chore: release/v1.2.0 #268

Merged
merged 13 commits into from
Nov 17, 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The `aa-sdk` is modular at every layer of the stack and can be easily extended t
yarn add @alchemy/aa-accounts @alchemy/aa-core
```

### [Light Account Example](https://accountkit.alchemy.com/getting-started#a-simple-light-account-example)
### [Light Account Example](https://accountkit.alchemy.com/overview/getting-started#a-simple-light-account-example)

## Docs

Expand Down
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

This dapp provides an example of how to use Alchemy's Account Kit to build a dApp that mints a token to a Light Account SCA using Alchemy's Gas Manager to provide a gas-less minting experience

[Try it out!](https://aa-simple-dapp.vercel.app/)

[View on Github!](https://github.com/alchemyplatform/aa-sdk/tree/development/examples/aa-simple-dapp)

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/alchemyplatform/aa-sdk/tree/main/examples/aa-simple-dapp?file=README.md)

## alchemy-dAApp
Expand Down
2 changes: 1 addition & 1 deletion examples/alchemy-daapp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const serverConfigs: Record<number, ServerConfiguration> = {
```
### **🗒️ Notes:** for `nftContractAddress` and `lightAccountFactoryAddress`
- There are already contract addresses deployed for them across [various chains here](https://github.com/alchemyplatform/aa-sdk/blob/main/examples/alchemy-daapp/src/configs/clientConfigs.ts).
- We used Alchemy's [lightAccountFactory here]. todo(ajay): post the repo when live
- We used Alchemy's [lightAccountFactory here](https://github.com/alchemyplatform/light-account).
- Finally, the contracts sibling package has the copy of the [NFT contract](https://github.com/alchemyplatform/aa-sdk/tree/main/examples/contracts/DAAppNFT/src) along instructions on [how to deploy it](https://github.com/alchemyplatform/aa-sdk/blob/main/examples/contracts/README.md).

4. Update the serverConfigs.ts file with your alchemy API keys:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import { KernelAccountProvider } from "../provider.js";
import { KernelBaseValidator, ValidatorMode } from "../validator/base.js";
import { MockSigner } from "./mocks/mock-signer.js";

const chain = polygonMumbai;

describe("Kernel Account Tests", () => {
//any wallet should work
const config = {
privateKey: generatePrivateKey(),
mockWallet: "0x48D4d3536cDe7A257087206870c6B6E76e3D4ff4",
chain: polygonMumbai,
rpcProvider: `${polygonMumbai.rpcUrls.alchemy.http[0]}/demo`,
chain,
rpcProvider: `${chain.rpcUrls.alchemy.http[0]}/demo`,
validatorAddress: "0x180D6465F921C7E0DEA0040107D342c87455fFF5" as Address,
accountFactoryAddress:
"0x5D006d3880645ec6e254E18C1F879DAC9Dd71A39" as Address,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export const MUMBAI_RPC_URL = process.env.MUMBAI_RPC_URL;
export const API_KEY = process.env.API_KEY;
export const OWNER_MNEMONIC = process.env.OWNER_MNEMONIC!;
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ import {
import { KernelAccountProvider } from "../provider.js";
import type { KernelUserOperationCallData } from "../types.js";
import { KernelBaseValidator, ValidatorMode } from "../validator/base.js";
import { MUMBAI_RPC_URL, OWNER_MNEMONIC } from "./constants.js";
import { API_KEY, OWNER_MNEMONIC } from "./constants.js";
import { MockSigner } from "./mocks/mock-signer.js";

const chain = polygonMumbai;

describe("Kernel Account Tests", () => {
//any wallet should work
const config = {
chain: polygonMumbai,
rpcProvider: MUMBAI_RPC_URL!,
chain,
rpcProvider: `${chain.rpcUrls.alchemy.http[0]}/${API_KEY}`!,
validatorAddress: "0x180D6465F921C7E0DEA0040107D342c87455fFF5" as Address,
accountFactoryAddress:
"0x5D006d3880645ec6e254E18C1F879DAC9Dd71A39" as Address,
entryPointAddress: getDefaultEntryPointAddress(polygonMumbai),
entryPointAddress: getDefaultEntryPointAddress(chain),
};

const ownerAccount = mnemonicToAccount(OWNER_MNEMONIC);
Expand Down
17 changes: 10 additions & 7 deletions packages/accounts/src/light-account/__tests__/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ import { describe, it } from "vitest";
import { LightSmartContractAccount } from "../account.js";
import { getDefaultLightAccountFactoryAddress } from "../utils.js";

const chain = polygonMumbai;

describe("Light Account Tests", () => {
const dummyMnemonic =
"test test test test test test test test test test test test";
const owner: SmartAccountSigner =
LocalAccountSigner.mnemonicToAccountSigner(dummyMnemonic);
const chain = polygonMumbai;

it("should correctly sign the message", async () => {
const signer = givenConnectedProvider({ owner, chain });
const provider = givenConnectedProvider({ owner, chain });
expect(
await signer.signMessage(
await provider.signMessage(
"0xa70d0af2ebb03a44dcd0714a8724f622e3ab876d0aa312f0ee04823285d6fb1b"
)
).toBe(
Expand All @@ -28,9 +29,9 @@ describe("Light Account Tests", () => {
});

it("should correctly sign typed data", async () => {
const signer = givenConnectedProvider({ owner, chain });
const provider = givenConnectedProvider({ owner, chain });
expect(
await signer.signTypedData({
await provider.signTypedData({
types: {
Request: [{ name: "hello", type: "string" }],
},
Expand All @@ -55,7 +56,7 @@ describe("Light Account Tests", () => {
});

it("should correctly encode batch transaction data", async () => {
const signer = givenConnectedProvider({ owner, chain });
const provider = givenConnectedProvider({ owner, chain });
const data = [
{
target: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
Expand All @@ -67,7 +68,9 @@ describe("Light Account Tests", () => {
},
] satisfies BatchUserOperationCallData;

expect(await signer.account.encodeBatchExecute(data)).toMatchInlineSnapshot(
expect(
await provider.account.encodeBatchExecute(data)
).toMatchInlineSnapshot(
'"0x18dfb3c7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000004deadbeef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004cafebabe00000000000000000000000000000000000000000000000000000000"'
);
});
Expand Down
2 changes: 0 additions & 2 deletions packages/accounts/src/light-account/e2e-tests/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
export const API_KEY = process.env.API_KEY!;
export const PAYMASTER_POLICY_ID = process.env.PAYMASTER_POLICY_ID!;

export const UNDEPLOYED_OWNER_MNEMONIC = process.env.UNDEPLOYED_OWNER_MNEMONIC!;
export const LIGHT_ACCOUNT_OWNER_MNEMONIC =
process.env.LIGHT_ACCOUNT_OWNER_MNEMONIC!;
// todo(ajay): replace with OWNER_MNEMONIC when light account factory address when live (accidentally moved owner account to a different mnemonic during testing)
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ describe("Light Account Tests", () => {
);

it("should successfully get counterfactual address", async () => {
const signer = givenConnectedProvider({ owner, chain });
expect(await signer.getAddress()).toMatchInlineSnapshot(
'"0xbd96C2c76dE02A75fe2909730422e05ce18f484e"'
const provider = givenConnectedProvider({ owner, chain });
expect(await provider.getAddress()).toMatchInlineSnapshot(
'"0x1a3a89cd46f124EF40848966c2D7074a575dbC27"'
);
});

it("should sign typed data successfully", async () => {
const signer = givenConnectedProvider({ owner, chain });
const provider = givenConnectedProvider({ owner, chain });
const typedData = {
types: {
Request: [{ name: "hello", type: "string" }],
Expand All @@ -47,20 +47,20 @@ describe("Light Account Tests", () => {
hello: "world",
},
};
expect(await signer.signTypedData(typedData)).toBe(
expect(await provider.signTypedData(typedData)).toBe(
await owner.signTypedData(typedData)
);
});

it("should sign message successfully", async () => {
const signer = givenConnectedProvider({ owner, chain });
expect(await signer.signMessage("test")).toBe(
const provider = givenConnectedProvider({ owner, chain });
expect(await provider.signMessage("test")).toBe(
await owner.signMessage("test")
);
});

it("should sign typed data with 6492 successfully for undeployed account", async () => {
const undeployedSigner = givenConnectedProvider({
const undeployedProvider = givenConnectedProvider({
owner: undeployedOwner,
chain,
});
Expand All @@ -74,21 +74,21 @@ describe("Light Account Tests", () => {
},
};
expect(
await undeployedSigner.signTypedDataWith6492(typedData)
await undeployedProvider.signTypedDataWith6492(typedData)
).toMatchInlineSnapshot(
'"0x000000000000000000000000000000893a26168158fbeadd9335be5bc96592e2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000445fbfb9cf000000000000000000000000ef9d7530d16df66481adf291dc9a12b44c7f7df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041591a9422219a5f2bc87ee24a82a6d5ef9674bf7408a2a289984de258466d148e75efb65b487ffbfcb061b268b1b667d8d7d4eac2c3d9d2d0a52d49c891be567c1c000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492"'
'"0x00000000000000000000000000000055c0b4fa41dde26a74435ff03692292fbd000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000445fbfb9cf000000000000000000000000ef9d7530d16df66481adf291dc9a12b44c7f7df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041591a9422219a5f2bc87ee24a82a6d5ef9674bf7408a2a289984de258466d148e75efb65b487ffbfcb061b268b1b667d8d7d4eac2c3d9d2d0a52d49c891be567c1c000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492"'
);
});

it("should sign message with 6492 successfully for undeployed account", async () => {
const undeployedSigner = givenConnectedProvider({
const undeployedProvider = givenConnectedProvider({
owner: undeployedOwner,
chain,
});
expect(
await undeployedSigner.signMessageWith6492("test")
await undeployedProvider.signMessageWith6492("test")
).toMatchInlineSnapshot(
'"0x000000000000000000000000000000893a26168158fbeadd9335be5bc96592e2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000445fbfb9cf000000000000000000000000ef9d7530d16df66481adf291dc9a12b44c7f7df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041be34ecce63c5248d5cda407e7da319be3c861e6e2c5d30c9630cd35dcb55e56205c482503552883923f79e751ea3671cbb84d65b18af33cd3034aeb7d529da9a1b000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492"'
'"0x00000000000000000000000000000055c0b4fa41dde26a74435ff03692292fbd000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000445fbfb9cf000000000000000000000000ef9d7530d16df66481adf291dc9a12b44c7f7df00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041be34ecce63c5248d5cda407e7da319be3c861e6e2c5d30c9630cd35dcb55e56205c482503552883923f79e751ea3671cbb84d65b18af33cd3034aeb7d529da9a1b000000000000000000000000000000000000000000000000000000000000006492649264926492649264926492649264926492649264926492649264926492"'
);
});

Expand All @@ -97,22 +97,28 @@ describe("Light Account Tests", () => {
* For current balance, @see: https://sepolia.etherscan.io/address/0x7eDdc16B15259E5541aCfdebC46929873839B872
*/
it("should execute successfully", async () => {
const signer = givenConnectedProvider({ owner, chain });
const result = await signer.sendUserOperation({
target: await signer.getAddress(),
const provider = givenConnectedProvider({ owner, chain });
const result = await provider.sendUserOperation({
target: await provider.getAddress(),
data: "0x",
});
const txnHash = signer.waitForUserOperationTransaction(result.hash as Hash);
const txnHash = provider.waitForUserOperationTransaction(
result.hash as Hash
);

await expect(txnHash).resolves.not.toThrowError();
}, 50000);

it("should fail to execute if account address is not deployed and not correct", async () => {
const accountAddress = "0xc33AbD9621834CA7c6Fc9f9CC3c47b9c17B03f9F";
const newSigner = givenConnectedProvider({ owner, chain, accountAddress });
const newProvider = givenConnectedProvider({
owner,
chain,
accountAddress,
});

const result = newSigner.sendUserOperation({
target: await newSigner.getAddress(),
const result = newProvider.sendUserOperation({
target: await newProvider.getAddress(),
data: "0x",
});

Expand All @@ -131,17 +137,17 @@ describe("Light Account Tests", () => {
});

it("should get owner successfully", async () => {
const signer = givenConnectedProvider({ owner, chain });
expect(await signer.account.getOwnerAddress()).toMatchInlineSnapshot(
const provider = givenConnectedProvider({ owner, chain });
expect(await provider.account.getOwnerAddress()).toMatchInlineSnapshot(
'"0x65eaA2AfDF6c97295bA44C458abb00FebFB3a5FA"'
);
expect(await signer.account.getOwnerAddress()).toBe(
expect(await provider.account.getOwnerAddress()).toBe(
await owner.getAddress()
);
});

it("should transfer ownership successfully", async () => {
const signer = givenConnectedProvider({
const provider = givenConnectedProvider({
owner,
chain,
feeOpts: {
Expand All @@ -154,15 +160,18 @@ describe("Light Account Tests", () => {
const throwawayOwner = LocalAccountSigner.privateKeyToAccountSigner(
generatePrivateKey()
);
const provider = givenConnectedProvider({ owner: throwawayOwner, chain });
const throwawayProvider = givenConnectedProvider({
owner: throwawayOwner,
chain,
});

// fund the throwaway address
const fundThrowawayResult = await signer.sendUserOperation({
target: await provider.getAddress(),
const fundThrowawayResult = await provider.sendUserOperation({
target: await throwawayProvider.getAddress(),
data: "0x",
value: 10000000000000n,
});
const fundThrowawayTxnHash = signer.waitForUserOperationTransaction(
const fundThrowawayTxnHash = provider.waitForUserOperationTransaction(
fundThrowawayResult.hash
);
await expect(fundThrowawayTxnHash).resolves.not.toThrowError();
Expand All @@ -172,16 +181,16 @@ describe("Light Account Tests", () => {
generatePrivateKey()
);
const result = await LightSmartContractAccount.transferOwnership(
provider,
throwawayProvider,
newThrowawayOwner
);
const txnHash = provider.waitForUserOperationTransaction(result);
const txnHash = throwawayProvider.waitForUserOperationTransaction(result);
await expect(txnHash).resolves.not.toThrowError();

expect(await provider.account.getOwnerAddress()).not.toBe(
expect(await throwawayProvider.account.getOwnerAddress()).not.toBe(
await throwawayOwner.getAddress()
);
expect(await provider.account.getOwnerAddress()).toBe(
expect(await throwawayProvider.account.getOwnerAddress()).toBe(
await newThrowawayOwner.getAddress()
);
}, 100000);
Expand Down
Loading
Loading