@mimicprotocol/cli 0.0.1-rc.18 → 0.0.1-rc.19

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.
@@ -46,23 +46,20 @@ class Compile extends core_1.Command {
46
46
  async run() {
47
47
  const { flags } = await this.parse(Compile);
48
48
  const { task: taskFile, output: outputDir, manifest: manifestDir } = flags;
49
- console.log(`Compiling AssemblyScript from ${taskFile}`);
50
- if (!fs.existsSync(outputDir))
51
- fs.mkdirSync(outputDir, { recursive: true });
49
+ const absTaskFile = path.resolve(taskFile);
50
+ const absOutputDir = path.resolve(outputDir);
51
+ if (!fs.existsSync(absOutputDir))
52
+ fs.mkdirSync(absOutputDir, { recursive: true });
52
53
  log_1.default.startAction('Verifying Manifest');
53
54
  const manifest = ManifestHandler_1.default.load(this, manifestDir);
54
55
  log_1.default.startAction('Compiling');
55
- const wasmPath = path.join(outputDir, 'task.wasm');
56
- const watPath = path.join(outputDir, 'task.wat');
57
56
  const ascArgs = [
58
57
  'asc',
59
- taskFile,
58
+ absTaskFile,
60
59
  '--target',
61
60
  'release',
62
61
  '--outFile',
63
- wasmPath,
64
- '--textFile',
65
- watPath,
62
+ path.join(absOutputDir, 'task.wasm'),
66
63
  '--optimize',
67
64
  '--exportRuntime',
68
65
  '--transform',
@@ -38,19 +38,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const core_1 = require("@oclif/core");
40
40
  const axios_1 = __importStar(require("axios"));
41
+ const child_process_1 = require("child_process");
41
42
  const form_data_1 = __importDefault(require("form-data"));
42
43
  const fs = __importStar(require("fs"));
43
44
  const path_1 = require("path");
44
45
  const errors_1 = require("../errors");
45
46
  const log_1 = __importDefault(require("../log"));
46
- const MIMIC_REGISTRY = 'https://api-protocol.mimic.fi';
47
+ const MIMIC_REGISTRY_DEFAULT = 'https://api-protocol.mimic.fi';
47
48
  class Deploy extends core_1.Command {
48
49
  async run() {
49
50
  const { flags } = await this.parse(Deploy);
50
- const { key, input: inputDir, output: outputDir } = flags;
51
- log_1.default.startAction('Validating');
51
+ const { key, input: inputDir, output: outputDir, 'skip-compile': skipCompile, url: registryUrl } = flags;
52
52
  const fullInputDir = (0, path_1.resolve)(inputDir);
53
53
  const fullOutputDir = (0, path_1.resolve)(outputDir);
54
+ if (!skipCompile) {
55
+ const codegen = (0, child_process_1.spawnSync)('yarn', ['mimic', 'codegen'], { stdio: 'inherit' });
56
+ if (codegen.status !== 0)
57
+ this.error('Code generation failed', { code: 'CodegenError', suggestions: ['Fix manifest and ABI files'] });
58
+ const compile = (0, child_process_1.spawnSync)('yarn', ['mimic', 'compile', '--output', fullInputDir], { stdio: 'inherit' });
59
+ if (compile.status !== 0)
60
+ this.error('Compilation failed', { code: 'BuildError', suggestions: ['Check the task source code'] });
61
+ }
62
+ log_1.default.startAction('Validating');
54
63
  if (!fs.existsSync(fullInputDir))
55
64
  this.error(`Directory ${log_1.default.highlightText(fullInputDir)} does not exist`, {
56
65
  code: 'Directory Not Found',
@@ -65,7 +74,7 @@ class Deploy extends core_1.Command {
65
74
  });
66
75
  }
67
76
  log_1.default.startAction('Uploading to Mimic Registry');
68
- const CID = await this.uploadToRegistry(neededFiles, key);
77
+ const CID = await this.uploadToRegistry(neededFiles, key, registryUrl);
69
78
  console.log(`IPFS CID: ${log_1.default.highlightText(CID)}`);
70
79
  log_1.default.stopAction();
71
80
  if (!fs.existsSync(fullOutputDir))
@@ -74,10 +83,10 @@ class Deploy extends core_1.Command {
74
83
  console.log(`CID saved at ${log_1.default.highlightText(fullOutputDir)}`);
75
84
  console.log(`Task deployed!`);
76
85
  }
77
- async uploadToRegistry(files, key) {
86
+ async uploadToRegistry(files, key, registryUrl) {
78
87
  try {
79
88
  const form = filesToForm(files);
80
- const { data } = await axios_1.default.post(`${MIMIC_REGISTRY}/tasks`, form, {
89
+ const { data } = await axios_1.default.post(`${registryUrl}/tasks`, form, {
81
90
  headers: {
82
91
  'x-api-key': key,
83
92
  'Content-Type': `multipart/form-data; boundary=${form.getBoundary()}`,
@@ -110,6 +119,8 @@ Deploy.flags = {
110
119
  key: core_1.Flags.string({ char: 'k', description: 'Your account deployment key', required: true }),
111
120
  input: core_1.Flags.string({ char: 'i', description: 'Directory containing the compiled artifacts', default: './build' }),
112
121
  output: core_1.Flags.string({ char: 'o', description: 'Output directory for deployment CID', default: './build' }),
122
+ url: core_1.Flags.string({ char: 'u', description: `Mimic Registry base URL`, default: MIMIC_REGISTRY_DEFAULT }),
123
+ 'skip-compile': core_1.Flags.boolean({ description: 'Skip codegen and compile steps before uploading', default: false }),
113
124
  };
114
125
  exports.default = Deploy;
115
126
  const filesToForm = (files) => {
@@ -48,19 +48,20 @@ class Init extends core_1.Command {
48
48
  const { directory, force } = flags;
49
49
  const fullDirectory = path.resolve(directory);
50
50
  const templateDirectory = path.join(__dirname, '../templates');
51
- if (force) {
52
- const shouldDelete = await (0, prompts_1.confirm)({
53
- message: `Are you sure you want to ${log_1.default.warnText('delete')} all the contents in ${log_1.default.highlightText(fullDirectory)}. This action is ${log_1.default.warnText('irreversible')}`,
54
- default: false,
55
- });
51
+ if (force && fs.existsSync(fullDirectory) && fs.readdirSync(fullDirectory).length > 0) {
52
+ const shouldDelete = process.env.NODE_ENV === 'test'
53
+ ? true
54
+ : await (0, prompts_1.confirm)({
55
+ message: `Are you sure you want to ${log_1.default.warnText('delete')} all the contents in ${log_1.default.highlightText(fullDirectory)}. This action is ${log_1.default.warnText('irreversible')}`,
56
+ default: false,
57
+ });
56
58
  if (!shouldDelete) {
57
59
  console.log('You can remove the --force flag from your command');
58
60
  console.log('Stopping initialization...');
59
61
  this.exit(0);
60
62
  }
61
63
  log_1.default.startAction(`Deleting contents of ${fullDirectory}`);
62
- if (fs.existsSync(fullDirectory))
63
- fs.rmSync(fullDirectory, { recursive: true });
64
+ fs.rmSync(fullDirectory, { recursive: true });
64
65
  }
65
66
  log_1.default.startAction('Creating files');
66
67
  if (fs.existsSync(fullDirectory) && fs.readdirSync(fullDirectory).length > 0) {
@@ -5,37 +5,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const types_1 = require("../../types");
7
7
  const AbiTypeConverter_1 = __importDefault(require("./AbiTypeConverter"));
8
+ const EventHandler_1 = __importDefault(require("./EventHandler"));
8
9
  const FunctionHandler_1 = __importDefault(require("./FunctionHandler"));
9
10
  const ImportManager_1 = __importDefault(require("./ImportManager"));
10
11
  const NameManager_1 = __importDefault(require("./NameManager"));
11
12
  const TupleHandler_1 = __importDefault(require("./TupleHandler"));
13
+ const UtilsHandler_1 = __importDefault(require("./UtilsHandler"));
12
14
  class ContractClassGenerator {
13
15
  constructor(abi) {
14
16
  this.abi = abi;
15
17
  this.importManager = new ImportManager_1.default();
16
18
  this.tupleDefinitions = TupleHandler_1.default.extractTupleDefinitions(this.abi);
19
+ this.eventDefinitions = EventHandler_1.default.extractEventDefinitions(this.abi);
17
20
  this.abiTypeConverter = new AbiTypeConverter_1.default(this.importManager, this.tupleDefinitions);
18
21
  }
19
22
  generate(contractName) {
20
- const mainClassCode = this.generateMainClass(contractName);
23
+ const functions = NameManager_1.default.resolveMethodNames(this.getFunctions());
24
+ const mainClassCode = this.generateMainClass(contractName, functions);
25
+ const utilsClassCode = this.generateUtilsClass(contractName, functions);
21
26
  const tupleClassesCode = TupleHandler_1.default.generateTupleClassesCode(this.tupleDefinitions, this.importManager, this.abiTypeConverter);
27
+ const eventClassesCode = EventHandler_1.default.generateEventClassesCode(this.eventDefinitions, this.importManager, this.abiTypeConverter);
22
28
  // Note: this should be generated after any other generation
23
29
  const importsCode = this.importManager.generateImportsCode();
30
+ const ignoreLint = '/* eslint-disable @typescript-eslint/no-unused-vars */';
24
31
  const notice = '// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE MANUALLY.';
25
32
  const separator = '\n\n';
26
- let result = notice + separator + importsCode + separator + mainClassCode;
33
+ let result = ignoreLint + separator + notice + separator + importsCode;
34
+ result += separator + mainClassCode;
35
+ result += separator + utilsClassCode;
27
36
  if (tupleClassesCode)
28
37
  result += separator + tupleClassesCode;
38
+ if (eventClassesCode)
39
+ result += separator + eventClassesCode;
29
40
  return result.trim();
30
41
  }
31
- generateMainClass(contractName) {
42
+ generateMainClass(contractName, functions) {
32
43
  const lines = [];
33
44
  this.appendClassDefinition(lines, contractName);
34
- const functions = NameManager_1.default.resolveMethodNames(this.getFunctions());
35
- functions.forEach((fn) => FunctionHandler_1.default.appendMethod(lines, fn, this.importManager, this.tupleDefinitions, this.abiTypeConverter));
45
+ functions.forEach((fn) => FunctionHandler_1.default.appendMethod(lines, fn, this.importManager, this.tupleDefinitions, this.abiTypeConverter, contractName));
36
46
  lines.push('}');
37
47
  return lines.join('\n');
38
48
  }
49
+ generateUtilsClass(contractName, functions) {
50
+ return UtilsHandler_1.default.generate(contractName, functions, this.importManager, this.tupleDefinitions, this.abiTypeConverter);
51
+ }
39
52
  appendClassDefinition(lines, contractName) {
40
53
  this.importManager.addType(types_1.LibTypes.Address);
41
54
  this.importManager.addType(types_1.LibTypes.ChainId);
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const types_1 = require("../../types");
40
+ const NameManager_1 = __importStar(require("./NameManager"));
41
+ const TupleHandler_1 = __importDefault(require("./TupleHandler"));
42
+ class EventHandler {
43
+ static extractEventDefinitions(abi) {
44
+ const eventDefinitions = new Map();
45
+ abi.forEach((item) => {
46
+ if (item.type !== 'event')
47
+ return;
48
+ const components = NameManager_1.default.resolveParameterNames(item.inputs || [], NameManager_1.NameContext.CLASS_PROPERTY);
49
+ const componentsWithIndexed = components.map((comp, index) => ({
50
+ ...comp,
51
+ indexed: item.inputs?.[index]?.indexed || false,
52
+ }));
53
+ eventDefinitions.set(item.name, {
54
+ className: `${item.name}Event`,
55
+ components: componentsWithIndexed,
56
+ });
57
+ });
58
+ return eventDefinitions;
59
+ }
60
+ static generateEventClassesCode(eventDefinitions, importManager, abiTypeConverter) {
61
+ if (eventDefinitions.size === 0)
62
+ return '';
63
+ const lines = [];
64
+ eventDefinitions.forEach((def) => {
65
+ lines.push(`export class ${def.className} {`);
66
+ const components = def.components;
67
+ components.forEach((comp) => {
68
+ const fieldName = comp.escapedName;
69
+ const componentType = abiTypeConverter.mapAbiType(comp);
70
+ lines.push(` readonly ${fieldName}: ${componentType}`);
71
+ });
72
+ lines.push('');
73
+ const constructorParams = components
74
+ .map((comp) => `${comp.escapedName}: ${abiTypeConverter.mapAbiType(comp)}`)
75
+ .join(', ');
76
+ lines.push(` constructor(${constructorParams}) {`);
77
+ components.forEach((comp) => {
78
+ const fieldName = comp.escapedName;
79
+ lines.push(` this.${fieldName} = ${fieldName}`);
80
+ });
81
+ lines.push(` }`);
82
+ lines.push('');
83
+ const indexedParams = def.components.filter((c) => c.indexed);
84
+ const nonIndexedParams = def.components.filter((c) => !c.indexed);
85
+ importManager.addType('evm');
86
+ importManager.addType('EvmDecodeParam');
87
+ const topicsParam = indexedParams.length > 0 ? 'topics' : '_topics';
88
+ const dataParam = nonIndexedParams.length > 0 ? 'data' : '_data';
89
+ lines.push(` static decode(${topicsParam}: ${types_1.AssemblyPrimitiveTypes.string}[], ${dataParam}: ${types_1.AssemblyPrimitiveTypes.string}): ${def.className} {`);
90
+ const localVarMap = new Map();
91
+ // Decode indexed parameters from topics
92
+ if (indexedParams.length > 0) {
93
+ lines.push(` // Decode indexed parameters from topics`);
94
+ NameManager_1.default.resolveParameterNames(indexedParams, NameManager_1.NameContext.LOCAL_VARIABLE).forEach((param, index) => {
95
+ const varName = param.escapedName;
96
+ localVarMap.set(indexedParams[index].escapedName, varName);
97
+ const mappedType = abiTypeConverter.mapAbiType(param);
98
+ const rawValue = `evm.decode(new EvmDecodeParam('${param.type}', topics[${index + 1}]))`; // Skip topics[0] which is event signature
99
+ lines.push(` const ${varName}: ${mappedType} = ${abiTypeConverter.generateTypeConversion(mappedType, rawValue, false, false)}`);
100
+ });
101
+ }
102
+ // Decode non-indexed parameters from data
103
+ if (nonIndexedParams.length > 0) {
104
+ lines.push(` // Decode non-indexed parameters from data`);
105
+ const dataAbiType = nonIndexedParams.length === 1
106
+ ? nonIndexedParams[0].type
107
+ : TupleHandler_1.default.generateTupleTypeString('tuple', nonIndexedParams.map((c) => ({ type: c.type, components: c.components })));
108
+ lines.push(` const decodedData = evm.decode(new EvmDecodeParam('${dataAbiType}', data))`);
109
+ const nonIndexedWithVarNames = NameManager_1.default.resolveParameterNames(nonIndexedParams, NameManager_1.NameContext.LOCAL_VARIABLE);
110
+ if (nonIndexedParams.length === 1) {
111
+ const param = nonIndexedWithVarNames[0];
112
+ const varName = param.escapedName;
113
+ localVarMap.set(nonIndexedParams[0].escapedName, varName);
114
+ const mappedType = abiTypeConverter.mapAbiType(param);
115
+ lines.push(` const ${varName}: ${mappedType} = ${abiTypeConverter.generateTypeConversion(mappedType, 'decodedData', false, false)}`);
116
+ }
117
+ else {
118
+ importManager.addType('JSON');
119
+ lines.push(` const dataParts = JSON.parse<${types_1.AssemblyPrimitiveTypes.string}[]>(decodedData)`);
120
+ nonIndexedWithVarNames.forEach((param, index) => {
121
+ const varName = param.escapedName;
122
+ localVarMap.set(nonIndexedParams[index].escapedName, varName);
123
+ const mappedType = abiTypeConverter.mapAbiType(param);
124
+ const parseLogic = TupleHandler_1.default.buildFieldParseLogic(`dataParts[${index}]`, param, mappedType, abiTypeConverter, importManager);
125
+ lines.push(` const ${varName}: ${mappedType} = ${parseLogic}`);
126
+ });
127
+ }
128
+ }
129
+ const constructorArgs = def.components.map((c) => localVarMap.get(c.escapedName) || c.escapedName).join(', ');
130
+ lines.push(` return new ${def.className}(${constructorArgs})`);
131
+ lines.push(` }`);
132
+ lines.push(`}`);
133
+ lines.push('');
134
+ });
135
+ return lines.join('\n');
136
+ }
137
+ }
138
+ exports.default = EventHandler;
@@ -36,23 +36,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- const helpers_1 = require("../../helpers");
40
39
  const types_1 = require("../../types");
41
- const ArrayHandler_1 = __importDefault(require("./ArrayHandler"));
42
40
  const NameManager_1 = __importStar(require("./NameManager"));
43
41
  const TupleHandler_1 = __importDefault(require("./TupleHandler"));
44
42
  const types_2 = require("./types");
45
43
  class FunctionHandler {
46
- static appendMethod(lines, fn, importManager, tupleDefinitions, abiTypeConverter) {
47
- const inputs = NameManager_1.default.resolveParameterNames(fn.inputs || [], NameManager_1.NameContext.FUNCTION_PARAMETER, 'param');
48
- const methodParams = this.generateMethodParams(inputs, abiTypeConverter);
49
- const returnType = this.getReturnType(fn, tupleDefinitions, abiTypeConverter);
50
- const methodName = fn.escapedName || fn.name;
51
- lines.push(` ${methodName}(${methodParams}): ${returnType} {`);
52
- const callArgs = this.generateCallArguments(inputs, importManager, abiTypeConverter);
53
- this.appendFunctionBody(lines, fn, returnType, callArgs, importManager, abiTypeConverter);
54
- lines.push(` }`);
55
- lines.push('');
44
+ static appendMethod(lines, fn, importManager, tupleDefinitions, abiTypeConverter, contractName) {
45
+ if (this.isWriteFunction(fn)) {
46
+ this.appendWriteMethod(lines, fn, importManager, tupleDefinitions, abiTypeConverter, contractName);
47
+ return;
48
+ }
49
+ this.appendReadMethod(lines, fn, importManager, tupleDefinitions, abiTypeConverter, contractName);
50
+ }
51
+ static getCapitalizedName(fn) {
52
+ const baseName = fn.escapedName || fn.name;
53
+ return `${baseName.charAt(0).toUpperCase()}${baseName.slice(1)}`;
54
+ }
55
+ static isWriteFunction(fn) {
56
+ return ['nonpayable', 'payable'].includes(fn.stateMutability || '');
56
57
  }
57
58
  static getReturnType(fn, tupleDefinitions, abiTypeConverter) {
58
59
  if (this.isWriteFunction(fn))
@@ -83,91 +84,39 @@ class FunctionHandler {
83
84
  })
84
85
  .join(', ');
85
86
  }
86
- static buildEvmEncodeParamCode(valueIdentifier, paramDefinition, abiTypeConverter, importManager, depth = 0) {
87
- importManager.addType('EvmEncodeParam');
88
- const currentAbiTypeSignature = TupleHandler_1.default.isBaseTypeATuple(paramDefinition.type)
89
- ? TupleHandler_1.default.mapTupleType(paramDefinition.type)
90
- : paramDefinition.type;
91
- if (ArrayHandler_1.default.isArrayType(paramDefinition.type)) {
92
- const elementLambdaVar = `s${depth}`;
93
- const elementAbiDefinition = {
94
- name: elementLambdaVar,
95
- type: ArrayHandler_1.default.getArrayType(paramDefinition.type),
96
- components: TupleHandler_1.default.isBaseTypeATuple(ArrayHandler_1.default.getArrayType(paramDefinition.type))
97
- ? paramDefinition.components
98
- : undefined,
99
- internalType: paramDefinition.internalType
100
- ? ArrayHandler_1.default.getArrayType(paramDefinition.internalType)
101
- : undefined,
102
- };
103
- const nestedEvmParam = FunctionHandler.buildEvmEncodeParamCode(elementLambdaVar, elementAbiDefinition, abiTypeConverter, importManager, depth + 1);
104
- return `EvmEncodeParam.fromValues('${currentAbiTypeSignature}', ${valueIdentifier}.map<EvmEncodeParam>((${elementLambdaVar}) => ${nestedEvmParam}))`;
105
- }
106
- if (TupleHandler_1.default.isBaseTypeATuple(paramDefinition.type)) {
107
- return `EvmEncodeParam.fromValues('${currentAbiTypeSignature}', ${valueIdentifier}.toEvmEncodeParams())`;
108
- }
109
- const mappedParamType = abiTypeConverter.mapAbiType(paramDefinition);
110
- const convertedValue = abiTypeConverter.toLibType(mappedParamType, valueIdentifier);
111
- return `EvmEncodeParam.fromValue('${currentAbiTypeSignature}', ${convertedValue})`;
112
- }
113
- static generateCallArguments(inputs, importManager, abiTypeConverter) {
114
- return inputs
115
- .map((input) => {
116
- const paramName = input.escapedName;
117
- return FunctionHandler.buildEvmEncodeParamCode(paramName, input, abiTypeConverter, importManager, 0);
118
- })
119
- .join(', ');
120
- }
121
- static getDecodeAbiType(fn) {
122
- const outputs = fn.outputs ?? [];
123
- if (outputs.length === 0)
124
- return '()';
125
- if (outputs.length === 1) {
126
- const [output] = outputs;
127
- const { type, components } = output;
128
- if (TupleHandler_1.default.isBaseTypeATuple(type) && components)
129
- return TupleHandler_1.default.generateTupleTypeString(type, components);
130
- return type;
131
- }
132
- return TupleHandler_1.default.generateTupleTypeString(types_2.TUPLE_ABI_TYPE, outputs);
133
- }
134
- static getReturnExpression(currentType, dataAccessString, importManager, abiTypeConverter, depth = 0) {
135
- if (ArrayHandler_1.default.isArrayType(currentType)) {
136
- importManager.addType('JSON');
137
- const elementType = ArrayHandler_1.default.getArrayType(currentType);
138
- const itemVar = `item${depth}`;
139
- const subLogic = this.getReturnExpression(elementType, itemVar, importManager, abiTypeConverter, depth + 1);
140
- return `${dataAccessString} === '' ? [] : JSON.parse<${types_1.AssemblyPrimitiveTypes.string}[]>(${dataAccessString}).map<${elementType}>(((${itemVar}: ${types_1.AssemblyPrimitiveTypes.string}) => ${subLogic}))`;
141
- }
142
- return abiTypeConverter.generateTypeConversion(currentType, dataAccessString, false, false);
87
+ static appendWriteMethod(lines, fn, importManager, tupleDefinitions, abiTypeConverter, contractName) {
88
+ const inputs = NameManager_1.default.resolveParameterNames(fn.inputs || [], NameManager_1.NameContext.FUNCTION_PARAMETER, 'param');
89
+ const methodParams = this.generateMethodParams(inputs, abiTypeConverter);
90
+ const returnType = this.getReturnType(fn, tupleDefinitions, abiTypeConverter);
91
+ const methodName = fn.escapedName || fn.name;
92
+ const capitalizedName = this.getCapitalizedName(fn);
93
+ lines.push(` ${methodName}(${methodParams}): ${returnType} {`);
94
+ lines.push(` const encodedData = ${contractName}Utils.encode${capitalizedName}(${inputs.map((p) => p.escapedName).join(', ')})`);
95
+ importManager.addType(types_1.LibTypes.Bytes);
96
+ importManager.addType('CallBuilder');
97
+ lines.push(` return CallBuilder.forChain(this._chainId).addCall(this._address, encodedData)`);
98
+ lines.push(` }`);
99
+ lines.push('');
143
100
  }
144
- static appendFunctionBody(lines, fn, returnType, callArgs, importManager, abiTypeConverter) {
145
- const selector = (0, helpers_1.getFunctionSelector)(fn);
146
- if (callArgs)
147
- importManager.addType('evm');
148
- const encodedCall = `'${selector}'${callArgs ? ` + evm.encode([${callArgs}])` : ''}`;
149
- if (this.isWriteFunction(fn)) {
150
- importManager.addType(types_1.LibTypes.Bytes);
151
- importManager.addType('CallBuilder');
152
- lines.push(` const encodedData = Bytes.fromHexString(${encodedCall})`);
153
- lines.push(` return CallBuilder.forChain(this._chainId).addCall(this._address, encodedData)`);
154
- return;
155
- }
101
+ static appendReadMethod(lines, fn, importManager, tupleDefinitions, abiTypeConverter, contractName) {
102
+ const inputs = NameManager_1.default.resolveParameterNames(fn.inputs || [], NameManager_1.NameContext.FUNCTION_PARAMETER, 'param');
103
+ const methodParams = this.generateMethodParams(inputs, abiTypeConverter);
104
+ const returnType = this.getReturnType(fn, tupleDefinitions, abiTypeConverter);
105
+ const methodName = fn.escapedName || fn.name;
106
+ const capitalizedName = this.getCapitalizedName(fn);
107
+ lines.push(` ${methodName}(${methodParams}): ${returnType} {`);
108
+ lines.push(` const encodedData = ${contractName}Utils.encode${capitalizedName}(${inputs.map((p) => p.escapedName).join(', ')})`);
156
109
  importManager.addType('environment');
157
- const contractCallCode = `environment.contractCall(this._address, this._chainId, this._timestamp, ${encodedCall})`;
110
+ const contractCallLine = `environment.contractCall(this._address, this._chainId, this._timestamp, encodedData.toHexString())`;
158
111
  if (returnType === 'void') {
159
- lines.push(` ${contractCallCode}`);
160
- return;
112
+ lines.push(` ${contractCallLine}`);
161
113
  }
162
- importManager.addType('EvmDecodeParam');
163
- const decodeAbiType = this.getDecodeAbiType(fn);
164
- lines.push(` const response = ${contractCallCode}`);
165
- lines.push(` const decodedResponse = evm.decode(new EvmDecodeParam('${decodeAbiType}', response))`);
166
- const returnExpression = this.getReturnExpression(returnType, 'decodedResponse', importManager, abiTypeConverter);
167
- lines.push(` return ${returnExpression}`);
168
- }
169
- static isWriteFunction(fn) {
170
- return ['nonpayable', 'payable'].includes(fn.stateMutability || '');
114
+ else {
115
+ lines.push(` const response = ${contractCallLine}`);
116
+ lines.push(` return ${contractName}Utils.decode${capitalizedName}(response)`);
117
+ }
118
+ lines.push(` }`);
119
+ lines.push('');
171
120
  }
172
121
  }
173
122
  exports.default = FunctionHandler;
@@ -39,9 +39,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  const helpers_1 = require("../../helpers");
40
40
  const types_1 = require("../../types");
41
41
  const ArrayHandler_1 = __importDefault(require("./ArrayHandler"));
42
- const FunctionHandler_1 = __importDefault(require("./FunctionHandler"));
43
42
  const NameManager_1 = __importStar(require("./NameManager"));
44
43
  const types_2 = require("./types");
44
+ const UtilsHandler_1 = __importDefault(require("./UtilsHandler"));
45
45
  class TupleHandler {
46
46
  /**
47
47
  * Checks if the given ABI type string ultimately represents a tuple.
@@ -206,15 +206,6 @@ class TupleHandler {
206
206
  return 'UnnamedFunctionOutputs';
207
207
  return `${(0, helpers_1.pascalCase)(fnNamePart)}Outputs`;
208
208
  }
209
- static getTupleParseMethodBody(def, abiTypeConverter, importManager) {
210
- return def.components.map((comp, index) => {
211
- const fieldName = comp.escapedName;
212
- const mappedComponentType = abiTypeConverter.mapAbiType(comp);
213
- const dataAccess = `parts[${index}]`;
214
- const parseLogic = this.buildFieldParseLogic(dataAccess, comp, mappedComponentType, abiTypeConverter, importManager);
215
- return ` const ${fieldName}: ${mappedComponentType} = ${parseLogic};`;
216
- });
217
- }
218
209
  static buildFieldParseLogic(dataAccessString, componentAbiParam, mappedTargetType, abiTypeConverter, importManager, depth = 0) {
219
210
  importManager.addType('JSON');
220
211
  const isAbiArray = ArrayHandler_1.default.isArrayType(componentAbiParam.type);
@@ -236,11 +227,20 @@ class TupleHandler {
236
227
  }
237
228
  return abiTypeConverter.generateTypeConversion(mappedTargetType, dataAccessString, false, false);
238
229
  }
230
+ static getTupleParseMethodBody(def, abiTypeConverter, importManager) {
231
+ return def.components.map((comp, index) => {
232
+ const fieldName = comp.escapedName;
233
+ const mappedComponentType = abiTypeConverter.mapAbiType(comp);
234
+ const dataAccess = `parts[${index}]`;
235
+ const parseLogic = this.buildFieldParseLogic(dataAccess, comp, mappedComponentType, abiTypeConverter, importManager);
236
+ return ` const ${fieldName}: ${mappedComponentType} = ${parseLogic};`;
237
+ });
238
+ }
239
239
  static getTupleToEvmParamsMethodBody(def, abiTypeConverter, importManager) {
240
240
  return def.components.map((comp) => {
241
241
  const fieldName = comp.escapedName;
242
242
  const valueAccessPath = `this.${fieldName}`;
243
- const paramCode = FunctionHandler_1.default.buildEvmEncodeParamCode(valueAccessPath, comp, abiTypeConverter, importManager);
243
+ const paramCode = UtilsHandler_1.default.buildEvmEncodeParamCode(valueAccessPath, comp, abiTypeConverter, importManager);
244
244
  return ` ${paramCode},`;
245
245
  });
246
246
  }
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const helpers_1 = require("../../helpers");
40
+ const types_1 = require("../../types");
41
+ const ArrayHandler_1 = __importDefault(require("./ArrayHandler"));
42
+ const FunctionHandler_1 = __importDefault(require("./FunctionHandler"));
43
+ const NameManager_1 = __importStar(require("./NameManager"));
44
+ const TupleHandler_1 = __importDefault(require("./TupleHandler"));
45
+ const types_2 = require("./types");
46
+ class UtilsHandler {
47
+ static generate(contractName, functions, importManager, tupleDefinitions, abiTypeConverter) {
48
+ const methods = [];
49
+ functions.forEach((fn) => {
50
+ methods.push(this.generateEncodeMethod(fn, importManager, abiTypeConverter));
51
+ methods.push(this.generateDecodeMethod(fn, importManager, tupleDefinitions, abiTypeConverter));
52
+ });
53
+ const nonEmptyMethods = methods.filter((method) => method.trim() !== '');
54
+ return `export class ${contractName}Utils {\n${nonEmptyMethods.join('\n')}\n}`;
55
+ }
56
+ static buildEvmEncodeParamCode(valueIdentifier, paramDefinition, abiTypeConverter, importManager, depth = 0) {
57
+ importManager.addType('EvmEncodeParam');
58
+ const currentAbiTypeSignature = TupleHandler_1.default.isBaseTypeATuple(paramDefinition.type)
59
+ ? TupleHandler_1.default.mapTupleType(paramDefinition.type)
60
+ : paramDefinition.type;
61
+ if (ArrayHandler_1.default.isArrayType(paramDefinition.type)) {
62
+ const elementLambdaVar = `s${depth}`;
63
+ const elementAbiDefinition = {
64
+ name: elementLambdaVar,
65
+ type: ArrayHandler_1.default.getArrayType(paramDefinition.type),
66
+ components: TupleHandler_1.default.isBaseTypeATuple(ArrayHandler_1.default.getArrayType(paramDefinition.type))
67
+ ? paramDefinition.components
68
+ : undefined,
69
+ internalType: paramDefinition.internalType
70
+ ? ArrayHandler_1.default.getArrayType(paramDefinition.internalType)
71
+ : undefined,
72
+ };
73
+ const nestedEvmParam = UtilsHandler.buildEvmEncodeParamCode(elementLambdaVar, elementAbiDefinition, abiTypeConverter, importManager, depth + 1);
74
+ return `EvmEncodeParam.fromValues('${currentAbiTypeSignature}', ${valueIdentifier}.map<EvmEncodeParam>((${elementLambdaVar}) => ${nestedEvmParam}))`;
75
+ }
76
+ if (TupleHandler_1.default.isBaseTypeATuple(paramDefinition.type)) {
77
+ return `EvmEncodeParam.fromValues('${currentAbiTypeSignature}', ${valueIdentifier}.toEvmEncodeParams())`;
78
+ }
79
+ const mappedParamType = abiTypeConverter.mapAbiType(paramDefinition);
80
+ const convertedValue = abiTypeConverter.toLibType(mappedParamType, valueIdentifier);
81
+ return `EvmEncodeParam.fromValue('${currentAbiTypeSignature}', ${convertedValue})`;
82
+ }
83
+ static generateEncodeMethod(fn, importManager, abiTypeConverter) {
84
+ const inputs = NameManager_1.default.resolveParameterNames(fn.inputs || [], NameManager_1.NameContext.FUNCTION_PARAMETER, 'param');
85
+ const methodParams = FunctionHandler_1.default.generateMethodParams(inputs, abiTypeConverter);
86
+ const capitalizedName = FunctionHandler_1.default.getCapitalizedName(fn);
87
+ importManager.addType(types_1.LibTypes.Bytes);
88
+ const lines = [];
89
+ lines.push(` static encode${capitalizedName}(${methodParams}): Bytes {`);
90
+ const callArgs = this.generateCallArguments(inputs, importManager, abiTypeConverter);
91
+ const selector = (0, helpers_1.getFunctionSelector)(fn);
92
+ if (callArgs)
93
+ importManager.addType('evm');
94
+ const encodedCall = `'${selector}'${callArgs ? ` + evm.encode([${callArgs}])` : ''}`;
95
+ lines.push(` return Bytes.fromHexString(${encodedCall})`);
96
+ lines.push(` }`);
97
+ lines.push('');
98
+ return lines.join('\n');
99
+ }
100
+ static generateDecodeMethod(fn, importManager, tupleDefinitions, abiTypeConverter) {
101
+ const capitalizedName = FunctionHandler_1.default.getCapitalizedName(fn);
102
+ // Skip decode method for write functions or void returns
103
+ const returnType = FunctionHandler_1.default.getReturnType(fn, tupleDefinitions, abiTypeConverter);
104
+ if (FunctionHandler_1.default.isWriteFunction(fn) || returnType === 'void')
105
+ return '';
106
+ importManager.addType('EvmDecodeParam');
107
+ importManager.addType('evm');
108
+ const lines = [];
109
+ lines.push(` static decode${capitalizedName}(encodedResponse: string): ${returnType} {`);
110
+ const decodeAbiType = this.getDecodeAbiType(fn);
111
+ lines.push(` const decodedResponse = evm.decode(new EvmDecodeParam('${decodeAbiType}', encodedResponse))`);
112
+ const returnExpression = this.getReturnExpression(returnType, 'decodedResponse', importManager, abiTypeConverter);
113
+ lines.push(` return ${returnExpression}`);
114
+ lines.push(` }`);
115
+ lines.push('');
116
+ return lines.join('\n');
117
+ }
118
+ static generateCallArguments(inputs, importManager, abiTypeConverter) {
119
+ return inputs
120
+ .map((input) => {
121
+ const paramName = input.escapedName;
122
+ return UtilsHandler.buildEvmEncodeParamCode(paramName, input, abiTypeConverter, importManager, 0);
123
+ })
124
+ .join(', ');
125
+ }
126
+ static getDecodeAbiType(fn) {
127
+ const outputs = fn.outputs ?? [];
128
+ if (outputs.length === 0)
129
+ return '()';
130
+ if (outputs.length === 1) {
131
+ const [output] = outputs;
132
+ const { type, components } = output;
133
+ if (TupleHandler_1.default.isBaseTypeATuple(type) && components)
134
+ return TupleHandler_1.default.generateTupleTypeString(type, components);
135
+ return type;
136
+ }
137
+ return TupleHandler_1.default.generateTupleTypeString(types_2.TUPLE_ABI_TYPE, outputs);
138
+ }
139
+ static getReturnExpression(currentType, dataAccessString, importManager, abiTypeConverter, depth = 0) {
140
+ if (ArrayHandler_1.default.isArrayType(currentType)) {
141
+ importManager.addType('JSON');
142
+ const elementType = ArrayHandler_1.default.getArrayType(currentType);
143
+ const itemVar = `item${depth}`;
144
+ const subLogic = this.getReturnExpression(elementType, itemVar, importManager, abiTypeConverter, depth + 1);
145
+ return `${dataAccessString} === '' ? [] : JSON.parse<${types_1.AssemblyPrimitiveTypes.string}[]>(${dataAccessString}).map<${elementType}>(((${itemVar}: ${types_1.AssemblyPrimitiveTypes.string}) => ${subLogic}))`;
146
+ }
147
+ return abiTypeConverter.generateTypeConversion(currentType, dataAccessString, false, false);
148
+ }
149
+ }
150
+ exports.default = UtilsHandler;
@@ -6,4 +6,4 @@ inputs:
6
6
  - token: address
7
7
  - amount: uint256
8
8
  - recipient: address
9
- - fee: uint256
9
+ - maxFee: uint256
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mimicprotocol/cli",
3
- "version": "0.0.1-rc.18",
3
+ "version": "0.0.1-rc.19",
4
4
  "license": "GPL-3.0",
5
5
  "private": false,
6
6
  "type": "commonjs",