@alephium/web3 0.1.0-rc.3-hc → 0.2.0-rc.1

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.
@@ -847,6 +847,36 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
847
847
  path: `/utils/sanity-check`,
848
848
  method: 'PUT',
849
849
  ...params
850
+ }).then(convertHttpResponse),
851
+
852
+ /**
853
+ * @description Update global log level, accepted: TRACE, DEBUG, INFO, WARN, ERROR
854
+ *
855
+ * @tags Utils
856
+ * @name PutUtilsUpdateGlobalLoglevel
857
+ * @request PUT:/utils/update-global-loglevel
858
+ */
859
+ putUtilsUpdateGlobalLoglevel: (data: 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR', params: RequestParams = {}) =>
860
+ this.request<void, BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
861
+ path: `/utils/update-global-loglevel`,
862
+ method: 'PUT',
863
+ body: data,
864
+ ...params
865
+ }).then(convertHttpResponse),
866
+
867
+ /**
868
+ * @description Update logging file, only logback.xml is accepted
869
+ *
870
+ * @tags Utils
871
+ * @name PutUtilsUpdateLogConfig
872
+ * @request PUT:/utils/update-log-config
873
+ */
874
+ putUtilsUpdateLogConfig: (data: string, params: RequestParams = {}) =>
875
+ this.request<void, BadRequest | Unauthorized | NotFound | InternalServerError | ServiceUnavailable>({
876
+ path: `/utils/update-log-config`,
877
+ method: 'PUT',
878
+ body: data,
879
+ ...params
850
880
  }).then(convertHttpResponse)
851
881
  }
852
882
  }
@@ -27,12 +27,31 @@ import { SignDeployContractTxParams, SignExecuteScriptTxParams, SignerWithNodePr
27
27
  import * as ralph from './ralph'
28
28
  import { bs58, binToHex, contractIdFromAddress, assertType, Eq } from '../utils'
29
29
 
30
+ class SourceFile {
31
+ readonly dirs: string[]
32
+ readonly dirPath: string
33
+ readonly contractPath: string
34
+ readonly artifactPath: string
35
+
36
+ constructor(dirs: string[], fileName: string) {
37
+ this.dirs = dirs
38
+ this.dirPath = dirs.length === 0 ? '' : dirs.join('/') + '/'
39
+ if (fileName.endsWith('.json')) {
40
+ this.contractPath = './contracts/' + this.dirPath + fileName.slice(0, -5)
41
+ this.artifactPath = './artifacts/' + this.dirPath + fileName
42
+ } else {
43
+ this.contractPath = './contracts/' + this.dirPath + fileName
44
+ this.artifactPath = './artifacts/' + this.dirPath + fileName + '.json'
45
+ }
46
+ }
47
+ }
48
+
30
49
  export abstract class Common {
31
50
  readonly sourceCodeSha256: string
32
51
  readonly functions: node.FunctionSig[]
33
52
 
34
- static readonly importRegex = new RegExp('^import "[a-z][a-z_0-9]*.ral"', 'mg')
35
- static readonly contractRegex = new RegExp('^TxContract [A-Z][a-zA-Z0-9]*', 'mg')
53
+ static readonly importRegex = new RegExp('^import "([^"/]+/(([^"]+)/)?)?[a-z][a-z_0-9]*.ral"', 'mg')
54
+ static readonly contractRegex = new RegExp('^(Abstract[ ]+)?Contract [A-Z][a-zA-Z0-9]*', 'mg')
36
55
  static readonly interfaceRegex = new RegExp('^Interface [A-Z][a-zA-Z0-9]* \\{', 'mg')
37
56
  static readonly scriptRegex = new RegExp('^TxScript [A-Z][a-zA-Z0-9]*', 'mg')
38
57
 
@@ -56,38 +75,53 @@ export abstract class Common {
56
75
  this.functions = functions
57
76
  }
58
77
 
59
- protected static _contractPath(fileName: string): string {
60
- if (fileName.endsWith('.json')) {
61
- return `./contracts/${fileName.slice(0, -5)}`
62
- } else {
63
- return `./contracts/${fileName}`
64
- }
78
+ protected static _artifactsFolder(): string {
79
+ return './artifacts/'
65
80
  }
66
81
 
67
- protected static _artifactPath(fileName: string): string {
68
- if (fileName.endsWith('.json')) {
69
- return `./artifacts/${fileName}`
70
- } else {
71
- return `./artifacts/${fileName}.json`
82
+ static getSourceFile(path: string, _dirs: string[]): SourceFile {
83
+ const parts = path.split('/')
84
+ const dirs = Array.from(_dirs)
85
+ if (parts.length === 1) {
86
+ return new SourceFile(dirs, path)
72
87
  }
88
+ parts.slice(0, parts.length - 1).forEach((part) => {
89
+ switch (part) {
90
+ case '.': {
91
+ break
92
+ }
93
+ case '..': {
94
+ if (dirs.length === 0) {
95
+ throw new Error('Invalid file path: ' + path)
96
+ }
97
+ dirs.pop()
98
+ break
99
+ }
100
+ default: {
101
+ dirs.push(part)
102
+ }
103
+ }
104
+ })
105
+ return new SourceFile(dirs, parts[parts.length - 1])
73
106
  }
74
107
 
75
- protected static _artifactsFolder(): string {
76
- return './artifacts/'
77
- }
78
-
79
- protected static async _handleImports(contractStr: string, importsCache: string[]): Promise<string> {
108
+ protected static async _handleImports(
109
+ pathes: string[],
110
+ contractStr: string,
111
+ importsCache: string[]
112
+ ): Promise<string> {
80
113
  const localImportsCache: string[] = []
81
114
  let result = contractStr.replace(Common.importRegex, (match) => {
82
115
  localImportsCache.push(match)
83
116
  return ''
84
117
  })
85
118
  for (const myImport of localImportsCache) {
86
- const fileName = myImport.slice(8, -1)
87
- if (!importsCache.includes(fileName)) {
88
- importsCache.push(fileName)
89
- const importContractStr = await Common._loadContractStr(fileName, importsCache, (code) =>
90
- Contract.checkCodeType(fileName, code)
119
+ const relativePath = myImport.slice(8, -1)
120
+ const importSourceFile = this.getSourceFile(relativePath, pathes)
121
+ if (!importsCache.includes(importSourceFile.contractPath)) {
122
+ importsCache.push(importSourceFile.contractPath)
123
+ const importContractStr = await Common._loadContractStr(importSourceFile, importsCache, (code) =>
124
+ Contract.checkCodeType(importSourceFile.contractPath, code)
91
125
  )
92
126
  result = result.concat('\n', importContractStr)
93
127
  }
@@ -96,16 +130,16 @@ export abstract class Common {
96
130
  }
97
131
 
98
132
  protected static async _loadContractStr(
99
- fileName: string,
133
+ sourceFile: SourceFile,
100
134
  importsCache: string[],
101
- validate: (fileName: string) => void
135
+ validate: (code: string) => void
102
136
  ): Promise<string> {
103
- const contractPath = this._contractPath(fileName)
137
+ const contractPath = sourceFile.contractPath
104
138
  const contractBuffer = await fsPromises.readFile(contractPath)
105
139
  const contractStr = contractBuffer.toString()
106
140
 
107
141
  validate(contractStr)
108
- return Common._handleImports(contractStr, importsCache)
142
+ return Common._handleImports(sourceFile.dirs, contractStr, importsCache)
109
143
  }
110
144
 
111
145
  static checkFileNameExtension(fileName: string): void {
@@ -116,25 +150,28 @@ export abstract class Common {
116
150
 
117
151
  protected static async _from<T extends { sourceCodeSha256: string }>(
118
152
  provider: NodeProvider,
119
- fileName: string,
120
- loadContractStr: (fileName: string, importsCache: string[]) => Promise<string>,
121
- compile: (provider: NodeProvider, fileName: string, contractStr: string, contractHash: string) => Promise<T>
153
+ sourceFile: SourceFile,
154
+ loadContractStr: (sourceFile: SourceFile, importsCache: string[]) => Promise<string>,
155
+ compile: (provider: NodeProvider, sourceFile: SourceFile, contractStr: string, contractHash: string) => Promise<T>
122
156
  ): Promise<T> {
123
- Common.checkFileNameExtension(fileName)
157
+ Common.checkFileNameExtension(sourceFile.contractPath)
124
158
 
125
- const contractStr = await loadContractStr(fileName, [])
159
+ const contractStr = await loadContractStr(sourceFile, [])
126
160
  const contractHash = cryptojs.SHA256(contractStr).toString()
127
161
  const existingContract = this._getArtifactFromCache(contractHash)
128
162
  if (typeof existingContract !== 'undefined') {
129
163
  return existingContract as unknown as T
130
164
  } else {
131
- return compile(provider, fileName, contractStr, contractHash)
165
+ return compile(provider, sourceFile, contractStr, contractHash)
132
166
  }
133
167
  }
134
168
 
135
- protected _saveToFile(fileName: string): Promise<void> {
136
- const artifactPath = Common._artifactPath(fileName)
137
- return fsPromises.writeFile(artifactPath, this.toString())
169
+ protected _saveToFile(sourceFile: SourceFile): Promise<void> {
170
+ const folder = Common._artifactsFolder() + sourceFile.dirPath
171
+ if (!fs.existsSync(folder)) {
172
+ fs.mkdirSync(folder, { recursive: true })
173
+ }
174
+ return fsPromises.writeFile(sourceFile.artifactPath, this.toString())
138
175
  }
139
176
 
140
177
  abstract buildByteCodeToDeploy(initialFields?: Fields): string
@@ -163,32 +200,38 @@ export class Contract extends Common {
163
200
 
164
201
  static checkCodeType(fileName: string, contractStr: string): void {
165
202
  const interfaceMatches = contractStr.match(Contract.interfaceRegex)
166
- if (interfaceMatches) {
167
- return
168
- }
169
-
170
203
  const contractMatches = contractStr.match(Contract.contractRegex)
171
- if (contractMatches === null) {
204
+ if (interfaceMatches === null && contractMatches === null) {
172
205
  throw new Error(`No contract found in: ${fileName}`)
173
- } else if (contractMatches.length > 1) {
174
- throw new Error(`Multiple contracts in: ${fileName}`)
175
- } else {
176
- return
206
+ }
207
+ if (interfaceMatches && contractMatches) {
208
+ throw new Error(`Multiple contracts and interfaces in: ${fileName}`)
209
+ }
210
+ if (interfaceMatches === null) {
211
+ if (contractMatches !== null && contractMatches.length > 1) {
212
+ throw new Error(`Multiple contracts in: ${fileName}`)
213
+ }
214
+ }
215
+ if (contractMatches === null) {
216
+ if (interfaceMatches !== null && interfaceMatches.length > 1) {
217
+ throw new Error(`Multiple interfaces in: ${fileName}`)
218
+ }
177
219
  }
178
220
  }
179
221
 
180
- private static async loadContractStr(fileName: string, importsCache: string[]): Promise<string> {
181
- return Common._loadContractStr(fileName, importsCache, (code) => Contract.checkCodeType(fileName, code))
222
+ private static async loadContractStr(sourceFile: SourceFile): Promise<string> {
223
+ return Common._loadContractStr(sourceFile, [], (code) => Contract.checkCodeType(sourceFile.contractPath, code))
182
224
  }
183
225
 
184
- static async fromSource(provider: NodeProvider, fileName: string): Promise<Contract> {
226
+ static async fromSource(provider: NodeProvider, path: string): Promise<Contract> {
185
227
  if (!fs.existsSync(Common._artifactsFolder())) {
186
228
  fs.mkdirSync(Common._artifactsFolder(), { recursive: true })
187
229
  }
230
+ const sourceFile = this.getSourceFile(path, [])
188
231
  const contract = await Common._from(
189
232
  provider,
190
- fileName,
191
- (fileName, importCaches) => Contract.loadContractStr(fileName, importCaches),
233
+ sourceFile,
234
+ (sourceFile) => Contract.loadContractStr(sourceFile),
192
235
  Contract.compile
193
236
  )
194
237
  this._putArtifactToCache(contract)
@@ -197,7 +240,7 @@ export class Contract extends Common {
197
240
 
198
241
  private static async compile(
199
242
  provider: NodeProvider,
200
- fileName: string,
243
+ sourceFile: SourceFile,
201
244
  contractStr: string,
202
245
  contractHash: string
203
246
  ): Promise<Contract> {
@@ -210,7 +253,7 @@ export class Contract extends Common {
210
253
  compiled.events,
211
254
  compiled.functions
212
255
  )
213
- await artifact._saveToFile(fileName)
256
+ await artifact._saveToFile(sourceFile)
214
257
  return artifact
215
258
  }
216
259
 
@@ -239,13 +282,19 @@ export class Contract extends Common {
239
282
  }
240
283
 
241
284
  // support both 'code.ral' and 'code.ral.json'
242
- static async fromArtifactFile(fileName: string): Promise<Contract> {
243
- const artifactPath = Contract._artifactPath(fileName)
285
+ static async fromArtifactFile(path: string): Promise<Contract> {
286
+ const sourceFile = this.getSourceFile(path, [])
287
+ const artifactPath = sourceFile.artifactPath
244
288
  const content = await fsPromises.readFile(artifactPath)
245
289
  const artifact = JSON.parse(content.toString())
246
290
  return Contract.fromJson(artifact)
247
291
  }
248
292
 
293
+ async fetchState(provider: NodeProvider, address: string, group: number): Promise<ContractState> {
294
+ const state = await provider.contracts.getContractsAddressState(address, { group: group })
295
+ return this.fromApiContractState(state)
296
+ }
297
+
249
298
  override toString(): string {
250
299
  return JSON.stringify(
251
300
  {
@@ -518,28 +567,24 @@ export class Script extends Common {
518
567
  }
519
568
  }
520
569
 
521
- private static async loadContractStr(fileName: string, importsCache: string[]): Promise<string> {
522
- return Common._loadContractStr(fileName, importsCache, (code) => Script.checkCodeType(fileName, code))
570
+ private static async loadContractStr(sourceFile: SourceFile): Promise<string> {
571
+ return Common._loadContractStr(sourceFile, [], (code) => Script.checkCodeType(sourceFile.contractPath, code))
523
572
  }
524
573
 
525
- static async fromSource(provider: NodeProvider, fileName: string): Promise<Script> {
526
- return Common._from(
527
- provider,
528
- fileName,
529
- (fileName, importsCache) => Script.loadContractStr(fileName, importsCache),
530
- Script.compile
531
- )
574
+ static async fromSource(provider: NodeProvider, path: string): Promise<Script> {
575
+ const sourceFile = this.getSourceFile(path, [])
576
+ return Common._from(provider, sourceFile, (sourceFile) => Script.loadContractStr(sourceFile), Script.compile)
532
577
  }
533
578
 
534
579
  private static async compile(
535
580
  provider: NodeProvider,
536
- fileName: string,
581
+ sourceFile: SourceFile,
537
582
  scriptStr: string,
538
583
  contractHash: string
539
584
  ): Promise<Script> {
540
585
  const compiled = await provider.contracts.postContractsCompileScript({ code: scriptStr })
541
586
  const artifact = new Script(contractHash, compiled.bytecodeTemplate, compiled.fields, compiled.functions)
542
- await artifact._saveToFile(fileName)
587
+ await artifact._saveToFile(sourceFile)
543
588
  return artifact
544
589
  }
545
590
 
@@ -556,8 +601,9 @@ export class Script extends Common {
556
601
  return new Script(artifact.sourceCodeSha256, artifact.bytecodeTemplate, artifact.fieldsSig, artifact.functions)
557
602
  }
558
603
 
559
- static async fromArtifactFile(fileName: string): Promise<Script> {
560
- const artifactPath = Common._artifactPath(fileName)
604
+ static async fromArtifactFile(path: string): Promise<Script> {
605
+ const sourceFile = this.getSourceFile(path, [])
606
+ const artifactPath = sourceFile.artifactPath
561
607
  const content = await fsPromises.readFile(artifactPath)
562
608
  const artifact = JSON.parse(content.toString())
563
609
  return this.fromJson(artifact)
@@ -42,7 +42,7 @@ export interface Account {
42
42
 
43
43
  export type SubmitTx = { submitTx?: boolean }
44
44
  export type SignerAddress = { signerAddress: string }
45
- type TxBuildParams<T> = Omit<T, 'fromPublicKey'> & SignerAddress & SubmitTx
45
+ type TxBuildParams<T> = Omit<T, 'fromPublicKey' | 'targetBlockHash'> & SignerAddress & SubmitTx
46
46
 
47
47
  export type GetAccountsParams = undefined
48
48
  export type GetAccountsResult = Account[]
@@ -151,10 +151,11 @@ describe('utils', function () {
151
151
  '0a38bc48fbb4300f1e305b201cd6129372d867122efb814d871d18c0bfe43b56',
152
152
  '4f51cd1f0af97cf5ec9c7a3397eaeea549d55a93c216e54f2ab4a8cf29f6f865'
153
153
  )
154
- ).toBe('293c948c81c5a9495178fff8b8c9f29f4f3e09e1728c40e9253c87adf5e18770')
154
+ ).toBe('0e28f15ca290002c31d691aa008aa56ac12356b0380efb6c88fff929b6a268a9')
155
155
  })
156
156
 
157
- it('should convert from string to hex', () => {
157
+ it('should convert from string to hex and back', () => {
158
158
  expect(utils.stringToHex('Hello Alephium!')).toBe('48656c6c6f20416c65706869756d21')
159
+ expect(utils.hexToString('48656c6c6f20416c65706869756d21')).toBe('Hello Alephium!')
159
160
  })
160
161
  })
@@ -190,7 +190,7 @@ export function contractIdFromTx(txId: string, outputIndex: number): string {
190
190
  }
191
191
 
192
192
  export function subContractId(parentContractId: string, pathInHex: string): string {
193
- const data = Buffer.concat([hexToBinUnsafe(pathInHex), hexToBinUnsafe(parentContractId)])
193
+ const data = Buffer.concat([hexToBinUnsafe(parentContractId), hexToBinUnsafe(pathInHex)])
194
194
 
195
195
  return binToHex(blake.blake2b(blake.blake2b(data, undefined, 32), undefined, 32))
196
196
  }
@@ -203,6 +203,14 @@ export function stringToHex(str: string): string {
203
203
  return hex
204
204
  }
205
205
 
206
+ export function hexToString(str: any): string {
207
+ return Buffer.from(str.toString(), 'hex').toString()
208
+ }
209
+
210
+ export function timeout(ms: number) {
211
+ return new Promise((resolve) => setTimeout(resolve, ms))
212
+ }
213
+
206
214
  type _Eq<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false
207
215
  export type Eq<X, Y> = _Eq<{ [P in keyof X]: X[P] }, { [P in keyof Y]: Y[P] }>
208
216
  // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
@@ -3,7 +3,7 @@
3
3
  "version": "0.1.0",
4
4
  "license": "GPL",
5
5
  "config": {
6
- "alephium_version": "1.4.0-rc2"
6
+ "alephium_version": "1.5.0-rc0"
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.1.0-rc.3"
15
+ "@alephium/web3": "0.2.0-rc.1"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/elliptic": "^6.4.13",
@@ -2,7 +2,7 @@
2
2
  "name": "my-dapp",
3
3
  "version": "0.1.0",
4
4
  "config": {
5
- "alephium_version": "1.4.0-rc2"
5
+ "alephium_version": "1.5.0-rc0"
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.1.0-rc.3",
15
+ "@alephium/web3": "0.2.0-rc.1",
16
16
  "react": "^18.0.0",
17
17
  "react-dom": "^18.0.0",
18
18
  "react-scripts": "5.0.1",
@@ -22,13 +22,14 @@ import * as path from 'path'
22
22
  import { NodeProvider } from '../src/api'
23
23
  import { Contract, Script, TestContractParams } from '../src/contract'
24
24
  import { testWallet } from '../src/test'
25
+ import { addressFromContractId } from '../src/utils'
25
26
 
26
27
  describe('contract', function () {
27
28
  async function testSuite1() {
28
29
  const provider = new NodeProvider('http://127.0.0.1:22973')
29
30
 
30
- const add = await Contract.fromSource(provider, 'add.ral')
31
- const sub = await Contract.fromSource(provider, 'sub.ral')
31
+ const add = await Contract.fromSource(provider, 'add/add.ral')
32
+ const sub = await Contract.fromSource(provider, 'sub/sub.ral')
32
33
 
33
34
  const subState = sub.toState({ result: 0 }, { alphAmount: BigInt('1000000000000000000') })
34
35
  const testParams: TestContractParams = {
@@ -61,6 +62,7 @@ describe('contract', function () {
61
62
  initialTokenAmounts: []
62
63
  })
63
64
  const subContractId = subDeployTx.contractId
65
+ const subContractAddress = addressFromContractId(subContractId)
64
66
  expect(subDeployTx.fromGroup).toEqual(0)
65
67
  expect(subDeployTx.toGroup).toEqual(0)
66
68
  const subSubmitResult = await signer.submitTransaction(subDeployTx.unsignedTx, subDeployTx.txId)
@@ -80,8 +82,16 @@ describe('contract', function () {
80
82
  expect(addSubmitResult.txId).toEqual(addDeployTx.txId)
81
83
 
82
84
  const addContractId = addDeployTx.contractId
83
- const main = await Script.fromSource(provider, 'main.ral')
85
+ const addContractAddress = addressFromContractId(addContractId)
86
+
87
+ // Check state for add/sub before main script is executed
88
+ let fetchedSubState = await sub.fetchState(provider, subContractAddress, 0)
89
+ expect(fetchedSubState.fields.result).toEqual(0)
90
+ let fetchedAddState = await add.fetchState(provider, addContractAddress, 0)
91
+ expect(fetchedAddState.fields.subContractId).toEqual(subContractId)
92
+ expect(fetchedAddState.fields.result).toEqual(0)
84
93
 
94
+ const main = await Script.fromSource(provider, 'main.ral')
85
95
  const mainScriptTx = await main.transactionForDeployment(signer, {
86
96
  initialFields: { addContractId: addContractId }
87
97
  })
@@ -90,12 +100,19 @@ describe('contract', function () {
90
100
  const mainSubmitResult = await signer.submitTransaction(mainScriptTx.unsignedTx, mainScriptTx.txId)
91
101
  expect(mainSubmitResult.fromGroup).toEqual(0)
92
102
  expect(mainSubmitResult.toGroup).toEqual(0)
103
+
104
+ // Check state for add/sub after main script is executed
105
+ fetchedSubState = await sub.fetchState(provider, subContractAddress, 0)
106
+ expect(fetchedSubState.fields.result).toEqual(1)
107
+ fetchedAddState = await add.fetchState(provider, addContractAddress, 0)
108
+ expect(fetchedAddState.fields.subContractId).toEqual(subContractId)
109
+ expect(fetchedAddState.fields.result).toEqual(3)
93
110
  }
94
111
 
95
112
  async function testSuite2() {
96
113
  const provider = new NodeProvider('http://127.0.0.1:22973')
97
114
 
98
- const greeter = await Contract.fromSource(provider, 'greeter.ral')
115
+ const greeter = await Contract.fromSource(provider, 'greeter/greeter.ral')
99
116
 
100
117
  const testParams: TestContractParams = {
101
118
  initialFields: { btcPrice: 1 }
@@ -151,11 +168,11 @@ describe('contract', function () {
151
168
  }
152
169
 
153
170
  it('should load contract from json', async () => {
154
- loadContract('./artifacts/add.ral.json')
155
- loadContract('./artifacts/sub.ral.json')
171
+ loadContract('./artifacts/add/add.ral.json')
172
+ loadContract('./artifacts/sub/sub.ral.json')
156
173
  loadScript('./artifacts/main.ral.json')
157
174
 
158
- loadContract('./artifacts/greeter.ral.json')
175
+ loadContract('./artifacts/greeter/greeter.ral.json')
159
176
  loadScript('./artifacts/greeter_main.ral.json')
160
177
  })
161
178
  })
@@ -22,11 +22,11 @@ import { Contract, Script } from '../src/contract'
22
22
  import { NodeWallet, SignExecuteScriptTxParams } from '../src/signer'
23
23
  import { ContractEvent } from '../src/api/api-alephium'
24
24
  import { testWallet } from '../src/test'
25
- import { SubscribeOptions } from '../src/utils'
25
+ import { SubscribeOptions, timeout } from '../src/utils'
26
26
 
27
27
  describe('events', function () {
28
28
  async function deployContract(provider: NodeProvider, signer: NodeWallet): Promise<[string, string]> {
29
- const sub = await Contract.fromSource(provider, 'sub.ral')
29
+ const sub = await Contract.fromSource(provider, 'sub/sub.ral')
30
30
  const subDeployTx = await sub.transactionForDeployment(signer, {
31
31
  initialFields: { result: 0 },
32
32
  initialTokenAmounts: []
@@ -35,7 +35,7 @@ describe('events', function () {
35
35
  const subSubmitResult = await signer.submitTransaction(subDeployTx.unsignedTx, subDeployTx.txId)
36
36
  expect(subSubmitResult.txId).toEqual(subDeployTx.txId)
37
37
 
38
- const add = await Contract.fromSource(provider, 'add.ral')
38
+ const add = await Contract.fromSource(provider, 'add/add.ral')
39
39
  const addDeployTx = await add.transactionForDeployment(signer, {
40
40
  initialFields: { subContractId: subContractId, result: 0 },
41
41
  initialTokenAmounts: []
@@ -78,7 +78,7 @@ describe('events', function () {
78
78
  signerAddress: (await signer.getAccounts())[0].address
79
79
  })
80
80
  await executeScript(scriptTxParams, signer, 3)
81
- await new Promise((resolve) => setTimeout(resolve, 3000))
81
+ await timeout(3000)
82
82
 
83
83
  expect(events.length).toEqual(3)
84
84
  events.forEach((event) => {
@@ -117,7 +117,7 @@ describe('events', function () {
117
117
  initialFields: { addContractId: contractId }
118
118
  })
119
119
  await signer.submitTransaction(scriptTx0.unsignedTx, scriptTx0.txId)
120
- await new Promise((resolve) => setTimeout(resolve, 1500))
120
+ await timeout(1500)
121
121
  subscription.unsubscribe()
122
122
 
123
123
  expect(events.length).toEqual(1)
@@ -132,7 +132,7 @@ describe('events', function () {
132
132
  initialFields: { addContractId: contractId }
133
133
  })
134
134
  await signer.submitTransaction(scriptTx1.unsignedTx, scriptTx1.txId)
135
- await new Promise((resolve) => setTimeout(resolve, 1500))
135
+ await timeout(1500)
136
136
  expect(events.length).toEqual(1)
137
137
  })
138
138
  })
@@ -21,12 +21,12 @@ import { subscribeToTxStatus } from '../src/transaction/status'
21
21
  import { Contract } from '../src/contract'
22
22
  import { TxStatus } from '../src/api/api-alephium'
23
23
  import { testWallet } from '../src/test'
24
- import { SubscribeOptions } from '../src/utils'
24
+ import { SubscribeOptions, timeout } from '../src/utils'
25
25
 
26
26
  describe('transactions', function () {
27
27
  it('should subscribe transaction status', async () => {
28
28
  const provider = new NodeProvider('http://127.0.0.1:22973')
29
- const sub = await Contract.fromSource(provider, 'sub.ral')
29
+ const sub = await Contract.fromSource(provider, 'sub/sub.ral')
30
30
  const signer = await testWallet(provider)
31
31
  const subDeployTx = await sub.transactionForDeployment(signer, {
32
32
  initialFields: { result: 0 },
@@ -53,11 +53,11 @@ describe('transactions', function () {
53
53
  const counterBeforeSubscribe = counter
54
54
 
55
55
  const subscription = subscribeToTxStatus(subscriptOptions, subDeployTx.txId)
56
- await new Promise((resolve) => setTimeout(resolve, 1500))
56
+ await timeout(1500)
57
57
  expect(txStatus).toMatchObject({ type: 'TxNotFound' })
58
58
 
59
59
  const subSubmitResult = await signer.submitTransaction(subDeployTx.unsignedTx, subDeployTx.txId)
60
- await new Promise((resolve) => setTimeout(resolve, 1500))
60
+ await timeout(1500)
61
61
  expect(txStatus).toMatchObject({ type: 'Confirmed' })
62
62
 
63
63
  expect(counterBeforeSubscribe).toBeLessThan(counter)
@@ -65,8 +65,8 @@ describe('transactions', function () {
65
65
  subscription.unsubscribe()
66
66
 
67
67
  const counterAfterUnsubscribe = counter
68
- await new Promise((resolve) => setTimeout(resolve, 1500))
68
+ await timeout(1500)
69
69
  expect(txStatus).toMatchObject({ type: 'Confirmed' })
70
70
  expect(counterAfterUnsubscribe).toEqual(counter)
71
- })
71
+ }, 10000)
72
72
  })