@alephium/web3 0.2.0-rc.6 → 0.2.0-rc.9
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/.eslintignore +2 -2
- package/README.md +2 -135
- package/contracts/greeter/greeter.ral +1 -1
- package/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/scripts/create-project.js +1 -1
- package/dist/src/api/api-alephium.d.ts +19 -6
- package/dist/src/api/api-explorer.d.ts +16 -16
- package/dist/src/api/index.js +5 -1
- package/dist/src/contract/contract.d.ts +27 -10
- package/dist/src/contract/contract.js +105 -64
- package/dist/src/contract/index.js +5 -1
- package/dist/src/global.d.ts +3 -0
- package/{src/utils/djb2.test.ts → dist/src/global.js} +20 -17
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +20 -1
- package/dist/src/signer/index.d.ts +0 -1
- package/dist/src/signer/index.js +5 -2
- package/dist/src/signer/signer.d.ts +1 -1
- package/dist/src/signer/signer.js +8 -3
- package/dist/src/transaction/index.d.ts +0 -1
- package/dist/src/transaction/index.js +5 -2
- package/dist/src/utils/index.d.ts +0 -1
- package/dist/src/utils/index.js +5 -2
- package/dist/src/utils/subscription.d.ts +0 -1
- package/dist/src/utils/subscription.js +2 -1
- package/dist/src/utils/utils.d.ts +3 -2
- package/dist/src/utils/utils.js +16 -15
- package/jest-config.json +11 -0
- package/package.json +6 -32
- package/scripts/create-project.ts +1 -1
- package/src/api/api-alephium.ts +14 -0
- package/src/contract/contract.ts +157 -69
- package/src/{test/index.ts → global.ts} +14 -10
- package/src/index.ts +3 -0
- package/src/signer/index.ts +0 -1
- package/src/signer/signer.ts +3 -2
- package/src/transaction/index.ts +0 -1
- package/src/utils/index.ts +0 -1
- package/src/utils/subscription.ts +2 -2
- package/src/utils/utils.ts +7 -7
- package/templates/base/package.json +2 -2
- package/templates/base/src/greeter.ts +8 -7
- package/templates/react/package.json +2 -2
- package/templates/react/src/App.tsx +2 -2
- package/.eslintrc.json +0 -21
- package/LICENSE +0 -165
- package/contracts/add/add.ral +0 -13
- package/contracts/main.ral +0 -4
- package/contracts/sub/sub.ral +0 -10
- package/contracts/test/metadata.ral +0 -18
- package/contracts/test/warnings.ral +0 -8
- package/dist/src/signer/node-wallet.d.ts +0 -13
- package/dist/src/signer/node-wallet.js +0 -60
- package/dist/src/test/index.d.ts +0 -7
- package/dist/src/test/index.js +0 -41
- package/dist/src/test/privatekey-wallet.d.ts +0 -12
- package/dist/src/test/privatekey-wallet.js +0 -68
- package/dist/src/transaction/sign-verify.d.ts +0 -2
- package/dist/src/transaction/sign-verify.js +0 -58
- package/dist/src/utils/password-crypto.d.ts +0 -2
- package/dist/src/utils/password-crypto.js +0 -69
- package/gitignore +0 -9
- package/src/contract/ralph.test.ts +0 -178
- package/src/fixtures/address.json +0 -36
- package/src/fixtures/balance.json +0 -9
- package/src/fixtures/self-clique.json +0 -19
- package/src/fixtures/transaction.json +0 -13
- package/src/fixtures/transactions.json +0 -179
- package/src/signer/fixtures/genesis.json +0 -26
- package/src/signer/fixtures/wallets.json +0 -26
- package/src/signer/node-wallet.ts +0 -74
- package/src/test/privatekey-wallet.ts +0 -58
- package/src/transaction/sign-verify.test.ts +0 -50
- package/src/transaction/sign-verify.ts +0 -39
- package/src/utils/address.test.ts +0 -47
- package/src/utils/password-crypto.test.ts +0 -27
- package/src/utils/password-crypto.ts +0 -77
- package/src/utils/utils.test.ts +0 -161
- package/test/contract.test.ts +0 -213
- package/test/events.test.ts +0 -143
- package/test/transaction.test.ts +0 -74
package/src/contract/contract.ts
CHANGED
|
@@ -17,16 +17,15 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { Buffer } from 'buffer/'
|
|
20
|
-
import
|
|
21
|
-
import * as crypto from 'crypto'
|
|
20
|
+
import { webcrypto as crypto } from 'crypto'
|
|
22
21
|
import fs from 'fs'
|
|
23
22
|
import { promises as fsPromises } from 'fs'
|
|
24
|
-
import { NodeProvider } from '../api'
|
|
25
|
-
import { node } from '../api'
|
|
23
|
+
import { node, NodeProvider } from '../api'
|
|
26
24
|
import { SignDeployContractTxParams, SignExecuteScriptTxParams, SignerWithNodeProvider } from '../signer'
|
|
27
25
|
import * as ralph from './ralph'
|
|
28
26
|
import { bs58, binToHex, contractIdFromAddress, assertType, Eq } from '../utils'
|
|
29
27
|
import { CompileContractResult, CompileScriptResult } from '../api/api-alephium'
|
|
28
|
+
import { getCurrentNodeProvider } from '../global'
|
|
30
29
|
|
|
31
30
|
type FieldsSig = node.FieldsSig
|
|
32
31
|
type EventSig = node.EventSig
|
|
@@ -39,16 +38,21 @@ enum SourceType {
|
|
|
39
38
|
Interface = 3
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
export type CompilerOptions = {
|
|
41
|
+
export type CompilerOptions = node.CompilerOptions & {
|
|
43
42
|
errorOnWarnings: boolean
|
|
44
|
-
ignoreUnusedConstantsWarnings: boolean
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
export const
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
export const DEFAULT_NODE_COMPILER_OPTIONS: node.CompilerOptions = {
|
|
46
|
+
ignoreUnusedConstantsWarnings: false,
|
|
47
|
+
ignoreUnusedVariablesWarnings: false,
|
|
48
|
+
ignoreUnusedFieldsWarnings: false,
|
|
49
|
+
ignoreUnusedPrivateFunctionsWarnings: false,
|
|
50
|
+
ignoreReadonlyCheckWarnings: false,
|
|
51
|
+
ignoreExternalCallCheckWarnings: false
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
export const DEFAULT_COMPILER_OPTIONS: CompilerOptions = { errorOnWarnings: true, ...DEFAULT_NODE_COMPILER_OPTIONS }
|
|
55
|
+
|
|
52
56
|
class TypedMatcher<T extends SourceType> {
|
|
53
57
|
matcher: RegExp
|
|
54
58
|
type: T
|
|
@@ -74,12 +78,17 @@ class SourceFile {
|
|
|
74
78
|
return artifactsRootPath + this.contractPath.slice(this.contractPath.indexOf('/')) + '.json'
|
|
75
79
|
}
|
|
76
80
|
|
|
77
|
-
constructor(type: SourceType, sourceCode: string, contractPath: string) {
|
|
81
|
+
constructor(type: SourceType, sourceCode: string, sourceCodeHash: string, contractPath: string) {
|
|
78
82
|
this.type = type
|
|
79
83
|
this.sourceCode = sourceCode
|
|
80
|
-
this.sourceCodeHash =
|
|
84
|
+
this.sourceCodeHash = sourceCodeHash
|
|
81
85
|
this.contractPath = contractPath
|
|
82
86
|
}
|
|
87
|
+
|
|
88
|
+
static async from(type: SourceType, sourceCode: string, contractPath: string): Promise<SourceFile> {
|
|
89
|
+
const sourceCodeHash = await crypto.subtle.digest('SHA-256', Buffer.from(sourceCode))
|
|
90
|
+
return new SourceFile(type, sourceCode, Buffer.from(sourceCodeHash).toString('hex'), contractPath)
|
|
91
|
+
}
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
class Compiled<T extends Artifact> {
|
|
@@ -97,19 +106,47 @@ class Compiled<T extends Artifact> {
|
|
|
97
106
|
class ProjectArtifact {
|
|
98
107
|
static readonly artifactFileName = '.project.json'
|
|
99
108
|
|
|
109
|
+
compilerOptionsUsed: node.CompilerOptions
|
|
100
110
|
infos: Map<string, { sourceCodeHash: string; warnings: string[] }>
|
|
101
111
|
|
|
102
|
-
|
|
112
|
+
static checkCompilerOptionsParameter(compilerOptions: node.CompilerOptions): void {
|
|
113
|
+
if (Object.keys(compilerOptions).length != Object.keys(DEFAULT_NODE_COMPILER_OPTIONS).length) {
|
|
114
|
+
throw Error(`Not all compiler options are set: ${compilerOptions}`)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const combined = { ...compilerOptions, ...DEFAULT_NODE_COMPILER_OPTIONS }
|
|
118
|
+
if (Object.keys(combined).length !== Object.keys(DEFAULT_NODE_COMPILER_OPTIONS).length) {
|
|
119
|
+
throw Error(`There are unknown compiler options: ${compilerOptions}`)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
constructor(
|
|
124
|
+
compilerOptionsUsed: node.CompilerOptions,
|
|
125
|
+
infos: Map<string, { sourceCodeHash: string; warnings: string[] }>
|
|
126
|
+
) {
|
|
127
|
+
ProjectArtifact.checkCompilerOptionsParameter(compilerOptionsUsed)
|
|
128
|
+
this.compilerOptionsUsed = compilerOptionsUsed
|
|
103
129
|
this.infos = infos
|
|
104
130
|
}
|
|
105
131
|
|
|
106
132
|
async saveToFile(rootPath: string): Promise<void> {
|
|
107
133
|
const filepath = rootPath + '/' + ProjectArtifact.artifactFileName
|
|
108
|
-
const
|
|
134
|
+
const artifact = { compilerOptionsUsed: this.compilerOptionsUsed, infos: Object.fromEntries(this.infos) }
|
|
135
|
+
const content = JSON.stringify(artifact, null, 2)
|
|
109
136
|
return fsPromises.writeFile(filepath, content)
|
|
110
137
|
}
|
|
111
138
|
|
|
112
|
-
|
|
139
|
+
needToReCompile(compilerOptions: node.CompilerOptions, files: SourceFile[]): boolean {
|
|
140
|
+
ProjectArtifact.checkCompilerOptionsParameter(compilerOptions)
|
|
141
|
+
|
|
142
|
+
const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
|
|
143
|
+
const usedOption = this.compilerOptionsUsed[`${key}`]
|
|
144
|
+
return usedOption === inputOption
|
|
145
|
+
})
|
|
146
|
+
if (!optionsMatched) {
|
|
147
|
+
return true
|
|
148
|
+
}
|
|
149
|
+
|
|
113
150
|
if (files.length !== this.infos.size) {
|
|
114
151
|
return true
|
|
115
152
|
}
|
|
@@ -119,6 +156,7 @@ class ProjectArtifact {
|
|
|
119
156
|
return true
|
|
120
157
|
}
|
|
121
158
|
}
|
|
159
|
+
|
|
122
160
|
return false
|
|
123
161
|
}
|
|
124
162
|
|
|
@@ -128,10 +166,10 @@ class ProjectArtifact {
|
|
|
128
166
|
return undefined
|
|
129
167
|
}
|
|
130
168
|
const content = await fsPromises.readFile(filepath)
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
)
|
|
134
|
-
return new ProjectArtifact(files)
|
|
169
|
+
const json = JSON.parse(content.toString())
|
|
170
|
+
const compilerOptionsUsed = json.compilerOptionsUsed as node.CompilerOptions
|
|
171
|
+
const files = new Map(Object.entries<{ sourceCodeHash: string; warnings: string[] }>(json.infos))
|
|
172
|
+
return new ProjectArtifact(compilerOptionsUsed, files)
|
|
135
173
|
}
|
|
136
174
|
}
|
|
137
175
|
|
|
@@ -139,6 +177,7 @@ export class Project {
|
|
|
139
177
|
sourceFiles: SourceFile[]
|
|
140
178
|
contracts: Compiled<Contract>[]
|
|
141
179
|
scripts: Compiled<Script>[]
|
|
180
|
+
projectArtifact: ProjectArtifact
|
|
142
181
|
|
|
143
182
|
readonly contractsRootPath: string
|
|
144
183
|
readonly artifactsRootPath: string
|
|
@@ -160,13 +199,44 @@ export class Project {
|
|
|
160
199
|
Project.scriptMatcher
|
|
161
200
|
]
|
|
162
201
|
|
|
202
|
+
static buildProjectArtifact(
|
|
203
|
+
sourceFiles: SourceFile[],
|
|
204
|
+
contracts: Compiled<Contract>[],
|
|
205
|
+
scripts: Compiled<Script>[],
|
|
206
|
+
compilerOptions: node.CompilerOptions
|
|
207
|
+
): ProjectArtifact {
|
|
208
|
+
const files: Map<string, { sourceCodeHash: string; warnings: string[] }> = new Map()
|
|
209
|
+
contracts.forEach((c) => {
|
|
210
|
+
files.set(c.sourceFile.contractPath, {
|
|
211
|
+
sourceCodeHash: c.sourceFile.sourceCodeHash,
|
|
212
|
+
warnings: c.warnings
|
|
213
|
+
})
|
|
214
|
+
})
|
|
215
|
+
scripts.forEach((s) => {
|
|
216
|
+
files.set(s.sourceFile.contractPath, {
|
|
217
|
+
sourceCodeHash: s.sourceFile.sourceCodeHash,
|
|
218
|
+
warnings: s.warnings
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
const compiledSize = contracts.length + scripts.length
|
|
222
|
+
sourceFiles.slice(compiledSize).forEach((c) => {
|
|
223
|
+
files.set(c.contractPath, {
|
|
224
|
+
sourceCodeHash: c.sourceCodeHash,
|
|
225
|
+
warnings: []
|
|
226
|
+
})
|
|
227
|
+
})
|
|
228
|
+
return new ProjectArtifact(compilerOptions, files)
|
|
229
|
+
}
|
|
230
|
+
|
|
163
231
|
private constructor(
|
|
164
232
|
provider: NodeProvider,
|
|
165
233
|
contractsRootPath: string,
|
|
166
234
|
artifactsRootPath: string,
|
|
167
235
|
sourceFiles: SourceFile[],
|
|
168
236
|
contracts: Compiled<Contract>[],
|
|
169
|
-
scripts: Compiled<Script>[]
|
|
237
|
+
scripts: Compiled<Script>[],
|
|
238
|
+
errorOnWarnings: boolean,
|
|
239
|
+
projectArtifact: ProjectArtifact
|
|
170
240
|
) {
|
|
171
241
|
this.nodeProvider = provider
|
|
172
242
|
this.contractsRootPath = contractsRootPath
|
|
@@ -174,6 +244,14 @@ export class Project {
|
|
|
174
244
|
this.sourceFiles = sourceFiles
|
|
175
245
|
this.contracts = contracts
|
|
176
246
|
this.scripts = scripts
|
|
247
|
+
this.projectArtifact = projectArtifact
|
|
248
|
+
|
|
249
|
+
if (errorOnWarnings) {
|
|
250
|
+
Project.checkCompilerWarnings(
|
|
251
|
+
[...contracts.map((c) => c.warnings).flat(), ...scripts.map((s) => s.warnings).flat()],
|
|
252
|
+
errorOnWarnings
|
|
253
|
+
)
|
|
254
|
+
}
|
|
177
255
|
}
|
|
178
256
|
|
|
179
257
|
private getContractPath(path: string): string {
|
|
@@ -184,15 +262,12 @@ export class Project {
|
|
|
184
262
|
: this.contractsRootPath + '/' + path
|
|
185
263
|
}
|
|
186
264
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
? warnings.filter((s) => !s.includes('unused constants'))
|
|
190
|
-
: warnings
|
|
191
|
-
if (remains.length !== 0) {
|
|
265
|
+
static checkCompilerWarnings(warnings: string[], errorOnWarnings: boolean): void {
|
|
266
|
+
if (warnings.length !== 0) {
|
|
192
267
|
const prefixPerWarning = ' - '
|
|
193
|
-
const warningString = prefixPerWarning +
|
|
194
|
-
const output =
|
|
195
|
-
if (
|
|
268
|
+
const warningString = prefixPerWarning + warnings.join('\n' + prefixPerWarning)
|
|
269
|
+
const output = `Compilation warnings:\n` + warningString + '\n'
|
|
270
|
+
if (errorOnWarnings) {
|
|
196
271
|
throw new Error(output)
|
|
197
272
|
} else {
|
|
198
273
|
console.log(output)
|
|
@@ -200,23 +275,21 @@ export class Project {
|
|
|
200
275
|
}
|
|
201
276
|
}
|
|
202
277
|
|
|
203
|
-
static contract(path: string
|
|
278
|
+
static contract(path: string): Contract {
|
|
204
279
|
const contractPath = Project.currentProject.getContractPath(path)
|
|
205
280
|
const contract = Project.currentProject.contracts.find((c) => c.sourceFile.contractPath === contractPath)
|
|
206
281
|
if (typeof contract === 'undefined') {
|
|
207
282
|
throw new Error(`Contract ${contractPath} does not exist`)
|
|
208
283
|
}
|
|
209
|
-
Project.checkCompilerWarnings(contract.warnings, { ...DEFAULT_COMPILER_OPTIONS, ...compilerOptions })
|
|
210
284
|
return contract.artifact
|
|
211
285
|
}
|
|
212
286
|
|
|
213
|
-
static script(path: string
|
|
287
|
+
static script(path: string): Script {
|
|
214
288
|
const contractPath = Project.currentProject.getContractPath(path)
|
|
215
289
|
const script = Project.currentProject.scripts.find((c) => c.sourceFile.contractPath === contractPath)
|
|
216
290
|
if (typeof script === 'undefined') {
|
|
217
291
|
throw new Error(`Script ${contractPath} does not exist`)
|
|
218
292
|
}
|
|
219
|
-
Project.checkCompilerWarnings(script.warnings, { ...DEFAULT_COMPILER_OPTIONS, ...compilerOptions })
|
|
220
293
|
return script.artifact
|
|
221
294
|
}
|
|
222
295
|
|
|
@@ -236,6 +309,7 @@ export class Project {
|
|
|
236
309
|
for (const script of this.scripts) {
|
|
237
310
|
await saveToFile(script)
|
|
238
311
|
}
|
|
312
|
+
await this.projectArtifact.saveToFile(this.artifactsRootPath)
|
|
239
313
|
}
|
|
240
314
|
|
|
241
315
|
contractByCodeHash(codeHash: string): Contract {
|
|
@@ -246,40 +320,18 @@ export class Project {
|
|
|
246
320
|
return contract.artifact
|
|
247
321
|
}
|
|
248
322
|
|
|
249
|
-
private async saveProjectArtifactToFile(): Promise<void> {
|
|
250
|
-
const files: Map<string, { sourceCodeHash: string; warnings: string[] }> = new Map()
|
|
251
|
-
this.contracts.forEach((c) => {
|
|
252
|
-
files.set(c.sourceFile.contractPath, {
|
|
253
|
-
sourceCodeHash: c.sourceFile.sourceCodeHash,
|
|
254
|
-
warnings: c.warnings
|
|
255
|
-
})
|
|
256
|
-
})
|
|
257
|
-
this.scripts.forEach((s) => {
|
|
258
|
-
files.set(s.sourceFile.contractPath, {
|
|
259
|
-
sourceCodeHash: s.sourceFile.sourceCodeHash,
|
|
260
|
-
warnings: s.warnings
|
|
261
|
-
})
|
|
262
|
-
})
|
|
263
|
-
const compiledSize = this.contracts.length + this.scripts.length
|
|
264
|
-
this.sourceFiles.slice(compiledSize).forEach((c) => {
|
|
265
|
-
files.set(c.contractPath, {
|
|
266
|
-
sourceCodeHash: c.sourceCodeHash,
|
|
267
|
-
warnings: []
|
|
268
|
-
})
|
|
269
|
-
})
|
|
270
|
-
const projectArtifact = new ProjectArtifact(files)
|
|
271
|
-
await projectArtifact.saveToFile(this.artifactsRootPath)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
323
|
private static async compile(
|
|
275
324
|
provider: NodeProvider,
|
|
276
325
|
files: SourceFile[],
|
|
277
326
|
contractsRootPath: string,
|
|
278
|
-
artifactsRootPath: string
|
|
327
|
+
artifactsRootPath: string,
|
|
328
|
+
errorOnWarnings: boolean,
|
|
329
|
+
compilerOptions: node.CompilerOptions
|
|
279
330
|
): Promise<Project> {
|
|
280
331
|
const sourceStr = files.map((f) => f.sourceCode).join('\n')
|
|
281
332
|
const result = await provider.contracts.postContractsCompileProject({
|
|
282
|
-
code: sourceStr
|
|
333
|
+
code: sourceStr,
|
|
334
|
+
compilerOptions: compilerOptions
|
|
283
335
|
})
|
|
284
336
|
const contracts: Compiled<Contract>[] = []
|
|
285
337
|
const scripts: Compiled<Script>[] = []
|
|
@@ -293,9 +345,18 @@ export class Project {
|
|
|
293
345
|
const script = Script.fromCompileResult(scriptResult)
|
|
294
346
|
scripts.push(new Compiled(sourceFile, script, scriptResult.warnings))
|
|
295
347
|
})
|
|
296
|
-
const
|
|
348
|
+
const projectArtifact = Project.buildProjectArtifact(files, contracts, scripts, compilerOptions)
|
|
349
|
+
const project = new Project(
|
|
350
|
+
provider,
|
|
351
|
+
contractsRootPath,
|
|
352
|
+
artifactsRootPath,
|
|
353
|
+
files,
|
|
354
|
+
contracts,
|
|
355
|
+
scripts,
|
|
356
|
+
errorOnWarnings,
|
|
357
|
+
projectArtifact
|
|
358
|
+
)
|
|
297
359
|
await project.saveArtifactsToFile()
|
|
298
|
-
await project.saveProjectArtifactToFile()
|
|
299
360
|
return project
|
|
300
361
|
}
|
|
301
362
|
|
|
@@ -304,7 +365,9 @@ export class Project {
|
|
|
304
365
|
files: SourceFile[],
|
|
305
366
|
projectArtifact: ProjectArtifact,
|
|
306
367
|
contractsRootPath: string,
|
|
307
|
-
artifactsRootPath: string
|
|
368
|
+
artifactsRootPath: string,
|
|
369
|
+
errorOnWarnings: boolean,
|
|
370
|
+
compilerOptions: node.CompilerOptions
|
|
308
371
|
): Promise<Project> {
|
|
309
372
|
try {
|
|
310
373
|
const contracts: Compiled<Contract>[] = []
|
|
@@ -324,10 +387,20 @@ export class Project {
|
|
|
324
387
|
scripts.push(new Compiled(file, artifact, warnings))
|
|
325
388
|
}
|
|
326
389
|
}
|
|
327
|
-
|
|
390
|
+
|
|
391
|
+
return new Project(
|
|
392
|
+
provider,
|
|
393
|
+
contractsRootPath,
|
|
394
|
+
artifactsRootPath,
|
|
395
|
+
files,
|
|
396
|
+
contracts,
|
|
397
|
+
scripts,
|
|
398
|
+
errorOnWarnings,
|
|
399
|
+
projectArtifact
|
|
400
|
+
)
|
|
328
401
|
} catch (error) {
|
|
329
402
|
console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`)
|
|
330
|
-
return Project.compile(provider, files, contractsRootPath, artifactsRootPath)
|
|
403
|
+
return Project.compile(provider, files, contractsRootPath, artifactsRootPath, errorOnWarnings, compilerOptions)
|
|
331
404
|
}
|
|
332
405
|
}
|
|
333
406
|
|
|
@@ -349,7 +422,7 @@ export class Project {
|
|
|
349
422
|
}
|
|
350
423
|
const matcherIndex = results.indexOf(1)
|
|
351
424
|
const type = this.matchers[`${matcherIndex}`].type
|
|
352
|
-
return
|
|
425
|
+
return SourceFile.from(type, sourceStr, contractPath)
|
|
353
426
|
}
|
|
354
427
|
|
|
355
428
|
private static async loadSourceFiles(contractsRootPath: string): Promise<SourceFile[]> {
|
|
@@ -377,21 +450,34 @@ export class Project {
|
|
|
377
450
|
}
|
|
378
451
|
|
|
379
452
|
static async build(
|
|
380
|
-
|
|
453
|
+
compilerOptionsPartial: Partial<CompilerOptions> = {},
|
|
381
454
|
contractsRootPath = 'contracts',
|
|
382
455
|
artifactsRootPath = 'artifacts'
|
|
383
456
|
): Promise<void> {
|
|
457
|
+
const provider = getCurrentNodeProvider()
|
|
384
458
|
const sourceFiles = await Project.loadSourceFiles(contractsRootPath)
|
|
459
|
+
const { errorOnWarnings, ...nodeCompilerOptions } = { ...DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial }
|
|
385
460
|
const projectArtifact = await ProjectArtifact.from(artifactsRootPath)
|
|
386
|
-
if (typeof projectArtifact === 'undefined' || projectArtifact.
|
|
387
|
-
|
|
461
|
+
if (typeof projectArtifact === 'undefined' || projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles)) {
|
|
462
|
+
console.log(`Compile contracts in folder "${contractsRootPath}"`)
|
|
463
|
+
Project.currentProject = await Project.compile(
|
|
464
|
+
provider,
|
|
465
|
+
sourceFiles,
|
|
466
|
+
contractsRootPath,
|
|
467
|
+
artifactsRootPath,
|
|
468
|
+
errorOnWarnings,
|
|
469
|
+
nodeCompilerOptions
|
|
470
|
+
)
|
|
388
471
|
} else {
|
|
472
|
+
console.log(`Load compiled contracts from folder "${artifactsRootPath}"`)
|
|
389
473
|
Project.currentProject = await Project.loadArtifacts(
|
|
390
474
|
provider,
|
|
391
475
|
sourceFiles,
|
|
392
476
|
projectArtifact,
|
|
393
477
|
contractsRootPath,
|
|
394
|
-
artifactsRootPath
|
|
478
|
+
artifactsRootPath,
|
|
479
|
+
errorOnWarnings,
|
|
480
|
+
nodeCompilerOptions
|
|
395
481
|
)
|
|
396
482
|
}
|
|
397
483
|
}
|
|
@@ -502,8 +588,10 @@ export class Contract extends Artifact {
|
|
|
502
588
|
}
|
|
503
589
|
}
|
|
504
590
|
|
|
591
|
+
// no need to be cryptographically strong random
|
|
505
592
|
static randomAddress(): string {
|
|
506
|
-
const bytes =
|
|
593
|
+
const bytes = new Uint8Array(33)
|
|
594
|
+
crypto.getRandomValues(bytes)
|
|
507
595
|
bytes[0] = 3
|
|
508
596
|
return bs58.encode(bytes)
|
|
509
597
|
}
|
|
@@ -16,17 +16,21 @@ You should have received a copy of the GNU Lesser General Public License
|
|
|
16
16
|
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { NodeProvider } from '
|
|
20
|
-
import { NodeWallet } from '../signer'
|
|
19
|
+
import { NodeProvider } from './api'
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
export const testAddress = '1DrDyTr9RpRsQnDnXo2YRiPzPW4ooHX5LLoqXrqfMrpQH'
|
|
24
|
-
export const testPassword = 'alph'
|
|
21
|
+
let _currentNodeProvider: NodeProvider | undefined = undefined
|
|
25
22
|
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
export function setCurrentNodeProvider(provider: NodeProvider | string): void {
|
|
24
|
+
if (typeof provider == 'string') {
|
|
25
|
+
_currentNodeProvider = new NodeProvider(provider)
|
|
26
|
+
} else {
|
|
27
|
+
_currentNodeProvider = provider
|
|
28
|
+
}
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
export
|
|
31
|
+
export function getCurrentNodeProvider(): NodeProvider {
|
|
32
|
+
if (typeof _currentNodeProvider === 'undefined') {
|
|
33
|
+
throw Error('No node provider is set.')
|
|
34
|
+
}
|
|
35
|
+
return _currentNodeProvider
|
|
36
|
+
}
|
package/src/index.ts
CHANGED
package/src/signer/index.ts
CHANGED
package/src/signer/signer.ts
CHANGED
|
@@ -23,6 +23,7 @@ import * as utils from '../utils'
|
|
|
23
23
|
import { Eq, assertType } from '../utils'
|
|
24
24
|
import blake from 'blakejs'
|
|
25
25
|
import { Token } from '../api/api-alephium'
|
|
26
|
+
import { getCurrentNodeProvider } from '../global'
|
|
26
27
|
|
|
27
28
|
const ec = new EC('secp256k1')
|
|
28
29
|
|
|
@@ -167,8 +168,8 @@ export abstract class SignerWithNodeProvider implements SignerProvider {
|
|
|
167
168
|
}
|
|
168
169
|
}
|
|
169
170
|
|
|
170
|
-
constructor(
|
|
171
|
-
this.provider =
|
|
171
|
+
constructor(alwaysSubmitTx: boolean) {
|
|
172
|
+
this.provider = getCurrentNodeProvider()
|
|
172
173
|
this.alwaysSubmitTx = alwaysSubmitTx
|
|
173
174
|
}
|
|
174
175
|
|
package/src/transaction/index.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -17,13 +17,13 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import EventEmitter from 'eventemitter3'
|
|
20
|
+
import { getCurrentNodeProvider } from '../global'
|
|
20
21
|
import { NodeProvider } from '../api'
|
|
21
22
|
|
|
22
23
|
type MessageCallback<Message> = (message: Message) => Promise<void>
|
|
23
24
|
type ErrorCallback<Message> = (error: any, subscription: Subscription<Message>) => Promise<void>
|
|
24
25
|
|
|
25
26
|
export interface SubscribeOptions<Message> {
|
|
26
|
-
provider: NodeProvider
|
|
27
27
|
pollingInterval: number
|
|
28
28
|
messageCallback: MessageCallback<Message>
|
|
29
29
|
errorCallback: ErrorCallback<Message>
|
|
@@ -40,7 +40,7 @@ export abstract class Subscription<Message> {
|
|
|
40
40
|
protected cancelled: boolean
|
|
41
41
|
|
|
42
42
|
constructor(options: SubscribeOptions<Message>) {
|
|
43
|
-
this.provider =
|
|
43
|
+
this.provider = getCurrentNodeProvider()
|
|
44
44
|
this.pollingInterval = options.pollingInterval
|
|
45
45
|
this.messageCallback = options.messageCallback
|
|
46
46
|
this.errorCallback = options.errorCallback
|
package/src/utils/utils.ts
CHANGED
|
@@ -51,7 +51,7 @@ export function signatureEncode(signature: EC.Signature): string {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// the signature should be in hex string format for 64 bytes
|
|
54
|
-
export
|
|
54
|
+
export function signatureDecode(ec: EC, signature: string): SignatureInput {
|
|
55
55
|
if (signature.length !== 128) {
|
|
56
56
|
throw new Error('Invalid signature length')
|
|
57
57
|
}
|
|
@@ -66,7 +66,7 @@ export const signatureDecode = (ec: EC, signature: string): SignatureInput => {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
export function xorByte(intValue: number): number {
|
|
70
70
|
const byte0 = (intValue >> 24) & 0xff
|
|
71
71
|
const byte1 = (intValue >> 16) & 0xff
|
|
72
72
|
const byte2 = (intValue >> 8) & 0xff
|
|
@@ -85,7 +85,7 @@ enum AddressType {
|
|
|
85
85
|
P2C = 0x03
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
export
|
|
88
|
+
export function groupOfAddress(address: string): number {
|
|
89
89
|
const decoded = bs58.decode(address)
|
|
90
90
|
|
|
91
91
|
if (decoded.length == 0) throw new Error('Address string is empty')
|
|
@@ -103,7 +103,7 @@ export const groupOfAddress = (address: string): number => {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
function groupOfAddressBytes(bytes: Uint8Array): number {
|
|
107
107
|
const hint = djb2(bytes) | 1
|
|
108
108
|
const hash = xorByte(hint)
|
|
109
109
|
const group = hash % TOTAL_NUMBER_OF_GROUPS
|
|
@@ -111,7 +111,7 @@ const groupOfAddressBytes = (bytes: Uint8Array): number => {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
// Pay to public key hash address
|
|
114
|
-
|
|
114
|
+
function groupOfP2pkhAddress(address: Uint8Array): number {
|
|
115
115
|
if (address.length != 32) {
|
|
116
116
|
throw new Error(`Invalid p2pkh address length: ${address.length}`)
|
|
117
117
|
}
|
|
@@ -120,7 +120,7 @@ const groupOfP2pkhAddress = (address: Uint8Array): number => {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// Pay to multiple public key hash address
|
|
123
|
-
|
|
123
|
+
function groupOfP2mpkhAddress(address: Uint8Array): number {
|
|
124
124
|
if ((address.length - 2) % 32 != 0) {
|
|
125
125
|
throw new Error(`Invalid p2mpkh address length: ${address.length}`)
|
|
126
126
|
}
|
|
@@ -129,7 +129,7 @@ const groupOfP2mpkhAddress = (address: Uint8Array): number => {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// Pay to script hash address
|
|
132
|
-
|
|
132
|
+
function groupOfP2shAddress(address: Uint8Array): number {
|
|
133
133
|
return groupOfAddressBytes(address)
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"license": "GPL",
|
|
5
5
|
"config": {
|
|
6
|
-
"alephium_version": "1.5.0-
|
|
6
|
+
"alephium_version": "1.5.0-rc7"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "rm -rf dist && npx tsc --build .",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"stop-devnet": "node scripts/stop-devnet.js"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@alephium/web3": "0.2.0-rc.
|
|
15
|
+
"@alephium/web3": "0.2.0-rc.9"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/elliptic": "^6.4.13",
|
|
@@ -2,21 +2,22 @@
|
|
|
2
2
|
* greeter.ts
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { TestContractParams, setCurrentNodeProvider, Project } from '@alephium/web3'
|
|
6
|
+
import { testNodeWallet } from '@alephium/web3/test'
|
|
7
7
|
|
|
8
8
|
async function greet() {
|
|
9
|
-
|
|
9
|
+
setCurrentNodeProvider('http://127.0.0.1:22973')
|
|
10
|
+
await Project.build()
|
|
10
11
|
|
|
11
|
-
const greeter =
|
|
12
|
+
const greeter = Project.contract('greeter/greeter.ral')
|
|
12
13
|
|
|
13
14
|
const testParams: TestContractParams = {
|
|
14
15
|
initialFields: { btcPrice: 1 }
|
|
15
16
|
}
|
|
16
|
-
const testResult = await greeter.testPublicMethod(
|
|
17
|
+
const testResult = await greeter.testPublicMethod('greet', testParams)
|
|
17
18
|
console.log(testResult)
|
|
18
19
|
|
|
19
|
-
const signer = await
|
|
20
|
+
const signer = await testNodeWallet()
|
|
20
21
|
|
|
21
22
|
const deployTx = await greeter.transactionForDeployment(signer, { initialFields: testParams.initialFields })
|
|
22
23
|
const greeterContractId = deployTx.contractId
|
|
@@ -26,7 +27,7 @@ async function greet() {
|
|
|
26
27
|
const submitResult = await signer.submitTransaction(deployTx.unsignedTx, deployTx.txId)
|
|
27
28
|
console.log(submitResult)
|
|
28
29
|
|
|
29
|
-
const main =
|
|
30
|
+
const main = Project.script('greeter_main.ral')
|
|
30
31
|
|
|
31
32
|
const mainScriptTx = await main.transactionForDeployment(signer, {
|
|
32
33
|
initialFields: { greeterContractId: greeterContractId }
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "my-dapp",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"alephium_version": "1.5.0-
|
|
5
|
+
"alephium_version": "1.5.0-rc7"
|
|
6
6
|
},
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@testing-library/jest-dom": "^5.16.4",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@types/node": "^16.11.26",
|
|
13
13
|
"@types/react": "^18.0.3",
|
|
14
14
|
"@types/react-dom": "^18.0.0",
|
|
15
|
-
"@alephium/web3": "0.2.0-rc.
|
|
15
|
+
"@alephium/web3": "0.2.0-rc.9",
|
|
16
16
|
"react": "^18.0.0",
|
|
17
17
|
"react-dom": "^18.0.0",
|
|
18
18
|
"react-scripts": "5.0.1",
|