# QR code mechanism

This section serves to illustrate how wallets can employ the QR code scanning feature to carry out tasks such as login, smart contract invocation, and other services.

There are two parties that are involved in the process:

* The `dApp` :  Blanket term that represents`dApps` developed for the users of Ontology ecosystem.
* The `Provider`: Wallets that support `dAPI` , and adhere to it's specifications.

## Interaction process

A dApp provides a QR code and the user scans it using the wallet. The QR code mechanism currently supports two functions: login and contract invocation.

### Login by scanning QR code

![](/files/-LvPYVGiR6Nj5rLpvWGM)

The process flow is as follows-

1. Wallet scans the QR code provided by the `dApp`.
2. `Provider` fetches the `callback URL` and the verification message, carries out user authentication and signature, and the transaction is carries out using the `dApps` callback address.
3. The `dApp` back end carries out signature verification and returns the result to the wallet.

### Invoke smart contract using QR code

![](/files/-LvskNo6m247YTTuJepu)

The process flow is as follows-

1. Wallet scans the QR code provided by the `dApp`.
2. Wallet initiates a transaction, the user signs it, the transaction is pre-executed, the user provides confirmation, the information is transmitted on to the chain, and finally the transaction `hash` is returned to the `dApp` back end using the callback address provided.
3. `dApp` back end uses the transaction `hash` to query the successful contract execution and transaction details.

## dAPI protocol usage

The following scenarios can be realized by integrating the dAPI -

### Login

Authentication is carried out by scanning the QR code from the wallet. The wallet fetches login parameters, carries out signature authorization and sends them to the `dApp` back end.

```yaml
{
    "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",
        "expire": 1546415363, # QR Code expire time
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

| Field    | Data type | Description                                                                                                      |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| action   | string    | States the function performed by the QR code, Login to be defined as "login" and contract invocation as "invoke" |
| id       | string    | Serial number (optional)                                                                                         |
| type     | string    | Login method used, ONT ID login to be set as "ontid" and wallet address login to be set as "address"             |
| dappName | string    | Name of the dApp                                                                                                 |
| dappIcon | string    | dApp icon resource link                                                                                          |
| message  | string    | Randomly generated message for identity verification                                                             |
| expire   | long      | Unix time stamp for when the QR code expires (optional)                                                          |
| callback | string    | Callback URL to communicate with the dApp back end                                                               |

#### dApp back end's return interface

Here's the post method message structure:

```yaml
# method:post
{
    "action": "login",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "user": "did:ont:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz or AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz",
        "message": "helloworld",
        "publickey": "0205c8fff4b1d21f4b2ec3b48cf88004e38402933d7e914b2a0eda0de15e73ba61",
        "signature": "01abd7ea9d79c857cd838cabbbaad3efb44a6fc4f5a5ef52ea8461d6c055b8a7cf324d1a58962988709705cefe40df5b26e88af3ca387ec5036ec7f5e6640a1754"
    }
}
```

| Field     | Data type | Description                                                                                                  |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| action    | string    | Operation type                                                                                               |
| id        | string    | Serial number (optional)                                                                                     |
| params    | string    | Parameters required by the method                                                                            |
| type      | string    | Login method used, "ontid" if ONT ID is used to login and "address" when the wallet address is used to login |
| user      | string    | Identifier of the account that is used for signature                                                         |
| message   | string    | Randomly generated message for identity verification                                                         |
| publickey | string    | Account's public key                                                                                         |
| signature | string    | Digital signature                                                                                            |

If the transaction was successful, the s**uccess message** is sent in response.

```yaml
{
  "action": "login",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": true
}
```

Otherwise, the **failure message** is sent in response.

```yaml
{
  "action": "login",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "PARAMS ERROR",
  "result": 1
}
```

### Message Signature

Message signature is essentially the same as login protocol, except that the `dApp` name and the icon are not a part of the request that is sent.

The structure of the signature request sent by the `dApp` after `URI` and `Base64` encoding are as follows:

```yaml
{
    "action": "signMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": "helloworld",
        "ishex": false
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

Or when multiple messages are signed:

```yaml
{
    "action": "signMultiMessage",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "type": "ontid or address",
        "message": ["aabbccdd"],
        "ishex": true
        "callback": "http://101.132.193.149:4027/blockchain/v1/common/test-onto-login"
    }
}
```

| Field    | Data type | Description                                                                                         |
| -------- | --------- | --------------------------------------------------------------------------------------------------- |
| action   | string    | Operation type                                                                                      |
| type     | string    | Login method used, "ontid" if ONT ID is used to login and "address" when the wallet address is used |
| message  | string    | Randomly generated message for identity verification                                                |
| ishex    | bool      | Whether the message is a hex code                                                                   |
| callback | string    | Callback URL to communicate with the dApp back end                                                  |

The response that the wallet sends back to the `dApp`, after `URI` and `Base 64` encoding, is structured as follows:

```yaml
# method: post
{
    "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"
    }
}
```

{% hint style="info" %}
If the action is "multimessage" the response sent back to the `dApp` is an array
{% endhint %}

### Contract Invocation

A payment operation also falls under the category of contract invocation, adopting a uniform protocol standard. The standard can be defined as follows:

```yaml
{
    "action": "invoke",
    "version": "v1.0.0",
    "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
    "params": {
        "login": true,
        "callback": "http://101.132.193.149:4027/invoke/callback",
        "qrcodeUrl": "http://101.132.193.149:4027/qrcode/AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ"
    }
}
```

| Field     | Data type | Description                                                                        |
| --------- | --------- | ---------------------------------------------------------------------------------- |
| action    | string    | Operation type, Login to be defined as "login" and contract invocation as "invoke" |
| qrcodeUrl | string    | Address for QR code parameters                                                     |
| callback  | string    | The callback address to send the transaction `hash` to the `dApp` back end         |

The data obtained from the `qrcodeURL` link's `GET` method is as follows-

```yaml
{
    "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
        }
    }
}
```

{% hint style="info" %}
Base58 addresses such as `AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ` can be assigned to the `%address` parameter, and the wallet will automatically assign it as the wallet's asset address. If the parameters contain an `%ontid`, the wallet will also automatically assign it to the wallet's `ONT ID` address.
{% endhint %}

The wallet initiates a transaction, the user authenticates and signs it, the transaction is pre-executed, issued, and then the transaction `hash` is sent to the `callback URL` using `POST` method.

The success message has the following structure:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 0,
  "desc": "SUCCESS",
  "result": "tx hash"
}
```

And the failure message is as follows:

```yaml
{
  "action": "invoke",
  "id": "10ba038e-48da-487b-96e8-8d3b99b6d18a",
  "error": 80001,
  "desc": "SEND TX ERROR",
  "result": 1
}
```

#### Pre-executing a transaction

Pre-executing a transaction is optional. One of the main functions is serves is informing the user how much `ONT` or `ONG` is involved in a particular transaction. The `Notify` message that is returned upon pre-execution can deliver the information regarding the amount of `ONT/ONG` the user will spend for a particular transaction in terms of transaction costs.

{% hint style="info" %}
The `Notify` message needs to be parsed to make a judgement, because a transaction may have multiple transfer or smart contract events. If the other contract events don't need to handled, then the nature of transferred tokens can be judged from the address i.e. `ONT/ONG` and the `transfer` method along with the sender.

It is also advised that the the sender and `amount` should be displayed on the `UI`. There is a transaction fee which roughly equals to 0.01`ONG`
{% endhint %}

If the pre-execution is a success the response from the node is:

```yaml
{
  "Action": "sendrawtransaction",
  "Desc": "SUCCESS",
  "Error": 0,
  "Result": {
                "Notify": [{
                    "States": ["transfer", "AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ", "AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ", 1],
                    "ContractAddress": "0100000000000000000000000000000000000000"
                }],
                "State": 1,
                "Gas": 20000,
                "Result": "01"
   },
  "Version": "1.0.0"
}
```

But if it fails, the `Error` value would be greater than 0.

## Code for reference

|                                              **Signature verification methods**                                              |                                                     **Transaction event query methods**                                                    |                         **Cyano Wallet**                        |                      **dAPI - Mobile provider SDK**                     | **dAPI - Mobile client SDK**                                |
| :--------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------------: | ----------------------------------------------------------- |
| [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/interface.md#%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE) | [Java SDK](https://github.com/ontio/ontology-java-sdk/blob/master/docs/cn/basic.md#%E4%B8%8E%E9%93%BE%E4%BA%A4%E4%BA%92%E6%8E%A5%E5%8F%A3) | [Cyano - Android](https://github.com/ontio-cyano/cyano-android) | [Cyano - Android SDK](https://github.com/ontio-cyano/cyano-android-sdk) | [Cyano Bridge](https://github.com/ontio-cyano/cyano-bridge) |
|               [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/ecdsa.crypto.test.ts)               |                        [TypeScript SDK](https://github.com/ontio/ontology-ts-sdk/blob/master/test/websocket.test.ts)                       |     [Cyano - iOS](https://github.com/ontio-cyano/cyano-ios)     |     [Cyano - iOS SDK](https://github.com/ontio-cyano/cyano-ios-sdk)     |                                                             |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ont.io/guides-and-tutorials/integration-guides/mobile-wallet-integration/dapi-integration/qr-code-mechanism.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
