In-wallet applications
Launching applications in the mobile wallet
The following section serves to guide developers on how to enable wallets to support Ontology's dAPI
, along with Provider SDK
integration into mobile wallet apps. It may be worth referring to the respective open source Android and iOS wallet source code.
The two parties involved in the integration process are:
The
dApp
: Blanket term that representsdApps
developed for the users of Ontology ecosystem.The
Provider
: Wallets that supportdAPI
, and adhere to it's specifications.
Interaction process
The URI scheme that the dApp
uses when sending requests:
ontprovider://ont.io?param=Base64.encode(Uri.encode({the json data}.toString()))
The process can be broadly divided in the following manner:
Step 1:Wallet uses Webview to open dApps (H5 design)
Wallet uses Webview
to open H5 dApps
in the dApp
store page layout
Step 2:dApp sends a request to fetch wallet's address
There are two ways to retrieve account information-
Using the
getAccount
methodUsing the
login
method
Step 3:dApp sends a contract invocation request
The steps involved-
dApp
sends invocation requestThe wallet initiates transaction, carries out user authentication and signature
Wallet pre-executes the transaction
Transaction is transmitted to the blockchain
Wallet returns transaction
hash
to thedApp
dAPI protocol usage
The dAPI protocol is extensible in nature. It's core features can be laid out in terms of the following functions.
Querying
Provider
informationQuerying wallet or account/identity related information
Authentication and login
Message signature
Smart contract invocation
Querying provider information
The query request that the dApp
sends to the wallet to fetch the provider
information is first encoded in URI
and Base64
, and then sent. The data is structured in the following manner:
{
"action": "getProvider",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"version": "v1.0.0",
"params": {
}
}
Data specification for the fields mentioned above-
Field
Data type
Description
action
string
Operation type
id
string
Serial number
The data set of provider information that the wallet returns, after URI
and Base64
decoding, is structured in the following manner:
{
"action": "getProvider",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 0,
"desc": "SUCCESS",
"result": {
"provider": "cyano walllet",
"version": "1.0.0"
}
}
Querying the wallet account or identity information
The query request that the dApp
sends to the wallet to fetch the account or identity information is first encoded in URI
and Base64
, and then sent. The data is structured in the following manner:
{
"action": "getAccount", // or getIdentity
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"params": {
"dappName": "dapp Name",
"dappIcon": "dapp Icon"
}
}
Data specification for the fields mentioned above-
Field
Data type
Description
action
string
Operation type
dappName
string
dApp name
dappIcon
string
dApp icon resource link
The data set that the wallet returns, after URI
and Base64
decoding, has the following structure:
{
"action": "getAccount", // or getIdentity
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 0,
"desc": "SUCCESS",
"result": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ" // or "did:ont:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"
}
Login
The login request that the dApp
sends to the wallet is first encoded in URI
and Base64
, and then sent. The data is structured in the following manner:
{
"action": "login",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"params": {
"type": "ontid or address",
"dappName": "dapp Name",
"dappIcon": "dapp Icon",
"message": "helloworld"
}
}
Data specification for the fields mentioned above-
Fields
Data type
Description
action
string
Operation type
type
string
Specifying the login method. ONT ID login is specified using "ontid", and wallet address login is specified as "address"
dappName
string
dApp name
dappIcon
string
dApp icon resource link
message
string
Randomly generated, used for identity verification
The wallet's response to the login request is of the following format after decoding:
Success response
{
"action": "login",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 0,
"desc": "SUCCESS",
"result": {
"type": "ontid or account",
"user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
"message": "helloworld",
"publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
"signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
}
}
Failure response
{
"action": "login",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 80001,
"desc": "PARAMS ERROR",
"result": 1
}
Data specification for the fields mentioned above-
Field
Data type
Description
action
string
Operation type
result
string
The result to be returned
type
string
Specifying the login method. ONT ID login is specified using "ontid", and wallet address login is specified as "address"
user
string
The account used for signature, ONT ID or wallet address
message
string
Randomly generated, used for identity verification
publickey
string
Account's public key
signature
string
User's signature
Message signature
The structure remains the same as the login request, with the difference being that dApp
name and icon are not needed. The request is encoded in URI
and Base64
, and then sent to the wallet.
{
"action": "signMessage",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"params": {
"type": "ontid or address",
"message": "helloworld"
}
}
Data specification for the fields mentioned above-
Field
Data type
Description
action
string
Operation type
type
string
Specifying the access method. ONT ID is specified using "ontid", and wallet address is specified as "address"
message
string
Randomly generated, used for identity verification
The wallet's success response to the request is of the following format after decoding:
{
"action": "signMessage",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 0,
"desc": "SUCCESS",
"result": {
"type": "ontid or address",
"user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
"message": "helloworld",
"publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
"signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
}
}
Contract invocation
Different invocation methods can be chosen using the action
parameter. The available options are:
Parameter value
Function
invoke
Normal process
invokeRead
Pre-execute the contract, the user does not need to sign, the result is returned to the dApp
invokePasswordFree
Invoke without the need of authentication, user does not need to enter password
The platform only trusts fixed methods and parameters, and not all the methods that are part of the contract. After authentication, the transaction parameters are saved as ((InvokeCode)txs[0]).code
If another request that requires the same data is submitted, the user does not need to enter the password again, and the smart contract does not need to be pre-executed on more time.
When the user exits the dApp
, please ensure that the parameters and the private key data are cleared from the memory.
dApp sends an invocation request
The data set of the request is encoded in URI
and Base64
and sent out. The structure is:
{
"action": "invoke",
"version": "v1.0.0",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"params": {
"invokeConfig": {
"contractHash": "16edbe366d1337eb510c2ff61099424c94aeef02",
"functions": [{
"operation": "method name",
"args": [{
"name": "arg0-list",
"value": [true, 100, "Long:100000000000", "Address:AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "ByteArray:aabb", "String:hello", [true, 100], {
"key": 6
}]
}, {
"name": "arg1-map",
"value": {
"key": "String:hello",
"key1": "ByteArray:aabb",
"key2": "Long:100000000000",
"key3": true,
"key4": 100,
"key5": [100],
"key6": {
"key": 6
}
}
}, {
"name": "arg2-str",
"value": "String:test"
}]
}],
"payer": "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ",
"gasLimit": 20000,
"gasPrice": 500
}
}
}
Wallet responds to the invocation request
First the wallet carries out URI and Base64 decoding. And then,
Wallet initiates a transaction
Wallet carries out user authentication and signature
The transaction is pre-executed
Wallet receives user confirmation
The transaction is transmitted onto the chain
Transaction hash is returned to the
dApp
The success response sent to the dApp
is:
{
"action": "invoke",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 0,
"desc": "SUCCESS",
"result": "tx hash"
}
The failure response sent to the dApp
is:
{
"action": "invoke",
"id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
"error": 80001,
"desc": "SEND TX ERROR",
"result": ""
}
Pre-executing transactions
The amount of ONT
and ONG
that the user is going to expend in the transaction can be determined from the notify
response, which is a result of the pre-execution.
A connection must be established with the following nodes:
MainNet - http://dappnode3.ont.io/
TestNet - http://polaris5.ont.io/
{
"Notify": [{
"States": ["transfer", "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ", 1],
"ContractAddress": "0100000000000000000000000000000000000000"
}],
"State": 1,
"Gas": 20000,
"Result": "01"
}
dAPI provider SDK integration
dAPI provider SDK
aids communication between Android webview
and a web based dApp
. It encapsulates a few methods for webview
. Separate details with respect to Android and iOS platforms are available for reference.
Android SDK sample code
//init
CyanoWebView cyanoWebView=new CyanoWebView(context);
cyanoWebView.loadUrl(url);
//Action handle
cyanoWebView.getNativeJsBridge().setHandleGetAccount(new NativeJsBridge.HandleGetAccount() {
@Override
public void handleAction(String data) {
/* TODO
* 1.Send wallet address to webView
* com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
* String action=reqJson.getString("action");
* String version=reqJson.getString("version");
* String id=reqJson.getString("id");
* cyanoWebView.sendSuccessToWeb(action,version, id, *wallet address*);
*/
}
});
cyanoWebView.getNativeJsBridge().setHandleInvoke(new NativeJsBridge.HandleInvoke() {
@Override
public void handleAction(String data) {
/* TODO
* 1. Password input prompt, resolve wallet account, build transaction using the data, carry out signature, pre-execute, note the processing time
*
* 2. Analyze the pre-execution notify reseponse, display transaction fees, if the result contains the contract address determine ONT/ONT, display recipient address and transfer amount
*
* 3. Transmit the transaction onto the chain after user confirmation
*
* 4. Send the transaction hash to webview
*
* com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
* String action=reqJson.getString("action");
* String version=reqJson.getString("version");
* String id=reqJson.getString("id");
* cyanoWebView.sendSuccessToWeb(action,version, id, 交易 hash);
*/
}
});
cyanoWebView.getNativeJsBridge().setHandleInvokeRead(new NativeJsBridge.HandleInvokeRead() {
@Override
public void handleAction(String data) {
/* TODO
* 1. Build transaction using the data, note the processing time
*
* 2 Send the pre-execution results to webview
* com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
* String action=reqJson.getString("action");
* String version=reqJson.getString("version");
* String id=reqJson.getString("id");
* cyanoWebView.sendSuccessToWeb(action,version, id, 预知行结果);
*/
}
});
cyanoWebView.getNativeJsBridge().setHandleInvokePasswordFree(new NativeJsBridge.HandleInvokePasswordFree() {
@Override
public void handleAction(String data, String message) {
/* TODO
* 1. Executing for the first time is the same as action : invoke, both the password and the message are saved
*
* 2. When the same request arrives for the second time, use the saved password for signature and fetch pre-execution result
*
* 3. The pre-execution results need not display for the user to confirmation
*
* 4. Send the transaction hash to the webview
* com.alibaba.fastjson.JSONObject reqJson = JSON.parseObject(data);
* String action=reqJson.getString("action");
* String version=reqJson.getString("version");
* String id=reqJson.getString("id");
* cyanoWebView.sendSuccessToWeb(action,version, id, 交易hash);
*/
}
});
//response
Map map = new HashMap<>();
map.put("action", "");
map.put("error", 0);
map.put("desc", "SUCCESS");
map.put("result", message);
cyanoWebView.sendBack(Base64.encodeToString(Uri.encode(JSON.toJSONString(map)).getBytes(), Base64.NO_WRAP));
iOS SDK sample code
RNJsWebView * webView = [[RNJsWebView alloc]initWithFrame:CGRectZero];
[webView setURL:@""];
[webView setGetAccountCallback:^(NSDictionary *callbackDic) {
}];
[webView setInvokeTransactionCallback:^(NSDictionary *callbackDic) {
}];
[webView setInvokeReadCallback:^(NSDictionary *callbackDic) {
}];
NSDictionary *params = @{
@"action":@"",
@"version":@"v1.0.0",
@"error":@0,
@"desc":@"SUCCESS",
@"result":@""
};
[webView sendMessageToWeb:params];
Code base for reference
Signature verification methods
Transaction event query methods
Cyano Wallet
dAPI - Mobile provider SDK
dAPI - Mobile client SDK
Last updated
Was this helpful?