Open yanguoyu opened 1 year ago
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`)
)
Init backend by kuai init
https://github.com/ckb-js/kuai/pull/457
This project demonstrates a basic kuai use case.
npm run build
node ./dist/src/main.js
path: /sudt/mint/:typeId
method: POST
{
"from": [""],
"to": "",
"amount": "1000",
}
{
"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": {}
}
}
}
path: /token
method: POST
{
"code": 200,
"data": {
"name": "USDT",
"account": "", // the address of owner
"decimal": 18,
"description": "",
"website": "",
"icon": "",
"email": ""
}
}
{
"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": {}
}
}
}
path: /token/:typeId
method: PUT
{
"code": 200,
"data": {
"name": "USDT",
"decimal": 18,
"description": "",
"website": "",
"icon": "",
"explorerCode": "" // the verify code from explorer
}
}
{
"code": 201,
"data": {}
}
path: /token/transfer
method: POST
{
"typeId": "", // token args
"amount": "",
"to": ""
}
{
"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": {}
}
}
}
path: /token
param | type | position | description |
---|---|---|---|
address | string | query | user address |
method: GET
{
"code": 200,
"data": [
{
"uan": "USDT",
"displayName": "USDT",
"name": "USDT",
"decimal": 18,
"description": "",
"website": "",
"icon": "",
"url": "",
"issuser": "",
"args": "",
"typeId": "",
},
]
}
path: /token/:args
method: GET
{
"code": 200,
"data": {
"uan": "USDT",
"displayName": "USDT",
"name": "USDT",
"decimal": 18,
"description": "",
"website": "",
"icon": "",
"url": "",
"issuser": ""
}
}
path: /account/:address/assets
method: GET
param | type | position | description |
---|---|---|---|
address | string | query | user address |
{
"code": 200,
"data": [
{
"uan": "USDT",
"displayName": "USDT",
"decimal": 18,
"amount": ""
}
]
}
path: /account/:address/assets/transfer/history
method: GET
{
"code": 200,
"data": [
{
"txHash": "",
"from": "",
"to": "",
"time": "",
"status": "",
"sudtAmount": "",
"CKBAmount": "",
"url": "",
}
]
}
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.
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?
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
}
}
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.
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
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?
I think the transaction should send in the front end directly
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
andurl
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
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.
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
andurl
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
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
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?
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
.
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.
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.