@account-kit/plugingen 4.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/esm/IPlugin.d.ts +474 -0
- package/dist/esm/IPlugin.js +397 -0
- package/dist/esm/IPlugin.js.map +1 -0
- package/dist/esm/cli.d.ts +2 -0
- package/dist/esm/cli.js +40 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/commands/generate/index.d.ts +14 -0
- package/dist/esm/commands/generate/index.js +179 -0
- package/dist/esm/commands/generate/index.js.map +1 -0
- package/dist/esm/commands/generate/phases/contract-abi-gen.d.ts +2 -0
- package/dist/esm/commands/generate/phases/contract-abi-gen.js +9 -0
- package/dist/esm/commands/generate/phases/contract-abi-gen.js.map +1 -0
- package/dist/esm/commands/generate/phases/contract-addresses-gen.d.ts +2 -0
- package/dist/esm/commands/generate/phases/contract-addresses-gen.js +10 -0
- package/dist/esm/commands/generate/phases/contract-addresses-gen.js.map +1 -0
- package/dist/esm/commands/generate/phases/execution-abi-gen.d.ts +2 -0
- package/dist/esm/commands/generate/phases/execution-abi-gen.js +12 -0
- package/dist/esm/commands/generate/phases/execution-abi-gen.js.map +1 -0
- package/dist/esm/commands/generate/phases/plugin-actions/index.d.ts +2 -0
- package/dist/esm/commands/generate/phases/plugin-actions/index.js +118 -0
- package/dist/esm/commands/generate/phases/plugin-actions/index.js.map +1 -0
- package/dist/esm/commands/generate/phases/plugin-actions/management-actions.d.ts +2 -0
- package/dist/esm/commands/generate/phases/plugin-actions/management-actions.js +105 -0
- package/dist/esm/commands/generate/phases/plugin-actions/management-actions.js.map +1 -0
- package/dist/esm/commands/generate/phases/plugin-actions/read-actions.d.ts +2 -0
- package/dist/esm/commands/generate/phases/plugin-actions/read-actions.js +75 -0
- package/dist/esm/commands/generate/phases/plugin-actions/read-actions.js.map +1 -0
- package/dist/esm/commands/generate/phases/plugin-generator/get-contract-gen.d.ts +2 -0
- package/dist/esm/commands/generate/phases/plugin-generator/get-contract-gen.js +26 -0
- package/dist/esm/commands/generate/phases/plugin-generator/get-contract-gen.js.map +1 -0
- package/dist/esm/commands/generate/phases/plugin-generator/index.d.ts +2 -0
- package/dist/esm/commands/generate/phases/plugin-generator/index.js +20 -0
- package/dist/esm/commands/generate/phases/plugin-generator/index.js.map +1 -0
- package/dist/esm/commands/generate/phases/plugin-generator/meta-gen.d.ts +2 -0
- package/dist/esm/commands/generate/phases/plugin-generator/meta-gen.js +14 -0
- package/dist/esm/commands/generate/phases/plugin-generator/meta-gen.js.map +1 -0
- package/dist/esm/commands/generate/types.d.ts +16 -0
- package/dist/esm/commands/generate/types.js +2 -0
- package/dist/esm/commands/generate/types.js.map +1 -0
- package/dist/esm/commands/generate/utils.d.ts +4 -0
- package/dist/esm/commands/generate/utils.js +16 -0
- package/dist/esm/commands/generate/utils.js.map +1 -0
- package/dist/esm/commands/init.d.ts +5 -0
- package/dist/esm/commands/init.js +76 -0
- package/dist/esm/commands/init.js.map +1 -0
- package/dist/esm/config.d.ts +36 -0
- package/dist/esm/config.js +4 -0
- package/dist/esm/config.js.map +1 -0
- package/dist/esm/errors.d.ts +14 -0
- package/dist/esm/errors.js +37 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/exports/config.d.ts +1 -0
- package/dist/esm/exports/config.js +2 -0
- package/dist/esm/exports/config.js.map +1 -0
- package/dist/esm/exports/index.d.ts +4 -0
- package/dist/esm/exports/index.js +5 -0
- package/dist/esm/exports/index.js.map +1 -0
- package/dist/esm/exports/types.d.ts +1 -0
- package/dist/esm/exports/types.js +2 -0
- package/dist/esm/exports/types.js.map +1 -0
- package/dist/esm/logger.d.ts +6 -0
- package/dist/esm/logger.js +30 -0
- package/dist/esm/logger.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/types.d.ts +6 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils/findConfig.d.ts +6 -0
- package/dist/esm/utils/findConfig.js +21 -0
- package/dist/esm/utils/findConfig.js.map +1 -0
- package/dist/esm/utils/format.d.ts +1 -0
- package/dist/esm/utils/format.js +10 -0
- package/dist/esm/utils/format.js.map +1 -0
- package/dist/esm/utils/isUsingTypescript.d.ts +1 -0
- package/dist/esm/utils/isUsingTypescript.js +19 -0
- package/dist/esm/utils/isUsingTypescript.js.map +1 -0
- package/dist/esm/utils/loadEnv.d.ts +4 -0
- package/dist/esm/utils/loadEnv.js +59 -0
- package/dist/esm/utils/loadEnv.js.map +1 -0
- package/dist/esm/utils/resolveConfig.d.ts +7 -0
- package/dist/esm/utils/resolveConfig.js +12 -0
- package/dist/esm/utils/resolveConfig.js.map +1 -0
- package/dist/esm/version.d.ts +1 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/types/IPlugin.d.ts +475 -0
- package/dist/types/IPlugin.d.ts.map +1 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/commands/generate/index.d.ts +17 -0
- package/dist/types/commands/generate/index.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/contract-abi-gen.d.ts +3 -0
- package/dist/types/commands/generate/phases/contract-abi-gen.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/contract-addresses-gen.d.ts +3 -0
- package/dist/types/commands/generate/phases/contract-addresses-gen.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/execution-abi-gen.d.ts +3 -0
- package/dist/types/commands/generate/phases/execution-abi-gen.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/plugin-actions/index.d.ts +3 -0
- package/dist/types/commands/generate/phases/plugin-actions/index.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/plugin-actions/management-actions.d.ts +3 -0
- package/dist/types/commands/generate/phases/plugin-actions/management-actions.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/plugin-actions/read-actions.d.ts +3 -0
- package/dist/types/commands/generate/phases/plugin-actions/read-actions.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/plugin-generator/get-contract-gen.d.ts +3 -0
- package/dist/types/commands/generate/phases/plugin-generator/get-contract-gen.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/plugin-generator/index.d.ts +3 -0
- package/dist/types/commands/generate/phases/plugin-generator/index.d.ts.map +1 -0
- package/dist/types/commands/generate/phases/plugin-generator/meta-gen.d.ts +3 -0
- package/dist/types/commands/generate/phases/plugin-generator/meta-gen.d.ts.map +1 -0
- package/dist/types/commands/generate/types.d.ts +17 -0
- package/dist/types/commands/generate/types.d.ts.map +1 -0
- package/dist/types/commands/generate/utils.d.ts +5 -0
- package/dist/types/commands/generate/utils.d.ts.map +1 -0
- package/dist/types/commands/init.d.ts +8 -0
- package/dist/types/commands/init.d.ts.map +1 -0
- package/dist/types/config.d.ts +59 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/errors.d.ts +15 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/exports/config.d.ts +2 -0
- package/dist/types/exports/config.d.ts.map +1 -0
- package/dist/types/exports/index.d.ts +5 -0
- package/dist/types/exports/index.d.ts.map +1 -0
- package/dist/types/exports/types.d.ts +2 -0
- package/dist/types/exports/types.d.ts.map +1 -0
- package/dist/types/logger.d.ts +7 -0
- package/dist/types/logger.d.ts.map +1 -0
- package/dist/types/types.d.ts +7 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils/findConfig.d.ts +15 -0
- package/dist/types/utils/findConfig.d.ts.map +1 -0
- package/dist/types/utils/format.d.ts +2 -0
- package/dist/types/utils/format.d.ts.map +1 -0
- package/dist/types/utils/isUsingTypescript.d.ts +2 -0
- package/dist/types/utils/isUsingTypescript.d.ts.map +1 -0
- package/dist/types/utils/loadEnv.d.ts +5 -0
- package/dist/types/utils/loadEnv.d.ts.map +1 -0
- package/dist/types/utils/resolveConfig.d.ts +15 -0
- package/dist/types/utils/resolveConfig.d.ts.map +1 -0
- package/dist/types/version.d.ts +2 -0
- package/dist/types/version.d.ts.map +1 -0
- package/package.json +83 -0
- package/src/IPlugin.ts +396 -0
- package/src/cli.ts +44 -0
- package/src/commands/generate/index.ts +270 -0
- package/src/commands/generate/phases/contract-abi-gen.ts +12 -0
- package/src/commands/generate/phases/contract-addresses-gen.ts +18 -0
- package/src/commands/generate/phases/execution-abi-gen.ts +20 -0
- package/src/commands/generate/phases/plugin-actions/index.ts +151 -0
- package/src/commands/generate/phases/plugin-actions/management-actions.ts +141 -0
- package/src/commands/generate/phases/plugin-actions/read-actions.ts +97 -0
- package/src/commands/generate/phases/plugin-generator/get-contract-gen.ts +30 -0
- package/src/commands/generate/phases/plugin-generator/index.ts +27 -0
- package/src/commands/generate/phases/plugin-generator/meta-gen.ts +17 -0
- package/src/commands/generate/types.ts +18 -0
- package/src/commands/generate/utils.ts +26 -0
- package/src/commands/init.ts +93 -0
- package/src/config.ts +79 -0
- package/src/errors.ts +58 -0
- package/src/exports/config.ts +1 -0
- package/src/exports/index.ts +7 -0
- package/src/exports/types.ts +1 -0
- package/src/logger.ts +36 -0
- package/src/types.ts +11 -0
- package/src/utils/findConfig.ts +37 -0
- package/src/utils/format.ts +11 -0
- package/src/utils/isUsingTypescript.ts +22 -0
- package/src/utils/loadEnv.ts +91 -0
- package/src/utils/resolveConfig.ts +25 -0
- package/src/version.ts +3 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { asyncPipe } from "@aa-sdk/core";
|
|
2
|
+
import { kebabCase } from "change-case";
|
|
3
|
+
import dedent from "dedent";
|
|
4
|
+
import { default as fs } from "fs-extra";
|
|
5
|
+
import { basename, dirname, resolve } from "pathe";
|
|
6
|
+
import pc from "picocolors";
|
|
7
|
+
import { createPublicClient, getContract, http, } from "viem";
|
|
8
|
+
import z from "zod";
|
|
9
|
+
import { IPluginAbi } from "../../IPlugin.js";
|
|
10
|
+
import * as logger from "../../logger.js";
|
|
11
|
+
import { findConfig } from "../../utils/findConfig.js";
|
|
12
|
+
import { format } from "../../utils/format.js";
|
|
13
|
+
import { getIsUsingTypeScript } from "../../utils/isUsingTypescript.js";
|
|
14
|
+
import { resolveConfig } from "../../utils/resolveConfig.js";
|
|
15
|
+
import { ContractAbiGenPhase } from "./phases/contract-abi-gen.js";
|
|
16
|
+
import { ContractAddressesGenPhase } from "./phases/contract-addresses-gen.js";
|
|
17
|
+
import { ExecutionAbiGenPhase } from "./phases/execution-abi-gen.js";
|
|
18
|
+
import { PluginActionsGenPhase } from "./phases/plugin-actions/index.js";
|
|
19
|
+
import { PluginGeneratorPhase } from "./phases/plugin-generator/index.js";
|
|
20
|
+
const GenerateSchema = z.object({
|
|
21
|
+
config: z.string().optional(),
|
|
22
|
+
root: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
export async function generate(options = {}) {
|
|
25
|
+
try {
|
|
26
|
+
options = await GenerateSchema.parseAsync(options);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof z.ZodError)
|
|
30
|
+
throw error;
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
const configPath = await findConfig(options);
|
|
34
|
+
if (!configPath) {
|
|
35
|
+
if (options.config) {
|
|
36
|
+
throw new Error(`Config not found at ${pc.gray(options.config)}`);
|
|
37
|
+
}
|
|
38
|
+
throw new Error("Config not found");
|
|
39
|
+
}
|
|
40
|
+
const resolvedConfigs = await resolveConfig({ configPath });
|
|
41
|
+
const isTypeScript = await getIsUsingTypeScript();
|
|
42
|
+
if (!isTypeScript) {
|
|
43
|
+
throw new Error("Only typescript is supported at the moment.");
|
|
44
|
+
}
|
|
45
|
+
const outNames = new Set();
|
|
46
|
+
const isArrayConfig = Array.isArray(resolvedConfigs);
|
|
47
|
+
const configs = isArrayConfig ? resolvedConfigs : [resolvedConfigs];
|
|
48
|
+
for (const config of configs) {
|
|
49
|
+
if (isArrayConfig)
|
|
50
|
+
logger.log(`Using config ${pc.gray(basename(configPath))}`);
|
|
51
|
+
if (!config.outDir)
|
|
52
|
+
throw new Error("outDir is required.");
|
|
53
|
+
if (outNames.has(config.outDir))
|
|
54
|
+
throw new Error(`outDir "${config.outDir}" must be unique.`);
|
|
55
|
+
outNames.add(config.outDir);
|
|
56
|
+
const spinner = logger.spinner();
|
|
57
|
+
const pluginConfigs = config.plugins;
|
|
58
|
+
spinner.start("Resolving plugin contracts");
|
|
59
|
+
if (!pluginConfigs || !pluginConfigs.length) {
|
|
60
|
+
logger.warn("no plugins found in config");
|
|
61
|
+
spinner.fail();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const plugins = pluginConfigs.map((plugin) => {
|
|
65
|
+
const chain = plugin.chain ?? config.chain;
|
|
66
|
+
const transport = http(plugin.rpcUrl ?? config.rpcUrl);
|
|
67
|
+
const client = createPublicClient({
|
|
68
|
+
chain,
|
|
69
|
+
transport,
|
|
70
|
+
});
|
|
71
|
+
if (!(chain.id in plugin.addresses)) {
|
|
72
|
+
spinner.fail();
|
|
73
|
+
throw new Error(`contract address missing for the reference chain ${chain.id}`);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
contract: getContract({
|
|
77
|
+
address: plugin.addresses[chain.id],
|
|
78
|
+
abi: IPluginAbi,
|
|
79
|
+
client,
|
|
80
|
+
}),
|
|
81
|
+
pluginConfig: plugin,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
spinner.succeed();
|
|
85
|
+
await Promise.all(plugins.map((plugin) => generatePlugin({
|
|
86
|
+
pluginConfig: plugin.pluginConfig,
|
|
87
|
+
contract: plugin.contract,
|
|
88
|
+
config,
|
|
89
|
+
})));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const phases = [
|
|
93
|
+
ContractAddressesGenPhase,
|
|
94
|
+
PluginGeneratorPhase,
|
|
95
|
+
PluginActionsGenPhase,
|
|
96
|
+
ExecutionAbiGenPhase,
|
|
97
|
+
ContractAbiGenPhase,
|
|
98
|
+
];
|
|
99
|
+
const generatePlugin = async ({ pluginConfig, contract, config, }) => {
|
|
100
|
+
const spinner = logger.spinner();
|
|
101
|
+
spinner.start(`Generating plugin ${pc.gray(pluginConfig.name)}`);
|
|
102
|
+
const imports = new Map();
|
|
103
|
+
const addImport = (moduleName, member) => {
|
|
104
|
+
if (!imports.has(moduleName)) {
|
|
105
|
+
imports.set(moduleName, {
|
|
106
|
+
types: new Set(),
|
|
107
|
+
members: new Set(),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const module = imports.get(moduleName);
|
|
111
|
+
if (member.isType) {
|
|
112
|
+
module.types.add(member.name);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
module.members.add(member.name);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const content = [];
|
|
119
|
+
const types = new Map();
|
|
120
|
+
const addType = (typeName, typeDef, isPublic) => {
|
|
121
|
+
if (types.has(typeName)) {
|
|
122
|
+
throw new Error(`Type ${typeName} already exists`);
|
|
123
|
+
}
|
|
124
|
+
types.set(typeName, {
|
|
125
|
+
definition: typeDef.replace(";", ""),
|
|
126
|
+
isPublic: isPublic ?? false,
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
const result = await asyncPipe(...phases)({
|
|
130
|
+
addImport,
|
|
131
|
+
addType,
|
|
132
|
+
content,
|
|
133
|
+
config,
|
|
134
|
+
contract,
|
|
135
|
+
pluginConfig,
|
|
136
|
+
});
|
|
137
|
+
const finalContent = dedent `
|
|
138
|
+
${Array.from(types.entries())
|
|
139
|
+
.map(([name, type]) => `${type.isPublic ? "export" : ""} type ${name} = ${type.definition};`)
|
|
140
|
+
.join("\n\n")}
|
|
141
|
+
|
|
142
|
+
${result.content.join("\n\n")}
|
|
143
|
+
`;
|
|
144
|
+
const finalImports = Array.from(imports.entries())
|
|
145
|
+
.map(([moduleName, { members, types }]) => {
|
|
146
|
+
return dedent `
|
|
147
|
+
import { ${Array.from(members.values()).join(",")} ${members.size > 0 ? "," : ""} ${Array.from(types.values())
|
|
148
|
+
.map((x) => `type ${x}`)
|
|
149
|
+
.join(",")} } from "${moduleName}";
|
|
150
|
+
`;
|
|
151
|
+
})
|
|
152
|
+
.join("\n");
|
|
153
|
+
spinner.succeed();
|
|
154
|
+
await writePlugin({
|
|
155
|
+
config,
|
|
156
|
+
content: finalContent,
|
|
157
|
+
imports: finalImports,
|
|
158
|
+
pluginConfig,
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
const writePlugin = async ({ config, content, imports, pluginConfig, }) => {
|
|
162
|
+
const isTypeScript = await getIsUsingTypeScript();
|
|
163
|
+
const pluginRegEx = /[pP]lugin/g;
|
|
164
|
+
const pluginPath = `${config.outDir}/${kebabCase(pluginConfig.name.replaceAll(pluginRegEx, ""))}/plugin.${isTypeScript ? "ts" : "js"}`;
|
|
165
|
+
const code = dedent `
|
|
166
|
+
${imports}
|
|
167
|
+
|
|
168
|
+
${content}
|
|
169
|
+
`;
|
|
170
|
+
const spinner = logger.spinner();
|
|
171
|
+
spinner.start(`Writing plugin to ${pc.gray(pluginPath)}`);
|
|
172
|
+
const cwd = process.cwd();
|
|
173
|
+
const outPath = resolve(cwd, pluginPath);
|
|
174
|
+
await fs.ensureDir(dirname(outPath));
|
|
175
|
+
const formatted = await format(code);
|
|
176
|
+
await fs.writeFile(outPath, formatted);
|
|
177
|
+
spinner.succeed();
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/generate/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { asyncPipe } from \"@aa-sdk/core\";\nimport { kebabCase } from \"change-case\";\nimport dedent from \"dedent\";\nimport { default as fs } from \"fs-extra\";\nimport { basename, dirname, resolve } from \"pathe\";\nimport pc from \"picocolors\";\nimport {\n createPublicClient,\n getContract,\n http,\n type GetContractReturnType,\n type PublicClient,\n} from \"viem\";\nimport z from \"zod\";\nimport type { Config, PluginConfig } from \"../../config.js\";\nimport { IPluginAbi } from \"../../IPlugin.js\";\nimport * as logger from \"../../logger.js\";\nimport { findConfig } from \"../../utils/findConfig.js\";\nimport { format } from \"../../utils/format.js\";\nimport { getIsUsingTypeScript } from \"../../utils/isUsingTypescript.js\";\nimport { resolveConfig } from \"../../utils/resolveConfig.js\";\nimport { ContractAbiGenPhase } from \"./phases/contract-abi-gen.js\";\nimport { ContractAddressesGenPhase } from \"./phases/contract-addresses-gen.js\";\nimport { ExecutionAbiGenPhase } from \"./phases/execution-abi-gen.js\";\nimport { PluginActionsGenPhase } from \"./phases/plugin-actions/index.js\";\nimport { PluginGeneratorPhase } from \"./phases/plugin-generator/index.js\";\nimport type { Phase, PhaseInput } from \"./types.js\";\n\nconst GenerateSchema = z.object({\n /** Path to config file */\n config: z.string().optional(),\n /** Directory to search for config file */\n root: z.string().optional(),\n});\n\nexport type GenerateOptions = z.infer<typeof GenerateSchema>;\n\nexport async function generate(options: GenerateOptions = {}) {\n try {\n options = await GenerateSchema.parseAsync(options);\n } catch (error) {\n if (error instanceof z.ZodError) throw error;\n throw error;\n }\n\n // Get cli config file\n const configPath = await findConfig(options);\n if (!configPath) {\n if (options.config) {\n throw new Error(`Config not found at ${pc.gray(options.config)}`);\n }\n\n throw new Error(\"Config not found\");\n }\n\n const resolvedConfigs = await resolveConfig({ configPath });\n // TODO: need to use this in the phases below and add support for JS within the generated code\n // To support that we will likely need to:\n // 1. generate a types.ts file instead of appending the types to the top of the generated code\n // 2. in generated plugin.(ts|js) files we will either import the types or use the type reference comment\n // 3. in generated plugin files we need to check if TS when specifying the types of methods\n const isTypeScript = await getIsUsingTypeScript();\n if (!isTypeScript) {\n throw new Error(\"Only typescript is supported at the moment.\");\n }\n\n const outNames = new Set<string>();\n const isArrayConfig = Array.isArray(resolvedConfigs);\n const configs = isArrayConfig ? resolvedConfigs : [resolvedConfigs];\n\n for (const config of configs) {\n if (isArrayConfig)\n logger.log(`Using config ${pc.gray(basename(configPath))}`);\n\n // group configs by out dir\n if (!config.outDir) throw new Error(\"outDir is required.\");\n if (outNames.has(config.outDir))\n throw new Error(`outDir \"${config.outDir}\" must be unique.`);\n outNames.add(config.outDir);\n const spinner = logger.spinner();\n const pluginConfigs = config.plugins;\n\n // Get contracts from config\n spinner.start(\"Resolving plugin contracts\");\n if (!pluginConfigs || !pluginConfigs.length) {\n logger.warn(\"no plugins found in config\");\n spinner.fail();\n return;\n }\n\n // TODO: check that plugins are unique\n const plugins = pluginConfigs.map((plugin) => {\n const chain = plugin.chain ?? config.chain;\n const transport = http(plugin.rpcUrl ?? config.rpcUrl);\n\n const client = createPublicClient({\n chain,\n transport,\n });\n\n if (!(chain.id in plugin.addresses)) {\n spinner.fail();\n throw new Error(\n `contract address missing for the reference chain ${chain.id}`\n );\n }\n\n return {\n contract: getContract({\n address: plugin.addresses[chain.id],\n abi: IPluginAbi,\n client,\n }),\n pluginConfig: plugin,\n };\n });\n spinner.succeed();\n\n // Generate plugin files\n await Promise.all(\n plugins.map((plugin) =>\n generatePlugin({\n pluginConfig: plugin.pluginConfig,\n contract: plugin.contract,\n config,\n })\n )\n );\n }\n}\n\n// Add more phases here if needed\nconst phases: Phase[] = [\n ContractAddressesGenPhase,\n PluginGeneratorPhase,\n PluginActionsGenPhase,\n ExecutionAbiGenPhase,\n ContractAbiGenPhase,\n];\n\nconst generatePlugin = async ({\n pluginConfig,\n contract,\n config,\n}: {\n pluginConfig: PluginConfig;\n contract: GetContractReturnType<typeof IPluginAbi, PublicClient>;\n config: Config;\n}) => {\n const spinner = logger.spinner();\n spinner.start(`Generating plugin ${pc.gray(pluginConfig.name)}`);\n // Setup plugin generator\n const imports: Map<\n string,\n {\n types: Set<string>;\n members: Set<string>;\n }\n > = new Map();\n const addImport: PhaseInput[\"addImport\"] = (moduleName, member) => {\n if (!imports.has(moduleName)) {\n imports.set(moduleName, {\n types: new Set(),\n members: new Set(),\n });\n }\n\n const module = imports.get(moduleName)!;\n if (member.isType) {\n module.types.add(member.name);\n } else {\n module.members.add(member.name);\n }\n };\n const content: string[] = [];\n const types: Map<string, { definition: string; isPublic: boolean }> =\n new Map();\n const addType: PhaseInput[\"addType\"] = (typeName, typeDef, isPublic) => {\n if (types.has(typeName)) {\n throw new Error(`Type ${typeName} already exists`);\n }\n\n types.set(typeName, {\n definition: typeDef.replace(\";\", \"\"),\n isPublic: isPublic ?? false,\n });\n };\n\n // TODO: we need to handle the case where this isn't typescript because right now we generate types in here\n const result = await asyncPipe(...phases)({\n addImport,\n addType,\n content,\n config,\n contract,\n pluginConfig,\n });\n\n // Aggregate Result of phase\n const finalContent = dedent`\n ${Array.from(types.entries())\n .map(\n ([name, type]) =>\n `${type.isPublic ? \"export\" : \"\"} type ${name} = ${type.definition};`\n )\n .join(\"\\n\\n\")}\n\n ${result.content.join(\"\\n\\n\")}\n`;\n\n const finalImports = Array.from(imports.entries())\n .map(([moduleName, { members, types }]) => {\n return dedent`\n import { ${Array.from(members.values()).join(\",\")} ${\n members.size > 0 ? \",\" : \"\"\n } ${Array.from(types.values())\n .map((x) => `type ${x}`)\n .join(\",\")} } from \"${moduleName}\";\n `;\n })\n .join(\"\\n\");\n spinner.succeed();\n await writePlugin({\n config,\n content: finalContent,\n imports: finalImports,\n pluginConfig,\n });\n};\n\nconst writePlugin = async ({\n config,\n content,\n imports,\n pluginConfig,\n}: {\n pluginConfig: PluginConfig;\n config: Config;\n content: string;\n imports: string;\n}) => {\n const isTypeScript = await getIsUsingTypeScript();\n\n const pluginRegEx: RegExp = /[pP]lugin/g;\n // TODO: because we are now generating these ourselves, we have a lot more flexibility\n // We could:\n // 1. generate a types.ts file containing the type defs intead of merging them with content\n // 2. generate an extensions.ts file which doesn't get overwritten on each generation\n // 3. generate an index.ts file which correctly exports all of the types + exports the output of extensions.ts\n // so that it's easier to extend and import without conflicts\n const pluginPath = `${config.outDir}/${kebabCase(\n pluginConfig.name.replaceAll(pluginRegEx, \"\")\n )}/plugin.${isTypeScript ? \"ts\" : \"js\"}`;\n\n const code = dedent`\n ${imports}\n\n ${content}\n`;\n\n const spinner = logger.spinner();\n spinner.start(`Writing plugin to ${pc.gray(pluginPath)}`);\n // Format and write output\n const cwd = process.cwd();\n const outPath = resolve(cwd, pluginPath);\n await fs.ensureDir(dirname(outPath));\n const formatted = await format(code);\n await fs.writeFile(outPath, formatted);\n spinner.succeed();\n};\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import dedent from "dedent";
|
|
2
|
+
export const ContractAbiGenPhase = async (input) => {
|
|
3
|
+
const { content, pluginConfig } = input;
|
|
4
|
+
content.push(dedent `
|
|
5
|
+
export const ${pluginConfig.name}Abi = ${JSON.stringify(pluginConfig.abi)} as const;
|
|
6
|
+
`);
|
|
7
|
+
return input;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=contract-abi-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-abi-gen.js","sourceRoot":"","sources":["../../../../../src/commands/generate/phases/contract-abi-gen.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAG5B,MAAM,CAAC,MAAM,mBAAmB,GAAU,KAAK,EAAE,KAAK,EAAE,EAAE;IACxD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IACxC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAA;mBACF,YAAY,CAAC,IAAI,SAAS,IAAI,CAAC,SAAS,CACvD,YAAY,CAAC,GAAG,CACjB;GACA,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["import dedent from \"dedent\";\nimport type { Phase } from \"../types\";\n\nexport const ContractAbiGenPhase: Phase = async (input) => {\n const { content, pluginConfig } = input;\n content.push(dedent`\n export const ${pluginConfig.name}Abi = ${JSON.stringify(\n pluginConfig.abi\n )} as const;\n `);\n return input;\n};\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import dedent from "dedent";
|
|
2
|
+
export const ContractAddressesGenPhase = async (input) => {
|
|
3
|
+
const { pluginConfig, content, addImport } = input;
|
|
4
|
+
addImport("viem", { name: "Address", isType: true });
|
|
5
|
+
content.push(dedent `
|
|
6
|
+
const addresses = {${Object.entries(pluginConfig.addresses).reduce((prev, [chainId, addr]) => (prev += `${chainId}: "${addr}" as Address, `), "")}} as Record<number, Address>;
|
|
7
|
+
`);
|
|
8
|
+
return input;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=contract-addresses-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-addresses-gen.js","sourceRoot":"","sources":["../../../../../src/commands/generate/phases/contract-addresses-gen.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAI5B,MAAM,CAAC,MAAM,yBAAyB,GAAU,KAAK,EAAE,KAAK,EAAE,EAAE;IAC9D,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAEnD,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAA;yBACI,MAAM,CAAC,OAAO,CACjC,YAAY,CAAC,SAAoC,CAClD,CAAC,MAAM,CACN,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,GAAG,OAAO,MAAM,IAAI,gBAAgB,CAAC,EACzE,EAAE,CACH;GACF,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["import dedent from \"dedent\";\nimport type { Address } from \"viem\";\nimport type { Phase } from \"../types\";\n\nexport const ContractAddressesGenPhase: Phase = async (input) => {\n const { pluginConfig, content, addImport } = input;\n\n addImport(\"viem\", { name: \"Address\", isType: true });\n content.push(dedent`\n const addresses = {${Object.entries(\n pluginConfig.addresses as Record<number, Address>\n ).reduce(\n (prev, [chainId, addr]) => (prev += `${chainId}: \"${addr}\" as Address, `),\n \"\"\n )}} as Record<number, Address>;\n `);\n return input;\n};\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import dedent from "dedent";
|
|
2
|
+
import { executionAbiConst, extractExecutionAbi } from "../utils.js";
|
|
3
|
+
export const ExecutionAbiGenPhase = async (input) => {
|
|
4
|
+
const { contract, content, pluginConfig } = input;
|
|
5
|
+
const { executionFunctions } = await contract.read.pluginManifest();
|
|
6
|
+
const executionAbi = extractExecutionAbi(executionFunctions, pluginConfig.abi);
|
|
7
|
+
content.push(dedent `
|
|
8
|
+
export const ${executionAbiConst(pluginConfig.name)} = ${JSON.stringify(executionAbi)} as const;
|
|
9
|
+
`);
|
|
10
|
+
return input;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=execution-abi-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-abi-gen.js","sourceRoot":"","sources":["../../../../../src/commands/generate/phases/execution-abi-gen.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,CAAC,MAAM,oBAAoB,GAAU,KAAK,EAAE,KAAK,EAAE,EAAE;IACzD,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IAElD,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;IACpE,MAAM,YAAY,GAAG,mBAAmB,CACtC,kBAAkB,EAClB,YAAY,CAAC,GAAG,CACjB,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAA;mBACF,iBAAiB,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,CACvE,YAAY,CACb;GACA,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["import dedent from \"dedent\";\nimport type { Phase } from \"../types\";\nimport { executionAbiConst, extractExecutionAbi } from \"../utils.js\";\n\nexport const ExecutionAbiGenPhase: Phase = async (input) => {\n const { contract, content, pluginConfig } = input;\n\n const { executionFunctions } = await contract.read.pluginManifest();\n const executionAbi = extractExecutionAbi(\n executionFunctions,\n pluginConfig.abi\n );\n\n content.push(dedent`\n export const ${executionAbiConst(pluginConfig.name)} = ${JSON.stringify(\n executionAbi\n )} as const;\n `);\n return input;\n};\n"]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { asyncPipe } from "@aa-sdk/core";
|
|
2
|
+
import { camelCase } from "change-case";
|
|
3
|
+
import dedent from "dedent";
|
|
4
|
+
import { extractExecutionAbi } from "../../utils.js";
|
|
5
|
+
import { ManagementActionsGenPhase } from "./management-actions.js";
|
|
6
|
+
import { AccountReadActionsGenPhase } from "./read-actions.js";
|
|
7
|
+
export const PluginActionsGenPhase = async (input) => {
|
|
8
|
+
const { pluginConfig, contract, addImport, addType } = input;
|
|
9
|
+
const { executionFunctions } = await contract.read.pluginManifest();
|
|
10
|
+
const executionAbiConst = `${pluginConfig.name}ExecutionFunctionAbi`;
|
|
11
|
+
const executionAbi = extractExecutionAbi(executionFunctions, pluginConfig.abi);
|
|
12
|
+
addImport("viem", { name: "EncodeFunctionDataParameters", isType: true });
|
|
13
|
+
addImport("viem", { name: "Transport", isType: true });
|
|
14
|
+
addImport("viem", { name: "Chain", isType: true });
|
|
15
|
+
addImport("viem", { name: "Client", isType: true });
|
|
16
|
+
addImport("@aa-sdk/core", {
|
|
17
|
+
name: "SmartContractAccount",
|
|
18
|
+
isType: true,
|
|
19
|
+
});
|
|
20
|
+
addImport("@aa-sdk/core", {
|
|
21
|
+
name: "GetAccountParameter",
|
|
22
|
+
isType: true,
|
|
23
|
+
});
|
|
24
|
+
addImport("@aa-sdk/core", {
|
|
25
|
+
name: "SendUserOperationResult",
|
|
26
|
+
isType: true,
|
|
27
|
+
});
|
|
28
|
+
addImport("@aa-sdk/core", {
|
|
29
|
+
name: "GetEntryPointFromAccount",
|
|
30
|
+
isType: true,
|
|
31
|
+
});
|
|
32
|
+
addImport("@aa-sdk/core", {
|
|
33
|
+
name: "UserOperationOverridesParameter",
|
|
34
|
+
isType: true,
|
|
35
|
+
});
|
|
36
|
+
addImport("@aa-sdk/core", {
|
|
37
|
+
name: "UserOperationContext",
|
|
38
|
+
isType: true,
|
|
39
|
+
});
|
|
40
|
+
addImport("@aa-sdk/core", { name: "AccountNotFoundError" });
|
|
41
|
+
addImport("@aa-sdk/core", { name: "isSmartAccountClient" });
|
|
42
|
+
addImport("@aa-sdk/core", { name: "IncompatibleClientError" });
|
|
43
|
+
addImport("@aa-sdk/core", { name: "GetContextParameter", isType: true });
|
|
44
|
+
const providerFunctionDefs = [];
|
|
45
|
+
const providerFunctions = executionAbi
|
|
46
|
+
.filter((n) => n.stateMutability !== "view")
|
|
47
|
+
.map((n) => {
|
|
48
|
+
const argsParamString = n.inputs.length > 0
|
|
49
|
+
? dedent `{
|
|
50
|
+
args,
|
|
51
|
+
overrides,
|
|
52
|
+
context,
|
|
53
|
+
account = client.account
|
|
54
|
+
}`
|
|
55
|
+
: dedent `{
|
|
56
|
+
overrides,
|
|
57
|
+
context,
|
|
58
|
+
account = client.account
|
|
59
|
+
}`;
|
|
60
|
+
const argsEncodeString = n.inputs.length > 0 ? "args," : "";
|
|
61
|
+
providerFunctionDefs.push(dedent `
|
|
62
|
+
${camelCase(n.name)}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${n.name}">, "args"> & UserOperationOverridesParameter<TEntryPointVersion> &
|
|
63
|
+
GetAccountParameter<TAccount> & GetContextParameter<TContext>) =>
|
|
64
|
+
Promise<SendUserOperationResult<TEntryPointVersion>>
|
|
65
|
+
`);
|
|
66
|
+
const methodName = camelCase(n.name);
|
|
67
|
+
return dedent `
|
|
68
|
+
${methodName}(${argsParamString}) {
|
|
69
|
+
if (!account) {
|
|
70
|
+
throw new AccountNotFoundError();
|
|
71
|
+
}
|
|
72
|
+
if (!isSmartAccountClient(client)) {
|
|
73
|
+
throw new IncompatibleClientError("SmartAccountClient", "${methodName}", client);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const uo = encodeFunctionData({
|
|
77
|
+
abi: ${executionAbiConst},
|
|
78
|
+
functionName: "${n.name}",
|
|
79
|
+
${argsEncodeString}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return client.sendUserOperation({ uo, overrides, account, context });
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
});
|
|
86
|
+
addType(`ExecutionActions<
|
|
87
|
+
TAccount extends SmartContractAccount | undefined = SmartContractAccount | undefined,
|
|
88
|
+
TContext extends UserOperationContext | undefined = UserOperationContext | undefined,
|
|
89
|
+
TEntryPointVersion extends GetEntryPointFromAccount<TAccount> = GetEntryPointFromAccount<TAccount>
|
|
90
|
+
>`, dedent `{
|
|
91
|
+
${providerFunctionDefs.join(";\n\n")}
|
|
92
|
+
}`);
|
|
93
|
+
const { hasReadMethods } = await asyncPipe(ManagementActionsGenPhase, AccountReadActionsGenPhase)({
|
|
94
|
+
...input,
|
|
95
|
+
content: providerFunctions,
|
|
96
|
+
});
|
|
97
|
+
addType(`${pluginConfig.name}Actions<
|
|
98
|
+
TAccount extends SmartContractAccount | undefined =
|
|
99
|
+
| SmartContractAccount
|
|
100
|
+
| undefined,
|
|
101
|
+
TContext extends UserOperationContext | undefined = UserOperationContext | undefined>`, dedent `
|
|
102
|
+
ExecutionActions<TAccount, TContext> & ManagementActions<TAccount, TContext> & ReadAndEncodeActions${hasReadMethods ? "<TAccount>" : ""}
|
|
103
|
+
`, true);
|
|
104
|
+
input.content.push(dedent `
|
|
105
|
+
export const ${camelCase(pluginConfig.name)}Actions: <
|
|
106
|
+
TTransport extends Transport = Transport,
|
|
107
|
+
TChain extends Chain | undefined = Chain | undefined,
|
|
108
|
+
TAccount extends SmartContractAccount | undefined =
|
|
109
|
+
| SmartContractAccount
|
|
110
|
+
| undefined,
|
|
111
|
+
TContext extends UserOperationContext | undefined = UserOperationContext | undefined
|
|
112
|
+
>(
|
|
113
|
+
client: Client<TTransport, TChain, TAccount>
|
|
114
|
+
) => ${pluginConfig.name}Actions<TAccount, TContext> = (client) => ({ ${providerFunctions.join(",\n")} });
|
|
115
|
+
`);
|
|
116
|
+
return input;
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/commands/generate/phases/plugin-actions/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { asyncPipe } from \"@aa-sdk/core\";\nimport { camelCase } from \"change-case\";\nimport dedent from \"dedent\";\nimport type { Phase } from \"../../types\";\nimport { extractExecutionAbi } from \"../../utils.js\";\nimport { ManagementActionsGenPhase } from \"./management-actions.js\";\nimport { AccountReadActionsGenPhase } from \"./read-actions.js\";\n\nexport const PluginActionsGenPhase: Phase = async (input) => {\n const { pluginConfig, contract, addImport, addType } = input;\n const { executionFunctions } = await contract.read.pluginManifest();\n const executionAbiConst = `${pluginConfig.name}ExecutionFunctionAbi`;\n const executionAbi = extractExecutionAbi(\n executionFunctions,\n pluginConfig.abi\n );\n\n addImport(\"viem\", { name: \"EncodeFunctionDataParameters\", isType: true });\n addImport(\"viem\", { name: \"Transport\", isType: true });\n addImport(\"viem\", { name: \"Chain\", isType: true });\n addImport(\"viem\", { name: \"Client\", isType: true });\n addImport(\"@aa-sdk/core\", {\n name: \"SmartContractAccount\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"GetAccountParameter\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"SendUserOperationResult\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"GetEntryPointFromAccount\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"UserOperationOverridesParameter\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"UserOperationContext\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", { name: \"AccountNotFoundError\" });\n addImport(\"@aa-sdk/core\", { name: \"isSmartAccountClient\" });\n addImport(\"@aa-sdk/core\", { name: \"IncompatibleClientError\" });\n addImport(\"@aa-sdk/core\", { name: \"GetContextParameter\", isType: true });\n\n const providerFunctionDefs: string[] = [];\n const providerFunctions = executionAbi\n .filter((n) => n.stateMutability !== \"view\")\n .map((n) => {\n const argsParamString =\n n.inputs.length > 0\n ? dedent`{\n args,\n overrides,\n context,\n account = client.account\n }`\n : dedent`{\n overrides,\n context,\n account = client.account\n }`;\n const argsEncodeString = n.inputs.length > 0 ? \"args,\" : \"\";\n\n providerFunctionDefs.push(dedent`\n ${camelCase(\n n.name\n )}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, \"${\n n.name\n }\">, \"args\"> & UserOperationOverridesParameter<TEntryPointVersion> &\n GetAccountParameter<TAccount> & GetContextParameter<TContext>) =>\n Promise<SendUserOperationResult<TEntryPointVersion>>\n `);\n const methodName = camelCase(n.name);\n return dedent`\n ${methodName}(${argsParamString}) {\n if (!account) {\n throw new AccountNotFoundError();\n }\n if (!isSmartAccountClient(client)) {\n throw new IncompatibleClientError(\"SmartAccountClient\", \"${methodName}\", client);\n }\n\n const uo = encodeFunctionData({\n abi: ${executionAbiConst},\n functionName: \"${n.name}\",\n ${argsEncodeString}\n });\n\n return client.sendUserOperation({ uo, overrides, account, context });\n }\n `;\n });\n\n addType(\n `ExecutionActions<\n TAccount extends SmartContractAccount | undefined = SmartContractAccount | undefined,\n TContext extends UserOperationContext | undefined = UserOperationContext | undefined,\n TEntryPointVersion extends GetEntryPointFromAccount<TAccount> = GetEntryPointFromAccount<TAccount>\n >`,\n dedent`{\n ${providerFunctionDefs.join(\";\\n\\n\")}\n }`\n );\n\n const { hasReadMethods } = await asyncPipe(\n ManagementActionsGenPhase,\n AccountReadActionsGenPhase\n )({\n ...input,\n content: providerFunctions,\n });\n\n addType(\n `${pluginConfig.name}Actions<\n TAccount extends SmartContractAccount | undefined =\n | SmartContractAccount\n | undefined,\n TContext extends UserOperationContext | undefined = UserOperationContext | undefined>`,\n dedent`\n ExecutionActions<TAccount, TContext> & ManagementActions<TAccount, TContext> & ReadAndEncodeActions${\n hasReadMethods ? \"<TAccount>\" : \"\"\n }\n `,\n true\n );\n\n input.content.push(dedent`\n export const ${camelCase(pluginConfig.name)}Actions: <\n TTransport extends Transport = Transport,\n TChain extends Chain | undefined = Chain | undefined,\n TAccount extends SmartContractAccount | undefined =\n | SmartContractAccount\n | undefined,\n TContext extends UserOperationContext | undefined = UserOperationContext | undefined\n >(\n client: Client<TTransport, TChain, TAccount>\n ) => ${\n pluginConfig.name\n }Actions<TAccount, TContext> = (client) => ({ ${providerFunctions.join(\n \",\\n\"\n )} });\n `);\n\n return input;\n};\n"]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { kebabCase } from "change-case";
|
|
2
|
+
import dedent from "dedent";
|
|
3
|
+
export const ManagementActionsGenPhase = async (input) => {
|
|
4
|
+
const { addImport, pluginConfig, addType } = input;
|
|
5
|
+
if (pluginConfig.installConfig != null) {
|
|
6
|
+
addImports(addImport, pluginConfig.installConfig.dependencies?.map((x) => x.plugin) ?? []);
|
|
7
|
+
const initArgs = pluginConfig.installConfig.initAbiParams ?? [];
|
|
8
|
+
addType("InstallArgs", JSON.stringify(initArgs));
|
|
9
|
+
addType(`Install${pluginConfig.name}Params`, dedent `{
|
|
10
|
+
args: Parameters<typeof encodeAbiParameters<InstallArgs>>[1];
|
|
11
|
+
pluginAddress?: Address;
|
|
12
|
+
dependencyOverrides?: FunctionReference[];
|
|
13
|
+
}`, true);
|
|
14
|
+
addType(`ManagementActions<
|
|
15
|
+
TAccount extends SmartContractAccount | undefined = SmartContractAccount | undefined,
|
|
16
|
+
TContext extends UserOperationContext | undefined = Record<string,any> | undefined,
|
|
17
|
+
TEntryPointVersion extends GetEntryPointFromAccount<TAccount> = GetEntryPointFromAccount<TAccount>
|
|
18
|
+
>`, dedent `{
|
|
19
|
+
install${pluginConfig.name}: (args:
|
|
20
|
+
UserOperationOverridesParameter<TEntryPointVersion> &
|
|
21
|
+
Install${pluginConfig.name}Params & GetAccountParameter<TAccount> & GetContextParameter<TContext>) =>
|
|
22
|
+
Promise<SendUserOperationResult<TEntryPointVersion>>
|
|
23
|
+
}`);
|
|
24
|
+
const dependencies = (pluginConfig.installConfig.dependencies ?? []).map((x) => dedent `
|
|
25
|
+
(() => {
|
|
26
|
+
const pluginAddress = ${x.plugin.name}.meta.addresses[chain.id];
|
|
27
|
+
if (!pluginAddress) {
|
|
28
|
+
throw new Error("missing ${x.plugin.name} address for chain " + chain.name);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return encodePacked(
|
|
32
|
+
["address", "uint8"],
|
|
33
|
+
[pluginAddress, ${x.functionId}]
|
|
34
|
+
);
|
|
35
|
+
})()
|
|
36
|
+
`);
|
|
37
|
+
const installMethodName = `install${pluginConfig.name}`;
|
|
38
|
+
input.content.push(dedent `
|
|
39
|
+
${installMethodName}({account = client.account, overrides, context, ...params}) {
|
|
40
|
+
if (!account) {
|
|
41
|
+
throw new AccountNotFoundError();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!isSmartAccountClient(client)) {
|
|
45
|
+
throw new IncompatibleClientError("SmartAccountClient", "${installMethodName}", client);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const chain = client.chain;
|
|
49
|
+
if (!chain) {
|
|
50
|
+
throw new ChainNotFoundError();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const dependencies = params.dependencyOverrides ?? [${dependencies.join(",\n\n")}];
|
|
54
|
+
const pluginAddress = params.pluginAddress ?? ${pluginConfig.name}.meta.addresses[chain.id] as Address | undefined;
|
|
55
|
+
|
|
56
|
+
if (!pluginAddress) {
|
|
57
|
+
throw new Error("missing ${pluginConfig.name} address for chain " + chain.name);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return installPlugin_(client, {
|
|
61
|
+
pluginAddress,
|
|
62
|
+
pluginInitData: encodeAbiParameters(${JSON.stringify(initArgs)}, params.args),
|
|
63
|
+
dependencies,
|
|
64
|
+
overrides,
|
|
65
|
+
account,
|
|
66
|
+
context,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
`);
|
|
70
|
+
}
|
|
71
|
+
return input;
|
|
72
|
+
};
|
|
73
|
+
const addImports = (addImport, deps) => {
|
|
74
|
+
if (deps != null && deps.length > 0) {
|
|
75
|
+
addImport("viem", { name: "encodePacked" });
|
|
76
|
+
deps.forEach((x) => {
|
|
77
|
+
addImport(`../${kebabCase(x.name.replaceAll(/[pP]lugin/g, ""))}/plugin.js`, {
|
|
78
|
+
name: x.name,
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
addImport("@aa-sdk/core", { name: "ChainNotFoundError" });
|
|
83
|
+
addImport("viem", { name: "encodeAbiParameters" });
|
|
84
|
+
addImport("@account-kit/smart-contracts", {
|
|
85
|
+
name: "installPlugin as installPlugin_",
|
|
86
|
+
});
|
|
87
|
+
addImport("@aa-sdk/core", {
|
|
88
|
+
name: "GetAccountParameter",
|
|
89
|
+
isType: true,
|
|
90
|
+
});
|
|
91
|
+
addImport("@aa-sdk/core", {
|
|
92
|
+
name: "GetEntryPointFromAccount",
|
|
93
|
+
isType: true,
|
|
94
|
+
});
|
|
95
|
+
addImport("@aa-sdk/core", {
|
|
96
|
+
name: "UserOperationContext",
|
|
97
|
+
isType: true,
|
|
98
|
+
});
|
|
99
|
+
addImport("@account-kit/smart-contracts", {
|
|
100
|
+
name: "FunctionReference",
|
|
101
|
+
isType: true,
|
|
102
|
+
});
|
|
103
|
+
addImport("@aa-sdk/core", { name: "GetContextParameter", isType: true });
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=management-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"management-actions.js","sourceRoot":"","sources":["../../../../../../src/commands/generate/phases/plugin-actions/management-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { kebabCase } from \"change-case\";\nimport dedent from \"dedent\";\nimport type { PluginConfig } from \"../../../../config\";\nimport type { Phase, PhaseInput } from \"../../types\";\n\nexport const ManagementActionsGenPhase: Phase = async (input) => {\n const { addImport, pluginConfig, addType } = input;\n if (pluginConfig.installConfig != null) {\n addImports(\n addImport,\n pluginConfig.installConfig.dependencies?.map((x) => x.plugin) ?? []\n );\n\n const initArgs = pluginConfig.installConfig.initAbiParams ?? [];\n\n addType(\"InstallArgs\", JSON.stringify(initArgs));\n addType(\n `Install${pluginConfig.name}Params`,\n dedent`{\n args: Parameters<typeof encodeAbiParameters<InstallArgs>>[1];\n pluginAddress?: Address;\n dependencyOverrides?: FunctionReference[];\n }`,\n true\n );\n addType(\n `ManagementActions<\n TAccount extends SmartContractAccount | undefined = SmartContractAccount | undefined,\n TContext extends UserOperationContext | undefined = Record<string,any> | undefined,\n TEntryPointVersion extends GetEntryPointFromAccount<TAccount> = GetEntryPointFromAccount<TAccount>\n >`,\n dedent`{\n install${pluginConfig.name}: (args:\n UserOperationOverridesParameter<TEntryPointVersion> &\n Install${pluginConfig.name}Params & GetAccountParameter<TAccount> & GetContextParameter<TContext>) =>\n Promise<SendUserOperationResult<TEntryPointVersion>>\n }`\n );\n\n const dependencies = (pluginConfig.installConfig.dependencies ?? []).map(\n (x) => dedent`\n (() => {\n const pluginAddress = ${x.plugin.name}.meta.addresses[chain.id];\n if (!pluginAddress) {\n throw new Error(\"missing ${x.plugin.name} address for chain \" + chain.name);\n }\n\n return encodePacked(\n [\"address\", \"uint8\"],\n [pluginAddress, ${x.functionId}]\n );\n })()\n `\n );\n\n const installMethodName = `install${pluginConfig.name}`;\n\n input.content.push(dedent`\n ${installMethodName}({account = client.account, overrides, context, ...params}) {\n if (!account) {\n throw new AccountNotFoundError();\n }\n\n if (!isSmartAccountClient(client)) {\n throw new IncompatibleClientError(\"SmartAccountClient\", \"${installMethodName}\", client);\n }\n\n const chain = client.chain;\n if (!chain) {\n throw new ChainNotFoundError();\n }\n\n const dependencies = params.dependencyOverrides ?? [${dependencies.join(\n \",\\n\\n\"\n )}];\n const pluginAddress = params.pluginAddress ?? ${\n pluginConfig.name\n }.meta.addresses[chain.id] as Address | undefined;\n\n if (!pluginAddress) {\n throw new Error(\"missing ${\n pluginConfig.name\n } address for chain \" + chain.name);\n }\n\n return installPlugin_(client, {\n pluginAddress,\n pluginInitData: encodeAbiParameters(${JSON.stringify(\n initArgs\n )}, params.args),\n dependencies,\n overrides,\n account,\n context,\n });\n }\n `);\n }\n\n return input;\n};\n\nconst addImports = (\n addImport: PhaseInput[\"addImport\"],\n deps?: PluginConfig[]\n) => {\n if (deps != null && deps.length > 0) {\n addImport(\"viem\", { name: \"encodePacked\" });\n deps.forEach((x) => {\n addImport(\n `../${kebabCase(x.name.replaceAll(/[pP]lugin/g, \"\"))}/plugin.js`,\n {\n name: x.name,\n }\n );\n });\n }\n\n addImport(\"@aa-sdk/core\", { name: \"ChainNotFoundError\" });\n addImport(\"viem\", { name: \"encodeAbiParameters\" });\n addImport(\"@account-kit/smart-contracts\", {\n name: \"installPlugin as installPlugin_\",\n });\n addImport(\"@aa-sdk/core\", {\n name: \"GetAccountParameter\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"GetEntryPointFromAccount\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", {\n name: \"UserOperationContext\",\n isType: true,\n });\n addImport(\"@account-kit/smart-contracts\", {\n name: \"FunctionReference\",\n isType: true,\n });\n addImport(\"@aa-sdk/core\", { name: \"GetContextParameter\", isType: true });\n};\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { pascalCase } from "change-case";
|
|
2
|
+
import dedent from "dedent";
|
|
3
|
+
import { extractExecutionAbi } from "../../utils.js";
|
|
4
|
+
export const AccountReadActionsGenPhase = async (input) => {
|
|
5
|
+
const { pluginConfig, contract, addImport, addType } = input;
|
|
6
|
+
const { executionFunctions } = await contract.read.pluginManifest();
|
|
7
|
+
const executionAbiConst = `${pluginConfig.name}ExecutionFunctionAbi`;
|
|
8
|
+
const executionAbi = extractExecutionAbi(executionFunctions, pluginConfig.abi);
|
|
9
|
+
addImport("viem", { name: "EncodeFunctionDataParameters", isType: true });
|
|
10
|
+
addImport("viem", { name: "encodeFunctionData" });
|
|
11
|
+
addImport("viem", { name: "Hex", isType: true });
|
|
12
|
+
const accountFunctionActionDefs = [];
|
|
13
|
+
const accountFunctions = executionAbi.map((n) => {
|
|
14
|
+
const methodContent = [];
|
|
15
|
+
const argsParamString = n.inputs.length > 0 ? `{ args }` : "";
|
|
16
|
+
const argsEncodeString = n.inputs.length > 0 ? "args," : "";
|
|
17
|
+
const isViewFunction = n.stateMutability === "view";
|
|
18
|
+
const encodeMethodName = `encode${pascalCase(n.name)}`;
|
|
19
|
+
accountFunctionActionDefs.push(dedent `${encodeMethodName}: (args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${n.name}">, "args">) => Hex`);
|
|
20
|
+
methodContent.push(dedent `
|
|
21
|
+
${encodeMethodName}(${argsParamString}) {
|
|
22
|
+
return encodeFunctionData({
|
|
23
|
+
abi: ${executionAbiConst},
|
|
24
|
+
functionName: "${n.name}",
|
|
25
|
+
${argsEncodeString}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
`);
|
|
29
|
+
const readArgsParamString = n.inputs.length > 0
|
|
30
|
+
? `{ args, account = client.account }`
|
|
31
|
+
: "{ account = client.account }";
|
|
32
|
+
if (isViewFunction) {
|
|
33
|
+
addImport("viem", { name: "ReadContractReturnType", isType: true });
|
|
34
|
+
input.hasReadMethods = true;
|
|
35
|
+
const readMethodName = `read${pascalCase(n.name)}`;
|
|
36
|
+
accountFunctionActionDefs.push(n.inputs.length > 0
|
|
37
|
+
? dedent `${readMethodName}: (
|
|
38
|
+
args: Pick<EncodeFunctionDataParameters<typeof ${executionAbiConst}, "${n.name}">, "args"> &
|
|
39
|
+
GetAccountParameter<TAccount>
|
|
40
|
+
) => Promise<ReadContractReturnType<typeof ${executionAbiConst}, "${n.name}">>`
|
|
41
|
+
: dedent `${readMethodName}: (args: GetAccountParameter<TAccount>) =>
|
|
42
|
+
Promise<ReadContractReturnType<typeof ${executionAbiConst}, "${n.name}">>`);
|
|
43
|
+
methodContent.push(dedent `
|
|
44
|
+
async ${readMethodName} (${readArgsParamString}) {
|
|
45
|
+
if (!account) {
|
|
46
|
+
throw new AccountNotFoundError();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!isSmartAccountClient(client)) {
|
|
50
|
+
throw new IncompatibleClientError("SmartAccountClient", "${readMethodName}", client);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return client.readContract({
|
|
54
|
+
address: account.address,
|
|
55
|
+
abi: ${executionAbiConst},
|
|
56
|
+
functionName: "${n.name}",
|
|
57
|
+
${argsEncodeString}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
`);
|
|
61
|
+
}
|
|
62
|
+
return methodContent.join(",\n\n");
|
|
63
|
+
});
|
|
64
|
+
const typeName = input.hasReadMethods
|
|
65
|
+
? `ReadAndEncodeActions<
|
|
66
|
+
TAccount extends SmartContractAccount | undefined = SmartContractAccount | undefined,
|
|
67
|
+
>`
|
|
68
|
+
: "ReadAndEncodeActions";
|
|
69
|
+
addType(typeName, dedent `{
|
|
70
|
+
${accountFunctionActionDefs.join(";\n\n")}
|
|
71
|
+
}`);
|
|
72
|
+
input.content.push(...accountFunctions);
|
|
73
|
+
return input;
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=read-actions.js.map
|