@sentio/cli 2.4.0 → 2.5.0-rc.2
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/lib/abi.d.ts +6 -0
- package/lib/abi.js +138 -0
- package/lib/abi.js.map +1 -0
- package/lib/chain.d.ts +98 -0
- package/lib/chain.js +198 -0
- package/lib/chain.js.map +1 -0
- package/lib/cli.js +5 -5
- package/lib/cli.js.map +1 -1
- package/lib/commands/build.d.ts +7 -1
- package/lib/commands/build.js +50 -8
- package/lib/commands/build.js.map +1 -1
- package/lib/commands/run-add.js +27 -82
- package/lib/commands/run-add.js.map +1 -1
- package/lib/commands/run-upload.d.ts +3 -3
- package/lib/commands/run-upload.js.map +1 -1
- package/lib/config.d.ts +9 -3
- package/lib/config.js.map +1 -1
- package/package.json +3 -4
- package/src/abi.ts +150 -0
- package/src/chain.ts +195 -0
- package/src/cli.ts +6 -6
- package/src/commands/build.ts +57 -8
- package/src/commands/run-add.ts +29 -84
- package/src/commands/run-upload.ts +4 -4
- package/src/config.ts +10 -5
package/src/abi.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { AptosClient } from 'aptos-sdk'
|
|
2
|
+
import { JsonRpcProvider } from '@mysten/sui.js'
|
|
3
|
+
import { CHAIN_IDS } from './chain.js'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import process from 'process'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
import fs from 'fs-extra'
|
|
8
|
+
// @ts-ignore no types
|
|
9
|
+
import { init } from 'etherscan-api'
|
|
10
|
+
|
|
11
|
+
export async function getABI(
|
|
12
|
+
chain: string,
|
|
13
|
+
address: string,
|
|
14
|
+
name: string | undefined
|
|
15
|
+
): Promise<{ name?: string; abi: object | string }> {
|
|
16
|
+
let ethApi
|
|
17
|
+
let aptosClient: AptosClient | undefined
|
|
18
|
+
let suiClient: JsonRpcProvider | undefined
|
|
19
|
+
|
|
20
|
+
switch (chain) {
|
|
21
|
+
case CHAIN_IDS.APTOS_MAINNET:
|
|
22
|
+
aptosClient = new AptosClient('https://mainnet.aptoslabs.com/')
|
|
23
|
+
break
|
|
24
|
+
case CHAIN_IDS.APTOS_TESTNET:
|
|
25
|
+
aptosClient = new AptosClient('https://testnet.aptoslabs.com/')
|
|
26
|
+
break
|
|
27
|
+
case CHAIN_IDS.SUI_MAINNET:
|
|
28
|
+
throw Error('SUI mainnet is not support yet, try sui/testnet')
|
|
29
|
+
// suiClient = new JsonRpcProvider('https://fullnode.mainnet.sui.io/')
|
|
30
|
+
// break
|
|
31
|
+
case CHAIN_IDS.SUI_TESTNET:
|
|
32
|
+
suiClient = new JsonRpcProvider('https://fullnode.testnet.sui.io/')
|
|
33
|
+
break
|
|
34
|
+
case CHAIN_IDS.ETHEREUM:
|
|
35
|
+
ethApi = init()
|
|
36
|
+
break
|
|
37
|
+
// case CHAIN_IDS.ROPSTEN:
|
|
38
|
+
// ethApi = init(undefined, "ropsten")
|
|
39
|
+
// break
|
|
40
|
+
// case CHAIN_IDS.RINKEBY:
|
|
41
|
+
// ethApi = init(undefined, "rinkeby")
|
|
42
|
+
// break
|
|
43
|
+
case CHAIN_IDS.GOERLI:
|
|
44
|
+
ethApi = init(undefined, 'goerli')
|
|
45
|
+
break
|
|
46
|
+
// case CHAIN_IDS.SEPOLIA:
|
|
47
|
+
// ethApi = init(undefined, "sepolia")
|
|
48
|
+
// break
|
|
49
|
+
|
|
50
|
+
case CHAIN_IDS.ARBITRUM:
|
|
51
|
+
ethApi = init(undefined, 'arbitrum')
|
|
52
|
+
break
|
|
53
|
+
case CHAIN_IDS.ARBITRUM_GOERLI:
|
|
54
|
+
ethApi = init(undefined, 'arbitrum_rinkeby')
|
|
55
|
+
break
|
|
56
|
+
case CHAIN_IDS.AVALANCHE:
|
|
57
|
+
ethApi = init(undefined, 'avalanche')
|
|
58
|
+
break
|
|
59
|
+
// case CHAIN_IDS.KOVAN:
|
|
60
|
+
// ethApi = init(undefined, "kovan")
|
|
61
|
+
// break
|
|
62
|
+
default:
|
|
63
|
+
console.error(chalk.red(`chain ${chain} not supported for direct add, please download the ABI manually`))
|
|
64
|
+
process.exit(1)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const baseErrMsg = chalk.red(
|
|
68
|
+
`Failed to automatic download contract ${address} from ${chain}, please manually download abi and put it into abis/eth directory`
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if (aptosClient) {
|
|
72
|
+
try {
|
|
73
|
+
return {
|
|
74
|
+
abi: await aptosClient.getAccountModules(address),
|
|
75
|
+
}
|
|
76
|
+
} catch (e) {
|
|
77
|
+
console.error(baseErrMsg, e)
|
|
78
|
+
process.exit(1)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (suiClient) {
|
|
82
|
+
try {
|
|
83
|
+
return {
|
|
84
|
+
abi: await suiClient.getNormalizedMoveModulesByPackage(address),
|
|
85
|
+
}
|
|
86
|
+
} catch (e) {
|
|
87
|
+
console.error(baseErrMsg, e)
|
|
88
|
+
process.exit(1)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
let resp = await ethApi.contract.getabi(address)
|
|
94
|
+
if (resp.status !== '1') {
|
|
95
|
+
throw Error(resp.message)
|
|
96
|
+
}
|
|
97
|
+
const abi = resp.result
|
|
98
|
+
|
|
99
|
+
if (!name) {
|
|
100
|
+
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
101
|
+
resp = await ethApi.contract.getsourcecode(address)
|
|
102
|
+
if (resp.status !== '1') {
|
|
103
|
+
throw Error(resp.message)
|
|
104
|
+
}
|
|
105
|
+
const contractName = resp.result[0].ContractName
|
|
106
|
+
if (contractName) {
|
|
107
|
+
name = contractName
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
name,
|
|
112
|
+
abi,
|
|
113
|
+
}
|
|
114
|
+
} catch (e) {
|
|
115
|
+
console.error(baseErrMsg, e)
|
|
116
|
+
process.exit(1)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function getABIFilePath(chain: string, name: string): string {
|
|
121
|
+
let subpath
|
|
122
|
+
switch (chain) {
|
|
123
|
+
case CHAIN_IDS.APTOS_MAINNET:
|
|
124
|
+
subpath = 'aptos'
|
|
125
|
+
break
|
|
126
|
+
case CHAIN_IDS.APTOS_TESTNET:
|
|
127
|
+
subpath = 'aptos/test'
|
|
128
|
+
break
|
|
129
|
+
case CHAIN_IDS.SUI_MAINNET:
|
|
130
|
+
subpath = 'sui'
|
|
131
|
+
break
|
|
132
|
+
case CHAIN_IDS.SUI_TESTNET:
|
|
133
|
+
subpath = 'sui/test'
|
|
134
|
+
break
|
|
135
|
+
default:
|
|
136
|
+
subpath = 'eth'
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return path.join('abis', subpath, name + '.json')
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function writeABIFile(obj: string | object, output: string) {
|
|
143
|
+
if (typeof obj === 'string') {
|
|
144
|
+
obj = JSON.parse(obj)
|
|
145
|
+
}
|
|
146
|
+
const data = JSON.stringify(obj, null, 2)
|
|
147
|
+
fs.mkdirSync(path.dirname(output), { recursive: true })
|
|
148
|
+
fs.writeFileSync(output, data)
|
|
149
|
+
console.log(chalk.green('ABI has been downloaded to', output))
|
|
150
|
+
}
|
package/src/chain.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// copy from https://github.com/DefiLlama/chainlist/blob/main/constants/chainIds.js
|
|
2
|
+
// and https://besu.hyperledger.org/en/stable/Concepts/NetworkID-And-ChainID/
|
|
3
|
+
|
|
4
|
+
export const CHAIN_IDS = {
|
|
5
|
+
KARDIA: '0',
|
|
6
|
+
ETHEREUM: '1',
|
|
7
|
+
EXPANSE: '2',
|
|
8
|
+
ROPSTEN: '3',
|
|
9
|
+
RINKEBY: '4',
|
|
10
|
+
GOERLI: '5',
|
|
11
|
+
KOTTI: '6',
|
|
12
|
+
UBIQ: '8',
|
|
13
|
+
OPTIMISM: '10',
|
|
14
|
+
SONGBIRD: '19',
|
|
15
|
+
ELASTOS: '20',
|
|
16
|
+
CRONOS: '25',
|
|
17
|
+
RSK: '30',
|
|
18
|
+
TELOS: '40',
|
|
19
|
+
XDC: '50',
|
|
20
|
+
CSC: '52',
|
|
21
|
+
ZYX: '55',
|
|
22
|
+
BINANCE: '56',
|
|
23
|
+
SYSCOIN: '57',
|
|
24
|
+
GOCHAIN: '60',
|
|
25
|
+
ETHCLASSIC: '61',
|
|
26
|
+
MORDOR: '63',
|
|
27
|
+
OKEXCHAIN: '66',
|
|
28
|
+
HOO: '70',
|
|
29
|
+
METER: '82',
|
|
30
|
+
TOMOCHAIN: '88',
|
|
31
|
+
BINANCE_TEST: '97',
|
|
32
|
+
XDAI: '100',
|
|
33
|
+
VELAS: '106',
|
|
34
|
+
THUNDERCORE: '108',
|
|
35
|
+
FUSE: '122',
|
|
36
|
+
HECO: '128',
|
|
37
|
+
POLYGON: '137',
|
|
38
|
+
XDAIARB: '200',
|
|
39
|
+
ASTOR: '212',
|
|
40
|
+
ENERGYWEB: '246',
|
|
41
|
+
FANTOM: '250',
|
|
42
|
+
HPB: '269',
|
|
43
|
+
BOBA: '288',
|
|
44
|
+
KUCOIN: '321',
|
|
45
|
+
ZKSYNC_ERA: '324',
|
|
46
|
+
SHIDEN: '336',
|
|
47
|
+
THETA: '361',
|
|
48
|
+
SX: '416',
|
|
49
|
+
CANDLE: '534',
|
|
50
|
+
ASTAR: '592',
|
|
51
|
+
CALLISTO: '820',
|
|
52
|
+
WANCHAIN: '888',
|
|
53
|
+
POLYGON_ZKEVM: '1101',
|
|
54
|
+
METIS: '1088',
|
|
55
|
+
OMCHAIN: '1246',
|
|
56
|
+
MOONBEAM: '1284',
|
|
57
|
+
MOONRIVER: '1285',
|
|
58
|
+
MOONBASE: '1287',
|
|
59
|
+
DEV: '2018',
|
|
60
|
+
RONIN: '2020',
|
|
61
|
+
KAVA: '2222',
|
|
62
|
+
EZCHAIN: '2612',
|
|
63
|
+
PHI: '4181',
|
|
64
|
+
IOTEX: '4689',
|
|
65
|
+
XLC: '5050',
|
|
66
|
+
NAHMII: '5551',
|
|
67
|
+
NMACTEST: '7777',
|
|
68
|
+
KLAYTN: '8217',
|
|
69
|
+
EVMOS: '9001',
|
|
70
|
+
BASE_GOERLI: '84531',
|
|
71
|
+
SMARTBCH: '10000',
|
|
72
|
+
CRYSTALEUM: '103090',
|
|
73
|
+
FUSION: '32659',
|
|
74
|
+
ARBITRUM: '42161',
|
|
75
|
+
CELO: '42220',
|
|
76
|
+
OASIS: '42262',
|
|
77
|
+
AVALANCHE: '43114',
|
|
78
|
+
GODWOKEN: '71402',
|
|
79
|
+
AKROMA: '200625',
|
|
80
|
+
POLIS: '333999',
|
|
81
|
+
ARBITRUM_GOERLI: '421613',
|
|
82
|
+
SEPOLIA: '11155111',
|
|
83
|
+
AURORA: '1313161554',
|
|
84
|
+
HARMONY: '1666600000',
|
|
85
|
+
PALM: '11297108109',
|
|
86
|
+
CURIO: '836542336838601',
|
|
87
|
+
SOLANA_MAINNET: 'sol_mainnet',
|
|
88
|
+
SOLANA_DEVNET: 'sol_devnet',
|
|
89
|
+
SOLANA_TESTNET: 'sol_testnet',
|
|
90
|
+
SOLANA_PYTH: 'sol_pyth',
|
|
91
|
+
SUI_MAINNET: 'sui_mainnet',
|
|
92
|
+
SUI_TESTNET: 'sui_testnet',
|
|
93
|
+
SUI_DEVNET: 'sui_devnet',
|
|
94
|
+
APTOS_MAINNET: 'aptos_mainnet',
|
|
95
|
+
APTOS_TESTNET: 'aptos_testnet',
|
|
96
|
+
APTOS_DEVNET: 'aptos_devnet',
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const CHAIN_MAP: Record<string, string> = {}
|
|
100
|
+
|
|
101
|
+
for (const [key, value] of Object.entries(CHAIN_IDS)) {
|
|
102
|
+
if (value === CHAIN_IDS.POLYGON_ZKEVM) {
|
|
103
|
+
CHAIN_MAP[value] = 'Polygon zkEVM'
|
|
104
|
+
} else if (value === CHAIN_IDS.ZKSYNC_ERA) {
|
|
105
|
+
CHAIN_MAP[value] = 'zkSync Era'
|
|
106
|
+
} else {
|
|
107
|
+
const parts = key.split('_')
|
|
108
|
+
CHAIN_MAP[value] = parts
|
|
109
|
+
.map((part, index) => {
|
|
110
|
+
return part[0] + part.slice(1).toLowerCase()
|
|
111
|
+
})
|
|
112
|
+
.join(' ')
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function getChainName(chainId: string | number | null | undefined): string {
|
|
117
|
+
if (typeof chainId === 'number') {
|
|
118
|
+
chainId = chainId.toString()
|
|
119
|
+
}
|
|
120
|
+
if (chainId) {
|
|
121
|
+
const name = CHAIN_MAP[chainId]
|
|
122
|
+
if (name) {
|
|
123
|
+
return name
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return chainId || ''
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function getChainType(chainId?: string | number): string {
|
|
130
|
+
const id = String(chainId).toLowerCase()
|
|
131
|
+
if (id.startsWith('sol')) {
|
|
132
|
+
return 'solana'
|
|
133
|
+
}
|
|
134
|
+
if (id.startsWith('sui')) {
|
|
135
|
+
return 'sui'
|
|
136
|
+
}
|
|
137
|
+
if (id.startsWith('apt')) {
|
|
138
|
+
return 'aptos'
|
|
139
|
+
}
|
|
140
|
+
return 'EVM'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function getChainScanUrl(
|
|
144
|
+
chainId?: string | number,
|
|
145
|
+
hash?: string,
|
|
146
|
+
subtype?: 'block' | 'address' | 'transaction'
|
|
147
|
+
): string | undefined {
|
|
148
|
+
const chainName = getChainName(chainId)
|
|
149
|
+
if (chainName === 'Ethereum') {
|
|
150
|
+
if (subtype === 'block') {
|
|
151
|
+
return `https://etherscan.io/block/${hash}`
|
|
152
|
+
} else if (subtype === 'address') {
|
|
153
|
+
return `https://etherscan.io/address/${hash}`
|
|
154
|
+
} else {
|
|
155
|
+
return `https://etherscan.io/tx/${hash}`
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (chainName === 'Polygon') {
|
|
159
|
+
if (subtype === 'block') {
|
|
160
|
+
return `https://polygonscan.com/block/${hash}`
|
|
161
|
+
} else if (subtype === 'address') {
|
|
162
|
+
return `https://polygonscan.com/address/${hash}`
|
|
163
|
+
} else {
|
|
164
|
+
return `https://polygonscan.com/tx/${hash}`
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (chainName.startsWith('Aptos ')) {
|
|
168
|
+
if (subtype === 'block') {
|
|
169
|
+
return `https://explorer.aptos.io/block/${hash}`
|
|
170
|
+
} else if (subtype === 'address') {
|
|
171
|
+
return `https://explorer.aptos.io/account/${hash}`
|
|
172
|
+
} else {
|
|
173
|
+
return `https://explorer.aptos.io/txn/${hash}`
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (chainName.startsWith('Solana ')) {
|
|
177
|
+
if (subtype === 'block') {
|
|
178
|
+
return `https://explorer.solana.com/block/${hash}`
|
|
179
|
+
} else if (subtype === 'address') {
|
|
180
|
+
return `https://explorer.solana.com/address/${hash}`
|
|
181
|
+
} else {
|
|
182
|
+
return `https://explorer.solana.io/tx/${hash}`
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (chainName.startsWith('Sui ')) {
|
|
186
|
+
if (subtype === 'block') {
|
|
187
|
+
return `https://explorer.sui.io/block/${hash}`
|
|
188
|
+
} else if (subtype === 'address') {
|
|
189
|
+
return `https://explorer.sui.io/address/${hash}`
|
|
190
|
+
} else {
|
|
191
|
+
return `https://explorer.sui.io/transaction/${hash}`
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return undefined
|
|
195
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -5,10 +5,10 @@ import commandLineUsage from 'command-line-usage'
|
|
|
5
5
|
import fs from 'fs'
|
|
6
6
|
import path from 'path'
|
|
7
7
|
|
|
8
|
-
import yaml from '
|
|
9
|
-
import {
|
|
8
|
+
import yaml from 'yaml'
|
|
9
|
+
import { YamlProjectConfig } from './config.js'
|
|
10
10
|
import chalk from 'chalk'
|
|
11
|
-
import {
|
|
11
|
+
import { buildProcessorWithArgs, generate } from './commands/build.js'
|
|
12
12
|
import { runCreate } from './commands/run-create.js'
|
|
13
13
|
import { runVersion } from './commands/run-version.js'
|
|
14
14
|
import { runLogin } from './commands/run-login.js'
|
|
@@ -41,7 +41,7 @@ if (mainOptions.command === 'login') {
|
|
|
41
41
|
// TODO move them to their own modules
|
|
42
42
|
|
|
43
43
|
// Process configs
|
|
44
|
-
let processorConfig:
|
|
44
|
+
let processorConfig: YamlProjectConfig = { host: '', project: '', build: true, debug: false, contracts: [] }
|
|
45
45
|
// Fist step, read from project yaml file
|
|
46
46
|
try {
|
|
47
47
|
console.log(chalk.blue('Loading Process config'))
|
|
@@ -59,7 +59,7 @@ if (mainOptions.command === 'login') {
|
|
|
59
59
|
process.exit(1)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
processorConfig = yaml.
|
|
62
|
+
processorConfig = yaml.parse(fs.readFileSync('sentio.yaml', 'utf8')) as YamlProjectConfig
|
|
63
63
|
if (!processorConfig.project === undefined) {
|
|
64
64
|
console.error('Config yaml must have contain a valid project identifier')
|
|
65
65
|
process.exit(1)
|
|
@@ -95,7 +95,7 @@ if (mainOptions.command === 'login') {
|
|
|
95
95
|
} else if (mainOptions.command === 'build') {
|
|
96
96
|
await buildProcessorWithArgs(argv)
|
|
97
97
|
} else if (mainOptions.command === 'gen') {
|
|
98
|
-
await
|
|
98
|
+
await generate(argv)
|
|
99
99
|
} else {
|
|
100
100
|
usage()
|
|
101
101
|
}
|
package/src/commands/build.ts
CHANGED
|
@@ -6,6 +6,9 @@ import * as process from 'process'
|
|
|
6
6
|
import { getPackageRoot } from '../utils.js'
|
|
7
7
|
import commandLineArgs from 'command-line-args'
|
|
8
8
|
import commandLineUsage from 'command-line-usage'
|
|
9
|
+
import yaml from 'yaml'
|
|
10
|
+
import { YamlProjectConfig } from '../config.js'
|
|
11
|
+
import { getABIFilePath, getABI, writeABIFile } from '../abi.js'
|
|
9
12
|
|
|
10
13
|
export const buildOptionDefinitions = [
|
|
11
14
|
{
|
|
@@ -24,14 +27,27 @@ export const buildOptionDefinitions = [
|
|
|
24
27
|
type: Boolean,
|
|
25
28
|
description: 'Skip dependency enforce.',
|
|
26
29
|
},
|
|
30
|
+
{
|
|
31
|
+
name: 'example',
|
|
32
|
+
type: Boolean,
|
|
33
|
+
description: 'Generate example usage of the processor.',
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
export const GenOptionDefinitions = [
|
|
38
|
+
{
|
|
39
|
+
name: 'example',
|
|
40
|
+
type: Boolean,
|
|
41
|
+
description: 'Generate example usage of the processor.',
|
|
42
|
+
},
|
|
27
43
|
]
|
|
28
44
|
|
|
29
45
|
export async function buildProcessorWithArgs(argv: string[]) {
|
|
30
46
|
const options = commandLineArgs(buildOptionDefinitions, { argv })
|
|
31
47
|
const usage = commandLineUsage([
|
|
32
48
|
{
|
|
33
|
-
header: '
|
|
34
|
-
content: 'sentio
|
|
49
|
+
header: 'Build project',
|
|
50
|
+
content: 'sentio build',
|
|
35
51
|
},
|
|
36
52
|
{
|
|
37
53
|
header: 'Options',
|
|
@@ -46,13 +62,33 @@ export async function buildProcessorWithArgs(argv: string[]) {
|
|
|
46
62
|
await buildProcessor(false, options)
|
|
47
63
|
}
|
|
48
64
|
|
|
65
|
+
export async function generate(argv: string[]) {
|
|
66
|
+
const options = commandLineArgs(GenOptionDefinitions, { argv })
|
|
67
|
+
const usage = commandLineUsage([
|
|
68
|
+
{
|
|
69
|
+
header: 'Generate type binding',
|
|
70
|
+
content: 'sentio gen [--example]',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
header: 'Options',
|
|
74
|
+
optionList: GenOptionDefinitions,
|
|
75
|
+
},
|
|
76
|
+
])
|
|
77
|
+
|
|
78
|
+
if (options.help) {
|
|
79
|
+
console.log(usage)
|
|
80
|
+
process.exit(0)
|
|
81
|
+
}
|
|
82
|
+
await buildProcessor(true, options)
|
|
83
|
+
}
|
|
84
|
+
|
|
49
85
|
export async function buildProcessor(onlyGen: boolean, options: commandLineArgs.CommandLineOptions) {
|
|
50
86
|
if (!options['skip-deps'] && !onlyGen) {
|
|
51
87
|
await installDeps()
|
|
52
88
|
}
|
|
53
89
|
|
|
54
90
|
if (!options['skip-gen']) {
|
|
55
|
-
await codegen()
|
|
91
|
+
await codegen(options.example || false)
|
|
56
92
|
}
|
|
57
93
|
|
|
58
94
|
if (!onlyGen) {
|
|
@@ -87,8 +123,21 @@ import 'mine.js'
|
|
|
87
123
|
}
|
|
88
124
|
}
|
|
89
125
|
|
|
90
|
-
export async function codegen() {
|
|
126
|
+
export async function codegen(genExample: boolean) {
|
|
127
|
+
const processorConfig = yaml.parse(fs.readFileSync('sentio.yaml', 'utf8')) as YamlProjectConfig
|
|
128
|
+
|
|
129
|
+
for (const contract of processorConfig.contracts || []) {
|
|
130
|
+
const outputPath = getABIFilePath(contract.chain, contract.name || contract.address)
|
|
131
|
+
if (fs.existsSync(outputPath)) {
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
console.log('Download Missing ABI specified in sentio.yaml')
|
|
135
|
+
const res = await getABI(contract.chain, contract.address, contract.name)
|
|
136
|
+
writeABIFile(res.abi, outputPath)
|
|
137
|
+
}
|
|
138
|
+
|
|
91
139
|
const outputBase = path.resolve('src', 'types')
|
|
140
|
+
|
|
92
141
|
try {
|
|
93
142
|
// @ts-ignore dynamic import
|
|
94
143
|
const codegen = await import('@sentio/sdk/eth/codegen')
|
|
@@ -100,7 +149,7 @@ export async function codegen() {
|
|
|
100
149
|
}
|
|
101
150
|
fs.emptyDirSync(output)
|
|
102
151
|
// @ts-ignore dynamic import
|
|
103
|
-
await codegen.codegen(input, output)
|
|
152
|
+
await codegen.codegen(input, output, processorConfig.contracts)
|
|
104
153
|
} catch (e) {
|
|
105
154
|
console.error('code gen error', e)
|
|
106
155
|
}
|
|
@@ -113,7 +162,7 @@ export async function codegen() {
|
|
|
113
162
|
fs.emptyDirSync(output)
|
|
114
163
|
|
|
115
164
|
// @ts-ignore dynamic import
|
|
116
|
-
await codegen.codegen(path.resolve('abis', 'solana'), output)
|
|
165
|
+
await codegen.codegen(path.resolve('abis', 'solana'), output, genExample)
|
|
117
166
|
} catch (e) {
|
|
118
167
|
console.error('code gen error', e)
|
|
119
168
|
}
|
|
@@ -126,7 +175,7 @@ export async function codegen() {
|
|
|
126
175
|
fs.emptyDirSync(output)
|
|
127
176
|
|
|
128
177
|
// @ts-ignore dynamic import
|
|
129
|
-
await codegen.codegen(path.resolve('abis', 'aptos'), output)
|
|
178
|
+
await codegen.codegen(path.resolve('abis', 'aptos'), output, genExample)
|
|
130
179
|
} catch (e) {
|
|
131
180
|
console.error('code gen error', e)
|
|
132
181
|
}
|
|
@@ -139,7 +188,7 @@ export async function codegen() {
|
|
|
139
188
|
fs.emptyDirSync(output)
|
|
140
189
|
|
|
141
190
|
// @ts-ignore dynamic import
|
|
142
|
-
await codegen.codegen(path.resolve('abis', 'sui'), output)
|
|
191
|
+
await codegen.codegen(path.resolve('abis', 'sui'), output, genExample)
|
|
143
192
|
} catch (e) {
|
|
144
193
|
console.error('code gen error', e)
|
|
145
194
|
}
|
package/src/commands/run-add.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import commandLineArgs from 'command-line-args'
|
|
2
2
|
import commandLineUsage from 'command-line-usage'
|
|
3
|
-
import path from 'path'
|
|
4
3
|
import fs from 'fs-extra'
|
|
5
4
|
import chalk from 'chalk'
|
|
6
5
|
|
|
7
6
|
import { codegen } from './build.js'
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import { JsonRpcProvider } from '@mysten/sui.js'
|
|
8
|
+
import * as process from 'process'
|
|
9
|
+
import yaml from 'yaml'
|
|
10
|
+
import { getABIFilePath, getABI, writeABIFile } from '../abi.js'
|
|
13
11
|
|
|
14
12
|
export async function runAdd(argv: string[]) {
|
|
15
13
|
const optionDefinitions = [
|
|
@@ -23,9 +21,9 @@ export async function runAdd(argv: string[]) {
|
|
|
23
21
|
name: 'chain',
|
|
24
22
|
alias: 'c',
|
|
25
23
|
type: String,
|
|
26
|
-
defaultValue: '
|
|
24
|
+
defaultValue: '1',
|
|
27
25
|
description:
|
|
28
|
-
'Chain
|
|
26
|
+
'Chain id define from here: https://raw.githubusercontent.com/sentioxyz/sentio-sdk/main/packages/sdk/src/core/chain.ts notice some chain may not support this command',
|
|
29
27
|
},
|
|
30
28
|
{
|
|
31
29
|
name: 'address',
|
|
@@ -64,91 +62,38 @@ export async function runAdd(argv: string[]) {
|
|
|
64
62
|
process.exit(1)
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let suiClient: JsonRpcProvider | undefined
|
|
70
|
-
switch (chain) {
|
|
71
|
-
case 'aptos':
|
|
72
|
-
aptosClient = new AptosClient('https://mainnet.aptoslabs.com/')
|
|
73
|
-
break
|
|
74
|
-
case 'aptos/testnet':
|
|
75
|
-
aptosClient = new AptosClient('https://testnet.aptoslabs.com/')
|
|
76
|
-
break
|
|
77
|
-
case 'sui':
|
|
78
|
-
throw Error('SUI mainnet is not support yet, try sui/testnet')
|
|
79
|
-
// suiClient = new JsonRpcProvider('https://fullnode.mainnet.sui.io/')
|
|
80
|
-
// break
|
|
81
|
-
case 'sui/testnet':
|
|
82
|
-
suiClient = new JsonRpcProvider('https://fullnode.testnet.sui.io/')
|
|
83
|
-
break
|
|
84
|
-
case 'mainnet':
|
|
85
|
-
case 'homestead':
|
|
86
|
-
ethApi = init()
|
|
87
|
-
break
|
|
88
|
-
default:
|
|
89
|
-
ethApi = init(undefined, chain)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const baseErrMsg = chalk.red(
|
|
93
|
-
`Failed to automatic download contract ${address} from ${chain}, please manually download abi and put it into abis/eth directory`
|
|
94
|
-
)
|
|
65
|
+
const abiRes = await getABI(chain, address, options.name)
|
|
66
|
+
const filename = abiRes.name || address
|
|
95
67
|
|
|
96
|
-
|
|
68
|
+
writeABIFile(abiRes.abi, getABIFilePath(chain, filename))
|
|
97
69
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
process.exit(1)
|
|
105
|
-
}
|
|
70
|
+
// Write contract info to sentio.yaml
|
|
71
|
+
const yamlDocument: yaml.Document = yaml.parseDocument(fs.readFileSync('sentio.yaml', 'utf8'))
|
|
72
|
+
let contracts = yamlDocument.get('contracts') as yaml.YAMLSeq
|
|
73
|
+
if (!contracts) {
|
|
74
|
+
contracts = new yaml.YAMLSeq()
|
|
75
|
+
yamlDocument.set('contracts', contracts)
|
|
106
76
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.error(baseErrMsg, e)
|
|
113
|
-
process.exit(1)
|
|
77
|
+
|
|
78
|
+
let hasContract = false
|
|
79
|
+
for (const item of contracts.items as yaml.YAMLMap[]) {
|
|
80
|
+
if (item.get('chain') === chain && item.get('address') === address) {
|
|
81
|
+
hasContract = true
|
|
114
82
|
}
|
|
115
83
|
}
|
|
116
84
|
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
writeToDirectory(resp.result, chain, filename)
|
|
124
|
-
} catch (e) {
|
|
125
|
-
console.error(baseErrMsg, e)
|
|
126
|
-
process.exit(1)
|
|
85
|
+
if (!hasContract) {
|
|
86
|
+
const newContract = new yaml.YAMLMap()
|
|
87
|
+
newContract.set('chain', chain)
|
|
88
|
+
newContract.set('address', address)
|
|
89
|
+
if (address !== filename) {
|
|
90
|
+
newContract.set('name', filename)
|
|
127
91
|
}
|
|
92
|
+
contracts.add(newContract)
|
|
93
|
+
fs.writeFileSync('sentio.yaml', yamlDocument.toString(), 'utf8')
|
|
128
94
|
}
|
|
129
|
-
// Run gen
|
|
130
|
-
await codegen()
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
95
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
obj = JSON.parse(obj)
|
|
137
|
-
}
|
|
138
|
-
const data = JSON.stringify(obj, null, 2)
|
|
139
|
-
let subpath = chain
|
|
140
|
-
switch (chain) {
|
|
141
|
-
case 'aptos':
|
|
142
|
-
case 'aptos/testnet':
|
|
143
|
-
case 'sui':
|
|
144
|
-
case 'sui/testnet':
|
|
145
|
-
break
|
|
146
|
-
default:
|
|
147
|
-
subpath = 'eth'
|
|
96
|
+
// Run gen
|
|
97
|
+
await codegen(false)
|
|
148
98
|
}
|
|
149
|
-
|
|
150
|
-
const output = path.join('abis', subpath, name + '.json')
|
|
151
|
-
fs.mkdirSync(path.dirname(output), { recursive: true })
|
|
152
|
-
fs.writeFileSync(output, data)
|
|
153
|
-
console.log(chalk.green('ABI has been downloaded to', output))
|
|
154
99
|
}
|