approveSessionAuthenticate method
Implementation
@override
Future<ApproveResponse> approveSessionAuthenticate({
required int id,
List<Cacao>? auths,
}) async {
_checkInitialized();
final pendingSessionAuthRequests = getPendingSessionAuthRequests();
if (!pendingSessionAuthRequests.containsKey(id)) {
throw Errors.getInternalError(
Errors.MISSING_OR_INVALID,
context: 'approveSessionAuthenticate() '
'Could not find pending auth request with id $id',
);
}
AuthApiValidators.isValidRespondAuthenticate(
id: id,
pendingRequests: pendingSessionAuthRequests,
auths: auths,
);
final pendingRequest = pendingSessionAuthRequests[id]!;
if (!pendingRequest.transportType.isLinkMode) {
_confirmOnlineStateOrThrow();
}
final receiverPublicKey = pendingRequest.requester.publicKey;
final senderPublicKey = await core.crypto.generateKeyPair();
final responseTopic = core.crypto.getUtils().hashKey(receiverPublicKey);
final encodeOpts = EncodeOptions(
type: EncodeOptions.TYPE_1,
receiverPublicKey: receiverPublicKey,
senderPublicKey: senderPublicKey,
);
final approvedMethods = <String>{};
final approvedAccounts = <String>{};
for (final Cacao cacao in auths!) {
final isValid = await validateSignedCacao(
cacao: cacao,
projectId: core.projectId,
);
if (!isValid) {
final error = Errors.getSdkError(
Errors.SIGNATURE_VERIFICATION_FAILED,
context: 'Signature verification failed',
);
await core.pairing.sendError(
id,
responseTopic,
MethodConstants.WC_SESSION_AUTHENTICATE,
JsonRpcError(code: error.code, message: error.message),
encodeOptions: encodeOpts,
);
throw error;
}
final CacaoPayload payload = cacao.p;
final chainId = AddressUtils.getDidChainId(payload.iss);
final approvedChains = ['eip155:$chainId'];
final recap = ReCapsUtils.getRecapFromResources(
resources: payload.resources,
);
if (recap != null) {
final methodsfromRecap = ReCapsUtils.getMethodsFromRecap(recap);
final chainsFromRecap = ReCapsUtils.getChainsFromRecap(recap);
approvedMethods.addAll(methodsfromRecap);
approvedChains.addAll(chainsFromRecap);
}
final parsedAddress = AddressUtils.getDidAddress(payload.iss);
for (var chain in approvedChains.toSet()) {
approvedAccounts.add('$chain:${parsedAddress.toEIP55()}');
}
}
final sessionTopic = await core.crypto.generateSharedKey(
senderPublicKey,
receiverPublicKey,
);
SessionData? session;
if (approvedMethods.isNotEmpty) {
session = SessionData(
topic: sessionTopic,
acknowledged: true,
self: ConnectionMetadata(
publicKey: senderPublicKey,
metadata: metadata,
),
peer: pendingRequest.requester,
controller: receiverPublicKey,
expiry: WalletConnectUtils.calculateExpiry(
WalletConnectConstants.SEVEN_DAYS,
),
relay: Relay(WalletConnectConstants.RELAYER_DEFAULT_PROTOCOL),
pairingTopic: pendingRequest.pairingTopic,
namespaces: NamespaceUtils.buildNamespacesFromAuth(
accounts: approvedAccounts,
methods: approvedMethods,
),
authentication: auths,
transportType: pendingRequest.transportType,
);
await core.relayClient.subscribe(topic: sessionTopic);
await sessions.set(sessionTopic, session);
await core.pairing.updateMetadata(
topic: pendingRequest.pairingTopic,
metadata: pendingRequest.requester.metadata,
);
}
await sessionAuthRequests.delete(id.toString());
await core.pairing.activate(topic: pendingRequest.pairingTopic);
final result = WcSessionAuthRequestResult(
cacaos: auths,
responder: ConnectionMetadata(
publicKey: senderPublicKey,
metadata: metadata,
),
);
await core.pairing.sendResult(
id,
responseTopic,
MethodConstants.WC_SESSION_AUTHENTICATE,
result.toJson(),
encodeOptions: encodeOpts,
appLink: _getAppLinkIfEnabled(pendingRequest.requester.metadata),
);
return ApproveResponse(
topic: sessionTopic,
session: session,
);
}