# はじめに

**unWallet Enterprise** は、**unWallet** と連携したブロックチェーンアプリケーションの開発をサポートするサービスです。


# 技術仕様


# HTTP エンドポイント


# 基本情報

## ベース URL

```
https://api.ent.unwallet.world/v2beta
```

## 認証

`Authorization` ヘッダーに以下の形式で認証トークンを設定してください。なお、`<AUTH_TOKEN>` はご自身の API クライアントの認証トークンに置き換えてください。

```
Bearer <AUTH_TOKEN>
```


# インターフェース


# ブロックチェーン関連

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/mintNFT" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/mintSFT" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/mintFT" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/getTransaction" method="get" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/issueSignatureTicket" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/issueTransactionTicket" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/sendNotification" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}


# 認証アプリケーション関連

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/registerApplication" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/getApplication" method="get" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/getApplicationStats" method="get" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/getApplications" method="get" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/updateApplication" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Zk7gHHL6Rp7KTbo9Kt33" path="/deleteApplication" method="post" %}
[openapi.yaml](https://1199386841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FU6S2p0BxJZVNAblW3oe8%2Fuploads%2Fgit-blob-186d0821c07be68bb4178239b147738a534b4774%2Fopenapi.yaml?alt=media)
{% endopenapi %}


# クライアントサイド SDK


# 基本情報

{% hint style="warning" %}
本 SDK はブラウザ上でのみ正しく動作します。
{% endhint %}

## インストール方法

```
npm install unwallet-client-sdk
```

## 初期化方法

```js
import { UnWallet } from "unwallet-client-sdk";

const unWallet = await UnWallet.init({
  clientID: "<CLIENT_ID_OF_YOUR_APPLICATION>",
});
```


# インターフェース

## authorize

unWallet ユーザーに対して、ID トークン（JWT）の発行をリクエストします。

### 引数

|                | 必須  | 型         | 説明                                                                                 |
| -------------- | --- | --------- | ---------------------------------------------------------------------------------- |
| `responseMode` | No  | `string`  | ID トークンのレスポンス方式。`"fragment"` もしくは `"form_post"` を指定してください。デフォルト値は `"fragment"` です。 |
| `redirectURL`  | Yes | `string`  | ユーザーが unWallet で ID トークンの発行を認可した後のコールバック先となる URL。                                  |
| `nonce`        | No  | `string`  | リプレイアタックを防ぐための任意の文字列。指定した値は ID トークンに含められます。                                        |
| `isVirtual`    | No  | `boolean` | リクエスト時にユーザーが unWallet にサインインしていない場合、サインイン方式をバーチャルサインインにするかどうか。デフォルト値は `true` です。   |
| `chainID`      | No  | `number`  | ユーザーに接続を促したいブロックチェーンのチェーン ID。                                                      |

{% hint style="info" %}
バーチャルサインインは unWallet へのサインイン方式の 1 つです。この方式では、コントラクトウォレットやそれに対応する秘密鍵のセットアップがスキップされるため、サインイン時に MFA が要求されません。
{% endhint %}

### 実行例

```js
unWallet.authorize({
  redirectURL: "https://example.com/callback",
  nonce: "0AbvXkwAv67DIRyQEMXZgC8SneZX56WX",
});
```

### 実行結果

#### `responseMode` が `"fragment"` の場合

`redirectURL` にリダイレクトされます。ID トークンは URL フラグメントとして付帯します。

#### `responseMode` が `"form_post"` の場合

`redirectURL` に POST リクエストが送信されます。ID トークンはフォームパラメータ（`id_token`）として付帯します。

## sign

unWallet ユーザーに対して、指定したメッセージに対する電子署名をリクエストします。

### 引数

|               | 必須  | 型        | 説明               |
| ------------- | --- | -------- | ---------------- |
| `message`     | Yes | `string` | 電子署名の対象となるメッセージ。 |
| `ticketToken` | Yes | `string` | 電子署名チケットトークン。    |

{% hint style="info" %}
電子署名チケットトークンは [POST /issueSignatureTicket](/01_spec/01_http-endpoint/01_interface/01_blockchain#issuesignatureticket) を利用して発行してください。
{% endhint %}

### 実行例

```js
const result = await unWallet.sign({
  message: "message to be signed",
  ticketToken:
    "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEiLCJ0eXAiOiJKV1QifQ.eyJhcGlDbGllbnRJRCI6IlFWQkpRMnhwWlc1ME9qRT0iLCJjbGllbnRJRCI6IkNYcWxKcEtZaVhMelZ1cTNtVTQ5VVk1VUZuMk4zVVJWdCIsImV4cCI6MTcyMTIwNzA2MCwiaWF0IjoxNzIxMjA2NzYwLCJpZCI6IjYxNWEwZGMzNjk2MTI5NjZhYTk5OGIxY2RiZTk4MDQyNDI5NmNhNTE4ODI3OTNmNmU4NWQyODEyMmVmZGY1ZjIiLCJzaWduYXR1cmVNZXNzYWdlIjoibWVzc2FnZSB0byBiZSBzaWduZWQiLCJzaWduYXR1cmVTaWduZXJBZGRyZXNzIjoiMHhkMTIyOUVlMkIwY0Y5NzhEQTc3MDdBRDVEMDI1MzAxMjBmMDRhOUYxIn0.lDSA60K4KlixyU2Vh937i1RIw0kH0QdC2Zyey5pDmuxShH0mzyH3DEuG_h_6U6xHf1pbCwtivDBaK-KQlZtiTA",
});
```

### 実行結果例

```json
{
  "digest": "0xc0f4c2c0633d048d72c13778562f37b49bfa2999fec3e286bce7248e51f9d337",
  "signature": "0x020d4c8b71c7aa69848f1ef28b8ecd0e13b19155931e1518445f4d5b1bf1292b0e95a5df9d27383ee62045a56806d8d48a0e53881513c16e3114e2088193b1c71b"
}
```

## signEIP712TypedData

unWallet ユーザーに対して、指定した [EIP-712](https://eips.ethereum.org/EIPS/eip-712) 構造化データに対する電子署名をリクエストします。

### 引数

|               | 必須  | 型        | 説明                                                                   |
| ------------- | --- | -------- | -------------------------------------------------------------------- |
| `typedData`   | Yes | `object` | 電子署名の対象となる [EIP-712](https://eips.ethereum.org/EIPS/eip-712) 構造化データ。 |
| `ticketToken` | Yes | `string` | 電子署名チケットトークン。                                                        |

{% hint style="info" %}
電子署名チケットトークンは [POST /issueSignatureTicket](/01_spec/01_http-endpoint/01_interface/01_blockchain#issuesignatureticket) を利用して発行してください。
{% endhint %}

### 実行例

```js
const result = await unWallet.signEIP712TypedData({
  typedData: {
    types: {
      EIP712Domain: [
        { name: "name", type: "string" },
        { name: "version", type: "string" },
        { name: "chainId", type: "uint256" },
        { name: "verifyingContract", type: "address" },
      ],
      Person: [
        { name: "name", type: "string" },
        { name: "wallet", type: "address" },
      ],
      Mail: [
        { name: "from", type: "Person" },
        { name: "to", type: "Person" },
        { name: "contents", type: "string" },
      ],
    },
    primaryType: "Mail",
    domain: {
      name: "Ether Mail",
      version: "1",
      chainId: 1,
      verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
    },
    message: {
      from: {
        name: "Cow",
        wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
      },
      to: {
        name: "Bob",
        wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
      },
      contents: "Hello, Bob!",
    },
  },
  ticketToken:
    "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEiLCJ0eXAiOiJKV1QifQ.eyJhcGlDbGllbnRJRCI6IlFWQkpRMnhwWlc1ME9qSXkiLCJjbGllbnRJRCI6IkNYcWxKcEtZaVhMelZ1cTNtVTQ5VVk1VUZuMk4zVVJWdCIsImV4cCI6MTc0NzgyMjE2MiwiaWF0IjoxNzQ3ODIxODYyLCJpZCI6ImI5YTFjOGJjOTlkMmVhNTcxNWIwN2U4NzE5YWEyNmQ2Y2M3YzM1N2JiNzNhYTcxNDc2NjJhODBjNzEyMzYzYzgiLCJzaWduYXR1cmVEaWdlc3QiOiIweGJlNjA5YWVlMzQzZmIzYzRiMjhlMWRmOWU2MzJmY2E2NGZjZmFlZGUyMGYwMmU4NjI0NGVmZGRmMzA5NTdiZDIiLCJzaWduYXR1cmVTaWduZXJBZGRyZXNzIjoiMHhkMTIyOUVlMkIwY0Y5NzhEQTc3MDdBRDVEMDI1MzAxMjBmMDRhOUYxIn0.VqCfO3Dh_BsBACqpr2bYOX47TIkJy3EXGy_l6SouW1sBc6XsZE1996gIJ9jwHIswye1F_YrovV4EU0iHrHk8_g",
});
```

### 実行結果例

```json
{
  "digest": "0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2",
  "signature": "0xebdb66458c40c2b052c8d4abb32ffb7b82ddaa43fa4fa90220d6137716e627130aea57283de1823f1f44d227510817aa44bff499b9edb298d7f1bee3b2e6ac011c"
}
```

## sendTransaction

unWallet ユーザーに対して、指定したトランザクションの送信をリクエストします。

### 引数

|               | 必須  | 型        | 説明                                                 |
| ------------- | --- | -------- | -------------------------------------------------- |
| `chainID`     | Yes | `number` | トランザクションの送信先となるブロックチェーンのチェーン ID。                   |
| `toAddress`   | Yes | `string` | トランザクションの対象となるブロックチェーンアドレス。                        |
| `value`       | No  | `string` | トランザクションによって送付されるネイティブトークンの量（`0x` から始まる 16 進数文字列）。 |
| `data`        | No  | `string` | トランザクションデータ（`0x` から始まる 16 進数文字列）。                  |
| `ticketToken` | Yes | `string` | トランザクションチケットトークン。                                  |

{% hint style="info" %}
トランザクションチケットトークンは [POST /issueTransactionTicket](/01_spec/01_http-endpoint/01_interface/01_blockchain#issuetransactionticket) を利用して発行してください。
{% endhint %}

### 実行例

```js
const result = await unWallet.sendTransaction({
  chainID: 137,
  toAddress: "0xd1229Ee2B0cF978DA7707AD5D02530120f04a9F1",
  value: "0xde0b6b3a7640000",
  ticketToken:
    "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEiLCJ0eXAiOiJKV1QifQ.eyJhcGlDbGllbnRJRCI6IlFWQkpRMnhwWlc1ME9qRT0iLCJjaGFpbklEIjoxMzcsImNsaWVudElEIjoiQ1hxbEpwS1lpWEx6VnVxM21VNDlVWTVVRm4yTjNVUlZ0IiwiZXhwIjoxNzIxMjA3MjE1LCJpYXQiOjE3MjEyMDY5MTUsImlkIjoiMmQ5NGU4MDZkYjU4Yzk1YjAwYzQyYTM3ZjM0NGY1NmNkYjliZWJjYTQyNmUxM2FlOGY1MzM3NDA1MTE4MzhlMCIsInBheW1lbnRUeXBlIjoidXNlciIsInRyYW5zYWN0aW9uRGF0YSI6IjB4IiwidHJhbnNhY3Rpb25Gcm9tQWRkcmVzcyI6IjB4ZDEyMjlFZTJCMGNGOTc4REE3NzA3QUQ1RDAyNTMwMTIwZjA0YTlGMSIsInRyYW5zYWN0aW9uVG9BZGRyZXNzIjoiMHhkMTIyOUVlMkIwY0Y5NzhEQTc3MDdBRDVEMDI1MzAxMjBmMDRhOUYxIiwidHJhbnNhY3Rpb25WYWx1ZSI6IjB4ZGUwYjZiM2E3NjQwMDAwIn0.3RXhgkmMaMJKXSlpco5tuBAVOvVsQ9PRygogvkgKXDDRt22gt9zvCWdJvC2puk7B5oaxrAGyG0gkxfFmkHr9fw",
});
```

### 実行結果例

```json
{
  "transactionID": "UXVldWVkVHJhbnNhY3Rpb246MQ=="
}
```


# ユースケース


# unWallet 認証を組み込む

## 手順

### 1. アプリケーションを登録する

アプリケーションに unWallet 認証を組み込むためには、該当アプリケーションを認証アプリケーションとして登録する必要があります。

[POST /registerApplication](/01_spec/01_http-endpoint/01_interface/02_application#registerapplication) を利用して該当アプリケーションを登録してください。

### 2. ID トークンの発行をリクエストする

[こちら](/01_spec/02_client-side-sdk/01_basic) を参考にクライアントサイド SDK をインストールし、初期化してください。なお、SDK を初期化する際に指定する `clientID` は、前段でアプリケーションを登録した際に発行されたものを利用してください。

初期化が完了したら、`authorize` を実行し、unWallet ユーザーに対して ID トークン（JWT）の発行をリクエストしてください。

{% hint style="info" %}
`authorize` の詳細な仕様については [こちら](/01_spec/02_client-side-sdk/02_interface#authorize) を参照してください。
{% endhint %}

対象の unWallet ユーザーがリクエストを認可すると、`responseMode` に応じた方式で ID トークンを受け取ることができます。リクエストが不正とみなされてしまう場合は、前段で登録したアプリケーションの `allowedCallerOrigins` や `allowedCallbackURLs` が正しく設定されているかを確認してください。

### 3. ID トークンからユーザー情報を取得する

ID トークンの `sub` クレームの値が該当ユーザーのウォレットアドレスとなります。

{% tabs %}
{% tab title="JavaScript" %}

```js
const idToken = "<ID_TOKEN>";
const idTokenParts = idToken.split(".");
const claim = JSON.parse(atob(idTokenParts[1]));
const userAddress = claim.sub;
```

{% endtab %}
{% endtabs %}

なお、ID トークンの正当性を検証するための JWKS は <https://api.authmgr.unwallet.world/.well-known/jwks> で公開されています。


# NFT を発行する

## 手順

### 1. NFT コントラクトを実装・デプロイする

unWallet Enterprise を介して NFT を発行するためには、該当 NFT に相当するコントラクトが以下の条件を満たす必要があります。

* `IAirdroppableNFT` を実装していること
  * `IAirdroppableNFT` の内容については [こちら](https://github.com/SIVIRA/evm-contract-samples/blob/main/contracts/IAirdroppableNFT.sol) を参照してください
  * `IAirdroppableNFT` に含まれる各関数は、[POST /mintNFT](/01_spec/01_http-endpoint/01_interface/01_blockchain#mintnft) を介してコールされます
    * `airdrop`：`nftMetadataType` と `nftMetadataURI` が指定されなかった場合にコールされます
    * `airdropByType`：`nftMetadataType` が指定された場合にコールされます
    * `airdropWithTokenURI`：`nftMetadataURI` が指定された場合にコールされます
* unWallet Enterprise 管理下にある特定のコントラクト（`0xb607656eBB77b4f0e273fFe5Bc613ff46A77E0CC`）から `IAirdroppableNFT` に含まれる各関数をコールできること

簡単のため、ここでは `airdrop` のみを実装したシンプルな NFT コントラクトを利用することとします。実装例は [こちら](https://github.com/SIVIRA/evm-contract-samples/blob/main/contracts/SampleSingleTypeNFT.sol) を参照してください。

{% hint style="info" %}
本ユースケースでは扱いませんが、`nftMetadataType` を指定して [POST /mintNFT](/01_spec/01_http-endpoint/01_interface/01_blockchain#mintnft) をコールしたい場合、対象となる NFT コントラクトが `airdropByType` を実装している必要があります。実装例は [こちら](https://github.com/SIVIRA/evm-contract-samples/blob/main/contracts/SampleMultipleTypeNFT.sol) を参照してください。
{% endhint %}

{% hint style="info" %}
本ユースケースでは扱いませんが、`nftMetadataURI` を指定して [POST /mintNFT](/01_spec/01_http-endpoint/01_interface/01_blockchain#mintnft) をコールしたい場合、対象となる NFT コントラクトが `airdropWithTokenURI` を実装している必要があります。実装例は [こちら](https://github.com/SIVIRA/evm-contract-samples/blob/main/contracts/SampleTypelessNFT.sol) を参照してください。
{% endhint %}

### 2. NFT の発行先となるアドレスを決定する

NFT の発行先となるアドレスを決定してください。

unWallet ユーザーに対して NFT を発行したい場合は、[unWallet 認証](/02_usecase/01_connect-to-unwallet) を行い、該当ユーザーのウォレットアドレスを取得してください。

### 3. NFT 発行をリクエストする

[POST /mintNFT](/01_spec/01_http-endpoint/01_interface/01_blockchain#mintnft) を利用して、NFT 発行をリクエストしてください。

前述した通り、ここでは `airdrop` のみを実装した NFT コントラクトに対して NFT 発行をリクエストしますので、以下のリクエストパラメータを指定することとなります。

* `chainID`：該当 NFT コントラクトがデプロイされているブロックチェーンのチェーン ID
* `nftAddress`：該当 NFT コントラクトのアドレス
* `ownerAddress`：NFT の発行先となるアドレス

なお、[POST /mintNFT](/01_spec/01_http-endpoint/01_interface/01_blockchain#mintnft) のレスポンスには NFT 発行トランザクションに関する情報が含まれます。後続の処理で利用しますので、適宜保存しておいてください。

### 4. NFT 発行トランザクションのステータスを確認する

[GET /getTransaction](/01_spec/01_http-endpoint/01_interface/01_blockchain#gettransaction) を利用して、NFT 発行トランザクションのステータスを確認することができます。

リクエスト直後のステータスは `pending` ですが、該当トランザクションがブロックチェーンに取り込まれると `success` または `failure` に変わります。このことを考慮して後続の処理を行なってください。


# unWallet ユーザーに対して電子署名をリクエストする

## 手順

### 1. unWallet 認証を終わらせる

unWallet ユーザーに対して電子署名をリクエストするためには、該当ユーザーがリクエスト元となる認証アプリケーションとの接続を認可している必要があります。この認可は [unWallet 認証](/02_usecase/01_connect-to-unwallet) の中で行われますので、まずはこちらを終わらせてください。

### 2. 電子署名チケットトークンを発行する

[POST /issueSignatureTicket](/01_spec/01_http-endpoint/01_interface/01_blockchain#issuesignatureticket) を利用して、電子署名チケットトークンを発行してください。なお、この処理はアプリケーションのバックエンドで行なってください。

### 3. 電子署名をリクエストする

クライアントサイド SDK の `sign` を実行し、unWallet ユーザーに対して電子署名をリクエストしてください。なお、`sign` の引数である `ticketToken` には、前段で発行した電子署名チケットトークンを指定してください。それ以外の引数には、前段で電子署名チケットトークンを発行した際に指定した値と同じ値を指定してください。

{% hint style="info" %}
`sign` の詳細な仕様については [こちら](/01_spec/02_client-side-sdk/02_interface#sign) を参照してください。
{% endhint %}

リクエストが不正とみなされてしまう場合は、前段で登録した認証アプリケーションの `allowedCallerOrigins` が正しく設定されているかを確認してください。

### 4. 電子署名の正当性を検証する

unWallet はコントラクトウォレットであるため、[ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) に準拠した方法で電子署名の正当性を検証してください。

{% tabs %}
{% tab title="JavaScript" %}

```js
import { ethers } from "ethers";

(async () => {
  const contract = new ethers.Contract(
    "<USER_ADDRESS>",
    [
      {
        inputs: [
          {
            internalType: "bytes32",
            name: "hash",
            type: "bytes32",
          },
          {
            internalType: "bytes",
            name: "signature",
            type: "bytes",
          },
        ],
        name: "isValidSignature",
        outputs: [
          {
            internalType: "bytes4",
            name: "",
            type: "bytes4",
          },
        ],
        stateMutability: "view",
        type: "function",
      },
    ],
    new ethers.JsonRpcProvider("<YOUR_RPC_URL>")
  );

  try {
    await contract.isValidSignature("<DIGEST>", "<SIGNATURE>");
  } catch (e) {
    console.log("invalid");
    return;
  }

  console.log("valid");
})();
```

{% endtab %}
{% endtabs %}


# unWallet ユーザーに対してトランザクション送信をリクエストする

## 手順

### 1. unWallet 認証を終わらせる

unWallet ユーザーに対してトランザクション送信をリクエストするためには、該当ユーザーがリクエスト元となる認証アプリケーションとの接続を認可している必要があります。この認可は [unWallet 認証](/02_usecase/01_connect-to-unwallet) の中で行われますので、まずはこちらを終わらせてください。

### 2. トランザクションチケットトークンを発行する

[POST /issueTransactionTicket](/01_spec/01_http-endpoint/01_interface/01_blockchain#issuetransactionticket) を利用して、トランザクションチケットトークンを発行してください。なお、この処理はアプリケーションのバックエンドで行なってください。

### 3. トランザクション送信をリクエストする

クライアントサイド SDK の `sendTransaction` を実行し、unWallet ユーザーに対してトランザクション送信をリクエストしてください。なお、`sendTransaction` の引数である `ticketToken` には、前段で発行したトランザクションチケットトークンを指定してください。それ以外の引数には、前段でトランザクションチケットトークンを発行した際に指定した値と同じ値を指定してください。

{% hint style="info" %}
`sendTransaction` の詳細な仕様については [こちら](/01_spec/02_client-side-sdk/02_interface#sendtransaction) を参照してください。
{% endhint %}

リクエストが不正とみなされてしまう場合は、前段で登録した認証アプリケーションの `allowedCallerOrigins` が正しく設定されているかを確認してください。

なお、`sendTransaction` の返り値には送信したトランザクションに関する情報が含まれます。後続の処理で利用しますので、適宜保存しておいてください。

### 4. トランザクションのステータスを確認する

[GET /getTransaction](/01_spec/01_http-endpoint/01_interface/01_blockchain#gettransaction) を利用して、送信したトランザクションのステータスを確認することができます。

リクエスト直後のステータスは `pending` ですが、該当トランザクションがブロックチェーンに取り込まれると `success` または `failure` に変わります。このことを考慮して後続の処理を行なってください。


