Skip to content

Commit

Permalink
feat: plugingen to generate plugin contract abi and get contract help…
Browse files Browse the repository at this point in the history
…er method
  • Loading branch information
denniswon committed Jan 16, 2024
1 parent f48afff commit db3e488
Show file tree
Hide file tree
Showing 13 changed files with 1,988 additions and 35 deletions.
9 changes: 8 additions & 1 deletion packages/accounts/plugingen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ import dedent from "dedent";
import { createPublicClient, getContract, http, type Chain } from "viem";
import type { PluginGenConfig } from "../plugindefs/types.js";
import { IPluginAbi } from "../src/msca/abis/IPlugin.js";
import { ContractAbiGenPhase } from "./phases/contract-abi-gen.js";
import { ContractAddressesGenPhase } from "./phases/contract-addresses-gen.js";
import { ExecutionAbiGenPhase } from "./phases/execution-abi-gen.js";
import { PluginGeneratorPhase } from "./phases/plugin-generator/index.js";
import type { Phase, PhaseInput } from "./types.js";

// Add more phases here if needed
const phases: Phase[] = [PluginGeneratorPhase, ExecutionAbiGenPhase];
const phases: Phase[] = [
ContractAddressesGenPhase,
PluginGeneratorPhase,
ExecutionAbiGenPhase,
ContractAbiGenPhase,
];

export function plugingen({
chain,
Expand Down
10 changes: 10 additions & 0 deletions packages/accounts/plugingen/phases/contract-abi-gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import dedent from "dedent";
import type { Phase } from "../types";

export const ContractAbiGenPhase: Phase = async (input) => {
const { contract, content } = input;
content.push(dedent`
export const ${contract.name}Abi = ${JSON.stringify(contract.abi)} as const;
`);
return input;
};
18 changes: 18 additions & 0 deletions packages/accounts/plugingen/phases/contract-addresses-gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import dedent from "dedent";
import type { Address } from "viem";
import type { Phase } from "../types";

export const ContractAddressesGenPhase: Phase = async (input) => {
const { contract, content, addImport } = input;

addImport("viem", { name: "Address", isType: true });
content.push(dedent`
const addresses = {${Object.entries(
contract.address as Record<number, Address>
).reduce(
(prev, [chainId, addr]) => (prev += `${chainId}: "${addr}" as Address, `),
""
)}} as Record<number, Address>;
`);
return input;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import dedent from "dedent";
import type { Phase } from "../../types";

export const GetContractGenPhase: Phase = async (input) => {
const { content, contract, addImport } = input;

addImport("viem", { name: "getContract", isType: false });
addImport("viem", { name: "GetContractReturnType", isType: true });
addImport("viem", { name: "Address", isType: true });
content.push(dedent`
getContract: (provider: ISmartAccountProvider): GetContractReturnType<typeof ${contract.name}Abi, typeof provider.rpcClient, undefined, Address> =>
getContract({
address: addresses[provider.rpcClient.chain.id],
abi: ${contract.name}Abi,
publicClient: provider.rpcClient,
})
`);

return input;
};
6 changes: 4 additions & 2 deletions packages/accounts/plugingen/phases/plugin-generator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { asyncPipe } from "@alchemy/aa-core";
import dedent from "dedent";
import type { Phase } from "../../types";
import { AccountMethodGenPhase } from "./account-method-gen.js";
import { GetContractGenPhase } from "./get-contract-gen.js";
import { MetaGenPhase } from "./meta-gen.js";
import { ProviderMethodGenPhase } from "./provider-method-gen/index.js";

export const PluginGeneratorPhase: Phase = async (input) => {
const pluginPhases: Phase[] = [
MetaGenPhase,
GetContractGenPhase,
AccountMethodGenPhase,
ProviderMethodGenPhase,
];
Expand All @@ -22,13 +24,13 @@ export const PluginGeneratorPhase: Phase = async (input) => {
input.content.push(dedent`
const ${contract.name}_ = {
${result.content.join(",\n")}
};
};
export const ${contract.name}: Plugin<ReturnType<typeof ${
contract.name
}_["accountMethods"]>, ReturnType<typeof ${
contract.name
}_["providerMethods"]>> = ${contract.name}_;
}_["providerMethods"]>, typeof ${contract.name}Abi> = ${contract.name}_;
`);

return input;
Expand Down
12 changes: 2 additions & 10 deletions packages/accounts/plugingen/phases/plugin-generator/meta-gen.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import dedent from "dedent";
import type { Address } from "viem";
import type { Phase } from "../../types";

export const MetaGenPhase: Phase = async (input) => {
const { plugin, content, contract, addImport } = input;
const { plugin, content } = input;
const { name, version } = await plugin.read.pluginMetadata();

addImport("viem", { name: "Address", isType: true });
content.push(dedent`
meta: {
name: "${name}",
version: "${version}",
addresses: {${Object.entries(
contract.address as Record<number, Address>
).reduce(
(prev, [chainId, addr]) =>
(prev += `${chainId}: "${addr}" as Address, `),
""
)}} as Record<number, Address>,
addresses,
}
`);

Expand Down
3 changes: 3 additions & 0 deletions packages/accounts/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,16 @@ export { type Plugin } from "./msca/plugins/types.js";

export {
MultiOwnerPlugin,
MultiOwnerPluginAbi,
MultiOwnerPluginExecutionFunctionAbi,
} from "./msca/plugins/multi-owner/plugin.js";
export {
SessionKeyPlugin,
SessionKeyPluginAbi,
SessionKeyPluginExecutionFunctionAbi,
} from "./msca/plugins/session-key/plugin.js";
export {
TokenReceiverPlugin,
TokenReceiverPluginAbi,
TokenReceiverPluginExecutionFunctionAbi,
} from "./msca/plugins/token-receiver/plugin.js";
6 changes: 3 additions & 3 deletions packages/accounts/src/msca/builder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type SignTypedDataParams,
type SupportedTransports,
} from "@alchemy/aa-core";
import { type Transport } from "viem";
import { type Abi, type Transport } from "viem";
import { z } from "zod";
import { pluginManagerDecorator } from "../plugin-manager/decorator.js";
import type { Plugin } from "../plugins/types";
Expand Down Expand Up @@ -105,8 +105,8 @@ export class MSCABuilder {
return factory(this);
}

extendWithPluginMethods = <AD, PD>(
plugin: Plugin<AD, PD>
extendWithPluginMethods = <AD, PD, TAbi extends Abi>(
plugin: Plugin<AD, PD, TAbi>
): DynamicMSCA<TProviderDecorators & PD> & AD => {
const methods = plugin.accountMethods(this);
const result = Object.assign(this, methods) as unknown as DynamicMSCA<
Expand Down
Loading

0 comments on commit db3e488

Please sign in to comment.