@stacks/rendezvous 0.7.0 → 0.7.2
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/dist/citizen.js +162 -74
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/citizen.js
CHANGED
|
@@ -12,10 +12,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.getTestContractSource = exports.buildRendezvousData = exports.getContractSource = exports.
|
|
15
|
+
exports.getSbtcBalancesFromSimnet = exports.getTestContractSource = exports.buildRendezvousData = exports.getContractSource = exports.deployContracts = exports.groupContractsByEpochFromDeploymentPlan = exports.issueFirstClassCitizenship = void 0;
|
|
16
16
|
exports.scheduleRendezvous = scheduleRendezvous;
|
|
17
17
|
const fs_1 = require("fs");
|
|
18
18
|
const path_1 = require("path");
|
|
19
|
+
const toml_1 = __importDefault(require("toml"));
|
|
19
20
|
const yaml_1 = __importDefault(require("yaml"));
|
|
20
21
|
const clarinet_sdk_1 = require("@hirosystems/clarinet-sdk");
|
|
21
22
|
const transactions_1 = require("@stacks/transactions");
|
|
@@ -35,31 +36,21 @@ const transactions_1 = require("@stacks/transactions");
|
|
|
35
36
|
* the test contract treated as a first-class citizen of the target contract.
|
|
36
37
|
*/
|
|
37
38
|
const issueFirstClassCitizenship = (manifestDir, manifestPath, remoteDataSettings, sutContractName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
//
|
|
39
|
+
var _a;
|
|
40
|
+
// Initialize the simnet, to generate the deployment plan and instance. The
|
|
41
|
+
// empty session will be set up, and contracts will be deployed in the
|
|
42
|
+
// correct order based on the deployment plan a few lines below.
|
|
41
43
|
const simnet = yield (0, clarinet_sdk_1.initSimnet)(manifestPath);
|
|
42
|
-
const
|
|
44
|
+
const deploymentPlan = yaml_1.default.parse((0, fs_1.readFileSync)((0, path_1.join)(manifestDir, "deployments", "default.simnet-plan.yaml"), {
|
|
43
45
|
encoding: "utf-8",
|
|
44
46
|
}));
|
|
45
|
-
const sortedContractsByEpoch = (0, exports.
|
|
47
|
+
const sortedContractsByEpoch = (0, exports.groupContractsByEpochFromDeploymentPlan)(deploymentPlan);
|
|
46
48
|
const simnetAddresses = [...simnet.getAccounts().values()];
|
|
47
49
|
const stxBalancesMap = new Map(simnetAddresses.map((address) => {
|
|
48
50
|
const balanceHex = simnet.runSnippet(`(stx-get-balance '${address})`);
|
|
49
51
|
return [address, (0, transactions_1.cvToValue)((0, transactions_1.hexToCV)(balanceHex))];
|
|
50
52
|
}));
|
|
51
|
-
const sbtcBalancesMap =
|
|
52
|
-
try {
|
|
53
|
-
const { result: getBalanceResult } = simnet.callReadOnlyFn("SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token", "get-balance", [transactions_1.Cl.principal(address)], address);
|
|
54
|
-
// If the previous read-only call works, the user is working with
|
|
55
|
-
// sBTC. This means we can proceed with restoring sBTC balances.
|
|
56
|
-
const sbtcBalance = (0, transactions_1.cvToJSON)(getBalanceResult).value.value;
|
|
57
|
-
return [address, sbtcBalance];
|
|
58
|
-
}
|
|
59
|
-
catch (e) {
|
|
60
|
-
return [address, 0];
|
|
61
|
-
}
|
|
62
|
-
}));
|
|
53
|
+
const sbtcBalancesMap = (0, exports.getSbtcBalancesFromSimnet)(simnet);
|
|
63
54
|
yield simnet.initEmptySession(remoteDataSettings);
|
|
64
55
|
simnetAddresses.forEach((address) => {
|
|
65
56
|
simnet.mintSTX(address, stxBalancesMap.get(address));
|
|
@@ -68,13 +59,19 @@ const issueFirstClassCitizenship = (manifestDir, manifestPath, remoteDataSetting
|
|
|
68
59
|
// resulting contract will replace the target contract in the simnet.
|
|
69
60
|
/** The contract names mapped to the concatenated source code. */
|
|
70
61
|
const rendezvousSources = new Map([sutContractName]
|
|
71
|
-
|
|
62
|
+
// For each target contract name, execute the processing steps to get the
|
|
63
|
+
// concatenated contract source code and the contract ID.
|
|
64
|
+
.map((contractName) => (0, exports.buildRendezvousData)(deploymentPlan, contractName, manifestDir))
|
|
65
|
+
// Use the contract ID as a key, mapping to the concatenated contract
|
|
66
|
+
// source code.
|
|
72
67
|
.map((rendezvousContractData) => [
|
|
73
|
-
rendezvousContractData.
|
|
74
|
-
rendezvousContractData.
|
|
68
|
+
rendezvousContractData.rendezvousContractId,
|
|
69
|
+
rendezvousContractData.rendezvousSourceCode,
|
|
75
70
|
]));
|
|
76
|
-
|
|
77
|
-
|
|
71
|
+
const clarinetToml = toml_1.default.parse((0, fs_1.readFileSync)(manifestPath, { encoding: "utf-8" }));
|
|
72
|
+
const cacheDir = ((_a = clarinetToml.project) === null || _a === void 0 ? void 0 : _a.cache_dir) || "./.cache";
|
|
73
|
+
// Deploy the contracts to the empty simnet session in the correct order.
|
|
74
|
+
yield (0, exports.deployContracts)(simnet, sortedContractsByEpoch, manifestDir, cacheDir, (name, sender, props) => (0, exports.getContractSource)([sutContractName], rendezvousSources, name, sender, props, manifestDir));
|
|
78
75
|
// Filter out addresses with zero balance. They do not need to be restored.
|
|
79
76
|
const sbtcBalancesToRestore = new Map([...sbtcBalancesMap.entries()].filter(([_, balance]) => balance !== 0));
|
|
80
77
|
// After all the contracts and requirements are deployed, if the test wallets
|
|
@@ -87,15 +84,15 @@ const issueFirstClassCitizenship = (manifestDir, manifestPath, remoteDataSetting
|
|
|
87
84
|
});
|
|
88
85
|
exports.issueFirstClassCitizenship = issueFirstClassCitizenship;
|
|
89
86
|
/**
|
|
90
|
-
* Groups contracts by epoch from the
|
|
91
|
-
* @param
|
|
87
|
+
* Groups contracts by epoch from the deployment plan.
|
|
88
|
+
* @param deploymentPlan The parsed deployment plan.
|
|
92
89
|
* @returns A record of contracts grouped by epoch. The record key is the epoch
|
|
93
90
|
* string, and the value is an array of contracts. Each contract is represented
|
|
94
91
|
* as a record with the contract name as the key and a record containing the
|
|
95
92
|
* contract path and clarity version as the value.
|
|
96
93
|
*/
|
|
97
|
-
const
|
|
98
|
-
return
|
|
94
|
+
const groupContractsByEpochFromDeploymentPlan = (deploymentPlan) => {
|
|
95
|
+
return deploymentPlan.plan.batches.reduce((acc, batch) => {
|
|
99
96
|
const epoch = batch.epoch;
|
|
100
97
|
const contracts = batch.transactions
|
|
101
98
|
.filter((tx) => tx["emulated-contract-publish"])
|
|
@@ -114,44 +111,56 @@ const groupContractsByEpochFromSimnetPlan = (simnetPlan) => {
|
|
|
114
111
|
return acc;
|
|
115
112
|
}, {});
|
|
116
113
|
};
|
|
117
|
-
exports.
|
|
114
|
+
exports.groupContractsByEpochFromDeploymentPlan = groupContractsByEpochFromDeploymentPlan;
|
|
118
115
|
/**
|
|
119
116
|
* Deploys the contracts to the simnet in the correct order.
|
|
120
117
|
* @param simnet The simnet instance.
|
|
121
118
|
* @param contractsByEpoch The record of contracts by epoch.
|
|
122
119
|
* @param getContractSourceFn The function to retrieve the contract source.
|
|
123
120
|
*/
|
|
124
|
-
const deployContracts = (simnet, contractsByEpoch, getContractSourceFn) => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
|
+
const deployContracts = (simnet, contractsByEpoch, manifestDir, cacheDir, getContractSourceFn) => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
122
|
for (const [epoch, contracts] of Object.entries(contractsByEpoch)) {
|
|
126
123
|
// Move to the next epoch and deploy the contracts in the correct order.
|
|
127
124
|
simnet.setEpoch(epoch);
|
|
128
125
|
for (const contract of contracts.flatMap(Object.entries)) {
|
|
129
126
|
const [name, props] = contract;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
//
|
|
134
|
-
const
|
|
135
|
-
|
|
127
|
+
// Resolve paths to absolute for proper comparison.
|
|
128
|
+
const absoluteContractPath = (0, path_1.resolve)(manifestDir, props.path);
|
|
129
|
+
const absoluteRequirementsPath = (0, path_1.resolve)(manifestDir, cacheDir, "requirements");
|
|
130
|
+
// Check if contract is in requirements directory.
|
|
131
|
+
const isRequirement = absoluteContractPath.startsWith(absoluteRequirementsPath);
|
|
132
|
+
const sender = isRequirement
|
|
133
|
+
? (0, path_1.basename)(props.path).split(".")[0]
|
|
136
134
|
: simnet.deployer;
|
|
135
|
+
const source = getContractSourceFn(name, sender, props);
|
|
137
136
|
simnet.deployContract(name, source, { clarityVersion: props.clarity_version }, sender);
|
|
138
137
|
}
|
|
139
138
|
}
|
|
140
139
|
});
|
|
140
|
+
exports.deployContracts = deployContracts;
|
|
141
141
|
/**
|
|
142
142
|
* Conditionally retrieves the contract source based on whether the contract is
|
|
143
143
|
* a SUT contract or not.
|
|
144
144
|
* @param targetContractNames The list of target contract names.
|
|
145
|
-
* @param rendezvousSourcesMap The contract
|
|
146
|
-
* source code.
|
|
145
|
+
* @param rendezvousSourcesMap The target contract IDs mapped to the resulting
|
|
146
|
+
* concatenated source code.
|
|
147
147
|
* @param contractName The contract name.
|
|
148
|
+
* @param contractSender The emulated sender of the contract according to the
|
|
149
|
+
* deployment plan.
|
|
148
150
|
* @param contractProps The contract deployment properties.
|
|
149
151
|
* @param manifestDir The relative path to the manifest directory.
|
|
150
152
|
* @returns The contract source code.
|
|
151
153
|
*/
|
|
152
|
-
const getContractSource = (targetContractNames, rendezvousSourcesMap, contractName, contractProps, manifestDir) => {
|
|
153
|
-
|
|
154
|
-
|
|
154
|
+
const getContractSource = (targetContractNames, rendezvousSourcesMap, contractName, contractSender, contractProps, manifestDir) => {
|
|
155
|
+
const contractId = `${contractSender}.${contractName}`;
|
|
156
|
+
// Checking if a contract is a SUT one just by using the name is not enough.
|
|
157
|
+
// There can be multiple contracts with the same name, but different senders
|
|
158
|
+
// in the deployment plan. The contract ID is the unique identifier used to
|
|
159
|
+
// store the concatenated Rendezvous source codes in the
|
|
160
|
+
// `rendezvousSourcesMap`.
|
|
161
|
+
if (targetContractNames.includes(contractName) &&
|
|
162
|
+
rendezvousSourcesMap.has(contractId)) {
|
|
163
|
+
const contractSource = rendezvousSourcesMap.get(contractId);
|
|
155
164
|
if (!contractSource) {
|
|
156
165
|
throw new Error(`Contract source not found for ${contractName}`);
|
|
157
166
|
}
|
|
@@ -166,20 +175,24 @@ const getContractSource = (targetContractNames, rendezvousSourcesMap, contractNa
|
|
|
166
175
|
exports.getContractSource = getContractSource;
|
|
167
176
|
/**
|
|
168
177
|
* Builds the Rendezvous data.
|
|
169
|
-
* @param
|
|
178
|
+
* @param deploymentPlan The parsed deployment plan.
|
|
170
179
|
* @param contractName The contract name.
|
|
171
180
|
* @param manifestDir The relative path to the manifest directory.
|
|
172
181
|
* @returns The Rendezvous data representing a record. The returned record
|
|
173
|
-
* contains the Rendezvous source code and the Rendezvous contract
|
|
182
|
+
* contains the Rendezvous source code and the unique Rendezvous contract ID.
|
|
174
183
|
*/
|
|
175
|
-
const buildRendezvousData = (
|
|
184
|
+
const buildRendezvousData = (deploymentPlan, contractName, manifestDir) => {
|
|
176
185
|
try {
|
|
177
|
-
const sutContractSource =
|
|
178
|
-
const testContractSource = (0, exports.getTestContractSource)(
|
|
186
|
+
const sutContractSource = getDeploymentPlanContractSource(deploymentPlan, contractName, manifestDir);
|
|
187
|
+
const testContractSource = (0, exports.getTestContractSource)(deploymentPlan, contractName, manifestDir);
|
|
179
188
|
const rendezvousSource = scheduleRendezvous(sutContractSource, testContractSource);
|
|
189
|
+
const rendezvousContractEmulatedSender = getSutContractDeploymentPlanEmulatedPublish(deploymentPlan, contractName)["emulated-sender"];
|
|
190
|
+
// Use the contract ID as a unique identifier of the contract within the
|
|
191
|
+
// deployment plan.
|
|
192
|
+
const rendezvousContractId = `${rendezvousContractEmulatedSender}.${contractName}`;
|
|
180
193
|
return {
|
|
181
|
-
|
|
182
|
-
|
|
194
|
+
rendezvousContractId: rendezvousContractId,
|
|
195
|
+
rendezvousSourceCode: rendezvousSource,
|
|
183
196
|
};
|
|
184
197
|
}
|
|
185
198
|
catch (error) {
|
|
@@ -188,47 +201,45 @@ const buildRendezvousData = (simnetPlan, contractName, manifestDir) => {
|
|
|
188
201
|
};
|
|
189
202
|
exports.buildRendezvousData = buildRendezvousData;
|
|
190
203
|
/**
|
|
191
|
-
* Retrieves the contract source code using the
|
|
192
|
-
* @param
|
|
193
|
-
* @param manifestDir The relative path to the manifest directory.
|
|
204
|
+
* Retrieves the contract source code using the deployment plan.
|
|
205
|
+
* @param deploymentPlan The parsed deployment plan.
|
|
194
206
|
* @param sutContractName The target contract name.
|
|
207
|
+
* @param manifestDir The relative path to the manifest directory.
|
|
195
208
|
* @returns The contract source code.
|
|
196
209
|
*/
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const contractInfo = (_a = simnetPlan.plan.batches
|
|
201
|
-
.flatMap((batch) => batch.transactions)
|
|
202
|
-
.find((transaction) => transaction["emulated-contract-publish"] &&
|
|
203
|
-
transaction["emulated-contract-publish"]["contract-name"] ===
|
|
204
|
-
sutContractName)) === null || _a === void 0 ? void 0 : _a["emulated-contract-publish"];
|
|
205
|
-
if (contractInfo == undefined) {
|
|
206
|
-
throw new Error(`"${sutContractName}" contract not found in Clarinet.toml.`);
|
|
207
|
-
}
|
|
208
|
-
return (0, fs_1.readFileSync)((0, path_1.join)(manifestDir, contractInfo.path), {
|
|
210
|
+
const getDeploymentPlanContractSource = (deploymentPlan, sutContractName, manifestDir) => {
|
|
211
|
+
const sutContractPath = getSutContractDeploymentPlanEmulatedPublish(deploymentPlan, sutContractName).path;
|
|
212
|
+
return (0, fs_1.readFileSync)((0, path_1.join)(manifestDir, sutContractPath), {
|
|
209
213
|
encoding: "utf-8",
|
|
210
214
|
}).toString();
|
|
211
215
|
};
|
|
212
216
|
/**
|
|
213
217
|
* Retrieves the test contract source code.
|
|
214
|
-
* @param
|
|
218
|
+
* @param deploymentPlan The parsed deployment plan.
|
|
215
219
|
* @param sutContractName The target contract name.
|
|
216
220
|
* @param manifestDir The relative path to the manifest directory.
|
|
217
221
|
* @returns The test contract source code.
|
|
218
222
|
*/
|
|
219
|
-
const getTestContractSource = (
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
.find((transaction) => transaction["emulated-contract-publish"] &&
|
|
224
|
-
transaction["emulated-contract-publish"]["contract-name"] ===
|
|
225
|
-
sutContractName)) === null || _a === void 0 ? void 0 : _a["emulated-contract-publish"];
|
|
226
|
-
const sutContractPath = contractInfo.path;
|
|
227
|
-
const extension = ".clar";
|
|
228
|
-
if (!sutContractPath.endsWith(extension)) {
|
|
223
|
+
const getTestContractSource = (deploymentPlan, sutContractName, manifestDir) => {
|
|
224
|
+
const sutContractPath = getSutContractDeploymentPlanEmulatedPublish(deploymentPlan, sutContractName).path;
|
|
225
|
+
const clarityExtension = ".clar";
|
|
226
|
+
if (!sutContractPath.endsWith(clarityExtension)) {
|
|
229
227
|
throw new Error(`Invalid contract extension for the "${sutContractName}" contract.`);
|
|
230
228
|
}
|
|
231
|
-
|
|
229
|
+
// If the sutContractPath is located under .cache/requirements/ path, search
|
|
230
|
+
// for the test contract in the classic `contracts` directory.
|
|
231
|
+
if (sutContractPath.includes(".cache")) {
|
|
232
|
+
const relativePath = sutContractPath.split(".cache/requirements/")[1];
|
|
233
|
+
const relativePathTestContract = relativePath.replace(clarityExtension, `.tests${clarityExtension}`);
|
|
234
|
+
return (0, fs_1.readFileSync)((0, path_1.join)(manifestDir, "contracts", relativePathTestContract), {
|
|
235
|
+
encoding: "utf-8",
|
|
236
|
+
}).toString();
|
|
237
|
+
}
|
|
238
|
+
// If the contract is not under the `.cache/requirements/` path, we assume it
|
|
239
|
+
// is located in a regular path specified in the manifest file. Just search
|
|
240
|
+
// for the test contract near the SUT one, following the naming
|
|
241
|
+
// convention: `<contract-name>.tests.clar`.
|
|
242
|
+
const testContractPath = sutContractPath.replace(clarityExtension, `.tests${clarityExtension}`);
|
|
232
243
|
try {
|
|
233
244
|
return (0, fs_1.readFileSync)((0, path_1.join)(manifestDir, testContractPath), {
|
|
234
245
|
encoding: "utf-8",
|
|
@@ -239,6 +250,58 @@ const getTestContractSource = (simnetPlan, sutContractName, manifestDir) => {
|
|
|
239
250
|
}
|
|
240
251
|
};
|
|
241
252
|
exports.getTestContractSource = getTestContractSource;
|
|
253
|
+
/**
|
|
254
|
+
* Retrieves the emulated contract publish data of the target contract from the
|
|
255
|
+
* deployment plan. If multiple contracts share the same name in the deployment
|
|
256
|
+
* plan, this utility will prioritize the one defined in `Clarinet.toml` as a
|
|
257
|
+
* project contract over a requirement. The prioritization is made comparing
|
|
258
|
+
* the deployment plan emulated sender with the deployer of the Clarinet project.
|
|
259
|
+
* @param deploymentPlan The parsed deployment plan.
|
|
260
|
+
* @param sutContractName The target contract name.
|
|
261
|
+
* @returns The emulated contract publish data of the SUT contract as present
|
|
262
|
+
* in the deployment plan.
|
|
263
|
+
*/
|
|
264
|
+
const getSutContractDeploymentPlanEmulatedPublish = (deploymentPlan, sutContractName) => {
|
|
265
|
+
var _a, _b;
|
|
266
|
+
// Filter all emulated contract publish transactions matching the target
|
|
267
|
+
// contract name from the deployment plan.
|
|
268
|
+
const contractPublishMatchesByName = deploymentPlan.plan.batches
|
|
269
|
+
.flatMap((batch) => batch.transactions)
|
|
270
|
+
.filter((transaction) => transaction["emulated-contract-publish"] &&
|
|
271
|
+
transaction["emulated-contract-publish"]["contract-name"] ===
|
|
272
|
+
sutContractName);
|
|
273
|
+
// If no matches are found, something went wrong.
|
|
274
|
+
if (contractPublishMatchesByName.length === 0) {
|
|
275
|
+
throw new Error(`"${sutContractName}" contract not found in Clarinet.toml.`);
|
|
276
|
+
}
|
|
277
|
+
// If multiple matches are found, search for the one deployed by the deployer
|
|
278
|
+
// defined in the `Devnet.toml` file and present in the deployment plan. This
|
|
279
|
+
// is the project contract.
|
|
280
|
+
if (contractPublishMatchesByName.length > 1) {
|
|
281
|
+
const deployer = (_a = deploymentPlan.genesis.wallets.find((wallet) => wallet.name === "deployer")) === null || _a === void 0 ? void 0 : _a.address;
|
|
282
|
+
if (!deployer) {
|
|
283
|
+
throw new Error(`Something went wrong. Deployer not found in the deployment plan.`);
|
|
284
|
+
}
|
|
285
|
+
// From the list of filtered emulated contract publish transactions with
|
|
286
|
+
// having the same name, select the one deployed by the deployer.
|
|
287
|
+
const targetContractDeploymentData = (_b = contractPublishMatchesByName.find((transaction) => transaction["emulated-contract-publish"]["emulated-sender"] ===
|
|
288
|
+
deployer)) === null || _b === void 0 ? void 0 : _b["emulated-contract-publish"];
|
|
289
|
+
// This is an edge case that can happen in practice. If the project has two
|
|
290
|
+
// requirements that share the same contract name, Rendezvous will not be
|
|
291
|
+
// able to select the one to be fuzzed. The recommendation for users would
|
|
292
|
+
// be to include the target contract in the Clarinet project.
|
|
293
|
+
if (!targetContractDeploymentData) {
|
|
294
|
+
throw new Error(`Multiple contracts named "${sutContractName}" found in the deployment plan, no one deployed by the deployer.`);
|
|
295
|
+
}
|
|
296
|
+
return targetContractDeploymentData;
|
|
297
|
+
}
|
|
298
|
+
// Only one match was found, return the path to the contract.
|
|
299
|
+
const contractNameMatch = contractPublishMatchesByName[0]["emulated-contract-publish"];
|
|
300
|
+
if (!contractNameMatch) {
|
|
301
|
+
throw new Error(`Could not locate "${sutContractName}" contract.`);
|
|
302
|
+
}
|
|
303
|
+
return contractNameMatch;
|
|
304
|
+
};
|
|
242
305
|
/**
|
|
243
306
|
* Schedules a Rendezvous between the System Under Test (`SUT`) and the test
|
|
244
307
|
* contract.
|
|
@@ -260,6 +323,31 @@ function scheduleRendezvous(targetContractSource, tests) {
|
|
|
260
323
|
(ok (map-set context function-name {called: called})))`;
|
|
261
324
|
return `${targetContractSource}\n\n${context}\n\n${tests}`;
|
|
262
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Maps the simnet accounts to their sBTC balances. The function tries to call
|
|
328
|
+
* the `get-balance` function of the `sbtc-token` contract for each address. If
|
|
329
|
+
* the call fails, it returns a balance of 0 for that address. The call fails
|
|
330
|
+
* if the user is not working with sBTC.
|
|
331
|
+
* @param simnet The simnet instance.
|
|
332
|
+
* @returns A map of addresses to their sBTC balances.
|
|
333
|
+
*/
|
|
334
|
+
const getSbtcBalancesFromSimnet = (simnet) => new Map([...simnet.getAccounts().values()].map((address) => {
|
|
335
|
+
try {
|
|
336
|
+
const { result: getBalanceResult } = simnet.callReadOnlyFn("SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-token", "get-balance", [transactions_1.Cl.principal(address)], address);
|
|
337
|
+
// If the previous read-only call works, the user is working with
|
|
338
|
+
// sBTC. This means we can proceed with restoring sBTC balances.
|
|
339
|
+
const sbtcBalanceJSON = (0, transactions_1.cvToJSON)(getBalanceResult);
|
|
340
|
+
// The `get-balance` function returns a response containing the uint
|
|
341
|
+
// balance of the address. In the JSON representation, the balance is
|
|
342
|
+
// represented as a string. We need to parse it to an integer.
|
|
343
|
+
const sbtcBalance = parseInt(sbtcBalanceJSON.value.value, 10);
|
|
344
|
+
return [address, sbtcBalance];
|
|
345
|
+
}
|
|
346
|
+
catch (e) {
|
|
347
|
+
return [address, 0];
|
|
348
|
+
}
|
|
349
|
+
}));
|
|
350
|
+
exports.getSbtcBalancesFromSimnet = getSbtcBalancesFromSimnet;
|
|
263
351
|
/**
|
|
264
352
|
* Utility function that restores the test wallets' initial sBTC balances in
|
|
265
353
|
* the re-initialized first-class citizenship simnet.
|
package/dist/package.json
CHANGED