Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Technical breakdown of sudt demo backend design #446

Open
2 of 4 tasks
yanguoyu opened this issue Aug 24, 2023 · 15 comments
Open
2 of 4 tasks

Technical breakdown of sudt demo backend design #446

yanguoyu opened this issue Aug 24, 2023 · 15 comments
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@yanguoyu
Copy link
Contributor

yanguoyu commented Aug 24, 2023

After these designs are finished, we will create a server from the template and start coding. Here is the server's APIs.
We can append comments to talk about the designs.

@yanguoyu
Copy link
Contributor Author

  1. OmnilockModel
    • meta get the meta of omnilock address(capacity)
    • mint use ckb to mint sudt
  2. SudtModel
    • meta get the meta data(capacity)
    • send collect cell to send sudt
    • destory destory all sudt cell
  3. View
    • generateTx generate a tx from inputs and outputs

@Daryl-L
Copy link
Contributor

Daryl-L commented Aug 30, 2023

Database

CREATE `token` (
  `id` int not null primary key auto_increment,
  `name` varchar(255) not null default '',
  `decimal` int not null default 18,
  `description` text not null default '',
  `website` varchar(255) not null default '',
  `icon` varchar(255) not null default '',
  `create_tx_hash` varchar(255) not null default '',
  `owner_id` int not null,
  `args` varchar(255) not null default '',
  `created_at` timestamp not null default current_timestamp(),
  `updated_at` timestamp not null default current_timestamp() on update current_timestamp(),
  unique key `uniq_args` (`args`),
);
CREATE `account` (
  `id` int not null primary key auto_increment(),
  `address` text not null,
  `eth_address` varchar(255) not null,
  `created_at` timestamp not null default current_timestamp(),
  `updated_at` timestamp not null default current_timestamp() on update current_timestamp()
)
CREATE `holder` (
  `id` int not null primary key auto_increment,
  `holder_id` int not null,
  `token_id` int not null,
  `amount` varchar(255) not null default '0',
  `created_at` timestamp not null default current_timestamp(),
  `updated_at` timestamp not null default current_timestamp() on update current_timestamp(),
  key `idx_token_id` (`token_id`),
  unique key `uniq_holder_id_token_id` (`holder_id`,`token_id`),
)
CREATE `token_history` (
  `id` int not null primary key auto_increment,
  `token_id` int not null,
  `tx_hash` varchar(255) not null,
  `status` int not null default 1 comment '1 - new, 2 - pending, 3 - success',
  `from` text not null,
  `to` text not null,
  `created_at` timestamp not null default current_timestamp(),
  `updated_at` timestamp not null default current_timestamp() on update current_timestamp(),
  unique key `uniq_token_id_tx_hash` (`token_id`, `tx_hash`)
)

@yanguoyu
Copy link
Contributor Author

Init backend by kuai init #457

@Daryl-L
Copy link
Contributor

Daryl-L commented Sep 14, 2023

Sample Kuai Project

This project demonstrates a basic kuai use case.

Run server

npm run build

node ./dist/src/main.js

API Doc

Mint Token

path: /sudt/mint/:typeId

method: POST

Request

{
  "from": [""],
  "to": "",
  "amount": "1000",
}

Response

{
  "code": 200,
  "data": {
    "txSkeleton": "txSkeleton": {
        "cellProvider": null,
        "cellDeps": [
            {
                "outPoint": {
                    "txHash": "0x27b62d8be8ed80b9f56ee0fe41355becdb6f6a40aeba82d3900434f43b1c8b60",
                    "index": "0x0"
                },
                "depType": "code"
            },
            {
                "outPoint": {
                    "txHash": "0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37",
                    "index": "0x0"
                },
                "depType": "depGroup"
            },
            {
                "outPoint": {
                    "txHash": "0xe12877ebd2c3c364dc46c5c992bcfaf4fee33fa13eebdf82c591fc9825aab769",
                    "index": "0x0"
                },
                "depType": "code"
            }
        ],
        "headerDeps": [],
        "inputs": [
            {
                "cellOutput": {
                    "capacity": "0x1b41bf852c00",
                    "lock": {
                        "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                        "hashType": "type",
                        "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                    },
                    "type": null
                },
                "data": "0x",
                "outPoint": {
                    "txHash": "0x5f2d84f67f378972ba7ee285e4d013450862d31defc121769fbf61fd5810627d",
                    "index": "0x1"
                },
                "blockNumber": "0xa66258"
            }
        ],
        "outputs": [
            {
                "cellOutput": {
                    "capacity": "0x35a4e9000",
                    "lock": {
                        "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                        "hashType": "type",
                        "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                    },
                    "type": {
                        "codeHash": "0xc5e5dcf215925f7ef4dfaf5f4b4f105bc321c02776d6e7d52a1db3fcd9d011a4",
                        "hashType": "type",
                        "args": "0xfb7b6c4a2baf39ebfdd634e76737725362cf18042a31256488382137ae830784"
                    }
                },
                "data": "0xa0860100000000000000000000000000"
            },
            {
                "cellOutput": {
                    "lock": {
                        "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                        "hashType": "type",
                        "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                    },
                    "capacity": "0x1b3e65351560"
                },
                "data": "0x"
            }
        ],
        "witnesses": [
            "0x690000001000000069000000690000005500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        ],
        "fixedEntries": [],
        "signingEntries": [],
        "inputSinces": {}
    }
  }
}

Create Token

path: /token

method: POST

Request

{
  "code": 200,
  "data": {
    "name": "USDT",
    "account": "", // the address of owner
    "decimal": 18,
    "description": "",
    "website": "",
    "icon": "",
    "email": ""
  }
}

Reponse

{
    "code": "201",
    "data": {
      "txSkeleton": {
        "cellProvider": null,
        "cellDeps": [
            {
                "outPoint": {
                    "txHash": "0x27b62d8be8ed80b9f56ee0fe41355becdb6f6a40aeba82d3900434f43b1c8b60",
                    "index": "0x0"
                },
                "depType": "code"
            },
            {
                "outPoint": {
                    "txHash": "0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37",
                    "index": "0x0"
                },
                "depType": "depGroup"
            },
            {
                "outPoint": {
                    "txHash": "0xe12877ebd2c3c364dc46c5c992bcfaf4fee33fa13eebdf82c591fc9825aab769",
                    "index": "0x0"
                },
                "depType": "code"
            }
        ],
        "headerDeps": [],
        "inputs": [
            {
                "cellOutput": {
                    "capacity": "0x1b41bf852c00",
                    "lock": {
                        "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                        "hashType": "type",
                        "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                    },
                    "type": null
                },
                "data": "0x",
                "outPoint": {
                    "txHash": "0x5f2d84f67f378972ba7ee285e4d013450862d31defc121769fbf61fd5810627d",
                    "index": "0x1"
                },
                "blockNumber": "0xa66258"
            }
        ],
        "outputs": [
            {
                "cellOutput": {
                    "capacity": "0x35a4e9000",
                    "lock": {
                        "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                        "hashType": "type",
                        "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                    },
                    "type": {
                        "codeHash": "0xc5e5dcf215925f7ef4dfaf5f4b4f105bc321c02776d6e7d52a1db3fcd9d011a4",
                        "hashType": "type",
                        "args": "0xfb7b6c4a2baf39ebfdd634e76737725362cf18042a31256488382137ae830784"
                    }
                },
                "data": "0xa0860100000000000000000000000000"
            },
            {
                "cellOutput": {
                    "lock": {
                        "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                        "hashType": "type",
                        "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                    },
                    "capacity": "0x1b3e65351560"
                },
                "data": "0x"
            }
        ],
        "witnesses": [
            "0x690000001000000069000000690000005500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        ],
        "fixedEntries": [],
        "signingEntries": [],
        "inputSinces": {}
    }
  }
}

Update Token

path: /token/:typeId

method: PUT

Request

{
  "code": 200,
  "data": {
    "name": "USDT",
    "decimal": 18,
    "description": "",
    "website": "",
    "icon": "",
    "explorerCode": "" // the verify code from explorer
  }
}

Response

{
  "code": 201,
  "data": {}
}

Transfer Token

path: /token/transfer

method: POST

Request

{
  "typeId": "", // token args
  "amount": "",
  "to": ""
}

Response

{
  "code": 200,
  "data": {
    "txSkeleton": {
      "cellProvider": null,
      "cellDeps": [
          {
              "outPoint": {
                  "txHash": "0x27b62d8be8ed80b9f56ee0fe41355becdb6f6a40aeba82d3900434f43b1c8b60",
                  "index": "0x0"
              },
              "depType": "code"
          },
          {
              "outPoint": {
                  "txHash": "0xf8de3bb47d055cdf460d93a2a6e1b05f7432f9777c8c474abf4eec1d4aee5d37",
                  "index": "0x0"
              },
              "depType": "depGroup"
          },
          {
              "outPoint": {
                  "txHash": "0xe12877ebd2c3c364dc46c5c992bcfaf4fee33fa13eebdf82c591fc9825aab769",
                  "index": "0x0"
              },
              "depType": "code"
          }
      ],
      "headerDeps": [],
      "inputs": [
          {
              "cellOutput": {
                  "capacity": "0x1b41bf852c00",
                  "lock": {
                      "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                      "hashType": "type",
                      "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                  },
                  "type": null
              },
              "data": "0x",
              "outPoint": {
                  "txHash": "0x5f2d84f67f378972ba7ee285e4d013450862d31defc121769fbf61fd5810627d",
                  "index": "0x1"
              },
              "blockNumber": "0xa66258"
          }
      ],
      "outputs": [
          {
              "cellOutput": {
                  "capacity": "0x35a4e9000",
                  "lock": {
                      "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                      "hashType": "type",
                      "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                  },
                  "type": {
                      "codeHash": "0xc5e5dcf215925f7ef4dfaf5f4b4f105bc321c02776d6e7d52a1db3fcd9d011a4",
                      "hashType": "type",
                      "args": "0xfb7b6c4a2baf39ebfdd634e76737725362cf18042a31256488382137ae830784"
                  }
              },
              "data": "0xa0860100000000000000000000000000"
          },
          {
              "cellOutput": {
                  "lock": {
                      "codeHash": "0xf329effd1c475a2978453c8600e1eaf0bc2087ee093c3ee64cc96ec6847752cb",
                      "hashType": "type",
                      "args": "0x00afbf535944be46a2f5879a3a349bc4fd5784a0e900"
                  },
                  "capacity": "0x1b3e65351560"
              },
              "data": "0x"
          }
      ],
      "witnesses": [
          "0x690000001000000069000000690000005500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
      ],
      "fixedEntries": [],
      "signingEntries": [],
      "inputSinces": {}
    }
  }
}

Token List

path: /token

Request

param type position description
address string query user address

method: GET

Response

{
  "code": 200,
  "data": [
    {
      "uan": "USDT",
      "displayName": "USDT",
      "name": "USDT",
      "decimal": 18,
      "description": "",
      "website": "",
      "icon": "",
      "url": "",
      "issuser": "",
      "args": "",
      "typeId": "",
    },
  ]
}

Token Detail

path: /token/:args

method: GET

Response

{
  "code": 200,
  "data": {
    "uan": "USDT",
    "displayName": "USDT",
    "name": "USDT",
    "decimal": 18,
    "description": "",
    "website": "",
    "icon": "",
    "url": "",
    "issuser": ""
  }
}

Asset List

path: /account/:address/assets

method: GET

Request

param type position description
address string query user address

Response

{
  "code": 200,
  "data": [
      {
        "uan": "USDT",
        "displayName": "USDT",
        "decimal": 18,
        "amount": ""
      }
    ]
}

Token Transfer History

path: /account/:address/assets/transfer/history

method: GET

Response

{
  "code": 200,
  "data": [
    {
      "txHash": "",
      "from": "",
      "to": "",
      "time": "",
      "status": "",
      "sudtAmount": "",
      "CKBAmount": "",
      "url": "",
    }
  ]
}

@Keith-CY
Copy link
Member

Keith-CY commented Sep 14, 2023

Create Token

path: /token

method: POST

Request

{
  "symbol": "USDT",
  "name": "USDT",
  "amount": "100000",
  "decimal": "18",
  "description": "",
  "website": "",
  "icon": ""
}

Reponse

{
  "code": 201,
  "data": {
    "url": "" // direct to explorer to the transaction to issue the token
  }
}

Response

Update Token

path: /token

method: PUT

Request

{
  "symbol": "USDT",
  "name": "USDT",
  "amount": "100000",
  "decimal": "18",
  "description": "",
  "website": "",
  "icon": "",
  "args": "", // sudt args
  "signature": ""
}

Response

{
  "code": 201,
  "data": {}
}

Transfer Token

path: /token/transfer

method: POST

Request

{
  "token": "", // token args
  "amount": "",
  "to": ""
}

Token List

path: /token

Request

param type position description
address string query user address
method: GET

Response

[
  {
    "symbol": "USDT",
    "name": "USDT",
    "amount": "100000",
    "decimal": "18",
    "description": "",
    "website": "",
    "icon": ""
  }
]

Token Detail

path: /token/:args

method: GET

Response

 {
    "symbol": "USDT",
    "name": "USDT",
    "amount": "100000",
    "decimal": "18",
    "description": "",
    "website": "",
    "icon": "",
    "url": "",
    "issuser": ""
}

Asset List

path: /assets

method: GET

Request

param type position description
address string query user address

Response

{
  "code": 200,
  "data": [
      {
        "symbol": "USDT",
        "name": "USDT",
        "amount": ""
      }
    ]
}

Token Transfer History

path: /token/transfer/history

method: GET

Request

param type position description
address string query user address

Response

[
  {
    "txHash": "",
    "from": "",
    "to": "",
    "time": "",
    "status": "",
    "sudtAmount": "",
    "CKBAmount": "",
    "url": "",
  }
]

The response should be canonical, some of them are wrapped with data that next to code, some are not.

@yanguoyu yanguoyu added the documentation Improvements or additions to documentation label Sep 15, 2023
@PainterPuppets
Copy link
Contributor

Update Token

path: /token

method: PUT

Request

{
  "code": 200,
  "data": {
    "symbol": "USDT",
    "name": "USDT",
    "amount": "100000",
    "decimal": "18",
    "description": "",
    "website": "",
    "icon": "",
    "args": "", // sudt args
    "signature": ""
  }
}

What is signature used for?

@Daryl-L
Copy link
Contributor

Daryl-L commented Oct 17, 2023

Update Token

path: /token
method: PUT

Request

{
  "code": 200,
  "data": {
    "symbol": "USDT",
    "name": "USDT",
    "amount": "100000",
    "decimal": "18",
    "description": "",
    "website": "",
    "icon": "",
    "args": "", // sudt args
    "signature": ""
  }
}

What is signature used for?

My mistake, the request should be the same as token update request, I have changed it just now.

{
  "code": 200,
  "data": {
    "symbol": "USDT",
    "name": "USDT",
    "account": "", // the args of account in omnilock
    "supply": "100000",
    "decimal": 18,
    "description": "",
    "website": "",
    "icon": "",
    "typeId": "",
    "args": "", // the args of sudt type script
    "explorerCode": "" // the verify code from explorer
  }
}

@Daryl-L
Copy link
Contributor

Daryl-L commented Oct 18, 2023

I have changed the API of create token based on the conclusion from last night. Some properties are added and the transaction skeleton will be responded.

@PainterPuppets
Copy link
Contributor

There are a few questions I want to confirm

  • Updating tokens:
    This api seems to be missing the token identifier, for example, if a user manages multiple tokens, which token is updated when he calls update, I guess the url should be PUT /token/:args

  • Transfer token
    Should this api perhaps return a Transaction?

  • Token list & detail
    The response type of these two api's seem to be different, but there is only a difference between the issuer and url fields, is it possible to unify them?

  • Asset list
    Maybe need the decimal field

  • History:
    The front-end page displays the specific tx information and perhaps needs to return the entire tx

image image

And I feel like maybe the mint api is missing?

Another question, if the frontend has signed the tx through the wallet, how should it be sent to the chain, is it a direct post to the rpc or through the backend?

@Daryl-L
Copy link
Contributor

Daryl-L commented Oct 18, 2023

I think the transaction should send in the front end directly

@Daryl-L
Copy link
Contributor

Daryl-L commented Oct 18, 2023

There are a few questions I want to confirm

  • Updating tokens:
    This api seems to be missing the token identifier, for example, if a user manages multiple tokens, which token is updated when he calls update, I guess the url should be PUT /token/:args
  • Transfer token
    Should this api perhaps return a Transaction?
  • Token list & detail
    The response type of these two api's seem to be different, but there is only a difference between the issuer and url fields, is it possible to unify them?
  • Asset list
    Maybe need the decimal field
  • History:
    The front-end page displays the specific tx information and perhaps needs to return the entire tx

image image
And I feel like maybe the mint api is missing?

Another question, if the frontend has signed the tx through the wallet, how should it be sent to the chain, is it a direct post to the rpc or through the backend?

update token, transfer token, token list, token detail, asset list has been changed, you can check it.

@Daryl-L
Copy link
Contributor

Daryl-L commented Oct 19, 2023

There are a few questions I want to confirm

  • Updating tokens:
    This api seems to be missing the token identifier, for example, if a user manages multiple tokens, which token is updated when he calls update, I guess the url should be PUT /token/:args
  • Transfer token
    Should this api perhaps return a Transaction?
  • Token list & detail
    The response type of these two api's seem to be different, but there is only a difference between the issuer and url fields, is it possible to unify them?
  • Asset list
    Maybe need the decimal field
  • History:
    The front-end page displays the specific tx information and perhaps needs to return the entire tx

image image
And I feel like maybe the mint api is missing?

Another question, if the frontend has signed the tx through the wallet, how should it be sent to the chain, is it a direct post to the rpc or through the backend?

mint provided

@PainterPuppets
Copy link
Contributor

PainterPuppets commented Oct 19, 2023

Mint Token

path: /sudt/mint/:typeId

method: POST

Request

{
  "from": [""],
  "to": "",
  "amount": "1000",
}

I'm not sure if only the issuer can mint.
Will there be another address in the from field?

@PainterPuppets
Copy link
Contributor

Token List

path: /token

Request

param type position description
address string query user address
method: GET

Response

{
  "code": 200,
  "data": [
    {
      "uan": "USDT",
      "displayName": "USDT",
      "name": "USDT",
      "decimal": 18,
      "description": "",
      "website": "",
      "icon": "",
      "url": "",
      "issuser": ""
    },
  ]
}

If mint and transfer apis need to use the typeid and args fields, perhaps token list and token detail need to return the typeid and args.

@Daryl-L
Copy link
Contributor

Daryl-L commented Oct 20, 2023

Mint Token

path: /sudt/mint/:typeId
method: POST

Request

{
  "from": [""],
  "to": "",
  "amount": "1000",
}

I'm not sure if only the issuer can mint. Will there be another address in the from field?

As I learnt from the RFC of sUDT, only issuer could mint more sUDT to others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
Status: 🏗 In progress
Development

No branches or pull requests

4 participants