query method

  1. @override
Future<QueryResponse> query(
  1. Principal canisterId,
  2. QueryFields options,
  3. Identity? identity
)
override

Send a query call to a canister. See the interface spec. @param canisterId The Principal of the Canister to send the query to. Sending a query to the management canister is not supported (as it has no meaning from an agent). @param options Options to use to create and send the query. @returns The response from the replica. The Promise will only reject when the communication failed. If the query itself failed but no protocol errors happened, the response will be of type QueryResponseRejected.

Implementation

@override
Future<QueryResponse> query(
  Principal canisterId,
  QueryFields options,
  Identity? identity,
) async {
  final canister = canisterId is String
      ? Principal.fromText(canisterId as String)
      : canisterId;
  final id = identity ?? _identity;
  final sender = id?.getPrincipal() ?? Principal.anonymous();

  final requestBody = QueryRequest(
    canisterId: canister,
    methodName: options.methodName,
    arg: options.arg!,
    sender: sender,
    ingressExpiry: Expiry(_defaultIngressExpiryDeltaInMilliseconds),
  );

  final rsRequest = HttpAgentQueryRequest(
    request: {
      'method': 'POST',
      'headers': {'Content-Type': 'application/cbor', ..._baseHeaders},
    },
    body: requestBody,
  );

  final transformedRequest = await _transform(rsRequest);
  final Map<String, dynamic> newTransformed =
      await id!.transformRequest(transformedRequest);

  final body = cbor.cborEncode(newTransformed['body']);

  final response = await withRetry(
    () => _fetch!(
      endpoint: '/api/v2/canister/${canister.toText()}/query',
      method: FetchMethod.post,
      headers: newTransformed['request']['headers'],
      body: body,
    ),
  );

  if (!(response['ok'] as bool)) {
    throw AgentFetchError(
      statusCode: response['statusCode'],
      statusText: response['statusText'],
      body: response['body'],
    );
  }

  final buffer = response['arrayBuffer'] as Uint8List;

  return QueryResponseWithStatus.fromJson(cbor.cborDecode<Map>(buffer));
}