diff --git a/Sources/ElixxirDAppsSDK/RestlikeCallback.swift b/Sources/ElixxirDAppsSDK/RestlikeCallback.swift
new file mode 100644
index 0000000000000000000000000000000000000000..1facd9d0762cc5b58b494bb5fac1edd3b52c164c
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/RestlikeCallback.swift
@@ -0,0 +1,44 @@
+import Bindings
+import XCTestDynamicOverlay
+
+public struct RestlikeCallback {
+  public init(handle: @escaping (Result<RestlikeMessage, NSError>) -> Void) {
+    self.handle = handle
+  }
+
+  public var handle: (Result<RestlikeMessage, NSError>) -> Void
+}
+
+extension RestlikeCallback {
+  public static let unimplemented = RestlikeCallback(
+    handle: XCTUnimplemented("\(Self.self)")
+  )
+}
+
+extension RestlikeCallback {
+  func makeBindingsRestlikeCallback() -> BindingsRestlikeCallbackProtocol {
+    class Callback: NSObject, BindingsRestlikeCallbackProtocol {
+      init(_ callback: RestlikeCallback) {
+        self.callback = callback
+      }
+
+      let callback: RestlikeCallback
+
+      func callback(_ p0: Data?, p1: Error?) {
+        if let error = p1 {
+          callback.handle(.failure(error as NSError))
+        } else if let messageData = p0 {
+          do {
+            callback.handle(.success(try RestlikeMessage.decode(messageData)))
+          } catch {
+            callback.handle(.failure(error as NSError))
+          }
+        } else {
+          fatalError("BindingsRestlikeCallback received `nil` message and `nil` error")
+        }
+      }
+    }
+
+    return Callback(self)
+  }
+}