NAV
javascript http shell html

Overview

HTTPS End Point (Base URL)

https://api.web3connect.jp/rest/v1

HTTP Headers required in the requests

Especially for the APIs that need to know the identity of the client (requester)

HTTP Header

Authorization: Bearer <ACCESS_TOKEN>

ACCESS_TOKEN is in JWT format.

ACCESS_TOKEN v.s. API_KEY_SECRET

DO NOT USE API KEY SECRET IN PUBLIC ZONE OR ANY FRONTEND.

Common Response Body Format

{
  "status": "ok", // "error"
  "result": {}, // null, Object, Array, Boolean, String or Number
  "error": null // null, Error Message in String or Error Message in Object
}

Auth API

Please obtain your API Key Secret from Web3Connect beforehand.

An API Key Secret can be used to obtain the access token and confirmation token.

Refresh (Obtain) Access Token with API Key Secret

Request Body JSON Sample (Content-Type: application/json)

{
  "api_key_secret": "<SECRET>"
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": "<ACCESS_TOKEN>",
  "error": null
}

Check Account Type and Address

Please obtain your API Key Secret from Web3Connect beforehand.

An API Key Secret can be used to obtain the access token and confirmation token.

Request Body JSON Sample (Content-Type: application/json)

{
  "api_key_secret": "<SECRET>"
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "account_id": "<YOUR_ACCOUNT_ID>",
    "id_wallet_address_eth": "<ID_WALLET_ADDRESS>",
    "id_wallet_address_suri": "<ID_WALLET_ADDRESS_SURI>",
    "account_type": "organization" // "end_user"
  },
  "error": null
}

Account Association & End-user Import

Generate Web3Connect Button OnClick JavaScript function code body

This API helps generating required JavaScript code for the Web3Connect button in organization's web page or mobile app.

Request Body JSON Sample (Content-Type: application/json)

{
  "api_key_secret": "<SECRET>" // YOUR API KEY SECRET,
  "redirect_url": "https://company.com/abc/def?g=h&userId=xxx" // For the redirection after the end-user finishes the association process
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": "function globalWeb3ConnectButtonOnClick() {...}", // JavaScript function code body
  "error": null
}

In redirect_url of the request body, the organization should include the identifier of the end-user in order to associate the organization's end-user with an ID Wallet Address in the organization's internal system.

For example, userId=xxx in the redirect url's query param (any query param is allowed for the organization).

(Cont'd) Embed the JavaScript code in to the organization's web page

The organization needs to embed the function code body in the <script>...</script> section in the header of the web page,
and bind the onclick event to the button like :

<head>
  <script>
    /* function globalWeb3ConnectButtonOnClick() {
    } */
    /* from the result of the previous API call */
  </script>
</head>

<body>
  <button onclick="event.preventDefault();globalWeb3ConnectButtonOnClick();">
    Web3Connect
  </button>
</body>

(Cont'd) Let the end-user walk through the association process

Once the end-user clicks the button, the end-user will walk through the association process in a newly opened web page (association page), and Web3Connect backend will associate the end-user account (will be created if needed) with the organization account (the reason why this API needs the API_KEY_SECRET).

(Cont'd) The organization process the callback http request (redirect_url)

And finally, a url (the adjusted redirect url) :

GET
https://company.com/abc/def?g=h&userId=xxx&id_wallet_address=0x1234567890123456789012345678901234567890

The url will be opened by the end-user's web browser (a query param id_wallet_address is appended to the url) at the end of the association process, the organization should process this HTTP request to finish the organization's internal system process.

(Cont'd) The organization should store the id_wallet_address of the end-user

The organization will need to store the id_wallet_address of the end-user inside their database or system.

Through this process, the organization will only know the id_wallet_address of an end-user, but not its email.

An ID Wallet will be automatically created if the end-user's info does not exist in Web3Connect.

This implies that the end-user already knows which email is used for login.

Request Body JSON Sample (Content-Type: application/json)

{
  "email": "abc@def.com"
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "email": "abc@def.com",
    "id_wallet_address": "0x....",
    "id_wallet_address_eth": "0x....",
    "id_wallet_address_suri": "5f...."
  }
  "error": null
}

Import Existing End-users with their emails in batch (Submit)

This implies that the end-user already knows which email is used for login.

Request Body JSON Sample (Content-Type: application/json)

{
  "api_key_secret": "<API_KEY_SECRET>",
  "emails": ["abc@def.com", "abc2@def.com"] // max number of emails in a batch is 10000
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "batch_id": "2023-10-18T04:38:18.615Z:W0Bq3p5GpqxQwh4F"
  },
  "error": null
}

Please use the batch_id to poll the result in next method.

Import Existing End-users with their emails in batch (Check)

This implies that the end-user already knows which email is used for login.

Request Body JSON Sample (Content-Type: application/json)

{
  "api_key_secret": "<API_KEY_SECRET>",
  "batch_id": "2023-10-18T04:38:18.615Z:W0Bq3p5GpqxQwh4F"
}

(Running) Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "batch_result": {
      "batch_id": "2023-10-18T04:38:18.615Z:W0Bq3p5GpqxQwh4F",
      "finished_at": "",
      "result": [],
      "started_at": "2023-10-18T04:38:18.615Z",
      "status": "running"
    }
  },
  "error": null
}

(Done) Response Body JSON Sample (Content-Type: application/json)

There can be "ok": false, meaning the id-wallet creation with the email was failed.

{
  "status": "ok",
  "result": {
    "batch_result": {
      "batch_id": "2023-10-18T04:38:18.615Z:W0Bq3p5GpqxQwh4F",
      "finished_at": "2023-10-18T04:38:19.389Z",
      "result": [
        {
          "email": "abc@def.com",
          "id_wallet_address": "0xa20165...",
          "id_wallet_address_eth": "0xa20165...",
          "id_wallet_address_suri": "5DpyvArpUV6H...",
          "ok": true
        },
        {
          "email": "abc2@def.com",
          "id_wallet_address": "",
          "id_wallet_address_eth": "",
          "id_wallet_address_suri": "",
          "ok": false
        }
      ],
      "started_at": "2023-10-18T04:38:18.615Z",
      "status": "done"
    }
  },
  "error": null
}

Verify API (for Organization Account)

Web3Connect will support the verification process during the creation of the organization account.

Verify Phone Step 1

This will send a code to the mobile.

Request Body JSON Sample (Content-Type: application/json)

{
  "phone_number": "+8860912345678" // a valid mobile phone number in E.164 format
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "tmp_token": "token string", // this is critical for step 2
    "code_sent": true
  },
  "error": null
}

Verify Phone Step 2

Please take the tmp_token from the response in step 1.

Request Body JSON Sample (Content-Type: application/json)

{
  "tmp_token": "token string", // from step 1
  "code": "123456" // the verification code received by the phone
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": true, // phone verified
  "error": null
}

Verify Domain Step 1

Only Organization Account can perform this action.

domain in the response is from the value during the sign-up process of the Organization Account.

Please set the value of txt_record under the domain's TXT record (the domain is already set during the sign-up process)

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "txt_record": "web3connect-domain-verification=XXXXXXXXXX",
    "domain": "company.com"
  },
  "error": null
}

Verify Domain Step 2

Only Organization Account can perform this action.

This step checks the txt record of the domain.

Please set the value of txt_record under the domain's TXT record in step 1.

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": true, // domain verified
  "error": null
}

Account API

Get Public Account Info by ID Wallet Address

Please replace the <id_wallet_address> section in the url with the ID Wallet Address (e.g. 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcdef)

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "id_wallet_address": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcdef",
    "id_wallet_public_key_jwk": {
      "kty": "EC",
      "crv": "secp256k1",
      "x": "base64url string",
      "y": "base64url string"
    }
  },
  "error": null
}

Get My Info

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "account_id": "6aecfd05-4de5-31c3-052c-ce3dae83057d",
    "oidc_issuer_url": null,
    "sub": "6aecfd05-4de5-31c3-052c-ce3dae83057d",
    "name": null,
    "given_name": null,
    "family_name": null,
    "middle_name": null,
    "nickname": null,
    "preferred_username": null,
    "profile": null,
    "picture": null,
    "website": null,
    "email": "My Email",
    "email_verified": true,
    "gender": null,
    "birthdate": null,
    "zoneinfo": null,
    "locale": null,
    "phone_number": null,
    "phone_number_verified": false,
    "address": null,
    "account_type": "end_user",
    "domain": null,
    "domain_verified": false,
    "id_wallet": {
      "address": "0x5d2c54024c8f9d58059da8c47ba7e5bbdab6b249",
      "jwk_encrypted": {
        "kty": "EC",
        "crv": "secp256k1",
        "x": "zP1RAll6_fSP83YulysNF3L3YVef6DGa0d0Dlh794K4",
        "y": "ON2BME5Sptnptg970Bnuz4qk9tZqSfaHuHg2W-jaKLE"
      },
      "owner": "62da2c56ec8145256f37f3fc",
      "created_date_string": "2022-07-22T04:49:26.105Z",
      "created_at": "2022-07-22T04:49:26.134Z",
      "updated_at": "2022-07-22T04:49:26.134Z",
    },
    "created_at": "2022-07-22T04:49:26.125Z",
    "updated_at": "2022-07-22T04:49:26.125Z",
  },
  "error": null
}

NFT API

Mint NFT by Organization Account

Only Organization Account can perform this action.

Organization Account's domain must be verified beforehand.

Please replace <holder_id_wallet_address> section in the url to the id_wallet_address of the end-user account (who will become the holder of the newly minted nft).
(e.g. 0x1234567890123456789012345678901234567890)

Body JSON Spec and Sample

https://docs.google.com/spreadsheets/d/1y2TTQHOvqhNcPiyFB877_60Nj-PhwQwrNN3Y8CsSiSw

Request Body JSON Sample (Content-Type: application/json)

{
  "metadata": {
    "static": {
      // all required, except "expired_at"
      "issuer": "string",
      "contents_provider": "name",
      "name": "name",
      "description": "text",
      "image": "url",
      "link": "url",
      "serial_number": 123, // integer
      "total_issued": 321, // integer
      "animation_url": "url",
      "expired_at": "2030-12-31T12:34:56.000Z" // optional, format is Date ISO String, by default it is 9999-12-31T23:59:59.000Z
    },
    "dynamic": {
      // all optional
      "external_url": "string",
      "youtube_url": "string",
      "background_color": "string",
      "category": "string",
      "id": "string",
      "points_earned": 12, // number
      "unit_of_points": "string",
      "program_name": "string",
      "organization": "string",
      "brand": "string",
      "branch": "string",
      "department": "string",
      "address": "string",
      "sns1": "string",
      "sns2": "string",
      "sns3": "string",
      "role": "string",
      "numbered_position": 1, // integer
      "email": "string",
      "tel": "string",
      "reference_name": "string",
      "license": "string",
      "competency": "string",
      "credential_category": "string",
      "level": "string",
      "status": "string",
      "date_created": 1784576401, // integer
      "date_modified": 1784576401, // integer
      "expires": 1784576401, // integer
      "valid_latitude": "string",
      "valid_longitude": "string",
      "valid_radius": 5.2, // number
      "unit_of_length": "string",
      "ticketed_seat": "string",
      "total_value": 100, // number
      "consumable_value": 123, // number
      "price_currency": "string",
      "discount_rate": 10, // number
      "gtin": "string",
      "gtin12": "string",
      "gtin13": "string",
      "gtin14": "string",
      "gtin8": "string",
      "has_adult_consideration": "string",
      "rating": "string",
      "copyright_notice": "string",
      "copyright_year": 2022, // integer
      "credit_text": "string",
      "version": "string",
      "policy": "string",
      "keywords": "string",
      "attributes": [], // array
      "properties": {}, // object
      "localization": {} // object
      // and any other keys and values
    }
  }
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "token_id": "string",
    "token_uri": "string",
    "minter_digital_signature": "string",
    "created_at": "2022-12-31T12:34:56.000Z",
    "metadata": {
      "static": {
        "issuer": "string",
        "contents_provider": "name",
        "name": "name",
        "description": "text",
        "image": "url",
        "link": "url",
        "serial_number": 123, // integer
        "total_issued": 321, // integer
        "animation_url": "url"
      },
      "dynamic": {
        "external_url": "string",
        "youtube_url": "string",
        "background_color": "string",
        "category": "string",
        "id": "string",
        "points_earned": 12, // number
        "unit_of_points": "string",
        "program_name": "string",
        "organization": "string",
        "brand": "string",
        "branch": "string",
        "department": "string",
        "address": "string",
        "sns1": "string",
        "sns2": "string",
        "sns3": "string",
        "role": "string",
        "numbered_position": 1, // integer
        "email": "string",
        "tel": "string",
        "reference_name": "string",
        "license": "string",
        "competency": "string",
        "credential_category": "string",
        "level": "string",
        "status": "string",
        "date_created": 1784576401, // integer
        "date_modified": 1784576401, // integer
        "expires": 1784576401, // integer
        "valid_latitude": "string",
        "valid_longitude": "string",
        "valid_radius": 5.2, // number
        "unit_of_length": "string",
        "ticketed_seat": "string",
        "total_value": 100, // number
        "consumable_value": 123, // number
        "price_currency": "string",
        "discount_rate": 10, // number
        "gtin": "string",
        "gtin12": "string",
        "gtin13": "string",
        "gtin14": "string",
        "gtin8": "string",
        "has_adult_consideration": "string",
        "rating": "string",
        "copyright_notice": "string",
        "copyright_year": 2022, // integer
        "credit_text": "string",
        "version": "string",
        "policy": "string",
        "keywords": "string",
        "attributes": [], // array
        "properties": {}, // object
        "localization": {} // object
        // and other properties
      }
    }
  },
  "error": null
}

Fetch NFT info

If the NFT's visibility is private, then only the holder or minter can check it.

If the NFT's visibility is public, then any account can check it.

Please replace <token_id> section in the url with the real value (a hex string, e.g. 0xabcdef123123123123...).

Please check the response body json in Mint NFT by Organization Account for the schema of the NFT object.

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {}, // the NFT object, please refer to the response of mint nft
  "error": null
}

Transfer NFT

This action can be performed only by the current holder or minter

Transfer the NFT to another end-user (receiver)

Please replace <token_id> section in the url with the real value (a hex string, e.g. 0xabcdef123123123123...).

Please replace <receiver_id_wallet_address> section in the url with receiver's id_wallet_address (eth).

Update NFT dynamic metadata

This action can be performed only by the minter of the NFT (Organization Account)

Please replace <token_id> section in the url with the real value (a hex string, e.g. 0xabcdef123123123123...).

Please check the response body json in Mint NFT by Organization Account for the schema of the NFT object.

Request Body JSON Sample (Content-Type: application/json)

{
  "key1": "value1", // any key-value supported for dynamic metadata, or any custom key-value
  "key2": "value2",
  "key3": "value3"
  // ....
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {}, // the NFT object with updated dynamic metadata, please refer to the response of mint nft
  "error": null
}

List NFTs being held by an ID Wallet (End-user Account)

Please replace the value <ID_WALLET_ADDRESS> to the actual one in the url.

perPageItemNum query param is for setting how many NFT objects per page. Default value is 10.

pageNum query param starts from 1, for listing the NFT objects of the n-th page. Default value is 1.

order query param is for controlling sort order based on created_at of the NFTs, it can be desc or asc, default value is asc.

Please check the response body json in Mint NFT by Organization Account for the schema of the NFT object.

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], // the Array of NFT object. For each NFT object, please refer to the response of mint nft
  "error": null
}

Only the NFTs visible by the requester (http client) will be returned.

List NFTs minted by Organization Account (Minter)

Only the minter (organization account) can perform this action.

perPageItemNum query param is for setting how many NFT objects per page.

pageNum query param starts from 1, for listing the NFT objects of the n-th page.

order query param is for controlling sort order based on created_at of the NFTs, it can be desc or asc, default value is asc.

Please check the response body json in Mint NFT by Organization Account for the schema of the NFT object.

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], // the Array of NFT object. For each NFT object, please refer to the response of mint nft
  "error": null
}

Toggle NFT visibility

Only the holder (end-user account) and the minter (organization account) can perform this action.

Please replace <token_id> section in the url with the real value (a hex string, e.g. 0xabcdef123123123123...).

Request Body JSON Sample (Content-Type: application/json)

{
  "to": "public" // or "private"
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": "public", // or "private"
  "error": null
}

This can only find public NFTs.

perPageItemNum query param is for setting how many NFT objects per page.

pageNum query param starts from 1, for listing the NFT objects of the n-th page.

order query param is for controlling sort order based on created_at of the NFTs, it can be desc or asc, default value is asc.

Please check the response body json in Mint NFT by Organization Account for the schema of the NFT object.

Request Body JSON Sample (Content-Type: application/json)

// each field can be set to undefined for ignoring the field matching
{
  "issuer": "string match value",
  "contents_provider": "string match value",
  "name": "string match value",
  "description": "string match value",
  "category": "string match value",
  "program_name": "string match value",
  "organization": "string match value",
  "brand": "string match value",
  "competency": "string match value",
  "credential_category": "string match value",
  "level": "string match value",
  "status": "string match value",
  "gtin": "string match value",
  "gtin12": "string match value",
  "gtin13": "string match value",
  "gtin14": "string match value",
  "gtin8": "string match value",
  "has_adult_consideration": "string match value",
  "rating": "string match value",
  "keywords": "string match value"
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}], // the Array of NFT object. For each NFT object, please refer to the response of mint nft
  "error": null
}

Please refer to the previous one for the request/response body format.

Generate QR Code for NFT verification by the holder (NFT Verification Step 1)

Only the holder (end-user account) can perform this action.

Please replace <token_id> section in the url with the real value (a hex string, e.g. 0xabcdef123123123123...).

The holder only needs to post the current gps location of its device to the web3connect api.

The QR Code in the result is base64 encoded image.

The QR Code will be only available for next 5 minutes, the scanner must scan this QR Code ASAP.

Request Body JSON Sample (Content-Type: application/json)

{
  // this should be the current location of the holder
  "gps": {
    "latitude": "26.583193",
    "longitude": "128.053881"
  }
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "code": "1234567890",
    "qr_code_base64": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAgAAAQICAYAAACAmekaAAAAAXNSR0IArs4c6QAAIABJREFUeF7snUGW3TgOBF33P7TnTXvtLz5nRQFJxaxFKBlIgBT8u+br9+/fv3/5PwlIQAISkIAEJCABCUhAAhKQgAReTeDLAcGr8+/mJSABCUhAAhKQgAQkIAEJSEAC/xFwQKARJCABCUhAAhKQgAQkIAEJSEACEnBAoAckIAEJSEACEpCABCQgAQlIQAIS8BcEekACEpCABCQgAQlIQAISkIAEJCAB/xMDPSABCUhAAhKQgAQkIAEJSEACEpDA/wn4Nwj0gQQkIAEJSEACEpCABCQgAQlIQAIOCPSABCQgAQlIQAISkIAEJCABCUhAAv6CQA9IQAISkIAEJCABCUhAAhKQgAQk4H9ioAckIAEJSEACEpCABCQgAQlIQAIS+D8B/waBPpCABCQgAQlIQAISkIAEJCABCUjAAYEekIAEJCABCUhAAhKQgAQkIAEJSMBfEOgBCUhAAhKQgAQkIAEJSEACEpCABPxPDPSABCQgAQlIQAISkIAEJCABCUhAAv8n4N8g0AcSkIAEJCABCUhAAhKQgAQkIAEJOCDQAxKQgAQkIAEJSEACEpCABCQgAQn4CwI9IAEJSEACEpCABCQgAQlIQAISkID/iYEekIAEJCABCUhAAhKQgAQkIAEJSOD/BPwbBPpAAhKQgAQkIAEJSEACEpCABCQgAQcEekACEpCABCQgAQlIQAISkIAEJCABf0GgByQgAQlIQAISkIAEJCABCUhAAhLwPzHQAxKQgAQkIAEJSEACEpCABCQgAQn8n4B/g0AfSEACEpCABCQgAQlIQAISkIAEJOCAQA9IQAISkIAEJCABCUhAAhKQgAQk8AO/IPj6+pKzBNYS+P3791ptJ8Lo+mrnc8IweYbmn2g7WdueX5o/zUf9Jy71mb8RoP3ZTp6ur3Y..."
  },
  "error": null
}

The content of the QR Code is a JSON String

{
  "c":"1UV7xBEH6hLWec5s5VzT6MBNrPBaTJJA",
  "m":{},
  "p":"nft_verification_code",
  "v":"0"
}

Verify QR Code for NFT verification by the scanner (NFT Verification Step 2)

The scanner scanned the qrcode.

The query param CODE is exactly from the qrcode image, the decoded content of the qrcode image is this CODE.

And the requester (scanner) must add location information into the request body

Request Body JSON Sample (Content-Type: application/json)

// this should be the current location of the scanner
{
  "gps": {
    "latitude": "26.583193",
    "longitude": "128.053881"
  }
}

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "token_id": "<VERIFIED_NFT_TOKEN_ID>"
  }
  "error": null
}

Poll NFT Verification result

Put the code from the response of step1 into the query param

Response Body JSON Sample (Content-Type: application/json)

{
  "status": "ok",
  "result": {
    "token_id": "<VERIFIED_NFT_TOKEN_ID>" // null if not verified yet
  }
  "error": null
}

Response Body JSON Sample (Content-Type: application/json)

{
    "status": "ok",
    "result": {
        "token_id": "0xf27cb07069a1de3da2f539f79ef7d2d080ecc8e3b7440bed6b975963786d0b5f",
        "transactions": [
            {
                "network": 7,
                "trackId": "2023-09-18T22:53:19.065Z:o1eDTXGPYJdC9jby",
                "transactionId": "1033784-2",
                "blockNumber": "1033784",
                "explorerUrl": "https://explorer.testnet.thxnet.org/lmt/extrinsic/1033784-2",
                "panelUrl": "https://panel.testnet.thxnet.org/?rpc=wss%3A%2F%2Fnode.lmt.testnet.thxnet.org%2Farchive-001%2Fws#/explorer/query/1033784"
            },
            {
                "network": 7,
                "trackId": "2023-09-18T23:36:58.364Z:V6UJMYYNrerdquUr",
                "transactionId": "1034001-2",
                "blockNumber": "1034001",
                "explorerUrl": "https://explorer.testnet.thxnet.org/lmt/extrinsic/1034001-2",
                "panelUrl": "https://panel.testnet.thxnet.org/?rpc=wss%3A%2F%2Fnode.lmt.testnet.thxnet.org%2Farchive-001%2Fws#/explorer/query/1034001"
            }
        ],
        "mint": {
            "network": 7,
            "trackId": "2023-09-18T22:53:19.065Z:o1eDTXGPYJdC9jby",
            "transactionId": "1033784-2",
            "blockNumber": "1033784",
            "explorerUrl": "https://explorer.testnet.thxnet.org/lmt/extrinsic/1033784-2",
            "panelUrl": "https://panel.testnet.thxnet.org/?rpc=wss%3A%2F%2Fnode.lmt.testnet.thxnet.org%2Farchive-001%2Fws#/explorer/query/1033784"
        },
        "transfers": [
            {
                "network": 7,
                "trackId": "2023-09-18T23:36:58.364Z:V6UJMYYNrerdquUr",
                "transactionId": "1034001-2",
                "blockNumber": "1034001",
                "explorerUrl": "https://explorer.testnet.thxnet.org/lmt/extrinsic/1034001-2",
                "panelUrl": "https://panel.testnet.thxnet.org/?rpc=wss%3A%2F%2Fnode.lmt.testnet.thxnet.org%2Farchive-001%2Fws#/explorer/query/1034001"
            }
        ],
        "burn": null
    },
    "error": null
}

OpenID Connect (OIDC)

Please obtain your client_id (your organization account's id) from Web3Connect beforehand.

Also, please register your redirect_uri(s) with Web3Connect beforehand, otherwise the OIDC Provider will deny the Authorization Request.

OIDC Configuration

https://oidc.web3connect.jp/.well-known/openid-configuration

Auth Endpoint

https://oidc.web3connect.jp/oauth2/auth

Preparation

  1. Pick a standard OIDC or OAuth Client implementation as the framework or library.
  2. Choose Hybrid Flow or Implicit Flow based on the scenario.

Hybrid Flow (Obtaining Authorization Code and ID Token) Step 1

Please memorize the value of the Code Verifier while generating the code challenge, it will be used in next steps.

To start a Hybrid Flow

https://oidc.web3connect.jp/oauth2/auth
  ?client_id=<Your Organization Account ID>
  &redirect_uri=<The Redirect URI>
  &scope=openid profile email
  &response_type=code id_token
  &response_mode=form_post
  &code_challenge_method=S256
  &code_challenge=Nn9K_hdiApoT5lZ57NJ3JTrxIUmYiBW2Jm9v2RMGgdw
  &state=6oys34lajmw
  &nonce=lmqks95eaz

Response (Form Body) to the redirect_uri

code=WcvHHQQRHJ8dfWaxNMHednOxwvrsP6uh97Q8BJq9dER
id_token=eyJhbGciOiJFUzI1NksiLCJ0eXAi.....FvCwaqwMvw
state=6oys34lajmw

The id_token in the response already contains the sub of the end-user, which is the id_wallet_address of the end-user.

Hybrid Flow Step 2 : Obtain Access Token with Authorization Code

Request

curl --request POST \
     --url https://oidc.web3connect.jp/oauth2/token \
     --header 'Content-Type: application/x-www-form-urlencoded' \
     --data grant_type=authorization_code \
     --data code='<The Authorization Code from previous step>' \
     --data redirect_uri='<The Redirect URI>' \
     --data code_verifier='<The Code Verifier used in the previous step>' \
     --data client_id='<Your Organization Account ID>'

Response Body JSON Sample (Content-Type: application/json)

{
    "access_token": "_7kmwbZI.....vSR",
    "expires_in": 3600,
    "id_token": "eyJhbGciOiJFUz.....mAf8Vs5vgzg",
    "scope": "openid profile email",
    "token_type": "Bearer"
}

Please use the value of access_token for the next step.

Hybrid Flow Step 3 : Obtain End-user's Claim with Access Token

Request

curl --request GET \
     --url https://oidc.web3connect.jp/userinfo \
     --header 'Authorization: Bearer _7kmwbZI.....vSR'

Response Body JSON Sample (Content-Type: application/json)

{
    "sub": "0x7c7e0922c583c1764b6d52255d58066af7cb3cfe",
    "id_wallet_address": "0x7c7e0922c583c1764b6d52255d58066af7cb3cfe",
  "email": "...."
}

Step 2 ~ Step 3 are unnecessary if the ID Token in Step 1 is enough for the scenario.

Implicit Flow (Obtaining ID Token directly)

Please remember to make a proper handler at redirect_uri if response_mode is set to form_post, the HTTP request being made to the redirect_uri is same as in Hybrid Flow, basically a form body (x-www-form-urlencoded).

To start an Implicit Flow

https://oidc.web3connect.jp/oauth2/auth
  ?client_id=<Your Organization Account ID>
  &redirect_uri=<The Redirect URI>
  &scope=openid profile email
  &response_type=id_token
  &response_mode=fragment
  &state=h57c17pw8b6
  &nonce=a2k8m15590n

Response in the fragment (#id_token=....) (window.location.hash) at redirect_uri

id_token=eyJhbGci...nmhg state=h57c17pw8b6

ID Token in the Implicit Flow will contain id_wallet_address directly, after decoding the payload will look like:

{
   "sub": "0x7c7e0922c583c1764b6d52255d58066af7cb3cfe",
   "id_wallet_address": "0x7c7e0922c583c1764b6d52255d58066af7cb3cfe",
   "email": "....",
   "nonce": "a2k8m15590n",
   "s_hash": "MTr5Del-UwmhaC6vVp6rQQ",
   "aud": "75a6....13",
   "exp": 1666185426,
   "iat": 1666181826,
   "iss": "https://oidc.web3connect.jp"
}

Errors

WIP