pic-js-mops
Version:
An Internet Computer Protocol canister testing library for TypeScript and JavaScript.
371 lines • 12.3 kB
JavaScript
import { Principal } from '@icp-sdk/core/principal';
import { base64Decode, base64DecodePrincipal, base64Encode, base64EncodePrincipal, hexDecode, isNil, isNotNil, } from './util/index.js';
import { TopologyValidationError } from './error.js';
export var SubnetStateType;
(function (SubnetStateType) {
SubnetStateType["New"] = "new";
SubnetStateType["FromPath"] = "fromPath";
})(SubnetStateType || (SubnetStateType = {}));
function encodeManySubnetConfigs(configs = []) {
return configs.map(encodeSubnetConfig).filter(isNotNil);
}
function encodeSubnetConfig(config) {
if (isNil(config)) {
return undefined;
}
switch (config.state.type) {
default: {
throw new Error(`Unknown subnet state type: ${config.state}`);
}
case SubnetStateType.New: {
return {
dts_flag: encodeDtsFlag(config.enableDeterministicTimeSlicing),
instruction_config: encodeInstructionConfig(config.enableBenchmarkingInstructionLimits),
state_config: 'New',
};
}
case SubnetStateType.FromPath: {
return {
dts_flag: encodeDtsFlag(config.enableDeterministicTimeSlicing),
instruction_config: encodeInstructionConfig(config.enableBenchmarkingInstructionLimits),
state_config: {
FromPath: config.state.path,
},
};
}
}
}
function encodeDtsFlag(enableDeterministicTimeSlicing) {
return enableDeterministicTimeSlicing === false ? 'Disabled' : 'Enabled';
}
function encodeInstructionConfig(enableBenchmarkingInstructionLimits) {
return enableBenchmarkingInstructionLimits === true
? 'Benchmarking'
: 'Production';
}
export function encodeCreateInstanceRequest(req) {
const defaultApplicationSubnet = {
state: { type: SubnetStateType.New },
};
const defaultOptions = req ?? {
application: [defaultApplicationSubnet],
};
const options = {
subnet_config_set: {
nns: encodeSubnetConfig(defaultOptions.nns),
sns: encodeSubnetConfig(defaultOptions.sns),
ii: encodeSubnetConfig(defaultOptions.ii),
fiduciary: encodeSubnetConfig(defaultOptions.fiduciary),
bitcoin: encodeSubnetConfig(defaultOptions.bitcoin),
system: encodeManySubnetConfigs(defaultOptions.system),
application: encodeManySubnetConfigs(defaultOptions.application ?? [defaultApplicationSubnet]),
verified_application: encodeManySubnetConfigs(defaultOptions.verifiedApplication),
},
nonmainnet_features: defaultOptions.nonmainnetFeatures ?? false,
};
if ((isNil(options.subnet_config_set.nns) &&
isNil(options.subnet_config_set.sns) &&
isNil(options.subnet_config_set.ii) &&
isNil(options.subnet_config_set.fiduciary) &&
isNil(options.subnet_config_set.bitcoin) &&
options.subnet_config_set.system.length === 0 &&
options.subnet_config_set.application.length === 0) ||
options.subnet_config_set.system.length < 0 ||
options.subnet_config_set.application.length < 0) {
throw new TopologyValidationError();
}
return options;
}
export function encodeGetPubKeyRequest(req) {
return {
subnet_id: base64EncodePrincipal(req.subnetId),
};
}
export var SubnetType;
(function (SubnetType) {
SubnetType["Application"] = "Application";
SubnetType["Bitcoin"] = "Bitcoin";
SubnetType["Fiduciary"] = "Fiduciary";
SubnetType["InternetIdentity"] = "II";
SubnetType["NNS"] = "NNS";
SubnetType["SNS"] = "SNS";
SubnetType["System"] = "System";
})(SubnetType || (SubnetType = {}));
export function decodeGetTopologyResponse(encoded) {
return Object.fromEntries(Object.entries(encoded.subnet_configs).map(([subnetId, subnetTopology]) => [
subnetId,
decodeSubnetTopology(subnetId, subnetTopology),
]));
}
export function decodeSubnetTopology(subnetId, encoded) {
return {
id: Principal.fromText(subnetId),
type: decodeSubnetKind(encoded.subnet_kind),
size: encoded.size,
canisterRanges: encoded.canister_ranges.map(range => ({
start: base64DecodePrincipal(range.start.canister_id),
end: base64DecodePrincipal(range.end.canister_id),
})),
};
}
export function decodeSubnetKind(kind) {
switch (kind) {
case 'Application':
return SubnetType.Application;
case 'Bitcoin':
return SubnetType.Bitcoin;
case 'Fiduciary':
return SubnetType.Fiduciary;
case 'II':
return SubnetType.InternetIdentity;
case 'NNS':
return SubnetType.NNS;
case 'SNS':
return SubnetType.SNS;
case 'System':
return SubnetType.System;
default:
throw new Error(`Unknown subnet kind: ${kind}`);
}
}
export function encodeGetControllersRequest(req) {
return {
canister_id: base64EncodePrincipal(req.canisterId),
};
}
export function decodeGetControllersResponse(res) {
return res.map(({ principal_id }) => base64DecodePrincipal(principal_id));
}
export function decodeGetTimeResponse(res) {
return {
millisSinceEpoch: res.nanos_since_epoch / 1_000_000,
};
}
export function encodeSetTimeRequest(req) {
return {
nanos_since_epoch: req.millisSinceEpoch * 1_000_000,
};
}
export function encodeGetSubnetIdRequest(req) {
return {
canister_id: base64EncodePrincipal(req.canisterId),
};
}
export function decodeGetSubnetIdResponse(res) {
if (isNil(res)) {
return { subnetId: null };
}
if ('subnet_id' in res) {
return { subnetId: base64DecodePrincipal(res.subnet_id) };
}
return { subnetId: null };
}
export function encodeGetCyclesBalanceRequest(req) {
return {
canister_id: base64EncodePrincipal(req.canisterId),
};
}
export function decodeGetCyclesBalanceResponse(res) {
return {
cycles: res.cycles,
};
}
export function encodeAddCyclesRequest(req) {
return {
canister_id: base64EncodePrincipal(req.canisterId),
amount: req.amount,
};
}
export function decodeAddCyclesResponse(res) {
return {
cycles: res.cycles,
};
}
export function encodeUploadBlobRequest(req) {
return req.blob;
}
export function decodeUploadBlobResponse(res) {
return {
blobId: new Uint8Array(hexDecode(res)),
};
}
export function encodeSetStableMemoryRequest(req) {
return {
canister_id: base64EncodePrincipal(req.canisterId),
blob_id: base64Encode(req.blobId),
};
}
export function encodeGetStableMemoryRequest(req) {
return {
canister_id: base64EncodePrincipal(req.canisterId),
};
}
export function decodeGetStableMemoryResponse(res) {
return {
blob: base64Decode(res.blob),
};
}
export var CanisterHttpMethod;
(function (CanisterHttpMethod) {
CanisterHttpMethod["GET"] = "GET";
CanisterHttpMethod["POST"] = "POST";
CanisterHttpMethod["HEAD"] = "HEAD";
})(CanisterHttpMethod || (CanisterHttpMethod = {}));
export var EncodedCanisterHttpMethod;
(function (EncodedCanisterHttpMethod) {
EncodedCanisterHttpMethod["GET"] = "GET";
EncodedCanisterHttpMethod["POST"] = "POST";
EncodedCanisterHttpMethod["HEAD"] = "HEAD";
})(EncodedCanisterHttpMethod || (EncodedCanisterHttpMethod = {}));
export function decodeGetPendingHttpsOutcallsResponse(res) {
return res.map(decodeHttpOutcall);
}
function decodeHttpOutcall(res) {
return {
subnetId: base64DecodePrincipal(res.subnet_id.subnet_id),
requestId: res.request_id,
httpMethod: decodeCanisterHttpMethod(res.http_method),
url: res.url,
headers: res.headers.map(decodeHttpHeader),
body: base64Decode(res.body),
maxResponseBytes: res.max_response_bytes,
};
}
function decodeCanisterHttpMethod(method) {
switch (method) {
default:
throw new Error(`Unknown canister HTTP method: ${method}`);
case EncodedCanisterHttpMethod.GET:
return CanisterHttpMethod.GET;
case EncodedCanisterHttpMethod.POST:
return CanisterHttpMethod.POST;
case EncodedCanisterHttpMethod.HEAD:
return CanisterHttpMethod.HEAD;
}
}
function decodeHttpHeader(header) {
return [header.name, header.value];
}
export function encodeMockPendingHttpsOutcallRequest(req) {
return {
subnet_id: {
subnet_id: base64EncodePrincipal(req.subnetId),
},
request_id: req.requestId,
response: encodeHttpsOutcallResponse(req.response),
additional_responses: req.additionalResponses.map(encodeHttpsOutcallResponse),
};
}
function encodeHttpsOutcallResponse(res) {
switch (res.type) {
default:
throw new Error(`Unknown response type: ${res}`);
case 'success': {
return {
CanisterHttpReply: {
status: res.statusCode,
headers: res.headers.map(encodeHttpHeader),
body: base64Encode(res.body),
},
};
}
case 'reject': {
return {
CanisterHttpReject: {
reject_code: res.statusCode,
message: res.message,
},
};
}
}
}
function encodeHttpHeader(header) {
return {
name: header[0],
value: header[1],
};
}
export function encodeEffectivePrincipal(effectivePrincipal) {
if (isNil(effectivePrincipal)) {
return 'None';
}
if ('subnetId' in effectivePrincipal) {
return {
SubnetId: base64EncodePrincipal(effectivePrincipal.subnetId),
};
}
else {
return {
CanisterId: base64EncodePrincipal(effectivePrincipal.canisterId),
};
}
}
export function decodeEffectivePrincipal(effectivePrincipal) {
if (effectivePrincipal === 'None') {
return null;
}
else if ('SubnetId' in effectivePrincipal) {
return {
subnetId: base64DecodePrincipal(effectivePrincipal.SubnetId),
};
}
else {
return {
canisterId: base64DecodePrincipal(effectivePrincipal.CanisterId),
};
}
}
export function encodeCanisterCallRequest(req) {
return {
sender: base64EncodePrincipal(req.sender),
canister_id: base64EncodePrincipal(req.canisterId),
method: req.method,
payload: base64Encode(req.payload),
effective_principal: encodeEffectivePrincipal(req.effectivePrincipal),
};
}
export function decodeCanisterCallResponse(res) {
const okRes = decodeResultResponse(res);
return {
body: base64Decode(okRes),
};
}
function decodeResultResponse(res) {
if ('Err' in res) {
throw new Error(`Canister call failed: ${res.Err.reject_message}. Reject code: ${res.Err.reject_code}. Error code: ${res.Err.error_code}. Certified: ${res.Err.certified}`);
}
return res.Ok;
}
export function encodeSubmitCanisterCallRequest(req) {
return encodeCanisterCallRequest(req);
}
export function decodeSubmitCanisterCallResponse(res) {
const okRes = decodeResultResponse(res);
return {
effectivePrincipal: decodeEffectivePrincipal(okRes.effective_principal),
messageId: okRes.message_id,
};
}
export function encodeIngressStatusRequest(req) {
return {
raw_message_id: req.messageId,
raw_caller: req.caller ? base64EncodePrincipal(req.caller) : undefined,
};
}
export function decodeIngressStatusResponse(res) {
if (isNil(res)) {
return null;
}
if ('Ok' in res || 'Err' in res) {
return decodeCanisterCallResponse(res);
}
throw new Error(`Unexpected ingress status response ${res}`);
}
export function encodeAwaitCanisterCallRequest(req) {
return {
effective_principal: encodeEffectivePrincipal(req.effectivePrincipal),
message_id: req.messageId,
};
}
//#endregion AwaitCanisterCall
//# sourceMappingURL=pocket-ic-client-types.js.map