diff --git a/exchange.py b/exchange.py
index 3a92a4cdc4b90024243f33465dd4ee074d481941..58b747e9ca0849cccd7f3323480598ed5053cc44 100644
--- a/exchange.py
+++ b/exchange.py
@@ -1,22 +1,25 @@
-#from participant import ureg, Q_
+from pint import UnitRegistry
 import time
 from datetime import datetime, timedelta
 
 
-class Trade:
-    pass
-
-
 class Exchange:
-    def __init__(self, pk: bytes, p: float, ppw: float):
+    def __init__(self, pk: bytes, p: float, ppw: float, extime: datetime):
+        self.ureg = None
+        self.Q_ = None
         self.pubicKey: bytes = pk
         self.timestamp: int = time.time_ns()
+        self.executiontime: datetime = extime
         self.__isActive: bool = False
-        self.power = Q_(p, ureg.watt)
-        self.__pricePerWatt = ppw  # this is in EUR, no new cryptocurrency should be created for this
-        self.__trades: set[Trade] = set()
+        self.power = p
+        self.pricePerWatt = ppw  # this is in EUR, no new cryptocurrency should be created for this
         self.__sig: bytes
 
+    def set_ureg(self, ureg: UnitRegistry) -> None:
+        self.ureg = ureg
+        self.Q_ = ureg.Quantity
+        self.power = self.Q_(self.power, ureg.watt)
+
     def activate(self) -> None:
         self.__isActive = True
 
@@ -34,7 +37,7 @@ class Exchange:
         end_of_minute = start_of_minute + timedelta(seconds=59)
         end_of_minute_unix = int(end_of_minute.timestamp())
 
-        if start_of_minute_unix <= self.timestamp <= end_of_minute_unix:
+        if start_of_minute_unix <= self.executiontime.timestamp() <= end_of_minute_unix:
             return True
         else:
             return False
@@ -51,11 +54,11 @@ class Exchange:
         end_of_minute = start_of_minute + timedelta(seconds=59)
         end_of_minute_unix = int(end_of_minute.timestamp())
 
-        if start_of_minute_unix <= self.timestamp <= end_of_minute_unix:
+        if start_of_minute_unix <= self.executiontime.timestamp() <= end_of_minute_unix:
             return True
         else:
             return False
 
     def is_old(self) -> bool:
         now = datetime.now()
-        return self.timestamp < int(now.timestamp())
+        return self.executiontime.timestamp() < int(now.timestamp())
diff --git a/line.py b/line.py
index aaf9bddfa9ec3463aefad7554466692d2b18795d..c0fa8e4f0449004710f2d463bb18e54d7fbd2179 100644
--- a/line.py
+++ b/line.py
@@ -16,7 +16,7 @@ import logging
 from connection import Connection
 from remotetransformer import RemoteTransformer
 from remoteparticipant import RemoteParticipant
-from remoteline import RemoteLine
+from remoteline import RemoteLine, SignedRemoteLine
 
 logger = logging.getLogger(__name__)
 
@@ -25,8 +25,10 @@ class Line(Connection):
     def __init__(self, cap: float, conips: set[ipaddress.IPv4Address], sched: AsyncIOScheduler):
         super().__init__(cap, conips, sched)
         self.adjacentConnections: set[RemoteTransformer | RemoteParticipant] = set()
+        self.lastSignedLine: dict[datetime.datetime, SignedRemoteLine] = dict()
         # adding fastapi endpoints
         self.fastRouter.add_api_route("/asRemoteJSON", self.asRemoteLineJSON, methods=["GET"])
+        self.fastRouter.add_api_route("/sign/{time}", self.sign, methods=["POST"])
         # setting up scheduling
         run_date = datetime.datetime.now() + datetime.timedelta(hours=1,
                                                                 seconds=5)  # +1 hour because timezones suck hard
@@ -47,6 +49,29 @@ class Line(Connection):
                                     self.usedCapacity, self.adjacentConnections, self.loss)
         return jsonpickle.encode(rl)
 
+    async def sign(self, time: datetime.datetime, rljson):
+        rl = jsonpickle.decode(rljson)
+        if rl.publicKey == self.publicKey:  # check if the rl actually is me
+            time = time.replace(second=0, microsecond=0)  # we are scheduling in minute intervals
+            if time not in self.lastSignedLine.keys():
+                origin = SignedRemoteLine(
+                    RemoteLine(self.publicIP, self.publicKey, self.availableCapacity,
+                               self.usedCapacity, self.adjacentConnections, self.loss), None)
+                origin.isOrigin = True
+                origin.signature = self.dil.sign_with_input(self.__secretKey, origin.__str__())
+                result = SignedRemoteLine(rl, origin)
+                result.signature = self.dil.sign_with_input(self.__secretKey, result.__str__())
+                self.lastSignedLine[time] = result
+                return jsonpickle.encode(result)
+            else:
+                # if there has been a route announced before, add the previous to the new one
+                result = SignedRemoteLine(rl, self.lastSignedLine[time])
+                result.signature = self.dil.sign_with_input(self.__secretKey, result.__str__())
+                self.lastSignedLine[time] = result
+                return jsonpickle.encode(result)
+        else:
+            return "Unauthorized"  # better handling here would be nice
+
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description='Connection service')
diff --git a/main.py b/main.py
index 4f65d7774206b80ec14dffcb7c14e33e43978d9a..c8d3eef9466271ef1a2a79302fb79a2fcd71c3de 100644
--- a/main.py
+++ b/main.py
@@ -27,10 +27,10 @@ import participant
 import DHTdummy
 
 import rustworkx as rx
+from rustworkx.visit import DijkstraVisitor
 import matplotlib.pyplot as plt
 from rustworkx.visualization import mpl_draw
 
-
 ureg = UnitRegistry()
 Q_ = ureg.Quantity
 
@@ -52,6 +52,36 @@ def get_ip():
     return IP
 
 
+class CustomDijkstraVisitor(DijkstraVisitor):
+    def __init__(self):
+        super().__init__()
+        self.examined_edges = set()
+
+    def discover_vertex(self, vertex, distance):
+        print(f"Discovered vertex: {vertex} with distance: {distance}")
+
+    def examine_edge(self, edge):
+        for e in self.examined_edges:
+            if edge[0] == e[1] and edge[1] == e[0]:
+                print(f"Edge already examined: {edge}")
+                return
+
+        print(f"Examining edge: {edge}")
+        self.examined_edges.add(edge)
+
+
+# Create a new graph
+graph = rx.PyGraph()
+graph.add_nodes_from([0, 1, 2, 3])
+graph.add_edges_from([(0, 1, 1.0), (1, 2, 2.0), (2, 3, 1.0)])
+
+# Create an instance of the custom visitor
+visitor = CustomDijkstraVisitor()
+
+# Perform Dijkstra's search
+rx.dijkstra_search(graph, [0], lambda _: 1.0, visitor)
+
+'''
 class GraphNode:
     def __init__(self, value):
         self.index = None
@@ -87,11 +117,20 @@ for edge in graph.edges():
     print(edge)
 
 plt.clf()
-mpl_draw(graph, with_labels=True)
+mpl_draw(graph, with_labels=True, edge_labels=str, labels=str)
+path = rx.dijkstra_shortest_paths(graph, 3, 5, lambda e: e.value)
 length = rx.dijkstra_shortest_path_lengths(graph, 2, lambda e: e.value, 6)
 print(length)
 
 plt.show()
+
+route = graph.subgraph(path[5])
+
+plt.clf()
+mpl_draw(route, with_labels=True, edge_labels=str, labels=str)
+plt.show()
+'''
+
 # --------------- Examples -----------------------
 
 
diff --git a/offer.py b/offer.py
index 8cd5d55c38fc6ad3daad6c92c77558b8e42df832..5fc8f302935204a1dd7d8318dfda8e91ba3a3609 100644
--- a/offer.py
+++ b/offer.py
@@ -1,6 +1,7 @@
 import exchange
+from datetime import datetime
 
 
 class Offer(exchange.Exchange):
-    def __init__(self, pk: bytes, p: float, ppw: float):
-        exchange.Exchange.__init__(self, pk, p, ppw)
+    def __init__(self, pk: bytes, p: float, ppw: float, extime: datetime):
+        exchange.Exchange.__init__(self, pk, p, ppw, extime)
diff --git a/participant.py b/participant.py
index 3b9a8ad2e8101bc9faaf9ae071702757fb4db0ef..e032d1c9572dc5ade7f396938633abd2e0981038 100644
--- a/participant.py
+++ b/participant.py
@@ -14,6 +14,7 @@ import argparse
 
 import rustworkx as rx
 from rustworkx.visualization import mpl_draw
+from rustworkx.visit import DijkstraVisitor
 import base64
 from io import BytesIO
 from fastapi.responses import HTMLResponse
@@ -27,8 +28,9 @@ from apscheduler.schedulers.asyncio import AsyncIOScheduler
 from dilithium import Dilithium
 import dilithium.dilithium
 import numpy
-from util import get_pub_ip
+from util import get_pub_ip, next_minute
 
+from route import Route
 from offer import Offer
 from request import Request
 from exchange import Exchange
@@ -101,7 +103,7 @@ class Participant:
         # set up scheduling for tasks
         self.scheduler.add_job(self.request_remoteparticipants, 'interval', seconds=15, id='1',
                                name='requestRemoteParticipants')
-        self.scheduler.add_job(self.updateCurrentPower, 'interval', seconds=2, id='2', name='updateCurrentPower')
+        self.scheduler.add_job(self.updateCurrentPower, 'interval', seconds=5, id='2', name='updateCurrentPower')
 
         logger.info("~~~>Finished setup on " + self.publicIP.__str__())
 
@@ -140,14 +142,17 @@ class Participant:
         all_remoteparticipants.update(self.remoteParticipants)
         return jsonpickle.encode(all_remoteparticipants)
 
-    def update_remoteparticipants(self, new_rps: set[RemoteParticipant], target_rps: set[RemoteParticipant]):
+    def update_remoteparticipants(self, new_rps: set[RemoteParticipant]):
         for new_rp in new_rps:
-            for rp in target_rps:
-                if new_rp == rp:  # found same participant
-                    rp.update_nextExchanges(new_rp.availableExchanges)
-                    rp.timestamp = new_rp.timestamp
-                else:  # participant is new
-                    target_rps.add(new_rp)
+            if new_rp == self.as_remote_participant():  # found self
+                continue
+            if new_rp in self.remoteParticipants:  # found same participant
+                for rp in self.remoteParticipants:
+                    if rp == new_rp:
+                        rp.update_nextExchanges(new_rp.availableExchanges)
+                        rp.timestamp = new_rp.timestamp
+            else:  # participant is new
+                self.remoteParticipants.add(new_rp)
 
     async def calc_distance(self, gridnodeindex: int) -> float:
         distdict = rx.dijkstra_shortest_path_lengths(self.grid, gridnodeindex, lambda l: l.loss,
@@ -176,7 +181,7 @@ class Participant:
                                 self.gridEdgeIndexes[rline.publicKey].add(i_edge)
                                 # this is actually stupid, when the distance changes based on the load of the line
                                 # we have to calculate this a when matching exchanges
-                                # but as a first step to get an order in which to contact participants this is fine
+                                # but as a first step to get an order in which to contact to participants, this is fine
                                 await self.add_distance_to_participants(rp.publicKey, await self.calc_distance(i))
                                 break
 
@@ -209,7 +214,7 @@ class Participant:
                     logger.error("httpx Error: " + err.__str__())
                     continue
 
-        self.update_remoteparticipants(all_remoteparticipants, self.remoteParticipants)
+        self.update_remoteparticipants(all_remoteparticipants)
         await self.insert_participants_into_grid(all_remoteparticipants)
 
     async def get_knownIPs(self):
@@ -293,39 +298,89 @@ class Participant:
         for t in self.ExchangeQueue:  # only produce a new exchange if there is no exchange for the next minute
             if t.is_min_next():
                 ex_next_min = True
-                break
 
         if power > Q_(0, ureg.watt) and not ex_next_min:
             # more energy will be available than needed, so we can create an offer
-            o = Offer(self.publicKey, power, 0.3)  # price should be dynamic, no time :D
+            # for now all offers will be at the same price, in a real world scenario this would be dynamic
+            # additionally, all offers will be for the next minute, when the system is able to take variable
+            # consumers (e.g. electric cars and heat pumps) into account, this can be adapted to request
+            # bigger amounts of energy in a foreseeable fashion
+            o = Offer(self.publicKey, power, 0.3, next_minute())  # price should be dynamic, no time :D
             self.ExchangeQueue.append(o)
             logger.info("===> created offer on " + self.publicIP.__str__())
         else:
             if power < Q_(0, ureg.watt) and not ex_next_min:
                 # more energy is needed than available, so we create a request
-                r = Request(self.publicKey, power, 0.3)
+                # for now all requests will be at the same price, in a real world scenario this would be dynamic
+                # additionally, all requests will be for the next minute, when the system is able to take variable
+                # consumers (e.g. electric cars and heat pumps) into account, this can be adapted to request
+                # bigger amounts of energy in a foreseeable fashion
+                r = Request(self.publicKey, power, 0.3, next_minute())
                 self.ExchangeQueue.append(r)
                 logger.info("===> created request on " + self.publicIP.__str__())
 
+    async def findRoute(self, start: RemoteParticipant, end: RemoteParticipant) -> Route:
+        s = self.gridNodeIndexes[start.publicKey]
+        e = self.gridNodeIndexes[end.publicKey]
+        path = rx.dijkstra_shortest_paths(self.grid, s, e, lambda l: l.loss)
+        routeloss = rx.dijkstra_shortest_path_lengths(self.grid, s, lambda l: l.loss, e)
+        graph = self.grid.subgraph(path[e])
+        return Route(start, end, graph, routeloss)
+
+    async def announceRoute(self, t: Trade):
+        class GridVisitor(DijkstraVisitor):
+            def __init__(self, trade: Trade):
+                super().__init__()
+                self.examined_edges = set()
+                self.trade: Trade = trade
+
+            def discover_vertex(self, vertex, distance):
+                logger.info(f"Discovered Trafo: {vertex}")
+
+
+            def examine_edge(self, edge):
+                for e in self.examined_edges:
+                    if edge[0] == e[1] and edge[1] == e[0]:
+                        logger.info(f"Line already examined: {edge}")
+                        return
+
+                logger.info(f"Examining Line: {edge}")
+                self.examined_edges.add(edge)
+
+        visitor = GridVisitor(t)
+        # walk the route and announce the route to all grid elements involved
+        rx.dijkstra_search(t.route.graph, [self.gridNodeIndexes[t.route.start.publicKey]], lambda _: 1.0, visitor)
+
     async def findOffer(self, discarded_rps=frozenset()):
         closest = self.as_remote_participant()  # this is just to have a rp to compare to
         for rp in self.remoteParticipants:
             if rp.distance < closest.distance and rp not in discarded_rps:
+                logger.info("===> found closer participant: " + rp.publicIP.__str__())
                 closest = rp
 
         if closest != self.as_remote_participant():  # check if there is actually someone
             async with httpx.AsyncClient() as client:
                 response = await client.get("http://" + closest.publicIP.__str__() + ":8000/getOffersJSON")
-                offers = jsonpickle.decode(response.json())
+                offers: list[Offer] = jsonpickle.decode(response.json())
                 for o in offers:
+                    o.set_ureg(ureg)  # update the ureg of the offer for pint to work
                     if o.is_min_next():  # once again, only trying to find an offer for the next minute
-                        # TODO: now check if power is sufficient, for this solve pint ureg issue
-                        logger.info("===> found offer on " + closest.publicIP.__str__())
-
-
-
+                        if o.power >= self.ExchangeQueue[0].power:
+                            # the offer is big enough to fulfill the request
+                            # now find the route to the offering participant
+                            r = await self.findRoute(self.as_remote_participant(), closest)
+                            logger.info("===> found route to " + closest.publicIP.__str__())
+                            # create a trade, include offer and request, use power from request since we ensured that
+                            # the offer is big enough, use price from offer as this is the price that will be paid
+                            # and again, only trades for the next minute are possible at this point
+                            t = Trade(o, self.ExchangeQueue[0], self.ExchangeQueue[0].power, o.pricePerWatt, r,
+                                      next_minute())
+                            t.set_ureg(ureg)
+                            # now announce the route to all connections involved
+                            await self.announceRoute(t)
 
 
+                        logger.info("===> found offer on " + closest.publicIP.__str__())
         else:
             logger.info("===> no one to trade with on " + self.publicIP.__str__())
             return
@@ -339,14 +394,16 @@ class Participant:
         self.__availablePower = self.currentInHouseSupply - self.__currentInHouseDemand
         # simulate some random fluctuations
         self.__currentInHouseDemand = self.__currentInHouseDemand + Q_(uniform(-0.1, 0.1), ureg.watt)
-        t = Q_(2, ureg.second)  # this is run every 2 seconds
+        t = Q_(5, ureg.second)  # this is run every 5 seconds
         t.ito(ureg.hour)
         self.__energyOffset += self.__availablePower * t
         logger.info(">>>> available power: " + self.__availablePower.__str__() + " and energy offset " +
                     self.__energyOffset.__str__() + " on " + self.publicIP.__str__())
         await self.produceNextTrade()
-        if isinstance(self.ExchangeQueue[0], Request):  # see if there is a request for power in front of the queue
-            await self.findOffer()
+        if len(self.ExchangeQueue) > 0:
+            if isinstance(self.ExchangeQueue[0], Request):  # see if there is a request for power in front of the queue
+                logger.info("===> trying to find an offer on " + self.publicIP.__str__())
+                await self.findOffer()
 
 
 class Weather:
@@ -358,7 +415,7 @@ class Weather:
         self.participant = p
         self.scheduler = schd
 
-        run_date = datetime.now() + timedelta(hours=1, seconds=2)  # +1 hour because timezones suck hard
+        run_date = datetime.now() + timedelta(hours=1, seconds=1)  # +1 hour because timezones suck hard
         self.scheduler.add_job(self.setCurrentWeather, 'date', run_date=run_date, id='100', )
 
         self.scheduler.add_job(self.changeWeather, 'interval', seconds=300, id='101', name='changeWeather')
diff --git a/remoteconnection.py b/remoteconnection.py
index db3400bc71ce73b71c019362685a1e5748d15173..5feb406a3b0f2fa1233271ba5d964a95ff840389 100644
--- a/remoteconnection.py
+++ b/remoteconnection.py
@@ -3,11 +3,11 @@ import time
 
 
 class RemoteConnection:
-    def __init__(self, ip: ipaddress.IPv4Address, pk: bytes, cap: float, ucap: float, l):
+    def __init__(self, ip: ipaddress.IPv4Address, pk: bytes, cap: float, ucap: float, l: float):
         self.publicIP: ipaddress.IPv4Address = ip
         self.publicKey: bytes = pk
-        self.__availableCapacity: float = cap
-        self.__usedCapacity: float = ucap
+        self.availableCapacity: float = cap
+        self.usedCapacity: float = ucap
         self.loss = l  # loss rate during transmission or transformation
         self.timestamp = time.time_ns()
 
diff --git a/remoteline.py b/remoteline.py
index 1b31a3314974ffffefe0fbc869749da926b2bd0a..1a1b6228a25688454bd5034fea847b167e451a8b 100644
--- a/remoteline.py
+++ b/remoteline.py
@@ -9,3 +9,12 @@ class RemoteLine(remoteconnection.RemoteConnection):
                  cons, ll):
         super().__init__(ip, pk, cap, ucap, ll)
         self.adjacentConnections = cons
+
+
+class SignedRemoteLine:
+    def __init__(self, line: RemoteLine, prev: 'SignedRemoteLine'):
+        self.line = line
+        self.previous: SignedRemoteLine = prev
+        self.timestamp = time.time_ns()
+        self.isOrigin = False
+        self.signature: bytes = bytes(0)
diff --git a/remoteparticipant.py b/remoteparticipant.py
index 52e6b10ebce36c33c02572748b0d120d3b409e7c..55eebbc086cf32f27fd285979806a016693777c4 100644
--- a/remoteparticipant.py
+++ b/remoteparticipant.py
@@ -1,10 +1,8 @@
 import ipaddress
+import sys
 import time
 from datetime import datetime, timedelta
 
-import numpy
-from pydantic.dataclasses import dataclass
-
 import exchange
 import remoteline
 
@@ -18,14 +16,14 @@ class RemoteParticipant:
         self.adjacentLines: set[remoteline.RemoteLine] = adjlines
         self.timestamp = time.time_ns()
         #  a participant will calc the distance in electric loss to this participant when inserting
-        self.distance: float = numpy.iinfo(float).max
+        self.distance: float = sys.float_info.max
 
     def update_nextExchanges(self, exchanges: list[exchange.Exchange]):
         for ex in self.availableExchanges:  # clear all old exchanges
             if ex.is_old():
                 self.availableExchanges.remove(ex)
 
-        self.availableExchanges = self.availableExchanges.extend(exchanges)
+        self.availableExchanges.extend(exchanges)
 
     def is_min_now(self) -> bool:
         now = datetime.now()
diff --git a/remotetransformer.py b/remotetransformer.py
index cb5db4202ad832eb42d0937b8992f31572f3e3b5..7794e0e21667823c8a13b49638e20c76389ee035 100644
--- a/remotetransformer.py
+++ b/remotetransformer.py
@@ -10,3 +10,17 @@ class RemoteTransformer(remoteconnection.RemoteConnection):
                  cons: set['remoteline.RemoteLine'], ll):
         super().__init__(ip, pk, cap, ucap, ll)
         self.adjacentLines: set[remoteline.RemoteLine] = cons
+
+
+class SignedRemoteTransformer:
+    def __init__(self, transformer: RemoteTransformer, prev: 'SignedRemoteTransformer'):
+        self.transformer = transformer
+        self.previous: SignedRemoteTransformer = prev
+        self.timestamp = time.time_ns()
+        self.isOrigin = False
+        self.signature: bytes = bytes(0)
+
+    def __str__(self):
+        return self.transformer.publicIP.__str__() + " " + self.transformer.publicKey.hex() + " " + str(
+            self.transformer.availableCapacity) + " " + str(self.transformer.usedCapacity) + " " + str(
+            self.transformer.loss) + " " + str(self.timestamp) + " " + str(self.isOrigin)
diff --git a/request.py b/request.py
index 805c613b07ff20a9bb9e5ddc23c59f836e075e01..38a58e0ccc78d8126277442abfb87c125f311a10 100644
--- a/request.py
+++ b/request.py
@@ -1,6 +1,7 @@
 import exchange
+from datetime import datetime
 
 
 class Request(exchange.Exchange):
-    def __init__(self, pk: bytes, p: float, ppw: float):
-        exchange.Exchange.__init__(self, pk, p, ppw)
+    def __init__(self, pk: bytes, p: float, ppw: float, extime: datetime):
+        exchange.Exchange.__init__(self, pk, p, ppw, extime)
diff --git a/route.py b/route.py
index 953ca344544ccab4882cd1c6cd8ad1ab63c0ff35..f08628f9965ad4aa8427239fc856eb961ef1871a 100644
--- a/route.py
+++ b/route.py
@@ -5,8 +5,8 @@ import rustworkx as rx
 
 
 class Route:
-    def __init__(self, start: remoteparticipant, end: remoteparticipant):
-        self.__start = start
-        self.__end = end
-        self.__route = rx.PyGraph()
-        self.routeloss = 0.0
+    def __init__(self, start: remoteparticipant, end: remoteparticipant, g: rx.PyGraph, rl: float):
+        self.start: remoteparticipant = start
+        self.end: remoteparticipant = end
+        self.graph = g
+        self.routeloss = rl
diff --git a/trade.py b/trade.py
index 1d5d2e15105f9023f055a915b3f3eb9a265fee68..a47a9090d7c692667c1d6ddab02ed7c0f9912b26 100644
--- a/trade.py
+++ b/trade.py
@@ -1,8 +1,8 @@
-# from main import ureg,Q_
-import locale
 import time
 import datetime
 
+from pint import UnitRegistry
+
 import offer
 import request
 import route
@@ -11,12 +11,19 @@ import route
 class Trade:
     def __init__(self, off: offer.Offer, req: request.Request, pwr: float, ppw: float, rou: route.Route,
                  extime: datetime.datetime):
+        self.ureg = None
+        self.Q_ = None
         self.__timestamp = time.time_ns()
         self.__offer: offer.Offer = off
         self.__request: request.Request = req
-        self.__route = rou
-        # self.__power = Q_(pwr, ureg.watt)
-        self.__pricePerWatt = locale.currency(ppw)
+        self.route = rou
+        self.power = pwr
+        self.__pricePerWatt = ppw
         self.__executionTime: datetime.datetime = extime
         self.sig_off: bytes
         self.sig_req: bytes
+
+    def set_ureg(self, ureg: UnitRegistry) -> None:
+        self.ureg = ureg
+        self.Q_ = ureg.Quantity
+        self.power = self.Q_(self.power, ureg.watt)
diff --git a/transformer.py b/transformer.py
index 3dd9ed68efd82be04f0641ae209f1bbdd5cc76df..fff67ddc22f5d5f1c7255e5b4d4668fbbe6cc695 100644
--- a/transformer.py
+++ b/transformer.py
@@ -14,7 +14,7 @@ from util import get_pub_ip
 import logging
 
 from connection import Connection
-from remotetransformer import RemoteTransformer
+from remotetransformer import RemoteTransformer, SignedRemoteTransformer
 from remoteline import RemoteLine
 
 logger = logging.getLogger(__name__)
@@ -24,8 +24,10 @@ class Transformer(Connection):
     def __init__(self, cap: float, conips: set[ipaddress.IPv4Address], sched: AsyncIOScheduler):
         super().__init__(cap, conips, sched)
         self.adjacentLines: set[RemoteLine] = set()
+        self.lastSignedTransformer: dict[datetime.datetime, SignedRemoteTransformer] = dict()
         # adding fastapi endpoints
         self.fastRouter.add_api_route("/asRemoteJSON", self.asRemoteTransformerJSON, methods=["GET"])
+        self.fastRouter.add_api_route("/sign/{time}", self.sign, methods=["POST"])
         # setting up scheduling
         run_date = datetime.datetime.now() + datetime.timedelta(hours=1,
                                                                 seconds=5)  # +1 hour because timezones suck hard
@@ -46,6 +48,29 @@ class Transformer(Connection):
         self.adjacentLines.update(result)
         logger.info("===> Transformer: " + self.publicIP.__str__() + " retrieved connections: " + len(result).__str__())
 
+    async def sign(self, time: datetime.datetime, rtjson):
+        rt = jsonpickle.decode(rtjson)
+        if rt.publicKey == self.publicKey:  # check if the rt actually is me
+            if time not in self.lastSignedTransformer.keys():
+                # has there been no route announced before this one? then create an origin node for the trust chain
+                origin = SignedRemoteTransformer(
+                    RemoteTransformer(self.publicIP, self.publicKey, self.availableCapacity,
+                                      self.usedCapacity, self.adjacentLines, self.loss), None)
+                origin.isOrigin = True
+                origin.signature = self.dil.sign_with_input(self.__secretKey, origin.__str__())
+                result = SignedRemoteTransformer(rt, origin)
+                result.signature = self.dil.sign_with_input(self.__secretKey, result.__str__())
+                self.lastSignedTransformer[time] = result
+                return jsonpickle.encode(result)
+            else:
+                # if there has been a route announced before, add the previous to the new one
+                result = SignedRemoteTransformer(rt, self.lastSignedTransformer[time])
+                result.signature = self.dil.sign_with_input(self.__secretKey, result.__str__())
+                self.lastSignedTransformer[time] = result
+                return jsonpickle.encode(result)
+        else:
+            return "Unauthorized"  # better handling here would be nice
+
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description='Connection service')
diff --git a/util.py b/util.py
index 5df2296ca207e54c4a7ebed39e28c60b1a1a714f..cbc70944d7902ffc227652f0fd036669d2eb31d4 100644
--- a/util.py
+++ b/util.py
@@ -1,4 +1,5 @@
 import socket
+from datetime import datetime, timedelta
 
 
 def get_pub_ip():
@@ -12,4 +13,14 @@ def get_pub_ip():
         ip = '127.0.0.1'
     finally:
         s.close()
-    return ip
\ No newline at end of file
+    return ip
+
+
+def next_minute() -> datetime:
+    now = datetime.now()
+
+    # Calculate the first second of the next minute
+    start_of_minute = datetime(now.year, now.month, now.day, now.hour, now.minute, 0)
+    start_of_minute += timedelta(minutes=1)
+
+    return start_of_minute