@dfinity/agent
Advanced tools
Comparing version 0.20.0 to 0.20.1
@@ -7,2 +7,3 @@ import { JsonObject } from '@dfinity/candid'; | ||
import { HttpAgentRequest, HttpAgentRequestTransformFn } from './types'; | ||
import { SubnetStatus } from '../../canisterStatus'; | ||
export * from './transforms'; | ||
@@ -89,4 +90,4 @@ export { Nonce, makeNonce } from './types'; | ||
replaceIdentity(identity: Identity): void; | ||
fetchSubnetKeys(canisterId: Principal | string): Promise<any>; | ||
fetchSubnetKeys(canisterId: Principal | string): Promise<SubnetStatus | undefined>; | ||
protected _transform(request: HttpAgentRequest): Promise<HttpAgentRequest>; | ||
} |
@@ -143,3 +143,3 @@ "use strict"; | ||
_HttpAgent_subnetKeys.set(this, new expirableMap_1.ExpirableMap({ | ||
expirationTime: 60 * 60 * 1000, // 1 hour | ||
expirationTime: 5 * 60 * 1000, // 5 minutes | ||
})); | ||
@@ -161,5 +161,5 @@ _HttpAgent_verifyQuerySignatures.set(this, true); | ||
} | ||
const { status, signatures, requestId } = queryResponse; | ||
const { status, signatures = [], requestId } = queryResponse; | ||
const domainSeparator = new TextEncoder().encode('\x0Bic-response'); | ||
signatures === null || signatures === void 0 ? void 0 : signatures.forEach(sig => { | ||
for (const sig of signatures) { | ||
const { timestamp, identity } = sig; | ||
@@ -203,3 +203,3 @@ const nodeId = principal_1.Principal.fromUint8Array(identity).toText(); | ||
throw new certificate_1.CertificateVerificationError(`Invalid signature from replica ${nodeId} signed query.`); | ||
}); | ||
} | ||
return queryResponse; | ||
@@ -428,30 +428,15 @@ }); | ||
}; | ||
const queryPromise = new Promise((resolve, reject) => { | ||
makeQuery() | ||
.then(response => { | ||
resolve(response); | ||
}) | ||
.catch(error => { | ||
reject(error); | ||
}); | ||
}); | ||
const subnetStatusPromise = new Promise((resolve, reject) => { | ||
const getSubnetStatus = async () => { | ||
if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) { | ||
resolve(undefined); | ||
return undefined; | ||
} | ||
const subnetStatus = __classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").get(canisterId.toString()); | ||
if (subnetStatus) { | ||
resolve(subnetStatus); | ||
return subnetStatus; | ||
} | ||
else { | ||
this.fetchSubnetKeys(canisterId) | ||
.then(response => { | ||
resolve(response); | ||
}) | ||
.catch(error => { | ||
reject(error); | ||
}); | ||
} | ||
}); | ||
const [query, subnetStatus] = await Promise.all([queryPromise, subnetStatusPromise]); | ||
await this.fetchSubnetKeys(canisterId.toString()); | ||
return __classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").get(canisterId.toString()); | ||
}; | ||
// Make query and fetch subnet keys in parallel | ||
const [query, subnetStatus] = await Promise.all([makeQuery(), getSubnetStatus()]); | ||
// Skip verification if the user has disabled it | ||
@@ -461,3 +446,16 @@ if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) { | ||
} | ||
return __classPrivateFieldGet(this, _HttpAgent_verifyQueryResponse, "f").call(this, query, subnetStatus); | ||
try { | ||
return __classPrivateFieldGet(this, _HttpAgent_verifyQueryResponse, "f").call(this, query, subnetStatus); | ||
} | ||
catch (_) { | ||
// 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.'); | ||
__classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").delete(canisterId.toString()); | ||
await this.fetchSubnetKeys(canisterId.toString()); | ||
const updatedSubnetStatus = __classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").get(canisterId.toString()); | ||
if (!updatedSubnetStatus) { | ||
throw new certificate_1.CertificateVerificationError('Invalid signature from replica signed query: no matching node key found.'); | ||
} | ||
return __classPrivateFieldGet(this, _HttpAgent_verifyQueryResponse, "f").call(this, query, updatedSubnetStatus); | ||
} | ||
} | ||
@@ -562,4 +560,6 @@ async createReadStateRequest(fields, identity) { | ||
__classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").set(effectiveCanisterId.toText(), subnetResponse); | ||
return subnetResponse; | ||
} | ||
return subnetResponse; | ||
// If the subnet status is not returned, return undefined | ||
return undefined; | ||
} | ||
@@ -566,0 +566,0 @@ _transform(request) { |
@@ -7,2 +7,3 @@ import { JsonObject } from '@dfinity/candid'; | ||
import { HttpAgentRequest, HttpAgentRequestTransformFn } from './types'; | ||
import { SubnetStatus } from '../../canisterStatus'; | ||
export * from './transforms'; | ||
@@ -89,4 +90,4 @@ export { Nonce, makeNonce } from './types'; | ||
replaceIdentity(identity: Identity): void; | ||
fetchSubnetKeys(canisterId: Principal | string): Promise<any>; | ||
fetchSubnetKeys(canisterId: Principal | string): Promise<SubnetStatus | undefined>; | ||
protected _transform(request: HttpAgentRequest): Promise<HttpAgentRequest>; | ||
} |
@@ -112,3 +112,3 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
_HttpAgent_subnetKeys.set(this, new ExpirableMap({ | ||
expirationTime: 60 * 60 * 1000, // 1 hour | ||
expirationTime: 5 * 60 * 1000, // 5 minutes | ||
})); | ||
@@ -130,5 +130,5 @@ _HttpAgent_verifyQuerySignatures.set(this, true); | ||
} | ||
const { status, signatures, requestId } = queryResponse; | ||
const { status, signatures = [], requestId } = queryResponse; | ||
const domainSeparator = new TextEncoder().encode('\x0Bic-response'); | ||
signatures === null || signatures === void 0 ? void 0 : signatures.forEach(sig => { | ||
for (const sig of signatures) { | ||
const { timestamp, identity } = sig; | ||
@@ -172,3 +172,3 @@ const nodeId = Principal.fromUint8Array(identity).toText(); | ||
throw new CertificateVerificationError(`Invalid signature from replica ${nodeId} signed query.`); | ||
}); | ||
} | ||
return queryResponse; | ||
@@ -397,30 +397,15 @@ }); | ||
}; | ||
const queryPromise = new Promise((resolve, reject) => { | ||
makeQuery() | ||
.then(response => { | ||
resolve(response); | ||
}) | ||
.catch(error => { | ||
reject(error); | ||
}); | ||
}); | ||
const subnetStatusPromise = new Promise((resolve, reject) => { | ||
const getSubnetStatus = async () => { | ||
if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) { | ||
resolve(undefined); | ||
return undefined; | ||
} | ||
const subnetStatus = __classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").get(canisterId.toString()); | ||
if (subnetStatus) { | ||
resolve(subnetStatus); | ||
return subnetStatus; | ||
} | ||
else { | ||
this.fetchSubnetKeys(canisterId) | ||
.then(response => { | ||
resolve(response); | ||
}) | ||
.catch(error => { | ||
reject(error); | ||
}); | ||
} | ||
}); | ||
const [query, subnetStatus] = await Promise.all([queryPromise, subnetStatusPromise]); | ||
await this.fetchSubnetKeys(canisterId.toString()); | ||
return __classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").get(canisterId.toString()); | ||
}; | ||
// Make query and fetch subnet keys in parallel | ||
const [query, subnetStatus] = await Promise.all([makeQuery(), getSubnetStatus()]); | ||
// Skip verification if the user has disabled it | ||
@@ -430,3 +415,16 @@ if (!__classPrivateFieldGet(this, _HttpAgent_verifyQuerySignatures, "f")) { | ||
} | ||
return __classPrivateFieldGet(this, _HttpAgent_verifyQueryResponse, "f").call(this, query, subnetStatus); | ||
try { | ||
return __classPrivateFieldGet(this, _HttpAgent_verifyQueryResponse, "f").call(this, query, subnetStatus); | ||
} | ||
catch (_) { | ||
// 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.'); | ||
__classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").delete(canisterId.toString()); | ||
await this.fetchSubnetKeys(canisterId.toString()); | ||
const updatedSubnetStatus = __classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").get(canisterId.toString()); | ||
if (!updatedSubnetStatus) { | ||
throw new CertificateVerificationError('Invalid signature from replica signed query: no matching node key found.'); | ||
} | ||
return __classPrivateFieldGet(this, _HttpAgent_verifyQueryResponse, "f").call(this, query, updatedSubnetStatus); | ||
} | ||
} | ||
@@ -531,4 +529,6 @@ async createReadStateRequest(fields, identity) { | ||
__classPrivateFieldGet(this, _HttpAgent_subnetKeys, "f").set(effectiveCanisterId.toText(), subnetResponse); | ||
return subnetResponse; | ||
} | ||
return subnetResponse; | ||
// If the subnet status is not returned, return undefined | ||
return undefined; | ||
} | ||
@@ -535,0 +535,0 @@ _transform(request) { |
{ | ||
"name": "@dfinity/agent", | ||
"version": "0.20.0", | ||
"version": "0.20.1", | ||
"author": "DFINITY Stiftung <sdk@dfinity.org>", | ||
@@ -50,4 +50,4 @@ "license": "Apache-2.0", | ||
"peerDependencies": { | ||
"@dfinity/candid": "^0.20.0", | ||
"@dfinity/principal": "^0.20.0" | ||
"@dfinity/candid": "^0.20.1", | ||
"@dfinity/principal": "^0.20.1" | ||
}, | ||
@@ -54,0 +54,0 @@ "dependencies": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1264021
9996