@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.
- package/contracts/{add.ral → add/add.ral} +2 -2
- package/contracts/{greeter.ral → greeter/greeter.ral} +1 -1
- package/contracts/{greeter_interface.ral → greeter/greeter_interface.ral} +0 -0
- package/contracts/greeter_main.ral +3 -3
- package/contracts/main.ral +1 -1
- package/contracts/{sub.ral → sub/sub.ral} +1 -1
- 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 +24 -5
- package/dist/src/api/api-alephium.js +3 -3
- package/dist/src/api/api-explorer.d.ts +16 -0
- package/dist/src/api/api-explorer.js +26 -0
- package/dist/src/contract/contract.d.ts +18 -10
- package/dist/src/contract/contract.js +96 -57
- package/dist/src/utils/utils.d.ts +2 -0
- package/dist/src/utils/utils.js +10 -2
- package/package.json +4 -4
- package/src/api/api-alephium.ts +21 -6
- package/src/api/api-explorer.ts +30 -0
- package/src/contract/contract.ts +113 -67
- package/src/signer/signer.ts +1 -1
- package/src/utils/utils.test.ts +3 -2
- package/src/utils/utils.ts +9 -1
- package/templates/base/package.json +2 -2
- package/templates/react/package.json +2 -2
- package/test/contract.test.ts +24 -7
- package/test/events.test.ts +6 -6
- package/test/transaction.test.ts +6 -6
package/src/api/api-explorer.ts
CHANGED
|
@@ -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
|
}
|
package/src/contract/contract.ts
CHANGED
|
@@ -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('^
|
|
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
|
|
60
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return
|
|
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
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
133
|
+
sourceFile: SourceFile,
|
|
100
134
|
importsCache: string[],
|
|
101
|
-
validate: (
|
|
135
|
+
validate: (code: string) => void
|
|
102
136
|
): Promise<string> {
|
|
103
|
-
const contractPath =
|
|
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
|
-
|
|
120
|
-
loadContractStr: (
|
|
121
|
-
compile: (provider: NodeProvider,
|
|
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(
|
|
157
|
+
Common.checkFileNameExtension(sourceFile.contractPath)
|
|
124
158
|
|
|
125
|
-
const contractStr = await loadContractStr(
|
|
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,
|
|
165
|
+
return compile(provider, sourceFile, contractStr, contractHash)
|
|
132
166
|
}
|
|
133
167
|
}
|
|
134
168
|
|
|
135
|
-
protected _saveToFile(
|
|
136
|
-
const
|
|
137
|
-
|
|
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
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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(
|
|
181
|
-
return Common._loadContractStr(
|
|
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,
|
|
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
|
-
|
|
191
|
-
(
|
|
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
|
-
|
|
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(
|
|
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(
|
|
243
|
-
const
|
|
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(
|
|
522
|
-
return Common._loadContractStr(
|
|
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,
|
|
526
|
-
|
|
527
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
560
|
-
const
|
|
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)
|
package/src/signer/signer.ts
CHANGED
|
@@ -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[]
|
package/src/utils/utils.test.ts
CHANGED
|
@@ -151,10 +151,11 @@ describe('utils', function () {
|
|
|
151
151
|
'0a38bc48fbb4300f1e305b201cd6129372d867122efb814d871d18c0bfe43b56',
|
|
152
152
|
'4f51cd1f0af97cf5ec9c7a3397eaeea549d55a93c216e54f2ab4a8cf29f6f865'
|
|
153
153
|
)
|
|
154
|
-
).toBe('
|
|
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
|
})
|
package/src/utils/utils.ts
CHANGED
|
@@ -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(
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|
package/test/contract.test.ts
CHANGED
|
@@ -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
|
|
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
|
})
|
package/test/events.test.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
135
|
+
await timeout(1500)
|
|
136
136
|
expect(events.length).toEqual(1)
|
|
137
137
|
})
|
|
138
138
|
})
|
package/test/transaction.test.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
68
|
+
await timeout(1500)
|
|
69
69
|
expect(txStatus).toMatchObject({ type: 'Confirmed' })
|
|
70
70
|
expect(counterAfterUnsubscribe).toEqual(counter)
|
|
71
|
-
})
|
|
71
|
+
}, 10000)
|
|
72
72
|
})
|