Repository: hyperledger/aries-cloudagent-python

Issue:
BUG: Mediation, Multitenant Aca-Py - sub-wallet initiates mediation
Version: 0.8.1

Scenario: Aca-Py in multitenant mode, using mediator that is initiated and managed by the tenant (type 2 - see [multitenancy / mediation](https://github.com/hyperledger/aries-cloudagent-python/blob/main/Multitenancy.md#mediation)).

Issue: Mediation can be granted, but when the tenant attempts to use mediation, the expected routing for the verkey cannot be found. For example, if a tenant creates an invitation using their mediation_id, when the invitation is received the verkey cannot be found and the connection cannot be completed.

```
Traceback (most recent call last):
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/transport/pack_format.py", line 178, in pack
    message = await wallet.pack_message(
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/wallet/askar.py", line 679, in pack_message
    raise WalletNotFoundError("Missing key for pack operation")
aries_cloudagent.wallet.error.WalletNotFoundError: Missing key for pack operation
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/transport/pack_format.py", line 182, in pack
    raise WireFormatEncodeError("Message pack failed") from e
aries_cloudagent.transport.error.WireFormatEncodeError: Message pack failed
2023-05-12 17:49:06,048 aries_cloudagent.transport.outbound.manager ERROR Outbound message could not be delivered to https://1abe-207-6-152-178.ngrok.io
Traceback (most recent call last):
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/transport/pack_format.py", line 178, in pack
    message = await wallet.pack_message(
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/wallet/askar.py", line 679, in pack_message
    raise WalletNotFoundError("Missing key for pack operation")
aries_cloudagent.wallet.error.WalletNotFoundError: Missing key for pack operation
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 258, in __step
    result = coro.throw(exc)
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/transport/outbound/manager.py", line 483, in perform_encode
    queued.payload = await wire_format.encode_message(
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/transport/pack_format.py", line 156, in encode_message
    message = await (self.task_queue and self.task_queue.run(pack) or pack)
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/home/indy/.local/lib/python3.9/site-packages/aries_cloudagent/transport/pack_format.py", line 182, in pack
    raise WireFormatEncodeError("Message pack failed") from e
aries_cloudagent.transport.error.WireFormatEncodeError: Message pack failed
```

If multitenant is using mediation of type 1 (default mediator set up with `--mediator-invitation` and `--mediator-connections-invite`) then mediation works. Mediation also works when agents are in single-tenant mode. This only happens with multitenancy and mediation type 2 configuration.


Discussion:

Resolving patch:
diff --git a/aries_cloudagent/multitenant/route_manager.py b/aries_cloudagent/multitenant/route_manager.py
--- a/aries_cloudagent/multitenant/route_manager.py
+++ b/aries_cloudagent/multitenant/route_manager.py
@@ -81,8 +81,17 @@ async def _route_for_key(
                 keylist_updates = await mediation_mgr.remove_key(
                     replace_key, keylist_updates
                 )
-
-            responder = self.root_profile.inject(BaseResponder)
+            # in order to locate the correct verkey for message packing we need
+            # to use the correct profile.
+            # if we are using default/base mediation then we need
+            # the root_profile to create the responder.
+            # if sub-wallets are configuring their own mediation, then
+            # we need the sub-wallet (profile) to create the responder.
+            responder = (
+                self.root_profile.inject(BaseResponder)
+                if base_mediation_record
+                else profile.inject(BaseResponder)
+            )
             await responder.send(
                 keylist_updates, connection_id=mediation_record.connection_id
             )


Test patch: