@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.
Files changed (83) hide show
  1. package/.eslintignore +2 -2
  2. package/README.md +2 -135
  3. package/contracts/greeter/greeter.ral +1 -1
  4. package/dist/alephium-web3.min.js +1 -1
  5. package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
  6. package/dist/alephium-web3.min.js.map +1 -1
  7. package/dist/scripts/create-project.js +1 -1
  8. package/dist/src/api/api-alephium.d.ts +19 -6
  9. package/dist/src/api/api-explorer.d.ts +16 -16
  10. package/dist/src/api/index.js +5 -1
  11. package/dist/src/contract/contract.d.ts +27 -10
  12. package/dist/src/contract/contract.js +105 -64
  13. package/dist/src/contract/index.js +5 -1
  14. package/dist/src/global.d.ts +3 -0
  15. package/{src/utils/djb2.test.ts → dist/src/global.js} +20 -17
  16. package/dist/src/index.d.ts +2 -0
  17. package/dist/src/index.js +20 -1
  18. package/dist/src/signer/index.d.ts +0 -1
  19. package/dist/src/signer/index.js +5 -2
  20. package/dist/src/signer/signer.d.ts +1 -1
  21. package/dist/src/signer/signer.js +8 -3
  22. package/dist/src/transaction/index.d.ts +0 -1
  23. package/dist/src/transaction/index.js +5 -2
  24. package/dist/src/utils/index.d.ts +0 -1
  25. package/dist/src/utils/index.js +5 -2
  26. package/dist/src/utils/subscription.d.ts +0 -1
  27. package/dist/src/utils/subscription.js +2 -1
  28. package/dist/src/utils/utils.d.ts +3 -2
  29. package/dist/src/utils/utils.js +16 -15
  30. package/jest-config.json +11 -0
  31. package/package.json +6 -32
  32. package/scripts/create-project.ts +1 -1
  33. package/src/api/api-alephium.ts +14 -0
  34. package/src/contract/contract.ts +157 -69
  35. package/src/{test/index.ts → global.ts} +14 -10
  36. package/src/index.ts +3 -0
  37. package/src/signer/index.ts +0 -1
  38. package/src/signer/signer.ts +3 -2
  39. package/src/transaction/index.ts +0 -1
  40. package/src/utils/index.ts +0 -1
  41. package/src/utils/subscription.ts +2 -2
  42. package/src/utils/utils.ts +7 -7
  43. package/templates/base/package.json +2 -2
  44. package/templates/base/src/greeter.ts +8 -7
  45. package/templates/react/package.json +2 -2
  46. package/templates/react/src/App.tsx +2 -2
  47. package/.eslintrc.json +0 -21
  48. package/LICENSE +0 -165
  49. package/contracts/add/add.ral +0 -13
  50. package/contracts/main.ral +0 -4
  51. package/contracts/sub/sub.ral +0 -10
  52. package/contracts/test/metadata.ral +0 -18
  53. package/contracts/test/warnings.ral +0 -8
  54. package/dist/src/signer/node-wallet.d.ts +0 -13
  55. package/dist/src/signer/node-wallet.js +0 -60
  56. package/dist/src/test/index.d.ts +0 -7
  57. package/dist/src/test/index.js +0 -41
  58. package/dist/src/test/privatekey-wallet.d.ts +0 -12
  59. package/dist/src/test/privatekey-wallet.js +0 -68
  60. package/dist/src/transaction/sign-verify.d.ts +0 -2
  61. package/dist/src/transaction/sign-verify.js +0 -58
  62. package/dist/src/utils/password-crypto.d.ts +0 -2
  63. package/dist/src/utils/password-crypto.js +0 -69
  64. package/gitignore +0 -9
  65. package/src/contract/ralph.test.ts +0 -178
  66. package/src/fixtures/address.json +0 -36
  67. package/src/fixtures/balance.json +0 -9
  68. package/src/fixtures/self-clique.json +0 -19
  69. package/src/fixtures/transaction.json +0 -13
  70. package/src/fixtures/transactions.json +0 -179
  71. package/src/signer/fixtures/genesis.json +0 -26
  72. package/src/signer/fixtures/wallets.json +0 -26
  73. package/src/signer/node-wallet.ts +0 -74
  74. package/src/test/privatekey-wallet.ts +0 -58
  75. package/src/transaction/sign-verify.test.ts +0 -50
  76. package/src/transaction/sign-verify.ts +0 -39
  77. package/src/utils/address.test.ts +0 -47
  78. package/src/utils/password-crypto.test.ts +0 -27
  79. package/src/utils/password-crypto.ts +0 -77
  80. package/src/utils/utils.test.ts +0 -161
  81. package/test/contract.test.ts +0 -213
  82. package/test/events.test.ts +0 -143
  83. package/test/transaction.test.ts +0 -74
@@ -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 * as cryptojs from 'crypto-js'
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 DEFAULT_COMPILER_OPTIONS: CompilerOptions = {
48
- errorOnWarnings: true,
49
- ignoreUnusedConstantsWarnings: true
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 = cryptojs.SHA256(sourceCode).toString()
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
- constructor(infos: Map<string, { sourceCodeHash: string; warnings: string[] }>) {
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 content = JSON.stringify(Object.fromEntries(this.infos), null, 2)
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
- sourceHasChanged(files: SourceFile[]): boolean {
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 files = new Map(
132
- Object.entries<{ sourceCodeHash: string; warnings: string[] }>(JSON.parse(content.toString()))
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
- private static checkCompilerWarnings(warnings: string[], compilerOptions: CompilerOptions): void {
188
- const remains = compilerOptions.ignoreUnusedConstantsWarnings
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 + remains.join('\n' + prefixPerWarning)
194
- const output = 'Compilation warnings:\n' + warningString + '\n'
195
- if (compilerOptions.errorOnWarnings) {
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, compilerOptions?: Partial<CompilerOptions>): Contract {
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, compilerOptions?: Partial<CompilerOptions>): Script {
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 project = new Project(provider, contractsRootPath, artifactsRootPath, files, contracts, scripts)
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
- return new Project(provider, contractsRootPath, artifactsRootPath, files, contracts, scripts)
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 new SourceFile(type, sourceStr, contractPath)
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
- provider: NodeProvider,
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.sourceHasChanged(sourceFiles)) {
387
- Project.currentProject = await Project.compile(provider, sourceFiles, contractsRootPath, artifactsRootPath)
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 = crypto.randomBytes(33)
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 '../api'
20
- import { NodeWallet } from '../signer'
19
+ import { NodeProvider } from './api'
21
20
 
22
- export const testWalletName = 'alephium-web3-test-only-wallet'
23
- export const testAddress = '1DrDyTr9RpRsQnDnXo2YRiPzPW4ooHX5LLoqXrqfMrpQH'
24
- export const testPassword = 'alph'
21
+ let _currentNodeProvider: NodeProvider | undefined = undefined
25
22
 
26
- export async function testWallet(provider: NodeProvider): Promise<NodeWallet> {
27
- const wallet = new NodeWallet(provider, testWalletName)
28
- await wallet.unlock(testPassword)
29
- return wallet
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 * from './privatekey-wallet'
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
@@ -23,3 +23,6 @@ export * from './utils'
23
23
  export * from './transaction'
24
24
 
25
25
  export * from './constants'
26
+ export * from './global'
27
+
28
+ export * as utils from './utils'
@@ -17,4 +17,3 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
17
17
  */
18
18
 
19
19
  export * from './signer'
20
- export * from './node-wallet'
@@ -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(provider: NodeProvider, alwaysSubmitTx: boolean) {
171
- this.provider = provider
171
+ constructor(alwaysSubmitTx: boolean) {
172
+ this.provider = getCurrentNodeProvider()
172
173
  this.alwaysSubmitTx = alwaysSubmitTx
173
174
  }
174
175
 
@@ -16,5 +16,4 @@ 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
- export * from './sign-verify'
20
19
  export * from './status'
@@ -19,6 +19,5 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
19
19
  export * from './address'
20
20
  export * from './bs58'
21
21
  export * from './djb2'
22
- export * from './password-crypto'
23
22
  export * from './utils'
24
23
  export * from './subscription'
@@ -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 = options.provider
43
+ this.provider = getCurrentNodeProvider()
44
44
  this.pollingInterval = options.pollingInterval
45
45
  this.messageCallback = options.messageCallback
46
46
  this.errorCallback = options.errorCallback
@@ -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 const signatureDecode = (ec: EC, signature: string): SignatureInput => {
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
- const xorByte = (intValue: number) => {
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 const groupOfAddress = (address: string): number => {
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
- const groupOfAddressBytes = (bytes: Uint8Array): number => {
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
- const groupOfP2pkhAddress = (address: Uint8Array): number => {
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
- const groupOfP2mpkhAddress = (address: Uint8Array): number => {
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
- const groupOfP2shAddress = (address: Uint8Array): number => {
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-rc5"
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.6"
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 { NodeProvider, Contract, Script, TestContractParams } from '@alephium/web3'
6
- import { testWallet } from '@alephium/web3/test'
5
+ import { TestContractParams, setCurrentNodeProvider, Project } from '@alephium/web3'
6
+ import { testNodeWallet } from '@alephium/web3/test'
7
7
 
8
8
  async function greet() {
9
- const provider = new NodeProvider('http://127.0.0.1:22973')
9
+ setCurrentNodeProvider('http://127.0.0.1:22973')
10
+ await Project.build()
10
11
 
11
- const greeter = await Contract.fromSource(provider, 'greeter.ral')
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(provider, 'greet', testParams)
17
+ const testResult = await greeter.testPublicMethod('greet', testParams)
17
18
  console.log(testResult)
18
19
 
19
- const signer = await testWallet(provider)
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 = await Script.fromSource(provider, 'greeter_main.ral')
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-rc5"
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.6",
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",