@graphprotocol/graph-cli 0.29.2 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/arweave.ts +76 -0
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/cosmos.ts +341 -0
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/ethereum.ts +39 -0
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/global/global.ts +286 -142
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/index.ts +4 -2
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/package.json +2 -1
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/test/test.js +4 -2
- package/examples/basic-event-handlers/node_modules/keccak/build/config.gypi +300 -125
- package/examples/basic-event-handlers/node_modules/websocket/build/config.gypi +292 -15
- package/examples/basic-event-handlers/package.json +1 -1
- package/examples/basic-event-handlers/yarn.lock +4 -4
- package/examples/example-subgraph/package.json +1 -1
- package/examples/example-subgraph/yarn.lock +4 -4
- package/package.json +1 -1
- package/resources/test/docker-compose.yml +4 -2
- package/src/codegen/schema.js +5 -1
- package/src/codegen/schema.test.js +102 -0
- package/src/command-helpers/abi.js +69 -0
- package/src/command-helpers/scaffold.js +67 -0
- package/src/commands/add.js +198 -0
- package/src/commands/deploy.js +0 -5
- package/src/commands/init.js +25 -71
- package/src/migrations/mapping_api_version_0_0_5.js +1 -1
- package/src/migrations/mapping_api_version_0_0_6.js +74 -0
- package/src/migrations/spec_version_0_0_2.js +1 -1
- package/src/migrations/spec_version_0_0_3.js +29 -0
- package/src/migrations/spec_version_0_0_4.js +25 -0
- package/src/migrations.js +4 -0
- package/src/protocols/arweave/manifest.graphql +57 -0
- package/src/protocols/arweave/scaffold/manifest.js +19 -0
- package/src/protocols/arweave/scaffold/mapping.js +53 -0
- package/src/protocols/arweave/subgraph.js +20 -0
- package/src/protocols/{tendermint → cosmos}/manifest.graphql +6 -0
- package/src/protocols/cosmos/scaffold/manifest.js +16 -0
- package/src/protocols/cosmos/scaffold/mapping.js +39 -0
- package/src/protocols/{tendermint → cosmos}/subgraph.js +2 -1
- package/src/protocols/ethereum/codegen/abi.js +12 -0
- package/src/protocols/ethereum/manifest.graphql +2 -0
- package/src/protocols/ethereum/scaffold/manifest.js +2 -1
- package/src/protocols/index.js +53 -20
- package/src/protocols/near/manifest.graphql +1 -0
- package/src/protocols/near/scaffold/manifest.js +4 -2
- package/src/scaffold/cosmos.test.js +86 -0
- package/src/scaffold/ethereum.test.js +2 -1
- package/src/scaffold/index.js +5 -3
- package/src/scaffold/near.test.js +2 -1
- package/src/validation/manifest.js +64 -12
- package/src/validation/schema.js +2 -0
- package/tests/cli/validation/conflicting-protocol-names/Abi.json +7 -0
- package/tests/cli/validation/conflicting-protocol-names/mapping.ts +0 -0
- package/tests/cli/validation/conflicting-protocol-names/schema.graphql +3 -0
- package/tests/cli/validation/conflicting-protocol-names/subgraph.yaml +41 -0
- package/tests/cli/validation/conflicting-protocol-names.stderr +10 -0
- package/tests/cli/validation.test.js +9 -0
- package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/tendermint.ts +0 -554
- package/examples/basic-event-handlers/node_modules/keccak/build/Makefile +0 -342
- package/examples/basic-event-handlers/node_modules/keccak/build/Release/.deps/Release/obj.target/keccak/src/addon.o.d.raw +0 -27
- package/examples/basic-event-handlers/node_modules/keccak/build/binding.Makefile +0 -6
- package/examples/basic-event-handlers/node_modules/keccak/build/gyp-mac-tool +0 -615
- package/examples/basic-event-handlers/node_modules/keccak/build/keccak.target.mk +0 -209
- package/examples/basic-event-handlers/node_modules/websocket/build/Makefile +0 -347
- package/examples/basic-event-handlers/node_modules/websocket/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d.raw +0 -25
- package/examples/basic-event-handlers/node_modules/websocket/build/binding.Makefile +0 -6
- package/examples/basic-event-handlers/node_modules/websocket/build/bufferutil.target.mk +0 -192
- package/examples/basic-event-handlers/node_modules/websocket/build/gyp-mac-tool +0 -615
- package/examples/basic-event-handlers/node_modules/websocket/build/validation.target.mk +0 -192
- package/src/codegen/types/defaults.js +0 -34
- package/tests/cli/init/ethereum/from-example/.gitattributes +0 -1
- package/tests/cli/init/ethereum/from-example/LICENSE +0 -21
- package/tests/cli/init/ethereum/from-example/README.md +0 -3
- package/tests/cli/init/ethereum/from-example/abis/Gravity.json +0 -1
- package/tests/cli/init/ethereum/from-example/bin/Counter.bin +0 -1
- package/tests/cli/init/ethereum/from-example/contracts/Gravity.sol +0 -63
- package/tests/cli/init/ethereum/from-example/contracts/Migrations.sol +0 -23
- package/tests/cli/init/ethereum/from-example/docker-compose.yml +0 -39
- package/tests/cli/init/ethereum/from-example/migrations/1_initial_migration.js +0 -5
- package/tests/cli/init/ethereum/from-example/migrations/2_deploy_contract.js +0 -5
- package/tests/cli/init/ethereum/from-example/migrations/3_create_gravatars.js +0 -15
- package/tests/cli/init/ethereum/from-example/networks.json +0 -7
- package/tests/cli/init/ethereum/from-example/package.json +0 -23
- package/tests/cli/init/ethereum/from-example/schema.graphql +0 -6
- package/tests/cli/init/ethereum/from-example/src/mapping.ts +0 -22
- package/tests/cli/init/ethereum/from-example/subgraph.yaml +0 -27
- package/tests/cli/init/ethereum/from-example/truffle.js +0 -27
- package/tests/cli/init/ethereum/from-example/yarn.lock +0 -5977
|
@@ -1,8 +1,28 @@
|
|
|
1
1
|
const fs = require('fs-extra')
|
|
2
2
|
const path = require('path')
|
|
3
|
+
const prettier = require('prettier')
|
|
4
|
+
const yaml = require('yaml')
|
|
3
5
|
|
|
4
6
|
const { step } = require('./spinner')
|
|
5
7
|
const Scaffold = require('../scaffold')
|
|
8
|
+
const { generateEventIndexingHandlers } = require('../scaffold/mapping')
|
|
9
|
+
const { generateEventType, abiEvents } = require('../scaffold/schema')
|
|
10
|
+
const { strings } = require('gluegun')
|
|
11
|
+
const { Map } = require('immutable')
|
|
12
|
+
|
|
13
|
+
const generateDataSource = async (protocol, contractName, network, contractAddress, abi) => {
|
|
14
|
+
const protocolManifest = protocol.getManifestScaffold()
|
|
15
|
+
|
|
16
|
+
return Map.of(
|
|
17
|
+
'kind', protocol.name,
|
|
18
|
+
'name', contractName,
|
|
19
|
+
'network', network,
|
|
20
|
+
'source', yaml.parse(prettier.format(protocolManifest.source({contract: contractAddress, contractName}),
|
|
21
|
+
{parser: 'yaml'})),
|
|
22
|
+
'mapping', yaml.parse(prettier.format(protocolManifest.mapping({abi, contractName}),
|
|
23
|
+
{parser: 'yaml'}))
|
|
24
|
+
).asMutable()
|
|
25
|
+
}
|
|
6
26
|
|
|
7
27
|
const generateScaffold = async (
|
|
8
28
|
{
|
|
@@ -13,6 +33,7 @@ const generateScaffold = async (
|
|
|
13
33
|
subgraphName,
|
|
14
34
|
indexEvents,
|
|
15
35
|
contractName = 'Contract',
|
|
36
|
+
dataSourceName,
|
|
16
37
|
node,
|
|
17
38
|
},
|
|
18
39
|
spinner,
|
|
@@ -27,6 +48,7 @@ const generateScaffold = async (
|
|
|
27
48
|
network,
|
|
28
49
|
contractName,
|
|
29
50
|
subgraphName,
|
|
51
|
+
dataSourceName,
|
|
30
52
|
node,
|
|
31
53
|
})
|
|
32
54
|
|
|
@@ -59,8 +81,53 @@ const writeScaffold = async (scaffold, directory, spinner) => {
|
|
|
59
81
|
await writeScaffoldDirectory(scaffold, directory, spinner)
|
|
60
82
|
}
|
|
61
83
|
|
|
84
|
+
const writeABI = async (abi, contractName, abiPath = `./abis/${contractName}.json`) => {
|
|
85
|
+
let data = prettier.format(JSON.stringify(abi.data), {
|
|
86
|
+
parser: 'json',
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
await fs.writeFile(abiPath, data, { encoding: 'utf-8' })
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const writeSchema = async (abi, protocol, schemaPath, entities) => {
|
|
93
|
+
const events = protocol.hasEvents()
|
|
94
|
+
? abiEvents(abi).filter(event => entities.indexOf(event.get('name')) === -1).toJS()
|
|
95
|
+
: []
|
|
96
|
+
|
|
97
|
+
let data = prettier.format(
|
|
98
|
+
events.map(
|
|
99
|
+
event => generateEventType(event, protocol.name)
|
|
100
|
+
).join('\n\n'),
|
|
101
|
+
{
|
|
102
|
+
parser: 'graphql',
|
|
103
|
+
},
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
await fs.appendFile(schemaPath, data, { encoding: 'utf-8' })
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const writeMapping = async (abi, protocol, contractName, entities) => {
|
|
110
|
+
const events = protocol.hasEvents()
|
|
111
|
+
? abiEvents(abi).filter(event => entities.indexOf(event.get('name')) === -1).toJS()
|
|
112
|
+
: []
|
|
113
|
+
|
|
114
|
+
let mapping = prettier.format(
|
|
115
|
+
generateEventIndexingHandlers(
|
|
116
|
+
events,
|
|
117
|
+
contractName,
|
|
118
|
+
),
|
|
119
|
+
{ parser: 'typescript', semi: false },
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
await fs.writeFile(`./src/${strings.kebabCase(contractName)}.ts`, mapping, { encoding: 'utf-8' })
|
|
123
|
+
}
|
|
124
|
+
|
|
62
125
|
module.exports = {
|
|
63
126
|
...module.exports,
|
|
64
127
|
generateScaffold,
|
|
65
128
|
writeScaffold,
|
|
129
|
+
generateDataSource,
|
|
130
|
+
writeABI,
|
|
131
|
+
writeSchema,
|
|
132
|
+
writeMapping,
|
|
66
133
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
const chalk = require('chalk')
|
|
2
|
+
const toolbox = require('gluegun/toolbox')
|
|
3
|
+
const immutable = require('immutable')
|
|
4
|
+
const { withSpinner } = require('../command-helpers/spinner')
|
|
5
|
+
const Subgraph = require('../subgraph')
|
|
6
|
+
const Protocol = require('../protocols')
|
|
7
|
+
const DataSourcesExtractor = require('../command-helpers/data-sources')
|
|
8
|
+
const { generateDataSource, writeABI, writeSchema, writeMapping } = require('../command-helpers/scaffold')
|
|
9
|
+
const { loadAbiFromEtherscan, loadAbiFromBlockScout } = require('../command-helpers/abi')
|
|
10
|
+
const EthereumABI = require('../protocols/ethereum/abi')
|
|
11
|
+
const { fixParameters } = require('../command-helpers/gluegun')
|
|
12
|
+
|
|
13
|
+
const HELP = `
|
|
14
|
+
${chalk.bold('graph add')} <address> [<subgraph-manifest default: "./subgraph.yaml">]
|
|
15
|
+
|
|
16
|
+
${chalk.dim('Options:')}
|
|
17
|
+
|
|
18
|
+
--abi <path> Path to the contract ABI (default: download from Etherscan)
|
|
19
|
+
--contract-name Name of the contract (default: Contract)
|
|
20
|
+
--merge-entities Whether to merge entities with the same name (default: false)
|
|
21
|
+
-h, --help Show usage information
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
description: 'Creates a new subgraph with basic scaffolding',
|
|
26
|
+
run: async toolbox => {
|
|
27
|
+
// Obtain tools
|
|
28
|
+
let { print, system } = toolbox
|
|
29
|
+
|
|
30
|
+
// Read CLI parameters
|
|
31
|
+
let {
|
|
32
|
+
abi,
|
|
33
|
+
contractName,
|
|
34
|
+
h,
|
|
35
|
+
help,
|
|
36
|
+
mergeEntities
|
|
37
|
+
} = toolbox.parameters.options
|
|
38
|
+
|
|
39
|
+
let address = toolbox.parameters.first
|
|
40
|
+
let manifestPath = toolbox.parameters.second || './subgraph.yaml'
|
|
41
|
+
contractName = contractName || 'Contract'
|
|
42
|
+
|
|
43
|
+
// Validate the address
|
|
44
|
+
if (!address) {
|
|
45
|
+
print.error('No contract address provided')
|
|
46
|
+
process.exitCode = 1
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
fixParameters(toolbox.parameters, {
|
|
52
|
+
h,
|
|
53
|
+
help,
|
|
54
|
+
mergeEntities,
|
|
55
|
+
})
|
|
56
|
+
} catch (e) {
|
|
57
|
+
print.error(e.message)
|
|
58
|
+
process.exitCode = 1
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Show help text if requested
|
|
63
|
+
if (help || h) {
|
|
64
|
+
print.info(HELP)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifestPath)
|
|
69
|
+
let protocol = Protocol.fromDataSources(dataSourcesAndTemplates)
|
|
70
|
+
let manifest = await Subgraph.load(manifestPath, { protocol })
|
|
71
|
+
let network = manifest.result.get('dataSources').get(0).get('network')
|
|
72
|
+
let result = manifest.result.asMutable()
|
|
73
|
+
|
|
74
|
+
let entities = getEntities(manifest)
|
|
75
|
+
let contractNames = getContractNames(manifest)
|
|
76
|
+
if (contractNames.indexOf(contractName) !== -1) {
|
|
77
|
+
print.error(
|
|
78
|
+
`Datasource or template with name ${contractName} already exists, please choose a different name`,
|
|
79
|
+
)
|
|
80
|
+
process.exitCode = 1
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let ethabi = null
|
|
85
|
+
if (abi) {
|
|
86
|
+
ethabi = EthereumABI.load(contractName, abi)
|
|
87
|
+
} else {
|
|
88
|
+
if (network === 'poa-core') {
|
|
89
|
+
ethabi = await loadAbiFromBlockScout(EthereumABI, network, address)
|
|
90
|
+
} else {
|
|
91
|
+
ethabi = await loadAbiFromEtherscan(EthereumABI, network, address)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let { collisionEntities, onlyCollisions, abiData } = updateEventNamesOnCollision(ethabi, entities, contractName, mergeEntities)
|
|
96
|
+
ethabi.data = abiData
|
|
97
|
+
|
|
98
|
+
await writeABI(ethabi, contractName, abi)
|
|
99
|
+
await writeSchema(ethabi, protocol, result.getIn(['schema', 'file']), collisionEntities)
|
|
100
|
+
await writeMapping(ethabi, protocol, contractName, collisionEntities)
|
|
101
|
+
|
|
102
|
+
let dataSources = result.get('dataSources')
|
|
103
|
+
let dataSource = await generateDataSource(protocol,
|
|
104
|
+
contractName, network, address, ethabi)
|
|
105
|
+
|
|
106
|
+
// Handle the collisions edge case by copying another data source yaml data
|
|
107
|
+
if (mergeEntities && onlyCollisions) {
|
|
108
|
+
let firstDataSource = dataSources.get(0)
|
|
109
|
+
let source = dataSource.get('source')
|
|
110
|
+
let mapping = firstDataSource.get('mapping').asMutable()
|
|
111
|
+
|
|
112
|
+
// Save the address of the new data source
|
|
113
|
+
source.abi = firstDataSource.get('source').get('abi')
|
|
114
|
+
|
|
115
|
+
dataSource.set('mapping', mapping)
|
|
116
|
+
dataSource.set('source', source)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
result.set('dataSources', dataSources.push(dataSource))
|
|
120
|
+
|
|
121
|
+
await Subgraph.write(result, manifestPath)
|
|
122
|
+
|
|
123
|
+
// Detect Yarn and/or NPM
|
|
124
|
+
let yarn = await system.which('yarn')
|
|
125
|
+
let npm = await system.which('npm')
|
|
126
|
+
if (!yarn && !npm) {
|
|
127
|
+
print.error(
|
|
128
|
+
`Neither Yarn nor NPM were found on your system. Please install one of them.`,
|
|
129
|
+
)
|
|
130
|
+
process.exitCode = 1
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
await withSpinner(
|
|
135
|
+
'Running codegen',
|
|
136
|
+
'Failed to run codegen',
|
|
137
|
+
'Warning during codegen',
|
|
138
|
+
async spinner => {
|
|
139
|
+
await system.run(yarn ? 'yarn codegen' : 'npm run codegen')
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const getEntities = (manifest) => {
|
|
146
|
+
let dataSources = manifest.result.get('dataSources', immutable.List())
|
|
147
|
+
let templates = manifest.result.get('templates', immutable.List())
|
|
148
|
+
|
|
149
|
+
return dataSources
|
|
150
|
+
.concat(templates)
|
|
151
|
+
.map(dataSource => dataSource.getIn(['mapping', 'entities']))
|
|
152
|
+
.flatten()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const getContractNames = (manifest) => {
|
|
156
|
+
let dataSources = manifest.result.get('dataSources', immutable.List())
|
|
157
|
+
let templates = manifest.result.get('templates', immutable.List())
|
|
158
|
+
|
|
159
|
+
return dataSources
|
|
160
|
+
.concat(templates)
|
|
161
|
+
.map(dataSource => dataSource.get('name'))
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const updateEventNamesOnCollision = (ethabi, entities, contractName, mergeEntities) => {
|
|
165
|
+
let abiData = ethabi.data
|
|
166
|
+
let { print } = toolbox
|
|
167
|
+
let collisionEntities = []
|
|
168
|
+
let onlyCollisions = true
|
|
169
|
+
|
|
170
|
+
for (let i = 0; i < abiData.size; i++) {
|
|
171
|
+
let dataRow = abiData.get(i).asMutable()
|
|
172
|
+
|
|
173
|
+
if (dataRow.get('type') === 'event'){
|
|
174
|
+
if (entities.indexOf(dataRow.get('name')) !== -1) {
|
|
175
|
+
if (entities.indexOf(`${contractName}${dataRow.get('name')}`) !== -1) {
|
|
176
|
+
print.error(`Contract name ('${contractName}')
|
|
177
|
+
+ event name ('${dataRow.get('name')}') entity already exists.`)
|
|
178
|
+
process.exitCode = 1
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (mergeEntities) {
|
|
183
|
+
collisionEntities.push(dataRow.get('name'))
|
|
184
|
+
abiData = abiData.asImmutable().delete(i) // needs to be immutable when deleting, yes you read that right - https://github.com/immutable-js/immutable-js/issues/1901
|
|
185
|
+
i-- // deletion also shifts values to the left
|
|
186
|
+
continue
|
|
187
|
+
} else {
|
|
188
|
+
dataRow.set('name', `${contractName}${dataRow.get('name')}`)
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
onlyCollisions = false
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
abiData = abiData.asMutable().set(i, dataRow)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return { abiData, collisionEntities, onlyCollisions }
|
|
198
|
+
}
|
package/src/commands/deploy.js
CHANGED
|
@@ -294,7 +294,6 @@ $ graph create --node ${node} ${subgraphName}`)
|
|
|
294
294
|
const base = requestUrl.protocol + '//' + requestUrl.hostname
|
|
295
295
|
let playground = res.playground
|
|
296
296
|
let queries = res.queries
|
|
297
|
-
let subscriptions = res.subscriptions
|
|
298
297
|
|
|
299
298
|
// Add a base URL if graph-node did not return the full URL
|
|
300
299
|
if (playground.charAt(0) === ':') {
|
|
@@ -303,9 +302,6 @@ $ graph create --node ${node} ${subgraphName}`)
|
|
|
303
302
|
if (queries.charAt(0) === ':') {
|
|
304
303
|
queries = base + queries
|
|
305
304
|
}
|
|
306
|
-
if (subscriptions.charAt(0) === ':') {
|
|
307
|
-
subscriptions = base + subscriptions
|
|
308
|
-
}
|
|
309
305
|
|
|
310
306
|
if (isHostedService) {
|
|
311
307
|
print.success(
|
|
@@ -318,7 +314,6 @@ $ graph create --node ${node} ${subgraphName}`)
|
|
|
318
314
|
}
|
|
319
315
|
print.info('\nSubgraph endpoints:')
|
|
320
316
|
print.info(`Queries (HTTP): ${queries}`)
|
|
321
|
-
print.info(`Subscriptions (WS): ${subscriptions}`)
|
|
322
317
|
print.info(``)
|
|
323
318
|
}
|
|
324
319
|
},
|
package/src/commands/init.js
CHANGED
|
@@ -16,6 +16,7 @@ const { initNetworksConfig } = require('../command-helpers/network')
|
|
|
16
16
|
const { withSpinner, step } = require('../command-helpers/spinner')
|
|
17
17
|
const { fixParameters } = require('../command-helpers/gluegun')
|
|
18
18
|
const { chooseNodeUrl } = require('../command-helpers/node')
|
|
19
|
+
const { loadAbiFromEtherscan, loadAbiFromBlockScout } = require('../command-helpers/abi')
|
|
19
20
|
const { generateScaffold, writeScaffold } = require('../command-helpers/scaffold')
|
|
20
21
|
const { abiEvents } = require('../scaffold/schema')
|
|
21
22
|
const { validateContract } = require('../validation')
|
|
@@ -57,6 +58,11 @@ ${chalk.dim.underline('NEAR:')}
|
|
|
57
58
|
|
|
58
59
|
--network <${availableNetworks.get('near').join('|')}>
|
|
59
60
|
Selects the network the contract is deployed to
|
|
61
|
+
|
|
62
|
+
${chalk.dim.underline('Cosmos:')}
|
|
63
|
+
|
|
64
|
+
--network <${availableNetworks.get('cosmos').join('|')}>
|
|
65
|
+
Selects the network the contract is deployed to
|
|
60
66
|
`
|
|
61
67
|
|
|
62
68
|
const processInitForm = async (
|
|
@@ -169,6 +175,11 @@ const processInitForm = async (
|
|
|
169
175
|
return value
|
|
170
176
|
},
|
|
171
177
|
},
|
|
178
|
+
// TODO:
|
|
179
|
+
//
|
|
180
|
+
// protocols that don't support contract
|
|
181
|
+
// - arweave
|
|
182
|
+
// - tendermint
|
|
172
183
|
{
|
|
173
184
|
type: 'input',
|
|
174
185
|
name: 'contract',
|
|
@@ -176,10 +187,10 @@ const processInitForm = async (
|
|
|
176
187
|
ProtocolContract = protocolInstance.getContract()
|
|
177
188
|
return `Contract ${ProtocolContract.identifierName()}`
|
|
178
189
|
},
|
|
179
|
-
skip: fromExample !== undefined,
|
|
190
|
+
skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
|
|
180
191
|
initial: contract,
|
|
181
192
|
validate: async value => {
|
|
182
|
-
if (fromExample !== undefined) {
|
|
193
|
+
if (fromExample !== undefined || !protocolInstance.hasContract()) {
|
|
183
194
|
return true
|
|
184
195
|
}
|
|
185
196
|
|
|
@@ -237,11 +248,11 @@ const processInitForm = async (
|
|
|
237
248
|
name: 'contractName',
|
|
238
249
|
message: 'Contract Name',
|
|
239
250
|
initial: contractName || 'Contract',
|
|
240
|
-
skip: () => fromExample !== undefined,
|
|
251
|
+
skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
|
|
241
252
|
validate: value => value && value.length > 0,
|
|
242
253
|
result: value => {
|
|
243
|
-
contractName = value
|
|
244
|
-
return value
|
|
254
|
+
contractName = value
|
|
255
|
+
return value
|
|
245
256
|
}
|
|
246
257
|
},
|
|
247
258
|
]
|
|
@@ -254,67 +265,6 @@ const processInitForm = async (
|
|
|
254
265
|
}
|
|
255
266
|
}
|
|
256
267
|
|
|
257
|
-
const loadAbiFromBlockScout = async (ABI, network, address) =>
|
|
258
|
-
await withSpinner(
|
|
259
|
-
`Fetching ABI from BlockScout`,
|
|
260
|
-
`Failed to fetch ABI from BlockScout`,
|
|
261
|
-
`Warnings while fetching ABI from BlockScout`,
|
|
262
|
-
async spinner => {
|
|
263
|
-
let result = await fetch(
|
|
264
|
-
`https://blockscout.com/${
|
|
265
|
-
network.replace('-', '/')
|
|
266
|
-
}/api?module=contract&action=getabi&address=${address}`,
|
|
267
|
-
)
|
|
268
|
-
let json = await result.json()
|
|
269
|
-
|
|
270
|
-
// BlockScout returns a JSON object that has a `status`, a `message` and
|
|
271
|
-
// a `result` field. The `status` is '0' in case of errors and '1' in
|
|
272
|
-
// case of success
|
|
273
|
-
if (json.status === '1') {
|
|
274
|
-
return new ABI('Contract', undefined, immutable.fromJS(JSON.parse(json.result)))
|
|
275
|
-
} else {
|
|
276
|
-
throw new Error('ABI not found, try loading it from a local file')
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
const getEtherscanLikeAPIUrl = (network) => {
|
|
282
|
-
switch(network){
|
|
283
|
-
case "mainnet": return `https://api.etherscan.io/api`;
|
|
284
|
-
case "arbitrum-one": return `https://api.arbiscan.io/api`;
|
|
285
|
-
case "bsc": return `https://api.bscscan.com/api`;
|
|
286
|
-
case "matic": return `https://api.polygonscan.com/api`;
|
|
287
|
-
case "mumbai": return `https://api-testnet.polygonscan.com/api`;
|
|
288
|
-
case "aurora": return `https://api.aurorascan.dev/api`;
|
|
289
|
-
case "aurora-testnet": return `https://api-testnet.aurorascan.dev/api`;
|
|
290
|
-
case "optimism-kovan": return `https://api-kovan-optimistic.etherscan.io/api`;
|
|
291
|
-
default: return `https://api-${network}.etherscan.io/api`;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const loadAbiFromEtherscan = async (ABI, network, address) =>
|
|
296
|
-
await withSpinner(
|
|
297
|
-
`Fetching ABI from Etherscan`,
|
|
298
|
-
`Failed to fetch ABI from Etherscan`,
|
|
299
|
-
`Warnings while fetching ABI from Etherscan`,
|
|
300
|
-
async spinner => {
|
|
301
|
-
const scanApiUrl = getEtherscanLikeAPIUrl(network);
|
|
302
|
-
let result = await fetch(
|
|
303
|
-
`${scanApiUrl}?module=contract&action=getabi&address=${address}`,
|
|
304
|
-
)
|
|
305
|
-
let json = await result.json()
|
|
306
|
-
|
|
307
|
-
// Etherscan returns a JSON object that has a `status`, a `message` and
|
|
308
|
-
// a `result` field. The `status` is '0' in case of errors and '1' in
|
|
309
|
-
// case of success
|
|
310
|
-
if (json.status === '1') {
|
|
311
|
-
return new ABI('Contract', undefined, immutable.fromJS(JSON.parse(json.result)))
|
|
312
|
-
} else {
|
|
313
|
-
throw new Error('ABI not found, try loading it from a local file')
|
|
314
|
-
}
|
|
315
|
-
},
|
|
316
|
-
)
|
|
317
|
-
|
|
318
268
|
const loadAbiFromFile = async (ABI, filename) => {
|
|
319
269
|
let exists = await toolbox.filesystem.exists(filename)
|
|
320
270
|
|
|
@@ -768,6 +718,7 @@ const initSubgraphFromContract = async (
|
|
|
768
718
|
contract,
|
|
769
719
|
indexEvents,
|
|
770
720
|
contractName,
|
|
721
|
+
dataSourceName,
|
|
771
722
|
node,
|
|
772
723
|
studio,
|
|
773
724
|
product,
|
|
@@ -822,6 +773,7 @@ const initSubgraphFromContract = async (
|
|
|
822
773
|
contract,
|
|
823
774
|
indexEvents,
|
|
824
775
|
contractName,
|
|
776
|
+
dataSourceName,
|
|
825
777
|
node,
|
|
826
778
|
},
|
|
827
779
|
spinner,
|
|
@@ -835,11 +787,13 @@ const initSubgraphFromContract = async (
|
|
|
835
787
|
return
|
|
836
788
|
}
|
|
837
789
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
790
|
+
if (protocolInstance.hasContract()) {
|
|
791
|
+
let identifierName = protocolInstance.getContract().identifierName()
|
|
792
|
+
let networkConf = await initNetworksConfig(toolbox, directory, identifierName)
|
|
793
|
+
if (networkConf !== true) {
|
|
794
|
+
process.exitCode = 1
|
|
795
|
+
return
|
|
796
|
+
}
|
|
843
797
|
}
|
|
844
798
|
|
|
845
799
|
// Initialize a fresh Git repository
|
|
@@ -21,7 +21,7 @@ module.exports = {
|
|
|
21
21
|
|
|
22
22
|
let manifest = loadManifest(manifestFile)
|
|
23
23
|
return (
|
|
24
|
-
// Only migrate if the graph-ts version is >= 0.
|
|
24
|
+
// Only migrate if the graph-ts version is >= 0.24.0...
|
|
25
25
|
// Coerce needed because we may be dealing with an alpha version
|
|
26
26
|
// and in the `semver` library this would not return true on equality.
|
|
27
27
|
semver.gte(semver.coerce(graphTsVersion), '0.24.0') &&
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const fs = require('fs-extra')
|
|
2
|
+
const semver = require('semver')
|
|
3
|
+
const toolbox = require('gluegun/toolbox')
|
|
4
|
+
const yaml = require('js-yaml')
|
|
5
|
+
const { loadManifest } = require('./util/load-manifest')
|
|
6
|
+
const { getGraphTsVersion } = require('./util/versions')
|
|
7
|
+
|
|
8
|
+
// If any of the manifest apiVersions are 0.0.6, replace them with 0.0.7
|
|
9
|
+
module.exports = {
|
|
10
|
+
name: 'Bump mapping apiVersion from 0.0.6 to 0.0.7',
|
|
11
|
+
predicate: async ({ sourceDir, manifestFile }) => {
|
|
12
|
+
// Obtain the graph-ts version, if possible
|
|
13
|
+
let graphTsVersion
|
|
14
|
+
try {
|
|
15
|
+
graphTsVersion = await getGraphTsVersion(sourceDir)
|
|
16
|
+
} catch (_) {
|
|
17
|
+
// If we cannot obtain the version, return a hint that the graph-ts
|
|
18
|
+
// hasn't been installed yet
|
|
19
|
+
return 'graph-ts dependency not installed yet'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let manifest = loadManifest(manifestFile)
|
|
23
|
+
return (
|
|
24
|
+
// Only migrate if the graph-ts version is >= 0.27.0...
|
|
25
|
+
// Coerce needed because we may be dealing with an alpha version
|
|
26
|
+
// and in the `semver` library this would not return true on equality.
|
|
27
|
+
semver.gte(semver.coerce(graphTsVersion), '0.27.0') &&
|
|
28
|
+
// ...and we have a manifest with mapping > apiVersion = 0.0.6
|
|
29
|
+
manifest &&
|
|
30
|
+
typeof manifest === 'object' &&
|
|
31
|
+
Array.isArray(manifest.dataSources) &&
|
|
32
|
+
(manifest.dataSources.reduce(
|
|
33
|
+
(hasOldMappings, dataSource) =>
|
|
34
|
+
hasOldMappings ||
|
|
35
|
+
(typeof dataSource === 'object' &&
|
|
36
|
+
dataSource.mapping &&
|
|
37
|
+
typeof dataSource.mapping === 'object' &&
|
|
38
|
+
dataSource.mapping.apiVersion === '0.0.6'),
|
|
39
|
+
false,
|
|
40
|
+
) ||
|
|
41
|
+
(Array.isArray(manifest.templates) &&
|
|
42
|
+
manifest.templates.reduce(
|
|
43
|
+
(hasOldMappings, template) =>
|
|
44
|
+
hasOldMappings ||
|
|
45
|
+
(typeof template === 'object' &&
|
|
46
|
+
template.mapping &&
|
|
47
|
+
typeof template.mapping === 'object' &&
|
|
48
|
+
template.mapping.apiVersion === '0.0.6'),
|
|
49
|
+
false,
|
|
50
|
+
)))
|
|
51
|
+
)
|
|
52
|
+
},
|
|
53
|
+
apply: async ({ manifestFile }) => {
|
|
54
|
+
// Make sure we catch all variants; we could load the manifest
|
|
55
|
+
// and replace the values in the data structures here; unfortunately
|
|
56
|
+
// writing that back to the file messes with the formatting more than
|
|
57
|
+
// we'd like; that's why for now, we use a simple patching approach
|
|
58
|
+
await toolbox.patching.replace(
|
|
59
|
+
manifestFile,
|
|
60
|
+
new RegExp('apiVersion: 0.0.6', 'g'),
|
|
61
|
+
'apiVersion: 0.0.7',
|
|
62
|
+
)
|
|
63
|
+
await toolbox.patching.replace(
|
|
64
|
+
manifestFile,
|
|
65
|
+
new RegExp("apiVersion: '0.0.6'", 'g'),
|
|
66
|
+
"apiVersion: '0.0.7'",
|
|
67
|
+
)
|
|
68
|
+
await toolbox.patching.replace(
|
|
69
|
+
manifestFile,
|
|
70
|
+
new RegExp('apiVersion: "0.0.6"', 'g'),
|
|
71
|
+
'apiVersion: "0.0.7"',
|
|
72
|
+
)
|
|
73
|
+
},
|
|
74
|
+
}
|
|
@@ -6,7 +6,7 @@ const { loadManifest } = require('./util/load-manifest')
|
|
|
6
6
|
// Spec version to 0.0.2 uses top level templates. graph-cli no longer supports
|
|
7
7
|
// 0.0.1 which used nested templates.
|
|
8
8
|
module.exports = {
|
|
9
|
-
name: 'Bump
|
|
9
|
+
name: 'Bump manifest specVersion from 0.0.1 to 0.0.2',
|
|
10
10
|
predicate: async ({ sourceDir, manifestFile }) => {
|
|
11
11
|
let manifest = await loadManifest(manifestFile)
|
|
12
12
|
return (
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const fs = require('fs-extra')
|
|
2
|
+
const toolbox = require('gluegun/toolbox')
|
|
3
|
+
const yaml = require('js-yaml')
|
|
4
|
+
const { loadManifest } = require('./util/load-manifest')
|
|
5
|
+
|
|
6
|
+
// Spec version 0.0.4 uses feature management, but features are
|
|
7
|
+
// detected and validated by the graph-node instance during subgraph
|
|
8
|
+
// deployment.
|
|
9
|
+
//
|
|
10
|
+
// Also, we skip spec version 0.0.3, which is considered invalid and
|
|
11
|
+
// non-canonical.
|
|
12
|
+
module.exports = {
|
|
13
|
+
name: 'Bump manifest specVersion from 0.0.2 to 0.0.4',
|
|
14
|
+
predicate: async ({ sourceDir, manifestFile }) => {
|
|
15
|
+
let manifest = await loadManifest(manifestFile)
|
|
16
|
+
return (
|
|
17
|
+
manifest &&
|
|
18
|
+
typeof manifest === 'object' &&
|
|
19
|
+
manifest.specVersion &&
|
|
20
|
+
(manifest.specVersion === '0.0.2' || manifest.specVersion === '0.0.3')
|
|
21
|
+
)
|
|
22
|
+
},
|
|
23
|
+
apply: async ({ manifestFile }) => {
|
|
24
|
+
await toolbox.patching.patch(manifestFile, {
|
|
25
|
+
insert: 'specVersion: 0.0.4',
|
|
26
|
+
replace: new RegExp(`specVersion: ['"]?0.0.[23]['"]?`),
|
|
27
|
+
})
|
|
28
|
+
},
|
|
29
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const fs = require('fs-extra')
|
|
2
|
+
const toolbox = require('gluegun/toolbox')
|
|
3
|
+
const yaml = require('js-yaml')
|
|
4
|
+
const { loadManifest } = require('./util/load-manifest')
|
|
5
|
+
|
|
6
|
+
// Spec version 0.0.5 let event handlers require transaction receipt
|
|
7
|
+
// data to be accessed in the runtime.
|
|
8
|
+
module.exports = {
|
|
9
|
+
name: 'Bump manifest specVersion from 0.0.4 to 0.0.5',
|
|
10
|
+
predicate: async ({ sourceDir, manifestFile }) => {
|
|
11
|
+
let manifest = await loadManifest(manifestFile)
|
|
12
|
+
return (
|
|
13
|
+
manifest &&
|
|
14
|
+
typeof manifest === 'object' &&
|
|
15
|
+
manifest.specVersion &&
|
|
16
|
+
manifest.specVersion === '0.0.4'
|
|
17
|
+
)
|
|
18
|
+
},
|
|
19
|
+
apply: async ({ manifestFile }) => {
|
|
20
|
+
await toolbox.patching.patch(manifestFile, {
|
|
21
|
+
insert: 'specVersion: 0.0.5',
|
|
22
|
+
replace: new RegExp(`specVersion: ['"]?0.0.4['"]?`),
|
|
23
|
+
})
|
|
24
|
+
},
|
|
25
|
+
}
|
package/src/migrations.js
CHANGED
|
@@ -5,7 +5,11 @@ const MIGRATIONS = [
|
|
|
5
5
|
require('./migrations/mapping_api_version_0_0_2'),
|
|
6
6
|
require('./migrations/mapping_api_version_0_0_3'),
|
|
7
7
|
require('./migrations/mapping_api_version_0_0_4'),
|
|
8
|
+
require('./migrations/mapping_api_version_0_0_5'),
|
|
9
|
+
require('./migrations/mapping_api_version_0_0_6'),
|
|
8
10
|
require('./migrations/spec_version_0_0_2'),
|
|
11
|
+
require('./migrations/spec_version_0_0_3'),
|
|
12
|
+
require('./migrations/spec_version_0_0_4'),
|
|
9
13
|
]
|
|
10
14
|
|
|
11
15
|
const applyMigrations = async options =>
|