@stacks/rendezvous 0.5.0 → 0.6.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/dist/citizen.js +104 -2
- package/dist/package.json +3 -3
- package/package.json +3 -3
package/dist/citizen.js
CHANGED
|
@@ -44,13 +44,25 @@ const issueFirstClassCitizenship = (manifestDir, manifestPath, remoteDataSetting
|
|
|
44
44
|
}));
|
|
45
45
|
const sortedContractsByEpoch = (0, exports.groupContractsByEpochFromSimnetPlan)(simnetPlan);
|
|
46
46
|
const simnetAddresses = [...simnet.getAccounts().values()];
|
|
47
|
-
const
|
|
47
|
+
const stxBalancesMap = new Map(simnetAddresses.map((address) => {
|
|
48
48
|
const balanceHex = simnet.runSnippet(`(stx-get-balance '${address})`);
|
|
49
49
|
return [address, (0, transactions_1.cvToValue)((0, transactions_1.hexToCV)(balanceHex))];
|
|
50
50
|
}));
|
|
51
|
+
const sbtcBalancesMap = new Map(simnetAddresses.map((address) => {
|
|
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
|
+
}));
|
|
51
63
|
yield simnet.initEmptySession(remoteDataSettings);
|
|
52
64
|
simnetAddresses.forEach((address) => {
|
|
53
|
-
simnet.mintSTX(address,
|
|
65
|
+
simnet.mintSTX(address, stxBalancesMap.get(address));
|
|
54
66
|
});
|
|
55
67
|
// Combine the target contract with its tests into a single contract. The
|
|
56
68
|
// resulting contract will replace the target contract in the simnet.
|
|
@@ -63,6 +75,14 @@ const issueFirstClassCitizenship = (manifestDir, manifestPath, remoteDataSetting
|
|
|
63
75
|
]));
|
|
64
76
|
// Deploy the contracts to the simnet in the correct order.
|
|
65
77
|
yield deployContracts(simnet, sortedContractsByEpoch, (name, props) => (0, exports.getContractSource)([sutContractName], rendezvousSources, name, props, manifestDir));
|
|
78
|
+
// Filter out addresses with zero balance. They do not need to be restored.
|
|
79
|
+
const sbtcBalancesToRestore = new Map([...sbtcBalancesMap.entries()].filter(([_, balance]) => balance !== 0));
|
|
80
|
+
// After all the contracts and requirements are deployed, if the test wallets
|
|
81
|
+
// had sBTC balances previously, restore them. If no test wallet previously
|
|
82
|
+
// owned sBTC, skip this step.
|
|
83
|
+
if ([...sbtcBalancesToRestore.keys()].length > 0) {
|
|
84
|
+
restoreSbtcBalances(simnet, sbtcBalancesToRestore);
|
|
85
|
+
}
|
|
66
86
|
return simnet;
|
|
67
87
|
});
|
|
68
88
|
exports.issueFirstClassCitizenship = issueFirstClassCitizenship;
|
|
@@ -240,3 +260,85 @@ function scheduleRendezvous(targetContractSource, tests) {
|
|
|
240
260
|
(ok (map-set context function-name {called: called})))`;
|
|
241
261
|
return `${targetContractSource}\n\n${context}\n\n${tests}`;
|
|
242
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* Utility function that restores the test wallets' initial sBTC balances in
|
|
265
|
+
* the re-initialized first-class citizenship simnet.
|
|
266
|
+
*
|
|
267
|
+
* @param simnet The simnet instance.
|
|
268
|
+
* @param sbtcBalancesMap A map containing the test wallets' balances to be
|
|
269
|
+
* restored.
|
|
270
|
+
*/
|
|
271
|
+
const restoreSbtcBalances = (simnet, sbtcBalancesMap) => {
|
|
272
|
+
// For each address present in the balances map, restore the balance.
|
|
273
|
+
[...sbtcBalancesMap.entries()]
|
|
274
|
+
// Re-assure the map does not contain nil balances.
|
|
275
|
+
.filter(([_, balance]) => balance !== 0)
|
|
276
|
+
.forEach(([address, balance]) => {
|
|
277
|
+
// To deposit sBTC, one needs a txId and a sweep txId. A deposit transaction
|
|
278
|
+
// must have a unique txId and sweep txId.
|
|
279
|
+
const txId = getUniqueHex();
|
|
280
|
+
const sweepTxId = getUniqueHex();
|
|
281
|
+
mintSbtc(simnet, balance, address, txId, sweepTxId);
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Utility function to deposit an amount of sBTC to a Stacks address.
|
|
286
|
+
*
|
|
287
|
+
* @param simnet The simnet instance.
|
|
288
|
+
* @param amountSats The amount to mint in sats.
|
|
289
|
+
* @param recipient The Stacks address to mint sBTC to.
|
|
290
|
+
* @param txId A unique hex to use for the deposit.
|
|
291
|
+
* @param sweepTxId A unique hex to use for the deposit.
|
|
292
|
+
*/
|
|
293
|
+
const mintSbtc = (simnet, amountSats, recipient, txId, sweepTxId) => {
|
|
294
|
+
// Calling `get-burn-header` only works for past block heights. We mine one
|
|
295
|
+
// empty Stacks block if the initial height is 0.
|
|
296
|
+
if (simnet.blockHeight === 0) {
|
|
297
|
+
simnet.mineEmptyBlock();
|
|
298
|
+
}
|
|
299
|
+
const previousStacksHeight = simnet.blockHeight - 1;
|
|
300
|
+
const burnHash = simnet.callReadOnlyFn("SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-deposit", "get-burn-header", [
|
|
301
|
+
// (height uint)
|
|
302
|
+
transactions_1.Cl.uint(previousStacksHeight),
|
|
303
|
+
], simnet.deployer).result;
|
|
304
|
+
if (burnHash === null || burnHash.type === transactions_1.ClarityType.OptionalNone) {
|
|
305
|
+
throw new Error("Something went wrong trying to retrieve the burn header.");
|
|
306
|
+
}
|
|
307
|
+
const completeDepositTx = (0, transactions_1.cvToJSON)(simnet.callPublicFn("SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4.sbtc-deposit", "complete-deposit-wrapper", [
|
|
308
|
+
// (txid (buff 32))
|
|
309
|
+
transactions_1.Cl.bufferFromHex(txId),
|
|
310
|
+
// (vout-index uint)
|
|
311
|
+
transactions_1.Cl.uint(1),
|
|
312
|
+
// (amount uint)
|
|
313
|
+
transactions_1.Cl.uint(amountSats),
|
|
314
|
+
// (recipient principal)
|
|
315
|
+
transactions_1.Cl.principal(recipient),
|
|
316
|
+
// (burn-hash (buff 32))
|
|
317
|
+
burnHash.value,
|
|
318
|
+
// (burn-height uint)
|
|
319
|
+
transactions_1.Cl.uint(previousStacksHeight),
|
|
320
|
+
// (sweep-txid (buff 32))
|
|
321
|
+
transactions_1.Cl.bufferFromHex(sweepTxId),
|
|
322
|
+
], "SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4").result);
|
|
323
|
+
// If the deposit transaction fails, an unexpected outcome can happen. Throw
|
|
324
|
+
// an error if the transaction is not successful.
|
|
325
|
+
if (!completeDepositTx.success) {
|
|
326
|
+
throw new Error("Something went wrong trying to restore sBTC balances.");
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
/**
|
|
330
|
+
* Utility function that generates a random, unique hex to be used as txId in
|
|
331
|
+
* `mintSbtc`.
|
|
332
|
+
*
|
|
333
|
+
* @returns A random hex string.
|
|
334
|
+
*/
|
|
335
|
+
const getUniqueHex = () => {
|
|
336
|
+
let hex;
|
|
337
|
+
// Generate a 32-byte (64 character) random hex string.
|
|
338
|
+
const bytes = new Uint8Array(32);
|
|
339
|
+
crypto.getRandomValues(bytes);
|
|
340
|
+
hex = Array.from(bytes)
|
|
341
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
342
|
+
.join("");
|
|
343
|
+
return hex;
|
|
344
|
+
};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacks/rendezvous",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Meet your contract's vulnerabilities head-on.",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"url": "https://github.com/stacks-network/rendezvous.git"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@hirosystems/clarinet-sdk": "2.
|
|
33
|
+
"@hirosystems/clarinet-sdk": "2.15.2",
|
|
34
34
|
"@stacks/transactions": "^6.16.1",
|
|
35
35
|
"ansicolor": "^2.0.3",
|
|
36
36
|
"fast-check": "^3.20.0",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"yaml": "^2.6.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@hirosystems/clarinet-sdk-wasm": "2.
|
|
41
|
+
"@hirosystems/clarinet-sdk-wasm": "2.15.2",
|
|
42
42
|
"@types/jest": "^29.5.12",
|
|
43
43
|
"jest": "^29.7.0",
|
|
44
44
|
"ts-jest": "^29.2.5",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacks/rendezvous",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Meet your contract's vulnerabilities head-on.",
|
|
5
5
|
"main": "app.js",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"url": "https://github.com/stacks-network/rendezvous.git"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@hirosystems/clarinet-sdk": "2.
|
|
33
|
+
"@hirosystems/clarinet-sdk": "2.15.2",
|
|
34
34
|
"@stacks/transactions": "^6.16.1",
|
|
35
35
|
"ansicolor": "^2.0.3",
|
|
36
36
|
"fast-check": "^3.20.0",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"yaml": "^2.6.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@hirosystems/clarinet-sdk-wasm": "2.
|
|
41
|
+
"@hirosystems/clarinet-sdk-wasm": "2.15.2",
|
|
42
42
|
"@types/jest": "^29.5.12",
|
|
43
43
|
"jest": "^29.7.0",
|
|
44
44
|
"ts-jest": "^29.2.5",
|