diff --git a/mirage/_ms.py b/mirage/_ms.py
index 5f4d22d523dc142db4ce26c1c486bfbc8d7f916e..35e0e09054ad0809858b2c811e3d2c734d2d75dd 100644
--- a/mirage/_ms.py
+++ b/mirage/_ms.py
@@ -7,7 +7,4 @@ class MS:
     type = attr.ib()
     written_on = attr.ib()
     blockstamp = attr.ib()
-
-
-
-
+    timestamp = attr.ib()
diff --git a/mirage/block_forge.py b/mirage/block_forge.py
index 0056dc1bcb8a8071890d0e7220432daaeffd9cb1..a8227066dc123a7bedb8d830c2225c43b31359de 100644
--- a/mirage/block_forge.py
+++ b/mirage/block_forge.py
@@ -17,27 +17,27 @@ class BlockForge:
     """
     currency = attr.ib(validator=attr.validators.instance_of(str))
     key = attr.ib(validator=attr.validators.instance_of(SigningKey))
-    _pool = attr.ib(default=attr.Factory(list), validator=attr.validators.instance_of(list))
+    pool = attr.ib(default=attr.Factory(list), validator=attr.validators.instance_of(list))
     blocks = attr.ib(default=attr.Factory(list), validator=attr.validators.instance_of(list))
     user_identities = attr.ib(default=attr.Factory(dict), validator=attr.validators.instance_of(dict))
     _ud = attr.ib(default=False, validator=attr.validators.instance_of(bool))
     _logger = attr.ib(default=attr.Factory(lambda: logging.getLogger('mirage')))
 
     @classmethod
-    def start(cls, currency, salt, password, loop):
-        key = SigningKey(salt, password)
+    def start(cls, currency, salt, password, scrypt_params, loop):
+        key = SigningKey(salt, password, scrypt_params)
         return cls(currency, key)
 
     def push(self, document):
-        self._pool.append(document)
+        self.pool.append(document)
 
     def next_dividend(self):
         if self._ud:
             try:
-                latest_dividend = next(reversed([b for b in self.blocks if b.ud]))
+                latest_dividend = next(reversed([b.ud for b in self.blocks if b.ud]))
             except StopIteration:
                 return 100
-            return latest_dividend * 1.1
+            return int(latest_dividend * 1.1)
 
     def previous_hash(self):
         try:
@@ -57,41 +57,42 @@ class BlockForge:
         return len([i for i in self.user_identities.values() if i.member])
 
     def identities(self):
-        return [d for d in self._pool if type(d) is Identity]
+        return [d for d in self.pool if type(d) is Identity]
 
     def revocations(self):
-        return [r for r in self._pool if type(r) is Revocation]
+        return [r for r in self.pool if type(r) is Revocation]
 
     def joiners(self):
-        return [d for d in self._pool if type(d) is Membership and d.membership_type == 'IN'
-                and d.issuer in self.user_identities and not self.user_identities[d.issuer].member]
+        return [d for d in self.pool if type(d) is Membership and d.membership_type == 'IN'
+                and ((d.issuer in self.user_identities and not self.user_identities[d.issuer].member)
+                     or d.issuer in [d.pubkey for d in self.pool if type(d) is Identity])]
 
     def actives(self):
-        return [d for d in self._pool if type(d) is Membership and d.membership_type == 'IN'
+        return [d for d in self.pool if type(d) is Membership and d.membership_type == 'IN'
                 and d.issuer in self.user_identities and self.user_identities[d.issuer].member]
 
     def leavers(self):
-        return [d for d in self._pool if type(d) is Membership and d.membership_type == 'OUT'
+        return [d for d in self.pool if type(d) is Membership and d.membership_type == 'OUT'
                 and d.issuer in self.user_identities and self.user_identities[d.issuer].member]
 
     def excluded(self):
         return []
 
     def certifications(self):
-        return [d for d in self._pool if type(d) is Certification]
+        return [d for d in self.pool if type(d) is Certification]
 
     def transactions(self):
-        return [d for d in self._pool if type(d) is Transaction]
+        return [d for d in self.pool if type(d) is Transaction]
 
     def parameters(self):
         if not self.blocks:
             return 0.1, 86400, 100000, 10800, 40, 2629800, 31557600, 1, 604800, 604800,\
                                                 0.9, 15778800, 5, 12, 300, 25, 40, 0.66
 
-    def monetary_mass(self):
+    def monetary_mass(self, number=None):
         mass = 0
         for b in self.blocks:
-            if b.ud:
+            if b.ud and (not number or b.number <= number):
                 mass += b.ud * b.members_count
         return mass
 
@@ -163,7 +164,8 @@ class BlockForge:
             self.user_identities[membership.issuer].memberships.append(MS(pubkey=membership.issuer,
                                                                           type=membership.membership_type,
                                                                           written_on=block.number,
-                                                                          blockstamp=membership.membership_ts))
+                                                                          blockstamp=membership.membership_ts,
+                                                                          timestamp=block.mediantime))
 
         for tx in block.transactions:
             receivers = [o.conditions.left.pubkey for o in tx.outputs
@@ -171,4 +173,4 @@ class BlockForge:
             self.user_identities[tx.issuers[0]].tx_sent.append(tx)
             self.user_identities[receivers[0]].tx_received.append(tx)
 
-        self._pool = []
+        self.pool = []
diff --git a/mirage/http.py b/mirage/http.py
index a839038a5d96e2a8034b66da98051a8553cadde2..1cd28d3c66c21bc1a2e88605d9bd0fdb67c8b55c 100644
--- a/mirage/http.py
+++ b/mirage/http.py
@@ -2,6 +2,7 @@ from aiohttp import web, log, errors
 import json
 import socket
 from duniterpy.documents import Peer
+import asyncio
 
 
 class Request:
@@ -40,7 +41,7 @@ class HTTPServer:
     async def _handler(self, request, handle):
         await request.read()
         self.requests.append(Request(request.method, request.path, request.content))
-        json_data, http_code = handle(request)
+        json_data, http_code = await handle(request)
         return web.Response(body=bytes(json.dumps(json_data), "utf-8"),
                             headers={'Content-Type': 'application/json'},
                             status=http_code)
diff --git a/mirage/node.py b/mirage/node.py
index 9ac9ec329d7a56b0aead6fec22abef80e3772d81..a8418db95e92cf87416713746305a0a3604d81a3 100644
--- a/mirage/node.py
+++ b/mirage/node.py
@@ -1,5 +1,5 @@
 import attr
-from duniterpy.documents import Peer, BMAEndpoint, BlockUID
+from duniterpy.documents import Peer, BMAEndpoint, BlockUID, Identity, Certification
 from duniterpy.api import errors
 from duniterpy.key import SigningKey, ScryptParams
 from .http import HTTPServer
@@ -26,18 +26,73 @@ class Node:
             '/wot/lookup/{search}': node.lookup,
             '/wot/certifiers-of/{search}': node.certifiers_of,
             '/wot/certified-by/{search}': node.certified_by,
+            '/wot/requirements/{pubkey}': node.requirements,
             '/blockchain/parameters': node.parameters,
             '/blockchain/with/ud': node.with_ud,
             '/blockchain/memberships/{search}': node.memberships,
             '/tx/history/{search}': node.tx_history,
         }
+        post_routes = {
+            '/wot/add': node.add,
+            '/wot/certify': node.certify
+        }
         for r, h in get_routes.items():
             node.http.add_route("GET", r, h)
+        for r, h in post_routes.items():
+            node.http.add_route("POST", r, h)
         srv, port, url = await node.http.create_server()
         print("Server started on {0}".format(url))
         return node
 
-    def block_by_number(self, request):
+    async def add(self, request):
+        data = await request.post()
+        identity = Identity.from_signed_raw(data["identity"])
+        self.forge.pool.append(identity)
+        return {}, 200
+
+    async def certify(self, request):
+        data = await request.post()
+        certification = Certification.from_signed_raw(data["cert"])
+        self.forge.pool.append(certification)
+        return {}, 200
+
+    async def requirements(self, request):
+        pubkey = request.match_info['pubkey']
+        try:
+            user_identity = self.forge.user_identities[pubkey]
+        except KeyError:
+            try:
+                user_identity = next(i for i in self.forge.user_identities.values() if i.uid == pubkey)
+            except StopIteration:
+                return {
+                    'ucode': errors.NO_MEMBER_MATCHING_PUB_OR_UID,
+                    'message': "No member matching this pubkey or uid"
+                }, 404
+        return {
+                    "identities": [
+                            {
+                              "pubkey": user_identity.pubkey,
+                              "uid": user_identity.uid,
+                              "meta": {
+                                "timestamp": str(user_identity.blockstamp),
+                              },
+                              "expired": user_identity.revoked,
+                              "outdistanced": not user_identity.member,
+                              "certifications": [
+                                {
+                                  "from": c.from_identity.pubkey,
+                                  "to": c.to_identity.pubkey,
+                                  "expiresIn": max(self.forge.blocks[-1].mediantime - 31557600 - c.mediantime, 0)
+                                } for c in user_identity.certs_received
+                                ],
+                                "membershipPendingExpiresIn": 0,
+                                "membershipExpiresIn": max(self.forge.blocks[-1].mediantime - 15778800
+                                                           - user_identity.memberships[-1].timestamp, 0)
+                            },
+                        ]
+                    }, 200
+
+    async def block_by_number(self, request):
         number = int(request.match_info['number'])
         try:
             block = self.forge.blocks[number]
@@ -49,7 +104,7 @@ class Node:
                 "time": block.time,
                 "medianTime": block.mediantime,
                 "membersCount": block.members_count,
-                "monetaryMass": self.forge.monetary_mass(),
+                "monetaryMass": self.forge.monetary_mass(number),
                 "unitbase": block.unit_base,
                 "issuersCount": block.different_issuers_count,
                 "issuersFrame": block.issuers_frame,
@@ -79,7 +134,7 @@ class Node:
                 "message": "Block not found"
             }, 404
 
-    def current_block(self, request):
+    async def current_block(self, request):
         try:
             block = self.forge.blocks[-1]
             return {
@@ -120,7 +175,7 @@ class Node:
                 "message": "No current block"
             }, 404
 
-    def sources(self, request):
+    async def sources(self, request):
         pubkey = str(request.match_info['pubkey'])
         try:
             sources = self.forge.user_identities[pubkey].sources
@@ -142,7 +197,7 @@ class Node:
                       "sources": []
                    }, 200
 
-    def peering(self, request):
+    async def peering(self, request):
         return {
             "version": 2,
             "currency": self.peer_doc().currency,
@@ -156,7 +211,7 @@ class Node:
             "pubkey": self.peer_doc().pubkey
         }, 200
 
-    def parameters(self, request):
+    async def parameters(self, request):
         return {
             "currency": self.forge.currency,
             "c": 0.0025,
@@ -179,14 +234,14 @@ class Node:
             "percentRot": 0.66
         }, 200
 
-    def with_ud(self, request):
+    async def with_ud(self, request):
         return {
             "result": {
                 "blocks": [b.number for b in self.forge.blocks if b.ud]
             }
         }, 200
 
-    def memberships(self, request):
+    async def memberships(self, request):
         search = str(request.match_info['search'])
         try:
             user_identity = self.forge.user_identities[search]
@@ -216,7 +271,7 @@ class Node:
                ]
            }, 200
 
-    def certifiers_of(self, request):
+    async def certifiers_of(self, request):
         search = str(request.match_info['search'])
         try:
             user_identity = self.forge.user_identities[search]
@@ -255,7 +310,7 @@ class Node:
             ]
         }, 200
 
-    def certified_by(self, request):
+    async def certified_by(self, request):
         search = str(request.match_info['search'])
         try:
             user_identity = self.forge.user_identities[search]
@@ -294,7 +349,7 @@ class Node:
             ]
         }, 200
 
-    def lookup(self, request):
+    async def lookup(self, request):
         search = str(request.match_info['search'])
         matched = [i for i in self.forge.user_identities.values() if search in i.pubkey or search in i.uid]
 
@@ -340,7 +395,7 @@ class Node:
             ]
         }, 200
 
-    def tx_history(self, request):
+    async def tx_history(self, request):
         search = str(request.match_info['search'])
         try:
             user_identity = self.forge.user_identities[search]