@ton/sandbox 0.33.0-dev.20250613115101.21c0ffa → 0.33.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/CHANGELOG.md
CHANGED
|
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## [0.33.0] - 2025-06-16
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
11
|
|
|
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
18
18
|
|
|
19
19
|
- Fixed `now` not updating when running transaction through `blockchain.sendMessageIter`
|
|
20
20
|
- Fixed `is` methods type and code mismatch
|
|
21
|
+
- Fixed `Blockchain.snapshot()` returning mutable references to internal blockchain state
|
|
21
22
|
|
|
22
23
|
## [0.32.2] - 2025-06-10
|
|
23
24
|
|
|
@@ -16,6 +16,7 @@ exports.SmartContract = exports.EmulationError = exports.TimeError = exports.Get
|
|
|
16
16
|
const core_1 = require("@ton/core");
|
|
17
17
|
const ec_1 = require("../utils/ec");
|
|
18
18
|
const selector_1 = require("../utils/selector");
|
|
19
|
+
const deepcopy_1 = require("../utils/deepcopy");
|
|
19
20
|
function createShardAccount(args) {
|
|
20
21
|
let wc = args.workchain ?? 0;
|
|
21
22
|
let address = args.address ?? (0, core_1.contractAddress)(wc, { code: args.code, data: args.data });
|
|
@@ -137,18 +138,18 @@ class SmartContract {
|
|
|
137
138
|
this.blockchain = blockchain;
|
|
138
139
|
}
|
|
139
140
|
snapshot() {
|
|
140
|
-
return {
|
|
141
|
+
return (0, deepcopy_1.deepcopy)({
|
|
141
142
|
address: this.address,
|
|
142
143
|
account: this.account,
|
|
143
144
|
lastTxTime: __classPrivateFieldGet(this, _SmartContract_lastTxTime, "f"),
|
|
144
|
-
verbosity: __classPrivateFieldGet(this, _SmartContract_verbosity, "f")
|
|
145
|
-
};
|
|
145
|
+
verbosity: __classPrivateFieldGet(this, _SmartContract_verbosity, "f"),
|
|
146
|
+
});
|
|
146
147
|
}
|
|
147
148
|
loadFrom(snapshot) {
|
|
148
149
|
if (snapshot.address !== this.address) {
|
|
149
150
|
throw new Error('Wrong snapshot address');
|
|
150
151
|
}
|
|
151
|
-
this.account = snapshot.account;
|
|
152
|
+
this.account = (0, deepcopy_1.deepcopy)(snapshot.account);
|
|
152
153
|
__classPrivateFieldSet(this, _SmartContract_lastTxTime, snapshot.lastTxTime, "f");
|
|
153
154
|
__classPrivateFieldSet(this, _SmartContract_verbosity, snapshot.verbosity === undefined ? undefined : { ...snapshot.verbosity }, "f");
|
|
154
155
|
}
|
package/dist/utils/deepcopy.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import { Address, Cell, Dictionary, DictionaryKeyTypes } from '@ton/core';
|
|
2
3
|
type Primitive = undefined | null | boolean | number | string | bigint | symbol;
|
|
3
|
-
type DeepCopiable = Primitive | Buffer | DeepCopiable[] | {
|
|
4
|
-
[key: string | number | symbol]: DeepCopiable;
|
|
4
|
+
type DeepCopiable = Primitive | Buffer | Address | Cell | Map<DeepCopiable, DeepCopiable> | DeepCopiable[] | Partial<{
|
|
5
|
+
[key: Partial<string | number | symbol>]: DeepCopiable;
|
|
6
|
+
}> | Dictionary<DictionaryKeyTypes, DeepCopiable>;
|
|
7
|
+
type InterfaceToType<T> = {
|
|
8
|
+
[key in keyof T]: InterfaceToType<T[key]>;
|
|
5
9
|
};
|
|
6
|
-
|
|
10
|
+
type IsCopiable<T> = T extends DeepCopiable ? true : InterfaceToType<T> extends DeepCopiable ? true : false;
|
|
11
|
+
export declare function deepcopy<T extends IsCopiable<T> extends true ? unknown : DeepCopiable>(obj: T): T;
|
|
7
12
|
export {};
|
package/dist/utils/deepcopy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deepcopy = void 0;
|
|
4
|
+
const core_1 = require("@ton/core");
|
|
4
5
|
function deepcopyBuffer(buffer) {
|
|
5
6
|
if (!buffer)
|
|
6
7
|
return;
|
|
@@ -8,16 +9,41 @@ function deepcopyBuffer(buffer) {
|
|
|
8
9
|
buffer.copy(newBuffer);
|
|
9
10
|
return newBuffer;
|
|
10
11
|
}
|
|
12
|
+
function deepcopyDict(dict) {
|
|
13
|
+
const rawDict = dict;
|
|
14
|
+
// TODO: make pr to @ton/core with key, value and map fields
|
|
15
|
+
// @ts-expect-error Accessing private constructor for cloning purposes
|
|
16
|
+
return new core_1.Dictionary(deepcopy(rawDict._map), rawDict._key, rawDict._value);
|
|
17
|
+
}
|
|
11
18
|
function deepcopy(obj) {
|
|
12
19
|
if (obj === null || obj === undefined)
|
|
13
20
|
return obj;
|
|
14
21
|
if (Buffer.isBuffer(obj)) {
|
|
15
22
|
return deepcopyBuffer(obj);
|
|
16
23
|
}
|
|
24
|
+
if (obj instanceof (core_1.Dictionary)) {
|
|
25
|
+
return deepcopyDict(obj);
|
|
26
|
+
}
|
|
27
|
+
if (core_1.Address.isAddress(obj)) {
|
|
28
|
+
return new core_1.Address(obj.workChain, deepcopyBuffer(obj.hash));
|
|
29
|
+
}
|
|
17
30
|
if (Array.isArray(obj)) {
|
|
18
31
|
return obj.map((item) => deepcopy(item));
|
|
19
32
|
}
|
|
33
|
+
if (obj instanceof core_1.Cell) {
|
|
34
|
+
return obj;
|
|
35
|
+
}
|
|
36
|
+
if (obj instanceof Map) {
|
|
37
|
+
const newMap = new Map();
|
|
38
|
+
for (const [key, value] of obj) {
|
|
39
|
+
newMap.set(deepcopy(key), deepcopy(value));
|
|
40
|
+
}
|
|
41
|
+
return newMap;
|
|
42
|
+
}
|
|
20
43
|
if (typeof obj === 'object') {
|
|
44
|
+
if (obj.constructor && obj.constructor.name !== 'Object') {
|
|
45
|
+
throw new Error(`Unknown class ${obj.constructor.name} passed to deepcopy`);
|
|
46
|
+
}
|
|
21
47
|
const result = {};
|
|
22
48
|
for (const [key, value] of Object.entries(obj)) {
|
|
23
49
|
result[key] = deepcopy(value);
|