approveSession method

  1. @override
Future<ApproveResponse> approveSession({
  1. required int id,
  2. required Map<String, Namespace> namespaces,
  3. Map<String, String>? sessionProperties,
  4. String? relayProtocol,
})
override

Approves a proposal with the id provided in the parameters. Assumes the proposal is already created.

Implementation

@override
Future<ApproveResponse> approveSession({
  required int id,
  required Map<String, Namespace> namespaces,
  Map<String, String>? sessionProperties,
  String? relayProtocol,
}) async {
  // print('sign approveSession');
  _checkInitialized();
  _confirmOnlineStateOrThrow();

  await _isValidApprove(
    id: id,
    namespaces: namespaces,
    sessionProperties: sessionProperties,
    relayProtocol: relayProtocol,
  );

  final ProposalData proposal = proposals.get(id.toString())!;

  final String selfPubKey = await core.crypto.generateKeyPair();
  final String peerPubKey = proposal.proposer.publicKey;
  final String sessionTopic = await core.crypto.generateSharedKey(
    selfPubKey,
    peerPubKey,
  );
  // print('approve session topic: $sessionTopic');
  final protocol = relayProtocol ?? ReownConstants.RELAYER_DEFAULT_PROTOCOL;
  final relay = Relay(protocol);

  // Respond to the proposal
  final sessionProposalResponse = WcSessionProposeResponse(
    relay: relay,
    responderPublicKey: selfPubKey,
  );
  await _deleteProposal(id);
  await core.pairing.activate(topic: proposal.pairingTopic);

  await core.pairing.updateMetadata(
    topic: proposal.pairingTopic,
    metadata: proposal.proposer.metadata,
  );

  await core.relayClient.subscribe(
    options: SubscribeOptions(topic: sessionTopic, skipSubscribe: true),
  );

  final int expiry = ReownCoreUtils.calculateExpiry(
    ReownConstants.SEVEN_DAYS,
  );

  SessionData session = SessionData(
    topic: sessionTopic,
    pairingTopic: proposal.pairingTopic,
    relay: relay,
    expiry: expiry,
    acknowledged: false,
    controller: selfPubKey,
    namespaces: namespaces,
    self: ConnectionMetadata(publicKey: selfPubKey, metadata: metadata),
    peer: proposal.proposer,
    sessionProperties: proposal.sessionProperties,
    transportType: TransportType.relay,
  );

  onSessionConnect.broadcast(SessionConnect(session));

  await sessions.set(sessionTopic, session);
  await _setSessionExpiry(sessionTopic, expiry);

  // `wc_sessionSettle` is not critical throughout the entire session.
  final sessionSettleRequest = WcSessionSettleRequest(
    relay: relay,
    namespaces: namespaces,
    sessionProperties: sessionProperties,
    expiry: expiry,
    controller: ConnectionMetadata(publicKey: selfPubKey, metadata: metadata),
  );
  bool acknowledged = await core.pairing
      .sendApproveSessionRequest(
        sessionTopic,
        proposal.pairingTopic,
        responseId: proposal.id,
        sessionProposalResponse: sessionProposalResponse.toJson(),
        sessionSettlementRequest: sessionSettleRequest.toJson(),
      )
      .timeout(const Duration(seconds: 60))
      .catchError((_) => false)
      .then((_) => true);

  session = session.copyWith(acknowledged: acknowledged);

  if (acknowledged && sessions.has(sessionTopic)) {
    // We directly update the latest value.
    await sessions.set(sessionTopic, session);
  }

  return ApproveResponse(topic: sessionTopic, session: session);
}