Search packages, repositories and app categories

GitHub repositoryarchethic-foundation/lib-deeplink-rpc

lib-deeplink-rpc

A RPC-via-deeplink communication library

lib-deeplink-rpc project cover
Stars
3
Forks
2
Last push (UTC)
Apr 9, 2025
Project status
Active

Original README

English project snapshot. Visit GitHub for the latest content.

Deeplink RPC

A RPC-via-deeplink communication library coded in Dart. This is dedicated to Flutter mobile applications (iOS / Android).

Protocol

Deeplink codec

Deeplink messages are appended to the deeplink URI. Because of that, there are limitations in the available formatting.

To get it working, the message is encoded that way :

                     +--------------+   +------+   +-----------+
method_payload :     | Json Message |-> | gzip |-> | base64Url |
                     +--------------+   +------+   +-----------+


Deeplink Url : `<scheme>://<host>/<method_name>/<method_payload>`

Example :

                     +--------------------------+      +----------------------------------------------------------------+
method_payload :     | { "param1" : "a_value" } |----> | "H4sIAAAAAAAAA6tWUCpILErMNVRSsFJQSowvS8wpTVVSqAUAhIgKchgAAAA=" |
                     +--------------------------+      +----------------------------------------------------------------+


Deeplink Url : `scheme://host/a_method/H4sIAAAAAAAAA6tWUCpILErMNVRSsFJQSowvS8wpTVVSqAUAhIgKchgAAAA=`

Request formatting

Requests payload are encapsulated in a JSON-RPC 2.0 message.

{
  "id": Number,                     // An unique client-generated integer identifying the request
  "replyUrl": String,               // Deeplink URL to which send the invokation result. This should be a Deeplink URL handled by the DApp.
  "params": {
    "origin": {
      "name": String,               // Human readable identifier of the DApp
      "url": String | undefined,    // URL of the DApp
      "logo": Base64 | undefined,   // Logo of the DApp 
    },
    "version": 2,                   // Version of the DApp API
    "payload": Object,              // Method parameters
  }
}
Success Response formatting
{
  "id": Number,                     // The request identifier
  "result":  Object,                // Result payload
}
Failure Response formatting
{
  "id": Number,                     // The request identifier
  "failure": {
    "code": Number,                 // Error code
    "message": String | undefined,  // Error description
    "data": Object | undefined,     // Error data
  },
}

Usage

Server - listening to incoming requests
/// 1. Enable deeplinking for your application (https://docs.flutter.dev/development/ui/navigation/deep-linking)

/// 2. Declare the deeplink-rpc receiver
/// When a RPC call <scheme>://a_rpc_command/<payload> is received, the payload is decoded
/// and transmitted to the `handle` method.
final _deeplinkRpcServer = DeeplinkRpcServer()
    ..registerHandler(
      DeeplinkRpcRequestHandler(
        route: const DeeplinkRpcRoute('a_rpc_command'),
        handle: (request) {
            log('Command received');
        }
      ),
    );


class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DeeplinkRPC Demo',
      home: const SendForm(),
      onGenerateRoute: (settings) {
        /// 3. Listen to incoming deeplink requests
        if (_deeplinkRpcServer.handleRoute(settings.name)) return;

        // ... do other route generation stuffs here.
        return null;
      },
    );
  }
}
Client - Sending requests and listening for responses
/// 1. Enable deeplinking for your application (https://docs.flutter.dev/development/ui/navigation/deep-linking)
/// It is necessary to receive responses.

/// 2. Declare the deeplink-rpc client
/// When a RPC call <scheme>://a_rpc_command/<payload> is received, the payload is decoded
/// and transmitted to the `handle` method.
final _deeplinkRpcClient = DeeplinkRpcClient();

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'DeeplinkRPC Demo',
      onGenerateRoute: (settings) {
        /// 3. Listen to incoming deeplink requests
        if (_deeplinkRpcClient.handleRoute(settings.name)) return;

        // ... do other route generation stuffs here.
        return null;
      },
      home: Scaffold(
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.send),
          onPressed: () async {
            final response = await _deeplinkRpcClient.send(
              timeout: const Duration(seconds: 5),
              request: DeeplinkRpcRequest(
                requestUrl: 'serverapp://server.app/request_endpoint',
                replyUrl: 'clientapp://client.app/reply_endpoint',
                params: {
                  'param1': 'value1',
                  'param2': 'value2',
                },
              ),
            );

            response.map(
              failure: (failure) {
                log(
                  'RPC request failed',
                  error: failure,
                );
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(
                      content: Text(failure.message ?? "An error occured")),
                );
              },
              success: (result) {
                log(
                  'RPC request succeed : ${json.encode(result)}',
                );
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text(json.encode(result))),
                );
              },
            );
          },
        ),
        body: const SafeArea(
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Center(
              child: Text('Client example'),
            ),
          ),
        ),
      ),
    );
  }
}
Archethic Foundation GitHub avatar
GitHub author

Archethic Foundation ↗

Digital sovereignty at your fingertips

LanguagesDartRubySwiftKotlinObjective-C

Packages published by this repository

Dependencies used

Dependency list 11 items

How do I choose a repository?

Start with your use case, compare repository activity, and check the original project before adopting it.

  1. Search by repository name, owner or description, then narrow the results by topic.
  2. Compare stars, forks and recent pushes. Stars show community interest, not a guarantee of quality.
  3. Read the README, license and issues on GitHub before using a project.

Sources and maintenance

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗