Skip to content

Commit

Permalink
Merge branch 'alchemyplatform:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
moldy530 authored Jan 31, 2024
2 parents 2cffee7 + be8c1ae commit f96d896
Show file tree
Hide file tree
Showing 234 changed files with 3,610 additions and 5,779 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
examples/**/*
site/.vitepress/cache/**/*
.nx/*
.github/*
.github/*
/.nx/cache
2 changes: 1 addition & 1 deletion .github/workflows/on-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- name: Build
env:
API_KEY: ${{ secrets.API_KEY }}
run: yarn build
run: yarn build:ci

- name: Unit Test
run: yarn test
5 changes: 1 addition & 4 deletions .github/workflows/publish-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,7 @@ jobs:
- name: Build
env:
API_KEY: ${{ secrets.API_KEY }}
run: yarn build

- name: Lint Write
run: yarn lint:write
run: yarn build:ci

- name: Build with VitePress
working-directory: site
Expand Down
2 changes: 0 additions & 2 deletions lerna.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true,
"version": "3.0.0-alpha.0",
"useNx": true,
"npmClient": "yarn",
"conventionalCommits": true,
"conventionalPrerelease": true,
Expand Down
22 changes: 11 additions & 11 deletions nx.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"tasksRunnerOptions": {
"default": {
"runner": "nx/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "test"]
}
}
},
"targetDefaults": {
"build": {
"dependsOn": ["^build", "generate"],
"outputs": ["{projectRoot}/dist"]
"outputs": ["{projectRoot}/dist"],
"cache": true
},
"test": {
"dependsOn": ["build"]
"dependsOn": ["build"],
"cache": true
},
"generate": {
"dependsOn": ["^build"],
"outputs": ["{projectRoot}/src/plugins"]
"outputs": ["{projectRoot}/src/plugins"],
"cache": true
}
},
"namedInputs": {
"default": ["{projectRoot}/**/*", "sharedGlobals"],
"sharedGlobals": [],
"production": ["default"]
}
}
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
"scripts": {
"generate": "lerna run generate",
"postgenerate": "yarn lint:write",
"build": "lerna run build --ignore=alchemy-daapp --ignore=aa-simple-dapp",
"build": "lerna run build --verbose --ignore=alchemy-daapp --ignore=aa-simple-dapp",
"build:ci": "yarn build && yarn lint:write",
"build:examples": "lerna run build",
"clean": "lerna run clean",
"test": "lerna run test:run",
"test:e2e": "lerna run test:run-e2e --concurrency=1 --ignore=@alchemy/aa-signers",
"test": "lerna run --verbose test:run",
"test:e2e": "lerna run --verbose test:run-e2e --concurrency=1 --ignore=@alchemy/aa-signers",
"lint:write": "eslint . --fix && prettier --write --ignore-unknown .",
"lint:check": "eslint . && prettier --check .",
"prepare": "husky install",
Expand All @@ -31,9 +32,10 @@
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-import": "^2.27.5",
"husky": "^8.0.0",
"lerna": "^6.6.1",
"lerna": "^8.0.2",
"lint-staged": "^13.2.2",
"node-fetch": "^3.3.1",
"nx": "^17.3.0",
"prettier": "^2.8.8",
"vitest": "^0.31.0"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/accounts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ If you are looking to add a new account type, please follow the following struct
export const MyContractAbi = [] as const; // the as const is important so we can get correct typing from viem
```

4. If you need to extend the [`SmartAccountProvider`](https://accountkit.alchemy.com/packages/aa-core/provider/introduction.html) class, add a file called `provider.ts` and add your implementation for `SmartAccountProvider`.
4. If you need to extend the [`SmartAccountProvider`](https://accountkit.alchemy.com/packages/aa-core/smart-account-client/introduction.html) class, add a file called `provider.ts` and add your implementation for `SmartAccountProvider`.

- Ideally, your `Account` impl should _just_ work with the base provider provided by `aa-core`.
- If not, consider generalizing the use case and updating SmartAccountProvider
Expand Down
29 changes: 13 additions & 16 deletions packages/accounts/plugingen/phases/plugin-actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const PluginActionsGenPhase: Phase = async (input) => {
addImport("viem", { name: "EncodeFunctionDataParameters", isType: true });
addImport("viem", { name: "Transport", isType: true });
addImport("viem", { name: "Chain", isType: true });
addImport("viem", { name: "Client", isType: true });
addImport("@alchemy/aa-core", {
name: "SmartContractAccount",
isType: true,
Expand All @@ -23,10 +24,6 @@ export const PluginActionsGenPhase: Phase = async (input) => {
name: "UserOperationOverrides",
isType: true,
});
addImport("@alchemy/aa-core", {
name: "SmartAccountClient",
isType: true,
});
addImport("@alchemy/aa-core", {
name: "GetAccountParameter",
isType: true,
Expand All @@ -36,6 +33,8 @@ export const PluginActionsGenPhase: Phase = async (input) => {
isType: true,
});
addImport("@alchemy/aa-core", { name: "AccountNotFoundError" });
addImport("@alchemy/aa-core", { name: "isSmartAccountClient" });
addImport("@alchemy/aa-core", { name: "IncompatibleClientError" });

const providerFunctionDefs: string[] = [];
const providerFunctions = executionAbi
Expand All @@ -58,11 +57,15 @@ export const PluginActionsGenPhase: Phase = async (input) => {
n.name
}">, "args"> & { overrides?: UserOperationOverrides; } & GetAccountParameter<TAccount>) => Promise<SendUserOperationResult>
`);
const methodName = camelCase(n.name);
return dedent`
${camelCase(n.name)}(${argsParamString}) {
${methodName}(${argsParamString}) {
if (!account) {
throw new AccountNotFoundError();
}
}
if (!isSmartAccountClient(client)) {
throw new IncompatibleClientError("SmartAccountClient", "${methodName}");
}
const uo = encodeFunctionData({
abi: ${executionAbiConst},
Expand Down Expand Up @@ -110,16 +113,10 @@ export const PluginActionsGenPhase: Phase = async (input) => {
| SmartContractAccount
| undefined
>(
client: SmartAccountClient<TTransport, TChain, TAccount>
) => ${contract.name}Actions<TAccount> = <
TTransport extends Transport = Transport,
TChain extends Chain | undefined = Chain | undefined,
TAccount extends SmartContractAccount | undefined =
| SmartContractAccount
| undefined
>(
client: SmartAccountClient<TTransport, TChain, TAccount>
) => ({ ${providerFunctions.join(",\n")} });
client: Client<TTransport, TChain, TAccount>
) => ${
contract.name
}Actions<TAccount> = (client) => ({ ${providerFunctions.join(",\n")} });
`);

return input;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,18 @@ export const ManagementActionsGenPhase: Phase = async (input) => {
`
);

const installMethodName = `install${contract.name}`;

input.content.push(dedent`
install${contract.name}({account = client.account, overrides, ...params}) {
${installMethodName}({account = client.account, overrides, ...params}) {
if (!account) {
throw new AccountNotFoundError();
}
if (!isSmartAccountClient(client)) {
throw new IncompatibleClientError("SmartAccountClient", "${installMethodName}");
}
const chain = client.chain;
if (!chain) {
throw new Error("Chain is required");
Expand Down
30 changes: 11 additions & 19 deletions packages/accounts/plugingen/phases/plugin-actions/read-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@ export const AccountReadActionsGenPhase: Phase = async (input) => {
const argsEncodeString = n.inputs.length > 0 ? "args," : "";
const isViewFunction = n.stateMutability === "view";

const encodeMethodName = `encode${pascalCase(n.name)}`;
accountFunctionActionDefs.push(
dedent`encode${pascalCase(
n.name
)}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${
n.name
}">, "args">) => Hex`
dedent`${encodeMethodName}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${n.name}">, "args">) => Hex`
);
methodContent.push(dedent`
encode${pascalCase(n.name)}(${argsParamString}) {
${encodeMethodName}(${argsParamString}) {
return encodeFunctionData({
abi: ${executionAbiConst},
functionName: "${n.name}",
Expand All @@ -45,28 +42,23 @@ export const AccountReadActionsGenPhase: Phase = async (input) => {
if (isViewFunction) {
addImport("viem", { name: "ReadContractReturnType", isType: true });
input.hasReadMethods = true;
const readMethodName = `read${pascalCase(n.name)}`;
accountFunctionActionDefs.push(
n.inputs.length > 0
? dedent`read${pascalCase(
n.name
)}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${
n.name
}">, "args"> & GetAccountParameter<TAccount>) => Promise<ReadContractReturnType<typeof ${executionAbiConst}, "${
n.name
}">>`
: dedent`read${pascalCase(
n.name
)}: (args: GetAccountParameter<TAccount>) => Promise<ReadContractReturnType<typeof ${executionAbiConst}, "${
n.name
}">>`
? dedent`${readMethodName}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${n.name}">, "args"> & GetAccountParameter<TAccount>) => Promise<ReadContractReturnType<typeof ${executionAbiConst}, "${n.name}">>`
: dedent`${readMethodName}: (args: GetAccountParameter<TAccount>) => Promise<ReadContractReturnType<typeof ${executionAbiConst}, "${n.name}">>`
);

methodContent.push(dedent`
async read${pascalCase(n.name)} (${readArgsParamString}) {
async ${readMethodName} (${readArgsParamString}) {
if (!account) {
throw new AccountNotFoundError();
}
if (!isSmartAccountClient(client)) {
throw new IncompatibleClientError("SmartAccountClient", "${readMethodName}");
}
return client.readContract({
address: account.address,
abi: ${executionAbiConst},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@ import type { Phase } from "../../types";
export const GetContractGenPhase: Phase = async (input) => {
const { content, contract, addImport } = input;

addImport("@alchemy/aa-core", {
name: "SmartAccountClient",
isType: true,
});
addImport("viem", { name: "getContract", isType: false });
addImport("viem", { name: "GetContractReturnType", isType: true });
addImport("viem", { name: "Address", isType: true });
Expand Down
1 change: 1 addition & 0 deletions packages/accounts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
export type * from "./light-account/account.js";
export { createLightAccount } from "./light-account/account.js";
export { transferOwnership as transferLightAccountOwnership } from "./light-account/actions/transferOwnership.js";
export { createLightAccountClient } from "./light-account/createLightAccountClient.js";
export { getLightAccountVersion } from "./light-account/getLightAccountVersion.js";
export type * from "./light-account/lightAccountClientDecorator.js";
export { lightAccountClientActions } from "./light-account/lightAccountClientDecorator.js";
Expand Down
25 changes: 10 additions & 15 deletions packages/accounts/src/light-account/account.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import {
LocalAccountSigner,
createPublicErc4337FromClient,
polygonMumbai,
type BatchUserOperationCallData,
type SmartAccountSigner,
} from "@alchemy/aa-core";
import { createPublicClient, custom, type Chain } from "viem";
import { custom, type Chain } from "viem";
import { createLightAccountClient } from "./createLightAccountClient.js";

const chain = polygonMumbai;
Expand Down Expand Up @@ -89,17 +88,13 @@ const givenConnectedProvider = ({
owner,
accountAddress: "0xb856DBD4fA1A79a46D426f537455e7d3E79ab7c4",
},
client: createPublicErc4337FromClient(
createPublicClient({
transport: custom({
request: async ({ method }) => {
if (method === "eth_getStorageAt") {
return "0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba"; // v1.1.0 address
}
return;
},
}),
chain,
})
),
transport: custom({
request: async ({ method }) => {
if (method === "eth_getStorageAt") {
return "0xae8c656ad28F2B59a196AB61815C16A0AE1c3cba"; // v1.1.0 address
}
return;
},
}),
chain,
});
24 changes: 17 additions & 7 deletions packages/accounts/src/light-account/account.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {
createBundlerClient,
getAccountAddress,
getDefaultEntryPointAddress,
toSmartContractAccount,
type Address,
type Hex,
type OwnedSmartContractAccount,
type PublicErc4337Client,
type SmartAccountSigner,
type ToSmartContractAccountParams,
type UpgradeToAndCallParams,
} from "@alchemy/aa-core";
import {
Expand Down Expand Up @@ -43,8 +44,10 @@ export type LightAccount<
export type CreateLightAccountParams<
TTransport extends Transport = Transport,
TOwner extends SmartAccountSigner = SmartAccountSigner
> = {
client: PublicErc4337Client<TTransport>;
> = Pick<
ToSmartContractAccountParams<"LightAccount", TTransport>,
"transport" | "chain"
> & {
owner: TOwner;
index?: bigint;
factoryAddress?: Address;
Expand All @@ -62,16 +65,22 @@ export async function createLightAccount<
): Promise<LightAccount<TOwner>>;

export async function createLightAccount({
client,
transport,
chain,
owner: owner_,
accountAddress,
initCode,
version = "v1.1.0",
entrypointAddress = getDefaultEntryPointAddress(client.chain),
factoryAddress = getDefaultLightAccountFactoryAddress(client.chain, version),
entrypointAddress = getDefaultEntryPointAddress(chain),
factoryAddress = getDefaultLightAccountFactoryAddress(chain, version),
index: index_ = 0n,
}: CreateLightAccountParams): Promise<LightAccount> {
let owner = owner_;
const client = createBundlerClient({
transport,
chain,
});

const getAccountInitCode = async () => {
if (initCode) return initCode;

Expand Down Expand Up @@ -154,7 +163,8 @@ export async function createLightAccount({
};

const account = await toSmartContractAccount({
client,
transport,
chain,
entrypointAddress,
accountAddress: address,
source: "LightAccount",
Expand Down
Loading

0 comments on commit f96d896

Please sign in to comment.