-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.js
More file actions
137 lines (125 loc) · 4.85 KB
/
index.js
File metadata and controls
137 lines (125 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const fs = require('fs')
const path = require('path')
const FormData = require('form-data')
const dotenv = require('dotenv')
dotenv.load()
const prodUrl = new URL('https://contract-service.amberdata.io/api/v1/upload')
const devUrl = new URL('http://localhost:1234/api/v1/upload')
const mainPath = process.env.NODE_ENV === 'development' ? devUrl : prodUrl
const headers = {'x-amberdata-api-key': process.env.AMBERDATA_API_KEY || ''}
// The standard path to the contract apis per truffle specs
const DEFAULT_BUILD_DIR = path.join(__dirname, '/../../', 'build/contracts/')
// An Object containing amberdata specfic values for use with our api
const blockchainIds = {
1: {
blockchainId: '1c9c969065fcd1cf',
slug: 'ethereum-mainnet'
},
4: {
blockchainId: '1b3f7a72b3e99c13',
slug: 'ethereum-rinkeby'
}
}
// Ethereum JSON RPC network_ids for user help message
const ETHEREUM_NETWORKS = {
1: 'Ethereum Mainnet',
3: 'Ropsten Testnet',
4: 'Rinkeby Testnet',
42: 'Kovan Testnet'
}
/**
* @desc getMeta() returns an object containing the
* metadata of the contract to upload with the abi
* @param { Object } networks contains details of the deployed contract
* @param { Object } networkId the JSON RPC network_id of the
* network that the contract was deployed to
* @param { Object } account the deployer account address
* @return { Object } the metadata of the contract
*/
const getMeta = function(networks, networkId, account) {
return {
contractAddress: networks.address,
walletAddress: account,
transactionHash: networks.transactionHash,
blockchainId: blockchainIds[networkId].blockchainId,
slug: blockchainIds[networkId].slug
}
}
/**
* @desc uploadAbi() uploads a multipart format of files
* @param { String } file the path of the file to upload
* @param { Object } payload the metadata to upload with the contract abi
*/
const uploadAbi = function(file, payload) {
const form = new FormData()
form.append('uploadedFiles', fs.createReadStream(file))
form.append('contractAddress', payload.contractAddress)
form.append('transactionHash', payload.transactionHash)
form.append('walletAddress', payload.walletAddress)
form.append('blockchainId', payload.blockchainId)
const options = Object.assign({}, mainPath, {headers})
form.submit(options, (err, res) => {
if (err) {
console.log(err, res.statusCode)
} else {
console.log(
`[ Uploader ] \u001B[34mINFO:\u001B[0m View your contract, ${payload.contractName} at: \u001B[36mhttps://${payload.slug}.amberdata.io/addresses/${payload.contractAddress}/management\u001B[0m`
)
}
})
}
/**
* @desc isEmpty() takes an object and
* evaluates whether an object is empty or not
* @param { Object } obj the object that's tested for emptiness
* @return { Boolean } true if empty and false otherwise
*/
const isEmpty = function(obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object
}
/**
* @desc Uploads contract abi to amberdata servers
* @param { Object } deployer the truffle deployer object
* @param { String } network name of the network as defined in truffle.js
* @param { Array } accounts the list of account addresses
*/
module.exports = function(deployer, network, accounts) {
const networkId = parseInt(deployer.network_id, 10)
// Check that network is supported by amberdata
if (![1, 4].includes(networkId)) {
console.log(
`\n [ Uploader ] \u001B[33mWARN:\u001B[0m Network, '${
ETHEREUM_NETWORKS[networkId] ? ETHEREUM_NETWORKS[networkId] : networkId
}', not supported by amberdata. Contract ABI not uploaded.\n see
\u001B[36mhttps://github.com/web3data/web3data-deploy#installation\u001B[0m for more details.`
)
return // Bail, network not supported
}
fs.readdir(DEFAULT_BUILD_DIR, (err, files) => {
if (err) {
console.log(`\u001B[31m${err}\u001B[0m\n`)
} else {
for (const element of files) {
if (element !== 'Migrations.json') {
// Get absolute file path of conract abi and load the api
const filePath = path.join(DEFAULT_BUILD_DIR, '/', element)
const abi = JSON.parse(fs.readFileSync(filePath))
/* Check if the networks field is empty. If it is, then the contract
* was not deployed to a network
*/
if (isEmpty(abi.networks)) {
console.log(
`\n[ Uploader ] \u001B[34mINFO:\u001B[0m '${element}' might not have been deployed therefore it was skipped by the Uploader`
)
} else {
// Get the 'networks' object from the abi, parse data and contruct the payload then upload the file
const networks = abi.networks[networkId]
const payload = getMeta(networks, networkId, accounts[0])
payload.contractName = abi.contractName
uploadAbi(filePath, payload)
}
}
}
}
})
}