@alephium/web3 0.3.0-rc.3 → 0.3.0-rc.5
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/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +1 -1
- package/dist/src/api/api-alephium.js +1 -1
- package/dist/src/contract/contract.d.ts +21 -21
- package/dist/src/contract/contract.js +103 -108
- package/dist/src/signer/index.d.ts +1 -0
- package/dist/src/signer/index.js +1 -0
- package/dist/src/signer/signer.d.ts +19 -101
- package/dist/src/signer/signer.js +47 -19
- package/dist/src/signer/types.d.ts +109 -0
- package/dist/src/signer/types.js +30 -0
- package/dist/src/transaction/index.d.ts +1 -0
- package/dist/src/transaction/index.js +1 -0
- package/dist/src/transaction/sign-verify.d.ts +2 -0
- package/dist/src/transaction/sign-verify.js +62 -0
- package/package.json +3 -2
- package/src/api/api-alephium.ts +1 -1
- package/src/contract/contract.ts +143 -121
- package/src/signer/index.ts +1 -0
- package/src/signer/signer.ts +80 -130
- package/src/signer/types.ts +148 -0
- package/src/transaction/index.ts +1 -0
- package/src/transaction/sign-verify.ts +38 -0
- package/webpack.config.js +1 -0
package/src/contract/contract.ts
CHANGED
|
@@ -46,6 +46,7 @@ import * as ralph from './ralph'
|
|
|
46
46
|
import { bs58, binToHex, contractIdFromAddress, assertType, Eq } from '../utils'
|
|
47
47
|
import { getCurrentNodeProvider } from '../global'
|
|
48
48
|
import { web3 } from '..'
|
|
49
|
+
import * as path from 'path'
|
|
49
50
|
|
|
50
51
|
export type FieldsSig = node.FieldsSig
|
|
51
52
|
export type EventSig = node.EventSig
|
|
@@ -53,7 +54,7 @@ export type FunctionSig = node.FunctionSig
|
|
|
53
54
|
export type Fields = NamedVals
|
|
54
55
|
export type Arguments = NamedVals
|
|
55
56
|
|
|
56
|
-
enum
|
|
57
|
+
enum SourceKind {
|
|
57
58
|
Contract = 0,
|
|
58
59
|
Script = 1,
|
|
59
60
|
AbstractContract = 2,
|
|
@@ -75,7 +76,7 @@ export const DEFAULT_NODE_COMPILER_OPTIONS: node.CompilerOptions = {
|
|
|
75
76
|
|
|
76
77
|
export const DEFAULT_COMPILER_OPTIONS: CompilerOptions = { errorOnWarnings: true, ...DEFAULT_NODE_COMPILER_OPTIONS }
|
|
77
78
|
|
|
78
|
-
class TypedMatcher<T extends
|
|
79
|
+
class TypedMatcher<T extends SourceKind> {
|
|
79
80
|
matcher: RegExp
|
|
80
81
|
type: T
|
|
81
82
|
|
|
@@ -83,49 +84,63 @@ class TypedMatcher<T extends SourceType> {
|
|
|
83
84
|
this.matcher = new RegExp(pattern, 'mg')
|
|
84
85
|
this.type = type
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
-
match(str: string): number {
|
|
88
|
-
const results = str.match(this.matcher)
|
|
89
|
-
return results === null ? 0 : results.length
|
|
90
|
-
}
|
|
91
87
|
}
|
|
92
88
|
|
|
93
|
-
class
|
|
94
|
-
type:
|
|
95
|
-
|
|
89
|
+
class SourceInfo {
|
|
90
|
+
type: SourceKind
|
|
91
|
+
name: string
|
|
92
|
+
contractRelativePath: string
|
|
96
93
|
sourceCode: string
|
|
97
94
|
sourceCodeHash: string
|
|
98
95
|
|
|
99
96
|
getArtifactPath(artifactsRootDir: string): string {
|
|
100
|
-
return artifactsRootDir
|
|
97
|
+
return path.join(artifactsRootDir, this.contractRelativePath) + '.json'
|
|
101
98
|
}
|
|
102
99
|
|
|
103
|
-
constructor(
|
|
100
|
+
constructor(
|
|
101
|
+
type: SourceKind,
|
|
102
|
+
name: string,
|
|
103
|
+
sourceCode: string,
|
|
104
|
+
sourceCodeHash: string,
|
|
105
|
+
contractRelativePath: string
|
|
106
|
+
) {
|
|
104
107
|
this.type = type
|
|
108
|
+
this.name = name
|
|
105
109
|
this.sourceCode = sourceCode
|
|
106
110
|
this.sourceCodeHash = sourceCodeHash
|
|
107
|
-
this.
|
|
111
|
+
this.contractRelativePath = contractRelativePath
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
static async from(
|
|
114
|
+
static async from(
|
|
115
|
+
type: SourceKind,
|
|
116
|
+
name: string,
|
|
117
|
+
sourceCode: string,
|
|
118
|
+
contractRelativePath: string
|
|
119
|
+
): Promise<SourceInfo> {
|
|
111
120
|
const sourceCodeHash = await crypto.subtle.digest('SHA-256', Buffer.from(sourceCode))
|
|
112
|
-
return new
|
|
121
|
+
return new SourceInfo(type, name, sourceCode, Buffer.from(sourceCodeHash).toString('hex'), contractRelativePath)
|
|
113
122
|
}
|
|
114
123
|
}
|
|
115
124
|
|
|
116
125
|
class Compiled<T extends Artifact> {
|
|
117
|
-
|
|
126
|
+
sourceInfo: SourceInfo
|
|
118
127
|
artifact: T
|
|
119
128
|
warnings: string[]
|
|
120
129
|
|
|
121
|
-
constructor(
|
|
122
|
-
this.
|
|
130
|
+
constructor(sourceInfo: SourceInfo, artifact: T, warnings: string[]) {
|
|
131
|
+
this.sourceInfo = sourceInfo
|
|
123
132
|
this.artifact = artifact
|
|
124
133
|
this.warnings = warnings
|
|
125
134
|
}
|
|
126
135
|
}
|
|
127
136
|
|
|
128
|
-
type CodeInfo = {
|
|
137
|
+
type CodeInfo = {
|
|
138
|
+
sourceFile: string
|
|
139
|
+
sourceCodeHash: string
|
|
140
|
+
bytecodeDebugPatch: string
|
|
141
|
+
codeHashDebug: string
|
|
142
|
+
warnings: string[]
|
|
143
|
+
}
|
|
129
144
|
|
|
130
145
|
class ProjectArtifact {
|
|
131
146
|
static readonly artifactFileName = '.project.json'
|
|
@@ -151,13 +166,16 @@ class ProjectArtifact {
|
|
|
151
166
|
}
|
|
152
167
|
|
|
153
168
|
async saveToFile(rootPath: string): Promise<void> {
|
|
154
|
-
const filepath = rootPath
|
|
155
|
-
const artifact = {
|
|
169
|
+
const filepath = path.join(rootPath, ProjectArtifact.artifactFileName)
|
|
170
|
+
const artifact = {
|
|
171
|
+
compilerOptionsUsed: this.compilerOptionsUsed,
|
|
172
|
+
infos: Object.fromEntries(new Map([...this.infos].sort()))
|
|
173
|
+
}
|
|
156
174
|
const content = JSON.stringify(artifact, null, 2)
|
|
157
175
|
return fsPromises.writeFile(filepath, content)
|
|
158
176
|
}
|
|
159
177
|
|
|
160
|
-
needToReCompile(compilerOptions: node.CompilerOptions,
|
|
178
|
+
needToReCompile(compilerOptions: node.CompilerOptions, sourceInfos: SourceInfo[]): boolean {
|
|
161
179
|
ProjectArtifact.checkCompilerOptionsParameter(compilerOptions)
|
|
162
180
|
|
|
163
181
|
const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
|
|
@@ -168,12 +186,12 @@ class ProjectArtifact {
|
|
|
168
186
|
return true
|
|
169
187
|
}
|
|
170
188
|
|
|
171
|
-
if (
|
|
189
|
+
if (sourceInfos.length !== this.infos.size) {
|
|
172
190
|
return true
|
|
173
191
|
}
|
|
174
|
-
for (const
|
|
175
|
-
const info = this.infos.get(
|
|
176
|
-
if (typeof info === 'undefined' || info.sourceCodeHash !==
|
|
192
|
+
for (const sourceInfo of sourceInfos) {
|
|
193
|
+
const info = this.infos.get(sourceInfo.name)
|
|
194
|
+
if (typeof info === 'undefined' || info.sourceCodeHash !== sourceInfo.sourceCodeHash) {
|
|
177
195
|
return true
|
|
178
196
|
}
|
|
179
197
|
}
|
|
@@ -182,7 +200,7 @@ class ProjectArtifact {
|
|
|
182
200
|
}
|
|
183
201
|
|
|
184
202
|
static async from(rootPath: string): Promise<ProjectArtifact | undefined> {
|
|
185
|
-
const filepath = rootPath
|
|
203
|
+
const filepath = path.join(rootPath, ProjectArtifact.artifactFileName)
|
|
186
204
|
if (!fs.existsSync(filepath)) {
|
|
187
205
|
return undefined
|
|
188
206
|
}
|
|
@@ -195,9 +213,9 @@ class ProjectArtifact {
|
|
|
195
213
|
}
|
|
196
214
|
|
|
197
215
|
export class Project {
|
|
198
|
-
|
|
199
|
-
contracts: Compiled<Contract
|
|
200
|
-
scripts: Compiled<Script
|
|
216
|
+
sourceInfos: SourceInfo[]
|
|
217
|
+
contracts: Map<string, Compiled<Contract>>
|
|
218
|
+
scripts: Map<string, Compiled<Script>>
|
|
201
219
|
projectArtifact: ProjectArtifact
|
|
202
220
|
|
|
203
221
|
readonly contractsRootDir: string
|
|
@@ -205,13 +223,13 @@ export class Project {
|
|
|
205
223
|
|
|
206
224
|
static currentProject: Project
|
|
207
225
|
|
|
208
|
-
static readonly abstractContractMatcher = new TypedMatcher<
|
|
209
|
-
'^Abstract Contract [A-Z][a-zA-Z0-9]*',
|
|
210
|
-
|
|
226
|
+
static readonly abstractContractMatcher = new TypedMatcher<SourceKind>(
|
|
227
|
+
'^Abstract Contract ([A-Z][a-zA-Z0-9]*)',
|
|
228
|
+
SourceKind.AbstractContract
|
|
211
229
|
)
|
|
212
|
-
static readonly contractMatcher = new TypedMatcher('^Contract [A-Z][a-zA-Z0-9]*',
|
|
213
|
-
static readonly interfaceMatcher = new TypedMatcher('^Interface [A-Z][a-zA-Z0-9]* \\{',
|
|
214
|
-
static readonly scriptMatcher = new TypedMatcher('^TxScript [A-Z][a-zA-Z0-9]*',
|
|
230
|
+
static readonly contractMatcher = new TypedMatcher('^Contract ([A-Z][a-zA-Z0-9]*)', SourceKind.Contract)
|
|
231
|
+
static readonly interfaceMatcher = new TypedMatcher('^Interface ([A-Z][a-zA-Z0-9]*) \\{', SourceKind.Interface)
|
|
232
|
+
static readonly scriptMatcher = new TypedMatcher('^TxScript ([A-Z][a-zA-Z0-9]*)', SourceKind.Script)
|
|
215
233
|
static readonly matchers = [
|
|
216
234
|
Project.abstractContractMatcher,
|
|
217
235
|
Project.contractMatcher,
|
|
@@ -220,31 +238,34 @@ export class Project {
|
|
|
220
238
|
]
|
|
221
239
|
|
|
222
240
|
static buildProjectArtifact(
|
|
223
|
-
|
|
224
|
-
contracts: Compiled<Contract
|
|
225
|
-
scripts: Compiled<Script
|
|
241
|
+
sourceInfos: SourceInfo[],
|
|
242
|
+
contracts: Map<string, Compiled<Contract>>,
|
|
243
|
+
scripts: Map<string, Compiled<Script>>,
|
|
226
244
|
compilerOptions: node.CompilerOptions
|
|
227
245
|
): ProjectArtifact {
|
|
228
246
|
const files: Map<string, CodeInfo> = new Map()
|
|
229
247
|
contracts.forEach((c) => {
|
|
230
|
-
files.set(c.
|
|
231
|
-
|
|
248
|
+
files.set(c.artifact.name, {
|
|
249
|
+
sourceFile: c.sourceInfo.contractRelativePath,
|
|
250
|
+
sourceCodeHash: c.sourceInfo.sourceCodeHash,
|
|
232
251
|
bytecodeDebugPatch: c.artifact.bytecodeDebugPatch,
|
|
233
252
|
codeHashDebug: c.artifact.codeHashDebug,
|
|
234
253
|
warnings: c.warnings
|
|
235
254
|
})
|
|
236
255
|
})
|
|
237
256
|
scripts.forEach((s) => {
|
|
238
|
-
files.set(s.
|
|
239
|
-
|
|
257
|
+
files.set(s.artifact.name, {
|
|
258
|
+
sourceFile: s.sourceInfo.contractRelativePath,
|
|
259
|
+
sourceCodeHash: s.sourceInfo.sourceCodeHash,
|
|
240
260
|
bytecodeDebugPatch: s.artifact.bytecodeDebugPatch,
|
|
241
261
|
codeHashDebug: '',
|
|
242
262
|
warnings: s.warnings
|
|
243
263
|
})
|
|
244
264
|
})
|
|
245
|
-
const compiledSize = contracts.
|
|
246
|
-
|
|
247
|
-
files.set(c.
|
|
265
|
+
const compiledSize = contracts.size + scripts.size
|
|
266
|
+
sourceInfos.slice(compiledSize).forEach((c) => {
|
|
267
|
+
files.set(c.name, {
|
|
268
|
+
sourceFile: c.contractRelativePath,
|
|
248
269
|
sourceCodeHash: c.sourceCodeHash,
|
|
249
270
|
bytecodeDebugPatch: '',
|
|
250
271
|
codeHashDebug: '',
|
|
@@ -257,35 +278,30 @@ export class Project {
|
|
|
257
278
|
private constructor(
|
|
258
279
|
contractsRootDir: string,
|
|
259
280
|
artifactsRootDir: string,
|
|
260
|
-
|
|
261
|
-
contracts: Compiled<Contract
|
|
262
|
-
scripts: Compiled<Script
|
|
281
|
+
sourceInfos: SourceInfo[],
|
|
282
|
+
contracts: Map<string, Compiled<Contract>>,
|
|
283
|
+
scripts: Map<string, Compiled<Script>>,
|
|
263
284
|
errorOnWarnings: boolean,
|
|
264
285
|
projectArtifact: ProjectArtifact
|
|
265
286
|
) {
|
|
266
287
|
this.contractsRootDir = contractsRootDir
|
|
267
288
|
this.artifactsRootDir = artifactsRootDir
|
|
268
|
-
this.
|
|
289
|
+
this.sourceInfos = sourceInfos
|
|
269
290
|
this.contracts = contracts
|
|
270
291
|
this.scripts = scripts
|
|
271
292
|
this.projectArtifact = projectArtifact
|
|
272
293
|
|
|
273
294
|
if (errorOnWarnings) {
|
|
274
295
|
Project.checkCompilerWarnings(
|
|
275
|
-
[
|
|
296
|
+
[
|
|
297
|
+
...[...contracts.entries()].map((c) => c[1].warnings).flat(),
|
|
298
|
+
...[...scripts.entries()].map((s) => s[1].warnings).flat()
|
|
299
|
+
],
|
|
276
300
|
errorOnWarnings
|
|
277
301
|
)
|
|
278
302
|
}
|
|
279
303
|
}
|
|
280
304
|
|
|
281
|
-
private getContractPath(path: string): string {
|
|
282
|
-
return path.startsWith(`./${this.contractsRootDir}`)
|
|
283
|
-
? path.slice(2)
|
|
284
|
-
: path.startsWith(this.contractsRootDir)
|
|
285
|
-
? path
|
|
286
|
-
: this.contractsRootDir + '/' + path
|
|
287
|
-
}
|
|
288
|
-
|
|
289
305
|
static checkCompilerWarnings(warnings: string[], errorOnWarnings: boolean): void {
|
|
290
306
|
if (warnings.length !== 0) {
|
|
291
307
|
const prefixPerWarning = ' - '
|
|
@@ -300,7 +316,7 @@ export class Project {
|
|
|
300
316
|
}
|
|
301
317
|
|
|
302
318
|
static contract(name: string): Contract {
|
|
303
|
-
const contract = Project.currentProject.contracts.
|
|
319
|
+
const contract = Project.currentProject.contracts.get(name)
|
|
304
320
|
if (typeof contract === 'undefined') {
|
|
305
321
|
throw new Error(`Contract "${name}" does not exist`)
|
|
306
322
|
}
|
|
@@ -308,7 +324,7 @@ export class Project {
|
|
|
308
324
|
}
|
|
309
325
|
|
|
310
326
|
static script(name: string): Script {
|
|
311
|
-
const script = Project.currentProject.scripts.
|
|
327
|
+
const script = Project.currentProject.scripts.get(name)
|
|
312
328
|
if (typeof script === 'undefined') {
|
|
313
329
|
throw new Error(`Script "${name}" does not exist`)
|
|
314
330
|
}
|
|
@@ -318,24 +334,20 @@ export class Project {
|
|
|
318
334
|
private async saveArtifactsToFile(): Promise<void> {
|
|
319
335
|
const artifactsRootDir = this.artifactsRootDir
|
|
320
336
|
const saveToFile = async function (compiled: Compiled<Artifact>): Promise<void> {
|
|
321
|
-
const
|
|
322
|
-
const
|
|
323
|
-
if (!fs.existsSync(
|
|
324
|
-
fs.mkdirSync(
|
|
337
|
+
const artifactPath = compiled.sourceInfo.getArtifactPath(artifactsRootDir)
|
|
338
|
+
const dirname = path.dirname(artifactPath)
|
|
339
|
+
if (!fs.existsSync(dirname)) {
|
|
340
|
+
fs.mkdirSync(dirname, { recursive: true })
|
|
325
341
|
}
|
|
326
|
-
return fsPromises.writeFile(
|
|
327
|
-
}
|
|
328
|
-
for (const contract of this.contracts) {
|
|
329
|
-
saveToFile(contract)
|
|
330
|
-
}
|
|
331
|
-
for (const script of this.scripts) {
|
|
332
|
-
await saveToFile(script)
|
|
342
|
+
return fsPromises.writeFile(artifactPath, compiled.artifact.toString())
|
|
333
343
|
}
|
|
344
|
+
this.contracts.forEach((contract) => saveToFile(contract))
|
|
345
|
+
this.scripts.forEach((script) => saveToFile(script))
|
|
334
346
|
await this.projectArtifact.saveToFile(this.artifactsRootDir)
|
|
335
347
|
}
|
|
336
348
|
|
|
337
349
|
contractByCodeHash(codeHash: string): Contract {
|
|
338
|
-
const contract = this.contracts.find(
|
|
350
|
+
const contract = [...this.contracts.values()].find(
|
|
339
351
|
(c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash
|
|
340
352
|
)
|
|
341
353
|
if (typeof contract === 'undefined') {
|
|
@@ -346,34 +358,34 @@ export class Project {
|
|
|
346
358
|
|
|
347
359
|
private static async compile(
|
|
348
360
|
provider: NodeProvider,
|
|
349
|
-
|
|
361
|
+
sourceInfos: SourceInfo[],
|
|
350
362
|
contractsRootDir: string,
|
|
351
363
|
artifactsRootDir: string,
|
|
352
364
|
errorOnWarnings: boolean,
|
|
353
365
|
compilerOptions: node.CompilerOptions
|
|
354
366
|
): Promise<Project> {
|
|
355
|
-
const sourceStr =
|
|
367
|
+
const sourceStr = sourceInfos.map((f) => f.sourceCode).join('\n')
|
|
356
368
|
const result = await provider.contracts.postContractsCompileProject({
|
|
357
369
|
code: sourceStr,
|
|
358
370
|
compilerOptions: compilerOptions
|
|
359
371
|
})
|
|
360
|
-
const contracts
|
|
361
|
-
const scripts
|
|
372
|
+
const contracts = new Map<string, Compiled<Contract>>()
|
|
373
|
+
const scripts = new Map<string, Compiled<Script>>()
|
|
362
374
|
result.contracts.forEach((contractResult, index) => {
|
|
363
|
-
const
|
|
375
|
+
const sourceInfo = sourceInfos[`${index}`]
|
|
364
376
|
const contract = Contract.fromCompileResult(contractResult)
|
|
365
|
-
contracts.
|
|
377
|
+
contracts.set(contract.name, new Compiled(sourceInfo, contract, contractResult.warnings))
|
|
366
378
|
})
|
|
367
379
|
result.scripts.forEach((scriptResult, index) => {
|
|
368
|
-
const
|
|
380
|
+
const sourceInfo = sourceInfos[index + contracts.size]
|
|
369
381
|
const script = Script.fromCompileResult(scriptResult)
|
|
370
|
-
scripts.
|
|
382
|
+
scripts.set(script.name, new Compiled(sourceInfo, script, scriptResult.warnings))
|
|
371
383
|
})
|
|
372
|
-
const projectArtifact = Project.buildProjectArtifact(
|
|
384
|
+
const projectArtifact = Project.buildProjectArtifact(sourceInfos, contracts, scripts, compilerOptions)
|
|
373
385
|
const project = new Project(
|
|
374
386
|
contractsRootDir,
|
|
375
387
|
artifactsRootDir,
|
|
376
|
-
|
|
388
|
+
sourceInfos,
|
|
377
389
|
contracts,
|
|
378
390
|
scripts,
|
|
379
391
|
errorOnWarnings,
|
|
@@ -385,7 +397,7 @@ export class Project {
|
|
|
385
397
|
|
|
386
398
|
private static async loadArtifacts(
|
|
387
399
|
provider: NodeProvider,
|
|
388
|
-
|
|
400
|
+
sourceInfos: SourceInfo[],
|
|
389
401
|
projectArtifact: ProjectArtifact,
|
|
390
402
|
contractsRootDir: string,
|
|
391
403
|
artifactsRootDir: string,
|
|
@@ -393,28 +405,28 @@ export class Project {
|
|
|
393
405
|
compilerOptions: node.CompilerOptions
|
|
394
406
|
): Promise<Project> {
|
|
395
407
|
try {
|
|
396
|
-
const contracts
|
|
397
|
-
const scripts
|
|
398
|
-
for (const
|
|
399
|
-
const info = projectArtifact.infos.get(
|
|
408
|
+
const contracts = new Map<string, Compiled<Contract>>()
|
|
409
|
+
const scripts = new Map<string, Compiled<Script>>()
|
|
410
|
+
for (const sourceInfo of sourceInfos) {
|
|
411
|
+
const info = projectArtifact.infos.get(sourceInfo.name)
|
|
400
412
|
if (typeof info === 'undefined') {
|
|
401
|
-
throw Error(`Unable to find project info for ${
|
|
413
|
+
throw Error(`Unable to find project info for ${sourceInfo.name}, please rebuild the project`)
|
|
402
414
|
}
|
|
403
415
|
const warnings = info.warnings
|
|
404
|
-
const artifactDir =
|
|
405
|
-
if (
|
|
416
|
+
const artifactDir = sourceInfo.getArtifactPath(artifactsRootDir)
|
|
417
|
+
if (sourceInfo.type === SourceKind.Contract) {
|
|
406
418
|
const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug)
|
|
407
|
-
contracts.
|
|
408
|
-
} else if (
|
|
419
|
+
contracts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings))
|
|
420
|
+
} else if (sourceInfo.type === SourceKind.Script) {
|
|
409
421
|
const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch)
|
|
410
|
-
scripts.
|
|
422
|
+
scripts.set(artifact.name, new Compiled(sourceInfo, artifact, warnings))
|
|
411
423
|
}
|
|
412
424
|
}
|
|
413
425
|
|
|
414
426
|
return new Project(
|
|
415
427
|
contractsRootDir,
|
|
416
428
|
artifactsRootDir,
|
|
417
|
-
|
|
429
|
+
sourceInfos,
|
|
418
430
|
contracts,
|
|
419
431
|
scripts,
|
|
420
432
|
errorOnWarnings,
|
|
@@ -422,53 +434,63 @@ export class Project {
|
|
|
422
434
|
)
|
|
423
435
|
} catch (error) {
|
|
424
436
|
console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`)
|
|
425
|
-
return Project.compile(
|
|
437
|
+
return Project.compile(
|
|
438
|
+
provider,
|
|
439
|
+
sourceInfos,
|
|
440
|
+
contractsRootDir,
|
|
441
|
+
artifactsRootDir,
|
|
442
|
+
errorOnWarnings,
|
|
443
|
+
compilerOptions
|
|
444
|
+
)
|
|
426
445
|
}
|
|
427
446
|
}
|
|
428
447
|
|
|
429
|
-
private static async loadSourceFile(
|
|
430
|
-
|
|
448
|
+
private static async loadSourceFile(
|
|
449
|
+
contractsRootDir: string,
|
|
450
|
+
dirPath: string,
|
|
451
|
+
filename: string
|
|
452
|
+
): Promise<SourceInfo[]> {
|
|
453
|
+
const contractPath = path.join(dirPath, filename)
|
|
454
|
+
const contractRelativePath = path.relative(contractsRootDir, contractPath)
|
|
431
455
|
if (!filename.endsWith('.ral')) {
|
|
432
456
|
throw new Error(`Invalid filename: ${contractPath}, smart contract file name should end with ".ral"`)
|
|
433
457
|
}
|
|
434
458
|
|
|
435
459
|
const sourceBuffer = await fsPromises.readFile(contractPath)
|
|
436
460
|
const sourceStr = sourceBuffer.toString()
|
|
437
|
-
const
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
461
|
+
const sourceInfos: SourceInfo[] = []
|
|
462
|
+
for (const matcher of this.matchers) {
|
|
463
|
+
const results = sourceStr.matchAll(matcher.matcher)
|
|
464
|
+
for (const result of results) {
|
|
465
|
+
const sourceInfo = await SourceInfo.from(matcher.type, result[1], sourceStr, contractRelativePath)
|
|
466
|
+
sourceInfos.push(sourceInfo)
|
|
467
|
+
}
|
|
444
468
|
}
|
|
445
|
-
|
|
446
|
-
const type = this.matchers[`${matcherIndex}`].type
|
|
447
|
-
return SourceFile.from(type, sourceStr, contractPath)
|
|
469
|
+
return sourceInfos
|
|
448
470
|
}
|
|
449
471
|
|
|
450
|
-
private static async loadSourceFiles(contractsRootDir: string): Promise<
|
|
451
|
-
const loadDir = async function (dirPath: string, results:
|
|
472
|
+
private static async loadSourceFiles(contractsRootDir: string): Promise<SourceInfo[]> {
|
|
473
|
+
const loadDir = async function (dirPath: string, results: SourceInfo[]): Promise<void> {
|
|
452
474
|
const dirents = await fsPromises.readdir(dirPath, { withFileTypes: true })
|
|
453
475
|
for (const dirent of dirents) {
|
|
454
476
|
if (dirent.isFile()) {
|
|
455
|
-
const
|
|
456
|
-
results.push(
|
|
477
|
+
const sourceInfos = await Project.loadSourceFile(contractsRootDir, dirPath, dirent.name)
|
|
478
|
+
results.push(...sourceInfos)
|
|
457
479
|
} else {
|
|
458
|
-
const newPath = dirPath
|
|
480
|
+
const newPath = path.join(dirPath, dirent.name)
|
|
459
481
|
await loadDir(newPath, results)
|
|
460
482
|
}
|
|
461
483
|
}
|
|
462
484
|
}
|
|
463
|
-
const
|
|
464
|
-
await loadDir(contractsRootDir,
|
|
465
|
-
const contractAndScriptSize =
|
|
466
|
-
(f) => f.type ===
|
|
485
|
+
const sourceInfos: SourceInfo[] = []
|
|
486
|
+
await loadDir(contractsRootDir, sourceInfos)
|
|
487
|
+
const contractAndScriptSize = sourceInfos.filter(
|
|
488
|
+
(f) => f.type === SourceKind.Contract || f.type === SourceKind.Script
|
|
467
489
|
).length
|
|
468
|
-
if (
|
|
490
|
+
if (sourceInfos.length === 0 || contractAndScriptSize === 0) {
|
|
469
491
|
throw new Error('Project have no source files')
|
|
470
492
|
}
|
|
471
|
-
return
|
|
493
|
+
return sourceInfos.sort((a, b) => a.type - b.type)
|
|
472
494
|
}
|
|
473
495
|
|
|
474
496
|
static readonly DEFAULT_CONTRACTS_DIR = 'contracts'
|
|
@@ -825,7 +847,7 @@ export class Contract extends Artifact {
|
|
|
825
847
|
): Promise<SignDeployContractTxParams> {
|
|
826
848
|
const bytecode = this.buildByteCodeToDeploy(params.initialFields ? params.initialFields : {})
|
|
827
849
|
const signerParams: SignDeployContractTxParams = {
|
|
828
|
-
signerAddress:
|
|
850
|
+
signerAddress: await signer.getSelectedAddress(),
|
|
829
851
|
bytecode: bytecode,
|
|
830
852
|
initialAttoAlphAmount: params.initialAttoAlphAmount,
|
|
831
853
|
issueTokenAmount: params.issueTokenAmount,
|
|
@@ -922,7 +944,7 @@ export class Script extends Artifact {
|
|
|
922
944
|
params: Omit<BuildExecuteScriptTx, 'signerAddress'>
|
|
923
945
|
): Promise<SignExecuteScriptTxParams> {
|
|
924
946
|
const signerParams: SignExecuteScriptTxParams = {
|
|
925
|
-
signerAddress:
|
|
947
|
+
signerAddress: await signer.getSelectedAddress(),
|
|
926
948
|
bytecode: this.buildByteCodeToDeploy(params.initialFields ? params.initialFields : {}),
|
|
927
949
|
attoAlphAmount: params.attoAlphAmount,
|
|
928
950
|
tokens: params.tokens,
|
package/src/signer/index.ts
CHANGED