@mimicprotocol/cli 0.0.1-rc.9
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/README.md +96 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +6 -0
- package/dist/commands/codegen.js +100 -0
- package/dist/commands/compile.js +91 -0
- package/dist/commands/deploy.js +122 -0
- package/dist/commands/init.js +102 -0
- package/dist/commands/test.js +63 -0
- package/dist/errors.js +32 -0
- package/dist/helpers.js +17 -0
- package/dist/index.js +2 -0
- package/dist/lib/AbisInterfaceGenerator/AbiTypeConverter.js +137 -0
- package/dist/lib/AbisInterfaceGenerator/ArrayHandler.js +67 -0
- package/dist/lib/AbisInterfaceGenerator/ContractClassGenerator.js +57 -0
- package/dist/lib/AbisInterfaceGenerator/FunctionHandler.js +173 -0
- package/dist/lib/AbisInterfaceGenerator/ImportManager.js +17 -0
- package/dist/lib/AbisInterfaceGenerator/NameManager.js +98 -0
- package/dist/lib/AbisInterfaceGenerator/TupleHandler.js +250 -0
- package/dist/lib/AbisInterfaceGenerator/index.js +11 -0
- package/dist/lib/AbisInterfaceGenerator/types.js +4 -0
- package/dist/lib/InputsInterfaceGenerator.js +88 -0
- package/dist/lib/ManifestHandler.js +134 -0
- package/dist/lib/index.js +12 -0
- package/dist/log.js +13 -0
- package/dist/templates/manifest.yaml +9 -0
- package/dist/templates/package.json +27 -0
- package/dist/templates/src/task.ts +7 -0
- package/dist/templates/tests/Task.spec.ts +39 -0
- package/dist/templates/tsconfig.json +4 -0
- package/dist/types.js +25 -0
- package/dist/validators.js +18 -0
- package/package.json +58 -0
|
@@ -0,0 +1,250 @@
|
|
|
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 ArrayHandler_1 = __importDefault(require("./ArrayHandler"));
|
|
41
|
+
const FunctionHandler_1 = __importDefault(require("./FunctionHandler"));
|
|
42
|
+
const NameManager_1 = __importStar(require("./NameManager"));
|
|
43
|
+
const types_1 = require("./types");
|
|
44
|
+
class TupleHandler {
|
|
45
|
+
/**
|
|
46
|
+
* Checks if the given ABI type string ultimately represents a tuple.
|
|
47
|
+
* E.g., 'tuple', 'tuple[]', 'tuple[2]' would all return true.
|
|
48
|
+
*/
|
|
49
|
+
static isBaseTypeATuple(abiType) {
|
|
50
|
+
return ArrayHandler_1.default.getBaseType(abiType) === types_1.TUPLE_ABI_TYPE;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Checks if the given value is a tuple class name.
|
|
54
|
+
*/
|
|
55
|
+
static isTupleClassName(value, tupleDefinitions) {
|
|
56
|
+
return [...tupleDefinitions.values()].some((def) => def.className === value);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Gets the class name for an already defined tuple.
|
|
60
|
+
* Uses internalType or structural matching if necessary.
|
|
61
|
+
*/
|
|
62
|
+
static getClassNameForTupleDefinition(param, tupleDefinitions) {
|
|
63
|
+
if (!this.isBaseTypeATuple(param.type))
|
|
64
|
+
return undefined;
|
|
65
|
+
const baseInternalType = param.internalType ? ArrayHandler_1.default.getBaseType(param.internalType) : undefined;
|
|
66
|
+
if (baseInternalType && tupleDefinitions.has(baseInternalType))
|
|
67
|
+
return tupleDefinitions.get(baseInternalType).className;
|
|
68
|
+
const representativeParamForSearch = {
|
|
69
|
+
...param,
|
|
70
|
+
type: types_1.TUPLE_ABI_TYPE,
|
|
71
|
+
};
|
|
72
|
+
const existingByStructure = this.findMatchingDefinition(representativeParamForSearch, tupleDefinitions);
|
|
73
|
+
if (existingByStructure)
|
|
74
|
+
return existingByStructure.className;
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
static extractTupleDefinitions(abi) {
|
|
78
|
+
const tupleDefinitions = new Map();
|
|
79
|
+
let tupleCounter = 0;
|
|
80
|
+
const processParam = (param) => {
|
|
81
|
+
if (!this.isBaseTypeATuple(param.type)) {
|
|
82
|
+
param.components?.forEach(processParam);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const tupleToDefine = {
|
|
86
|
+
name: param.name,
|
|
87
|
+
type: types_1.TUPLE_ABI_TYPE,
|
|
88
|
+
internalType: param.internalType,
|
|
89
|
+
components: param.components,
|
|
90
|
+
};
|
|
91
|
+
if (!tupleToDefine.components || tupleToDefine.components.length === 0)
|
|
92
|
+
return;
|
|
93
|
+
const existingClassName = this.getClassNameForTupleDefinition(tupleToDefine, tupleDefinitions);
|
|
94
|
+
if (existingClassName)
|
|
95
|
+
return existingClassName;
|
|
96
|
+
let className = `Tuple${tupleCounter++}`;
|
|
97
|
+
const baseInternalType = tupleToDefine.internalType
|
|
98
|
+
? ArrayHandler_1.default.getBaseType(tupleToDefine.internalType)
|
|
99
|
+
: undefined;
|
|
100
|
+
if (baseInternalType) {
|
|
101
|
+
const structMatch = baseInternalType.match(/struct\s+(?:\w+\.)?(\w+)/);
|
|
102
|
+
if (structMatch && structMatch[1])
|
|
103
|
+
className = structMatch[1];
|
|
104
|
+
}
|
|
105
|
+
const key = baseInternalType || className;
|
|
106
|
+
const components = this.resolveComponentNames(tupleToDefine.components, NameManager_1.NameContext.CLASS_PROPERTY);
|
|
107
|
+
tupleDefinitions.set(key, {
|
|
108
|
+
className,
|
|
109
|
+
components,
|
|
110
|
+
});
|
|
111
|
+
tupleToDefine.components.forEach((subComp) => processParam(subComp));
|
|
112
|
+
return className;
|
|
113
|
+
};
|
|
114
|
+
abi.forEach((item) => {
|
|
115
|
+
if (item.type !== 'function')
|
|
116
|
+
return;
|
|
117
|
+
item.inputs?.forEach((input) => processParam(input));
|
|
118
|
+
item.outputs?.forEach((output) => processParam(output));
|
|
119
|
+
if (item.outputs && item.outputs.length > 1) {
|
|
120
|
+
const name = this.getOutputTupleClassName(item.name);
|
|
121
|
+
const representativeOutputTuple = {
|
|
122
|
+
name,
|
|
123
|
+
type: types_1.TUPLE_ABI_TYPE,
|
|
124
|
+
internalType: `struct ${name}`,
|
|
125
|
+
components: item.outputs,
|
|
126
|
+
};
|
|
127
|
+
processParam(representativeOutputTuple);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
return tupleDefinitions;
|
|
131
|
+
}
|
|
132
|
+
static findMatchingDefinition(param, definitions) {
|
|
133
|
+
if (!param.components || param.type !== types_1.TUPLE_ABI_TYPE)
|
|
134
|
+
return undefined;
|
|
135
|
+
return [...definitions.values()].find((def) => def.components.length === param.components.length &&
|
|
136
|
+
def.components.every((c, i) => c.type === param.components[i].type &&
|
|
137
|
+
(c.name === param.components[i].name || !c.name || !param.components[i].name)));
|
|
138
|
+
}
|
|
139
|
+
static generateTupleTypeString(type, components) {
|
|
140
|
+
if (!components || components.length === 0)
|
|
141
|
+
return this.mapTupleType(type);
|
|
142
|
+
const typeStrings = components.map((comp) => {
|
|
143
|
+
if (this.isBaseTypeATuple(comp.type) && comp.components)
|
|
144
|
+
return this.generateTupleTypeString(comp.type, comp.components);
|
|
145
|
+
return comp.type;
|
|
146
|
+
});
|
|
147
|
+
return this.mapTupleType(type, typeStrings.join(','));
|
|
148
|
+
}
|
|
149
|
+
static mapTupleType(abiType, tupleContent = '') {
|
|
150
|
+
if (!this.isBaseTypeATuple(abiType))
|
|
151
|
+
throw new Error(`${abiType} is not a tuple type`);
|
|
152
|
+
return abiType.replace(types_1.TUPLE_ABI_TYPE, `(${tupleContent})`);
|
|
153
|
+
}
|
|
154
|
+
static generateTupleClassesCode(tupleDefinitions, importManager, abiTypeConverter) {
|
|
155
|
+
if (tupleDefinitions.size === 0)
|
|
156
|
+
return '';
|
|
157
|
+
importManager.addType('parseCSVNotNullable');
|
|
158
|
+
const lines = [];
|
|
159
|
+
tupleDefinitions.forEach((def) => {
|
|
160
|
+
lines.push(`export class ${def.className} {`);
|
|
161
|
+
const components = def.components;
|
|
162
|
+
components.forEach((comp) => {
|
|
163
|
+
const fieldName = comp.escapedName;
|
|
164
|
+
const componentType = abiTypeConverter.mapAbiType(comp);
|
|
165
|
+
lines.push(` readonly ${fieldName}: ${componentType}`);
|
|
166
|
+
});
|
|
167
|
+
lines.push('');
|
|
168
|
+
const constructorParams = components
|
|
169
|
+
.map((comp) => {
|
|
170
|
+
const fieldName = comp.escapedName;
|
|
171
|
+
const componentType = abiTypeConverter.mapAbiType(comp);
|
|
172
|
+
return `${fieldName}: ${componentType}`;
|
|
173
|
+
})
|
|
174
|
+
.join(', ');
|
|
175
|
+
lines.push(` constructor(${constructorParams}) {`);
|
|
176
|
+
components.forEach((comp) => {
|
|
177
|
+
const fieldName = comp.escapedName;
|
|
178
|
+
lines.push(` this.${fieldName} = ${fieldName}`);
|
|
179
|
+
});
|
|
180
|
+
lines.push(` }`);
|
|
181
|
+
lines.push('');
|
|
182
|
+
lines.push(` static parse(data: string): ${def.className} {`);
|
|
183
|
+
lines.push(` const parts = parseCSVNotNullable(data)`);
|
|
184
|
+
lines.push(` if (parts.length !== ${def.components.length}) throw new Error("Invalid data for tuple parsing")`);
|
|
185
|
+
const componentsWithVarNames = this.resolveComponentNames(def.components, NameManager_1.NameContext.LOCAL_VARIABLE);
|
|
186
|
+
lines.push(...this.getTupleParseMethodBody({ ...def, components: componentsWithVarNames }, abiTypeConverter, importManager));
|
|
187
|
+
const constructorArgs = componentsWithVarNames.map((r) => r.escapedName).join(', ');
|
|
188
|
+
lines.push(` return new ${def.className}(${constructorArgs})`);
|
|
189
|
+
lines.push(` }`);
|
|
190
|
+
lines.push('');
|
|
191
|
+
lines.push(` toEvmEncodeParams(): EvmEncodeParam[] {`);
|
|
192
|
+
importManager.addType('EvmEncodeParam');
|
|
193
|
+
lines.push(` return [`);
|
|
194
|
+
lines.push(...this.getTupleToEvmParamsMethodBody(def, abiTypeConverter, importManager));
|
|
195
|
+
lines.push(` ]`);
|
|
196
|
+
lines.push(` }`);
|
|
197
|
+
lines.push(`}`);
|
|
198
|
+
lines.push('');
|
|
199
|
+
});
|
|
200
|
+
return lines.join('\n');
|
|
201
|
+
}
|
|
202
|
+
static getOutputTupleClassName(functionName) {
|
|
203
|
+
const fnNamePart = functionName.replace(/[^a-zA-Z0-9_]/g, '');
|
|
204
|
+
if (!fnNamePart)
|
|
205
|
+
return 'UnnamedFunctionOutputs';
|
|
206
|
+
return `${(0, helpers_1.pascalCase)(fnNamePart)}Outputs`;
|
|
207
|
+
}
|
|
208
|
+
static getTupleParseMethodBody(def, abiTypeConverter, importManager) {
|
|
209
|
+
return def.components.map((comp, index) => {
|
|
210
|
+
const fieldName = comp.escapedName;
|
|
211
|
+
const mappedComponentType = abiTypeConverter.mapAbiType(comp);
|
|
212
|
+
const dataAccess = `parts[${index}]`;
|
|
213
|
+
const parseLogic = this.buildFieldParseLogic(dataAccess, comp, mappedComponentType, abiTypeConverter, importManager);
|
|
214
|
+
return ` const ${fieldName}: ${mappedComponentType} = ${parseLogic};`;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
static buildFieldParseLogic(dataAccessString, componentAbiParam, mappedTargetType, abiTypeConverter, importManager, depth = 0) {
|
|
218
|
+
importManager.addType('parseCSVNotNullable');
|
|
219
|
+
const isAbiArray = ArrayHandler_1.default.isArrayType(componentAbiParam.type);
|
|
220
|
+
const baseAbiType = ArrayHandler_1.default.getBaseType(componentAbiParam.type);
|
|
221
|
+
if (isAbiArray) {
|
|
222
|
+
const elementType = ArrayHandler_1.default.getArrayType(mappedTargetType);
|
|
223
|
+
const itemVar = `item${depth}`;
|
|
224
|
+
const elementAbiParam = {
|
|
225
|
+
...componentAbiParam,
|
|
226
|
+
name: `${componentAbiParam.name || 'arrayElement'}_${itemVar}`,
|
|
227
|
+
type: ArrayHandler_1.default.getArrayType(componentAbiParam.type),
|
|
228
|
+
components: baseAbiType === types_1.TUPLE_ABI_TYPE ? componentAbiParam.components : undefined,
|
|
229
|
+
internalType: componentAbiParam.internalType
|
|
230
|
+
? ArrayHandler_1.default.getArrayType(componentAbiParam.internalType)
|
|
231
|
+
: undefined,
|
|
232
|
+
};
|
|
233
|
+
const subLogic = this.buildFieldParseLogic(itemVar, elementAbiParam, elementType, abiTypeConverter, importManager, depth + 1);
|
|
234
|
+
return `${dataAccessString} === '' ? [] : parseCSVNotNullable(${dataAccessString}).map<${elementType}>(((${itemVar}: string) => ${subLogic}))`;
|
|
235
|
+
}
|
|
236
|
+
return abiTypeConverter.generateTypeConversion(mappedTargetType, dataAccessString, false, false);
|
|
237
|
+
}
|
|
238
|
+
static getTupleToEvmParamsMethodBody(def, abiTypeConverter, importManager) {
|
|
239
|
+
return def.components.map((comp) => {
|
|
240
|
+
const fieldName = comp.escapedName;
|
|
241
|
+
const valueAccessPath = `this.${fieldName}`;
|
|
242
|
+
const paramCode = FunctionHandler_1.default.buildEvmEncodeParamCode(valueAccessPath, comp, abiTypeConverter, importManager);
|
|
243
|
+
return ` ${paramCode},`;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
static resolveComponentNames(components, context) {
|
|
247
|
+
return NameManager_1.default.resolveParameterNames(components, context, 'field');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.default = TupleHandler;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const ContractClassGenerator_1 = __importDefault(require("./ContractClassGenerator"));
|
|
7
|
+
exports.default = {
|
|
8
|
+
generate(abi, contractName) {
|
|
9
|
+
return new ContractClassGenerator_1.default(abi).generate(contractName);
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = {
|
|
4
|
+
generate(inputs) {
|
|
5
|
+
if (Object.entries(inputs).length == 0)
|
|
6
|
+
return '';
|
|
7
|
+
const convertedInputs = convertInputs(inputs);
|
|
8
|
+
const inputsMapping = generateInputsMapping(convertedInputs);
|
|
9
|
+
const imports = generateImports(convertedInputs);
|
|
10
|
+
const inputsClass = generateInputsClass(convertedInputs);
|
|
11
|
+
return [
|
|
12
|
+
'// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE MANUALLY.',
|
|
13
|
+
'',
|
|
14
|
+
imports,
|
|
15
|
+
'',
|
|
16
|
+
'declare namespace input {',
|
|
17
|
+
` ${inputsMapping}`,
|
|
18
|
+
'}',
|
|
19
|
+
'',
|
|
20
|
+
'// The class name is intentionally lowercase and plural to resemble a namespace when used in a task.',
|
|
21
|
+
'export class inputs {',
|
|
22
|
+
` ${inputsClass}`,
|
|
23
|
+
'}',
|
|
24
|
+
]
|
|
25
|
+
.join('\n')
|
|
26
|
+
.trim();
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
function convertInputs(inputs) {
|
|
30
|
+
return Object.fromEntries(Object.entries(inputs).map(([name, type]) => [name, convertType(type)]));
|
|
31
|
+
}
|
|
32
|
+
function generateImports(inputs) {
|
|
33
|
+
const typesToImport = new Set(Object.values(inputs).filter((e) => e === 'Address' || e === 'Bytes' || e === 'BigInt'));
|
|
34
|
+
if (typesToImport.size === 0)
|
|
35
|
+
return '';
|
|
36
|
+
return `import { ${[...typesToImport].sort().join(', ')} } from '@mimicprotocol/lib-ts'`;
|
|
37
|
+
}
|
|
38
|
+
function generateInputsMapping(inputs) {
|
|
39
|
+
return Object.entries(inputs)
|
|
40
|
+
.map(([name, type]) => type === 'string' || type === 'Address' || type === 'Bytes' || type === 'BigInt'
|
|
41
|
+
? `var ${name}: string | null`
|
|
42
|
+
: `const ${name}: ${type}`)
|
|
43
|
+
.join('\n ');
|
|
44
|
+
}
|
|
45
|
+
function generateInputsClass(inputs) {
|
|
46
|
+
return Object.entries(inputs)
|
|
47
|
+
.map(([name, type]) => generateGetter(name, type))
|
|
48
|
+
.join('\n\n ');
|
|
49
|
+
}
|
|
50
|
+
function convertType(type) {
|
|
51
|
+
const match = type.match(/^(u?)int(\d+)?$/);
|
|
52
|
+
if (match) {
|
|
53
|
+
const isUnsigned = match[1] === 'u';
|
|
54
|
+
const size = parseInt(match[2] || '256');
|
|
55
|
+
const prefix = isUnsigned ? 'u' : 'i';
|
|
56
|
+
if (size <= 8)
|
|
57
|
+
return `${prefix}8`;
|
|
58
|
+
if (size <= 16)
|
|
59
|
+
return `${prefix}16`;
|
|
60
|
+
if (size <= 32)
|
|
61
|
+
return `${prefix}32`;
|
|
62
|
+
if (size <= 64)
|
|
63
|
+
return `${prefix}64`;
|
|
64
|
+
return 'BigInt'; // 128 and 256 go here
|
|
65
|
+
}
|
|
66
|
+
if (type.includes('address'))
|
|
67
|
+
return 'Address';
|
|
68
|
+
if (type.includes('bytes'))
|
|
69
|
+
return 'Bytes';
|
|
70
|
+
return type;
|
|
71
|
+
}
|
|
72
|
+
function generateGetter(name, type) {
|
|
73
|
+
const str = `input.${name}`;
|
|
74
|
+
let returnStr;
|
|
75
|
+
if (type === 'string')
|
|
76
|
+
returnStr = `${str}!`;
|
|
77
|
+
else if (type === 'Address')
|
|
78
|
+
returnStr = `Address.fromString(${str}!)`;
|
|
79
|
+
else if (type === 'Bytes')
|
|
80
|
+
returnStr = `Bytes.fromHexString(${str}!)`;
|
|
81
|
+
else if (type === 'BigInt')
|
|
82
|
+
returnStr = `BigInt.fromString(${str}!)`;
|
|
83
|
+
else
|
|
84
|
+
returnStr = str;
|
|
85
|
+
return `static get ${name}(): ${type} {
|
|
86
|
+
return ${returnStr}
|
|
87
|
+
}`;
|
|
88
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const js_yaml_1 = require("js-yaml");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const zod_1 = require("zod");
|
|
40
|
+
const errors_1 = require("../errors");
|
|
41
|
+
const validators_1 = require("../validators");
|
|
42
|
+
exports.default = {
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
44
|
+
validate(manifest) {
|
|
45
|
+
if (!manifest)
|
|
46
|
+
throw new errors_1.EmptyManifestError();
|
|
47
|
+
const mergedManifest = {
|
|
48
|
+
...manifest,
|
|
49
|
+
inputs: mergeIfUnique(manifest.inputs),
|
|
50
|
+
abis: mergeIfUnique(manifest.abis),
|
|
51
|
+
metadata: { libVersion: getLibVersion() },
|
|
52
|
+
};
|
|
53
|
+
return validators_1.ManifestValidator.parse(mergedManifest);
|
|
54
|
+
},
|
|
55
|
+
load(command, manifestDir) {
|
|
56
|
+
let loadedManifest;
|
|
57
|
+
try {
|
|
58
|
+
loadedManifest = (0, js_yaml_1.load)(fs.readFileSync(manifestDir, 'utf-8'));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
command.error(`Could not find ${manifestDir}`, {
|
|
62
|
+
code: 'FileNotFound',
|
|
63
|
+
suggestions: ['Use the -m or --manifest flag to specify the correct path'],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
return this.validate(loadedManifest);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
handleValidationError(command, err);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
function mergeIfUnique(list) {
|
|
75
|
+
const merged = {};
|
|
76
|
+
for (const obj of list || []) {
|
|
77
|
+
const entries = Object.entries(obj);
|
|
78
|
+
if (entries.length !== 1)
|
|
79
|
+
throw new errors_1.MoreThanOneEntryError(entries);
|
|
80
|
+
const [key, val] = entries[0];
|
|
81
|
+
if (key in merged)
|
|
82
|
+
throw new errors_1.DuplicateEntryError(key);
|
|
83
|
+
merged[key] = val;
|
|
84
|
+
}
|
|
85
|
+
return merged;
|
|
86
|
+
}
|
|
87
|
+
function handleValidationError(command, err) {
|
|
88
|
+
let message;
|
|
89
|
+
let code;
|
|
90
|
+
let suggestions;
|
|
91
|
+
if (err instanceof errors_1.MoreThanOneEntryError) {
|
|
92
|
+
;
|
|
93
|
+
[message, code] = [err.message, err.name];
|
|
94
|
+
suggestions = [`${err.location[1][0]}: ${err.location[1][1]} might be missing a prepended '-' on manifest`];
|
|
95
|
+
}
|
|
96
|
+
else if (err instanceof errors_1.DuplicateEntryError) {
|
|
97
|
+
;
|
|
98
|
+
[message, code] = [err.message, err.name];
|
|
99
|
+
suggestions = [`Review manifest for duplicate key: ${err.duplicateKey}`];
|
|
100
|
+
}
|
|
101
|
+
else if (err instanceof errors_1.EmptyManifestError) {
|
|
102
|
+
;
|
|
103
|
+
[message, code] = [err.message, err.name];
|
|
104
|
+
suggestions = ['Verify if you are using the correct manifest file'];
|
|
105
|
+
}
|
|
106
|
+
else if (err instanceof zod_1.ZodError) {
|
|
107
|
+
;
|
|
108
|
+
[message, code] = ['Missing/Incorrect Fields', 'FieldsError'];
|
|
109
|
+
suggestions = err.errors.map((e) => `Fix Field "${e.path.join('.')}" -- ${e.message}`);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
;
|
|
113
|
+
[message, code] = [`Unkown Error: ${err}`, 'UnknownError'];
|
|
114
|
+
suggestions = [
|
|
115
|
+
'Contact the Mimic team for further assistance at our website https://www.mimic.fi/ or discord https://discord.com/invite/cpcyV9EsEg',
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
command.error(message, { code, suggestions });
|
|
119
|
+
}
|
|
120
|
+
function getLibVersion() {
|
|
121
|
+
try {
|
|
122
|
+
let currentDir = process.cwd();
|
|
123
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
124
|
+
const libPackagePath = path.join(currentDir, 'node_modules', '@mimicprotocol', 'lib-ts', 'package.json');
|
|
125
|
+
if (fs.existsSync(libPackagePath))
|
|
126
|
+
return JSON.parse(fs.readFileSync(libPackagePath, 'utf-8')).version;
|
|
127
|
+
currentDir = path.dirname(currentDir);
|
|
128
|
+
}
|
|
129
|
+
throw new Error('Could not find @mimicprotocol/lib-ts package');
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error(`Failed to read @mimicprotocol/lib-ts version: ${error}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ManifestHandler = exports.InputsInterfaceGenerator = exports.AbisInterfaceGenerator = void 0;
|
|
7
|
+
const index_1 = __importDefault(require("./AbisInterfaceGenerator/index"));
|
|
8
|
+
exports.AbisInterfaceGenerator = index_1.default;
|
|
9
|
+
const InputsInterfaceGenerator_1 = __importDefault(require("./InputsInterfaceGenerator"));
|
|
10
|
+
exports.InputsInterfaceGenerator = InputsInterfaceGenerator_1.default;
|
|
11
|
+
const ManifestHandler_1 = __importDefault(require("./ManifestHandler"));
|
|
12
|
+
exports.ManifestHandler = ManifestHandler_1.default;
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const log = {
|
|
5
|
+
startAction: (text, color) => {
|
|
6
|
+
log.stopAction();
|
|
7
|
+
core_1.ux.action.start(core_1.ux.colorize(color, text));
|
|
8
|
+
},
|
|
9
|
+
stopAction: (text) => core_1.ux.action.stop(core_1.ux.colorize('green', `${text ? `${text} ` : ''}✔️`)),
|
|
10
|
+
warnText: (text) => core_1.ux.colorize('red', text),
|
|
11
|
+
highlightText: (text) => core_1.ux.colorize('yellow', text),
|
|
12
|
+
};
|
|
13
|
+
exports.default = log;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mimic-task",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "Unlicensed",
|
|
5
|
+
"private": true,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "yarn codegen && yarn compile",
|
|
9
|
+
"codegen": "mimic codegen",
|
|
10
|
+
"compile": "mimic compile",
|
|
11
|
+
"test": "mimic test"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@mimicprotocol/cli": "^0.0.1-rc.0",
|
|
15
|
+
"@mimicprotocol/lib-ts": "^0.0.1-rc.0",
|
|
16
|
+
"@mimicprotocol/test-ts": "^0.0.1-rc.0",
|
|
17
|
+
"@types/mocha": "^10.0.1",
|
|
18
|
+
"@types/node": "^22.10.5",
|
|
19
|
+
"assemblyscript": "0.27.36",
|
|
20
|
+
"chai": "^4.3.7",
|
|
21
|
+
"json-as": "1.0.7",
|
|
22
|
+
"mocha": "^10.2.0",
|
|
23
|
+
"tsx": "^4.20.3",
|
|
24
|
+
"typescript": "^5.8.3",
|
|
25
|
+
"visitor-as": "0.11.4"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { runTask } from '@mimicprotocol/test-ts'
|
|
2
|
+
import { expect } from 'chai'
|
|
3
|
+
|
|
4
|
+
describe('Task', () => {
|
|
5
|
+
it('produces the expected intents', async () => {
|
|
6
|
+
const taskDir = './'
|
|
7
|
+
|
|
8
|
+
const context = {
|
|
9
|
+
user: '0x756f45e3fa69347a9a973a725e3c98bc4db0b5a0',
|
|
10
|
+
settler: '0xdcf1d9d12a0488dfb70a8696f44d6d3bc303963d',
|
|
11
|
+
timestamp: '1438223173000',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const inputs = {
|
|
15
|
+
chainId: 10,
|
|
16
|
+
token: '0x7f5c764cbc14f9669b88837ca1490cca17c31607',
|
|
17
|
+
amount: '10000000',
|
|
18
|
+
recipient: context.user,
|
|
19
|
+
fee: '100',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const intents = await runTask(taskDir, context, { inputs })
|
|
23
|
+
|
|
24
|
+
expect(intents).to.be.an('array').that.is.not.empty
|
|
25
|
+
expect(intents).to.have.lengthOf(1)
|
|
26
|
+
|
|
27
|
+
expect(intents[0].type).to.be.equal('transfer')
|
|
28
|
+
expect(intents[0].settler).to.be.equal(context.settler)
|
|
29
|
+
expect(intents[0].user).to.be.equal(context.user)
|
|
30
|
+
expect(intents[0].chainId).to.be.equal(inputs.chainId)
|
|
31
|
+
expect(intents[0].feeToken).to.be.equal(inputs.token)
|
|
32
|
+
expect(intents[0].feeAmount).to.be.equal(inputs.fee)
|
|
33
|
+
|
|
34
|
+
expect(intents[0].transfers).to.have.lengthOf(1)
|
|
35
|
+
expect(intents[0].transfers[0].token).to.be.equal(inputs.token)
|
|
36
|
+
expect(intents[0].transfers[0].amount).to.be.equal(inputs.amount)
|
|
37
|
+
expect(intents[0].transfers[0].recipient).to.be.equal(inputs.recipient)
|
|
38
|
+
})
|
|
39
|
+
})
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssemblyPrimitiveTypes = exports.LibTypes = void 0;
|
|
4
|
+
var LibTypes;
|
|
5
|
+
(function (LibTypes) {
|
|
6
|
+
LibTypes["BigInt"] = "BigInt";
|
|
7
|
+
LibTypes["Address"] = "Address";
|
|
8
|
+
LibTypes["Bytes"] = "Bytes";
|
|
9
|
+
LibTypes["ChainId"] = "ChainId";
|
|
10
|
+
LibTypes["TokenAmount"] = "TokenAmount";
|
|
11
|
+
})(LibTypes || (exports.LibTypes = LibTypes = {}));
|
|
12
|
+
var AssemblyPrimitiveTypes;
|
|
13
|
+
(function (AssemblyPrimitiveTypes) {
|
|
14
|
+
AssemblyPrimitiveTypes["u8"] = "u8";
|
|
15
|
+
AssemblyPrimitiveTypes["u16"] = "u16";
|
|
16
|
+
AssemblyPrimitiveTypes["u32"] = "u32";
|
|
17
|
+
AssemblyPrimitiveTypes["u64"] = "u64";
|
|
18
|
+
AssemblyPrimitiveTypes["i8"] = "i8";
|
|
19
|
+
AssemblyPrimitiveTypes["i16"] = "i16";
|
|
20
|
+
AssemblyPrimitiveTypes["i32"] = "i32";
|
|
21
|
+
AssemblyPrimitiveTypes["i64"] = "i64";
|
|
22
|
+
AssemblyPrimitiveTypes["bool"] = "bool";
|
|
23
|
+
AssemblyPrimitiveTypes["string"] = "string";
|
|
24
|
+
AssemblyPrimitiveTypes["Date"] = "Date";
|
|
25
|
+
})(AssemblyPrimitiveTypes || (exports.AssemblyPrimitiveTypes = AssemblyPrimitiveTypes = {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ManifestValidator = exports.SEM_VER_REGEX = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const String = zod_1.z.string().min(1);
|
|
6
|
+
const SOLIDITY_TYPE_REGEX = /^(u?int(8|16|32|64|128|256)?|bool|address|bytes([1-9]|[1-2][0-9]|3[0-2])?|string)$/;
|
|
7
|
+
// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
|
|
8
|
+
exports.SEM_VER_REGEX = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
9
|
+
exports.ManifestValidator = zod_1.z.object({
|
|
10
|
+
version: String.regex(exports.SEM_VER_REGEX, 'Must be a valid semver'),
|
|
11
|
+
name: String,
|
|
12
|
+
description: String,
|
|
13
|
+
inputs: zod_1.z.record(String, String.regex(SOLIDITY_TYPE_REGEX, 'Must be a valid solidity type')),
|
|
14
|
+
abis: zod_1.z.record(String, String),
|
|
15
|
+
metadata: zod_1.z.object({
|
|
16
|
+
libVersion: String.regex(exports.SEM_VER_REGEX, 'Must be a valid semver'),
|
|
17
|
+
}),
|
|
18
|
+
});
|