@alephium/web3 0.2.0-test.1 → 0.2.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/.eslintignore +2 -2
- package/README.md +2 -135
- package/dist/alephium-web3.min.js +1 -1
- package/dist/alephium-web3.min.js.LICENSE.txt +0 -17
- package/dist/alephium-web3.min.js.map +1 -1
- package/dist/src/api/api-alephium.d.ts +115 -17
- package/dist/src/api/api-alephium.js +145 -80
- package/dist/src/api/api-explorer.d.ts +178 -51
- package/dist/src/api/api-explorer.js +172 -37
- package/dist/src/api/index.d.ts +40 -5
- package/dist/src/api/index.js +115 -7
- package/dist/src/api/types.d.ts +23 -0
- package/dist/src/api/types.js +235 -0
- package/dist/src/api/utils.d.ts +6 -0
- package/dist/{scripts/rename-gitignore.js → src/api/utils.js} +11 -6
- package/dist/src/contract/contract.d.ts +68 -55
- package/dist/src/contract/contract.js +235 -384
- package/dist/src/contract/events.d.ts +4 -4
- package/dist/src/contract/events.js +2 -1
- package/dist/src/contract/index.js +5 -1
- package/dist/src/contract/ralph.d.ts +5 -4
- package/dist/src/contract/ralph.js +27 -1
- package/dist/src/global.d.ts +6 -2
- package/dist/src/global.js +19 -3
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +23 -2
- package/dist/src/signer/index.d.ts +0 -1
- package/dist/src/signer/index.js +5 -2
- package/dist/src/signer/signer.d.ts +59 -60
- package/dist/src/signer/signer.js +99 -70
- package/dist/src/transaction/index.d.ts +0 -1
- package/dist/src/transaction/index.js +5 -2
- package/dist/src/transaction/status.d.ts +2 -1
- package/dist/src/transaction/status.js +2 -1
- package/dist/src/utils/bs58.d.ts +1 -0
- package/dist/src/utils/bs58.js +13 -1
- package/dist/src/utils/index.d.ts +0 -1
- package/dist/src/utils/index.js +5 -2
- package/dist/src/utils/subscription.d.ts +0 -2
- package/dist/src/utils/subscription.js +0 -2
- package/dist/src/utils/utils.d.ts +4 -9
- package/dist/src/utils/utils.js +20 -24
- package/jest-config.json +11 -0
- package/package.json +11 -45
- package/src/api/api-alephium.ts +162 -25
- package/src/api/api-explorer.ts +247 -54
- package/src/api/index.ts +140 -6
- package/src/api/types.ts +229 -0
- package/{scripts/rename-gitignore.js → src/api/utils.ts} +7 -6
- package/src/contract/contract.ts +398 -429
- package/src/contract/events.ts +6 -5
- package/src/contract/ralph.ts +29 -4
- package/src/global.ts +23 -3
- package/src/index.ts +7 -1
- package/src/signer/index.ts +0 -1
- package/src/signer/signer.ts +165 -135
- package/src/transaction/index.ts +0 -1
- package/src/transaction/status.ts +5 -2
- package/src/utils/bs58.ts +11 -0
- package/src/utils/index.ts +0 -1
- package/src/utils/subscription.ts +0 -4
- package/src/utils/utils.ts +11 -19
- package/webpack.config.js +3 -0
- package/.eslintrc.json +0 -21
- package/LICENSE +0 -165
- package/contracts/add/add.ral +0 -13
- package/contracts/greeter/greeter.ral +0 -7
- package/contracts/greeter/greeter_interface.ral +0 -4
- package/contracts/greeter_main.ral +0 -7
- package/contracts/main.ral +0 -4
- package/contracts/sub/sub.ral +0 -10
- package/contracts/test/metadata.ral +0 -18
- package/contracts/test/warnings.ral +0 -8
- package/dev/user.conf +0 -29
- package/dist/scripts/create-project.d.ts +0 -2
- package/dist/scripts/create-project.js +0 -125
- package/dist/scripts/rename-gitignore.d.ts +0 -1
- package/dist/scripts/start-devnet.d.ts +0 -1
- package/dist/scripts/start-devnet.js +0 -131
- package/dist/scripts/stop-devnet.d.ts +0 -1
- package/dist/scripts/stop-devnet.js +0 -32
- package/dist/src/signer/node-wallet.d.ts +0 -11
- package/dist/src/signer/node-wallet.js +0 -57
- package/dist/src/test/index.d.ts +0 -6
- package/dist/src/test/index.js +0 -41
- package/dist/src/test/privatekey-wallet.d.ts +0 -11
- package/dist/src/test/privatekey-wallet.js +0 -68
- package/dist/src/transaction/sign-verify.d.ts +0 -2
- package/dist/src/transaction/sign-verify.js +0 -58
- package/dist/src/utils/password-crypto.d.ts +0 -2
- package/dist/src/utils/password-crypto.js +0 -69
- package/gitignore +0 -9
- package/scripts/create-project.ts +0 -137
- package/scripts/start-devnet.js +0 -141
- package/scripts/stop-devnet.js +0 -32
- package/src/contract/ralph.test.ts +0 -178
- package/src/fixtures/address.json +0 -36
- package/src/fixtures/balance.json +0 -9
- package/src/fixtures/self-clique.json +0 -19
- package/src/fixtures/transaction.json +0 -13
- package/src/fixtures/transactions.json +0 -179
- package/src/signer/fixtures/genesis.json +0 -26
- package/src/signer/fixtures/wallets.json +0 -26
- package/src/signer/node-wallet.ts +0 -65
- package/src/test/index.ts +0 -31
- package/src/test/privatekey-wallet.ts +0 -57
- package/src/transaction/sign-verify.test.ts +0 -50
- package/src/transaction/sign-verify.ts +0 -39
- package/src/utils/address.test.ts +0 -47
- package/src/utils/djb2.test.ts +0 -35
- package/src/utils/password-crypto.test.ts +0 -27
- package/src/utils/password-crypto.ts +0 -77
- package/src/utils/utils.test.ts +0 -161
- package/templates/base/README.md +0 -34
- package/templates/base/package.json +0 -35
- package/templates/base/src/greeter.ts +0 -42
- package/templates/base/tsconfig.json +0 -19
- package/templates/react/README.md +0 -34
- package/templates/react/config-overrides.js +0 -18
- package/templates/react/package.json +0 -66
- package/templates/react/src/App.tsx +0 -42
- package/templates/react/src/artifacts/greeter.ral.json +0 -26
- package/templates/react/src/artifacts/greeter_main.ral.json +0 -22
- package/templates/shared/.eslintrc.json +0 -12
- package/templates/shared/scripts/header.js +0 -0
- package/test/contract.test.ts +0 -213
- package/test/events.test.ts +0 -141
- package/test/transaction.test.ts +0 -73
|
@@ -18,7 +18,11 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
18
18
|
*/
|
|
19
19
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
20
|
if (k2 === undefined) k2 = k;
|
|
21
|
-
Object.
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
22
26
|
}) : (function(o, m, k, k2) {
|
|
23
27
|
if (k2 === undefined) k2 = k;
|
|
24
28
|
o[k2] = m[k];
|
|
@@ -39,15 +43,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
43
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
44
|
};
|
|
41
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.
|
|
46
|
+
exports.Script = exports.Contract = exports.Artifact = exports.Project = exports.DEFAULT_COMPILER_OPTIONS = exports.DEFAULT_NODE_COMPILER_OPTIONS = void 0;
|
|
43
47
|
const buffer_1 = require("buffer/");
|
|
44
|
-
const
|
|
45
|
-
const crypto = __importStar(require("crypto"));
|
|
48
|
+
const crypto_1 = require("crypto");
|
|
46
49
|
const fs_1 = __importDefault(require("fs"));
|
|
47
50
|
const fs_2 = require("fs");
|
|
51
|
+
const api_1 = require("../api");
|
|
48
52
|
const ralph = __importStar(require("./ralph"));
|
|
49
53
|
const utils_1 = require("../utils");
|
|
50
54
|
const global_1 = require("../global");
|
|
55
|
+
const __1 = require("..");
|
|
51
56
|
var SourceType;
|
|
52
57
|
(function (SourceType) {
|
|
53
58
|
SourceType[SourceType["Contract"] = 0] = "Contract";
|
|
@@ -55,34 +60,38 @@ var SourceType;
|
|
|
55
60
|
SourceType[SourceType["AbstractContract"] = 2] = "AbstractContract";
|
|
56
61
|
SourceType[SourceType["Interface"] = 3] = "Interface";
|
|
57
62
|
})(SourceType || (SourceType = {}));
|
|
58
|
-
exports.
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
exports.DEFAULT_NODE_COMPILER_OPTIONS = {
|
|
64
|
+
ignoreUnusedConstantsWarnings: false,
|
|
65
|
+
ignoreUnusedVariablesWarnings: false,
|
|
66
|
+
ignoreUnusedFieldsWarnings: false,
|
|
67
|
+
ignoreUnusedPrivateFunctionsWarnings: false,
|
|
68
|
+
ignoreReadonlyCheckWarnings: false,
|
|
69
|
+
ignoreExternalCallCheckWarnings: false
|
|
61
70
|
};
|
|
71
|
+
exports.DEFAULT_COMPILER_OPTIONS = { errorOnWarnings: true, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
|
|
62
72
|
class TypedMatcher {
|
|
63
73
|
constructor(pattern, type) {
|
|
64
74
|
this.matcher = new RegExp(pattern, 'mg');
|
|
65
75
|
this.type = type;
|
|
66
|
-
this.name = undefined;
|
|
67
76
|
}
|
|
68
77
|
match(str) {
|
|
69
|
-
const results =
|
|
70
|
-
|
|
71
|
-
this.name = results[0][1];
|
|
72
|
-
}
|
|
73
|
-
return results.length;
|
|
78
|
+
const results = str.match(this.matcher);
|
|
79
|
+
return results === null ? 0 : results.length;
|
|
74
80
|
}
|
|
75
81
|
}
|
|
76
82
|
class SourceFile {
|
|
77
|
-
constructor(type,
|
|
83
|
+
constructor(type, sourceCode, sourceCodeHash, contractPath) {
|
|
78
84
|
this.type = type;
|
|
79
|
-
this.typeId = typeId;
|
|
80
85
|
this.sourceCode = sourceCode;
|
|
81
|
-
this.sourceCodeHash =
|
|
86
|
+
this.sourceCodeHash = sourceCodeHash;
|
|
82
87
|
this.contractPath = contractPath;
|
|
83
88
|
}
|
|
84
|
-
getArtifactPath(
|
|
85
|
-
return
|
|
89
|
+
getArtifactPath(artifactsRootDir) {
|
|
90
|
+
return artifactsRootDir + this.contractPath.slice(this.contractPath.indexOf('/')) + '.json';
|
|
91
|
+
}
|
|
92
|
+
static async from(type, sourceCode, contractPath) {
|
|
93
|
+
const sourceCodeHash = await crypto_1.webcrypto.subtle.digest('SHA-256', buffer_1.Buffer.from(sourceCode));
|
|
94
|
+
return new SourceFile(type, sourceCode, buffer_1.Buffer.from(sourceCodeHash).toString('hex'), contractPath);
|
|
86
95
|
}
|
|
87
96
|
}
|
|
88
97
|
class Compiled {
|
|
@@ -93,15 +102,35 @@ class Compiled {
|
|
|
93
102
|
}
|
|
94
103
|
}
|
|
95
104
|
class ProjectArtifact {
|
|
96
|
-
constructor(infos) {
|
|
105
|
+
constructor(compilerOptionsUsed, infos) {
|
|
106
|
+
ProjectArtifact.checkCompilerOptionsParameter(compilerOptionsUsed);
|
|
107
|
+
this.compilerOptionsUsed = compilerOptionsUsed;
|
|
97
108
|
this.infos = infos;
|
|
98
109
|
}
|
|
110
|
+
static checkCompilerOptionsParameter(compilerOptions) {
|
|
111
|
+
if (Object.keys(compilerOptions).length != Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
|
|
112
|
+
throw Error(`Not all compiler options are set: ${compilerOptions}`);
|
|
113
|
+
}
|
|
114
|
+
const combined = { ...compilerOptions, ...exports.DEFAULT_NODE_COMPILER_OPTIONS };
|
|
115
|
+
if (Object.keys(combined).length !== Object.keys(exports.DEFAULT_NODE_COMPILER_OPTIONS).length) {
|
|
116
|
+
throw Error(`There are unknown compiler options: ${compilerOptions}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
99
119
|
async saveToFile(rootPath) {
|
|
100
120
|
const filepath = rootPath + '/' + ProjectArtifact.artifactFileName;
|
|
101
|
-
const
|
|
121
|
+
const artifact = { compilerOptionsUsed: this.compilerOptionsUsed, infos: Object.fromEntries(this.infos) };
|
|
122
|
+
const content = JSON.stringify(artifact, null, 2);
|
|
102
123
|
return fs_2.promises.writeFile(filepath, content);
|
|
103
124
|
}
|
|
104
|
-
|
|
125
|
+
needToReCompile(compilerOptions, files) {
|
|
126
|
+
ProjectArtifact.checkCompilerOptionsParameter(compilerOptions);
|
|
127
|
+
const optionsMatched = Object.entries(compilerOptions).every(([key, inputOption]) => {
|
|
128
|
+
const usedOption = this.compilerOptionsUsed[`${key}`];
|
|
129
|
+
return usedOption === inputOption;
|
|
130
|
+
});
|
|
131
|
+
if (!optionsMatched) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
105
134
|
if (files.length !== this.infos.size) {
|
|
106
135
|
return true;
|
|
107
136
|
}
|
|
@@ -119,36 +148,67 @@ class ProjectArtifact {
|
|
|
119
148
|
return undefined;
|
|
120
149
|
}
|
|
121
150
|
const content = await fs_2.promises.readFile(filepath);
|
|
122
|
-
const
|
|
123
|
-
|
|
151
|
+
const json = JSON.parse(content.toString());
|
|
152
|
+
const compilerOptionsUsed = json.compilerOptionsUsed;
|
|
153
|
+
const files = new Map(Object.entries(json.infos));
|
|
154
|
+
return new ProjectArtifact(compilerOptionsUsed, files);
|
|
124
155
|
}
|
|
125
156
|
}
|
|
126
157
|
ProjectArtifact.artifactFileName = '.project.json';
|
|
127
158
|
class Project {
|
|
128
|
-
constructor(
|
|
129
|
-
this.
|
|
130
|
-
this.
|
|
131
|
-
this.artifactsRootPath = artifactsRootPath;
|
|
159
|
+
constructor(contractsRootDir, artifactsRootDir, sourceFiles, contracts, scripts, errorOnWarnings, projectArtifact) {
|
|
160
|
+
this.contractsRootDir = contractsRootDir;
|
|
161
|
+
this.artifactsRootDir = artifactsRootDir;
|
|
132
162
|
this.sourceFiles = sourceFiles;
|
|
133
163
|
this.contracts = contracts;
|
|
134
164
|
this.scripts = scripts;
|
|
165
|
+
this.projectArtifact = projectArtifact;
|
|
166
|
+
if (errorOnWarnings) {
|
|
167
|
+
Project.checkCompilerWarnings([...contracts.map((c) => c.warnings).flat(), ...scripts.map((s) => s.warnings).flat()], errorOnWarnings);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
static buildProjectArtifact(sourceFiles, contracts, scripts, compilerOptions) {
|
|
171
|
+
const files = new Map();
|
|
172
|
+
contracts.forEach((c) => {
|
|
173
|
+
files.set(c.sourceFile.contractPath, {
|
|
174
|
+
sourceCodeHash: c.sourceFile.sourceCodeHash,
|
|
175
|
+
bytecodeDebugPatch: c.artifact.bytecodeDebugPatch,
|
|
176
|
+
codeHashDebug: c.artifact.codeHashDebug,
|
|
177
|
+
warnings: c.warnings
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
scripts.forEach((s) => {
|
|
181
|
+
files.set(s.sourceFile.contractPath, {
|
|
182
|
+
sourceCodeHash: s.sourceFile.sourceCodeHash,
|
|
183
|
+
bytecodeDebugPatch: s.artifact.bytecodeDebugPatch,
|
|
184
|
+
codeHashDebug: '',
|
|
185
|
+
warnings: s.warnings
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
const compiledSize = contracts.length + scripts.length;
|
|
189
|
+
sourceFiles.slice(compiledSize).forEach((c) => {
|
|
190
|
+
files.set(c.contractPath, {
|
|
191
|
+
sourceCodeHash: c.sourceCodeHash,
|
|
192
|
+
bytecodeDebugPatch: '',
|
|
193
|
+
codeHashDebug: '',
|
|
194
|
+
warnings: []
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
return new ProjectArtifact(compilerOptions, files);
|
|
135
198
|
}
|
|
136
199
|
getContractPath(path) {
|
|
137
|
-
return path.startsWith(`./${this.
|
|
200
|
+
return path.startsWith(`./${this.contractsRootDir}`)
|
|
138
201
|
? path.slice(2)
|
|
139
|
-
: path.startsWith(this.
|
|
202
|
+
: path.startsWith(this.contractsRootDir)
|
|
140
203
|
? path
|
|
141
|
-
: this.
|
|
204
|
+
: this.contractsRootDir + '/' + path;
|
|
142
205
|
}
|
|
143
|
-
static checkCompilerWarnings(warnings,
|
|
144
|
-
|
|
145
|
-
? warnings.filter((s) => !s.includes('unused constants'))
|
|
146
|
-
: warnings;
|
|
147
|
-
if (remains.length !== 0) {
|
|
206
|
+
static checkCompilerWarnings(warnings, errorOnWarnings) {
|
|
207
|
+
if (warnings.length !== 0) {
|
|
148
208
|
const prefixPerWarning = ' - ';
|
|
149
|
-
const warningString = prefixPerWarning +
|
|
150
|
-
const output =
|
|
151
|
-
if (
|
|
209
|
+
const warningString = prefixPerWarning + warnings.join('\n' + prefixPerWarning);
|
|
210
|
+
const output = `Compilation warnings:\n` + warningString + '\n';
|
|
211
|
+
if (errorOnWarnings) {
|
|
152
212
|
throw new Error(output);
|
|
153
213
|
}
|
|
154
214
|
else {
|
|
@@ -156,95 +216,69 @@ class Project {
|
|
|
156
216
|
}
|
|
157
217
|
}
|
|
158
218
|
}
|
|
159
|
-
static contract(
|
|
160
|
-
const
|
|
161
|
-
const contract = Project.currentProject.contracts.find((c) => c.sourceFile.contractPath === contractPath);
|
|
219
|
+
static contract(name) {
|
|
220
|
+
const contract = Project.currentProject.contracts.find((c) => c.artifact.name === name);
|
|
162
221
|
if (typeof contract === 'undefined') {
|
|
163
|
-
throw new Error(`Contract ${
|
|
222
|
+
throw new Error(`Contract "${name}" does not exist`);
|
|
164
223
|
}
|
|
165
|
-
Project.checkCompilerWarnings(contract.warnings, { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptions });
|
|
166
224
|
return contract.artifact;
|
|
167
225
|
}
|
|
168
|
-
static script(
|
|
169
|
-
const
|
|
170
|
-
const script = Project.currentProject.scripts.find((c) => c.sourceFile.contractPath === contractPath);
|
|
226
|
+
static script(name) {
|
|
227
|
+
const script = Project.currentProject.scripts.find((c) => c.artifact.name === name);
|
|
171
228
|
if (typeof script === 'undefined') {
|
|
172
|
-
throw new Error(`Script ${
|
|
229
|
+
throw new Error(`Script "${name}" does not exist`);
|
|
173
230
|
}
|
|
174
|
-
Project.checkCompilerWarnings(script.warnings, { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptions });
|
|
175
231
|
return script.artifact;
|
|
176
232
|
}
|
|
177
233
|
async saveArtifactsToFile() {
|
|
178
|
-
const
|
|
234
|
+
const artifactsRootDir = this.artifactsRootDir;
|
|
179
235
|
const saveToFile = async function (compiled) {
|
|
180
|
-
const
|
|
181
|
-
const folder =
|
|
236
|
+
const artifactDir = compiled.sourceFile.getArtifactPath(artifactsRootDir);
|
|
237
|
+
const folder = artifactDir.slice(0, artifactDir.lastIndexOf('/'));
|
|
182
238
|
if (!fs_1.default.existsSync(folder)) {
|
|
183
239
|
fs_1.default.mkdirSync(folder, { recursive: true });
|
|
184
240
|
}
|
|
185
|
-
return fs_2.promises.writeFile(
|
|
241
|
+
return fs_2.promises.writeFile(artifactDir, compiled.artifact.toString());
|
|
186
242
|
};
|
|
187
243
|
for (const contract of this.contracts) {
|
|
188
|
-
|
|
244
|
+
saveToFile(contract);
|
|
189
245
|
}
|
|
190
246
|
for (const script of this.scripts) {
|
|
191
247
|
await saveToFile(script);
|
|
192
248
|
}
|
|
249
|
+
await this.projectArtifact.saveToFile(this.artifactsRootDir);
|
|
193
250
|
}
|
|
194
251
|
contractByCodeHash(codeHash) {
|
|
195
|
-
const contract = this.contracts.find((c) => c.artifact.codeHash === codeHash);
|
|
252
|
+
const contract = this.contracts.find((c) => c.artifact.codeHash === codeHash || c.artifact.codeHashDebug == codeHash);
|
|
196
253
|
if (typeof contract === 'undefined') {
|
|
197
254
|
throw new Error(`Unknown code with code hash: ${codeHash}`);
|
|
198
255
|
}
|
|
199
256
|
return contract.artifact;
|
|
200
257
|
}
|
|
201
|
-
async
|
|
202
|
-
const files = new Map();
|
|
203
|
-
this.contracts.forEach((c) => {
|
|
204
|
-
files.set(c.sourceFile.contractPath, {
|
|
205
|
-
sourceCodeHash: c.sourceFile.sourceCodeHash,
|
|
206
|
-
warnings: c.warnings
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
this.scripts.forEach((s) => {
|
|
210
|
-
files.set(s.sourceFile.contractPath, {
|
|
211
|
-
sourceCodeHash: s.sourceFile.sourceCodeHash,
|
|
212
|
-
warnings: s.warnings
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
const compiledSize = this.contracts.length + this.scripts.length;
|
|
216
|
-
this.sourceFiles.slice(compiledSize).forEach((c) => {
|
|
217
|
-
files.set(c.contractPath, {
|
|
218
|
-
sourceCodeHash: c.sourceCodeHash,
|
|
219
|
-
warnings: []
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
const projectArtifact = new ProjectArtifact(files);
|
|
223
|
-
await projectArtifact.saveToFile(this.artifactsRootPath);
|
|
224
|
-
}
|
|
225
|
-
static async compile(provider, files, contractsRootPath, artifactsRootPath) {
|
|
258
|
+
static async compile(provider, files, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
|
|
226
259
|
const sourceStr = files.map((f) => f.sourceCode).join('\n');
|
|
227
260
|
const result = await provider.contracts.postContractsCompileProject({
|
|
228
|
-
code: sourceStr
|
|
261
|
+
code: sourceStr,
|
|
262
|
+
compilerOptions: compilerOptions
|
|
229
263
|
});
|
|
230
264
|
const contracts = [];
|
|
231
265
|
const scripts = [];
|
|
232
266
|
result.contracts.forEach((contractResult, index) => {
|
|
233
267
|
const sourceFile = files[`${index}`];
|
|
234
|
-
const contract = Contract.fromCompileResult(
|
|
268
|
+
const contract = Contract.fromCompileResult(contractResult);
|
|
235
269
|
contracts.push(new Compiled(sourceFile, contract, contractResult.warnings));
|
|
236
270
|
});
|
|
237
271
|
result.scripts.forEach((scriptResult, index) => {
|
|
238
272
|
const sourceFile = files[index + contracts.length];
|
|
239
|
-
const script = Script.fromCompileResult(
|
|
273
|
+
const script = Script.fromCompileResult(scriptResult);
|
|
240
274
|
scripts.push(new Compiled(sourceFile, script, scriptResult.warnings));
|
|
241
275
|
});
|
|
242
|
-
const
|
|
276
|
+
const projectArtifact = Project.buildProjectArtifact(files, contracts, scripts, compilerOptions);
|
|
277
|
+
const project = new Project(contractsRootDir, artifactsRootDir, files, contracts, scripts, errorOnWarnings, projectArtifact);
|
|
243
278
|
await project.saveArtifactsToFile();
|
|
244
|
-
await project.saveProjectArtifactToFile();
|
|
245
279
|
return project;
|
|
246
280
|
}
|
|
247
|
-
static async loadArtifacts(provider, files, projectArtifact,
|
|
281
|
+
static async loadArtifacts(provider, files, projectArtifact, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions) {
|
|
248
282
|
try {
|
|
249
283
|
const contracts = [];
|
|
250
284
|
const scripts = [];
|
|
@@ -254,21 +288,21 @@ class Project {
|
|
|
254
288
|
throw Error(`Unable to find project info for ${file.contractPath}, please rebuild the project`);
|
|
255
289
|
}
|
|
256
290
|
const warnings = info.warnings;
|
|
257
|
-
const
|
|
291
|
+
const artifactDir = file.getArtifactPath(artifactsRootDir);
|
|
258
292
|
if (file.type === SourceType.Contract) {
|
|
259
|
-
const artifact = await Contract.fromArtifactFile(
|
|
293
|
+
const artifact = await Contract.fromArtifactFile(artifactDir, info.bytecodeDebugPatch, info.codeHashDebug);
|
|
260
294
|
contracts.push(new Compiled(file, artifact, warnings));
|
|
261
295
|
}
|
|
262
296
|
else if (file.type === SourceType.Script) {
|
|
263
|
-
const artifact = await Script.fromArtifactFile(
|
|
297
|
+
const artifact = await Script.fromArtifactFile(artifactDir, info.bytecodeDebugPatch);
|
|
264
298
|
scripts.push(new Compiled(file, artifact, warnings));
|
|
265
299
|
}
|
|
266
300
|
}
|
|
267
|
-
return new Project(
|
|
301
|
+
return new Project(contractsRootDir, artifactsRootDir, files, contracts, scripts, errorOnWarnings, projectArtifact);
|
|
268
302
|
}
|
|
269
303
|
catch (error) {
|
|
270
304
|
console.log(`Failed to load artifacts, error: ${error}, try to re-compile contracts...`);
|
|
271
|
-
return Project.compile(provider, files,
|
|
305
|
+
return Project.compile(provider, files, contractsRootDir, artifactsRootDir, errorOnWarnings, compilerOptions);
|
|
272
306
|
}
|
|
273
307
|
}
|
|
274
308
|
static async loadSourceFile(dirPath, filename) {
|
|
@@ -287,14 +321,10 @@ class Project {
|
|
|
287
321
|
throw new Error(`Multiple definitions in file: ${contractPath}`);
|
|
288
322
|
}
|
|
289
323
|
const matcherIndex = results.indexOf(1);
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
if (matcher.name === undefined) {
|
|
293
|
-
throw new Error(`Invalid definition in file: ${contractPath}`);
|
|
294
|
-
}
|
|
295
|
-
return new SourceFile(type, matcher.name, sourceStr, contractPath);
|
|
324
|
+
const type = this.matchers[`${matcherIndex}`].type;
|
|
325
|
+
return SourceFile.from(type, sourceStr, contractPath);
|
|
296
326
|
}
|
|
297
|
-
static async loadSourceFiles(
|
|
327
|
+
static async loadSourceFiles(contractsRootDir) {
|
|
298
328
|
const loadDir = async function (dirPath, results) {
|
|
299
329
|
const dirents = await fs_2.promises.readdir(dirPath, { withFileTypes: true });
|
|
300
330
|
for (const dirent of dirents) {
|
|
@@ -309,39 +339,45 @@ class Project {
|
|
|
309
339
|
}
|
|
310
340
|
};
|
|
311
341
|
const sourceFiles = [];
|
|
312
|
-
await loadDir(
|
|
342
|
+
await loadDir(contractsRootDir, sourceFiles);
|
|
313
343
|
const contractAndScriptSize = sourceFiles.filter((f) => f.type === SourceType.Contract || f.type === SourceType.Script).length;
|
|
314
344
|
if (sourceFiles.length === 0 || contractAndScriptSize === 0) {
|
|
315
345
|
throw new Error('Project have no source files');
|
|
316
346
|
}
|
|
317
347
|
return sourceFiles.sort((a, b) => a.type - b.type);
|
|
318
348
|
}
|
|
319
|
-
static async build(
|
|
349
|
+
static async build(compilerOptionsPartial = {}, contractsRootDir = Project.DEFAULT_CONTRACTS_DIR, artifactsRootDir = Project.DEFAULT_ARTIFACTS_DIR) {
|
|
320
350
|
const provider = (0, global_1.getCurrentNodeProvider)();
|
|
321
|
-
const sourceFiles = await Project.loadSourceFiles(
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
351
|
+
const sourceFiles = await Project.loadSourceFiles(contractsRootDir);
|
|
352
|
+
const { errorOnWarnings, ...nodeCompilerOptions } = { ...exports.DEFAULT_COMPILER_OPTIONS, ...compilerOptionsPartial };
|
|
353
|
+
const projectArtifact = await ProjectArtifact.from(artifactsRootDir);
|
|
354
|
+
if (typeof projectArtifact === 'undefined' || projectArtifact.needToReCompile(nodeCompilerOptions, sourceFiles)) {
|
|
355
|
+
console.log(`Compiling contracts in folder "${contractsRootDir}"`);
|
|
356
|
+
Project.currentProject = await Project.compile(provider, sourceFiles, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
|
|
325
357
|
}
|
|
326
358
|
else {
|
|
327
|
-
|
|
359
|
+
console.log(`Contracts are compiled already. Loading them from folder "${artifactsRootDir}"`);
|
|
360
|
+
Project.currentProject = await Project.loadArtifacts(provider, sourceFiles, projectArtifact, contractsRootDir, artifactsRootDir, errorOnWarnings, nodeCompilerOptions);
|
|
328
361
|
}
|
|
329
362
|
}
|
|
330
363
|
}
|
|
331
364
|
exports.Project = Project;
|
|
332
|
-
Project.abstractContractMatcher = new TypedMatcher('^Abstract Contract
|
|
333
|
-
Project.contractMatcher = new TypedMatcher('^Contract
|
|
334
|
-
Project.interfaceMatcher = new TypedMatcher('^Interface
|
|
335
|
-
Project.scriptMatcher = new TypedMatcher('^TxScript
|
|
365
|
+
Project.abstractContractMatcher = new TypedMatcher('^Abstract Contract [A-Z][a-zA-Z0-9]*', SourceType.AbstractContract);
|
|
366
|
+
Project.contractMatcher = new TypedMatcher('^Contract [A-Z][a-zA-Z0-9]*', SourceType.Contract);
|
|
367
|
+
Project.interfaceMatcher = new TypedMatcher('^Interface [A-Z][a-zA-Z0-9]* \\{', SourceType.Interface);
|
|
368
|
+
Project.scriptMatcher = new TypedMatcher('^TxScript [A-Z][a-zA-Z0-9]*', SourceType.Script);
|
|
336
369
|
Project.matchers = [
|
|
337
370
|
Project.abstractContractMatcher,
|
|
338
371
|
Project.contractMatcher,
|
|
339
372
|
Project.interfaceMatcher,
|
|
340
373
|
Project.scriptMatcher
|
|
341
374
|
];
|
|
375
|
+
Project.DEFAULT_CONTRACTS_DIR = 'contracts';
|
|
376
|
+
Project.DEFAULT_ARTIFACTS_DIR = 'artifacts';
|
|
342
377
|
class Artifact {
|
|
343
|
-
constructor(
|
|
344
|
-
this.
|
|
378
|
+
constructor(version, name, functions) {
|
|
379
|
+
this.version = version;
|
|
380
|
+
this.name = name;
|
|
345
381
|
this.functions = functions;
|
|
346
382
|
}
|
|
347
383
|
publicFunctions() {
|
|
@@ -356,43 +392,49 @@ class Artifact {
|
|
|
356
392
|
}
|
|
357
393
|
exports.Artifact = Artifact;
|
|
358
394
|
class Contract extends Artifact {
|
|
359
|
-
constructor(
|
|
360
|
-
super(
|
|
395
|
+
constructor(version, name, bytecode, bytecodeDebugPatch, codeHash, codeHashDebug, fieldsSig, eventsSig, functions) {
|
|
396
|
+
super(version, name, functions);
|
|
361
397
|
this.bytecode = bytecode;
|
|
398
|
+
this.bytecodeDebugPatch = bytecodeDebugPatch;
|
|
362
399
|
this.codeHash = codeHash;
|
|
363
400
|
this.fieldsSig = fieldsSig;
|
|
364
401
|
this.eventsSig = eventsSig;
|
|
402
|
+
this.bytecodeDebug = ralph.buildDebugBytecode(this.bytecode, this.bytecodeDebugPatch);
|
|
403
|
+
this.codeHashDebug = codeHashDebug;
|
|
365
404
|
}
|
|
366
405
|
// TODO: safely parse json
|
|
367
|
-
static fromJson(artifact) {
|
|
368
|
-
if (artifact.
|
|
406
|
+
static fromJson(artifact, bytecodeDebugPatch = '', codeHashDebug = '') {
|
|
407
|
+
if (artifact.version == null ||
|
|
408
|
+
artifact.name == null ||
|
|
409
|
+
artifact.bytecode == null ||
|
|
369
410
|
artifact.codeHash == null ||
|
|
370
411
|
artifact.fieldsSig == null ||
|
|
371
412
|
artifact.eventsSig == null ||
|
|
372
413
|
artifact.functions == null) {
|
|
373
414
|
throw Error('The artifact JSON for contract is incomplete');
|
|
374
415
|
}
|
|
375
|
-
const contract = new Contract(artifact.
|
|
416
|
+
const contract = new Contract(artifact.version, artifact.name, artifact.bytecode, bytecodeDebugPatch, artifact.codeHash, codeHashDebug ? codeHashDebug : artifact.codeHash, artifact.fieldsSig, artifact.eventsSig, artifact.functions);
|
|
376
417
|
return contract;
|
|
377
418
|
}
|
|
378
|
-
static fromCompileResult(
|
|
379
|
-
return new Contract(
|
|
419
|
+
static fromCompileResult(result) {
|
|
420
|
+
return new Contract(result.version, result.name, result.bytecode, result.bytecodeDebugPatch, result.codeHash, result.codeHashDebug, result.fields, result.events, result.functions);
|
|
380
421
|
}
|
|
381
422
|
// support both 'code.ral' and 'code.ral.json'
|
|
382
|
-
static async fromArtifactFile(path) {
|
|
423
|
+
static async fromArtifactFile(path, bytecodeDebugPatch, codeHashDebug) {
|
|
383
424
|
const content = await fs_2.promises.readFile(path);
|
|
384
425
|
const artifact = JSON.parse(content.toString());
|
|
385
|
-
return Contract.fromJson(artifact);
|
|
426
|
+
return Contract.fromJson(artifact, bytecodeDebugPatch, codeHashDebug);
|
|
386
427
|
}
|
|
387
428
|
async fetchState(address, group) {
|
|
388
|
-
const state = await
|
|
429
|
+
const state = await __1.web3.getCurrentNodeProvider().contracts.getContractsAddressState(address, {
|
|
389
430
|
group: group
|
|
390
431
|
});
|
|
391
432
|
return this.fromApiContractState(state);
|
|
392
433
|
}
|
|
393
434
|
toString() {
|
|
394
435
|
const object = {
|
|
395
|
-
|
|
436
|
+
version: this.version,
|
|
437
|
+
name: this.name,
|
|
396
438
|
bytecode: this.bytecode,
|
|
397
439
|
codeHash: this.codeHash,
|
|
398
440
|
fieldsSig: this.fieldsSig,
|
|
@@ -413,16 +455,27 @@ class Contract extends Artifact {
|
|
|
413
455
|
asset: asset
|
|
414
456
|
};
|
|
415
457
|
}
|
|
458
|
+
// no need to be cryptographically strong random
|
|
416
459
|
static randomAddress() {
|
|
417
|
-
const bytes =
|
|
460
|
+
const bytes = new Uint8Array(33);
|
|
461
|
+
crypto_1.webcrypto.getRandomValues(bytes);
|
|
418
462
|
bytes[0] = 3;
|
|
419
463
|
return utils_1.bs58.encode(bytes);
|
|
420
464
|
}
|
|
421
|
-
|
|
465
|
+
_printDebugMessages(funcName, messages) {
|
|
466
|
+
if (messages.length != 0) {
|
|
467
|
+
console.log(`Testing ${this.name}.${funcName}:`);
|
|
468
|
+
messages.forEach((m) => console.log(`Debug - ${m.contractAddress} - ${m.message}`));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
async _test(funcName, params, expectPublic, accessType, printDebugMessages) {
|
|
422
472
|
const apiParams = this.toTestContract(funcName, params);
|
|
423
|
-
const apiResult = await
|
|
473
|
+
const apiResult = await __1.web3.getCurrentNodeProvider().contracts.postContractsTestContract(apiParams);
|
|
424
474
|
const methodIndex = typeof params.testMethodIndex !== 'undefined' ? params.testMethodIndex : this.getMethodIndex(funcName);
|
|
425
475
|
const isPublic = this.functions[`${methodIndex}`].isPublic;
|
|
476
|
+
if (printDebugMessages) {
|
|
477
|
+
this._printDebugMessages(funcName, apiResult.debugMessages);
|
|
478
|
+
}
|
|
426
479
|
if (isPublic === expectPublic) {
|
|
427
480
|
const result = await this.fromTestContractResult(methodIndex, apiResult);
|
|
428
481
|
return result;
|
|
@@ -431,11 +484,11 @@ class Contract extends Artifact {
|
|
|
431
484
|
throw new Error(`The test method ${funcName} is not ${accessType}`);
|
|
432
485
|
}
|
|
433
486
|
}
|
|
434
|
-
async testPublicMethod(funcName, params) {
|
|
435
|
-
return this._test(funcName, params, true, 'public');
|
|
487
|
+
async testPublicMethod(funcName, params, printDebugMessages = true) {
|
|
488
|
+
return this._test(funcName, params, true, 'public', printDebugMessages);
|
|
436
489
|
}
|
|
437
|
-
async testPrivateMethod(funcName, params) {
|
|
438
|
-
return this._test(funcName, params, false, 'private');
|
|
490
|
+
async testPrivateMethod(funcName, params, printDebugMessages = true) {
|
|
491
|
+
return this._test(funcName, params, false, 'private', printDebugMessages);
|
|
439
492
|
}
|
|
440
493
|
toApiFields(fields) {
|
|
441
494
|
if (typeof fields === 'undefined') {
|
|
@@ -467,7 +520,7 @@ class Contract extends Artifact {
|
|
|
467
520
|
return {
|
|
468
521
|
group: params.group,
|
|
469
522
|
address: params.address,
|
|
470
|
-
bytecode: this.
|
|
523
|
+
bytecode: this.bytecodeDebug,
|
|
471
524
|
initialFields: this.toApiFields(params.initialFields),
|
|
472
525
|
initialAsset: typeof params.initialAsset !== 'undefined' ? toApiAsset(params.initialAsset) : undefined,
|
|
473
526
|
methodIndex: this.getMethodIndex(funcName),
|
|
@@ -476,7 +529,7 @@ class Contract extends Artifact {
|
|
|
476
529
|
inputAssets: toApiInputAssets(params.inputAssets)
|
|
477
530
|
};
|
|
478
531
|
}
|
|
479
|
-
|
|
532
|
+
fromApiContractState(state) {
|
|
480
533
|
const contract = Project.currentProject.contractByCodeHash(state.codeHash);
|
|
481
534
|
return {
|
|
482
535
|
address: state.address,
|
|
@@ -489,7 +542,7 @@ class Contract extends Artifact {
|
|
|
489
542
|
asset: fromApiAsset(state.asset)
|
|
490
543
|
};
|
|
491
544
|
}
|
|
492
|
-
static
|
|
545
|
+
static fromApiEvent(event, codeHash) {
|
|
493
546
|
let eventSig;
|
|
494
547
|
if (event.eventIndex == -1) {
|
|
495
548
|
eventSig = this.ContractCreatedEvent;
|
|
@@ -508,18 +561,18 @@ class Contract extends Artifact {
|
|
|
508
561
|
fields: fromApiEventFields(event.fields, eventSig)
|
|
509
562
|
};
|
|
510
563
|
}
|
|
511
|
-
|
|
564
|
+
fromTestContractResult(methodIndex, result) {
|
|
512
565
|
const addressToCodeHash = new Map();
|
|
513
566
|
addressToCodeHash.set(result.address, result.codeHash);
|
|
514
567
|
result.contracts.forEach((contract) => addressToCodeHash.set(contract.address, contract.codeHash));
|
|
515
568
|
return {
|
|
516
|
-
address: result.address,
|
|
517
569
|
contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(result.address)),
|
|
518
|
-
|
|
570
|
+
contractAddress: result.address,
|
|
571
|
+
returns: (0, api_1.fromApiArray)(result.returns, this.functions[`${methodIndex}`].returnTypes),
|
|
519
572
|
gasUsed: result.gasUsed,
|
|
520
|
-
contracts:
|
|
573
|
+
contracts: result.contracts.map((contract) => this.fromApiContractState(contract)),
|
|
521
574
|
txOutputs: result.txOutputs.map(fromApiOutput),
|
|
522
|
-
events:
|
|
575
|
+
events: result.events.map((event) => {
|
|
523
576
|
const contractAddress = event.contractAddress;
|
|
524
577
|
const codeHash = addressToCodeHash.get(contractAddress);
|
|
525
578
|
if (typeof codeHash !== 'undefined' || event.eventIndex < 0) {
|
|
@@ -528,29 +581,26 @@ class Contract extends Artifact {
|
|
|
528
581
|
else {
|
|
529
582
|
throw Error(`Cannot find codeHash for the contract address: ${contractAddress}`);
|
|
530
583
|
}
|
|
531
|
-
})
|
|
584
|
+
}),
|
|
585
|
+
debugMessages: result.debugMessages
|
|
532
586
|
};
|
|
533
587
|
}
|
|
534
|
-
async
|
|
588
|
+
async txParamsForDeployment(signer, params) {
|
|
535
589
|
const bytecode = this.buildByteCodeToDeploy(params.initialFields ? params.initialFields : {});
|
|
536
590
|
const signerParams = {
|
|
537
|
-
signerAddress:
|
|
591
|
+
signerAddress: (await signer.getSelectedAccount()).address,
|
|
538
592
|
bytecode: bytecode,
|
|
539
|
-
initialAttoAlphAmount:
|
|
540
|
-
issueTokenAmount:
|
|
541
|
-
initialTokenAmounts: params.initialTokenAmounts
|
|
593
|
+
initialAttoAlphAmount: params.initialAttoAlphAmount,
|
|
594
|
+
issueTokenAmount: params.issueTokenAmount,
|
|
595
|
+
initialTokenAmounts: params.initialTokenAmounts,
|
|
542
596
|
gasAmount: params.gasAmount,
|
|
543
|
-
gasPrice:
|
|
597
|
+
gasPrice: params.gasPrice
|
|
544
598
|
};
|
|
545
599
|
return signerParams;
|
|
546
600
|
}
|
|
547
|
-
async
|
|
548
|
-
const signerParams = await this.
|
|
549
|
-
|
|
550
|
-
signerAddress: (await signer.getAccounts())[0].address
|
|
551
|
-
});
|
|
552
|
-
const response = await signer.buildContractCreationTx(signerParams);
|
|
553
|
-
return fromApiDeployContractUnsignedTx(response);
|
|
601
|
+
async deploy(signer, params) {
|
|
602
|
+
const signerParams = await this.txParamsForDeployment(signer, params);
|
|
603
|
+
return signer.signAndSubmitDeployContractTx(signerParams);
|
|
554
604
|
}
|
|
555
605
|
buildByteCodeToDeploy(initialFields) {
|
|
556
606
|
return ralph.buildContractByteCode(this.bytecode, initialFields, this.fieldsSig);
|
|
@@ -568,273 +618,77 @@ Contract.ContractDestroyedEvent = {
|
|
|
568
618
|
fieldTypes: ['Address']
|
|
569
619
|
};
|
|
570
620
|
class Script extends Artifact {
|
|
571
|
-
constructor(
|
|
572
|
-
super(
|
|
621
|
+
constructor(version, name, bytecodeTemplate, bytecodeDebugPatch, fieldsSig, functions) {
|
|
622
|
+
super(version, name, functions);
|
|
573
623
|
this.bytecodeTemplate = bytecodeTemplate;
|
|
624
|
+
this.bytecodeDebugPatch = bytecodeDebugPatch;
|
|
574
625
|
this.fieldsSig = fieldsSig;
|
|
575
626
|
}
|
|
576
|
-
static fromCompileResult(
|
|
577
|
-
return new Script(
|
|
627
|
+
static fromCompileResult(result) {
|
|
628
|
+
return new Script(result.version, result.name, result.bytecodeTemplate, result.bytecodeDebugPatch, result.fields, result.functions);
|
|
578
629
|
}
|
|
579
630
|
// TODO: safely parse json
|
|
580
|
-
static fromJson(artifact) {
|
|
581
|
-
if (artifact.
|
|
631
|
+
static fromJson(artifact, bytecodeDebugPatch = '') {
|
|
632
|
+
if (artifact.version == null ||
|
|
633
|
+
artifact.name == null ||
|
|
634
|
+
artifact.bytecodeTemplate == null ||
|
|
635
|
+
artifact.fieldsSig == null ||
|
|
636
|
+
artifact.functions == null) {
|
|
582
637
|
throw Error('The artifact JSON for script is incomplete');
|
|
583
638
|
}
|
|
584
|
-
return new Script(artifact.
|
|
639
|
+
return new Script(artifact.version, artifact.name, artifact.bytecodeTemplate, bytecodeDebugPatch, artifact.fieldsSig, artifact.functions);
|
|
585
640
|
}
|
|
586
|
-
static async fromArtifactFile(path) {
|
|
641
|
+
static async fromArtifactFile(path, bytecodeDebugPatch) {
|
|
587
642
|
const content = await fs_2.promises.readFile(path);
|
|
588
643
|
const artifact = JSON.parse(content.toString());
|
|
589
|
-
return this.fromJson(artifact);
|
|
644
|
+
return this.fromJson(artifact, bytecodeDebugPatch);
|
|
590
645
|
}
|
|
591
646
|
toString() {
|
|
592
647
|
const object = {
|
|
593
|
-
|
|
648
|
+
version: this.version,
|
|
649
|
+
name: this.name,
|
|
594
650
|
bytecodeTemplate: this.bytecodeTemplate,
|
|
595
651
|
fieldsSig: this.fieldsSig,
|
|
596
652
|
functions: this.functions
|
|
597
653
|
};
|
|
598
654
|
return JSON.stringify(object, null, 2);
|
|
599
655
|
}
|
|
600
|
-
async
|
|
656
|
+
async txParamsForExecution(signer, params) {
|
|
601
657
|
const signerParams = {
|
|
602
|
-
signerAddress:
|
|
658
|
+
signerAddress: (await signer.getSelectedAccount()).address,
|
|
603
659
|
bytecode: this.buildByteCodeToDeploy(params.initialFields ? params.initialFields : {}),
|
|
604
|
-
attoAlphAmount:
|
|
605
|
-
tokens:
|
|
660
|
+
attoAlphAmount: params.attoAlphAmount,
|
|
661
|
+
tokens: params.tokens,
|
|
606
662
|
gasAmount: params.gasAmount,
|
|
607
|
-
gasPrice:
|
|
663
|
+
gasPrice: params.gasPrice
|
|
608
664
|
};
|
|
609
665
|
return signerParams;
|
|
610
666
|
}
|
|
611
|
-
async
|
|
612
|
-
const signerParams = await this.
|
|
613
|
-
|
|
614
|
-
signerAddress: (await signer.getAccounts())[0].address
|
|
615
|
-
});
|
|
616
|
-
return await signer.buildScriptTx(signerParams);
|
|
667
|
+
async execute(signer, params) {
|
|
668
|
+
const signerParams = await this.txParamsForExecution(signer, params);
|
|
669
|
+
return await signer.signAndSubmitExecuteScriptTx(signerParams);
|
|
617
670
|
}
|
|
618
671
|
buildByteCodeToDeploy(initialFields) {
|
|
619
672
|
return ralph.buildScriptByteCode(this.bytecodeTemplate, initialFields, this.fieldsSig);
|
|
620
673
|
}
|
|
621
674
|
}
|
|
622
675
|
exports.Script = Script;
|
|
623
|
-
function extractBoolean(v) {
|
|
624
|
-
if (typeof v === 'boolean') {
|
|
625
|
-
return v;
|
|
626
|
-
}
|
|
627
|
-
else {
|
|
628
|
-
throw new Error(`Invalid boolean value: ${v}`);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
// TODO: check integer bounds
|
|
632
|
-
function extractNumber256(v) {
|
|
633
|
-
if ((typeof v === 'number' && Number.isInteger(v)) || typeof v === 'bigint') {
|
|
634
|
-
return v.toString();
|
|
635
|
-
}
|
|
636
|
-
else if (typeof v === 'string') {
|
|
637
|
-
return v;
|
|
638
|
-
}
|
|
639
|
-
else {
|
|
640
|
-
throw new Error(`Invalid 256 bit number: ${v}`);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
function extractOptionalNumber256(v) {
|
|
644
|
-
return typeof v !== 'undefined' ? extractNumber256(v) : undefined;
|
|
645
|
-
}
|
|
646
|
-
// TODO: check hex string
|
|
647
|
-
function extractByteVec(v) {
|
|
648
|
-
if (typeof v === 'string') {
|
|
649
|
-
// try to convert from address to contract id
|
|
650
|
-
try {
|
|
651
|
-
const address = utils_1.bs58.decode(v);
|
|
652
|
-
if (address.length == 33 && address[0] == 3) {
|
|
653
|
-
return buffer_1.Buffer.from(address.slice(1)).toString('hex');
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
catch (_) {
|
|
657
|
-
return v;
|
|
658
|
-
}
|
|
659
|
-
return v;
|
|
660
|
-
}
|
|
661
|
-
else {
|
|
662
|
-
throw new Error(`Invalid string: ${v}`);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
function extractBs58(v) {
|
|
666
|
-
if (typeof v === 'string') {
|
|
667
|
-
try {
|
|
668
|
-
utils_1.bs58.decode(v);
|
|
669
|
-
return v;
|
|
670
|
-
}
|
|
671
|
-
catch (error) {
|
|
672
|
-
throw new Error(`Invalid base58 string: ${v}`);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
throw new Error(`Invalid string: ${v}`);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
function decodeNumber256(n) {
|
|
680
|
-
if (Number.isSafeInteger(Number.parseInt(n))) {
|
|
681
|
-
return Number(n);
|
|
682
|
-
}
|
|
683
|
-
else {
|
|
684
|
-
return BigInt(n);
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
function extractArray(tpe, v) {
|
|
688
|
-
if (!Array.isArray(v)) {
|
|
689
|
-
throw new Error(`Expected array, got ${v}`);
|
|
690
|
-
}
|
|
691
|
-
const semiColonIndex = tpe.lastIndexOf(';');
|
|
692
|
-
if (semiColonIndex == -1) {
|
|
693
|
-
throw new Error(`Invalid Val type: ${tpe}`);
|
|
694
|
-
}
|
|
695
|
-
const subType = tpe.slice(1, semiColonIndex);
|
|
696
|
-
const dim = parseInt(tpe.slice(semiColonIndex + 1, -1));
|
|
697
|
-
if (v.length != dim) {
|
|
698
|
-
throw new Error(`Invalid val dimension: ${v}`);
|
|
699
|
-
}
|
|
700
|
-
else {
|
|
701
|
-
return { value: v.map((v) => toApiVal(v, subType)), type: 'Array' };
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
exports.extractArray = extractArray;
|
|
705
|
-
function toApiVal(v, tpe) {
|
|
706
|
-
if (tpe === 'Bool') {
|
|
707
|
-
return { value: extractBoolean(v), type: tpe };
|
|
708
|
-
}
|
|
709
|
-
else if (tpe === 'U256' || tpe === 'I256') {
|
|
710
|
-
return { value: extractNumber256(v), type: tpe };
|
|
711
|
-
}
|
|
712
|
-
else if (tpe === 'ByteVec') {
|
|
713
|
-
return { value: extractByteVec(v), type: tpe };
|
|
714
|
-
}
|
|
715
|
-
else if (tpe === 'Address') {
|
|
716
|
-
return { value: extractBs58(v), type: tpe };
|
|
717
|
-
}
|
|
718
|
-
else {
|
|
719
|
-
return extractArray(tpe, v);
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
exports.toApiVal = toApiVal;
|
|
723
|
-
function decodeArrayType(tpe) {
|
|
724
|
-
const semiColonIndex = tpe.lastIndexOf(';');
|
|
725
|
-
if (semiColonIndex === -1) {
|
|
726
|
-
throw new Error(`Invalid Val type: ${tpe}`);
|
|
727
|
-
}
|
|
728
|
-
const subType = tpe.slice(1, semiColonIndex);
|
|
729
|
-
const dim = parseInt(tpe.slice(semiColonIndex + 1, -1));
|
|
730
|
-
if (subType[0] == '[') {
|
|
731
|
-
const [baseType, subDim] = decodeArrayType(subType);
|
|
732
|
-
return [baseType, (subDim.unshift(dim), subDim)];
|
|
733
|
-
}
|
|
734
|
-
else {
|
|
735
|
-
return [subType, [dim]];
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
function foldVals(vals, dims) {
|
|
739
|
-
if (dims.length == 1) {
|
|
740
|
-
return vals;
|
|
741
|
-
}
|
|
742
|
-
else {
|
|
743
|
-
const result = [];
|
|
744
|
-
const chunkSize = vals.length / dims[0];
|
|
745
|
-
const chunkDims = dims.slice(1);
|
|
746
|
-
for (let i = 0; i < vals.length; i += chunkSize) {
|
|
747
|
-
const chunk = vals.slice(i, i + chunkSize);
|
|
748
|
-
result.push(foldVals(chunk, chunkDims));
|
|
749
|
-
}
|
|
750
|
-
return result;
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
function _fromApiVal(vals, valIndex, tpe) {
|
|
754
|
-
if (vals.length === 0) {
|
|
755
|
-
throw new Error('Not enough Vals');
|
|
756
|
-
}
|
|
757
|
-
const firstVal = vals[`${valIndex}`];
|
|
758
|
-
if (tpe === 'Bool' && firstVal.type === tpe) {
|
|
759
|
-
return [firstVal.value, valIndex + 1];
|
|
760
|
-
}
|
|
761
|
-
else if ((tpe === 'U256' || tpe === 'I256') && firstVal.type === tpe) {
|
|
762
|
-
return [decodeNumber256(firstVal.value), valIndex + 1];
|
|
763
|
-
}
|
|
764
|
-
else if ((tpe === 'ByteVec' || tpe === 'Address') && firstVal.type === tpe) {
|
|
765
|
-
return [firstVal.value, valIndex + 1];
|
|
766
|
-
}
|
|
767
|
-
else {
|
|
768
|
-
const [baseType, dims] = decodeArrayType(tpe);
|
|
769
|
-
const arraySize = dims.reduce((a, b) => a * b);
|
|
770
|
-
const nextIndex = valIndex + arraySize;
|
|
771
|
-
const valsToUse = vals.slice(valIndex, nextIndex);
|
|
772
|
-
if (valsToUse.length == arraySize && valsToUse.every((val) => val.type === baseType)) {
|
|
773
|
-
const localVals = valsToUse.map((val) => fromApiVal(val, baseType));
|
|
774
|
-
return [foldVals(localVals, dims), nextIndex];
|
|
775
|
-
}
|
|
776
|
-
else {
|
|
777
|
-
throw new Error(`Invalid array Val type: ${valsToUse}, ${tpe}`);
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
676
|
function fromApiFields(vals, fieldsSig) {
|
|
782
|
-
return fromApiVals(vals, fieldsSig.names, fieldsSig.types);
|
|
677
|
+
return (0, api_1.fromApiVals)(vals, fieldsSig.names, fieldsSig.types);
|
|
783
678
|
}
|
|
784
679
|
function fromApiEventFields(vals, eventSig) {
|
|
785
|
-
return fromApiVals(vals, eventSig.fieldNames, eventSig.fieldTypes);
|
|
786
|
-
}
|
|
787
|
-
function fromApiVals(vals, names, types) {
|
|
788
|
-
let valIndex = 0;
|
|
789
|
-
const result = {};
|
|
790
|
-
types.forEach((currentType, index) => {
|
|
791
|
-
const currentName = names[`${index}`];
|
|
792
|
-
const [val, nextIndex] = _fromApiVal(vals, valIndex, currentType);
|
|
793
|
-
valIndex = nextIndex;
|
|
794
|
-
result[`${currentName}`] = val;
|
|
795
|
-
});
|
|
796
|
-
return result;
|
|
797
|
-
}
|
|
798
|
-
function fromApiArray(vals, types) {
|
|
799
|
-
let valIndex = 0;
|
|
800
|
-
const result = [];
|
|
801
|
-
for (const currentType of types) {
|
|
802
|
-
const [val, nextIndex] = _fromApiVal(vals, valIndex, currentType);
|
|
803
|
-
result.push(val);
|
|
804
|
-
valIndex = nextIndex;
|
|
805
|
-
}
|
|
806
|
-
return result;
|
|
807
|
-
}
|
|
808
|
-
function fromApiVal(v, tpe) {
|
|
809
|
-
if (v.type === 'Bool' && v.type === tpe) {
|
|
810
|
-
return v.value;
|
|
811
|
-
}
|
|
812
|
-
else if ((v.type === 'U256' || v.type === 'I256') && v.type === tpe) {
|
|
813
|
-
return decodeNumber256(v.value);
|
|
814
|
-
}
|
|
815
|
-
else if ((v.type === 'ByteVec' || v.type === 'Address') && v.type === tpe) {
|
|
816
|
-
return v.value;
|
|
817
|
-
}
|
|
818
|
-
else {
|
|
819
|
-
throw new Error(`Invalid node.Val type: ${v}`);
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
function toApiToken(token) {
|
|
823
|
-
return { id: token.id, amount: extractNumber256(token.amount) };
|
|
824
|
-
}
|
|
825
|
-
function fromApiToken(token) {
|
|
826
|
-
return { id: token.id, amount: decodeNumber256(token.amount) };
|
|
680
|
+
return (0, api_1.fromApiVals)(vals, eventSig.fieldNames, eventSig.fieldTypes);
|
|
827
681
|
}
|
|
828
682
|
function toApiAsset(asset) {
|
|
829
683
|
return {
|
|
830
|
-
attoAlphAmount:
|
|
831
|
-
tokens: typeof asset.tokens !== 'undefined' ? asset.tokens.map(toApiToken) : []
|
|
684
|
+
attoAlphAmount: (0, api_1.toApiNumber256)(asset.alphAmount),
|
|
685
|
+
tokens: typeof asset.tokens !== 'undefined' ? asset.tokens.map(api_1.toApiToken) : []
|
|
832
686
|
};
|
|
833
687
|
}
|
|
834
688
|
function fromApiAsset(asset) {
|
|
835
689
|
return {
|
|
836
|
-
alphAmount:
|
|
837
|
-
tokens:
|
|
690
|
+
alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
|
|
691
|
+
tokens: (0, api_1.fromApiTokens)(asset.tokens)
|
|
838
692
|
};
|
|
839
693
|
}
|
|
840
694
|
function getVal(vals, name) {
|
|
@@ -865,7 +719,7 @@ function toApiVals(fields, names, types) {
|
|
|
865
719
|
return names.map((name, index) => {
|
|
866
720
|
const val = getVal(fields, name);
|
|
867
721
|
const tpe = types[`${index}`];
|
|
868
|
-
return toApiVal(val, tpe);
|
|
722
|
+
return (0, api_1.toApiVal)(val, tpe);
|
|
869
723
|
});
|
|
870
724
|
}
|
|
871
725
|
function toApiInputAsset(inputAsset) {
|
|
@@ -880,8 +734,8 @@ function fromApiOutput(output) {
|
|
|
880
734
|
return {
|
|
881
735
|
type: 'AssetOutput',
|
|
882
736
|
address: asset.address,
|
|
883
|
-
alphAmount:
|
|
884
|
-
tokens: asset.tokens
|
|
737
|
+
alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
|
|
738
|
+
tokens: (0, api_1.fromApiTokens)(asset.tokens),
|
|
885
739
|
lockTime: asset.lockTime,
|
|
886
740
|
message: asset.message
|
|
887
741
|
};
|
|
@@ -891,16 +745,13 @@ function fromApiOutput(output) {
|
|
|
891
745
|
return {
|
|
892
746
|
type: 'ContractOutput',
|
|
893
747
|
address: asset.address,
|
|
894
|
-
alphAmount:
|
|
895
|
-
tokens: asset.tokens
|
|
748
|
+
alphAmount: (0, api_1.fromApiNumber256)(asset.attoAlphAmount),
|
|
749
|
+
tokens: (0, api_1.fromApiTokens)(asset.tokens)
|
|
896
750
|
};
|
|
897
751
|
}
|
|
898
752
|
else {
|
|
899
753
|
throw new Error(`Unknown output type: ${output}`);
|
|
900
754
|
}
|
|
901
755
|
}
|
|
902
|
-
function fromApiDeployContractUnsignedTx(result) {
|
|
903
|
-
return { ...result, contractId: (0, utils_1.binToHex)((0, utils_1.contractIdFromAddress)(result.contractAddress)) };
|
|
904
|
-
}
|
|
905
756
|
(0, utils_1.assertType)();
|
|
906
757
|
(0, utils_1.assertType)();
|