decryptPayload method

Future<Map<String, dynamic>> decryptPayload(
  1. Map<String, String> params
)

Decrypts the data payload returned by Phantom Wallet

Implementation

Future<Map<String, dynamic>> decryptPayload(
  Map<String, String> params,
) async {
  if (params.containsKey('errorCode')) {
    return params;
  }

  final phantomRequest = params['phantomRequest'] ?? '';
  // phantom_encryption_public_key is Phantom publicKey (not solana Address)
  final phantomKey = params['phantom_encryption_public_key'] ?? '';
  _core.logger.d('[$runtimeType] phantom_encryption_public_key $phantomKey');

  if (phantomRequest == 'connect') {
    // executed only once after successful /connect
    _phantomPublicKey = phantomKey;
    await _createSharedSecret();
  }

  if (phantomRequest == 'disconnect') {
    return <String, dynamic>{'phantomRequest': phantomRequest};
  }

  try {
    final data = params['data']!;
    final nonce = params['nonce']!;
    final decryptedData = _sharedSecretBox?.decrypt(
      pncl.ByteList(base58.decode(data)),
      nonce: Uint8List.fromList(base58.decode(nonce)),
    );

    final payload = <String, dynamic>{
      ...JsonDecoder().convert(String.fromCharCodes(
        decryptedData!,
      )),
      if (phantomKey.isNotEmpty) 'phantom_encryption_public_key': phantomKey,
      if (phantomRequest.isNotEmpty) 'phantomRequest': phantomRequest,
    };

    _sessionToken = payload['session'] ?? _sessionToken;

    return payload;
  } catch (e) {
    final queryParams = Uri.parse(phantomRequest).queryParameters;
    if (queryParams.containsKey('errorCode')) {
      final errorCode = queryParams['errorCode'];
      final errorMessage = params['errorMessage'];
      return {
        'errorCode': errorCode,
        'errorMessage': errorMessage,
      };
    } else {
      return Errors.getInternalError(
        Errors.MISSING_OR_INVALID,
        context: e.toString(),
      ).toJson();
    }
  }
}