Socket
Socket
Sign inDemoInstall

@dfinity/agent

Package Overview
Dependencies
Maintainers
10
Versions
121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dfinity/agent - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

2

lib/cjs/agent/http/index.d.ts

@@ -71,2 +71,3 @@ import { JsonObject } from '@dfinity/candid';

readonly _isAgent = true;
get waterMark(): number;
log: ObservableLog;

@@ -86,2 +87,3 @@ constructor(options?: HttpAgentOptions);

readState(canisterId: Principal | string, fields: ReadStateOptions, identity?: Identity | Promise<Identity>, request?: any): Promise<ReadStateResponse>;
parseTimeFromResponse(response: ReadStateResponse): Promise<number>;
/**

@@ -88,0 +90,0 @@ * Allows agent to sync its time with the network. Can be called during intialization or mid-lifecycle if the device's clock has drifted away from the network time. This is necessary to set the Expiry for a request

@@ -39,3 +39,3 @@ "use strict";

};
var _HttpAgent_queryPipeline, _HttpAgent_updatePipeline, _HttpAgent_subnetKeys, _HttpAgent_verifyQuerySignatures, _HttpAgent_verifyQueryResponse;
var _HttpAgent_instances, _HttpAgent_waterMark, _HttpAgent_queryPipeline, _HttpAgent_updatePipeline, _HttpAgent_subnetKeys, _HttpAgent_verifyQuerySignatures, _HttpAgent_requestAndRetryQuery, _HttpAgent_verifyQueryResponse;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -57,2 +57,3 @@ exports.HttpAgent = exports.IdentityInvalidError = exports.RequestStatusResponseStatus = exports.makeNonce = void 0;

const public_key_1 = require("../../public_key");
const leb_1 = require("../../utils/leb");
const observable_1 = require("../../observable");

@@ -139,2 +140,4 @@ __exportStar(require("./transforms"), exports);

constructor(options = {}) {
var _a;
_HttpAgent_instances.add(this);
this.rootKey = (0, buffer_1.fromHex)(IC_ROOT_KEY);

@@ -144,2 +147,4 @@ this._timeDiffMsecs = 0;

this._isAgent = true;
// The UTC time in milliseconds when the latest request was made
_HttpAgent_waterMark.set(this, 0);
this.log = new observable_1.ObservableLog();

@@ -261,3 +266,3 @@ _HttpAgent_queryPipeline.set(this, []);

this._host = new URL('https://icp-api.io');
console.warn('Could not infer host from window.location, defaulting to mainnet gateway of https://icp-api.io. Please provide a host to the HttpAgent constructor to avoid this warning.');
this.log.warn('Could not infer host from window.location, defaulting to mainnet gateway of https://icp-api.io. Please provide a host to the HttpAgent constructor to avoid this warning.');
}

@@ -268,5 +273,4 @@ }

}
// Default is 3, only set from option if greater or equal to 0
this._retryTimes =
options.retryTimes !== undefined && options.retryTimes >= 0 ? options.retryTimes : 3;
// Default is 3
this._retryTimes = (_a = options.retryTimes) !== null && _a !== void 0 ? _a : 3;
// Rewrite to avoid redirects

@@ -306,2 +310,5 @@ if (this._host.hostname.endsWith(IC0_SUB_DOMAIN)) {

}
get waterMark() {
return __classPrivateFieldGet(this, _HttpAgent_waterMark, "f");
}
isLocal() {

@@ -389,3 +396,3 @@ const hostname = this._host.hostname;

if (this._retryTimes > tries) {
console.warn(`Caught exception while attempting to make request:\n` +
this.log.warn(`Caught exception while attempting to make request:\n` +
` ${error}\n` +

@@ -405,3 +412,3 @@ ` Retrying request.`);

if (this._retryTimes > tries) {
console.warn(errorMessage + ` Retrying request.`);
this.log.warn(errorMessage + ` Retrying request.`);
return await this._requestAndRetry(request, tries + 1);

@@ -417,2 +424,3 @@ }

async query(canisterId, fields, identity) {
this.log(`making query to canister ${canisterId} with fields:`, fields);
const makeQuery = async () => {

@@ -445,12 +453,11 @@ const id = await (identity !== undefined ? await identity : await this._identity);

// Apply transform for identity.
transformedRequest = await (id === null || id === void 0 ? void 0 : id.transformRequest(transformedRequest));
transformedRequest = (await (id === null || id === void 0 ? void 0 : id.transformRequest(transformedRequest)));
const body = cbor.encode(transformedRequest.body);
const response = await this._requestAndRetry(() => this._fetch('' + new URL(`/api/v2/canister/${canister.toText()}/query`, this._host), Object.assign(Object.assign(Object.assign({}, this._fetchOptions), transformedRequest.request), { body })));
const queryResponse = cbor.decode(await response.arrayBuffer());
return Object.assign(Object.assign({}, queryResponse), { httpDetails: {
ok: response.ok,
status: response.status,
statusText: response.statusText,
headers: (0, transforms_1.httpHeadersTransform)(response.headers),
}, requestId });
const args = {
canister: canister.toText(),
transformedRequest,
body,
requestId,
};
return await __classPrivateFieldGet(this, _HttpAgent_instances, "m", _HttpAgent_requestAndRetryQuery).call(this, args);
};

@@ -468,4 +475,7 @@ const getSubnetStatus = async () => {

};
// Attempt to make the query i=retryTimes times
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// Make query and fetch subnet keys in parallel
const [query, subnetStatus] = await Promise.all([makeQuery(), getSubnetStatus()]);
this.log('Query response:', query);
// Skip verification if the user has disabled it

@@ -480,3 +490,3 @@ if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) {

// In case the node signatures have changed, refresh the subnet keys and try again
console.warn('Query response verification failed. Retrying with fresh subnet keys.');
this.log.warn('Query response verification failed. Retrying with fresh subnet keys.');
__classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").delete(canisterId.toString());

@@ -528,4 +538,38 @@ await this.fetchSubnetKeys(canisterId.toString());

}
return cbor.decode(await response.arrayBuffer());
const decodedResponse = cbor.decode(await response.arrayBuffer());
this.log('Read state response:', decodedResponse);
const parsedTime = await this.parseTimeFromResponse(decodedResponse);
if (parsedTime > 0) {
this.log('Read state response time:', parsedTime);
__classPrivateFieldSet(this, _HttpAgent_waterMark, parsedTime, "f");
}
return decodedResponse;
}
async parseTimeFromResponse(response) {
let tree;
if (response.certificate) {
const decoded = cbor.decode(response.certificate);
if (decoded && 'tree' in decoded) {
tree = decoded.tree;
}
else {
throw new Error('Could not decode time from response');
}
const timeLookup = (0, certificate_1.lookup_path)(['time'], tree);
if (!timeLookup) {
throw new Error('Time was not found in the response or was not in its expected format.');
}
if (!(timeLookup instanceof ArrayBuffer) && !ArrayBuffer.isView(timeLookup)) {
throw new Error('Time was not found in the response or was not in its expected format.');
}
const date = (0, leb_1.decodeTime)((0, buffer_1.bufFromBufLike)(timeLookup));
this.log('Time from response:', date);
this.log('Time from response in milliseconds:', Number(date));
return Number(date);
}
else {
this.log.warn('No certificate found in response');
}
return 0;
}
/**

@@ -611,3 +655,56 @@ * Allows agent to sync its time with the network. Can be called during intialization or mid-lifecycle if the device's clock has drifted away from the network time. This is necessary to set the Expiry for a request

exports.HttpAgent = HttpAgent;
_HttpAgent_queryPipeline = new WeakMap(), _HttpAgent_updatePipeline = new WeakMap(), _HttpAgent_subnetKeys = new WeakMap(), _HttpAgent_verifyQuerySignatures = new WeakMap(), _HttpAgent_verifyQueryResponse = new WeakMap();
_HttpAgent_waterMark = new WeakMap(), _HttpAgent_queryPipeline = new WeakMap(), _HttpAgent_updatePipeline = new WeakMap(), _HttpAgent_subnetKeys = new WeakMap(), _HttpAgent_verifyQuerySignatures = new WeakMap(), _HttpAgent_verifyQueryResponse = new WeakMap(), _HttpAgent_instances = new WeakSet(), _HttpAgent_requestAndRetryQuery = async function _HttpAgent_requestAndRetryQuery(args, tries = 0) {
var _a, _b;
const { canister, transformedRequest, body, requestId } = args;
let response;
// Make the request and retry if it throws an error
try {
const fetchResponse = await this._fetch('' + new URL(`/api/v2/canister/${canister}/query`, this._host), Object.assign(Object.assign(Object.assign({}, this._fetchOptions), transformedRequest.request), { body }));
const queryResponse = cbor.decode(await fetchResponse.arrayBuffer());
response = Object.assign(Object.assign({}, queryResponse), { httpDetails: {
ok: fetchResponse.ok,
status: fetchResponse.status,
statusText: fetchResponse.statusText,
headers: (0, transforms_1.httpHeadersTransform)(fetchResponse.headers),
}, requestId });
}
catch (error) {
if (tries < this._retryTimes) {
this.log.warn(`Caught exception while attempting to make query:\n` +
` ${error}\n` +
` Retrying query.`);
return await __classPrivateFieldGet(this, _HttpAgent_instances, "m", _HttpAgent_requestAndRetryQuery).call(this, args, tries + 1);
}
throw error;
}
const timestamp = (_b = (_a = response.signatures) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.timestamp;
// Skip watermark verification if the user has set verifyQuerySignatures to false
if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) {
return response;
}
if (!timestamp) {
throw new Error('Timestamp not found in query response. This suggests a malformed or malicious response.');
}
// Convert the timestamp to milliseconds
const timeStampInMs = Number(BigInt(timestamp) / BigInt(1000000));
this.log('watermark and timestamp', {
waterMark: this.waterMark,
timestamp: timeStampInMs,
});
// If the timestamp is less than the watermark, retry the request up to the retry limit
if (Number(this.waterMark) > timeStampInMs) {
const error = new errors_1.AgentError('Timestamp is below the watermark. Retrying query.');
this.log.error('Timestamp is below', error, {
timestamp,
waterMark: this.waterMark,
});
if (tries < this._retryTimes) {
return await __classPrivateFieldGet(this, _HttpAgent_instances, "m", _HttpAgent_requestAndRetryQuery).call(this, args, tries + 1);
}
{
throw new errors_1.AgentError(`Timestamp failed to pass the watermark after retrying the configured ${this._retryTimes} times. We cannot guarantee the integrity of the response since it could be a replay attack.`);
}
}
return response;
};
//# sourceMappingURL=index.js.map

10

lib/cjs/observable.d.ts
import { AgentError } from './errors';
export declare type ObserveFunction<T> = (data: T) => void;
export declare type ObserveFunction<T> = (data: T, ...rest: unknown[]) => void;
export declare class Observable<T> extends Function {

@@ -9,3 +9,3 @@ #private;

unsubscribe(func: ObserveFunction<T>): void;
notify(data: T): void;
notify(data: T, ...rest: unknown[]): void;
}

@@ -23,5 +23,5 @@ export declare type AgentLog = {

constructor();
log(message: string): void;
warn(message: string): void;
error(message: string, error: AgentError): void;
log(message: string, ...rest: unknown[]): void;
warn(message: string, ...rest: unknown[]): void;
error(message: string, error: AgentError, ...rest: unknown[]): void;
}

@@ -16,3 +16,3 @@ "use strict";

return new Proxy(this, {
apply: (target, _, args) => __classPrivateFieldGet(target, _Observable_instances, "m", _Observable_call).call(target, args[0]),
apply: (target, _, args) => __classPrivateFieldGet(target, _Observable_instances, "m", _Observable_call).call(target, args[0], ...args.slice(1)),
});

@@ -26,9 +26,9 @@ }

}
notify(data) {
this.observers.forEach(observer => observer(data));
notify(data, ...rest) {
this.observers.forEach(observer => observer(data, ...rest));
}
}
exports.Observable = Observable;
_Observable_instances = new WeakSet(), _Observable_call = function _Observable_call(message) {
this.notify(message);
_Observable_instances = new WeakSet(), _Observable_call = function _Observable_call(message, ...rest) {
this.notify(message, ...rest);
};

@@ -40,19 +40,19 @@ class ObservableLog extends Observable {

return new Proxy(this, {
apply: (target, _, args) => __classPrivateFieldGet(target, _ObservableLog_instances, "m", _ObservableLog_call).call(target, args[0]),
apply: (target, _, args) => __classPrivateFieldGet(target, _ObservableLog_instances, "m", _ObservableLog_call).call(target, args[0], ...args.slice(1)),
});
}
log(message) {
this.notify({ message, level: 'info' });
log(message, ...rest) {
this.notify({ message, level: 'info' }, ...rest);
}
warn(message) {
this.notify({ message, level: 'warn' });
warn(message, ...rest) {
this.notify({ message, level: 'warn' }, ...rest);
}
error(message, error) {
this.notify({ message, level: 'error', error });
error(message, error, ...rest) {
this.notify({ message, level: 'error', error }, ...rest);
}
}
exports.ObservableLog = ObservableLog;
_ObservableLog_instances = new WeakSet(), _ObservableLog_call = function _ObservableLog_call(message) {
this.log(message);
_ObservableLog_instances = new WeakSet(), _ObservableLog_call = function _ObservableLog_call(message, ...rest) {
this.log(message, ...rest);
};
//# sourceMappingURL=observable.js.map

@@ -41,2 +41,4 @@ /**

*/
export declare function bufFromBufLike(bufLike: ArrayBuffer | Uint8Array | DataView | ArrayBufferView | ArrayBufferLike): ArrayBuffer;
export declare function bufFromBufLike(bufLike: ArrayBuffer | Uint8Array | DataView | ArrayBufferView | ArrayBufferLike | [number] | {
buffer: ArrayBuffer;
}): ArrayBuffer;

@@ -95,8 +95,11 @@ "use strict";

}
if (Array.isArray(bufLike)) {
return uint8ToBuf(new Uint8Array(bufLike));
}
if ('buffer' in bufLike) {
return bufLike.buffer;
return bufFromBufLike(bufLike.buffer);
}
return new Uint8Array(bufLike);
return uint8ToBuf(new Uint8Array(bufLike));
}
exports.bufFromBufLike = bufFromBufLike;
//# sourceMappingURL=buffer.js.map

@@ -71,2 +71,3 @@ import { JsonObject } from '@dfinity/candid';

readonly _isAgent = true;
get waterMark(): number;
log: ObservableLog;

@@ -86,2 +87,3 @@ constructor(options?: HttpAgentOptions);

readState(canisterId: Principal | string, fields: ReadStateOptions, identity?: Identity | Promise<Identity>, request?: any): Promise<ReadStateResponse>;
parseTimeFromResponse(response: ReadStateResponse): Promise<number>;
/**

@@ -88,0 +90,0 @@ * Allows agent to sync its time with the network. Can be called during intialization or mid-lifecycle if the device's clock has drifted away from the network time. This is necessary to set the Expiry for a request

@@ -12,3 +12,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {

};
var _HttpAgent_queryPipeline, _HttpAgent_updatePipeline, _HttpAgent_subnetKeys, _HttpAgent_verifyQuerySignatures, _HttpAgent_verifyQueryResponse;
var _HttpAgent_instances, _HttpAgent_waterMark, _HttpAgent_queryPipeline, _HttpAgent_updatePipeline, _HttpAgent_subnetKeys, _HttpAgent_verifyQuerySignatures, _HttpAgent_requestAndRetryQuery, _HttpAgent_verifyQueryResponse;
import { Principal } from '@dfinity/principal';

@@ -19,3 +19,3 @@ import { AgentError } from '../../errors';

import { hashOfMap, requestIdOf } from '../../request_id';
import { concat, fromHex } from '../../utils/buffer';
import { bufFromBufLike, concat, fromHex } from '../../utils/buffer';
import { Expiry, httpHeadersTransform, makeNonceTransform } from './transforms';

@@ -25,6 +25,7 @@ import { makeNonce, SubmitRequestType, } from './types';

import { request } from '../../canisterStatus';
import { CertificateVerificationError } from '../../certificate';
import { CertificateVerificationError, lookup_path } from '../../certificate';
import { ed25519 } from '@noble/curves/ed25519';
import { ExpirableMap } from '../../utils/expirableMap';
import { Ed25519PublicKey } from '../../public_key';
import { decodeTime } from '../../utils/leb';
import { ObservableLog } from '../../observable';

@@ -109,2 +110,4 @@ export * from './transforms';

constructor(options = {}) {
var _a;
_HttpAgent_instances.add(this);
this.rootKey = fromHex(IC_ROOT_KEY);

@@ -114,2 +117,4 @@ this._timeDiffMsecs = 0;

this._isAgent = true;
// The UTC time in milliseconds when the latest request was made
_HttpAgent_waterMark.set(this, 0);
this.log = new ObservableLog();

@@ -231,3 +236,3 @@ _HttpAgent_queryPipeline.set(this, []);

this._host = new URL('https://icp-api.io');
console.warn('Could not infer host from window.location, defaulting to mainnet gateway of https://icp-api.io. Please provide a host to the HttpAgent constructor to avoid this warning.');
this.log.warn('Could not infer host from window.location, defaulting to mainnet gateway of https://icp-api.io. Please provide a host to the HttpAgent constructor to avoid this warning.');
}

@@ -238,5 +243,4 @@ }

}
// Default is 3, only set from option if greater or equal to 0
this._retryTimes =
options.retryTimes !== undefined && options.retryTimes >= 0 ? options.retryTimes : 3;
// Default is 3
this._retryTimes = (_a = options.retryTimes) !== null && _a !== void 0 ? _a : 3;
// Rewrite to avoid redirects

@@ -276,2 +280,5 @@ if (this._host.hostname.endsWith(IC0_SUB_DOMAIN)) {

}
get waterMark() {
return __classPrivateFieldGet(this, _HttpAgent_waterMark, "f");
}
isLocal() {

@@ -359,3 +366,3 @@ const hostname = this._host.hostname;

if (this._retryTimes > tries) {
console.warn(`Caught exception while attempting to make request:\n` +
this.log.warn(`Caught exception while attempting to make request:\n` +
` ${error}\n` +

@@ -375,3 +382,3 @@ ` Retrying request.`);

if (this._retryTimes > tries) {
console.warn(errorMessage + ` Retrying request.`);
this.log.warn(errorMessage + ` Retrying request.`);
return await this._requestAndRetry(request, tries + 1);

@@ -387,2 +394,3 @@ }

async query(canisterId, fields, identity) {
this.log(`making query to canister ${canisterId} with fields:`, fields);
const makeQuery = async () => {

@@ -415,12 +423,11 @@ const id = await (identity !== undefined ? await identity : await this._identity);

// Apply transform for identity.
transformedRequest = await (id === null || id === void 0 ? void 0 : id.transformRequest(transformedRequest));
transformedRequest = (await (id === null || id === void 0 ? void 0 : id.transformRequest(transformedRequest)));
const body = cbor.encode(transformedRequest.body);
const response = await this._requestAndRetry(() => this._fetch('' + new URL(`/api/v2/canister/${canister.toText()}/query`, this._host), Object.assign(Object.assign(Object.assign({}, this._fetchOptions), transformedRequest.request), { body })));
const queryResponse = cbor.decode(await response.arrayBuffer());
return Object.assign(Object.assign({}, queryResponse), { httpDetails: {
ok: response.ok,
status: response.status,
statusText: response.statusText,
headers: httpHeadersTransform(response.headers),
}, requestId });
const args = {
canister: canister.toText(),
transformedRequest,
body,
requestId,
};
return await __classPrivateFieldGet(this, _HttpAgent_instances, "m", _HttpAgent_requestAndRetryQuery).call(this, args);
};

@@ -438,4 +445,7 @@ const getSubnetStatus = async () => {

};
// Attempt to make the query i=retryTimes times
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// Make query and fetch subnet keys in parallel
const [query, subnetStatus] = await Promise.all([makeQuery(), getSubnetStatus()]);
this.log('Query response:', query);
// Skip verification if the user has disabled it

@@ -450,3 +460,3 @@ if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) {

// In case the node signatures have changed, refresh the subnet keys and try again
console.warn('Query response verification failed. Retrying with fresh subnet keys.');
this.log.warn('Query response verification failed. Retrying with fresh subnet keys.');
__classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").delete(canisterId.toString());

@@ -498,4 +508,38 @@ await this.fetchSubnetKeys(canisterId.toString());

}
return cbor.decode(await response.arrayBuffer());
const decodedResponse = cbor.decode(await response.arrayBuffer());
this.log('Read state response:', decodedResponse);
const parsedTime = await this.parseTimeFromResponse(decodedResponse);
if (parsedTime > 0) {
this.log('Read state response time:', parsedTime);
__classPrivateFieldSet(this, _HttpAgent_waterMark, parsedTime, "f");
}
return decodedResponse;
}
async parseTimeFromResponse(response) {
let tree;
if (response.certificate) {
const decoded = cbor.decode(response.certificate);
if (decoded && 'tree' in decoded) {
tree = decoded.tree;
}
else {
throw new Error('Could not decode time from response');
}
const timeLookup = lookup_path(['time'], tree);
if (!timeLookup) {
throw new Error('Time was not found in the response or was not in its expected format.');
}
if (!(timeLookup instanceof ArrayBuffer) && !ArrayBuffer.isView(timeLookup)) {
throw new Error('Time was not found in the response or was not in its expected format.');
}
const date = decodeTime(bufFromBufLike(timeLookup));
this.log('Time from response:', date);
this.log('Time from response in milliseconds:', Number(date));
return Number(date);
}
else {
this.log.warn('No certificate found in response');
}
return 0;
}
/**

@@ -580,3 +624,56 @@ * Allows agent to sync its time with the network. Can be called during intialization or mid-lifecycle if the device's clock has drifted away from the network time. This is necessary to set the Expiry for a request

}
_HttpAgent_queryPipeline = new WeakMap(), _HttpAgent_updatePipeline = new WeakMap(), _HttpAgent_subnetKeys = new WeakMap(), _HttpAgent_verifyQuerySignatures = new WeakMap(), _HttpAgent_verifyQueryResponse = new WeakMap();
_HttpAgent_waterMark = new WeakMap(), _HttpAgent_queryPipeline = new WeakMap(), _HttpAgent_updatePipeline = new WeakMap(), _HttpAgent_subnetKeys = new WeakMap(), _HttpAgent_verifyQuerySignatures = new WeakMap(), _HttpAgent_verifyQueryResponse = new WeakMap(), _HttpAgent_instances = new WeakSet(), _HttpAgent_requestAndRetryQuery = async function _HttpAgent_requestAndRetryQuery(args, tries = 0) {
var _a, _b;
const { canister, transformedRequest, body, requestId } = args;
let response;
// Make the request and retry if it throws an error
try {
const fetchResponse = await this._fetch('' + new URL(`/api/v2/canister/${canister}/query`, this._host), Object.assign(Object.assign(Object.assign({}, this._fetchOptions), transformedRequest.request), { body }));
const queryResponse = cbor.decode(await fetchResponse.arrayBuffer());
response = Object.assign(Object.assign({}, queryResponse), { httpDetails: {
ok: fetchResponse.ok,
status: fetchResponse.status,
statusText: fetchResponse.statusText,
headers: httpHeadersTransform(fetchResponse.headers),
}, requestId });
}
catch (error) {
if (tries < this._retryTimes) {
this.log.warn(`Caught exception while attempting to make query:\n` +
` ${error}\n` +
` Retrying query.`);
return await __classPrivateFieldGet(this, _HttpAgent_instances, "m", _HttpAgent_requestAndRetryQuery).call(this, args, tries + 1);
}
throw error;
}
const timestamp = (_b = (_a = response.signatures) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.timestamp;
// Skip watermark verification if the user has set verifyQuerySignatures to false
if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) {
return response;
}
if (!timestamp) {
throw new Error('Timestamp not found in query response. This suggests a malformed or malicious response.');
}
// Convert the timestamp to milliseconds
const timeStampInMs = Number(BigInt(timestamp) / BigInt(1000000));
this.log('watermark and timestamp', {
waterMark: this.waterMark,
timestamp: timeStampInMs,
});
// If the timestamp is less than the watermark, retry the request up to the retry limit
if (Number(this.waterMark) > timeStampInMs) {
const error = new AgentError('Timestamp is below the watermark. Retrying query.');
this.log.error('Timestamp is below', error, {
timestamp,
waterMark: this.waterMark,
});
if (tries < this._retryTimes) {
return await __classPrivateFieldGet(this, _HttpAgent_instances, "m", _HttpAgent_requestAndRetryQuery).call(this, args, tries + 1);
}
{
throw new AgentError(`Timestamp failed to pass the watermark after retrying the configured ${this._retryTimes} times. We cannot guarantee the integrity of the response since it could be a replay attack.`);
}
}
return response;
};
//# sourceMappingURL=index.js.map
import { AgentError } from './errors';
export declare type ObserveFunction<T> = (data: T) => void;
export declare type ObserveFunction<T> = (data: T, ...rest: unknown[]) => void;
export declare class Observable<T> extends Function {

@@ -9,3 +9,3 @@ #private;

unsubscribe(func: ObserveFunction<T>): void;
notify(data: T): void;
notify(data: T, ...rest: unknown[]): void;
}

@@ -23,5 +23,5 @@ export declare type AgentLog = {

constructor();
log(message: string): void;
warn(message: string): void;
error(message: string, error: AgentError): void;
log(message: string, ...rest: unknown[]): void;
warn(message: string, ...rest: unknown[]): void;
error(message: string, error: AgentError, ...rest: unknown[]): void;
}

@@ -13,3 +13,3 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {

return new Proxy(this, {
apply: (target, _, args) => __classPrivateFieldGet(target, _Observable_instances, "m", _Observable_call).call(target, args[0]),
apply: (target, _, args) => __classPrivateFieldGet(target, _Observable_instances, "m", _Observable_call).call(target, args[0], ...args.slice(1)),
});

@@ -23,8 +23,8 @@ }

}
notify(data) {
this.observers.forEach(observer => observer(data));
notify(data, ...rest) {
this.observers.forEach(observer => observer(data, ...rest));
}
}
_Observable_instances = new WeakSet(), _Observable_call = function _Observable_call(message) {
this.notify(message);
_Observable_instances = new WeakSet(), _Observable_call = function _Observable_call(message, ...rest) {
this.notify(message, ...rest);
};

@@ -36,18 +36,18 @@ export class ObservableLog extends Observable {

return new Proxy(this, {
apply: (target, _, args) => __classPrivateFieldGet(target, _ObservableLog_instances, "m", _ObservableLog_call).call(target, args[0]),
apply: (target, _, args) => __classPrivateFieldGet(target, _ObservableLog_instances, "m", _ObservableLog_call).call(target, args[0], ...args.slice(1)),
});
}
log(message) {
this.notify({ message, level: 'info' });
log(message, ...rest) {
this.notify({ message, level: 'info' }, ...rest);
}
warn(message) {
this.notify({ message, level: 'warn' });
warn(message, ...rest) {
this.notify({ message, level: 'warn' }, ...rest);
}
error(message, error) {
this.notify({ message, level: 'error', error });
error(message, error, ...rest) {
this.notify({ message, level: 'error', error }, ...rest);
}
}
_ObservableLog_instances = new WeakSet(), _ObservableLog_call = function _ObservableLog_call(message) {
this.log(message);
_ObservableLog_instances = new WeakSet(), _ObservableLog_call = function _ObservableLog_call(message, ...rest) {
this.log(message, ...rest);
};
//# sourceMappingURL=observable.js.map

@@ -41,2 +41,4 @@ /**

*/
export declare function bufFromBufLike(bufLike: ArrayBuffer | Uint8Array | DataView | ArrayBufferView | ArrayBufferLike): ArrayBuffer;
export declare function bufFromBufLike(bufLike: ArrayBuffer | Uint8Array | DataView | ArrayBufferView | ArrayBufferLike | [number] | {
buffer: ArrayBuffer;
}): ArrayBuffer;

@@ -86,7 +86,10 @@ /**

}
if (Array.isArray(bufLike)) {
return uint8ToBuf(new Uint8Array(bufLike));
}
if ('buffer' in bufLike) {
return bufLike.buffer;
return bufFromBufLike(bufLike.buffer);
}
return new Uint8Array(bufLike);
return uint8ToBuf(new Uint8Array(bufLike));
}
//# sourceMappingURL=buffer.js.map
{
"name": "@dfinity/agent",
"version": "1.0.1",
"version": "1.1.0",
"author": "DFINITY Stiftung <sdk@dfinity.org>",

@@ -45,3 +45,3 @@ "license": "Apache-2.0",

"lint": "npm run eslint",
"make:docs/reference": "typedoc src/index.ts --out ../../docs/generated/agent --excludeInternal",
"make:docs/reference": "typedoc src/index.ts --out ../../docs/agent --excludeInternal",
"test": "jest",

@@ -51,4 +51,4 @@ "test:coverage": "jest --collectCoverage"

"peerDependencies": {
"@dfinity/candid": "^1.0.1",
"@dfinity/principal": "^1.0.1"
"@dfinity/candid": "^1.1.0",
"@dfinity/principal": "^1.1.0"
},

@@ -55,0 +55,0 @@ "dependencies": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc