@dfinity/pic 0.12.0-b0
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/README.md +73 -0
- package/dist/error.d.ts +21 -0
- package/dist/error.js +55 -0
- package/dist/error.js.map +1 -0
- package/dist/http2-client.d.ts +27 -0
- package/dist/http2-client.js +137 -0
- package/dist/http2-client.js.map +1 -0
- package/dist/identity.d.ts +74 -0
- package/dist/identity.js +94 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/management-canister.d.ts +45 -0
- package/dist/management-canister.js +71 -0
- package/dist/management-canister.js.map +1 -0
- package/dist/pocket-ic-actor.d.ts +85 -0
- package/dist/pocket-ic-actor.js +58 -0
- package/dist/pocket-ic-actor.js.map +1 -0
- package/dist/pocket-ic-client-types.d.ts +372 -0
- package/dist/pocket-ic-client-types.js +395 -0
- package/dist/pocket-ic-client-types.js.map +1 -0
- package/dist/pocket-ic-client.d.ts +31 -0
- package/dist/pocket-ic-client.js +152 -0
- package/dist/pocket-ic-client.js.map +1 -0
- package/dist/pocket-ic-deferred-actor.d.ts +67 -0
- package/dist/pocket-ic-deferred-actor.js +44 -0
- package/dist/pocket-ic-deferred-actor.js.map +1 -0
- package/dist/pocket-ic-server-types.d.ts +13 -0
- package/dist/pocket-ic-server-types.js +3 -0
- package/dist/pocket-ic-server-types.js.map +1 -0
- package/dist/pocket-ic-server.d.ts +53 -0
- package/dist/pocket-ic-server.js +126 -0
- package/dist/pocket-ic-server.js.map +1 -0
- package/dist/pocket-ic-types.d.ts +679 -0
- package/dist/pocket-ic-types.js +72 -0
- package/dist/pocket-ic-types.js.map +1 -0
- package/dist/pocket-ic.d.ts +972 -0
- package/dist/pocket-ic.js +1248 -0
- package/dist/pocket-ic.js.map +1 -0
- package/dist/util/candid.d.ts +3 -0
- package/dist/util/candid.js +21 -0
- package/dist/util/candid.js.map +1 -0
- package/dist/util/encoding.d.ts +6 -0
- package/dist/util/encoding.js +24 -0
- package/dist/util/encoding.js.map +1 -0
- package/dist/util/fs.d.ts +4 -0
- package/dist/util/fs.js +28 -0
- package/dist/util/fs.js.map +1 -0
- package/dist/util/index.d.ts +6 -0
- package/dist/util/index.js +23 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/is-nil.d.ts +2 -0
- package/dist/util/is-nil.js +11 -0
- package/dist/util/is-nil.js.map +1 -0
- package/dist/util/os.d.ts +4 -0
- package/dist/util/os.js +19 -0
- package/dist/util/os.js.map +1 -0
- package/dist/util/poll.d.ts +5 -0
- package/dist/util/poll.js +23 -0
- package/dist/util/poll.js.map +1 -0
- package/package.json +40 -0
- package/postinstall.mjs +25 -0
|
@@ -0,0 +1,1248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PocketIc = void 0;
|
|
4
|
+
const principal_1 = require("@dfinity/principal");
|
|
5
|
+
const util_1 = require("./util");
|
|
6
|
+
const pocket_ic_client_1 = require("./pocket-ic-client");
|
|
7
|
+
const pocket_ic_actor_1 = require("./pocket-ic-actor");
|
|
8
|
+
const pocket_ic_types_1 = require("./pocket-ic-types");
|
|
9
|
+
const management_canister_1 = require("./management-canister");
|
|
10
|
+
const pocket_ic_deferred_actor_1 = require("./pocket-ic-deferred-actor");
|
|
11
|
+
/**
|
|
12
|
+
* This class represents the main PocketIC client.
|
|
13
|
+
* It is responsible for interacting with the PocketIC server via the REST API.
|
|
14
|
+
* See {@link PocketIcServer} for details on the server to use with this client.
|
|
15
|
+
*
|
|
16
|
+
* @category API
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* The easist way to use PocketIC is to use {@link setupCanister} convenience method:
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
22
|
+
* import { _SERVICE, idlFactory } from '../declarations';
|
|
23
|
+
*
|
|
24
|
+
* const wasmPath = resolve('..', '..', 'canister.wasm');
|
|
25
|
+
*
|
|
26
|
+
* const picServer = await PocketIcServer.create();
|
|
27
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
28
|
+
*
|
|
29
|
+
* const fixture = await pic.setupCanister<_SERVICE>({ idlFactory, wasmPath });
|
|
30
|
+
* const { actor } = fixture;
|
|
31
|
+
*
|
|
32
|
+
* // perform tests...
|
|
33
|
+
*
|
|
34
|
+
* await pic.tearDown();
|
|
35
|
+
* await picServer.stop();
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* If more control is needed, then the {@link createCanister}, {@link installCode} and
|
|
39
|
+
* {@link createActor} methods can be used directly:
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
42
|
+
* import { _SERVICE, idlFactory } from '../declarations';
|
|
43
|
+
*
|
|
44
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
45
|
+
*
|
|
46
|
+
* const picServer = await PocketIcServer.create();
|
|
47
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
48
|
+
*
|
|
49
|
+
* const canisterId = await pic.createCanister();
|
|
50
|
+
* await pic.installCode({ canisterId, wasm });
|
|
51
|
+
* const actor = pic.createActor<_SERVICE>({ idlFactory, canisterId });
|
|
52
|
+
*
|
|
53
|
+
* // perform tests...
|
|
54
|
+
*
|
|
55
|
+
* await pic.tearDown();
|
|
56
|
+
* await picServer.stop();
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
class PocketIc {
|
|
60
|
+
client;
|
|
61
|
+
constructor(client) {
|
|
62
|
+
this.client = client;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Creates a PocketIC instance.
|
|
66
|
+
*
|
|
67
|
+
* @param url The URL of an existing PocketIC server to connect to.
|
|
68
|
+
* @param options Options for creating the PocketIC instance see {@link CreateInstanceOptions}.
|
|
69
|
+
* @returns A new PocketIC instance.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
74
|
+
*
|
|
75
|
+
* const picServer = await PocketIcServer.create();
|
|
76
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
77
|
+
*
|
|
78
|
+
* const fixture = await pic.setupCanister<_SERVICE>({ idlFactory, wasmPath });
|
|
79
|
+
* const { actor } = fixture;
|
|
80
|
+
*
|
|
81
|
+
* await pic.tearDown();
|
|
82
|
+
* await picServer.stop();
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
static async create(url, options) {
|
|
86
|
+
const client = await pocket_ic_client_1.PocketIcClient.create(url, options);
|
|
87
|
+
return new PocketIc(client);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A convenience method that creates a new canister,
|
|
91
|
+
* installs the given WASM module to it and returns a typesafe {@link Actor}
|
|
92
|
+
* that implements the Candid interface of the canister.
|
|
93
|
+
* To just create a canister, see {@link createCanister}.
|
|
94
|
+
* To just install code to an existing canister, see {@link installCode}.
|
|
95
|
+
* To just create an Actor for an existing canister, see {@link createActor}.
|
|
96
|
+
*
|
|
97
|
+
* @param options Options for setting up the canister, see {@link SetupCanisterOptions}.
|
|
98
|
+
* @returns The {@link Actor} instance.
|
|
99
|
+
*
|
|
100
|
+
* @see [Candid](https://internetcomputer.org/docs/current/references/candid-ref)
|
|
101
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
106
|
+
* import { _SERVICE, idlFactory } from '../declarations';
|
|
107
|
+
*
|
|
108
|
+
* const wasmPath = resolve('..', '..', 'canister.wasm');
|
|
109
|
+
*
|
|
110
|
+
* const picServer = await PocketIcServer.create();
|
|
111
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
112
|
+
*
|
|
113
|
+
* const fixture = await pic.setupCanister<_SERVICE>({ idlFactory, wasmPath });
|
|
114
|
+
* const { actor } = fixture;
|
|
115
|
+
*
|
|
116
|
+
* await pic.tearDown();
|
|
117
|
+
* await picServer.stop();
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
async setupCanister({ sender, arg, wasm, idlFactory, computeAllocation, controllers, cycles, freezingThreshold, memoryAllocation, targetCanisterId, targetSubnetId, reservedCyclesLimit, }) {
|
|
121
|
+
const canisterId = await this.createCanister({
|
|
122
|
+
computeAllocation,
|
|
123
|
+
controllers,
|
|
124
|
+
cycles,
|
|
125
|
+
freezingThreshold,
|
|
126
|
+
memoryAllocation,
|
|
127
|
+
reservedCyclesLimit,
|
|
128
|
+
targetCanisterId,
|
|
129
|
+
targetSubnetId,
|
|
130
|
+
sender,
|
|
131
|
+
});
|
|
132
|
+
await this.installCode({ canisterId, wasm, arg, sender, targetSubnetId });
|
|
133
|
+
const actor = this.createActor(idlFactory, canisterId);
|
|
134
|
+
return { actor, canisterId };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Creates a new canister.
|
|
138
|
+
* For a more convenient way of creating a PocketIC instance,
|
|
139
|
+
* creating a canister and installing code, see {@link setupCanister}.
|
|
140
|
+
*
|
|
141
|
+
* @param options Options for creating the canister, see {@link CreateCanisterOptions}.
|
|
142
|
+
* @returns The Principal of the newly created canister.
|
|
143
|
+
*
|
|
144
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
149
|
+
*
|
|
150
|
+
* const picServer = await PocketIcServer.create();
|
|
151
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
152
|
+
*
|
|
153
|
+
* const canisterId = await pic.createCanister();
|
|
154
|
+
*
|
|
155
|
+
* await pic.tearDown();
|
|
156
|
+
* await picServer.stop();
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
async createCanister({ sender = principal_1.Principal.anonymous(), cycles = 1000000000000000000n, controllers, computeAllocation, freezingThreshold, memoryAllocation, reservedCyclesLimit, targetCanisterId, targetSubnetId, } = {}) {
|
|
160
|
+
const payload = (0, management_canister_1.encodeCreateCanisterRequest)({
|
|
161
|
+
settings: [
|
|
162
|
+
{
|
|
163
|
+
controllers: (0, util_1.optional)(controllers),
|
|
164
|
+
compute_allocation: (0, util_1.optional)(computeAllocation),
|
|
165
|
+
memory_allocation: (0, util_1.optional)(memoryAllocation),
|
|
166
|
+
freezing_threshold: (0, util_1.optional)(freezingThreshold),
|
|
167
|
+
reserved_cycles_limit: (0, util_1.optional)(reservedCyclesLimit),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
amount: [cycles],
|
|
171
|
+
specified_id: (0, util_1.optional)(targetCanisterId),
|
|
172
|
+
});
|
|
173
|
+
const res = await this.client.updateCall({
|
|
174
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
175
|
+
sender,
|
|
176
|
+
method: 'provisional_create_canister_with_cycles',
|
|
177
|
+
payload,
|
|
178
|
+
effectivePrincipal: targetSubnetId
|
|
179
|
+
? {
|
|
180
|
+
subnetId: targetSubnetId,
|
|
181
|
+
}
|
|
182
|
+
: undefined,
|
|
183
|
+
});
|
|
184
|
+
return (0, management_canister_1.decodeCreateCanisterResponse)(res.body).canister_id;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Starts the given canister.
|
|
188
|
+
*
|
|
189
|
+
* @param options Options for starting the canister, see {@link StartCanisterOptions}.
|
|
190
|
+
*
|
|
191
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* import { Principal } from '@dfinity/principal';
|
|
196
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
197
|
+
*
|
|
198
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
199
|
+
*
|
|
200
|
+
* const picServer = await PocketIcServer.create();
|
|
201
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
202
|
+
*
|
|
203
|
+
* await pic.startCanister({ canisterId });
|
|
204
|
+
*
|
|
205
|
+
* await pic.tearDown();
|
|
206
|
+
* await picServer.stop();
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
async startCanister({ canisterId, sender = principal_1.Principal.anonymous(), targetSubnetId, }) {
|
|
210
|
+
const payload = (0, management_canister_1.encodeStartCanisterRequest)({
|
|
211
|
+
canister_id: canisterId,
|
|
212
|
+
});
|
|
213
|
+
await this.client.updateCall({
|
|
214
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
215
|
+
sender,
|
|
216
|
+
method: 'start_canister',
|
|
217
|
+
payload,
|
|
218
|
+
effectivePrincipal: targetSubnetId
|
|
219
|
+
? {
|
|
220
|
+
subnetId: targetSubnetId,
|
|
221
|
+
}
|
|
222
|
+
: undefined,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Stops the given canister.
|
|
227
|
+
*
|
|
228
|
+
* @param options Options for stopping the canister, see {@link StopCanisterOptions}.
|
|
229
|
+
*
|
|
230
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```ts
|
|
234
|
+
* import { Principal } from '@dfinity/principal';
|
|
235
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
236
|
+
*
|
|
237
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
238
|
+
*
|
|
239
|
+
* const picServer = await PocketIcServer.create();
|
|
240
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
241
|
+
*
|
|
242
|
+
* await pic.stopCanister({ canisterId });
|
|
243
|
+
*
|
|
244
|
+
* await pic.tearDown();
|
|
245
|
+
* await picServer.stop();
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
async stopCanister({ canisterId, sender = principal_1.Principal.anonymous(), targetSubnetId, }) {
|
|
249
|
+
const payload = (0, management_canister_1.encodeStartCanisterRequest)({
|
|
250
|
+
canister_id: canisterId,
|
|
251
|
+
});
|
|
252
|
+
await this.client.updateCall({
|
|
253
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
254
|
+
sender,
|
|
255
|
+
method: 'stop_canister',
|
|
256
|
+
payload,
|
|
257
|
+
effectivePrincipal: targetSubnetId
|
|
258
|
+
? {
|
|
259
|
+
subnetId: targetSubnetId,
|
|
260
|
+
}
|
|
261
|
+
: undefined,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Installs the given WASM module to the provided canister.
|
|
266
|
+
* To create a canister to install code to, see {@link createCanister}.
|
|
267
|
+
* For a more convenient way of creating a PocketIC instance,
|
|
268
|
+
* creating a canister and installing code, see {@link setupCanister}.
|
|
269
|
+
*
|
|
270
|
+
* @param options Options for installing the code, see {@link InstallCodeOptions}.
|
|
271
|
+
*
|
|
272
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```ts
|
|
276
|
+
* import { Principal } from '@dfinity/principal';
|
|
277
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
278
|
+
* import { resolve } from 'node:path';
|
|
279
|
+
*
|
|
280
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
281
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
282
|
+
*
|
|
283
|
+
* const picServer = await PocketIcServer.create();
|
|
284
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
285
|
+
*
|
|
286
|
+
* await pic.installCode({ canisterId, wasm });
|
|
287
|
+
*
|
|
288
|
+
* await pic.tearDown();
|
|
289
|
+
* await picServer.stop();
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
async installCode({ arg = new Uint8Array(), sender = principal_1.Principal.anonymous(), canisterId, wasm, targetSubnetId, }) {
|
|
293
|
+
if (typeof wasm === 'string') {
|
|
294
|
+
wasm = await (0, util_1.readFileAsBytes)(wasm);
|
|
295
|
+
}
|
|
296
|
+
const payload = (0, management_canister_1.encodeInstallCodeRequest)({
|
|
297
|
+
arg: new Uint8Array(arg),
|
|
298
|
+
canister_id: canisterId,
|
|
299
|
+
mode: {
|
|
300
|
+
install: null,
|
|
301
|
+
},
|
|
302
|
+
wasm_module: new Uint8Array(wasm),
|
|
303
|
+
});
|
|
304
|
+
await this.client.updateCall({
|
|
305
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
306
|
+
sender,
|
|
307
|
+
method: 'install_code',
|
|
308
|
+
payload,
|
|
309
|
+
effectivePrincipal: targetSubnetId
|
|
310
|
+
? {
|
|
311
|
+
subnetId: targetSubnetId,
|
|
312
|
+
}
|
|
313
|
+
: undefined,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Reinstalls the given WASM module to the provided canister.
|
|
318
|
+
* This will reset both the canister's heap and its stable memory.
|
|
319
|
+
* To create a canister to upgrade, see {@link createCanister}.
|
|
320
|
+
* To install the initial WASM module to a new canister, see {@link installCode}.
|
|
321
|
+
*
|
|
322
|
+
* @param options Options for reinstalling the code, see {@link ReinstallCodeOptions}.
|
|
323
|
+
*
|
|
324
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
325
|
+
*
|
|
326
|
+
* @example
|
|
327
|
+
* ```ts
|
|
328
|
+
* import { Principal } from '@dfinity/principal';
|
|
329
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
330
|
+
* import { resolve } from 'node:path';
|
|
331
|
+
*
|
|
332
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
333
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
334
|
+
*
|
|
335
|
+
* const picServer = await PocketIcServer.create();
|
|
336
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
337
|
+
*
|
|
338
|
+
* await pic.reinstallCode({ canisterId, wasm });
|
|
339
|
+
*
|
|
340
|
+
* await pic.tearDown();
|
|
341
|
+
* await picServer.stop();
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
async reinstallCode({ sender = principal_1.Principal.anonymous(), arg = new Uint8Array(), canisterId, wasm, }) {
|
|
345
|
+
if (typeof wasm === 'string') {
|
|
346
|
+
wasm = await (0, util_1.readFileAsBytes)(wasm);
|
|
347
|
+
}
|
|
348
|
+
const payload = (0, management_canister_1.encodeInstallCodeRequest)({
|
|
349
|
+
arg: new Uint8Array(arg),
|
|
350
|
+
canister_id: canisterId,
|
|
351
|
+
mode: {
|
|
352
|
+
reinstall: null,
|
|
353
|
+
},
|
|
354
|
+
wasm_module: new Uint8Array(wasm),
|
|
355
|
+
});
|
|
356
|
+
await this.client.updateCall({
|
|
357
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
358
|
+
sender,
|
|
359
|
+
method: 'install_code',
|
|
360
|
+
payload,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Upgrades the given canister with the given WASM module.
|
|
365
|
+
* This will reset the canister's heap, but preserve stable memory.
|
|
366
|
+
* To create a canister to upgrade to, see {@link createCanister}.
|
|
367
|
+
* To install the initial WASM module to a new canister, see {@link installCode}.
|
|
368
|
+
*
|
|
369
|
+
* @param options Options for upgrading the canister, see {@link UpgradeCanisterOptions}.
|
|
370
|
+
*
|
|
371
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```ts
|
|
375
|
+
* import { Principal } from '@dfinity/principal';
|
|
376
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
377
|
+
* import { resolve } from 'node:path';
|
|
378
|
+
*
|
|
379
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
380
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
381
|
+
*
|
|
382
|
+
* const picServer = await PocketIcServer.create();
|
|
383
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
384
|
+
*
|
|
385
|
+
* await pic.upgradeCanister({ canisterId, wasm });
|
|
386
|
+
*
|
|
387
|
+
* await pic.tearDown();
|
|
388
|
+
* await picServer.stop();
|
|
389
|
+
* ```
|
|
390
|
+
*/
|
|
391
|
+
async upgradeCanister({ sender = principal_1.Principal.anonymous(), arg = new Uint8Array(), canisterId, wasm, }) {
|
|
392
|
+
if (typeof wasm === 'string') {
|
|
393
|
+
wasm = await (0, util_1.readFileAsBytes)(wasm);
|
|
394
|
+
}
|
|
395
|
+
const payload = (0, management_canister_1.encodeInstallCodeRequest)({
|
|
396
|
+
arg: new Uint8Array(arg),
|
|
397
|
+
canister_id: canisterId,
|
|
398
|
+
mode: {
|
|
399
|
+
upgrade: null,
|
|
400
|
+
},
|
|
401
|
+
wasm_module: new Uint8Array(wasm),
|
|
402
|
+
});
|
|
403
|
+
await this.client.updateCall({
|
|
404
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
405
|
+
sender,
|
|
406
|
+
method: 'install_code',
|
|
407
|
+
payload,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Updates the settings of the given canister.
|
|
412
|
+
*
|
|
413
|
+
* @param options Options for updating the canister settings, see {@link UpdateCanisterSettingsOptions}.
|
|
414
|
+
*
|
|
415
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* ```ts
|
|
419
|
+
* import { Principal } from '@dfinity/principal';
|
|
420
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
421
|
+
*
|
|
422
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
423
|
+
*
|
|
424
|
+
* const picServer = await PocketIcServer.create();
|
|
425
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
426
|
+
*
|
|
427
|
+
* await pic.updateCanisterSettings({
|
|
428
|
+
* canisterId,
|
|
429
|
+
* controllers: [Principal.fromUint8Array(new Uint8Array([1]))],
|
|
430
|
+
* });
|
|
431
|
+
*
|
|
432
|
+
* await pic.tearDown();
|
|
433
|
+
* await picServer.stop();
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
async updateCanisterSettings({ canisterId, computeAllocation, controllers, freezingThreshold, memoryAllocation, reservedCyclesLimit, sender = principal_1.Principal.anonymous(), }) {
|
|
437
|
+
const payload = (0, management_canister_1.encodeUpdateCanisterSettingsRequest)({
|
|
438
|
+
canister_id: canisterId,
|
|
439
|
+
settings: {
|
|
440
|
+
controllers: (0, util_1.optional)(controllers),
|
|
441
|
+
compute_allocation: (0, util_1.optional)(computeAllocation),
|
|
442
|
+
memory_allocation: (0, util_1.optional)(memoryAllocation),
|
|
443
|
+
freezing_threshold: (0, util_1.optional)(freezingThreshold),
|
|
444
|
+
reserved_cycles_limit: (0, util_1.optional)(reservedCyclesLimit),
|
|
445
|
+
},
|
|
446
|
+
});
|
|
447
|
+
await this.client.updateCall({
|
|
448
|
+
canisterId: management_canister_1.MANAGEMENT_CANISTER_ID,
|
|
449
|
+
sender,
|
|
450
|
+
method: 'update_settings',
|
|
451
|
+
payload,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Creates an {@link Actor} for the given canister.
|
|
456
|
+
* An {@link Actor} is a typesafe class that implements the Candid interface of a canister.
|
|
457
|
+
* To create a canister for the {@link Actor}, see {@link createCanister}.
|
|
458
|
+
* For a more convenient way of creating a PocketIC instance,
|
|
459
|
+
* creating a canister and installing code, see {@link setupCanister}.
|
|
460
|
+
*
|
|
461
|
+
* @param interfaceFactory The InterfaceFactory to use for the {@link Actor}.
|
|
462
|
+
* @param canisterId The Principal of the canister to create the {@link Actor} for.
|
|
463
|
+
* @typeparam T The type of the {@link Actor}. Must implement {@link ActorInterface}.
|
|
464
|
+
* @returns The {@link Actor} instance.
|
|
465
|
+
*
|
|
466
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
467
|
+
* @see [InterfaceFactory](https://agent-js.icp.xyz/candid/modules/IDL.html#InterfaceFactory)
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```ts
|
|
471
|
+
* import { Principal } from '@dfinity/principal';
|
|
472
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
473
|
+
* import { _SERVICE, idlFactory } from '../declarations';
|
|
474
|
+
*
|
|
475
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
476
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
477
|
+
*
|
|
478
|
+
* const picServer = await PocketIcServer.create();
|
|
479
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
480
|
+
*
|
|
481
|
+
* const canisterId = await pic.createCanister();
|
|
482
|
+
* await pic.installCode({ canisterId, wasm });
|
|
483
|
+
* const actor = pic.createActor<_SERVICE>({ idlFactory, canisterId });
|
|
484
|
+
*
|
|
485
|
+
* await pic.tearDown();
|
|
486
|
+
* await picServer.stop();
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
489
|
+
createActor(interfaceFactory, canisterId) {
|
|
490
|
+
const Actor = (0, pocket_ic_actor_1.createActorClass)(interfaceFactory, canisterId, this.client);
|
|
491
|
+
return new Actor();
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Creates a {@link DeferredActor} for the given canister.
|
|
495
|
+
* A {@link DeferredActor} is a typesafe class that implements the Candid interface of a canister.
|
|
496
|
+
*
|
|
497
|
+
* A {@link DeferredActor} in contrast to a normal {@link Actor} will submit the call to the PocketIc replica,
|
|
498
|
+
* but the call will not be executed immediately. Instead, the calls are queued and a `Promise` is returned
|
|
499
|
+
* by the {@link DeferredActor} that can be awaited to process the pending canister call.
|
|
500
|
+
*
|
|
501
|
+
* To create a canister for the {@link DeferredActor}, see {@link createCanister}.
|
|
502
|
+
* For a more convenient way of creating a PocketIC instance,
|
|
503
|
+
* creating a canister and installing code, see {@link setupCanister}.
|
|
504
|
+
*
|
|
505
|
+
* @param interfaceFactory The InterfaceFactory to use for the {@link DeferredActor}.
|
|
506
|
+
* @param canisterId The Principal of the canister to create the {@link DeferredActor} for.
|
|
507
|
+
* @typeparam T The type of the {@link DeferredActor}. Must implement {@link ActorInterface}.
|
|
508
|
+
* @returns The {@link DeferredActor} instance.
|
|
509
|
+
*
|
|
510
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
511
|
+
* @see [InterfaceFactory](https://agent-js.icp.xyz/candid/modules/IDL.html#InterfaceFactory)
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
*/
|
|
515
|
+
createDeferredActor(interfaceFactory, canisterId) {
|
|
516
|
+
const DeferredActor = (0, pocket_ic_deferred_actor_1.createDeferredActorClass)(interfaceFactory, canisterId, this.client);
|
|
517
|
+
return new DeferredActor();
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Makes a query call to the given canister.
|
|
521
|
+
*
|
|
522
|
+
* @param options Options for making the query call, see {@link QueryCallOptions}.
|
|
523
|
+
* @returns The Candid-encoded response of the query call.
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```ts
|
|
527
|
+
* import { Principal } from '@dfinity/principal';
|
|
528
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
529
|
+
* import { _SERVICE, idlFactory } from '../declarations';
|
|
530
|
+
*
|
|
531
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
532
|
+
*
|
|
533
|
+
* const picServer = await PocketIcServer.create();
|
|
534
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
535
|
+
*
|
|
536
|
+
* canisterId = await pic.createCanister({
|
|
537
|
+
* sender: controllerIdentity.getPrincipal(),
|
|
538
|
+
* });
|
|
539
|
+
* await pic.installCode({ canisterId, wasm });
|
|
540
|
+
*
|
|
541
|
+
* const res = await pic.queryCall({
|
|
542
|
+
* canisterId,
|
|
543
|
+
* method: 'greet',
|
|
544
|
+
* });
|
|
545
|
+
*
|
|
546
|
+
* await pic.tearDown();
|
|
547
|
+
* await picServer.stop();
|
|
548
|
+
* ```
|
|
549
|
+
*/
|
|
550
|
+
async queryCall({ canisterId, method, arg = new Uint8Array(), sender = principal_1.Principal.anonymous(), targetSubnetId, }) {
|
|
551
|
+
const res = await this.client.queryCall({
|
|
552
|
+
canisterId,
|
|
553
|
+
method,
|
|
554
|
+
payload: new Uint8Array(arg),
|
|
555
|
+
sender,
|
|
556
|
+
effectivePrincipal: targetSubnetId
|
|
557
|
+
? {
|
|
558
|
+
subnetId: targetSubnetId,
|
|
559
|
+
}
|
|
560
|
+
: undefined,
|
|
561
|
+
});
|
|
562
|
+
return res.body;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Makes an update call to the given canister.
|
|
566
|
+
*
|
|
567
|
+
* @param options Options for making the update call, see {@link UpdateCallOptions}.
|
|
568
|
+
* @returns The Candid-encoded response of the update call.
|
|
569
|
+
*
|
|
570
|
+
* @example
|
|
571
|
+
* ```ts
|
|
572
|
+
* import { Principal } from '@dfinity/principal';
|
|
573
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
574
|
+
* import { _SERVICE, idlFactory } from '../declarations';
|
|
575
|
+
*
|
|
576
|
+
* const wasm = resolve('..', '..', 'canister.wasm');
|
|
577
|
+
*
|
|
578
|
+
* const picServer = await PocketIcServer.create();
|
|
579
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
580
|
+
*
|
|
581
|
+
* canisterId = await pic.createCanister({
|
|
582
|
+
* sender: controllerIdentity.getPrincipal(),
|
|
583
|
+
* });
|
|
584
|
+
* await pic.installCode({ canisterId, wasm });
|
|
585
|
+
*
|
|
586
|
+
* const res = await pic.updateCall({
|
|
587
|
+
* canisterId,
|
|
588
|
+
* method: 'greet',
|
|
589
|
+
* });
|
|
590
|
+
*
|
|
591
|
+
* await pic.tearDown();
|
|
592
|
+
* await picServer.stop();
|
|
593
|
+
* ```
|
|
594
|
+
*/
|
|
595
|
+
async updateCall({ canisterId, method, arg = new Uint8Array(), sender = principal_1.Principal.anonymous(), targetSubnetId, }) {
|
|
596
|
+
const res = await this.client.updateCall({
|
|
597
|
+
canisterId,
|
|
598
|
+
method,
|
|
599
|
+
payload: new Uint8Array(arg),
|
|
600
|
+
sender,
|
|
601
|
+
effectivePrincipal: targetSubnetId
|
|
602
|
+
? {
|
|
603
|
+
subnetId: targetSubnetId,
|
|
604
|
+
}
|
|
605
|
+
: undefined,
|
|
606
|
+
});
|
|
607
|
+
return res.body;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Deletes the PocketIC instance.
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
615
|
+
*
|
|
616
|
+
* const picServer = await PocketIcServer.create();
|
|
617
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
618
|
+
*
|
|
619
|
+
* await pic.tearDown();
|
|
620
|
+
* await picServer.stop();
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
async tearDown() {
|
|
624
|
+
await this.client.deleteInstance();
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Make the IC produce and progress by one block. Accepts a parameter `times` to tick multiple times,
|
|
628
|
+
* the default is `1`.
|
|
629
|
+
*
|
|
630
|
+
* @param times The number of new blocks to produce and progress by. Defaults to `1`.
|
|
631
|
+
*
|
|
632
|
+
* ```ts
|
|
633
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
634
|
+
*
|
|
635
|
+
* const picServer = await PocketIcServer.create();
|
|
636
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
637
|
+
*
|
|
638
|
+
* await pic.tick();
|
|
639
|
+
*
|
|
640
|
+
* // or to tick multiple times
|
|
641
|
+
* await pic.tick(3);
|
|
642
|
+
*
|
|
643
|
+
* await pic.tearDown();
|
|
644
|
+
* await picServer.stop();
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
async tick(times = 1) {
|
|
648
|
+
for (let i = 0; i < times; i++) {
|
|
649
|
+
await this.client.tick();
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Get the controllers of the specified canister.
|
|
654
|
+
*
|
|
655
|
+
* @param canisterId The Principal of the canister to get the controllers of.
|
|
656
|
+
* @returns The controllers of the specified canister.
|
|
657
|
+
*
|
|
658
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
659
|
+
*
|
|
660
|
+
* @example
|
|
661
|
+
* ```ts
|
|
662
|
+
* import { Principal } from '@dfinity/principal';
|
|
663
|
+
*
|
|
664
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
665
|
+
*
|
|
666
|
+
* const picServer = await PocketIcServer.create();
|
|
667
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
668
|
+
*
|
|
669
|
+
* const controllers = await pic.getControllers(canisterId);
|
|
670
|
+
*
|
|
671
|
+
* await pic.tearDown();
|
|
672
|
+
* await picServer.stop();
|
|
673
|
+
*/
|
|
674
|
+
async getControllers(canisterId) {
|
|
675
|
+
return await this.client.getControllers({ canisterId });
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Get the current time of the IC in milliseconds since the Unix epoch.
|
|
679
|
+
*
|
|
680
|
+
* @returns The current time in milliseconds since the UNIX epoch.
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```ts
|
|
684
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
685
|
+
*
|
|
686
|
+
* const picServer = await PocketIcServer.create();
|
|
687
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
688
|
+
*
|
|
689
|
+
* const time = await pic.getTime();
|
|
690
|
+
*
|
|
691
|
+
* await pic.tearDown();
|
|
692
|
+
* await picServer.stop();
|
|
693
|
+
* ```
|
|
694
|
+
*/
|
|
695
|
+
async getTime() {
|
|
696
|
+
const { millisSinceEpoch } = await this.client.getTime();
|
|
697
|
+
return millisSinceEpoch;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Reset the time of the IC to the current time.
|
|
701
|
+
* {@link tick} should be called after calling this method in order for query calls
|
|
702
|
+
* and read state request to reflect the new time.
|
|
703
|
+
*
|
|
704
|
+
* Use {@link resetCertifiedTime} to set time and immediately have query calls and
|
|
705
|
+
* read state requests reflect the new time.
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* ```ts
|
|
709
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
710
|
+
*
|
|
711
|
+
* const picServer = await PocketIcServer.create();
|
|
712
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
713
|
+
*
|
|
714
|
+
* await pic.resetTime();
|
|
715
|
+
* await pic.tick();
|
|
716
|
+
*
|
|
717
|
+
* const time = await pic.getTime();
|
|
718
|
+
*
|
|
719
|
+
* await pic.tearDown();
|
|
720
|
+
* await picServer.stop();
|
|
721
|
+
* ```
|
|
722
|
+
*/
|
|
723
|
+
async resetTime() {
|
|
724
|
+
await this.setTime(Date.now());
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Reset the time of the IC to the current time and immediately have query calls and
|
|
728
|
+
* read state requests reflect the new time.
|
|
729
|
+
*
|
|
730
|
+
* Use {@link resetTime} to reset time without immediately reflecting the new time.
|
|
731
|
+
*
|
|
732
|
+
* @example
|
|
733
|
+
* ```ts
|
|
734
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
735
|
+
*
|
|
736
|
+
* const picServer = await PocketIcServer.create();
|
|
737
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
738
|
+
*
|
|
739
|
+
* await pic.resetCertifiedTime();
|
|
740
|
+
*
|
|
741
|
+
* const time = await pic.getTime();
|
|
742
|
+
*
|
|
743
|
+
* await pic.tearDown();
|
|
744
|
+
* await picServer.stop();
|
|
745
|
+
* ```
|
|
746
|
+
*/
|
|
747
|
+
async resetCertifiedTime() {
|
|
748
|
+
await this.setCertifiedTime(Date.now());
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Set the current time of the IC.
|
|
752
|
+
* {@link tick} should be called after calling this method in order for query calls
|
|
753
|
+
* and read state request to reflect the new time.
|
|
754
|
+
*
|
|
755
|
+
* Use {@link setCertifiedTime} to set time and immediately have query calls and
|
|
756
|
+
* read state requests reflect the new time.
|
|
757
|
+
*
|
|
758
|
+
* @param time The time to set in milliseconds since the Unix epoch.
|
|
759
|
+
*
|
|
760
|
+
* @example
|
|
761
|
+
* ```ts
|
|
762
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
763
|
+
*
|
|
764
|
+
* const pic = await PocketIc.create();
|
|
765
|
+
*
|
|
766
|
+
* const date = new Date();
|
|
767
|
+
*
|
|
768
|
+
* const picServer = await PocketIcServer.create();
|
|
769
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
770
|
+
*
|
|
771
|
+
* await pic.setTime(date);
|
|
772
|
+
* // or
|
|
773
|
+
* await pic.setTime(date.getTime());
|
|
774
|
+
*
|
|
775
|
+
* await pic.tick();
|
|
776
|
+
*
|
|
777
|
+
* const time = await pic.getTime();
|
|
778
|
+
*
|
|
779
|
+
* await pic.tearDown();
|
|
780
|
+
* await picServer.stop();
|
|
781
|
+
* ```
|
|
782
|
+
*/
|
|
783
|
+
async setTime(time) {
|
|
784
|
+
if (time instanceof Date) {
|
|
785
|
+
time = time.getTime();
|
|
786
|
+
}
|
|
787
|
+
await this.client.setTime({ millisSinceEpoch: time });
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Set the current time of the IC and immediately have query calls and
|
|
791
|
+
* read state requests reflect the new time.
|
|
792
|
+
*
|
|
793
|
+
* Use {@link setTime} to set time without immediately reflecting the new time.
|
|
794
|
+
*
|
|
795
|
+
* @param time The time to set in milliseconds since the Unix epoch.
|
|
796
|
+
*
|
|
797
|
+
* @example
|
|
798
|
+
* ```ts
|
|
799
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
800
|
+
*
|
|
801
|
+
* const pic = await PocketIc.create();
|
|
802
|
+
*
|
|
803
|
+
* const date = new Date();
|
|
804
|
+
*
|
|
805
|
+
* const picServer = await PocketIcServer.create();
|
|
806
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
807
|
+
*
|
|
808
|
+
* await pic.setCertifiedTime(date);
|
|
809
|
+
* // or
|
|
810
|
+
* await pic.setCertifiedTime(date.getTime());
|
|
811
|
+
*
|
|
812
|
+
* const time = await pic.getTime();
|
|
813
|
+
*
|
|
814
|
+
* await pic.tearDown();
|
|
815
|
+
* await picServer.stop();
|
|
816
|
+
* ```
|
|
817
|
+
*/
|
|
818
|
+
async setCertifiedTime(time) {
|
|
819
|
+
if (time instanceof Date) {
|
|
820
|
+
time = time.getTime();
|
|
821
|
+
}
|
|
822
|
+
await this.client.setCertifiedTime({ millisSinceEpoch: time });
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Advance the time of the IC by the given duration in milliseconds.
|
|
826
|
+
* {@link tick} should be called after calling this method in order for query calls
|
|
827
|
+
* and read state requests to reflect the new time.
|
|
828
|
+
*
|
|
829
|
+
* Use {@link advanceCertifiedTime} to advance time and immediately have query calls and
|
|
830
|
+
* read state requests reflect the new time.
|
|
831
|
+
*
|
|
832
|
+
* @param duration The duration to advance the time by.
|
|
833
|
+
*
|
|
834
|
+
* @example
|
|
835
|
+
* ```ts
|
|
836
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
837
|
+
*
|
|
838
|
+
* const picServer = await PocketIcServer.create();
|
|
839
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
840
|
+
*
|
|
841
|
+
* const initialTime = await pic.getTime();
|
|
842
|
+
* await pic.advanceTime(1_000);
|
|
843
|
+
* await pic.tick();
|
|
844
|
+
*
|
|
845
|
+
* const newTime = await pic.getTime();
|
|
846
|
+
*
|
|
847
|
+
* await pic.tearDown();
|
|
848
|
+
* await picServer.stop();
|
|
849
|
+
* ```
|
|
850
|
+
*/
|
|
851
|
+
async advanceTime(duration) {
|
|
852
|
+
const currentTime = await this.getTime();
|
|
853
|
+
const newTime = currentTime + duration;
|
|
854
|
+
await this.setTime(newTime);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Advance the time of the IC by the given duration in milliseconds and
|
|
858
|
+
* immediately have query calls and read state requests reflect the new time.
|
|
859
|
+
*
|
|
860
|
+
* Use {@link advanceTime} to advance time without immediately reflecting the new time.
|
|
861
|
+
*
|
|
862
|
+
* @param duration The duration to advance the time by.
|
|
863
|
+
*
|
|
864
|
+
* @example
|
|
865
|
+
* ```ts
|
|
866
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
867
|
+
*
|
|
868
|
+
* const picServer = await PocketIcServer.create();
|
|
869
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
870
|
+
*
|
|
871
|
+
* const initialTime = await pic.getTime();
|
|
872
|
+
* await pic.advanceCertifiedTime(1_000);
|
|
873
|
+
*
|
|
874
|
+
* const newTime = await pic.getTime();
|
|
875
|
+
*
|
|
876
|
+
* await pic.tearDown();
|
|
877
|
+
* await picServer.stop();
|
|
878
|
+
* ```
|
|
879
|
+
*/
|
|
880
|
+
async advanceCertifiedTime(duration) {
|
|
881
|
+
const currentTime = await this.getTime();
|
|
882
|
+
const newTime = currentTime + duration;
|
|
883
|
+
await this.setCertifiedTime(newTime);
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Fetch the public key of the specified subnet.
|
|
887
|
+
*
|
|
888
|
+
* @param subnetId The Principal of the subnet to fetch the public key of.
|
|
889
|
+
* @returns The public key of the specified subnet.
|
|
890
|
+
*
|
|
891
|
+
* @example
|
|
892
|
+
* ```ts
|
|
893
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
894
|
+
*
|
|
895
|
+
* const picServer = await PocketIcServer.create();
|
|
896
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
897
|
+
*
|
|
898
|
+
* const subnets = pic.getApplicationSubnets();
|
|
899
|
+
* const pubKey = await pic.getPubKey(subnets[0].id);
|
|
900
|
+
*
|
|
901
|
+
* await pic.tearDown();
|
|
902
|
+
* await picServer.stop();
|
|
903
|
+
* ```
|
|
904
|
+
*/
|
|
905
|
+
async getPubKey(subnetId) {
|
|
906
|
+
return await this.client.getPubKey({ subnetId });
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Gets the subnet Id of the provided canister Id.
|
|
910
|
+
*
|
|
911
|
+
* @param canisterId The Principal of the canister to get the subnet Id of.
|
|
912
|
+
* @returns The canister's subnet Id if the canister exists, `null` otherwise.
|
|
913
|
+
*
|
|
914
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
* ```ts
|
|
918
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
919
|
+
*
|
|
920
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
921
|
+
*
|
|
922
|
+
* const picServer = await PocketIcServer.create();
|
|
923
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
924
|
+
*
|
|
925
|
+
* const subnetId = await pic.getCanisterSubnetId(canisterId);
|
|
926
|
+
*
|
|
927
|
+
* await pic.tearDown();
|
|
928
|
+
* await picServer.stop();
|
|
929
|
+
* ```
|
|
930
|
+
*/
|
|
931
|
+
async getCanisterSubnetId(canisterId) {
|
|
932
|
+
const { subnetId } = await this.client.getSubnetId({ canisterId });
|
|
933
|
+
return subnetId;
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Get the topology of this instance's network.
|
|
937
|
+
* The topology is a list of subnets, each with a type and a list of canister ID ranges
|
|
938
|
+
* that can be deployed to that subnet.
|
|
939
|
+
* The instance network topology is configured via the {@link create} method.
|
|
940
|
+
*
|
|
941
|
+
* @returns An array of subnet topologies, see {@link SubnetTopology}.
|
|
942
|
+
*/
|
|
943
|
+
async getTopology() {
|
|
944
|
+
const topology = await this.client.getTopology();
|
|
945
|
+
return Object.values(topology);
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Get the Bitcoin subnet topology for this instance's network.
|
|
949
|
+
* The instance network topology is configured via the {@link create} method.
|
|
950
|
+
*
|
|
951
|
+
* @returns The subnet topology for the Bitcoin subnet,
|
|
952
|
+
* if it exists on this instance's network.
|
|
953
|
+
*/
|
|
954
|
+
async getBitcoinSubnet() {
|
|
955
|
+
const topology = await this.getTopology();
|
|
956
|
+
return topology.find(subnet => subnet.type === pocket_ic_types_1.SubnetType.Bitcoin);
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Get the Fiduciary subnet topology for this instance's network.
|
|
960
|
+
* The instance network topology is configured via the {@link create} method.
|
|
961
|
+
*
|
|
962
|
+
* @returns The subnet topology for the Fiduciary subnet,
|
|
963
|
+
* if it exists on this instance's network.
|
|
964
|
+
*/
|
|
965
|
+
async getFiduciarySubnet() {
|
|
966
|
+
const topology = await this.getTopology();
|
|
967
|
+
return topology.find(subnet => subnet.type === pocket_ic_types_1.SubnetType.Fiduciary);
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Get the Internet Identity subnet topology for this instance's network.
|
|
971
|
+
* The instance network topology is configured via the {@link create} method.
|
|
972
|
+
*
|
|
973
|
+
* @returns The subnet topology for the Internet Identity subnet,
|
|
974
|
+
* if it exists on this instance's network.
|
|
975
|
+
*/
|
|
976
|
+
async getInternetIdentitySubnet() {
|
|
977
|
+
const topology = await this.getTopology();
|
|
978
|
+
return topology.find(subnet => subnet.type === pocket_ic_types_1.SubnetType.InternetIdentity);
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Get the NNS subnet topology for this instance's network.
|
|
982
|
+
* The instance network topology is configured via the {@link create} method.
|
|
983
|
+
*
|
|
984
|
+
* @returns The subnet topology for the NNS subnet,
|
|
985
|
+
* if it exists on this instance's network.
|
|
986
|
+
*/
|
|
987
|
+
async getNnsSubnet() {
|
|
988
|
+
const topology = await this.getTopology();
|
|
989
|
+
return topology.find(subnet => subnet.type === pocket_ic_types_1.SubnetType.NNS);
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Get the SNS subnet topology for this instance's network.
|
|
993
|
+
* The instance network topology is configured via the {@link create} method.
|
|
994
|
+
*
|
|
995
|
+
* @returns The subnet topology for the SNS subnet,
|
|
996
|
+
* if it exists on this instance's network.
|
|
997
|
+
*/
|
|
998
|
+
async getSnsSubnet() {
|
|
999
|
+
const topology = await this.getTopology();
|
|
1000
|
+
return topology.find(subnet => subnet.type === pocket_ic_types_1.SubnetType.SNS);
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Get all application subnet topologies for this instance's network.
|
|
1004
|
+
* The instance network topology is configured via the {@link create} method.
|
|
1005
|
+
*
|
|
1006
|
+
* @returns An array of subnet topologies for each application subnet
|
|
1007
|
+
* that exists on this instance's network.
|
|
1008
|
+
*/
|
|
1009
|
+
async getApplicationSubnets() {
|
|
1010
|
+
const topology = await this.getTopology();
|
|
1011
|
+
return topology.filter(subnet => subnet.type === pocket_ic_types_1.SubnetType.Application);
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Get all system subnet topologies for this instance's network.
|
|
1015
|
+
* The instance network topology is configured via the {@link create} method.
|
|
1016
|
+
*
|
|
1017
|
+
* @returns An array of subnet topologies for each system subnet
|
|
1018
|
+
* that exists on this instance's network.
|
|
1019
|
+
*/
|
|
1020
|
+
async getSystemSubnets() {
|
|
1021
|
+
const topology = await this.getTopology();
|
|
1022
|
+
return topology.filter(subnet => subnet.type === pocket_ic_types_1.SubnetType.System);
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Gets the current cycle balance of the specified canister.
|
|
1026
|
+
*
|
|
1027
|
+
* @param canisterId The Principal of the canister to check.
|
|
1028
|
+
* @returns The current cycles balance of the canister.
|
|
1029
|
+
*
|
|
1030
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
1031
|
+
*
|
|
1032
|
+
* @example
|
|
1033
|
+
* ```ts
|
|
1034
|
+
* import { Principal } from '@dfinity/principal';
|
|
1035
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
1036
|
+
*
|
|
1037
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
1038
|
+
*
|
|
1039
|
+
* const picServer = await PocketIcServer.create();
|
|
1040
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
1041
|
+
*
|
|
1042
|
+
* const cyclesBalance = await pic.getCyclesBalance(canisterId);
|
|
1043
|
+
*
|
|
1044
|
+
* await pic.tearDown();
|
|
1045
|
+
* await picServer.stop();
|
|
1046
|
+
* ```
|
|
1047
|
+
*/
|
|
1048
|
+
async getCyclesBalance(canisterId) {
|
|
1049
|
+
const { cycles } = await this.client.getCyclesBalance({ canisterId });
|
|
1050
|
+
return cycles;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Add cycles to the specified canister.
|
|
1054
|
+
*
|
|
1055
|
+
* @param canisterId The Principal of the canister to add cycles to.
|
|
1056
|
+
* @param amount The amount of cycles to add.
|
|
1057
|
+
* @returns The new cycle balance of the canister.
|
|
1058
|
+
*
|
|
1059
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```ts
|
|
1063
|
+
* import { Principal } from '@dfinity/principal';
|
|
1064
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
1065
|
+
*
|
|
1066
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
1067
|
+
*
|
|
1068
|
+
* const picServer = await PocketIcServer.create();
|
|
1069
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
1070
|
+
*
|
|
1071
|
+
* const newCyclesBalance = await pic.addCycles(canisterId, 10_000_000);
|
|
1072
|
+
*
|
|
1073
|
+
* await pic.tearDown();
|
|
1074
|
+
* await picServer.stop();
|
|
1075
|
+
* ```
|
|
1076
|
+
*/
|
|
1077
|
+
async addCycles(canisterId, amount) {
|
|
1078
|
+
const { cycles } = await this.client.addCycles({ canisterId, amount });
|
|
1079
|
+
return cycles;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Set the stable memory of a given canister.
|
|
1083
|
+
*
|
|
1084
|
+
* @param canisterId The Principal of the canister to set the stable memory of.
|
|
1085
|
+
* @param stableMemory A blob containing the stable memory to set.
|
|
1086
|
+
*
|
|
1087
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
1088
|
+
*
|
|
1089
|
+
* @example
|
|
1090
|
+
* ```ts
|
|
1091
|
+
* import { Principal } from '@dfinity/principal';
|
|
1092
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
1093
|
+
*
|
|
1094
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
1095
|
+
* const stableMemory = new Uint8Array([0, 1, 2, 3, 4]);
|
|
1096
|
+
*
|
|
1097
|
+
* const picServer = await PocketIcServer.create();
|
|
1098
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
1099
|
+
*
|
|
1100
|
+
* await pic.setStableMemory(canisterId, stableMemory);
|
|
1101
|
+
*
|
|
1102
|
+
* await pic.tearDown();
|
|
1103
|
+
* await picServer.stop();
|
|
1104
|
+
* ```
|
|
1105
|
+
*/
|
|
1106
|
+
async setStableMemory(canisterId, stableMemory) {
|
|
1107
|
+
const { blobId } = await this.client.uploadBlob({
|
|
1108
|
+
blob: new Uint8Array(stableMemory),
|
|
1109
|
+
});
|
|
1110
|
+
await this.client.setStableMemory({ canisterId, blobId });
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Get the stable memory of a given canister.
|
|
1114
|
+
*
|
|
1115
|
+
* @param canisterId The Principal of the canister to get the stable memory of.
|
|
1116
|
+
* @returns A blob containing the canister's stable memory.
|
|
1117
|
+
*
|
|
1118
|
+
* @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html)
|
|
1119
|
+
*
|
|
1120
|
+
* @example
|
|
1121
|
+
* ```ts
|
|
1122
|
+
* import { Principal } from '@dfinity/principal';
|
|
1123
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
1124
|
+
*
|
|
1125
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
1126
|
+
*
|
|
1127
|
+
* const picServer = await PocketIcServer.create();
|
|
1128
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
1129
|
+
*
|
|
1130
|
+
* const stableMemory = await pic.getStableMemory(canisterId);
|
|
1131
|
+
*
|
|
1132
|
+
* await pic.tearDown();
|
|
1133
|
+
* await picServer.stop();
|
|
1134
|
+
* ```
|
|
1135
|
+
*/
|
|
1136
|
+
async getStableMemory(canisterId) {
|
|
1137
|
+
const { blob } = await this.client.getStableMemory({ canisterId });
|
|
1138
|
+
return blob;
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Get all pending HTTPS Outcalls across all subnets on this
|
|
1142
|
+
* PocketIC instance.
|
|
1143
|
+
*
|
|
1144
|
+
* @returns An array of pending HTTPS Outcalls.
|
|
1145
|
+
*
|
|
1146
|
+
* @example
|
|
1147
|
+
* ```ts
|
|
1148
|
+
* import { Principal } from '@dfinity/principal';
|
|
1149
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
1150
|
+
*
|
|
1151
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
1152
|
+
*
|
|
1153
|
+
* const picServer = await PocketIcServer.create();
|
|
1154
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
1155
|
+
*
|
|
1156
|
+
* // queue the canister message that will send the HTTPS Outcall
|
|
1157
|
+
* const executeGoogleSearch = await deferredActor.google_search();
|
|
1158
|
+
*
|
|
1159
|
+
* // tick for two rounds to allow the canister message to be processed
|
|
1160
|
+
* // and for the HTTPS Outcall to be queued
|
|
1161
|
+
* await pic.tick(2);
|
|
1162
|
+
*
|
|
1163
|
+
* // get all queued HTTPS Outcalls
|
|
1164
|
+
* const pendingHttpsOutcalls = await pic.getPendingHttpsOutcalls();
|
|
1165
|
+
*
|
|
1166
|
+
* // get the first pending HTTPS Outcall
|
|
1167
|
+
* const pendingGoogleSearchOutcall = pendingHttpsOutcalls[0];
|
|
1168
|
+
*
|
|
1169
|
+
* // mock the HTTPS Outcall
|
|
1170
|
+
* await pic.mockPendingHttpsOutcall({
|
|
1171
|
+
* requestId: pendingGoogleSearchOutcall.requestId,
|
|
1172
|
+
* subnetId: pendingGoogleSearchOutcall.subnetId,
|
|
1173
|
+
* response: {
|
|
1174
|
+
* type: 'success',
|
|
1175
|
+
* body: new TextEncoder().encode('Google search result'),
|
|
1176
|
+
* statusCode: 200,
|
|
1177
|
+
* headers: [],
|
|
1178
|
+
* },
|
|
1179
|
+
* });
|
|
1180
|
+
*
|
|
1181
|
+
* // finish executing the message, including the HTTPS Outcall
|
|
1182
|
+
* const result = await executeGoogleSearch();
|
|
1183
|
+
*
|
|
1184
|
+
* await pic.tearDown();
|
|
1185
|
+
* await picServer.stop();
|
|
1186
|
+
* ```
|
|
1187
|
+
*/
|
|
1188
|
+
async getPendingHttpsOutcalls() {
|
|
1189
|
+
return await this.client.getPendingHttpsOutcalls();
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Mock a pending HTTPS Outcall.
|
|
1193
|
+
*
|
|
1194
|
+
* @param options Options for mocking the pending HTTPS Outcall, see {@link MockPendingHttpsOutcallOptions}.
|
|
1195
|
+
*
|
|
1196
|
+
* @example
|
|
1197
|
+
* ```ts
|
|
1198
|
+
* import { Principal } from '@dfinity/principal';
|
|
1199
|
+
* import { PocketIc, PocketIcServer } from '@dfinity/pic';
|
|
1200
|
+
*
|
|
1201
|
+
* const canisterId = Principal.fromUint8Array(new Uint8Array([0]));
|
|
1202
|
+
*
|
|
1203
|
+
* const picServer = await PocketIcServer.create();
|
|
1204
|
+
* const pic = await PocketIc.create(picServer.getUrl());
|
|
1205
|
+
*
|
|
1206
|
+
* // queue the canister message that will send the HTTPS Outcall
|
|
1207
|
+
* const executeGoogleSearch = await deferredActor.google_search();
|
|
1208
|
+
*
|
|
1209
|
+
* // tick for two rounds to allow the canister message to be processed
|
|
1210
|
+
* // and for the HTTPS Outcall to be queued
|
|
1211
|
+
* await pic.tick(2);
|
|
1212
|
+
*
|
|
1213
|
+
* // get all queued HTTPS Outcalls
|
|
1214
|
+
* const pendingHttpsOutcalls = await pic.getPendingHttpsOutcalls();
|
|
1215
|
+
*
|
|
1216
|
+
* // get the first pending HTTPS Outcall
|
|
1217
|
+
* const pendingGoogleSearchOutcall = pendingHttpsOutcalls[0];
|
|
1218
|
+
*
|
|
1219
|
+
* // mock the HTTPS Outcall
|
|
1220
|
+
* await pic.mockPendingHttpsOutcall({
|
|
1221
|
+
* requestId: pendingGoogleSearchOutcall.requestId,
|
|
1222
|
+
* subnetId: pendingGoogleSearchOutcall.subnetId,
|
|
1223
|
+
* response: {
|
|
1224
|
+
* type: 'success',
|
|
1225
|
+
* body: new TextEncoder().encode('Google search result'),
|
|
1226
|
+
* statusCode: 200,
|
|
1227
|
+
* headers: [],
|
|
1228
|
+
* },
|
|
1229
|
+
* });
|
|
1230
|
+
*
|
|
1231
|
+
* // finish executing the message, including the HTTPS Outcall
|
|
1232
|
+
* const result = await executeGoogleSearch();
|
|
1233
|
+
*
|
|
1234
|
+
* await pic.tearDown();
|
|
1235
|
+
* await picServer.stop();
|
|
1236
|
+
* ```
|
|
1237
|
+
*/
|
|
1238
|
+
async mockPendingHttpsOutcall({ requestId, response, subnetId, additionalResponses = [], }) {
|
|
1239
|
+
return await this.client.mockPendingHttpsOutcall({
|
|
1240
|
+
requestId,
|
|
1241
|
+
response,
|
|
1242
|
+
subnetId,
|
|
1243
|
+
additionalResponses,
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
exports.PocketIc = PocketIc;
|
|
1248
|
+
//# sourceMappingURL=pocket-ic.js.map
|