@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,505 @@
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 abi_1 = __importDefault(require("../protocols/ethereum/abi"));
7
+ const immutable_1 = __importDefault(require("immutable"));
8
+ const _1 = __importDefault(require("./"));
9
+ const protocols_1 = __importDefault(require("../protocols"));
10
+ const TEST_EVENT = {
11
+ name: 'ExampleEvent',
12
+ type: 'event',
13
+ inputs: [
14
+ { name: 'a', type: 'uint256', indexed: true },
15
+ { name: 'b', type: 'bytes[4]' },
16
+ { type: 'string' },
17
+ {
18
+ name: 'c',
19
+ type: 'tuple',
20
+ components: [
21
+ { name: 'c1', type: 'uint256' },
22
+ { type: 'bytes32' },
23
+ { type: 'string' },
24
+ {
25
+ name: 'c3',
26
+ type: 'tuple',
27
+ components: [
28
+ { name: 'c31', type: 'uint96' },
29
+ { type: 'string' },
30
+ { type: 'bytes32' },
31
+ ],
32
+ },
33
+ ],
34
+ },
35
+ { name: 'd', type: 'string', indexed: true },
36
+ ],
37
+ };
38
+ const OVERLOADED_EVENT = {
39
+ name: 'ExampleEvent',
40
+ type: 'event',
41
+ inputs: [{ name: 'a', type: 'bytes32' }],
42
+ };
43
+ const TEST_CONTRACT = {
44
+ name: 'ExampleContract',
45
+ type: 'contract',
46
+ };
47
+ const TEST_CALLABLE_FUNCTIONS = [
48
+ {
49
+ name: 'someVariable',
50
+ type: 'function',
51
+ stateMutability: 'view',
52
+ outputs: [{ type: 'uint256' }],
53
+ },
54
+ {
55
+ name: 'getSomeValue',
56
+ type: 'function',
57
+ stateMutability: 'pure',
58
+ outputs: [{ type: 'tuple', components: [{ type: 'uint256' }] }],
59
+ },
60
+ ];
61
+ const TEST_ABI = new abi_1.default('Contract', undefined, immutable_1.default.fromJS([
62
+ TEST_EVENT,
63
+ OVERLOADED_EVENT,
64
+ TEST_CONTRACT,
65
+ ...TEST_CALLABLE_FUNCTIONS,
66
+ ]));
67
+ const protocol = new protocols_1.default('ethereum');
68
+ const scaffoldOptions = {
69
+ protocol,
70
+ abi: TEST_ABI,
71
+ contract: '0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d',
72
+ network: 'kovan',
73
+ contractName: 'Contract',
74
+ };
75
+ const scaffold = new _1.default(scaffoldOptions);
76
+ const scaffoldWithIndexEvents = new _1.default({
77
+ ...scaffoldOptions,
78
+ indexEvents: true,
79
+ });
80
+ describe('Ethereum subgraph scaffolding', () => {
81
+ test('Manifest', () => {
82
+ expect(scaffold.generateManifest()).toEqual(`\
83
+ specVersion: 0.0.5
84
+ schema:
85
+ file: ./schema.graphql
86
+ dataSources:
87
+ - kind: ethereum
88
+ name: Contract
89
+ network: kovan
90
+ source:
91
+ address: "0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d"
92
+ abi: Contract
93
+ mapping:
94
+ kind: ethereum/events
95
+ apiVersion: 0.0.7
96
+ language: wasm/assemblyscript
97
+ entities:
98
+ - ExampleEvent
99
+ - ExampleEvent1
100
+ abis:
101
+ - name: Contract
102
+ file: ./abis/Contract.json
103
+ eventHandlers:
104
+ - event: ExampleEvent(indexed uint256,bytes[4],string,(uint256,bytes32,string,(uint96,string,bytes32)),indexed string)
105
+ handler: handleExampleEvent
106
+ - event: ExampleEvent(bytes32)
107
+ handler: handleExampleEvent1
108
+ file: ./src/contract.ts
109
+ `);
110
+ });
111
+ test('Schema (default)', () => {
112
+ expect(scaffold.generateSchema()).toEqual(`\
113
+ type ExampleEntity @entity {
114
+ id: Bytes!
115
+ count: BigInt!
116
+ a: BigInt! # uint256
117
+ b: [Bytes]! # bytes[4]
118
+ }
119
+ `);
120
+ });
121
+ test('Schema (for indexing events)', () => {
122
+ expect(scaffoldWithIndexEvents.generateSchema()).toEqual(`\
123
+ type ExampleEvent @entity(immutable: true) {
124
+ id: Bytes!
125
+ a: BigInt! # uint256
126
+ b: [Bytes]! # bytes[4]
127
+ param2: String! # string
128
+ c_c1: BigInt! # uint256
129
+ c_value1: Bytes! # bytes32
130
+ c_value2: String! # string
131
+ c_c3_c31: BigInt! # uint96
132
+ c_c3_value1: String! # string
133
+ c_c3_value2: Bytes! # bytes32
134
+ d: String! # string
135
+ blockNumber: BigInt!
136
+ blockTimestamp: BigInt!
137
+ transactionHash: Bytes!
138
+ }
139
+
140
+ type ExampleEvent1 @entity(immutable: true) {
141
+ id: Bytes!
142
+ a: Bytes! # bytes32
143
+ blockNumber: BigInt!
144
+ blockTimestamp: BigInt!
145
+ transactionHash: Bytes!
146
+ }
147
+ `);
148
+ });
149
+ test('Mapping (default)', () => {
150
+ expect(scaffold.generateMapping()).toEqual(`\
151
+ import { BigInt } from "@graphprotocol/graph-ts"
152
+ import {
153
+ Contract,
154
+ ExampleEvent,
155
+ ExampleEvent1
156
+ } from "../generated/Contract/Contract"
157
+ import { ExampleEntity } from "../generated/schema"
158
+
159
+ export function handleExampleEvent(event: ExampleEvent): void {
160
+ // Entities can be loaded from the store using a string ID; this ID
161
+ // needs to be unique across all entities of the same type
162
+ let entity = ExampleEntity.load(event.transaction.from)
163
+
164
+ // Entities only exist after they have been saved to the store;
165
+ // \`null\` checks allow to create entities on demand
166
+ if (!entity) {
167
+ entity = new ExampleEntity(event.transaction.from)
168
+
169
+ // Entity fields can be set using simple assignments
170
+ entity.count = BigInt.fromI32(0)
171
+ }
172
+
173
+ // BigInt and BigDecimal math are supported
174
+ entity.count = entity.count + BigInt.fromI32(1)
175
+
176
+ // Entity fields can be set based on event parameters
177
+ entity.a = event.params.a
178
+ entity.b = event.params.b
179
+
180
+ // Entities can be written to the store with \`.save()\`
181
+ entity.save()
182
+
183
+ // Note: If a handler doesn't require existing field values, it is faster
184
+ // _not_ to load the entity from the store. Instead, create it fresh with
185
+ // \`new Entity(...)\`, set the fields that should be updated and save the
186
+ // entity back to the store. Fields that were not set or unset remain
187
+ // unchanged, allowing for partial updates to be applied.
188
+
189
+ // It is also possible to access smart contracts from mappings. For
190
+ // example, the contract that has emitted the event can be connected to
191
+ // with:
192
+ //
193
+ // let contract = Contract.bind(event.address)
194
+ //
195
+ // The following functions can then be called on this contract to access
196
+ // state variables and other data:
197
+ //
198
+ // - contract.someVariable(...)
199
+ // - contract.getSomeValue(...)
200
+ }
201
+
202
+ export function handleExampleEvent1(event: ExampleEvent1): void {}
203
+ `);
204
+ });
205
+ test('Mapping (for indexing events)', () => {
206
+ expect(scaffoldWithIndexEvents.generateMapping()).toEqual(`\
207
+ import {
208
+ ExampleEvent as ExampleEventEvent,
209
+ ExampleEvent1 as ExampleEvent1Event
210
+ } from "../generated/Contract/Contract"
211
+ import { ExampleEvent, ExampleEvent1 } from "../generated/schema"
212
+
213
+ export function handleExampleEvent(event: ExampleEventEvent): void {
214
+ let entity = new ExampleEvent(
215
+ event.transaction.hash.concatI32(event.logIndex.toI32())
216
+ )
217
+ entity.a = event.params.a
218
+ entity.b = event.params.b
219
+ entity.param2 = event.params.param2
220
+ entity.c_c1 = event.params.c.c1
221
+ entity.c_value1 = event.params.c.value1
222
+ entity.c_value2 = event.params.c.value2
223
+ entity.c_c3_c31 = event.params.c.c3.c31
224
+ entity.c_c3_value1 = event.params.c.c3.value1
225
+ entity.c_c3_value2 = event.params.c.c3.value2
226
+ entity.d = event.params.d
227
+
228
+ entity.blockNumber = event.block.number
229
+ entity.blockTimestamp = event.block.timestamp
230
+ entity.transactionHash = event.transaction.hash
231
+
232
+ entity.save()
233
+ }
234
+
235
+ export function handleExampleEvent1(event: ExampleEvent1Event): void {
236
+ let entity = new ExampleEvent1(
237
+ event.transaction.hash.concatI32(event.logIndex.toI32())
238
+ )
239
+ entity.a = event.params.a
240
+
241
+ entity.blockNumber = event.block.number
242
+ entity.blockTimestamp = event.block.timestamp
243
+ entity.transactionHash = event.transaction.hash
244
+
245
+ entity.save()
246
+ }
247
+ `);
248
+ });
249
+ test('Test Files (default)', () => {
250
+ const files = scaffoldWithIndexEvents.generateTests();
251
+ const testFile = files['contract.test.ts'];
252
+ const utilsFile = files['contract-utils.ts'];
253
+ expect(testFile).toEqual(`\
254
+ import {
255
+ assert,
256
+ describe,
257
+ test,
258
+ clearStore,
259
+ beforeAll,
260
+ afterAll
261
+ } from \"matchstick-as/assembly/index\"
262
+ import { BigInt, Bytes } from \"@graphprotocol/graph-ts\"
263
+ import { ExampleEvent } from \"../generated/schema\"
264
+ import { ExampleEvent as ExampleEventEvent } from \"../generated/Contract/Contract\"
265
+ import { handleExampleEvent } from \"../src/contract\"
266
+ import { createExampleEventEvent } from \"./contract-utils\"
267
+
268
+ // Tests structure (matchstick-as >=0.5.0)
269
+ // https://thegraph.com/docs/en/developer/matchstick/#tests-structure-0-5-0
270
+
271
+ describe(\"Describe entity assertions\", () => {
272
+ beforeAll(() => {
273
+ let a = BigInt.fromI32(234)
274
+ let b = [Bytes.fromI32(1234567890)]
275
+ let param2 = \"Example string value\"
276
+ let c = \"ethereum.Tuple Not implemented\"
277
+ let d = \"Example string value\"
278
+ let newExampleEventEvent = createExampleEventEvent(a, b, param2, c, d)
279
+ handleExampleEvent(newExampleEventEvent)
280
+ })
281
+
282
+ afterAll(() => {
283
+ clearStore()
284
+ })
285
+
286
+ // For more test scenarios, see:
287
+ // https://thegraph.com/docs/en/developer/matchstick/#write-a-unit-test
288
+
289
+ test(\"ExampleEvent created and stored\", () => {
290
+ assert.entityCount(\"ExampleEvent\", 1)
291
+
292
+ // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function
293
+ assert.fieldEquals(
294
+ \"ExampleEvent\",
295
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
296
+ \"a\",
297
+ \"234\"
298
+ )
299
+ assert.fieldEquals(
300
+ \"ExampleEvent\",
301
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
302
+ \"b\",
303
+ \"[1234567890]\"
304
+ )
305
+ assert.fieldEquals(
306
+ \"ExampleEvent\",
307
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
308
+ \"param2\",
309
+ \"Example string value\"
310
+ )
311
+ assert.fieldEquals(
312
+ \"ExampleEvent\",
313
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
314
+ \"c\",
315
+ \"ethereum.Tuple Not implemented\"
316
+ )
317
+ assert.fieldEquals(
318
+ \"ExampleEvent\",
319
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
320
+ \"d\",
321
+ \"Example string value\"
322
+ )
323
+
324
+ // More assert options:
325
+ // https://thegraph.com/docs/en/developer/matchstick/#asserts
326
+ })
327
+ })
328
+ `);
329
+ expect(utilsFile).toEqual(`\
330
+ import { newMockEvent } from \"matchstick-as\"
331
+ import { ethereum, BigInt, Bytes } from \"@graphprotocol/graph-ts\"
332
+ import { ExampleEvent, ExampleEvent1 } from \"../generated/Contract/Contract\"
333
+
334
+ export function createExampleEventEvent(
335
+ a: BigInt,
336
+ b: Array<Bytes>,
337
+ param2: string,
338
+ c: ethereum.Tuple,
339
+ d: string
340
+ ): ExampleEvent {
341
+ let exampleEventEvent = changetype<ExampleEvent>(newMockEvent())
342
+
343
+ exampleEventEvent.parameters = new Array()
344
+
345
+ exampleEventEvent.parameters.push(
346
+ new ethereum.EventParam(\"a\", ethereum.Value.fromUnsignedBigInt(a))
347
+ )
348
+ exampleEventEvent.parameters.push(
349
+ new ethereum.EventParam(\"b\", ethereum.Value.fromBytesArray(b))
350
+ )
351
+ exampleEventEvent.parameters.push(
352
+ new ethereum.EventParam(\"param2\", ethereum.Value.fromString(param2))
353
+ )
354
+ exampleEventEvent.parameters.push(
355
+ new ethereum.EventParam(\"c\", ethereum.Value.fromTuple(c))
356
+ )
357
+ exampleEventEvent.parameters.push(
358
+ new ethereum.EventParam(\"d\", ethereum.Value.fromString(d))
359
+ )
360
+
361
+ return exampleEventEvent
362
+ }
363
+
364
+ export function createExampleEvent1Event(a: Bytes): ExampleEvent1 {
365
+ let exampleEvent1Event = changetype<ExampleEvent1>(newMockEvent())
366
+
367
+ exampleEvent1Event.parameters = new Array()
368
+
369
+ exampleEvent1Event.parameters.push(
370
+ new ethereum.EventParam(\"a\", ethereum.Value.fromFixedBytes(a))
371
+ )
372
+
373
+ return exampleEvent1Event
374
+ }
375
+ `);
376
+ });
377
+ test('Test Files (for indexing events)', () => {
378
+ const files = scaffoldWithIndexEvents.generateTests();
379
+ const testFile = files['contract.test.ts'];
380
+ const utilsFile = files['contract-utils.ts'];
381
+ expect(testFile).toEqual(`\
382
+ import {
383
+ assert,
384
+ describe,
385
+ test,
386
+ clearStore,
387
+ beforeAll,
388
+ afterAll
389
+ } from \"matchstick-as/assembly/index\"
390
+ import { BigInt, Bytes } from \"@graphprotocol/graph-ts\"
391
+ import { ExampleEvent } from \"../generated/schema\"
392
+ import { ExampleEvent as ExampleEventEvent } from \"../generated/Contract/Contract\"
393
+ import { handleExampleEvent } from \"../src/contract\"
394
+ import { createExampleEventEvent } from \"./contract-utils\"
395
+
396
+ // Tests structure (matchstick-as >=0.5.0)
397
+ // https://thegraph.com/docs/en/developer/matchstick/#tests-structure-0-5-0
398
+
399
+ describe(\"Describe entity assertions\", () => {
400
+ beforeAll(() => {
401
+ let a = BigInt.fromI32(234)
402
+ let b = [Bytes.fromI32(1234567890)]
403
+ let param2 = \"Example string value\"
404
+ let c = \"ethereum.Tuple Not implemented\"
405
+ let d = \"Example string value\"
406
+ let newExampleEventEvent = createExampleEventEvent(a, b, param2, c, d)
407
+ handleExampleEvent(newExampleEventEvent)
408
+ })
409
+
410
+ afterAll(() => {
411
+ clearStore()
412
+ })
413
+
414
+ // For more test scenarios, see:
415
+ // https://thegraph.com/docs/en/developer/matchstick/#write-a-unit-test
416
+
417
+ test(\"ExampleEvent created and stored\", () => {
418
+ assert.entityCount(\"ExampleEvent\", 1)
419
+
420
+ // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function
421
+ assert.fieldEquals(
422
+ \"ExampleEvent\",
423
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
424
+ \"a\",
425
+ \"234\"
426
+ )
427
+ assert.fieldEquals(
428
+ \"ExampleEvent\",
429
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
430
+ \"b\",
431
+ \"[1234567890]\"
432
+ )
433
+ assert.fieldEquals(
434
+ \"ExampleEvent\",
435
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
436
+ \"param2\",
437
+ \"Example string value\"
438
+ )
439
+ assert.fieldEquals(
440
+ \"ExampleEvent\",
441
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
442
+ \"c\",
443
+ \"ethereum.Tuple Not implemented\"
444
+ )
445
+ assert.fieldEquals(
446
+ \"ExampleEvent\",
447
+ \"0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1\",
448
+ \"d\",
449
+ \"Example string value\"
450
+ )
451
+
452
+ // More assert options:
453
+ // https://thegraph.com/docs/en/developer/matchstick/#asserts
454
+ })
455
+ })
456
+ `);
457
+ expect(utilsFile).toEqual(`\
458
+ import { newMockEvent } from \"matchstick-as\"
459
+ import { ethereum, BigInt, Bytes } from \"@graphprotocol/graph-ts\"
460
+ import { ExampleEvent, ExampleEvent1 } from \"../generated/Contract/Contract\"
461
+
462
+ export function createExampleEventEvent(
463
+ a: BigInt,
464
+ b: Array<Bytes>,
465
+ param2: string,
466
+ c: ethereum.Tuple,
467
+ d: string
468
+ ): ExampleEvent {
469
+ let exampleEventEvent = changetype<ExampleEvent>(newMockEvent())
470
+
471
+ exampleEventEvent.parameters = new Array()
472
+
473
+ exampleEventEvent.parameters.push(
474
+ new ethereum.EventParam(\"a\", ethereum.Value.fromUnsignedBigInt(a))
475
+ )
476
+ exampleEventEvent.parameters.push(
477
+ new ethereum.EventParam(\"b\", ethereum.Value.fromBytesArray(b))
478
+ )
479
+ exampleEventEvent.parameters.push(
480
+ new ethereum.EventParam(\"param2\", ethereum.Value.fromString(param2))
481
+ )
482
+ exampleEventEvent.parameters.push(
483
+ new ethereum.EventParam(\"c\", ethereum.Value.fromTuple(c))
484
+ )
485
+ exampleEventEvent.parameters.push(
486
+ new ethereum.EventParam(\"d\", ethereum.Value.fromString(d))
487
+ )
488
+
489
+ return exampleEventEvent
490
+ }
491
+
492
+ export function createExampleEvent1Event(a: Bytes): ExampleEvent1 {
493
+ let exampleEvent1Event = changetype<ExampleEvent1>(newMockEvent())
494
+
495
+ exampleEvent1Event.parameters = new Array()
496
+
497
+ exampleEvent1Event.parameters.push(
498
+ new ethereum.EventParam(\"a\", ethereum.Value.fromFixedBytes(a))
499
+ )
500
+
501
+ return exampleEvent1Event
502
+ }
503
+ `);
504
+ });
505
+ });
@@ -0,0 +1,128 @@
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 prettier_1 = __importDefault(require("prettier"));
7
+ const pkginfo = require('pkginfo')(module);
8
+ const gluegun_1 = require("gluegun");
9
+ const GRAPH_CLI_VERSION = process.env.GRAPH_CLI_TESTS
10
+ ? // JSON.stringify should remove this key, we will install the local
11
+ // graph-cli for the tests using `npm link` instead of fetching from npm.
12
+ undefined
13
+ : // For scaffolding real subgraphs
14
+ `${module.exports.version}`;
15
+ const schema_1 = require("./schema");
16
+ const mapping_1 = require("./mapping");
17
+ const tests_1 = require("./tests");
18
+ const subgraph_1 = require("../command-helpers/subgraph");
19
+ class Scaffold {
20
+ constructor(options = {}) {
21
+ this.protocol = options.protocol;
22
+ this.abi = options.abi;
23
+ this.indexEvents = options.indexEvents;
24
+ this.contract = options.contract;
25
+ this.network = options.network;
26
+ this.contractName = options.contractName;
27
+ this.subgraphName = options.subgraphName;
28
+ this.node = options.node;
29
+ }
30
+ generatePackageJson() {
31
+ return prettier_1.default.format(JSON.stringify({
32
+ name: (0, subgraph_1.getSubgraphBasename)(this.subgraphName),
33
+ license: 'UNLICENSED',
34
+ scripts: {
35
+ codegen: 'graph codegen',
36
+ build: 'graph build',
37
+ deploy: `graph deploy ` + `--node ${this.node} ` + this.subgraphName,
38
+ 'create-local': `graph create --node http://localhost:8020/ ${this.subgraphName}`,
39
+ 'remove-local': `graph remove --node http://localhost:8020/ ${this.subgraphName}`,
40
+ 'deploy-local': `graph deploy ` +
41
+ `--node http://localhost:8020/ ` +
42
+ `--ipfs http://localhost:5001 ` +
43
+ this.subgraphName,
44
+ test: 'graph test',
45
+ },
46
+ dependencies: {
47
+ '@graphprotocol/graph-cli': GRAPH_CLI_VERSION,
48
+ '@graphprotocol/graph-ts': `0.29.1`,
49
+ },
50
+ devDependencies: this.protocol.hasEvents()
51
+ ? { 'matchstick-as': `0.5.0` }
52
+ : undefined,
53
+ }), { parser: 'json' });
54
+ }
55
+ generateManifest() {
56
+ const protocolManifest = this.protocol.getManifestScaffold();
57
+ return prettier_1.default.format(`
58
+ specVersion: 0.0.5
59
+ schema:
60
+ file: ./schema.graphql
61
+ dataSources:
62
+ - kind: ${this.protocol.name}
63
+ name: ${this.contractName}
64
+ network: ${this.network}
65
+ source: ${protocolManifest.source(this)}
66
+ mapping: ${protocolManifest.mapping(this)}
67
+ `, { parser: 'yaml' });
68
+ }
69
+ generateSchema() {
70
+ const hasEvents = this.protocol.hasEvents();
71
+ const events = hasEvents ? (0, schema_1.abiEvents)(this.abi).toJS() : [];
72
+ return prettier_1.default.format(hasEvents && this.indexEvents
73
+ ? events.map(event => (0, schema_1.generateEventType)(event, this.protocol.name)).join('\n\n')
74
+ : (0, schema_1.generateExampleEntityType)(this.protocol, events), {
75
+ parser: 'graphql',
76
+ });
77
+ }
78
+ generateTsConfig() {
79
+ return prettier_1.default.format(JSON.stringify({
80
+ extends: '@graphprotocol/graph-ts/types/tsconfig.base.json',
81
+ include: ['src'],
82
+ }), { parser: 'json' });
83
+ }
84
+ generateMappings() {
85
+ return this.protocol.getMappingScaffold()
86
+ ? { [`${gluegun_1.strings.kebabCase(this.contractName)}.ts`]: this.generateMapping() }
87
+ : undefined;
88
+ }
89
+ generateMapping() {
90
+ const hasEvents = this.protocol.hasEvents();
91
+ const events = hasEvents ? (0, schema_1.abiEvents)(this.abi).toJS() : [];
92
+ const protocolMapping = this.protocol.getMappingScaffold();
93
+ return prettier_1.default.format(hasEvents && this.indexEvents
94
+ ? (0, mapping_1.generateEventIndexingHandlers)(events, this.contractName)
95
+ : protocolMapping.generatePlaceholderHandlers({
96
+ ...this,
97
+ events,
98
+ }), { parser: 'typescript', semi: false });
99
+ }
100
+ generateABIs() {
101
+ return this.protocol.hasABIs()
102
+ ? {
103
+ [`${this.contractName}.json`]: prettier_1.default.format(JSON.stringify(this.abi.data), {
104
+ parser: 'json',
105
+ }),
106
+ }
107
+ : undefined;
108
+ }
109
+ generateTests() {
110
+ const hasEvents = this.protocol.hasEvents();
111
+ const events = hasEvents ? (0, schema_1.abiEvents)(this.abi).toJS() : [];
112
+ return events.length > 0
113
+ ? (0, tests_1.generateTestsFiles)(this.contractName, events, this.indexEvents)
114
+ : undefined;
115
+ }
116
+ generate() {
117
+ return {
118
+ 'package.json': this.generatePackageJson(),
119
+ 'subgraph.yaml': this.generateManifest(),
120
+ 'schema.graphql': this.generateSchema(),
121
+ 'tsconfig.json': this.generateTsConfig(),
122
+ src: this.generateMappings(),
123
+ abis: this.generateABIs(),
124
+ tests: this.generateTests(),
125
+ };
126
+ }
127
+ }
128
+ exports.default = Scaffold;
@@ -0,0 +1,61 @@
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
+ exports.generateEventIndexingHandlers = exports.generateEventFieldAssignments = exports.generateFieldAssignments = exports.generateFieldAssignment = void 0;
30
+ const path_1 = __importDefault(require("path"));
31
+ const util = __importStar(require("../codegen/util"));
32
+ const generateFieldAssignment = path => `entity.${path.join('_')} = event.params.${path.join('.')}`;
33
+ exports.generateFieldAssignment = generateFieldAssignment;
34
+ const generateFieldAssignments = ({ index, input }) => input.type === 'tuple'
35
+ ? util
36
+ .unrollTuple({ value: input, index, path: [input.name || `param${index}`] })
37
+ .map(({ path }) => generateFieldAssignment(path))
38
+ : generateFieldAssignment([input.name || `param${index}`]);
39
+ exports.generateFieldAssignments = generateFieldAssignments;
40
+ const generateEventFieldAssignments = event => event.inputs.reduce((acc, input, index) => acc.concat(generateFieldAssignments({ input, index })), []);
41
+ exports.generateEventFieldAssignments = generateEventFieldAssignments;
42
+ const generateEventIndexingHandlers = (events, contractName) => `
43
+ import { ${events.map(event => `${event._alias} as ${event._alias}Event`)}} from '../generated/${contractName}/${contractName}'
44
+ import { ${events.map(event => event._alias)} } from '../generated/schema'
45
+
46
+ ${events
47
+ .map(event => `
48
+ export function handle${event._alias}(event: ${event._alias}Event): void {
49
+ let entity = new ${event._alias}(event.transaction.hash.concatI32(event.logIndex.toI32()))
50
+ ${generateEventFieldAssignments(event).join('\n')}
51
+
52
+ entity.blockNumber = event.block.number
53
+ entity.blockTimestamp = event.block.timestamp
54
+ entity.transactionHash = event.transaction.hash
55
+
56
+ entity.save()
57
+ }
58
+ `)
59
+ .join('\n')}
60
+ `;
61
+ exports.generateEventIndexingHandlers = generateEventIndexingHandlers;