diff --git a/Example/example-app/Sources/AppFeature/PasswordStorage+Keychain.swift b/Example/example-app/Sources/AppFeature/PasswordStorage+Keychain.swift
index 7af6bc4faa48b2b35a7a7a5eb8583f31998c5e14..5eb1a61d6b07cb9197b443f98226b8257b6cc5f9 100644
--- a/Example/example-app/Sources/AppFeature/PasswordStorage+Keychain.swift
+++ b/Example/example-app/Sources/AppFeature/PasswordStorage+Keychain.swift
@@ -8,7 +8,7 @@ extension PasswordStorage {
     )
     return PasswordStorage(
       save: { password in keychain[data: "password"] = password},
-      load: { try keychain[data: "password"] ?? { throw PasswordStorageMissingPasswordError() }() }
+      load: { try keychain[data: "password"] ?? { throw MissingPasswordError() }() }
     )
   }()
 }
diff --git a/Frameworks/Bindings.xcframework/Info.plist b/Frameworks/Bindings.xcframework/Info.plist
index 5da456bbdabbf3d610daca4ce17734b523413a53..3c96df61083ca794226526858401b4539235d6ba 100644
--- a/Frameworks/Bindings.xcframework/Info.plist
+++ b/Frameworks/Bindings.xcframework/Info.plist
@@ -6,30 +6,30 @@
 	<array>
 		<dict>
 			<key>LibraryIdentifier</key>
-			<string>ios-arm64</string>
+			<string>ios-arm64_x86_64-simulator</string>
 			<key>LibraryPath</key>
 			<string>Bindings.framework</string>
 			<key>SupportedArchitectures</key>
 			<array>
 				<string>arm64</string>
+				<string>x86_64</string>
 			</array>
 			<key>SupportedPlatform</key>
 			<string>ios</string>
+			<key>SupportedPlatformVariant</key>
+			<string>simulator</string>
 		</dict>
 		<dict>
 			<key>LibraryIdentifier</key>
-			<string>ios-arm64_x86_64-simulator</string>
+			<string>ios-arm64</string>
 			<key>LibraryPath</key>
 			<string>Bindings.framework</string>
 			<key>SupportedArchitectures</key>
 			<array>
 				<string>arm64</string>
-				<string>x86_64</string>
 			</array>
 			<key>SupportedPlatform</key>
 			<string>ios</string>
-			<key>SupportedPlatformVariant</key>
-			<string>simulator</string>
 		</dict>
 	</array>
 	<key>CFBundlePackageType</key>
diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Bindings b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Bindings
index 6a502beec597ed1474bd50e61fa0537e2588f3eb..ccd958e618b71e7946c6e9afaba0bcefdabcb5bf 100644
Binary files a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Bindings differ
diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Headers/Bindings.objc.h
index e3d9fefd0c6c4c233b287f3340a56d0d229d72b9..24d5cc9bca1be47de6ccf3a6e1cdfe505003ae1c 100644
--- a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Headers/Bindings.objc.h
+++ b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Headers/Bindings.objc.h
@@ -17,9 +17,9 @@
 @class BindingsE2ESendReport;
 @class BindingsFact;
 @class BindingsIdentity;
-@class BindingsListenerID;
 @class BindingsMessage;
 @class BindingsRestlikeMessage;
+@class BindingsRoundsList;
 @protocol BindingsClientError;
 @class BindingsClientError;
 @protocol BindingsListener;
@@ -38,10 +38,11 @@
 @protocol BindingsListener <NSObject>
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -67,9 +68,10 @@
 // skipped field AuthenticatedConnection.Connection with unsupported type: gitlab.com/elixxir/client/bindings.Connection
 
 - (void)close;
+- (long)getId;
 - (NSData* _Nullable)getPartner;
 - (BOOL)isAuthenticated;
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 - (NSData* _Nullable)sendE2E:(long)mt payload:(NSData* _Nullable)payload error:(NSError* _Nullable* _Nullable)error;
 @end
 
@@ -113,8 +115,7 @@ messages can be sent
  */
 - (BOOL)isNetworkHealthy;
 /**
- * MakeIdentity generates a new cryptographic identity for receving
-messages
+ * MakeIdentity generates a new cryptographic identity for receiving messages
  */
 - (NSData* _Nullable)makeIdentity:(NSError* _Nullable* _Nullable)error;
 /**
@@ -167,6 +168,14 @@ Threads Started:
 		Responds to confirmations of successful rekey operations
  */
 - (BOOL)startNetworkFollower:(long)timeoutMS error:(NSError* _Nullable* _Nullable)error;
+/**
+ * StopNetworkFollower stops the network follower if it is running.
+It returns errors if the Follower is in the wrong status to stop or if it
+fails to stop it.
+if the network follower is running and this fails, the client object will
+most likely be in an unrecoverable state and need to be trashed.
+ */
+- (BOOL)stopNetworkFollower:(NSError* _Nullable* _Nullable)error;
 - (void)unregisterNetworkHealthCB:(int64_t)funcID;
 /**
  * WaitForMessageDelivery allows the caller to get notified if the rounds a
@@ -189,7 +198,7 @@ passed timeout. It will return true if the network is healthy
 @end
 
 /**
- * Connection is the bindings representation of a connect.Connection object that can be tracked
+ * Connection is the bindings representation of a connect.Connection object that can be tracked by id
  */
 @interface BindingsConnection : NSObject <goSeqRefInterface> {
 }
@@ -201,6 +210,10 @@ passed timeout. It will return true if the network is healthy
  * Close deletes this Connection's partner.Manager and releases resources
  */
 - (void)close;
+/**
+ * GetId returns the Connection.id
+ */
+- (long)getId;
 /**
  * GetPartner returns the partner.Manager for this Connection
  */
@@ -210,7 +223,7 @@ passed timeout. It will return true if the network is healthy
 and allows for reading data sent from the partner.Manager
 Returns marshalled ListenerID
  */
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 /**
  * SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
 Returns marshalled E2ESendReport
@@ -220,6 +233,10 @@ Returns marshalled E2ESendReport
 
 /**
  * E2ESendReport is the bindings representation of the return values of SendE2E
+Example E2ESendReport:
+{"RoundList":{"Rounds":[1,5,9]},
+ "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=",
+ "Timestamp":1653582683183384000}
  */
 @interface BindingsE2ESendReport : NSObject <goSeqRefInterface> {
 }
@@ -227,13 +244,17 @@ Returns marshalled E2ESendReport
 
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 - (nonnull instancetype)init;
+// skipped field E2ESendReport.RoundsList with unsupported type: gitlab.com/elixxir/client/bindings.RoundsList
+
 @property (nonatomic) NSData* _Nullable messageID;
 @property (nonatomic) int64_t timestamp;
 - (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
 @end
 
 /**
- * TODO: this seems completely pointless, as the FactList type is effectively the same thing
+ * Fact is an internal fact type for use in the bindings layer
+example marshalled Fact:
+{"Fact":"Zezima","Type":0}
  */
 @interface BindingsFact : NSObject <goSeqRefInterface> {
 }
@@ -269,19 +290,17 @@ Example marshalled Identity:
 @property (nonatomic) NSData* _Nullable dhKeyPrivate;
 @end
 
-/**
- * ListenerID represents the return type of RegisterListener
- */
-@interface BindingsListenerID : NSObject <goSeqRefInterface> {
-}
-@property(strong, readonly) _Nonnull id _ref;
-
-- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
-- (nonnull instancetype)init;
-@end
-
 /**
  * Message is the bindings representation of a receive.Message
+Example Message format:
+{"MessageType":1,
+ "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+ "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+ "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "EphemeralID":17,"Timestamp":1653580439357351000,
+ "Encrypted":false,
+ "RoundId":19}
  */
 @interface BindingsMessage : NSObject <goSeqRefInterface> {
 }
@@ -325,6 +344,21 @@ Example marshalled RestlikeMessage:
 @property (nonatomic) NSString* _Nonnull error;
 @end
 
+/**
+ * Example marshalled roundList object:
+[1001,1003,1006]
+ */
+@interface BindingsRoundsList : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (nonnull instancetype)init;
+// skipped field RoundsList.Rounds with unsupported type: []int
+
+- (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
+@end
+
 /**
  * DownloadAndVerifySignedNdfWithUrl retrieves the NDF from a specified URL.
 The NDF is processed into a protobuf containing a signature which
@@ -345,11 +379,21 @@ which should be set to 32, but can be set higher in certain cases.
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGenerateSecret(long numBytes);
 
+/**
+ * GetDependencies returns the api DEPENDENCIES
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetDependencies(void);
+
 /**
  * GetFactsFromContact accepts a marshalled contact.Contact object, returning its marshalled list of Fact objects
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetFactsFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetGitVersion rturns the api GITVERSION
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetGitVersion(void);
+
 /**
  * GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object
  */
@@ -360,6 +404,11 @@ FOUNDATION_EXPORT NSData* _Nullable BindingsGetIDFromContact(NSData* _Nullable m
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetPubkeyFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetVersion returns the api SEMVER
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetVersion(void);
+
 /**
  * sets level of logging. All logs the set level and above will be displayed
 options are:
@@ -453,10 +502,11 @@ time.
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -472,6 +522,9 @@ time.
 /**
  * MessageDeliveryCallback gets called on the determination if all events
 related to a message send were successful.
+If delivered == true, timedOut == false && roundResults != nil
+If delivered == false, roundResults == nil
+If timedOut == true, delivered == false && roundResults == nil
  */
 @interface BindingsMessageDeliveryCallback : NSObject <goSeqRefInterface, BindingsMessageDeliveryCallback> {
 }
diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings
index 6a502beec597ed1474bd50e61fa0537e2588f3eb..ccd958e618b71e7946c6e9afaba0bcefdabcb5bf 100644
Binary files a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Bindings differ
diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h
index e3d9fefd0c6c4c233b287f3340a56d0d229d72b9..24d5cc9bca1be47de6ccf3a6e1cdfe505003ae1c 100644
--- a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h
+++ b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/A/Headers/Bindings.objc.h
@@ -17,9 +17,9 @@
 @class BindingsE2ESendReport;
 @class BindingsFact;
 @class BindingsIdentity;
-@class BindingsListenerID;
 @class BindingsMessage;
 @class BindingsRestlikeMessage;
+@class BindingsRoundsList;
 @protocol BindingsClientError;
 @class BindingsClientError;
 @protocol BindingsListener;
@@ -38,10 +38,11 @@
 @protocol BindingsListener <NSObject>
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -67,9 +68,10 @@
 // skipped field AuthenticatedConnection.Connection with unsupported type: gitlab.com/elixxir/client/bindings.Connection
 
 - (void)close;
+- (long)getId;
 - (NSData* _Nullable)getPartner;
 - (BOOL)isAuthenticated;
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 - (NSData* _Nullable)sendE2E:(long)mt payload:(NSData* _Nullable)payload error:(NSError* _Nullable* _Nullable)error;
 @end
 
@@ -113,8 +115,7 @@ messages can be sent
  */
 - (BOOL)isNetworkHealthy;
 /**
- * MakeIdentity generates a new cryptographic identity for receving
-messages
+ * MakeIdentity generates a new cryptographic identity for receiving messages
  */
 - (NSData* _Nullable)makeIdentity:(NSError* _Nullable* _Nullable)error;
 /**
@@ -167,6 +168,14 @@ Threads Started:
 		Responds to confirmations of successful rekey operations
  */
 - (BOOL)startNetworkFollower:(long)timeoutMS error:(NSError* _Nullable* _Nullable)error;
+/**
+ * StopNetworkFollower stops the network follower if it is running.
+It returns errors if the Follower is in the wrong status to stop or if it
+fails to stop it.
+if the network follower is running and this fails, the client object will
+most likely be in an unrecoverable state and need to be trashed.
+ */
+- (BOOL)stopNetworkFollower:(NSError* _Nullable* _Nullable)error;
 - (void)unregisterNetworkHealthCB:(int64_t)funcID;
 /**
  * WaitForMessageDelivery allows the caller to get notified if the rounds a
@@ -189,7 +198,7 @@ passed timeout. It will return true if the network is healthy
 @end
 
 /**
- * Connection is the bindings representation of a connect.Connection object that can be tracked
+ * Connection is the bindings representation of a connect.Connection object that can be tracked by id
  */
 @interface BindingsConnection : NSObject <goSeqRefInterface> {
 }
@@ -201,6 +210,10 @@ passed timeout. It will return true if the network is healthy
  * Close deletes this Connection's partner.Manager and releases resources
  */
 - (void)close;
+/**
+ * GetId returns the Connection.id
+ */
+- (long)getId;
 /**
  * GetPartner returns the partner.Manager for this Connection
  */
@@ -210,7 +223,7 @@ passed timeout. It will return true if the network is healthy
 and allows for reading data sent from the partner.Manager
 Returns marshalled ListenerID
  */
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 /**
  * SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
 Returns marshalled E2ESendReport
@@ -220,6 +233,10 @@ Returns marshalled E2ESendReport
 
 /**
  * E2ESendReport is the bindings representation of the return values of SendE2E
+Example E2ESendReport:
+{"RoundList":{"Rounds":[1,5,9]},
+ "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=",
+ "Timestamp":1653582683183384000}
  */
 @interface BindingsE2ESendReport : NSObject <goSeqRefInterface> {
 }
@@ -227,13 +244,17 @@ Returns marshalled E2ESendReport
 
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 - (nonnull instancetype)init;
+// skipped field E2ESendReport.RoundsList with unsupported type: gitlab.com/elixxir/client/bindings.RoundsList
+
 @property (nonatomic) NSData* _Nullable messageID;
 @property (nonatomic) int64_t timestamp;
 - (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
 @end
 
 /**
- * TODO: this seems completely pointless, as the FactList type is effectively the same thing
+ * Fact is an internal fact type for use in the bindings layer
+example marshalled Fact:
+{"Fact":"Zezima","Type":0}
  */
 @interface BindingsFact : NSObject <goSeqRefInterface> {
 }
@@ -269,19 +290,17 @@ Example marshalled Identity:
 @property (nonatomic) NSData* _Nullable dhKeyPrivate;
 @end
 
-/**
- * ListenerID represents the return type of RegisterListener
- */
-@interface BindingsListenerID : NSObject <goSeqRefInterface> {
-}
-@property(strong, readonly) _Nonnull id _ref;
-
-- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
-- (nonnull instancetype)init;
-@end
-
 /**
  * Message is the bindings representation of a receive.Message
+Example Message format:
+{"MessageType":1,
+ "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+ "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+ "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "EphemeralID":17,"Timestamp":1653580439357351000,
+ "Encrypted":false,
+ "RoundId":19}
  */
 @interface BindingsMessage : NSObject <goSeqRefInterface> {
 }
@@ -325,6 +344,21 @@ Example marshalled RestlikeMessage:
 @property (nonatomic) NSString* _Nonnull error;
 @end
 
+/**
+ * Example marshalled roundList object:
+[1001,1003,1006]
+ */
+@interface BindingsRoundsList : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (nonnull instancetype)init;
+// skipped field RoundsList.Rounds with unsupported type: []int
+
+- (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
+@end
+
 /**
  * DownloadAndVerifySignedNdfWithUrl retrieves the NDF from a specified URL.
 The NDF is processed into a protobuf containing a signature which
@@ -345,11 +379,21 @@ which should be set to 32, but can be set higher in certain cases.
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGenerateSecret(long numBytes);
 
+/**
+ * GetDependencies returns the api DEPENDENCIES
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetDependencies(void);
+
 /**
  * GetFactsFromContact accepts a marshalled contact.Contact object, returning its marshalled list of Fact objects
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetFactsFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetGitVersion rturns the api GITVERSION
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetGitVersion(void);
+
 /**
  * GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object
  */
@@ -360,6 +404,11 @@ FOUNDATION_EXPORT NSData* _Nullable BindingsGetIDFromContact(NSData* _Nullable m
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetPubkeyFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetVersion returns the api SEMVER
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetVersion(void);
+
 /**
  * sets level of logging. All logs the set level and above will be displayed
 options are:
@@ -453,10 +502,11 @@ time.
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -472,6 +522,9 @@ time.
 /**
  * MessageDeliveryCallback gets called on the determination if all events
 related to a message send were successful.
+If delivered == true, timedOut == false && roundResults != nil
+If delivered == false, roundResults == nil
+If timedOut == true, delivered == false && roundResults == nil
  */
 @interface BindingsMessageDeliveryCallback : NSObject <goSeqRefInterface, BindingsMessageDeliveryCallback> {
 }
diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Bindings b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Bindings
index 6a502beec597ed1474bd50e61fa0537e2588f3eb..ccd958e618b71e7946c6e9afaba0bcefdabcb5bf 100644
Binary files a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Bindings differ
diff --git a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Headers/Bindings.objc.h
index e3d9fefd0c6c4c233b287f3340a56d0d229d72b9..24d5cc9bca1be47de6ccf3a6e1cdfe505003ae1c 100644
--- a/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Headers/Bindings.objc.h
+++ b/Frameworks/Bindings.xcframework/ios-arm64/Bindings.framework/Versions/Current/Headers/Bindings.objc.h
@@ -17,9 +17,9 @@
 @class BindingsE2ESendReport;
 @class BindingsFact;
 @class BindingsIdentity;
-@class BindingsListenerID;
 @class BindingsMessage;
 @class BindingsRestlikeMessage;
+@class BindingsRoundsList;
 @protocol BindingsClientError;
 @class BindingsClientError;
 @protocol BindingsListener;
@@ -38,10 +38,11 @@
 @protocol BindingsListener <NSObject>
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -67,9 +68,10 @@
 // skipped field AuthenticatedConnection.Connection with unsupported type: gitlab.com/elixxir/client/bindings.Connection
 
 - (void)close;
+- (long)getId;
 - (NSData* _Nullable)getPartner;
 - (BOOL)isAuthenticated;
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 - (NSData* _Nullable)sendE2E:(long)mt payload:(NSData* _Nullable)payload error:(NSError* _Nullable* _Nullable)error;
 @end
 
@@ -113,8 +115,7 @@ messages can be sent
  */
 - (BOOL)isNetworkHealthy;
 /**
- * MakeIdentity generates a new cryptographic identity for receving
-messages
+ * MakeIdentity generates a new cryptographic identity for receiving messages
  */
 - (NSData* _Nullable)makeIdentity:(NSError* _Nullable* _Nullable)error;
 /**
@@ -167,6 +168,14 @@ Threads Started:
 		Responds to confirmations of successful rekey operations
  */
 - (BOOL)startNetworkFollower:(long)timeoutMS error:(NSError* _Nullable* _Nullable)error;
+/**
+ * StopNetworkFollower stops the network follower if it is running.
+It returns errors if the Follower is in the wrong status to stop or if it
+fails to stop it.
+if the network follower is running and this fails, the client object will
+most likely be in an unrecoverable state and need to be trashed.
+ */
+- (BOOL)stopNetworkFollower:(NSError* _Nullable* _Nullable)error;
 - (void)unregisterNetworkHealthCB:(int64_t)funcID;
 /**
  * WaitForMessageDelivery allows the caller to get notified if the rounds a
@@ -189,7 +198,7 @@ passed timeout. It will return true if the network is healthy
 @end
 
 /**
- * Connection is the bindings representation of a connect.Connection object that can be tracked
+ * Connection is the bindings representation of a connect.Connection object that can be tracked by id
  */
 @interface BindingsConnection : NSObject <goSeqRefInterface> {
 }
@@ -201,6 +210,10 @@ passed timeout. It will return true if the network is healthy
  * Close deletes this Connection's partner.Manager and releases resources
  */
 - (void)close;
+/**
+ * GetId returns the Connection.id
+ */
+- (long)getId;
 /**
  * GetPartner returns the partner.Manager for this Connection
  */
@@ -210,7 +223,7 @@ passed timeout. It will return true if the network is healthy
 and allows for reading data sent from the partner.Manager
 Returns marshalled ListenerID
  */
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 /**
  * SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
 Returns marshalled E2ESendReport
@@ -220,6 +233,10 @@ Returns marshalled E2ESendReport
 
 /**
  * E2ESendReport is the bindings representation of the return values of SendE2E
+Example E2ESendReport:
+{"RoundList":{"Rounds":[1,5,9]},
+ "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=",
+ "Timestamp":1653582683183384000}
  */
 @interface BindingsE2ESendReport : NSObject <goSeqRefInterface> {
 }
@@ -227,13 +244,17 @@ Returns marshalled E2ESendReport
 
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 - (nonnull instancetype)init;
+// skipped field E2ESendReport.RoundsList with unsupported type: gitlab.com/elixxir/client/bindings.RoundsList
+
 @property (nonatomic) NSData* _Nullable messageID;
 @property (nonatomic) int64_t timestamp;
 - (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
 @end
 
 /**
- * TODO: this seems completely pointless, as the FactList type is effectively the same thing
+ * Fact is an internal fact type for use in the bindings layer
+example marshalled Fact:
+{"Fact":"Zezima","Type":0}
  */
 @interface BindingsFact : NSObject <goSeqRefInterface> {
 }
@@ -269,19 +290,17 @@ Example marshalled Identity:
 @property (nonatomic) NSData* _Nullable dhKeyPrivate;
 @end
 
-/**
- * ListenerID represents the return type of RegisterListener
- */
-@interface BindingsListenerID : NSObject <goSeqRefInterface> {
-}
-@property(strong, readonly) _Nonnull id _ref;
-
-- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
-- (nonnull instancetype)init;
-@end
-
 /**
  * Message is the bindings representation of a receive.Message
+Example Message format:
+{"MessageType":1,
+ "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+ "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+ "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "EphemeralID":17,"Timestamp":1653580439357351000,
+ "Encrypted":false,
+ "RoundId":19}
  */
 @interface BindingsMessage : NSObject <goSeqRefInterface> {
 }
@@ -325,6 +344,21 @@ Example marshalled RestlikeMessage:
 @property (nonatomic) NSString* _Nonnull error;
 @end
 
+/**
+ * Example marshalled roundList object:
+[1001,1003,1006]
+ */
+@interface BindingsRoundsList : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (nonnull instancetype)init;
+// skipped field RoundsList.Rounds with unsupported type: []int
+
+- (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
+@end
+
 /**
  * DownloadAndVerifySignedNdfWithUrl retrieves the NDF from a specified URL.
 The NDF is processed into a protobuf containing a signature which
@@ -345,11 +379,21 @@ which should be set to 32, but can be set higher in certain cases.
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGenerateSecret(long numBytes);
 
+/**
+ * GetDependencies returns the api DEPENDENCIES
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetDependencies(void);
+
 /**
  * GetFactsFromContact accepts a marshalled contact.Contact object, returning its marshalled list of Fact objects
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetFactsFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetGitVersion rturns the api GITVERSION
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetGitVersion(void);
+
 /**
  * GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object
  */
@@ -360,6 +404,11 @@ FOUNDATION_EXPORT NSData* _Nullable BindingsGetIDFromContact(NSData* _Nullable m
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetPubkeyFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetVersion returns the api SEMVER
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetVersion(void);
+
 /**
  * sets level of logging. All logs the set level and above will be displayed
 options are:
@@ -453,10 +502,11 @@ time.
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -472,6 +522,9 @@ time.
 /**
  * MessageDeliveryCallback gets called on the determination if all events
 related to a message send were successful.
+If delivered == true, timedOut == false && roundResults != nil
+If delivered == false, roundResults == nil
+If timedOut == true, delivered == false && roundResults == nil
  */
 @interface BindingsMessageDeliveryCallback : NSObject <goSeqRefInterface, BindingsMessageDeliveryCallback> {
 }
diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Bindings b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Bindings
index 8c6be89d2d97ed4d6b76cfd45d4012c4f7b649c1..79d4ca8d48c3c58f8b660c1644567f0d9a9eaca9 100644
Binary files a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Bindings differ
diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Headers/Bindings.objc.h
index e3d9fefd0c6c4c233b287f3340a56d0d229d72b9..24d5cc9bca1be47de6ccf3a6e1cdfe505003ae1c 100644
--- a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Headers/Bindings.objc.h
+++ b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Headers/Bindings.objc.h
@@ -17,9 +17,9 @@
 @class BindingsE2ESendReport;
 @class BindingsFact;
 @class BindingsIdentity;
-@class BindingsListenerID;
 @class BindingsMessage;
 @class BindingsRestlikeMessage;
+@class BindingsRoundsList;
 @protocol BindingsClientError;
 @class BindingsClientError;
 @protocol BindingsListener;
@@ -38,10 +38,11 @@
 @protocol BindingsListener <NSObject>
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -67,9 +68,10 @@
 // skipped field AuthenticatedConnection.Connection with unsupported type: gitlab.com/elixxir/client/bindings.Connection
 
 - (void)close;
+- (long)getId;
 - (NSData* _Nullable)getPartner;
 - (BOOL)isAuthenticated;
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 - (NSData* _Nullable)sendE2E:(long)mt payload:(NSData* _Nullable)payload error:(NSError* _Nullable* _Nullable)error;
 @end
 
@@ -113,8 +115,7 @@ messages can be sent
  */
 - (BOOL)isNetworkHealthy;
 /**
- * MakeIdentity generates a new cryptographic identity for receving
-messages
+ * MakeIdentity generates a new cryptographic identity for receiving messages
  */
 - (NSData* _Nullable)makeIdentity:(NSError* _Nullable* _Nullable)error;
 /**
@@ -167,6 +168,14 @@ Threads Started:
 		Responds to confirmations of successful rekey operations
  */
 - (BOOL)startNetworkFollower:(long)timeoutMS error:(NSError* _Nullable* _Nullable)error;
+/**
+ * StopNetworkFollower stops the network follower if it is running.
+It returns errors if the Follower is in the wrong status to stop or if it
+fails to stop it.
+if the network follower is running and this fails, the client object will
+most likely be in an unrecoverable state and need to be trashed.
+ */
+- (BOOL)stopNetworkFollower:(NSError* _Nullable* _Nullable)error;
 - (void)unregisterNetworkHealthCB:(int64_t)funcID;
 /**
  * WaitForMessageDelivery allows the caller to get notified if the rounds a
@@ -189,7 +198,7 @@ passed timeout. It will return true if the network is healthy
 @end
 
 /**
- * Connection is the bindings representation of a connect.Connection object that can be tracked
+ * Connection is the bindings representation of a connect.Connection object that can be tracked by id
  */
 @interface BindingsConnection : NSObject <goSeqRefInterface> {
 }
@@ -201,6 +210,10 @@ passed timeout. It will return true if the network is healthy
  * Close deletes this Connection's partner.Manager and releases resources
  */
 - (void)close;
+/**
+ * GetId returns the Connection.id
+ */
+- (long)getId;
 /**
  * GetPartner returns the partner.Manager for this Connection
  */
@@ -210,7 +223,7 @@ passed timeout. It will return true if the network is healthy
 and allows for reading data sent from the partner.Manager
 Returns marshalled ListenerID
  */
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 /**
  * SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
 Returns marshalled E2ESendReport
@@ -220,6 +233,10 @@ Returns marshalled E2ESendReport
 
 /**
  * E2ESendReport is the bindings representation of the return values of SendE2E
+Example E2ESendReport:
+{"RoundList":{"Rounds":[1,5,9]},
+ "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=",
+ "Timestamp":1653582683183384000}
  */
 @interface BindingsE2ESendReport : NSObject <goSeqRefInterface> {
 }
@@ -227,13 +244,17 @@ Returns marshalled E2ESendReport
 
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 - (nonnull instancetype)init;
+// skipped field E2ESendReport.RoundsList with unsupported type: gitlab.com/elixxir/client/bindings.RoundsList
+
 @property (nonatomic) NSData* _Nullable messageID;
 @property (nonatomic) int64_t timestamp;
 - (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
 @end
 
 /**
- * TODO: this seems completely pointless, as the FactList type is effectively the same thing
+ * Fact is an internal fact type for use in the bindings layer
+example marshalled Fact:
+{"Fact":"Zezima","Type":0}
  */
 @interface BindingsFact : NSObject <goSeqRefInterface> {
 }
@@ -269,19 +290,17 @@ Example marshalled Identity:
 @property (nonatomic) NSData* _Nullable dhKeyPrivate;
 @end
 
-/**
- * ListenerID represents the return type of RegisterListener
- */
-@interface BindingsListenerID : NSObject <goSeqRefInterface> {
-}
-@property(strong, readonly) _Nonnull id _ref;
-
-- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
-- (nonnull instancetype)init;
-@end
-
 /**
  * Message is the bindings representation of a receive.Message
+Example Message format:
+{"MessageType":1,
+ "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+ "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+ "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "EphemeralID":17,"Timestamp":1653580439357351000,
+ "Encrypted":false,
+ "RoundId":19}
  */
 @interface BindingsMessage : NSObject <goSeqRefInterface> {
 }
@@ -325,6 +344,21 @@ Example marshalled RestlikeMessage:
 @property (nonatomic) NSString* _Nonnull error;
 @end
 
+/**
+ * Example marshalled roundList object:
+[1001,1003,1006]
+ */
+@interface BindingsRoundsList : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (nonnull instancetype)init;
+// skipped field RoundsList.Rounds with unsupported type: []int
+
+- (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
+@end
+
 /**
  * DownloadAndVerifySignedNdfWithUrl retrieves the NDF from a specified URL.
 The NDF is processed into a protobuf containing a signature which
@@ -345,11 +379,21 @@ which should be set to 32, but can be set higher in certain cases.
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGenerateSecret(long numBytes);
 
+/**
+ * GetDependencies returns the api DEPENDENCIES
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetDependencies(void);
+
 /**
  * GetFactsFromContact accepts a marshalled contact.Contact object, returning its marshalled list of Fact objects
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetFactsFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetGitVersion rturns the api GITVERSION
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetGitVersion(void);
+
 /**
  * GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object
  */
@@ -360,6 +404,11 @@ FOUNDATION_EXPORT NSData* _Nullable BindingsGetIDFromContact(NSData* _Nullable m
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetPubkeyFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetVersion returns the api SEMVER
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetVersion(void);
+
 /**
  * sets level of logging. All logs the set level and above will be displayed
 options are:
@@ -453,10 +502,11 @@ time.
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -472,6 +522,9 @@ time.
 /**
  * MessageDeliveryCallback gets called on the determination if all events
 related to a message send were successful.
+If delivered == true, timedOut == false && roundResults != nil
+If delivered == false, roundResults == nil
+If timedOut == true, delivered == false && roundResults == nil
  */
 @interface BindingsMessageDeliveryCallback : NSObject <goSeqRefInterface, BindingsMessageDeliveryCallback> {
 }
diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings
index 8c6be89d2d97ed4d6b76cfd45d4012c4f7b649c1..79d4ca8d48c3c58f8b660c1644567f0d9a9eaca9 100644
Binary files a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Bindings differ
diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h
index e3d9fefd0c6c4c233b287f3340a56d0d229d72b9..24d5cc9bca1be47de6ccf3a6e1cdfe505003ae1c 100644
--- a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h
+++ b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/A/Headers/Bindings.objc.h
@@ -17,9 +17,9 @@
 @class BindingsE2ESendReport;
 @class BindingsFact;
 @class BindingsIdentity;
-@class BindingsListenerID;
 @class BindingsMessage;
 @class BindingsRestlikeMessage;
+@class BindingsRoundsList;
 @protocol BindingsClientError;
 @class BindingsClientError;
 @protocol BindingsListener;
@@ -38,10 +38,11 @@
 @protocol BindingsListener <NSObject>
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -67,9 +68,10 @@
 // skipped field AuthenticatedConnection.Connection with unsupported type: gitlab.com/elixxir/client/bindings.Connection
 
 - (void)close;
+- (long)getId;
 - (NSData* _Nullable)getPartner;
 - (BOOL)isAuthenticated;
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 - (NSData* _Nullable)sendE2E:(long)mt payload:(NSData* _Nullable)payload error:(NSError* _Nullable* _Nullable)error;
 @end
 
@@ -113,8 +115,7 @@ messages can be sent
  */
 - (BOOL)isNetworkHealthy;
 /**
- * MakeIdentity generates a new cryptographic identity for receving
-messages
+ * MakeIdentity generates a new cryptographic identity for receiving messages
  */
 - (NSData* _Nullable)makeIdentity:(NSError* _Nullable* _Nullable)error;
 /**
@@ -167,6 +168,14 @@ Threads Started:
 		Responds to confirmations of successful rekey operations
  */
 - (BOOL)startNetworkFollower:(long)timeoutMS error:(NSError* _Nullable* _Nullable)error;
+/**
+ * StopNetworkFollower stops the network follower if it is running.
+It returns errors if the Follower is in the wrong status to stop or if it
+fails to stop it.
+if the network follower is running and this fails, the client object will
+most likely be in an unrecoverable state and need to be trashed.
+ */
+- (BOOL)stopNetworkFollower:(NSError* _Nullable* _Nullable)error;
 - (void)unregisterNetworkHealthCB:(int64_t)funcID;
 /**
  * WaitForMessageDelivery allows the caller to get notified if the rounds a
@@ -189,7 +198,7 @@ passed timeout. It will return true if the network is healthy
 @end
 
 /**
- * Connection is the bindings representation of a connect.Connection object that can be tracked
+ * Connection is the bindings representation of a connect.Connection object that can be tracked by id
  */
 @interface BindingsConnection : NSObject <goSeqRefInterface> {
 }
@@ -201,6 +210,10 @@ passed timeout. It will return true if the network is healthy
  * Close deletes this Connection's partner.Manager and releases resources
  */
 - (void)close;
+/**
+ * GetId returns the Connection.id
+ */
+- (long)getId;
 /**
  * GetPartner returns the partner.Manager for this Connection
  */
@@ -210,7 +223,7 @@ passed timeout. It will return true if the network is healthy
 and allows for reading data sent from the partner.Manager
 Returns marshalled ListenerID
  */
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 /**
  * SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
 Returns marshalled E2ESendReport
@@ -220,6 +233,10 @@ Returns marshalled E2ESendReport
 
 /**
  * E2ESendReport is the bindings representation of the return values of SendE2E
+Example E2ESendReport:
+{"RoundList":{"Rounds":[1,5,9]},
+ "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=",
+ "Timestamp":1653582683183384000}
  */
 @interface BindingsE2ESendReport : NSObject <goSeqRefInterface> {
 }
@@ -227,13 +244,17 @@ Returns marshalled E2ESendReport
 
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 - (nonnull instancetype)init;
+// skipped field E2ESendReport.RoundsList with unsupported type: gitlab.com/elixxir/client/bindings.RoundsList
+
 @property (nonatomic) NSData* _Nullable messageID;
 @property (nonatomic) int64_t timestamp;
 - (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
 @end
 
 /**
- * TODO: this seems completely pointless, as the FactList type is effectively the same thing
+ * Fact is an internal fact type for use in the bindings layer
+example marshalled Fact:
+{"Fact":"Zezima","Type":0}
  */
 @interface BindingsFact : NSObject <goSeqRefInterface> {
 }
@@ -269,19 +290,17 @@ Example marshalled Identity:
 @property (nonatomic) NSData* _Nullable dhKeyPrivate;
 @end
 
-/**
- * ListenerID represents the return type of RegisterListener
- */
-@interface BindingsListenerID : NSObject <goSeqRefInterface> {
-}
-@property(strong, readonly) _Nonnull id _ref;
-
-- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
-- (nonnull instancetype)init;
-@end
-
 /**
  * Message is the bindings representation of a receive.Message
+Example Message format:
+{"MessageType":1,
+ "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+ "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+ "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "EphemeralID":17,"Timestamp":1653580439357351000,
+ "Encrypted":false,
+ "RoundId":19}
  */
 @interface BindingsMessage : NSObject <goSeqRefInterface> {
 }
@@ -325,6 +344,21 @@ Example marshalled RestlikeMessage:
 @property (nonatomic) NSString* _Nonnull error;
 @end
 
+/**
+ * Example marshalled roundList object:
+[1001,1003,1006]
+ */
+@interface BindingsRoundsList : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (nonnull instancetype)init;
+// skipped field RoundsList.Rounds with unsupported type: []int
+
+- (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
+@end
+
 /**
  * DownloadAndVerifySignedNdfWithUrl retrieves the NDF from a specified URL.
 The NDF is processed into a protobuf containing a signature which
@@ -345,11 +379,21 @@ which should be set to 32, but can be set higher in certain cases.
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGenerateSecret(long numBytes);
 
+/**
+ * GetDependencies returns the api DEPENDENCIES
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetDependencies(void);
+
 /**
  * GetFactsFromContact accepts a marshalled contact.Contact object, returning its marshalled list of Fact objects
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetFactsFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetGitVersion rturns the api GITVERSION
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetGitVersion(void);
+
 /**
  * GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object
  */
@@ -360,6 +404,11 @@ FOUNDATION_EXPORT NSData* _Nullable BindingsGetIDFromContact(NSData* _Nullable m
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetPubkeyFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetVersion returns the api SEMVER
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetVersion(void);
+
 /**
  * sets level of logging. All logs the set level and above will be displayed
 options are:
@@ -453,10 +502,11 @@ time.
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -472,6 +522,9 @@ time.
 /**
  * MessageDeliveryCallback gets called on the determination if all events
 related to a message send were successful.
+If delivered == true, timedOut == false && roundResults != nil
+If delivered == false, roundResults == nil
+If timedOut == true, delivered == false && roundResults == nil
  */
 @interface BindingsMessageDeliveryCallback : NSObject <goSeqRefInterface, BindingsMessageDeliveryCallback> {
 }
diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Bindings b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Bindings
index 8c6be89d2d97ed4d6b76cfd45d4012c4f7b649c1..79d4ca8d48c3c58f8b660c1644567f0d9a9eaca9 100644
Binary files a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Bindings and b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Bindings differ
diff --git a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Headers/Bindings.objc.h b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Headers/Bindings.objc.h
index e3d9fefd0c6c4c233b287f3340a56d0d229d72b9..24d5cc9bca1be47de6ccf3a6e1cdfe505003ae1c 100644
--- a/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Headers/Bindings.objc.h
+++ b/Frameworks/Bindings.xcframework/ios-arm64_x86_64-simulator/Bindings.framework/Versions/Current/Headers/Bindings.objc.h
@@ -17,9 +17,9 @@
 @class BindingsE2ESendReport;
 @class BindingsFact;
 @class BindingsIdentity;
-@class BindingsListenerID;
 @class BindingsMessage;
 @class BindingsRestlikeMessage;
+@class BindingsRoundsList;
 @protocol BindingsClientError;
 @class BindingsClientError;
 @protocol BindingsListener;
@@ -38,10 +38,11 @@
 @protocol BindingsListener <NSObject>
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -67,9 +68,10 @@
 // skipped field AuthenticatedConnection.Connection with unsupported type: gitlab.com/elixxir/client/bindings.Connection
 
 - (void)close;
+- (long)getId;
 - (NSData* _Nullable)getPartner;
 - (BOOL)isAuthenticated;
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 - (NSData* _Nullable)sendE2E:(long)mt payload:(NSData* _Nullable)payload error:(NSError* _Nullable* _Nullable)error;
 @end
 
@@ -113,8 +115,7 @@ messages can be sent
  */
 - (BOOL)isNetworkHealthy;
 /**
- * MakeIdentity generates a new cryptographic identity for receving
-messages
+ * MakeIdentity generates a new cryptographic identity for receiving messages
  */
 - (NSData* _Nullable)makeIdentity:(NSError* _Nullable* _Nullable)error;
 /**
@@ -167,6 +168,14 @@ Threads Started:
 		Responds to confirmations of successful rekey operations
  */
 - (BOOL)startNetworkFollower:(long)timeoutMS error:(NSError* _Nullable* _Nullable)error;
+/**
+ * StopNetworkFollower stops the network follower if it is running.
+It returns errors if the Follower is in the wrong status to stop or if it
+fails to stop it.
+if the network follower is running and this fails, the client object will
+most likely be in an unrecoverable state and need to be trashed.
+ */
+- (BOOL)stopNetworkFollower:(NSError* _Nullable* _Nullable)error;
 - (void)unregisterNetworkHealthCB:(int64_t)funcID;
 /**
  * WaitForMessageDelivery allows the caller to get notified if the rounds a
@@ -189,7 +198,7 @@ passed timeout. It will return true if the network is healthy
 @end
 
 /**
- * Connection is the bindings representation of a connect.Connection object that can be tracked
+ * Connection is the bindings representation of a connect.Connection object that can be tracked by id
  */
 @interface BindingsConnection : NSObject <goSeqRefInterface> {
 }
@@ -201,6 +210,10 @@ passed timeout. It will return true if the network is healthy
  * Close deletes this Connection's partner.Manager and releases resources
  */
 - (void)close;
+/**
+ * GetId returns the Connection.id
+ */
+- (long)getId;
 /**
  * GetPartner returns the partner.Manager for this Connection
  */
@@ -210,7 +223,7 @@ passed timeout. It will return true if the network is healthy
 and allows for reading data sent from the partner.Manager
 Returns marshalled ListenerID
  */
-- (NSData* _Nullable)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
+- (void)registerListener:(long)messageType newListener:(id<BindingsListener> _Nullable)newListener;
 /**
  * SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
 Returns marshalled E2ESendReport
@@ -220,6 +233,10 @@ Returns marshalled E2ESendReport
 
 /**
  * E2ESendReport is the bindings representation of the return values of SendE2E
+Example E2ESendReport:
+{"RoundList":{"Rounds":[1,5,9]},
+ "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=",
+ "Timestamp":1653582683183384000}
  */
 @interface BindingsE2ESendReport : NSObject <goSeqRefInterface> {
 }
@@ -227,13 +244,17 @@ Returns marshalled E2ESendReport
 
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 - (nonnull instancetype)init;
+// skipped field E2ESendReport.RoundsList with unsupported type: gitlab.com/elixxir/client/bindings.RoundsList
+
 @property (nonatomic) NSData* _Nullable messageID;
 @property (nonatomic) int64_t timestamp;
 - (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
 @end
 
 /**
- * TODO: this seems completely pointless, as the FactList type is effectively the same thing
+ * Fact is an internal fact type for use in the bindings layer
+example marshalled Fact:
+{"Fact":"Zezima","Type":0}
  */
 @interface BindingsFact : NSObject <goSeqRefInterface> {
 }
@@ -269,19 +290,17 @@ Example marshalled Identity:
 @property (nonatomic) NSData* _Nullable dhKeyPrivate;
 @end
 
-/**
- * ListenerID represents the return type of RegisterListener
- */
-@interface BindingsListenerID : NSObject <goSeqRefInterface> {
-}
-@property(strong, readonly) _Nonnull id _ref;
-
-- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
-- (nonnull instancetype)init;
-@end
-
 /**
  * Message is the bindings representation of a receive.Message
+Example Message format:
+{"MessageType":1,
+ "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+ "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+ "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+ "EphemeralID":17,"Timestamp":1653580439357351000,
+ "Encrypted":false,
+ "RoundId":19}
  */
 @interface BindingsMessage : NSObject <goSeqRefInterface> {
 }
@@ -325,6 +344,21 @@ Example marshalled RestlikeMessage:
 @property (nonatomic) NSString* _Nonnull error;
 @end
 
+/**
+ * Example marshalled roundList object:
+[1001,1003,1006]
+ */
+@interface BindingsRoundsList : NSObject <goSeqRefInterface> {
+}
+@property(strong, readonly) _Nonnull id _ref;
+
+- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
+- (nonnull instancetype)init;
+// skipped field RoundsList.Rounds with unsupported type: []int
+
+- (NSData* _Nullable)marshal:(NSError* _Nullable* _Nullable)error;
+@end
+
 /**
  * DownloadAndVerifySignedNdfWithUrl retrieves the NDF from a specified URL.
 The NDF is processed into a protobuf containing a signature which
@@ -345,11 +379,21 @@ which should be set to 32, but can be set higher in certain cases.
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGenerateSecret(long numBytes);
 
+/**
+ * GetDependencies returns the api DEPENDENCIES
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetDependencies(void);
+
 /**
  * GetFactsFromContact accepts a marshalled contact.Contact object, returning its marshalled list of Fact objects
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetFactsFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetGitVersion rturns the api GITVERSION
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetGitVersion(void);
+
 /**
  * GetIDFromContact accepts a marshalled contact.Contact object & returns a marshalled id.ID object
  */
@@ -360,6 +404,11 @@ FOUNDATION_EXPORT NSData* _Nullable BindingsGetIDFromContact(NSData* _Nullable m
  */
 FOUNDATION_EXPORT NSData* _Nullable BindingsGetPubkeyFromContact(NSData* _Nullable marshaled, NSError* _Nullable* _Nullable error);
 
+/**
+ * GetVersion returns the api SEMVER
+ */
+FOUNDATION_EXPORT NSString* _Nonnull BindingsGetVersion(void);
+
 /**
  * sets level of logging. All logs the set level and above will be displayed
 options are:
@@ -453,10 +502,11 @@ time.
 - (nonnull instancetype)initWithRef:(_Nonnull id)ref;
 /**
  * Hear is called to receive a message in the UI
+Accepts a marshalled Message object
  */
 - (void)hear:(NSData* _Nullable)item;
 /**
- * Returns a name, used for debugging
+ * Name returns a name, used for debugging
  */
 - (NSString* _Nonnull)name;
 @end
@@ -472,6 +522,9 @@ time.
 /**
  * MessageDeliveryCallback gets called on the determination if all events
 related to a message send were successful.
+If delivered == true, timedOut == false && roundResults != nil
+If delivered == false, roundResults == nil
+If timedOut == true, delivered == false && roundResults == nil
  */
 @interface BindingsMessageDeliveryCallback : NSObject <goSeqRefInterface, BindingsMessageDeliveryCallback> {
 }
diff --git a/README.md b/README.md
index 49d8fbb44a5398de29a79d5b13be47e1ba0db1d0..5a65a5b5b1fe7f15909ce3ac57f2027eb78811a0 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,12 @@
 ![Swift 5.6](https://img.shields.io/badge/swift-5.6-orange.svg)
 ![platform iOS](https://img.shields.io/badge/platform-iOS-blue.svg)
 
+## 📖 Usage
+
+Add `ElixxirDAppsSDK` library as a dependency to your project using Swift Package Manager.
+
+For usage examples, checkout included example iOS application.
+
 ## 🛠 Development
 
 Open `ElixxirDAppsSDK.xcworkspace` in Xcode (≥13.4).
diff --git a/Sources/ElixxirDAppsSDK/Cancellable.swift b/Sources/ElixxirDAppsSDK/Cancellable.swift
new file mode 100644
index 0000000000000000000000000000000000000000..1984e3f10916319e9e88959aa7f21f554d0d0e27
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/Cancellable.swift
@@ -0,0 +1,11 @@
+public final class Cancellable {
+  public init(cancel: @escaping () -> Void) {
+    self.cancel = cancel
+  }
+
+  deinit {
+    cancel()
+  }
+
+  public let cancel: () -> Void
+}
diff --git a/Sources/ElixxirDAppsSDK/Client.swift b/Sources/ElixxirDAppsSDK/Client.swift
index 49a970947ecb0c5b5e80a3965d1dc0399855fbab..c47d98c4009674a9fd144a0ce3b323f4838ff681 100644
--- a/Sources/ElixxirDAppsSDK/Client.swift
+++ b/Sources/ElixxirDAppsSDK/Client.swift
@@ -1,17 +1,51 @@
 import Bindings
 
 public struct Client {
-
+  public var getId: ClientIdProvider
+  public var hasRunningProcesses: ClientProcessStatusProvider
+  public var networkFollower: NetworkFollower
+  public var waitForNetwork: NetworkWaiter
+  public var isNetworkHealthy: NetworkHealthProvider
+  public var monitorNetworkHealth: NetworkHealthListener
+  public var listenErrors: ClientErrorListener
+  public var makeIdentity: IdentityMaker
+  public var connect: ConnectionMaker
+  public var getContactFromIdentity: ContactFromIdentityProvider
+  public var waitForDelivery: MessageDeliveryWaiter
 }
 
 extension Client {
   public static func live(bindingsClient: BindingsClient) -> Client {
-    Client()
+    Client(
+      getId: .live(bindingsClient: bindingsClient),
+      hasRunningProcesses: .live(bindingsClient: bindingsClient),
+      networkFollower: .live(bindingsClient: bindingsClient),
+      waitForNetwork: .live(bindingsClient: bindingsClient),
+      isNetworkHealthy: .live(bindingsClient: bindingsClient),
+      monitorNetworkHealth: .live(bindingsClient: bindingsClient),
+      listenErrors: .live(bindingsClient: bindingsClient),
+      makeIdentity: .live(bindingsClient: bindingsClient),
+      connect: .live(bindingsClient: bindingsClient),
+      getContactFromIdentity: .live(bindingsClient: bindingsClient),
+      waitForDelivery: .live(bindingsClient: bindingsClient)
+    )
   }
 }
 
 #if DEBUG
 extension Client {
-  public static let failing = Client()
+  public static let failing = Client(
+    getId: .failing,
+    hasRunningProcesses: .failing,
+    networkFollower: .failing,
+    waitForNetwork: .failing,
+    isNetworkHealthy: .failing,
+    monitorNetworkHealth: .failing,
+    listenErrors: .failing,
+    makeIdentity: .failing,
+    connect: .failing,
+    getContactFromIdentity: .failing,
+    waitForDelivery: .failing
+  )
 }
 #endif
diff --git a/Sources/ElixxirDAppsSDK/ClientCreator.swift b/Sources/ElixxirDAppsSDK/ClientCreator.swift
index e048227edb7b0db96fc42362725acb2bbf519d44..5049fbcec655896226e11f8f2751c94181910d75 100644
--- a/Sources/ElixxirDAppsSDK/ClientCreator.swift
+++ b/Sources/ElixxirDAppsSDK/ClientCreator.swift
@@ -1,30 +1,35 @@
 import Bindings
 
 public struct ClientCreator {
-  public var create: (URL, Data, Data) throws -> Void
+  public var create: (URL, Data, Data, String?) throws -> Void
 
-  public func callAsFunction(directoryURL: URL, ndf: Data, password: Data) throws {
-    try create(directoryURL, ndf, password)
+  public func callAsFunction(
+    directoryURL: URL,
+    ndf: Data,
+    password: Data,
+    regCode: String? = nil
+  ) throws {
+    try create(directoryURL, ndf, password, regCode)
   }
 }
 
 extension ClientCreator {
-  public static let live = ClientCreator { directoryURL, ndf, password in
+  public static let live = ClientCreator { directoryURL, ndf, password, regCode in
     var error: NSError?
     let network = String(data: ndf, encoding: .utf8)!
-    let created = BindingsNewClient(network, directoryURL.path, password, nil, &error)
+    let created = BindingsNewClient(network, directoryURL.path, password, regCode, &error)
     if let error = error {
       throw error
     }
     if !created {
-      throw BindingsNewClientUnknownError()
+      fatalError("BindingsNewClient returned `false` without providing error")
     }
   }
 }
 
 #if DEBUG
 extension ClientCreator {
-  public static let failing = ClientCreator { _, _, _ in
+  public static let failing = ClientCreator { _, _, _, _ in
     struct NotImplemented: Error {}
     throw NotImplemented()
   }
diff --git a/Sources/ElixxirDAppsSDK/ClientError.swift b/Sources/ElixxirDAppsSDK/ClientError.swift
new file mode 100644
index 0000000000000000000000000000000000000000..a0a911788f6828e9fc3632a75efd6394d669b6c4
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ClientError.swift
@@ -0,0 +1,11 @@
+public struct ClientError: Error, Equatable {
+  public init(source: String, message: String, trace: String) {
+    self.source = source
+    self.message = message
+    self.trace = trace
+  }
+
+  public var source: String
+  public var message: String
+  public var trace: String
+}
diff --git a/Sources/ElixxirDAppsSDK/ClientErrorListener.swift b/Sources/ElixxirDAppsSDK/ClientErrorListener.swift
new file mode 100644
index 0000000000000000000000000000000000000000..5e7b0446caf0c9d3becf7e885295a91e3eb6d0eb
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ClientErrorListener.swift
@@ -0,0 +1,48 @@
+import Bindings
+
+public struct ClientErrorListener {
+  public var listen: (@escaping (ClientError) -> Void) -> Void
+
+  public func callAsFunction(callback: @escaping (ClientError) -> Void) {
+    listen(callback)
+  }
+}
+
+extension ClientErrorListener {
+  public static func live(bindingsClient: BindingsClient) -> ClientErrorListener {
+    ClientErrorListener { callback in
+      let listener = Listener(onReport: callback)
+      bindingsClient.registerErrorCallback(listener)
+    }
+  }
+}
+
+private final class Listener: NSObject, BindingsClientErrorProtocol {
+  init(onReport: @escaping (ClientError) -> Void) {
+    self.onReport = onReport
+    super.init()
+  }
+
+  let onReport: (ClientError) -> Void
+
+  func report(_ source: String?, message: String?, trace: String?) {
+    guard let source = source else {
+      fatalError("BindingsClientError.source is `nil`")
+    }
+    guard let message = message else {
+      fatalError("BindingsClientError.message is `nil`")
+    }
+    guard let trace = trace else {
+      fatalError("BindingsClientError.trace is `nil`")
+    }
+    onReport(ClientError(source: source, message: message, trace: trace))
+  }
+}
+
+#if DEBUG
+extension ClientErrorListener {
+  public static let failing = ClientErrorListener { _ in
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ClientIdProvider.swift b/Sources/ElixxirDAppsSDK/ClientIdProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..259a64b2510afcae200c7e49e8613bc3858fc7ca
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ClientIdProvider.swift
@@ -0,0 +1,23 @@
+import Bindings
+
+public struct ClientIdProvider {
+  public var get: () -> Int
+
+  public func callAsFunction() -> Int {
+    get()
+  }
+}
+
+extension ClientIdProvider {
+  public static func live(bindingsClient: BindingsClient) -> ClientIdProvider {
+    ClientIdProvider(get: bindingsClient.getID)
+  }
+}
+
+#if DEBUG
+extension ClientIdProvider {
+  public static let failing = ClientIdProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ClientLoader.swift b/Sources/ElixxirDAppsSDK/ClientLoader.swift
index 632f01070f054694ab261c5b045e6956060b29a2..7c1ca48a5972eb644509ac569b167eeb31a64172 100644
--- a/Sources/ElixxirDAppsSDK/ClientLoader.swift
+++ b/Sources/ElixxirDAppsSDK/ClientLoader.swift
@@ -12,9 +12,11 @@ extension ClientLoader {
   public static let live = ClientLoader { directoryURL, password in
     var error: NSError?
     let bindingsClient = BindingsLogin(directoryURL.path, password, &error)
-    if let error = error { throw error }
+    if let error = error {
+      throw error
+    }
     guard let bindingsClient = bindingsClient else {
-      throw BindingsLoginUnknownError()
+      fatalError("BindingsLogin returned `nil` without providing error")
     }
     return Client.live(bindingsClient: bindingsClient)
   }
diff --git a/Sources/ElixxirDAppsSDK/ClientProcessStatusProvider.swift b/Sources/ElixxirDAppsSDK/ClientProcessStatusProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..297f00afde36933b6fb929e7fbde25ce0d67d7da
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ClientProcessStatusProvider.swift
@@ -0,0 +1,23 @@
+import Bindings
+
+public struct ClientProcessStatusProvider {
+  public var get: () -> Bool
+
+  public func callAsFunction() -> Bool {
+    get()
+  }
+}
+
+extension ClientProcessStatusProvider {
+  public static func live(bindingsClient: BindingsClient) -> ClientProcessStatusProvider {
+    ClientProcessStatusProvider(get: bindingsClient.hasRunningProcessies)
+  }
+}
+
+#if DEBUG
+extension ClientProcessStatusProvider {
+  public static let failing = ClientProcessStatusProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ClientStorage.swift b/Sources/ElixxirDAppsSDK/ClientStorage.swift
index 8471fa783efd5d7cd6ce80007bd9708d17ce3229..7c18828b69e30f48fd14c69ec16913d2785bc784 100644
--- a/Sources/ElixxirDAppsSDK/ClientStorage.swift
+++ b/Sources/ElixxirDAppsSDK/ClientStorage.swift
@@ -30,7 +30,7 @@ extension ClientStorage {
       },
       createClient: {
         let ndf = try downloadNDF(environment)
-        let password = try generatePassword()
+        let password = generatePassword()
         try passwordStorage.save(password)
         try? fileManager.removeItem(at: directoryURL)
         try? fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true)
diff --git a/Sources/ElixxirDAppsSDK/Connection.swift b/Sources/ElixxirDAppsSDK/Connection.swift
new file mode 100644
index 0000000000000000000000000000000000000000..00e18a81fef8334f4e329ff2acb5931a7d58d0ce
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/Connection.swift
@@ -0,0 +1,51 @@
+import Bindings
+
+public struct Connection {
+  public var getId: ConnectionIdProvider
+  public var isAuthenticated: ConnectionAuthStatusProvider
+  public var getPartner: ConnectionPartnerProvider
+  public var send: MessageSender
+  public var listen: MessageListener
+  public var close: ConnectionCloser
+}
+
+extension Connection {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> Connection {
+    Connection(
+      getId: .live(bindingsConnection: bindingsConnection),
+      isAuthenticated: .live(bindingsConnection: bindingsConnection),
+      getPartner: .live(bindingsConnection: bindingsConnection),
+      send: .live(bindingsConnection: bindingsConnection),
+      listen: .live(bindingsConnection: bindingsConnection),
+      close: .live(bindingsConnection: bindingsConnection)
+    )
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> Connection {
+    Connection(
+      getId: .live(bindingsAuthenticatedConnection: bindingsAuthenticatedConnection),
+      isAuthenticated: .live(bindingsAuthenticatedConnection: bindingsAuthenticatedConnection),
+      getPartner: .live(bindingsAuthenticatedConnection: bindingsAuthenticatedConnection),
+      send: .live(bindingsAuthenticatedConnection: bindingsAuthenticatedConnection),
+      listen: .live(bindingsAuthenticatedConnection: bindingsAuthenticatedConnection),
+      close: .live(bindingsAuthenticatedConnection: bindingsAuthenticatedConnection)
+    )
+  }
+}
+
+#if DEBUG
+extension Connection {
+  public static let failing = Connection(
+    getId: .failing,
+    isAuthenticated: .failing,
+    getPartner: .failing,
+    send: .failing,
+    listen: .failing,
+    close: .failing
+  )
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ConnectionAuthStatusProvider.swift b/Sources/ElixxirDAppsSDK/ConnectionAuthStatusProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..d42e78f3caf3d66b2b4756b5986c9ea6916298fc
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ConnectionAuthStatusProvider.swift
@@ -0,0 +1,33 @@
+import Bindings
+
+public struct ConnectionAuthStatusProvider {
+  public var isAuthenticated: () -> Bool
+
+  public func callAsFunction() -> Bool {
+    isAuthenticated()
+  }
+}
+
+extension ConnectionAuthStatusProvider {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> ConnectionAuthStatusProvider {
+    ConnectionAuthStatusProvider { false }
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> ConnectionAuthStatusProvider {
+    ConnectionAuthStatusProvider(
+      isAuthenticated: bindingsAuthenticatedConnection.isAuthenticated
+    )
+  }
+}
+
+#if DEBUG
+extension ConnectionAuthStatusProvider {
+  public static let failing = ConnectionAuthStatusProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ConnectionCloser.swift b/Sources/ElixxirDAppsSDK/ConnectionCloser.swift
new file mode 100644
index 0000000000000000000000000000000000000000..c74c62facc24cdbd70df2c1480dbd4424cf3925c
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ConnectionCloser.swift
@@ -0,0 +1,31 @@
+import Bindings
+
+public struct ConnectionCloser {
+  public var close: () -> Void
+
+  public func callAsFunction() {
+    close()
+  }
+}
+
+extension ConnectionCloser {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> ConnectionCloser {
+    ConnectionCloser(close: bindingsConnection.close)
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> ConnectionCloser {
+    ConnectionCloser(close: bindingsAuthenticatedConnection.close)
+  }
+}
+
+#if DEBUG
+extension ConnectionCloser {
+  public static let failing = ConnectionCloser {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ConnectionIdProvider.swift b/Sources/ElixxirDAppsSDK/ConnectionIdProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..3261dfd46f312e337bd586a0f21930087a21c273
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ConnectionIdProvider.swift
@@ -0,0 +1,31 @@
+import Bindings
+
+public struct ConnectionIdProvider {
+  public var get: () -> Int
+
+  public func callAsFunction() -> Int {
+    get()
+  }
+}
+
+extension ConnectionIdProvider {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> ConnectionIdProvider {
+    ConnectionIdProvider(get: bindingsConnection.getId)
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> ConnectionIdProvider {
+    ConnectionIdProvider(get: bindingsAuthenticatedConnection.getId)
+  }
+}
+
+#if DEBUG
+extension ConnectionIdProvider {
+  public static let failing = ConnectionIdProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ConnectionMaker.swift b/Sources/ElixxirDAppsSDK/ConnectionMaker.swift
new file mode 100644
index 0000000000000000000000000000000000000000..a898075f447753cba661589313ba86212727ebae
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ConnectionMaker.swift
@@ -0,0 +1,44 @@
+import Bindings
+
+public struct ConnectionMaker {
+  public var connect: (Bool, Data, Data) throws -> Connection
+
+  public func callAsFunction(
+    withAuthentication: Bool,
+    recipientContact: Data,
+    myIdentity: Data
+  ) throws -> Connection {
+    try connect(withAuthentication, recipientContact, myIdentity)
+  }
+}
+
+extension ConnectionMaker {
+  public static func live(bindingsClient: BindingsClient) -> ConnectionMaker {
+    ConnectionMaker { withAuthentication, recipientContact, myIdentity in
+      if withAuthentication {
+        return Connection.live(
+          bindingsConnection: try bindingsClient.connect(
+            recipientContact,
+            myIdentity: myIdentity
+          )
+        )
+      } else {
+        return Connection.live(
+          bindingsAuthenticatedConnection: try bindingsClient.connect(
+            withAuthentication: recipientContact,
+            myIdentity: myIdentity
+          )
+        )
+      }
+    }
+  }
+}
+
+#if DEBUG
+extension ConnectionMaker {
+  public static let failing = ConnectionMaker { _, _, _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ConnectionPartnerProvider.swift b/Sources/ElixxirDAppsSDK/ConnectionPartnerProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..8d2bcbce76c9693f3b4a615d43a5f41193551c99
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ConnectionPartnerProvider.swift
@@ -0,0 +1,41 @@
+import Bindings
+
+public struct ConnectionPartnerProvider {
+  public var get: () -> Data
+
+  public func callAsFunction() -> Data {
+    get()
+  }
+}
+
+extension ConnectionPartnerProvider {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> ConnectionPartnerProvider {
+    ConnectionPartnerProvider {
+      guard let data = bindingsConnection.getPartner() else {
+        fatalError("BindingsConnection.getPartner returned `nil`")
+      }
+      return data
+    }
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> ConnectionPartnerProvider {
+    ConnectionPartnerProvider {
+      guard let data = bindingsAuthenticatedConnection.getPartner() else {
+        fatalError("BindingsAuthenticatedConnection.getPartner returned `nil`")
+      }
+      return data
+    }
+  }
+}
+
+#if DEBUG
+extension ConnectionPartnerProvider {
+  public static let failing = ConnectionPartnerProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ContactFactsProvider.swift b/Sources/ElixxirDAppsSDK/ContactFactsProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..e2adebfbbb6b2e7143cc4abe074ee352f8bc400b
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ContactFactsProvider.swift
@@ -0,0 +1,32 @@
+import Bindings
+
+public struct ContactFactsProvider {
+  public var get: (Data) throws -> Data
+
+  public func callAsFunction(contact: Data) throws -> Data {
+    try get(contact)
+  }
+}
+
+extension ContactFactsProvider {
+  public static let live = ContactFactsProvider { contact in
+    var error: NSError?
+    let facts = BindingsGetFactsFromContact(contact, &error)
+    if let error = error {
+      throw error
+    }
+    guard let facts = facts else {
+      fatalError("BindingsGetFactsFromContact returned `nil` without providing error")
+    }
+    return facts
+  }
+}
+
+#if DEBUG
+extension ContactFactsProvider {
+  public static let failing = ContactFactsProvider { _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ContactFactsSetter.swift b/Sources/ElixxirDAppsSDK/ContactFactsSetter.swift
new file mode 100644
index 0000000000000000000000000000000000000000..0fca1df3f70537edc4e8fe62800d6ae093942f88
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ContactFactsSetter.swift
@@ -0,0 +1,32 @@
+import Bindings
+
+public struct ContactFactsSetter {
+  public var set: (Data, Data) throws -> Data
+
+  public func callAsFunction(contact: Data, facts: Data) throws -> Data {
+    try set(contact, facts)
+  }
+}
+
+extension ContactFactsSetter {
+  public static let live = ContactFactsSetter { contact, facts in
+    var error: NSError?
+    let updatedContact = BindingsSetFactsOnContact(contact, facts, &error)
+    if let error = error {
+      throw error
+    }
+    guard let updatedContact = updatedContact else {
+      fatalError("BindingsSetFactsOnContact returned `nil` without providing error")
+    }
+    return updatedContact
+  }
+}
+
+#if DEBUG
+extension ContactFactsSetter {
+  public static let failing = ContactFactsSetter { _, _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ContactFromIdentityProvider.swift b/Sources/ElixxirDAppsSDK/ContactFromIdentityProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..1643a0cdc4a6b2979d67f0112e4f5cc0398859da
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ContactFromIdentityProvider.swift
@@ -0,0 +1,24 @@
+import Bindings
+
+public struct ContactFromIdentityProvider {
+  public var get: (Data) throws -> Data
+
+  public func callAsFunction(identity: Data) throws -> Data {
+    try get(identity)
+  }
+}
+
+extension ContactFromIdentityProvider {
+  public static func live(bindingsClient: BindingsClient) -> ContactFromIdentityProvider {
+    ContactFromIdentityProvider(get: bindingsClient.getContactFromIdentity(_:))
+  }
+}
+
+#if DEBUG
+extension ContactFromIdentityProvider {
+  public static let failing = ContactFromIdentityProvider { _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ContactIdProvider.swift b/Sources/ElixxirDAppsSDK/ContactIdProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..ea291167c1cbd08555b33326b9609c170306eb14
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ContactIdProvider.swift
@@ -0,0 +1,32 @@
+import Bindings
+
+public struct ContactIdProvider {
+  public var get: (Data) throws -> Data
+
+  public func callAsFunction(contact: Data) throws -> Data {
+    try get(contact)
+  }
+}
+
+extension ContactIdProvider {
+  public static let live = ContactIdProvider { contact in
+    var error: NSError?
+    let id = BindingsGetIDFromContact(contact, &error)
+    if let error = error {
+      throw error
+    }
+    guard let id = id else {
+      fatalError("BindingsGetIDFromContact returned `nil` without providing error")
+    }
+    return id
+  }
+}
+
+#if DEBUG
+extension ContactIdProvider {
+  public static let failing = ContactIdProvider { _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/ContactPubkeyProvider.swift b/Sources/ElixxirDAppsSDK/ContactPubkeyProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..4f97eed0d5fc5c6a80dd7810eac225621930a36b
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ContactPubkeyProvider.swift
@@ -0,0 +1,32 @@
+import Bindings
+
+public struct ContactPubkeyProvider {
+  public var get: (Data) throws -> Data
+
+  public func callAsFunction(contact: Data) throws -> Data {
+    try get(contact)
+  }
+}
+
+extension ContactPubkeyProvider {
+  public static let live = ContactPubkeyProvider { contact in
+    var error: NSError?
+    let pubkey = BindingsGetPubkeyFromContact(contact, &error)
+    if let error = error {
+      throw error
+    }
+    guard let pubkey = pubkey else {
+      fatalError("BindingsGetPubkeyFromContact returned `nil` without providing error")
+    }
+    return pubkey
+  }
+}
+
+#if DEBUG
+extension ContactPubkeyProvider {
+  public static let failing = ContactPubkeyProvider { _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/DependenciesProvider.swift b/Sources/ElixxirDAppsSDK/DependenciesProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..d9168cd1cdca4f0f58dddd54ef85651161d26f1e
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/DependenciesProvider.swift
@@ -0,0 +1,19 @@
+import Bindings
+
+public struct DependenciesProvider {
+  public var get: () -> String
+
+  public func callAsFunction() -> String {
+    get()
+  }
+}
+
+extension DependenciesProvider {
+  public static let live = DependenciesProvider(get: BindingsGetDependencies)
+}
+
+#if DEBUG
+extension DependenciesProvider {
+  public static let failing = DependenciesProvider { fatalError("Not implemented") }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/Errors.swift b/Sources/ElixxirDAppsSDK/Errors.swift
deleted file mode 100644
index d28f5bafc0e6843d9a43a6f10171c5fa35596437..0000000000000000000000000000000000000000
--- a/Sources/ElixxirDAppsSDK/Errors.swift
+++ /dev/null
@@ -1,19 +0,0 @@
-public struct BindingsDownloadAndVerifySignedNdfWithUrlUnknownError: Error, Equatable {
-  public init() {}
-}
-
-public struct BindingsGenerateSecretUnknownError: Error, Equatable {
-  public init() {}
-}
-
-public struct PasswordStorageMissingPasswordError: Error, Equatable {
-  public init() {}
-}
-
-public struct BindingsNewClientUnknownError: Error, Equatable {
-  public init() {}
-}
-
-public struct BindingsLoginUnknownError: Error, Equatable {
-  public init() {}
-}
diff --git a/Sources/ElixxirDAppsSDK/GitVersionProvider.swift b/Sources/ElixxirDAppsSDK/GitVersionProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..29ef07a39bff3323a95df2eb176985deb176e241
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/GitVersionProvider.swift
@@ -0,0 +1,19 @@
+import Bindings
+
+public struct GitVersionProvider {
+  public var get: () -> String
+
+  public func callAsFunction() -> String {
+    get()
+  }
+}
+
+extension GitVersionProvider {
+  public static let live = GitVersionProvider(get: BindingsGetGitVersion)
+}
+
+#if DEBUG
+extension GitVersionProvider {
+  public static let failing = GitVersionProvider { fatalError("Not implemented") }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/IdentityMaker.swift b/Sources/ElixxirDAppsSDK/IdentityMaker.swift
new file mode 100644
index 0000000000000000000000000000000000000000..91e7eeed7c4d90d73896c100a8416471581d7564
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/IdentityMaker.swift
@@ -0,0 +1,26 @@
+import Bindings
+
+public struct IdentityMaker {
+  public var make: () throws -> Data
+
+  public func callAsFunction() throws -> Data {
+    try make()
+  }
+}
+
+extension IdentityMaker {
+  public static func live(bindingsClient: BindingsClient) -> IdentityMaker {
+    IdentityMaker {
+      try bindingsClient.makeIdentity()
+    }
+  }
+}
+
+#if DEBUG
+extension IdentityMaker {
+  public static let failing = IdentityMaker {
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/LogLevel.swift b/Sources/ElixxirDAppsSDK/LogLevel.swift
new file mode 100644
index 0000000000000000000000000000000000000000..70dffda519e7a262f6c2bdc04610f929b1102df9
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/LogLevel.swift
@@ -0,0 +1,9 @@
+public enum LogLevel: Int, Equatable {
+  case trace = 0
+  case debug = 1
+  case info = 2
+  case warn = 3
+  case error = 4
+  case critical = 5
+  case fatal = 6
+}
diff --git a/Sources/ElixxirDAppsSDK/LogLevelConfigurator.swift b/Sources/ElixxirDAppsSDK/LogLevelConfigurator.swift
new file mode 100644
index 0000000000000000000000000000000000000000..6137fc838a143b09ece6ca96a07a1334108cf44f
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/LogLevelConfigurator.swift
@@ -0,0 +1,31 @@
+import Bindings
+
+public struct LogLevelConfigurator {
+  public var set: (LogLevel) throws -> Void
+
+  public func callAsFunction(logLevel: LogLevel) throws {
+    try set(logLevel)
+  }
+}
+
+extension LogLevelConfigurator {
+  public static let live = LogLevelConfigurator { logLevel in
+    var error: NSError?
+    let result = BindingsLogLevel(logLevel.rawValue, &error)
+    if let error = error {
+      throw error
+    }
+    if !result {
+      fatalError("BindingsLogLevel returned `false` without providing error")
+    }
+  }
+}
+
+#if DEBUG
+extension LogLevelConfigurator {
+  public static let failing = LogLevelConfigurator { _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/LogsListener.swift b/Sources/ElixxirDAppsSDK/LogsListener.swift
new file mode 100644
index 0000000000000000000000000000000000000000..2b070877dbac36f8cb170fbd5ecb7af3271fbc74
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/LogsListener.swift
@@ -0,0 +1,40 @@
+import Bindings
+
+public struct LogsListener {
+  public var listen: (@escaping (String) -> Void) -> Void
+
+  public func callAsFunction(callback: @escaping (String) -> Void) {
+    listen(callback)
+  }
+}
+
+extension LogsListener {
+  public static let live = LogsListener { callback in
+    let listener = Listener(onLog: callback)
+    BindingsRegisterLogWriter(listener)
+  }
+}
+
+private final class Listener: NSObject, BindingsLogWriterProtocol {
+  init(onLog: @escaping (String) -> Void) {
+    self.onLog = onLog
+    super.init()
+  }
+
+  let onLog: (String) -> Void
+
+  func log(_ p0: String?) {
+    guard let p0 = p0 else {
+      fatalError("BindingsLogWriter.log received `nil`")
+    }
+    onLog(p0)
+  }
+}
+
+#if DEBUG
+extension LogsListener {
+  public static let failing = LogsListener { _ in
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/MessageDeliveryWaiter.swift b/Sources/ElixxirDAppsSDK/MessageDeliveryWaiter.swift
new file mode 100644
index 0000000000000000000000000000000000000000..92b6ab9673ee1f75910f6919e96dc7d089563228
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/MessageDeliveryWaiter.swift
@@ -0,0 +1,63 @@
+import Bindings
+
+public struct MessageDeliveryWaiter {
+  public enum Result: Equatable {
+    case delivered(roundResults: Data)
+    case notDelivered(timedOut: Bool)
+  }
+
+  public var wait: (Data, Int, @escaping (Result) -> Void) throws -> Void
+
+  public func callAsFunction(
+    roundList: Data,
+    timeoutMS: Int,
+    callback: @escaping (Result) -> Void
+  ) throws -> Void {
+    try wait(roundList, timeoutMS, callback)
+  }
+}
+
+extension MessageDeliveryWaiter {
+  public static func live(bindingsClient: BindingsClient) -> MessageDeliveryWaiter {
+    MessageDeliveryWaiter { roundList, timeoutMS, callback in
+      try bindingsClient.wait(
+        forMessageDelivery: roundList,
+        mdc: Callback(onCallback: callback),
+        timeoutMS: timeoutMS
+      )
+    }
+  }
+}
+
+private final class Callback: NSObject, BindingsMessageDeliveryCallbackProtocol {
+  init(onCallback: @escaping (MessageDeliveryWaiter.Result) -> Void) {
+    self.onCallback = onCallback
+    super.init()
+  }
+
+  let onCallback: (MessageDeliveryWaiter.Result) -> Void
+
+  func eventCallback(_ delivered: Bool, timedOut: Bool, roundResults: Data?) {
+    if delivered, !timedOut, let roundResults = roundResults {
+      return onCallback(.delivered(roundResults: roundResults))
+    }
+    if !delivered, roundResults == nil {
+      return onCallback(.notDelivered(timedOut: timedOut))
+    }
+    fatalError("""
+      BindingsMessageDeliveryCallback received invalid parameters:
+      - delivered → \(delivered)
+      - timedOut → \(timedOut)
+      - roundResults == nil → \(roundResults == nil)
+      """)
+  }
+}
+
+#if DEBUG
+extension MessageDeliveryWaiter {
+  public static let failing = MessageDeliveryWaiter { _, _, _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/MessageListener.swift b/Sources/ElixxirDAppsSDK/MessageListener.swift
new file mode 100644
index 0000000000000000000000000000000000000000..bed6b8c10517be2fd6d073f2e32b8d941436a795
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/MessageListener.swift
@@ -0,0 +1,67 @@
+import Bindings
+
+public struct MessageListener {
+  public var listen: (Int, String, @escaping (Data) -> Void) -> Void
+
+  public func callAsFunction(
+    messageType: Int,
+    listenerName: String = "MessageListener",
+    callback: @escaping (Data) -> Void
+  ) {
+    listen(messageType, listenerName, callback)
+  }
+}
+
+extension MessageListener {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> MessageListener {
+    MessageListener.live(
+      register: bindingsConnection.registerListener(_:newListener:)
+    )
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> MessageListener {
+    MessageListener.live(
+      register: bindingsAuthenticatedConnection.registerListener(_:newListener:)
+    )
+  }
+
+  private static func live(
+    register: @escaping (Int, BindingsListenerProtocol) -> Void
+  ) -> MessageListener {
+    MessageListener { messageType, listenerName, callback in
+      register(messageType, Listener(listenerName: listenerName, onHear: callback))
+    }
+  }
+}
+
+private class Listener: NSObject, BindingsListenerProtocol {
+  init(listenerName: String, onHear: @escaping (Data) -> Void) {
+    self.listenerName = listenerName
+    self.onHear = onHear
+    super.init()
+  }
+
+  let listenerName: String
+  let onHear: (Data) -> Void
+
+  func hear(_ item: Data?) {
+    guard let item = item else { return }
+    onHear(item)
+  }
+
+  func name() -> String {
+    listenerName
+  }
+}
+
+#if DEBUG
+extension MessageListener {
+  public static let failing = MessageListener { _, _, _ in
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/MessageSender.swift b/Sources/ElixxirDAppsSDK/MessageSender.swift
new file mode 100644
index 0000000000000000000000000000000000000000..888159b46e503b74ed83cd02b181793317a960ab
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/MessageSender.swift
@@ -0,0 +1,43 @@
+import Bindings
+
+public struct MessageSender {
+  public var send: (Int, Data) throws -> Data
+
+  public func callAsFunction(
+    messageType: Int,
+    payload: Data
+  ) throws -> Data {
+    try send(messageType, payload)
+  }
+}
+
+extension MessageSender {
+  public static func live(
+    bindingsConnection: BindingsConnection
+  ) -> MessageSender {
+    MessageSender.live(sendE2E: bindingsConnection.sendE2E(_:payload:))
+  }
+
+  public static func live(
+    bindingsAuthenticatedConnection: BindingsAuthenticatedConnection
+  ) -> MessageSender {
+    MessageSender.live(sendE2E: bindingsAuthenticatedConnection.sendE2E(_:payload:))
+  }
+
+  private static func live(
+    sendE2E: @escaping (Int, Data) throws -> Data
+  ) -> MessageSender {
+    MessageSender { messageType, payload in
+      try sendE2E(messageType, payload)
+    }
+  }
+}
+
+#if DEBUG
+extension MessageSender {
+  public static let failing = MessageSender { _, _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NDFDownloader.swift b/Sources/ElixxirDAppsSDK/NDFDownloader.swift
index c0552b99985d3a9b4c3a52fc554b2fad2a92a61c..fed3385073a483752931e8eade5479229512d531 100644
--- a/Sources/ElixxirDAppsSDK/NDFDownloader.swift
+++ b/Sources/ElixxirDAppsSDK/NDFDownloader.swift
@@ -20,7 +20,7 @@ extension NDFDownloader {
       throw error
     }
     guard let data = data else {
-      throw BindingsDownloadAndVerifySignedNdfWithUrlUnknownError()
+      fatalError("BindingsDownloadAndVerifySignedNdfWithUrl returned `nil` without providing error")
     }
     return data
   }
diff --git a/Sources/ElixxirDAppsSDK/NetworkFollower.swift b/Sources/ElixxirDAppsSDK/NetworkFollower.swift
new file mode 100644
index 0000000000000000000000000000000000000000..40e8b530f6bbbd0fe7fcb278036f40de6637d57f
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkFollower.swift
@@ -0,0 +1,27 @@
+import Bindings
+
+public struct NetworkFollower {
+  public var status: NetworkFollowerStatusProvider
+  public var start: NetworkFollowerStarter
+  public var stop: NetworkFollowerStopper
+}
+
+extension NetworkFollower {
+  public static func live(bindingsClient: BindingsClient) -> NetworkFollower {
+    NetworkFollower(
+      status: .live(bindingsClient: bindingsClient),
+      start: .live(bindingsClient: bindingsClient),
+      stop: .live(bindingsClient: bindingsClient)
+    )
+  }
+}
+
+#if DEBUG
+extension NetworkFollower {
+  public static let failing = NetworkFollower(
+    status: .failing,
+    start: .failing,
+    stop: .failing
+  )
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkFollowerStarter.swift b/Sources/ElixxirDAppsSDK/NetworkFollowerStarter.swift
new file mode 100644
index 0000000000000000000000000000000000000000..54b8c23747467874109ba52931e727a9cdd75c71
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkFollowerStarter.swift
@@ -0,0 +1,26 @@
+import Bindings
+
+public struct NetworkFollowerStarter {
+  public var start: (_ timeoutMS: Int) throws -> Void
+
+  public func callAsFunction(timeoutMS: Int) throws {
+    try start(timeoutMS)
+  }
+}
+
+extension NetworkFollowerStarter {
+  public static func live(bindingsClient: BindingsClient) -> NetworkFollowerStarter {
+    NetworkFollowerStarter { timeoutMS in
+      try bindingsClient.startNetworkFollower(timeoutMS)
+    }
+  }
+}
+
+#if DEBUG
+extension NetworkFollowerStarter {
+  public static let failing = NetworkFollowerStarter { _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkFollowerStatus.swift b/Sources/ElixxirDAppsSDK/NetworkFollowerStatus.swift
new file mode 100644
index 0000000000000000000000000000000000000000..8630aafe29e7f7f3703abb701bb5df1f4c3fc2b0
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkFollowerStatus.swift
@@ -0,0 +1,29 @@
+public enum NetworkFollowerStatus: Equatable {
+  case stopped
+  case starting
+  case running
+  case stopping
+  case unknown(code: Int)
+}
+
+extension NetworkFollowerStatus {
+  public init(rawValue: Int) {
+    switch rawValue {
+    case 0: self = .stopped
+    case 1_000: self = .starting
+    case 2_000: self = .running
+    case 3_000: self = .stopping
+    case let code: self = .unknown(code: code)
+    }
+  }
+
+  public var rawValue: Int {
+    switch self {
+    case .stopped: return 0
+    case .starting: return 1_000
+    case .running: return 2_000
+    case .stopping: return 3_000
+    case .unknown(let code): return code
+    }
+  }
+}
diff --git a/Sources/ElixxirDAppsSDK/NetworkFollowerStatusProvider.swift b/Sources/ElixxirDAppsSDK/NetworkFollowerStatusProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..b1049df732e2a2c209a0925df5cbbb14e9ec5158
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkFollowerStatusProvider.swift
@@ -0,0 +1,26 @@
+import Bindings
+
+public struct NetworkFollowerStatusProvider {
+  public var status: () -> NetworkFollowerStatus
+
+  public func callAsFunction() -> NetworkFollowerStatus {
+    status()
+  }
+}
+
+extension NetworkFollowerStatusProvider {
+  public static func live(bindingsClient: BindingsClient) -> NetworkFollowerStatusProvider {
+    NetworkFollowerStatusProvider {
+      let rawValue = bindingsClient.networkFollowerStatus()
+      return NetworkFollowerStatus(rawValue: rawValue)
+    }
+  }
+}
+
+#if DEBUG
+extension NetworkFollowerStatusProvider {
+  public static let failing = NetworkFollowerStatusProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkFollowerStopper.swift b/Sources/ElixxirDAppsSDK/NetworkFollowerStopper.swift
new file mode 100644
index 0000000000000000000000000000000000000000..dfe95111e09f49ce1f2b77f8baaa044f9671fb82
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkFollowerStopper.swift
@@ -0,0 +1,24 @@
+import Bindings
+
+public struct NetworkFollowerStopper {
+  public var stop: () throws -> Void
+
+  public func callAsFunction() throws {
+    try stop()
+  }
+}
+
+extension NetworkFollowerStopper {
+  public static func live(bindingsClient: BindingsClient) -> NetworkFollowerStopper {
+    NetworkFollowerStopper(stop: bindingsClient.stopNetworkFollower)
+  }
+}
+
+#if DEBUG
+extension NetworkFollowerStopper {
+  public static let failing = NetworkFollowerStopper {
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkHealthListener.swift b/Sources/ElixxirDAppsSDK/NetworkHealthListener.swift
new file mode 100644
index 0000000000000000000000000000000000000000..69419b2e403e0230d92356cfffd370432d4057ed
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkHealthListener.swift
@@ -0,0 +1,42 @@
+import Bindings
+
+public struct NetworkHealthListener {
+  public var listen: (@escaping (Bool) -> Void) -> Cancellable
+
+  public func callAsFunction(callback: @escaping (Bool) -> Void) -> Cancellable {
+    listen(callback)
+  }
+}
+
+extension NetworkHealthListener {
+  public static func live(bindingsClient: BindingsClient) -> NetworkHealthListener {
+    NetworkHealthListener { callback in
+      let listener = Listener(onCallback: callback)
+      let id = bindingsClient.registerNetworkHealthCB(listener)
+      return Cancellable {
+        bindingsClient.unregisterNetworkHealthCB(id)
+      }
+    }
+  }
+}
+
+private final class Listener: NSObject, BindingsNetworkHealthCallbackProtocol {
+  init(onCallback: @escaping (Bool) -> Void) {
+    self.onCallback = onCallback
+    super.init()
+  }
+
+  let onCallback: (Bool) -> Void
+
+  func callback(_ p0: Bool) {
+    onCallback(p0)
+  }
+}
+
+#if DEBUG
+extension NetworkHealthListener {
+  public static let failing = NetworkHealthListener { _ in
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkHealthProvider.swift b/Sources/ElixxirDAppsSDK/NetworkHealthProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..aba7ef8fb0239af8f07b908799a8877cca92666d
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkHealthProvider.swift
@@ -0,0 +1,23 @@
+import Bindings
+
+public struct NetworkHealthProvider {
+  public var get: () -> Bool
+
+  public func callAsFunction() -> Bool {
+    get()
+  }
+}
+
+extension NetworkHealthProvider {
+  public static func live(bindingsClient: BindingsClient) -> NetworkHealthProvider {
+    NetworkHealthProvider(get: bindingsClient.isNetworkHealthy)
+  }
+}
+
+#if DEBUG
+extension NetworkHealthProvider {
+  public static let failing = NetworkHealthProvider {
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/NetworkWaiter.swift b/Sources/ElixxirDAppsSDK/NetworkWaiter.swift
new file mode 100644
index 0000000000000000000000000000000000000000..c895104daa70bc1176a11041ca06ff6fe2bf4092
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/NetworkWaiter.swift
@@ -0,0 +1,25 @@
+import Bindings
+
+public struct NetworkWaiter {
+  public var wait: (_ timeoutMS: Int) -> Bool
+
+  public func callAsFunction(timeoutMS: Int) -> Bool {
+    wait(timeoutMS)
+  }
+}
+
+extension NetworkWaiter {
+  public static func live(bindingsClient: BindingsClient) -> NetworkWaiter {
+    NetworkWaiter { timeoutMS in
+      bindingsClient.wait(forNetwork: timeoutMS)
+    }
+  }
+}
+
+#if DEBUG
+extension NetworkWaiter {
+  public static let failing = NetworkWaiter { _ in
+    fatalError("Not implemented")
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/PasswordGenerator.swift b/Sources/ElixxirDAppsSDK/PasswordGenerator.swift
index 251ea87399bbcd310c56dd78af6908d802f3aaf1..4c5b978e7fd7e14ee367f437482aee25872fd655 100644
--- a/Sources/ElixxirDAppsSDK/PasswordGenerator.swift
+++ b/Sources/ElixxirDAppsSDK/PasswordGenerator.swift
@@ -1,17 +1,17 @@
 import Bindings
 
 public struct PasswordGenerator {
-  public var run: () throws -> Data
+  public var run: (Int) -> Data
 
-  public func callAsFunction() throws -> Data {
-    try run()
+  public func callAsFunction(numBytes: Int = 32) -> Data {
+    run(numBytes)
   }
 }
 
 extension PasswordGenerator {
-  public static let live = PasswordGenerator {
-    guard let secret = BindingsGenerateSecret(32) else {
-      throw BindingsGenerateSecretUnknownError()
+  public static let live = PasswordGenerator { numBytes in
+    guard let secret = BindingsGenerateSecret(numBytes) else {
+      fatalError("BindingsGenerateSecret returned `nil`")
     }
     return secret
   }
@@ -19,9 +19,8 @@ extension PasswordGenerator {
 
 #if DEBUG
 extension PasswordGenerator {
-  public static let failing = PasswordGenerator {
-    struct NotImplemented: Error {}
-    throw NotImplemented()
+  public static let failing = PasswordGenerator { _ in
+    fatalError("Not implemented")
   }
 }
 #endif
diff --git a/Sources/ElixxirDAppsSDK/PasswordStorage.swift b/Sources/ElixxirDAppsSDK/PasswordStorage.swift
index 82ae04dcd844cd97c365bec9fe2f1d9170043a59..89df9af8f14b84fc947e9e7ef4059488a295f504 100644
--- a/Sources/ElixxirDAppsSDK/PasswordStorage.swift
+++ b/Sources/ElixxirDAppsSDK/PasswordStorage.swift
@@ -1,6 +1,10 @@
 import Foundation
 
 public struct PasswordStorage {
+  public struct MissingPasswordError: Error, Equatable {
+    public init() {}
+  }
+
   public init(
     save: @escaping (Data) throws -> Void,
     load: @escaping () throws -> Data
diff --git a/Sources/ElixxirDAppsSDK/RestlikeRequestSender.swift b/Sources/ElixxirDAppsSDK/RestlikeRequestSender.swift
new file mode 100644
index 0000000000000000000000000000000000000000..fda472aa16a9854c2cb4d4376766d24a04151cd6
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/RestlikeRequestSender.swift
@@ -0,0 +1,44 @@
+import Bindings
+
+public struct RestlikeRequestSender {
+  public var send: (Int, Int, Data) throws -> Data
+
+  public func callAsFunction(
+    clientId: Int,
+    connectionId: Int,
+    request: Data
+  ) throws -> Data {
+    try send(clientId, connectionId, request)
+  }
+}
+
+extension RestlikeRequestSender {
+  public static func live(authenticated: Bool) -> RestlikeRequestSender {
+    RestlikeRequestSender { clientId, connectionId, request in
+      var error: NSError?
+      let response: Data?
+      if authenticated {
+        response = BindingsRestlikeRequestAuth(clientId, connectionId, request, &error)
+      } else {
+        response = BindingsRestlikeRequest(clientId, connectionId, request, &error)
+      }
+      if let error = error {
+        throw error
+      }
+      guard let response = response else {
+        let functionName = "BindingsRestlikeRequest\(authenticated ? "Auth" : "")"
+        fatalError("\(functionName) returned `nil` without providing error")
+      }
+      return response
+    }
+  }
+}
+
+#if DEBUG
+extension RestlikeRequestSender {
+  public static let failing = RestlikeRequestSender { _, _, _ in
+    struct NotImplemented: Error {}
+    throw NotImplemented()
+  }
+}
+#endif
diff --git a/Sources/ElixxirDAppsSDK/VersionProvider.swift b/Sources/ElixxirDAppsSDK/VersionProvider.swift
new file mode 100644
index 0000000000000000000000000000000000000000..bec9b293ca43a57f42feb3a3f6a8703c239b613f
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/VersionProvider.swift
@@ -0,0 +1,19 @@
+import Bindings
+
+public struct VersionProvider {
+  public var get: () -> String
+
+  public func callAsFunction() -> String {
+    get()
+  }
+}
+
+extension VersionProvider {
+  public static let live = VersionProvider(get: BindingsGetVersion)
+}
+
+#if DEBUG
+extension VersionProvider {
+  public static let failing = VersionProvider { fatalError("Not implemented") }
+}
+#endif