UNPKG

@dfinity/pic

Version:

An Internet Computer Protocol canister testing library for TypeScript and JavaScript.

182 lines 8.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PocketIcClient = void 0; const json_with_bigint_1 = require("json-with-bigint"); const http2_client_1 = require("./http2-client"); const pocket_ic_client_types_1 = require("./pocket-ic-client-types"); const util_1 = require("./util"); const PROCESSING_TIME_VALUE_MS = 30_000; const AWAIT_INGRESS_STATUS_ROUNDS = 100; class PocketIcClient { serverClient; instancePath; ingressMaxRetries; isInstanceDeleted = false; constructor(serverClient, instancePath, ingressMaxRetries) { this.serverClient = serverClient; this.instancePath = instancePath; this.ingressMaxRetries = ingressMaxRetries; } static async create(url, req) { const processingTimeoutMs = req?.processingTimeoutMs ?? PROCESSING_TIME_VALUE_MS; const serverClient = new http2_client_1.Http2Client(url, processingTimeoutMs); const res = await serverClient.jsonPost({ path: '/instances', body: (0, pocket_ic_client_types_1.encodeCreateInstanceRequest)(req), }); if ('Error' in res) { console.error('Error creating instance', res.Error.message); throw new Error(res.Error.message); } const instanceId = res.Created.instance_id; const ingressMaxRetries = req?.ingressMaxRetries ?? AWAIT_INGRESS_STATUS_ROUNDS; return new PocketIcClient(serverClient, `/instances/${instanceId}`, ingressMaxRetries); } async deleteInstance() { this.assertInstanceNotDeleted(); await this.serverClient.request({ method: 'DELETE', path: this.instancePath, }); this.isInstanceDeleted = true; } async getControllers(req) { this.assertInstanceNotDeleted(); const res = await this.post('/read/get_controllers', (0, pocket_ic_client_types_1.encodeGetControllersRequest)(req)); return (0, pocket_ic_client_types_1.decodeGetControllersResponse)(res); } async tick() { this.assertInstanceNotDeleted(); return await this.post('/update/tick', {}); } async getPubKey(req) { this.assertInstanceNotDeleted(); return await this.post('/read/pub_key', (0, pocket_ic_client_types_1.encodeGetPubKeyRequest)(req)); } async getTopology() { this.assertInstanceNotDeleted(); const res = await this.get('/_/topology'); return (0, pocket_ic_client_types_1.decodeGetTopologyResponse)(res); } async getDefaultEffectiveCanisterId() { this.assertInstanceNotDeleted(); const res = await this.get('/_/topology'); return (0, util_1.base64DecodePrincipal)(res.default_effective_canister_id.canister_id); } async getTime() { this.assertInstanceNotDeleted(); const res = await this.get('/read/get_time', json_with_bigint_1.JSONParse); return (0, pocket_ic_client_types_1.decodeGetTimeResponse)(res); } async setTime(req) { this.assertInstanceNotDeleted(); await this.post('/update/set_time', (0, pocket_ic_client_types_1.encodeSetTimeRequest)(req)); } async setCertifiedTime(req) { this.assertInstanceNotDeleted(); await this.post('/update/set_certified_time', (0, pocket_ic_client_types_1.encodeSetTimeRequest)(req)); } async getSubnetId(req) { this.assertInstanceNotDeleted(); const res = await this.post('/read/get_subnet', (0, pocket_ic_client_types_1.encodeGetSubnetIdRequest)(req)); return (0, pocket_ic_client_types_1.decodeGetSubnetIdResponse)(res); } async getCyclesBalance(req) { this.assertInstanceNotDeleted(); const res = await this.post('/read/get_cycles', (0, pocket_ic_client_types_1.encodeGetCyclesBalanceRequest)(req), json_with_bigint_1.JSONParse); return (0, pocket_ic_client_types_1.decodeGetCyclesBalanceResponse)(res); } async addCycles(req) { this.assertInstanceNotDeleted(); const res = await this.post('/update/add_cycles', (0, pocket_ic_client_types_1.encodeAddCyclesRequest)(req), json_with_bigint_1.JSONParse); return (0, pocket_ic_client_types_1.decodeAddCyclesResponse)(res); } async uploadBlob(req) { this.assertInstanceNotDeleted(); const res = await this.serverClient.request({ method: 'POST', path: '/blobstore', body: (0, pocket_ic_client_types_1.encodeUploadBlobRequest)(req), }); const body = await res.text(); return (0, pocket_ic_client_types_1.decodeUploadBlobResponse)(body); } async setStableMemory(req) { this.assertInstanceNotDeleted(); await this.serverClient.jsonPost({ path: `${this.instancePath}/update/set_stable_memory`, body: (0, pocket_ic_client_types_1.encodeSetStableMemoryRequest)(req), }); } async getStableMemory(req) { this.assertInstanceNotDeleted(); const res = await this.post('/read/get_stable_memory', (0, pocket_ic_client_types_1.encodeGetStableMemoryRequest)(req)); return (0, pocket_ic_client_types_1.decodeGetStableMemoryResponse)(res); } async getPendingHttpsOutcalls() { this.assertInstanceNotDeleted(); const res = await this.get('/read/get_canister_http'); return (0, pocket_ic_client_types_1.decodeGetPendingHttpsOutcallsResponse)(res); } async mockPendingHttpsOutcall(req) { this.assertInstanceNotDeleted(); await this.post('/update/mock_canister_http', (0, pocket_ic_client_types_1.encodeMockPendingHttpsOutcallRequest)(req)); } async updateCall(req) { this.assertInstanceNotDeleted(); const res = await this.submitCall(req); return await this.awaitCall(res); } async queryCall(req) { this.assertInstanceNotDeleted(); const res = await this.post('/read/query', (0, pocket_ic_client_types_1.encodeCanisterCallRequest)(req)); return (0, pocket_ic_client_types_1.decodeCanisterCallResponse)(res); } async submitCall(req) { this.assertInstanceNotDeleted(); const res = await this.post('/update/submit_ingress_message', (0, pocket_ic_client_types_1.encodeSubmitCanisterCallRequest)(req)); return (0, pocket_ic_client_types_1.decodeSubmitCanisterCallResponse)(res); } async ingressStatus(req) { this.assertInstanceNotDeleted(); const res = await this.post('/read/ingress_status', (0, pocket_ic_client_types_1.encodeIngressStatusRequest)(req)); return (0, pocket_ic_client_types_1.decodeIngressStatusResponse)(res); } async awaitCall(req) { this.assertInstanceNotDeleted(); const encodedReq = { messageId: (0, pocket_ic_client_types_1.encodeAwaitCanisterCallRequest)(req), // since this is always called immediately after making a call, there is no need to check the caller // the `ingressStatus` method is not exposed publicly, so it is safe to assume that the caller is the same as the one who made the call caller: undefined, }; for (let i = 0; i < this.ingressMaxRetries; i++) { await this.tick(); const result = await this.ingressStatus(encodedReq); if ((0, util_1.isNotNil)(result)) { return result; } } throw new Error(`PocketIC did not complete the update call within ${this.ingressMaxRetries} rounds`); } async post(endpoint, body, responseJsonParser) { return await this.serverClient.jsonPost({ path: `${this.instancePath}${endpoint}`, body, responseJsonParser, }); } async get(endpoint, responseJsonParser) { return await this.serverClient.jsonGet({ path: `${this.instancePath}${endpoint}`, responseJsonParser, }); } assertInstanceNotDeleted() { if (this.isInstanceDeleted) { throw new Error('Instance was deleted'); } } } exports.PocketIcClient = PocketIcClient; //# sourceMappingURL=pocket-ic-client.js.map