@graphprotocol/graph-cli 0.37.2 → 0.37.3-alpha-20230110163550-d64bef6

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.
Files changed (206) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/babel.config.js +3 -0
  3. package/dist/bin.js +6 -0
  4. package/dist/cli.js +32 -0
  5. package/dist/codegen/schema.js +250 -0
  6. package/dist/codegen/schema.test.js +458 -0
  7. package/dist/codegen/template.js +65 -0
  8. package/dist/codegen/types/conversions.js +359 -0
  9. package/dist/codegen/types/index.js +71 -0
  10. package/dist/codegen/types/index.test.js +563 -0
  11. package/dist/codegen/typescript.js +200 -0
  12. package/dist/codegen/util.js +46 -0
  13. package/dist/codegen/util.test.js +93 -0
  14. package/dist/command-helpers/abi.js +78 -0
  15. package/dist/command-helpers/auth.js +77 -0
  16. package/dist/command-helpers/compiler.js +66 -0
  17. package/dist/command-helpers/data-sources.js +29 -0
  18. package/dist/command-helpers/fs.js +9 -0
  19. package/dist/command-helpers/gluegun.js +49 -0
  20. package/dist/command-helpers/ipfs.js +5 -0
  21. package/dist/command-helpers/jsonrpc.js +29 -0
  22. package/dist/command-helpers/network.js +93 -0
  23. package/dist/command-helpers/network.test.js +86 -0
  24. package/dist/command-helpers/node.js +40 -0
  25. package/dist/command-helpers/scaffold.js +112 -0
  26. package/dist/command-helpers/spinner.js +84 -0
  27. package/dist/command-helpers/studio.js +13 -0
  28. package/dist/command-helpers/studio.test.js +41 -0
  29. package/dist/command-helpers/subgraph.js +24 -0
  30. package/dist/command-helpers/version.js +74 -0
  31. package/dist/command-helpers/version.test.js +179 -0
  32. package/dist/commands/add.js +190 -0
  33. package/dist/commands/auth.js +127 -0
  34. package/dist/commands/build.js +140 -0
  35. package/dist/commands/codegen.js +135 -0
  36. package/dist/commands/create.js +86 -0
  37. package/dist/commands/deploy.js +334 -0
  38. package/dist/commands/init.js +788 -0
  39. package/dist/commands/local.js +387 -0
  40. package/dist/commands/remove.js +86 -0
  41. package/dist/commands/test.js +295 -0
  42. package/dist/compiler/asc.js +83 -0
  43. package/dist/compiler/index.js +474 -0
  44. package/dist/debug.js +16 -0
  45. package/dist/migrations/mapping_api_version_0_0_1.js +78 -0
  46. package/dist/migrations/mapping_api_version_0_0_2.js +76 -0
  47. package/dist/migrations/mapping_api_version_0_0_3.js +78 -0
  48. package/dist/migrations/mapping_api_version_0_0_4.js +80 -0
  49. package/dist/migrations/mapping_api_version_0_0_5.js +80 -0
  50. package/dist/migrations/spec_version_0_0_2.js +49 -0
  51. package/dist/migrations/spec_version_0_0_3.js +54 -0
  52. package/dist/migrations/util/load-manifest.js +18 -0
  53. package/dist/migrations/util/versions.js +29 -0
  54. package/dist/migrations.js +56 -0
  55. package/dist/protocols/arweave/manifest.graphql +57 -0
  56. package/dist/protocols/arweave/scaffold/manifest.js +18 -0
  57. package/dist/protocols/arweave/scaffold/mapping.js +52 -0
  58. package/dist/protocols/arweave/subgraph.js +23 -0
  59. package/dist/protocols/cosmos/manifest.graphql +76 -0
  60. package/dist/protocols/cosmos/scaffold/manifest.js +15 -0
  61. package/dist/protocols/cosmos/scaffold/mapping.js +38 -0
  62. package/dist/protocols/cosmos/subgraph.js +25 -0
  63. package/dist/protocols/ethereum/abi.js +140 -0
  64. package/dist/protocols/ethereum/codegen/abi.js +451 -0
  65. package/dist/protocols/ethereum/codegen/abi.test.js +328 -0
  66. package/dist/protocols/ethereum/codegen/template.js +50 -0
  67. package/dist/protocols/ethereum/contract.js +20 -0
  68. package/dist/protocols/ethereum/manifest.graphql +94 -0
  69. package/dist/protocols/ethereum/scaffold/manifest.js +32 -0
  70. package/dist/protocols/ethereum/scaffold/mapping.js +65 -0
  71. package/dist/protocols/ethereum/subgraph.js +171 -0
  72. package/dist/protocols/ethereum/type-generator.js +125 -0
  73. package/dist/protocols/index.js +268 -0
  74. package/dist/protocols/ipfs/codegen/file_template.js +50 -0
  75. package/dist/protocols/near/contract.js +41 -0
  76. package/dist/protocols/near/manifest.graphql +64 -0
  77. package/dist/protocols/near/scaffold/manifest.js +16 -0
  78. package/dist/protocols/near/scaffold/mapping.js +38 -0
  79. package/dist/protocols/near/subgraph.js +20 -0
  80. package/dist/protocols/subgraph.js +2 -0
  81. package/dist/protocols/substreams/manifest.graphql +45 -0
  82. package/dist/protocols/substreams/scaffold/manifest.js +12 -0
  83. package/dist/protocols/substreams/subgraph.js +23 -0
  84. package/dist/scaffold/cosmos.test.js +83 -0
  85. package/dist/scaffold/ethereum.test.js +505 -0
  86. package/dist/scaffold/index.js +128 -0
  87. package/dist/scaffold/mapping.js +61 -0
  88. package/dist/scaffold/near.test.js +86 -0
  89. package/dist/scaffold/schema.js +83 -0
  90. package/dist/scaffold/tests.js +175 -0
  91. package/dist/schema.js +54 -0
  92. package/dist/subgraph.js +249 -0
  93. package/dist/type-generator.js +224 -0
  94. package/dist/validation/contract.js +46 -0
  95. package/dist/validation/index.js +8 -0
  96. package/dist/validation/manifest.js +271 -0
  97. package/dist/validation/schema.js +796 -0
  98. package/dist/validation/schema.test.js +35 -0
  99. package/dist/watcher.js +79 -0
  100. package/jest.config.js +1 -1
  101. package/package.json +16 -9
  102. package/{bin/graph → src/bin.ts} +2 -1
  103. package/src/cli.ts +36 -0
  104. package/src/codegen/schema.js +23 -22
  105. package/src/codegen/schema.test.js +33 -27
  106. package/src/codegen/{template.js → template.ts} +8 -6
  107. package/src/codegen/types/conversions.ts +382 -0
  108. package/src/codegen/types/index.js +4 -7
  109. package/src/codegen/types/index.test.js +10 -4
  110. package/src/codegen/{typescript.js → typescript.ts} +44 -26
  111. package/src/codegen/util.js +1 -1
  112. package/src/codegen/util.test.js +5 -2
  113. package/src/command-helpers/abi.js +46 -30
  114. package/src/command-helpers/auth.js +6 -9
  115. package/src/command-helpers/compiler.js +4 -6
  116. package/src/command-helpers/data-sources.js +8 -11
  117. package/src/command-helpers/fs.ts +5 -0
  118. package/src/command-helpers/gluegun.js +2 -4
  119. package/src/command-helpers/ipfs.ts +3 -0
  120. package/src/command-helpers/{jsonrpc.js → jsonrpc.ts} +11 -16
  121. package/src/command-helpers/network.js +58 -44
  122. package/src/command-helpers/network.test.js +23 -19
  123. package/src/command-helpers/node.js +3 -7
  124. package/src/command-helpers/scaffold.js +34 -25
  125. package/src/command-helpers/{spinner.js → spinner.ts} +10 -10
  126. package/src/command-helpers/studio.test.js +61 -30
  127. package/src/command-helpers/studio.ts +20 -0
  128. package/src/command-helpers/{subgraph.js → subgraph.ts} +6 -6
  129. package/src/command-helpers/version.js +11 -16
  130. package/src/command-helpers/version.test.js +111 -82
  131. package/src/commands/add.js +49 -35
  132. package/src/commands/auth.js +13 -25
  133. package/src/commands/build.js +9 -9
  134. package/src/commands/codegen.js +12 -12
  135. package/src/commands/create.js +22 -22
  136. package/src/commands/deploy.js +39 -34
  137. package/src/commands/init.js +21 -24
  138. package/src/commands/local.js +15 -14
  139. package/src/commands/remove.js +22 -22
  140. package/src/commands/test.js +86 -70
  141. package/src/compiler/{asc.js → asc.ts} +29 -16
  142. package/src/compiler/index.js +18 -18
  143. package/src/{debug.js → debug.ts} +2 -2
  144. package/src/migrations/mapping_api_version_0_0_1.js +7 -7
  145. package/src/migrations/mapping_api_version_0_0_2.js +5 -5
  146. package/src/migrations/mapping_api_version_0_0_3.js +7 -7
  147. package/src/migrations/mapping_api_version_0_0_4.js +7 -7
  148. package/src/migrations/mapping_api_version_0_0_5.js +7 -7
  149. package/src/migrations/spec_version_0_0_2.js +5 -5
  150. package/src/migrations/spec_version_0_0_3.js +5 -5
  151. package/src/migrations/util/load-manifest.js +6 -9
  152. package/src/migrations/util/versions.js +5 -10
  153. package/src/{migrations.js → migrations.ts} +14 -15
  154. package/src/protocols/arweave/scaffold/manifest.js +1 -4
  155. package/src/protocols/arweave/scaffold/mapping.js +1 -3
  156. package/src/protocols/arweave/subgraph.ts +22 -0
  157. package/src/protocols/cosmos/scaffold/manifest.js +1 -4
  158. package/src/protocols/cosmos/scaffold/mapping.js +1 -3
  159. package/src/protocols/cosmos/subgraph.js +2 -2
  160. package/src/protocols/ethereum/abi.js +7 -13
  161. package/src/protocols/ethereum/codegen/abi.js +219 -222
  162. package/src/protocols/ethereum/codegen/abi.test.js +6 -6
  163. package/src/protocols/ethereum/codegen/template.js +3 -5
  164. package/src/protocols/ethereum/contract.js +3 -2
  165. package/src/protocols/ethereum/scaffold/manifest.js +4 -7
  166. package/src/protocols/ethereum/scaffold/mapping.js +4 -11
  167. package/src/protocols/ethereum/subgraph.js +21 -20
  168. package/src/protocols/ethereum/type-generator.js +24 -30
  169. package/src/protocols/{index.js → index.ts} +65 -46
  170. package/src/protocols/ipfs/codegen/file_template.js +2 -2
  171. package/src/protocols/near/{contract.js → contract.ts} +16 -12
  172. package/src/protocols/near/scaffold/manifest.js +2 -5
  173. package/src/protocols/near/scaffold/mapping.js +1 -3
  174. package/src/protocols/near/subgraph.js +3 -6
  175. package/src/protocols/subgraph.ts +12 -0
  176. package/src/protocols/substreams/scaffold/{manifest.js → manifest.ts} +2 -7
  177. package/src/protocols/substreams/subgraph.ts +22 -0
  178. package/src/scaffold/cosmos.test.js +3 -3
  179. package/src/scaffold/ethereum.test.js +4 -4
  180. package/src/scaffold/index.js +7 -7
  181. package/src/scaffold/mapping.js +3 -3
  182. package/src/scaffold/near.test.js +3 -3
  183. package/src/scaffold/schema.js +4 -4
  184. package/src/scaffold/tests.js +72 -58
  185. package/src/schema.ts +26 -0
  186. package/src/{subgraph.js → subgraph.ts} +80 -60
  187. package/src/type-generator.js +20 -20
  188. package/src/validation/contract.js +2 -6
  189. package/src/validation/index.js +1 -1
  190. package/src/validation/manifest.js +24 -22
  191. package/src/validation/schema.test.js +1 -1
  192. package/src/validation/{schema.js → schema.ts} +268 -221
  193. package/src/{watcher.js → watcher.ts} +23 -12
  194. package/tests/cli/globalSetup.js +2 -2
  195. package/tests/cli/globalTeardown.js +2 -2
  196. package/tests/cli/init.test.js +2 -2
  197. package/tests/cli/util.js +7 -13
  198. package/tsconfig.json +18 -0
  199. package/src/cli.js +0 -38
  200. package/src/codegen/types/conversions.js +0 -329
  201. package/src/command-helpers/fs.js +0 -8
  202. package/src/command-helpers/ipfs.js +0 -6
  203. package/src/command-helpers/studio.js +0 -15
  204. package/src/protocols/arweave/subgraph.js +0 -20
  205. package/src/protocols/substreams/subgraph.js +0 -17
  206. package/src/schema.js +0 -23
@@ -0,0 +1,451 @@
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 (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const immutable_1 = __importDefault(require("immutable"));
30
+ const fs_1 = __importDefault(require("fs"));
31
+ const yaml_1 = __importDefault(require("yaml"));
32
+ const sync_request_1 = __importDefault(require("sync-request"));
33
+ const Web3EthAbi = require('web3-eth-abi');
34
+ const tsCodegen = __importStar(require("../../../codegen/typescript"));
35
+ const typesCodegen = __importStar(require("../../../codegen/types"));
36
+ const util = __importStar(require("../../../codegen/util"));
37
+ const doFixtureCodegen = fs_1.default.existsSync('./fixtures.yaml');
38
+ class AbiCodeGenerator {
39
+ constructor(abi) {
40
+ this.abi = abi;
41
+ }
42
+ generateModuleImports() {
43
+ let imports = [
44
+ tsCodegen.moduleImports([
45
+ // Ethereum integration
46
+ 'ethereum',
47
+ // Base classes
48
+ 'JSONValue',
49
+ 'TypedMap',
50
+ 'Entity',
51
+ // AssemblyScript types
52
+ 'Bytes',
53
+ 'Address',
54
+ 'BigInt',
55
+ ], '@graphprotocol/graph-ts'),
56
+ ];
57
+ if (doFixtureCodegen) {
58
+ imports.push(tsCodegen.moduleImports(['newMockEvent'], 'matchstick-as/assembly/index'));
59
+ }
60
+ return imports;
61
+ }
62
+ generateTypes() {
63
+ return [
64
+ ...this._generateEventTypes(),
65
+ ...this._generateSmartContractClass(),
66
+ ...this._generateCallTypes(),
67
+ ];
68
+ }
69
+ _generateCallTypes() {
70
+ let callFunctions = util.disambiguateNames({
71
+ values: this.abi.callFunctions(),
72
+ getName: fn => fn.get('name') || (fn.get('type') === 'constructor' ? 'constructor' : 'default'),
73
+ setName: (fn, name) => fn.set('_alias', name),
74
+ });
75
+ callFunctions = callFunctions.map(fn => {
76
+ let fnAlias = fn.get('_alias');
77
+ let fnClassName = `${fnAlias.charAt(0).toUpperCase()}${fnAlias.slice(1)}Call`;
78
+ let tupleClasses = [];
79
+ // First, generate a class with the input getters
80
+ let inputsClassName = fnClassName + '__Inputs';
81
+ let inputsClass = tsCodegen.klass(inputsClassName, { export: true });
82
+ inputsClass.addMember(tsCodegen.klassMember('_call', fnClassName));
83
+ inputsClass.addMethod(tsCodegen.method(`constructor`, [tsCodegen.param(`call`, fnClassName)], null, `this._call = call`));
84
+ // Generate getters and classes for function inputs
85
+ util
86
+ .disambiguateNames({
87
+ values: fn.get('inputs', immutable_1.default.List()),
88
+ getName: (input, index) => input.get('name') || `value${index}`,
89
+ setName: (input, name) => input.set('name', name),
90
+ })
91
+ .forEach((input, index) => {
92
+ let callInput = this._generateInputOrOutput(input, index, fnClassName, `call`, `inputValues`);
93
+ inputsClass.addMethod(callInput.getter);
94
+ tupleClasses.push(...callInput.classes);
95
+ });
96
+ // Second, generate a class with the output getters
97
+ let outputsClassName = fnClassName + '__Outputs';
98
+ let outputsClass = tsCodegen.klass(outputsClassName, { export: true });
99
+ outputsClass.addMember(tsCodegen.klassMember('_call', fnClassName));
100
+ outputsClass.addMethod(tsCodegen.method(`constructor`, [tsCodegen.param(`call`, fnClassName)], null, `this._call = call`));
101
+ // Generate getters and classes for function outputs
102
+ util
103
+ .disambiguateNames({
104
+ values: fn.get('outputs', immutable_1.default.List()),
105
+ getName: (output, index) => output.get('name') || `value${index}`,
106
+ setName: (output, name) => output.set('name', name),
107
+ })
108
+ .forEach((output, index) => {
109
+ let callInput = this._generateInputOrOutput(output, index, fnClassName, `call`, `outputValues`);
110
+ outputsClass.addMethod(callInput.getter);
111
+ tupleClasses.push(...callInput.classes);
112
+ });
113
+ // Then, generate the event class itself
114
+ let klass = tsCodegen.klass(fnClassName, {
115
+ export: true,
116
+ extends: 'ethereum.Call',
117
+ });
118
+ klass.addMethod(tsCodegen.method(`get inputs`, [], tsCodegen.namedType(inputsClassName), `return new ${inputsClassName}(this)`));
119
+ klass.addMethod(tsCodegen.method(`get outputs`, [], tsCodegen.namedType(outputsClassName), `return new ${outputsClassName}(this)`));
120
+ return [klass, inputsClass, outputsClass, ...tupleClasses];
121
+ });
122
+ return callFunctions.reduce(
123
+ // flatten the array
124
+ (array, classes) => array.concat(classes), []);
125
+ }
126
+ _generateEventTypes() {
127
+ // Enumerate events with duplicate names
128
+ let events = util.disambiguateNames({
129
+ values: this.abi.data.filter(member => member.get('type') === 'event'),
130
+ getName: event => event.get('name'),
131
+ setName: (event, name) => event.set('_alias', name),
132
+ });
133
+ events = events.map(event => {
134
+ let eventClassName = event.get('_alias');
135
+ let tupleClasses = [];
136
+ // First, generate a class with the param getters
137
+ let paramsClassName = eventClassName + '__Params';
138
+ let paramsClass = tsCodegen.klass(paramsClassName, { export: true });
139
+ paramsClass.addMember(tsCodegen.klassMember('_event', eventClassName));
140
+ paramsClass.addMethod(tsCodegen.method(`constructor`, [tsCodegen.param(`event`, eventClassName)], null, `this._event = event`));
141
+ // Enumerate inputs with duplicate names
142
+ let inputs = util.disambiguateNames({
143
+ values: event.get('inputs'),
144
+ getName: (input, index) => input.get('name') || `param${index}`,
145
+ setName: (input, name) => input.set('name', name),
146
+ });
147
+ let namesAndTypes = [];
148
+ inputs.forEach((input, index) => {
149
+ // Generate getters and classes for event params
150
+ let paramObject = this._generateInputOrOutput(input, index, eventClassName, `event`, `parameters`);
151
+ paramsClass.addMethod(paramObject.getter);
152
+ // Fixture generation
153
+ if (doFixtureCodegen) {
154
+ let ethType = typesCodegen.ethereumTypeForAsc(paramObject.getter.returnType);
155
+ if (typeof ethType === typeof {} &&
156
+ (ethType.test('int256') || ethType.test('uint256'))) {
157
+ ethType = 'int32';
158
+ }
159
+ namesAndTypes.push({ name: paramObject.getter.name.slice(4), type: ethType });
160
+ }
161
+ tupleClasses.push(...paramObject.classes);
162
+ });
163
+ // Then, generate the event class itself
164
+ let klass = tsCodegen.klass(eventClassName, {
165
+ export: true,
166
+ extends: 'ethereum.Event',
167
+ });
168
+ klass.addMethod(tsCodegen.method(`get params`, [], tsCodegen.namedType(paramsClassName), `return new ${paramsClassName}(this)`));
169
+ // Fixture generation
170
+ if (doFixtureCodegen) {
171
+ const args = yaml_1.default.parse(fs_1.default.readFileSync('./fixtures.yaml', 'utf8'));
172
+ const blockNumber = args['blockNumber'];
173
+ const contractAddr = args['contractAddr'];
174
+ const topic0 = args['topic0'];
175
+ const apiKey = args['apiKey'];
176
+ const url = `https://api.etherscan.io/api?module=logs&action=getLogs&fromBlock=${blockNumber}&toBlock=${blockNumber}&address=${contractAddr}&${topic0}=topic0&apikey=${apiKey}`;
177
+ let resp = (0, sync_request_1.default)('GET', url);
178
+ let body = JSON.parse(resp.getBody('utf8'));
179
+ if (body.status === '0') {
180
+ throw new Error(body.result);
181
+ }
182
+ let res = Web3EthAbi.decodeLog(namesAndTypes, body.result[0].data, []);
183
+ let stmnts = '';
184
+ for (let i = 0; i < namesAndTypes.length; i++) {
185
+ let code = '"' + res[i] + '"';
186
+ if (namesAndTypes[i].type.toString() == 'address') {
187
+ code = `Address.fromString(${code})`;
188
+ }
189
+ stmnts = stmnts.concat(`event.parameters.push(new ethereum.EventParam(\"${namesAndTypes[i].name}\", ${typesCodegen.ethereumFromAsc(code, namesAndTypes[i].type)}));`, `\n`);
190
+ }
191
+ klass.addMethod(tsCodegen.staticMethod(`mock${eventClassName}`, [], tsCodegen.namedType(eventClassName), `
192
+ let event = changetype<${eventClassName}>(newMockEvent());
193
+ ${stmnts}
194
+ return event;
195
+ `));
196
+ }
197
+ return [klass, paramsClass, ...tupleClasses];
198
+ });
199
+ return events.reduce(
200
+ // flatten the array
201
+ (array, classes) => array.concat(classes), []);
202
+ }
203
+ _generateInputOrOutput(inputOrOutput, index, parentClass, parentType, parentField) {
204
+ // Get name and type of the param, adjusting for indexed params and missing names
205
+ let name = inputOrOutput.get('name');
206
+ let valueType = parentType === 'event' && inputOrOutput.get('indexed')
207
+ ? this._indexedInputType(inputOrOutput.get('type'))
208
+ : inputOrOutput.get('type');
209
+ if (name === undefined || name === null || name === '') {
210
+ name = parentType === 'event' ? `param${index}` : `value${index}`;
211
+ }
212
+ // Generate getters and classes for the param (classes only created for Ethereum tuple types)
213
+ return util.containsTupleType(valueType)
214
+ ? this._generateTupleType(inputOrOutput, index, parentClass, parentType, parentField)
215
+ : {
216
+ name: [],
217
+ getter: tsCodegen.method(`get ${name}`, [], typesCodegen.ascTypeForEthereum(valueType), `
218
+ return ${typesCodegen.ethereumToAsc(util.isTupleType(parentType)
219
+ ? `this[${index}]`
220
+ : `this._${parentType}.${parentField}[${index}].value`, valueType)}
221
+ `),
222
+ classes: [],
223
+ };
224
+ }
225
+ _tupleTypeName(inputOrOutput, index, parentClass, parentType) {
226
+ return this._generateTupleType(inputOrOutput, index, parentClass, parentType, '').name;
227
+ }
228
+ _generateTupleType(inputOrOutput, index, parentClass, parentType, parentField) {
229
+ let type = inputOrOutput.get('type');
230
+ let name = inputOrOutput.get('name');
231
+ if (name === undefined || name === null || name === '') {
232
+ name = parentType === 'event' ? `param${index}` : `value${index}`;
233
+ }
234
+ let tupleIdentifier = parentClass + tsCodegen.namedType(name).capitalize();
235
+ let tupleClassName = tupleIdentifier + 'Struct';
236
+ let tupleClasses = [];
237
+ let isTupleType = util.isTupleType(type);
238
+ let returnValue = typesCodegen.ethereumToAsc(parentType === 'tuple'
239
+ ? `this[${index}]`
240
+ : `this._${parentType}.${parentField}[${index}].value`, type, tupleClassName);
241
+ // Generate getter for parent class
242
+ let tupleGetter = tsCodegen.method(`get ${name}`, [], util.isTupleMatrixType(type)
243
+ ? `Array<Array<${tupleClassName}>>`
244
+ : util.isTupleArrayType(type)
245
+ ? `Array<${tupleClassName}>`
246
+ : tupleClassName, `
247
+ return ${isTupleType ? `changetype<${tupleClassName}>(${returnValue})` : `${returnValue}`}
248
+ `);
249
+ // Generate tuple class
250
+ let baseTupleClass = tsCodegen.klass(tupleClassName, {
251
+ export: true,
252
+ extends: 'ethereum.Tuple',
253
+ });
254
+ // Add param getters to tuple class and generate classes for each tuple parameter
255
+ inputOrOutput.get('components').forEach((component, index) => {
256
+ let name = component.get('name');
257
+ let paramObject = this._generateInputOrOutput(component, index, tupleIdentifier, `tuple`);
258
+ baseTupleClass.addMethod(paramObject.getter);
259
+ tupleClasses = tupleClasses.concat(paramObject.classes);
260
+ });
261
+ // Combine all tuple classes generated
262
+ tupleClasses.unshift(baseTupleClass);
263
+ return {
264
+ name: tupleClassName,
265
+ getter: tupleGetter,
266
+ classes: tupleClasses,
267
+ };
268
+ }
269
+ _generateSmartContractClass() {
270
+ let klass = tsCodegen.klass(this.abi.name, {
271
+ export: true,
272
+ extends: 'ethereum.SmartContract',
273
+ });
274
+ let types = immutable_1.default.List();
275
+ klass.addMethod(tsCodegen.staticMethod('bind', immutable_1.default.List([
276
+ tsCodegen.param('address', typesCodegen.ascTypeForEthereum('address')),
277
+ ]), tsCodegen.namedType(this.abi.name), `
278
+ return new ${this.abi.name}('${this.abi.name}', address);
279
+ `));
280
+ // Get view/pure functions from the contract
281
+ let functions = this.callableFunctions();
282
+ // Disambiguate functions with duplicate names
283
+ functions = util.disambiguateNames({
284
+ values: functions,
285
+ getName: fn => fn.get('name'),
286
+ setName: (fn, name) => fn.set('_alias', name),
287
+ });
288
+ functions.forEach(member => {
289
+ let fnName = member.get('name');
290
+ let fnAlias = member.get('_alias');
291
+ let fnSignature = this.abi.functionSignature(member);
292
+ // Generate a type for the result of calling the function
293
+ let returnType = undefined;
294
+ let simpleReturnType = true;
295
+ let tupleResultParentType = this.abi.name + '__' + fnAlias + 'Result';
296
+ // Disambiguate outputs with duplicate names
297
+ let outputs = util.disambiguateNames({
298
+ values: member.get('outputs', immutable_1.default.List()),
299
+ getName: (input, index) => input.get('name') || `value${index}`,
300
+ setName: (input, name) => input.set('name', name),
301
+ });
302
+ if (member.get('outputs', immutable_1.default.List()).size > 1) {
303
+ simpleReturnType = false;
304
+ // Create a type dedicated to holding the return values
305
+ returnType = tsCodegen.klass(this.abi.name + '__' + fnAlias + 'Result', {
306
+ export: true,
307
+ });
308
+ // Add a constructor to this type
309
+ returnType.addMethod(tsCodegen.method('constructor', outputs.map((output, index) => tsCodegen.param(`value${index}`, this._getTupleParamType(output, index, tupleResultParentType))), null, outputs
310
+ .map((output, index) => `this.value${index} = value${index}`)
311
+ .join('\n')));
312
+ // Add a `toMap(): TypedMap<string,ethereum.Value>` function to the return type
313
+ returnType.addMethod(tsCodegen.method('toMap', [], tsCodegen.namedType('TypedMap<string,ethereum.Value>'), `
314
+ let map = new TypedMap<string,ethereum.Value>();
315
+ ${outputs
316
+ .map((output, index) => `map.set('value${index}', ${typesCodegen.ethereumFromAsc(`this.value${index}`, output.get('type'))})`)
317
+ .join(';')}
318
+ return map;
319
+ `));
320
+ // Add value0, value1 etc. members to the type
321
+ outputs
322
+ .map((output, index) => tsCodegen.klassMember(`value${index}`, this._getTupleParamType(output, index, tupleResultParentType)))
323
+ .forEach(member => returnType.addMember(member));
324
+ // Add getters to the type
325
+ outputs
326
+ .map((output, index) => !!output.get('name') &&
327
+ tsCodegen.method(`get${output.get('name')[0].toUpperCase()}${output.get('name').slice(1)}`, [], this._getTupleParamType(output, index, tupleResultParentType), `return this.value${index};`))
328
+ .forEach(method => !!method && returnType.addMethod(method));
329
+ // Create types for Tuple outputs
330
+ outputs.forEach((output, index) => {
331
+ if (util.containsTupleType(output.get('type'))) {
332
+ types = types.concat(this._generateTupleType(output, index, tupleResultParentType, 'function', this.abi.name).classes);
333
+ }
334
+ });
335
+ // Add the type to the types we'll create
336
+ types = types.push(returnType);
337
+ returnType = tsCodegen.namedType(returnType.name);
338
+ }
339
+ else {
340
+ let type = outputs.get(0).get('type');
341
+ if (util.containsTupleType(type)) {
342
+ // Add the Tuple type to the types we'll create
343
+ let tuple = this._generateTupleType(outputs.get(0), 0, tupleResultParentType, 'function', this.abi.name);
344
+ types = types.concat(tuple.classes);
345
+ returnType = util.isTupleType(type)
346
+ ? tsCodegen.namedType(tuple.name)
347
+ : `Array<${tsCodegen.namedType(tuple.name)}>`;
348
+ }
349
+ else {
350
+ returnType = tsCodegen.namedType(typesCodegen.ascTypeForEthereum(type));
351
+ }
352
+ }
353
+ // Disambiguate inputs with duplicate names
354
+ let inputs = util.disambiguateNames({
355
+ values: member.get('inputs', immutable_1.default.List()),
356
+ getName: (input, index) => input.get('name') || `param${index}`,
357
+ setName: (input, name) => input.set('name', name),
358
+ });
359
+ // Generate a type prefix to identify the Tuple inputs to a function
360
+ let tupleInputParentType = this.abi.name + '__' + fnAlias + 'Input';
361
+ // Create types for Tuple inputs
362
+ inputs.forEach((input, index) => {
363
+ if (util.containsTupleType(input.get('type'))) {
364
+ types = types.concat(this._generateTupleType(input, index, tupleInputParentType, 'function', this.abi.name).classes);
365
+ }
366
+ });
367
+ // Generate and add a method that implements calling the function on
368
+ // the smart contract
369
+ let params = inputs.map((input, index) => tsCodegen.param(input.get('name'), this._getTupleParamType(input, index, tupleInputParentType)));
370
+ let superInputs = `
371
+ '${fnName}',
372
+ '${fnSignature}',
373
+ [${inputs.size > 0
374
+ ? inputs
375
+ .map(input => typesCodegen.ethereumFromAsc(input.get('name'), input.get('type')))
376
+ .map(coercion => coercion.toString())
377
+ .join(', ')
378
+ : ''}]`;
379
+ let methodCallBody = isTry => {
380
+ const methodBody = `
381
+ ${isTry
382
+ ? `
383
+ let result = super.tryCall(${superInputs})
384
+ if (result.reverted) {
385
+ return new ethereum.CallResult()
386
+ }
387
+ let value = result.value
388
+ return ethereum.CallResult.fromValue(`
389
+ : `
390
+ let result = super.call(${superInputs})
391
+
392
+ return (`}`;
393
+ const returnVal = simpleReturnType
394
+ ? typesCodegen.ethereumToAsc(isTry ? 'value[0]' : 'result[0]', outputs.get(0).get('type'), util.isTupleArrayType(outputs.get(0).get('type'))
395
+ ? this._tupleTypeName(outputs.get(0), 0, tupleResultParentType, this.abi.name)
396
+ : '')
397
+ : `new ${returnType.name}(
398
+ ${outputs
399
+ .map((output, index) => {
400
+ const val = typesCodegen.ethereumToAsc(isTry ? `value[${index}]` : `result[${index}]`, output.get('type'), util.isTupleArrayType(output.get('type'))
401
+ ? this._tupleTypeName(output, index, tupleResultParentType, this.abi.name)
402
+ : '');
403
+ return util.isTupleType(output.get('type'))
404
+ ? `changetype<${this._tupleTypeName(output, index, tupleResultParentType, this.abi.name)}>(${val})`
405
+ : val;
406
+ })
407
+ .join(', ')}
408
+ )`;
409
+ const isTuple = util.isTupleType(outputs.get(0).get('type'));
410
+ return `${methodBody} ${isTuple ? `changetype<${returnType}>(${returnVal})` : returnVal})`;
411
+ };
412
+ // Generate method with an without `try_`.
413
+ klass.addMethod(tsCodegen.method(fnAlias, params, returnType, methodCallBody(false)));
414
+ klass.addMethod(tsCodegen.method('try_' + fnAlias, params, 'ethereum.CallResult<' + returnType + '>', methodCallBody(true)));
415
+ });
416
+ return [...types, klass];
417
+ }
418
+ _getTupleParamType(inputOrOutput, index, tupleParentType) {
419
+ const type = inputOrOutput.get('type');
420
+ return util.isTupleType(type)
421
+ ? this._tupleTypeName(inputOrOutput, index, tupleParentType, this.abi.name)
422
+ : util.isTupleMatrixType(type)
423
+ ? `Array<Array<${this._tupleTypeName(inputOrOutput, index, tupleParentType, this.abi.name)}>>`
424
+ : util.isTupleArrayType(type)
425
+ ? `Array<${this._tupleTypeName(inputOrOutput, index, tupleParentType, this.abi.name)}>`
426
+ : typesCodegen.ascTypeForEthereum(type);
427
+ }
428
+ _indexedInputType(inputType) {
429
+ // strings, bytes and arrays are encoded and hashed to a bytes32 value
430
+ if (inputType === 'string' ||
431
+ inputType === 'bytes' ||
432
+ inputType === 'tuple' ||
433
+ // the following matches arrays of the forms `uint256[]` and `uint256[12356789]`;
434
+ // the value type name doesn't matter here, just that the type name ends with
435
+ // brackets and, optionally, a number inside the brackets
436
+ inputType.match(/\[[0-9]*\]$/g)) {
437
+ return 'bytes32';
438
+ }
439
+ else {
440
+ return inputType;
441
+ }
442
+ }
443
+ callableFunctions() {
444
+ let allowedMutability = ['view', 'pure', 'nonpayable', 'constant'];
445
+ return this.abi.data.filter(member => member.get('type') === 'function' &&
446
+ member.get('outputs', immutable_1.default.List()).size !== 0 &&
447
+ (allowedMutability.includes(member.get('stateMutability')) ||
448
+ (member.get('stateMutability') === undefined && !member.get('payable', false))));
449
+ }
450
+ }
451
+ exports.default = AbiCodeGenerator;