KONG Bridge

What is it?

This app is intended to link KONG HaLo and SiLo devices that are registered in KONG registry with IPFS resources and smart contracts in order to create gaslessly minted crypto assets tied to HaLo's and SiLo's. The legacy portion of the server consists of an ExpressJS app communicating with a MongoDB database. This database mirrors the SiLo device information registered in the KONG registry contract and associated IPFS documents, e.g. the primary public key of a given device.

Ongoing Development

The new minting process leverages Arweave to create records in a fully decentralized fashion that do not rely on this server after creation. This process is currently only available to HaLo devices via the /mint endpoint.

Interfaces

This app consists of three kinds of interfaces: those relating directly to Devices, those relating to Tokens associated with devices and those used to Reveal token information for devices. Device interfaces are typically low level and can be considered to be "offchain" or unminted.

Devices

GET /device : find a SiLo device.

Present x and y public key coordinates as quert parameters in a GET request to look up the information of a registered device.

Example

curl --location --request GET 'localhost:3000/device?x=1f8b3a5703b376d9b82869605866a3d8bc4e08803873eba4a4c5e6ee847aae28&y=14a12a78c29acd8b2748f19a96c725111c873bf06e7514b042aa7ed1be718730'

Response

A successful retrieval of the device will return all information in the database relating to the device:

{
    "_id": "6095a4267cbf072c0888ed60",
    "hardwareHash": "0x3d83f849819dddb68c5f464f6d1e8e6e9876d1c4236287db1ee5fdba2f9b9fe3",
    "primaryPublicKeyHash": "0xe2e592b208029d63e9fb7fd00690a1a5331c125ea222e14335d78a79792fcbc9",
    "root": "0x6972388f34d8c7576f936f103728f7d2820224ec29d136bd1ad881c950f8e72b",
    "arweave": "9rFJMb1JflwadEzOvC_GOWdVxL6A8A2nOnL01g3APVk",
    "cid": "QmbHnwBuM7Y41Q1DqnMDRx8yQ1aCMtqVka9biPY6cjWogq"
}

Query Parameters

Required

POST /link : link media to a SiLo device.

Post a recent signature along with an IPFS document (e.g. image) that you wish to associate with the device. A minter address can also be included or set to 0 as shown in the example here. NOTE: this process is currently centralized to this server.

Example

curl --location --request POST 'localhost:3000/link' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'x=a1441c4e7dabb340fff0b27d26f9c0c44687a84d02a8217d7594185ccddfb06b' \
--data-urlencode 'y=4f0d74de943e68de5ab6499e9d81058aa55c86fef20dde1ba32a073b5f805ebd' \
--data-urlencode 'r=58d0990422a4acd64eb5c9016561cf4e3ae01869f1582dd6b5aa46ae81222cdc' \
--data-urlencode 's=e4052861cb46683a4da0ac8211b2a778b38c9489d334979b9a80b720f2fca715' \
--data-urlencode 'blockNumber=12421117' \
--data-urlencode 'address=0000000000000000000000000000000000000000' \
--data-urlencode 'cid=QmbHnwBuM7Y41Q1DqnMDRx8yQ1aCMtqVka9biPY6cjWogq'
--data-urlencode 'name=NFT'
--data-urlencode 'description=Chipped'

Response

If the CID is successfully added, the server will indicate that in the result:

cid set to QmbHnwBuM7Y41Q1DqnMDRx8yQ1aCMtqVka9biPY6cjWogq

Body Parameters

Required

Optional

POST /mint : link media to a HaLo device.

Post a recent signature along with a media file and metadata that you wish to associate with the device. NOTE: once successful this request is binding and the document is created permanently on Arweave.

Example

curl --location --request POST 'http://localhost:3000/mint' \
--form 'media=@"hello.png"' \
--form 'device_id="caecb195dc849ccdb47a341c082410d55239ab3528510d4d67c016672bae2744"' \
--form 'device_sig="{ \"r\":\"ca7df33e0a3b691e0133f008a8bb77c347cb7aee3aa00fed85e96e78382c2b28\", \"s\":\"d0eec0950695d0ed94e175449b848fb72dbad1b0bb1153d96b53ffb6b8026d72\" }"' \
--form 'device_token_metadata="{ \"name\":\"HaLo NFT\" }"' \
--form 'minter_addr="0x77f0cc420dea0ae726db6bef1460a4b69176a8ea"' \
--form 'minter_sig="{ \"r\":\"61dba084cc5e7035fd5f1fb1ada4b6f9011459bea15f4d2f4eab957fc918fa5b\", \"s\":\"99ea02a0d02d5e6301b185aadd54cb56c6538518ce2096d4f49f34c9701e617d\" }"' \
--form 'blockNumber="14303538"'

Response

If the media is successfully added to Arweavce, the server will indicate the Arweave ID and IPFS CID.

Body Parameters

Required

EIP-712 Minter Schema

    const typedData = {
      types: {
        EIP712Domain: [
          { name: "name", type: "string" },
          { name: "version", type: "string" },
          { name: "chainId", type: "uint256" },
        ],
        Device: [
          { name: "id", type: "string" },
          { name: "signatureR", type: "string" },
          { name: "signatureS", type: "string" },           
          { name: "digest", type: "string" },  
        ],
        Media: [
          { name: "cid", type: "string" },
          { name: "name", type: "string" },
          { name: "description", type: "string" },
          { name: "minter", type: "address" },
          { name: "device", type: "Device" },
        ],
      },
      primaryType: "Media",
      domain: {
        name: "ERS",
        version: "0.1.0",
        chainId: chainId,
      },
      message: {
        cid: ipfsCid,
        name: device_token_metadata.name,
        description: device_token_metadata.description,
        minter: address,
        device: {
          id: device_id,
          signatureR: sigSplit.r,
          signatureS: sigSplit.s,
          digest: sigMsg,
        },
      },
    };

Tokens

GET /token/:address/:id : tokenUri for a SiLo-linked ERC721.

Retrieve the ERC721 tokenUri details for a SiLo-linked ERC721 if available.

Example

curl --location --request GET 'localhost:3000/token/0xd431b82796865F396e28d0f56b6a3d6626268A6e/3'

Response

{
    "name": null,
    "description": null,
    "image": "ipfs://QmagtqYd6D2cNHudEJQnNNNS9DTnACwjLSBJoHXea9QXaq",
    "nonce": "4a90150413774ede3e1f9ba517bb723a714baf1c0f3275e6fb36d624e49af712",
    "attributes": [
        {
            "trait_type": "statue",
            "value": "Apollo"
        },
        {
            "trait_type": "halo",
            "value": "GoldHalo"
        },
        {
            "trait_type": "material",
            "value": "Aquamarine"
        },
        {
            "trait_type": "lighting",
            "value": "Gold"
        },
        {
            "trait_type": "earrings",
            "value": "None"
        },
        {
            "trait_type": "tattoos",
            "value": "None"
        }
    ]
}

GET /token/:address : all token information for a SiLo-linked ERC721.

Retrieve all ERC721 tokenUri details for a SiLo-linked ERC721 if available.

Example

curl --location --request GET 'localhost:3000/token/0xd431b82796865F396e28d0f56b6a3d6626268A6e'

Response

[
    {
        "name": null,
        "description": null,
        "image": "ipfs://QmagtqYd6D2cNHudEJQnNNNS9DTnACwjLSBJoHXea9QXaq",
        "nonce": "4a90150413774ede3e1f9ba517bb723a714baf1c0f3275e6fb36d624e49af712",
        "attributes": [
            {
                "trait_type": "statue",
                "value": "Apollo"
            },
            {
                "trait_type": "halo",
                "value": "GoldHalo"
            },
            {
                "trait_type": "material",
                "value": "Aquamarine"
            },
            {
                "trait_type": "lighting",
                "value": "Gold"
            },
            {
                "trait_type": "earrings",
                "value": "None"
            },
            {
                "trait_type": "tattoos",
                "value": "None"
            }
        ]
    }
]

Reveal

GET /reveal : start a reveal for a KONG Land NFT using a Passport.

Using a recent signature from the device that you want to link along with the tokenId corresponding to the NFT, retrieve a signature from the oracle indicating that device signature verified. This oracle signature can be submitted to the RevealCitizen contract to associate the Kong Land NFT to the Passport.

Example

curl --location --request GET 'localhost:3000/reveal?x=a1441c4e7dabb340fff0b27d26f9c0c44687a84d02a8217d7594185ccddfb06b&y=4f0d74de943e68de5ab6499e9d81058aa55c86fef20dde1ba32a073b5f805ebd&r=95278b2495c7b1507eb41e1c97ee282e0a88ed516dc96da3f93bab150a232f2e&s=e4c4ece763e7d039a9df5a1e7ef0b56cebc47e3edaace36fce09783d04ba5163&blockNumber=11516941&addr=1dCD8763c01961C2BbB5ed58C6E51F55b1378589'

Response

If the server can successfully verify the signature against the signed blockhash, it will generate an oracleSignature in response that can be used in the RevealCitizen contract.

0xb154fae59e0295033f858e8a3b0789e81cea6465f5e3322ac653bc92d79fcb1b63d136fbb5b587d4fd641299f40dd97d4b21d4fbaa2521c71f8de883df5e57fe1b

Query Parameters

Required

POST /reveal : complete a reveal for a KONG Land NFT using a Passport.

Complete the reveal process by sending the transaction information from setting the Passport information in RevealCitizen. The server will review the transaction and link to the token URI if a corresponding device is found.

Example

curl --location --request POST 'localhost:3000/reveal' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'tx=0xfb2c7172ba64dd3547a11aa6db9eb85022fbbbea03303c3082da148100589d14'

Response

If the tx is matches a device, the server will indicate success.

TODO: redirect to the token URI.

success

Body Parameters

Required

Utilities

GET /defaults : a list of default nodes and contracts used in the KONG mobile app.

Example

curl --location --request GET 'localhost:3000/defaults'

Response

{
  "ethNode": "https://ropsten.infura.io/v3/xyz,
  "ipfsNode": "https://gateway.pinata.cloud/ipfs",
  "contracts": {
    "registerMerkleRoot": "0x2ca8a7ecc577b3abec55ac4e74a5d3135874a5f4",
    "oldRegistry": "0x41a81c92F019EbB05D3365A0E7b56D868eD2318e",
    "citizenERC20": "0x4e4C7051EcCe3985403BE5C551C55b716DdbF2aB",
    "citizenERC721": "0xc8b3EAD0d32E793D6549E6898b1F9e5078D9bAc2",
    "revealCitizen": "0x535250a854bc2999a2798709a8c3016e60fe0600"
  }
}

Running the App

Scripts

node device-sign.js --address=1dCD8763c01961C2BbB5ed58C6E51F55b1378589 --blockNumber=11345106   

Note: it requires a test device JSON file (signer/test-silo.json) with a primaryPrivateKey hex string, for instance:

{ "primaryPrivateKey": "0x12345..." }

Notes

const xBuffer = Buffer.from(pub.x, 'hex');
const yBuffer = Buffer.from(pub.y, 'hex');
const xyBuffer = Buffer.concat([xBuffer,yBuffer]);

const pubHashFromBuffer = '0x' + crypto.createHash('sha256').update(xyBuffer).digest('hex');

const pubHashFromHex = '0x' + crypto.createHash('sha256').update(pub.x + pub.y, 'hex').digest('hex');

const pubHashEthers = ethers.utils.sha256('0x' + pub.x + pub.y);

Reveal Smart Contract

See the RevealCitizen.sol contract in https://github.com/kong-org/citizen for an example of a reveal contract. This app expects that the contract has the following interfaces:

'function _revealCid() view returns (string)',
'function _revealERC721() view returns (address)'

See https://gateway.pinata.cloud/ipfs/QmNPY4aqViDHkMmmn8jVBWWq2e2CteVVUF43perEbYxGQA for an example of attributes.

Reval Attributes Schema

You can create attributes that are revealed on a successful device signature.

Required

Optional