@alephium/web3 0.1.0 → 0.2.0-test.0
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} +1 -1
- package/contracts/{greeter.ral → greeter/greeter.ral} +0 -0
- package/contracts/{greeter_interface.ral → greeter/greeter_interface.ral} +0 -0
- package/contracts/greeter_main.ral +1 -1
- package/contracts/main.ral +1 -1
- package/contracts/{sub.ral → sub/sub.ral} +0 -0
- 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 +2 -0
- package/dist/src/contract/contract.d.ts +18 -10
- package/dist/src/contract/contract.js +95 -56
- package/dist/src/contract/events.d.ts +7 -25
- package/dist/src/contract/events.js +18 -31
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/transaction/index.d.ts +2 -0
- package/dist/src/transaction/index.js +31 -0
- package/dist/src/{utils/transaction.d.ts → transaction/sign-verify.d.ts} +0 -0
- package/dist/src/{utils/transaction.js → transaction/sign-verify.js} +1 -1
- package/dist/src/transaction/status.d.ts +10 -0
- package/dist/src/transaction/status.js +48 -0
- package/dist/src/utils/index.d.ts +1 -1
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/subscription.d.ts +24 -0
- package/dist/src/utils/subscription.js +52 -0
- package/dist/src/utils/utils.d.ts +2 -0
- package/dist/src/utils/utils.js +9 -1
- package/package.json +1 -1
- package/src/api/api-alephium.ts +2 -0
- package/src/contract/contract.ts +112 -66
- package/src/contract/events.ts +21 -48
- package/src/index.ts +1 -0
- package/src/transaction/index.ts +20 -0
- package/src/{utils/transaction.test.ts → transaction/sign-verify.test.ts} +1 -1
- package/src/{utils/transaction.ts → transaction/sign-verify.ts} +1 -1
- package/src/transaction/status.ts +58 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/subscription.ts +72 -0
- package/src/utils/utils.test.ts +2 -1
- package/src/utils/utils.ts +8 -0
- package/test/contract.test.ts +24 -7
- package/test/events.test.ts +18 -19
- package/test/transaction.test.ts +72 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
4
|
+
This file is part of the alephium project.
|
|
5
|
+
|
|
6
|
+
The library is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
The library is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Lesser General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.Subscription = void 0;
|
|
24
|
+
const eventemitter3_1 = __importDefault(require("eventemitter3"));
|
|
25
|
+
class Subscription {
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.provider = options.provider;
|
|
28
|
+
this.pollingInterval = options.pollingInterval;
|
|
29
|
+
this.messageCallback = options.messageCallback;
|
|
30
|
+
this.errorCallback = options.errorCallback;
|
|
31
|
+
this.task = undefined;
|
|
32
|
+
this.cancelled = false;
|
|
33
|
+
this.eventEmitter = new eventemitter3_1.default();
|
|
34
|
+
}
|
|
35
|
+
startPolling() {
|
|
36
|
+
this.eventEmitter.on('tick', async () => {
|
|
37
|
+
await this.polling();
|
|
38
|
+
if (!this.cancelled) {
|
|
39
|
+
this.task = setTimeout(() => this.eventEmitter.emit('tick'), this.pollingInterval);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
this.eventEmitter.emit('tick');
|
|
43
|
+
}
|
|
44
|
+
unsubscribe() {
|
|
45
|
+
this.eventEmitter.removeAllListeners();
|
|
46
|
+
this.cancelled = true;
|
|
47
|
+
if (typeof this.task !== 'undefined') {
|
|
48
|
+
clearTimeout(this.task);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.Subscription = Subscription;
|
|
@@ -20,6 +20,8 @@ export declare function addressFromContractId(contractId: string): string;
|
|
|
20
20
|
export declare function contractIdFromTx(txId: string, outputIndex: number): string;
|
|
21
21
|
export declare function subContractId(parentContractId: string, pathInHex: string): string;
|
|
22
22
|
export declare function stringToHex(str: string): string;
|
|
23
|
+
export declare function hexToString(str: any): string;
|
|
24
|
+
export declare function timeout(ms: number): Promise<unknown>;
|
|
23
25
|
declare type _Eq<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
|
|
24
26
|
export declare type Eq<X, Y> = _Eq<{
|
|
25
27
|
[P in keyof X]: X[P];
|
package/dist/src/utils/utils.js
CHANGED
|
@@ -20,7 +20,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
20
20
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.assertType = exports.stringToHex = exports.subContractId = exports.contractIdFromTx = exports.addressFromContractId = exports.addressFromPublicKey = exports.publicKeyFromPrivateKey = exports.binToHex = exports.hexToBinUnsafe = exports.tokenIdFromAddress = exports.contractIdFromAddress = exports.groupOfAddress = exports.isHexString = exports.signatureDecode = exports.signatureEncode = exports.convertHttpResponse = void 0;
|
|
23
|
+
exports.assertType = exports.timeout = exports.hexToString = exports.stringToHex = exports.subContractId = exports.contractIdFromTx = exports.addressFromContractId = exports.addressFromPublicKey = exports.publicKeyFromPrivateKey = exports.binToHex = exports.hexToBinUnsafe = exports.tokenIdFromAddress = exports.contractIdFromAddress = exports.groupOfAddress = exports.isHexString = exports.signatureDecode = exports.signatureEncode = exports.convertHttpResponse = void 0;
|
|
24
24
|
const elliptic_1 = require("elliptic");
|
|
25
25
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
26
26
|
const blakejs_1 = __importDefault(require("blakejs"));
|
|
@@ -194,6 +194,14 @@ function stringToHex(str) {
|
|
|
194
194
|
return hex;
|
|
195
195
|
}
|
|
196
196
|
exports.stringToHex = stringToHex;
|
|
197
|
+
function hexToString(str) {
|
|
198
|
+
return buffer_1.Buffer.from(str.toString(), 'hex').toString();
|
|
199
|
+
}
|
|
200
|
+
exports.hexToString = hexToString;
|
|
201
|
+
function timeout(ms) {
|
|
202
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
203
|
+
}
|
|
204
|
+
exports.timeout = timeout;
|
|
197
205
|
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
|
|
198
206
|
function assertType() { }
|
|
199
207
|
exports.assertType = assertType;
|
package/package.json
CHANGED
package/src/api/api-alephium.ts
CHANGED
package/src/contract/contract.ts
CHANGED
|
@@ -27,11 +27,30 @@ 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')
|
|
53
|
+
static readonly importRegex = new RegExp('^import "([^"/]+/(([^"]+)/)?)?[a-z][a-z_0-9]*.ral"', 'mg')
|
|
35
54
|
static readonly contractRegex = new RegExp('^TxContract [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')
|
|
@@ -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/contract/events.ts
CHANGED
|
@@ -16,64 +16,33 @@ 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
|
|
20
|
-
import {
|
|
21
|
-
import { NodeProvider } from '../api'
|
|
19
|
+
import { ContractEvent } from '../api/api-alephium'
|
|
20
|
+
import { Subscription, SubscribeOptions } from '../utils'
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
type ErrorCallback = (error: any, subscription: Subscription) => Promise<void>
|
|
25
|
-
|
|
26
|
-
export interface SubscribeOptions {
|
|
27
|
-
provider: NodeProvider
|
|
28
|
-
contractAddress: string
|
|
29
|
-
fromCount?: number
|
|
30
|
-
pollingInterval: number
|
|
31
|
-
eventCallback: EventCallback
|
|
32
|
-
errorCallback: ErrorCallback
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class Subscription {
|
|
36
|
-
provider: NodeProvider
|
|
22
|
+
export class EventSubscription extends Subscription<ContractEvent> {
|
|
37
23
|
readonly contractAddress: string
|
|
38
|
-
pollingInterval: number
|
|
39
|
-
|
|
40
24
|
private fromCount: number
|
|
41
|
-
private eventCallback: EventCallback
|
|
42
|
-
private errorCallback: ErrorCallback
|
|
43
|
-
private task: ReturnType<typeof setTimeout> | undefined
|
|
44
|
-
private cancelled: boolean
|
|
45
|
-
private eventEmitter: EventEmitter
|
|
46
25
|
|
|
47
|
-
constructor(options: SubscribeOptions) {
|
|
48
|
-
|
|
49
|
-
this.contractAddress =
|
|
50
|
-
this.fromCount = typeof
|
|
51
|
-
this.pollingInterval = options.pollingInterval
|
|
52
|
-
this.eventCallback = options.eventCallback
|
|
53
|
-
this.errorCallback = options.errorCallback
|
|
54
|
-
this.task = undefined
|
|
55
|
-
this.cancelled = false
|
|
26
|
+
constructor(options: SubscribeOptions<ContractEvent>, contractAddress: string, fromCount?: number) {
|
|
27
|
+
super(options)
|
|
28
|
+
this.contractAddress = contractAddress
|
|
29
|
+
this.fromCount = typeof fromCount === 'undefined' ? 0 : fromCount
|
|
56
30
|
|
|
57
|
-
this.
|
|
31
|
+
this.startPolling()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
override startPolling() {
|
|
58
35
|
this.eventEmitter.on('tick', async () => {
|
|
59
|
-
await this.
|
|
36
|
+
await this.polling()
|
|
60
37
|
})
|
|
61
38
|
this.eventEmitter.emit('tick')
|
|
62
39
|
}
|
|
63
40
|
|
|
64
|
-
unsubscribe(): void {
|
|
65
|
-
this.eventEmitter.removeAllListeners()
|
|
66
|
-
this.cancelled = true
|
|
67
|
-
if (typeof this.task !== 'undefined') {
|
|
68
|
-
clearTimeout(this.task)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
41
|
currentEventCount(): number {
|
|
73
42
|
return this.fromCount
|
|
74
43
|
}
|
|
75
44
|
|
|
76
|
-
|
|
45
|
+
override async polling() {
|
|
77
46
|
try {
|
|
78
47
|
const events = await this.provider.events.getEventsContractContractaddress(this.contractAddress, {
|
|
79
48
|
start: this.fromCount
|
|
@@ -87,16 +56,20 @@ export class Subscription {
|
|
|
87
56
|
return
|
|
88
57
|
}
|
|
89
58
|
|
|
90
|
-
const promises = events.events.map((event) => this.
|
|
59
|
+
const promises = events.events.map((event) => this.messageCallback(event))
|
|
91
60
|
await Promise.all(promises)
|
|
92
61
|
this.fromCount = events.nextStart
|
|
93
|
-
await this.
|
|
62
|
+
await this.polling()
|
|
94
63
|
} catch (err) {
|
|
95
64
|
await this.errorCallback(err, this)
|
|
96
65
|
}
|
|
97
66
|
}
|
|
98
67
|
}
|
|
99
68
|
|
|
100
|
-
export function
|
|
101
|
-
|
|
69
|
+
export function subscribeToEvents(
|
|
70
|
+
options: SubscribeOptions<ContractEvent>,
|
|
71
|
+
contractAddress: string,
|
|
72
|
+
fromCount?: number
|
|
73
|
+
): EventSubscription {
|
|
74
|
+
return new EventSubscription(options, contractAddress, fromCount)
|
|
102
75
|
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
3
|
+
This file is part of the alephium project.
|
|
4
|
+
|
|
5
|
+
The library is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
The library is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export * from './sign-verify'
|
|
20
|
+
export * from './status'
|
|
@@ -19,7 +19,7 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
19
19
|
import EC from 'elliptic'
|
|
20
20
|
import assert from 'assert'
|
|
21
21
|
|
|
22
|
-
import { transactionSign, transactionVerifySignature } from './
|
|
22
|
+
import { transactionSign, transactionVerifySignature } from './sign-verify'
|
|
23
23
|
|
|
24
24
|
describe('transaction', function () {
|
|
25
25
|
it('should verify signature', () => {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 - 2022 The Alephium Authors
|
|
3
|
+
This file is part of the alephium project.
|
|
4
|
+
|
|
5
|
+
The library is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
The library is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Lesser General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { TxStatus } from '../api/api-alephium'
|
|
20
|
+
import { Subscription, SubscribeOptions } from '../utils'
|
|
21
|
+
|
|
22
|
+
export class TxStatusSubscription extends Subscription<TxStatus> {
|
|
23
|
+
readonly txId: string
|
|
24
|
+
readonly fromGroup?: number
|
|
25
|
+
readonly toGroup?: number
|
|
26
|
+
|
|
27
|
+
constructor(options: SubscribeOptions<TxStatus>, txId: string, fromGroup?: number, toGroup?: number) {
|
|
28
|
+
super(options)
|
|
29
|
+
this.txId = txId
|
|
30
|
+
this.fromGroup = fromGroup
|
|
31
|
+
this.toGroup = toGroup
|
|
32
|
+
|
|
33
|
+
this.startPolling()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override async polling() {
|
|
37
|
+
try {
|
|
38
|
+
const txStatus = await this.provider.transactions.getTransactionsStatus({
|
|
39
|
+
txId: this.txId,
|
|
40
|
+
fromGroup: this.fromGroup,
|
|
41
|
+
toGroup: this.toGroup
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
await this.messageCallback(txStatus)
|
|
45
|
+
} catch (err) {
|
|
46
|
+
await this.errorCallback(err, this)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function subscribeToTxStatus(
|
|
52
|
+
options: SubscribeOptions<TxStatus>,
|
|
53
|
+
txId: string,
|
|
54
|
+
fromGroup?: number,
|
|
55
|
+
toGroup?: number
|
|
56
|
+
): TxStatusSubscription {
|
|
57
|
+
return new TxStatusSubscription(options, txId, fromGroup, toGroup)
|
|
58
|
+
}
|