|
1 | 1 | import type { HexString, Hash } from '@ckb-lumos/base' |
2 | | -import { BaseController, Controller, Body, Post } from '@ckb-js/kuai-io' |
3 | 2 | import { ActorReference } from '@ckb-js/kuai-models' |
4 | | -import { BadRequest } from 'http-errors' |
| 3 | +import { BadRequest, NotFound } from 'http-errors' |
5 | 4 | import { SudtModel, appRegistry } from '../actors' |
6 | 5 | import { Tx } from '../views/tx.view' |
7 | 6 | import { getLock } from '../utils' |
8 | | -import { SudtResponse } from '../response' |
| 7 | +import { BaseController, Body, Controller, Get, Param, Post, Put } from '@ckb-js/kuai-io' |
| 8 | +import { SudtResponse } from '../../response' |
| 9 | +import { CreateTokenRequest } from '../dto/create-token.dto' |
| 10 | +import { DataSource, QueryFailedError } from 'typeorm' |
| 11 | +import { Token } from '../entities/token.entity' |
| 12 | +import { Account } from '../entities/account.entity' |
| 13 | +import { tokenEntityToDto } from '../dto/token.dto' |
9 | 14 |
|
10 | 15 | @Controller('sudt') |
11 | 16 | export default class SudtController extends BaseController { |
| 17 | + #explorerHost = process.env.EXPLORER_HOST || 'https://explorer.nervos.org' |
| 18 | + constructor(private _dataSource: DataSource) { |
| 19 | + super() |
| 20 | + } |
| 21 | + |
12 | 22 | @Post('/send') |
13 | 23 | async send( |
14 | 24 | @Body() { from, to, amount, typeArgs }: { from: string[]; to: string; amount: HexString; typeArgs: Hash }, |
@@ -39,4 +49,58 @@ export default class SudtController extends BaseController { |
39 | 49 | ) |
40 | 50 | return SudtResponse.ok(await Tx.toJsonString(result)) |
41 | 51 | } |
| 52 | + |
| 53 | + @Post('/token') |
| 54 | + async createToken(@Body() req: CreateTokenRequest) { |
| 55 | + let owner = await this._dataSource.getRepository(Account).findOneBy({ address: req.account }) |
| 56 | + if (!owner) { |
| 57 | + owner = await this._dataSource |
| 58 | + .getRepository(Account) |
| 59 | + .save(this._dataSource.getRepository(Account).create({ address: req.account })) |
| 60 | + } |
| 61 | + |
| 62 | + try { |
| 63 | + const token = await this._dataSource |
| 64 | + .getRepository(Token) |
| 65 | + .save(this._dataSource.getRepository(Token).create({ ...req, ownerId: owner.id })) |
| 66 | + return new SudtResponse('201', { url: `${this.#explorerHost}/transaction/${token.typeId}` }) |
| 67 | + } catch (e) { |
| 68 | + if (e instanceof QueryFailedError) { |
| 69 | + switch (e.driverError.code) { |
| 70 | + case 'ER_DUP_ENTRY': |
| 71 | + return SudtResponse.err('409', { message: 'Token already exists' }) |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + console.error(e) |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + @Put('/token') |
| 80 | + async updateToken(@Body() req: CreateTokenRequest) { |
| 81 | + const token = await this._dataSource.getRepository(Token).findOneBy({ typeId: req.typeId }) |
| 82 | + if (token) { |
| 83 | + await this._dataSource.getRepository(Token).save({ ...token, ...req }) |
| 84 | + } |
| 85 | + |
| 86 | + return new SudtResponse('201', {}) |
| 87 | + } |
| 88 | + |
| 89 | + @Get('/token/:typeId') |
| 90 | + async getToken(@Param('typeId') typeId: string) { |
| 91 | + const token = await this._dataSource.getRepository(Token).findOneBy({ typeId }) |
| 92 | + |
| 93 | + if (token) { |
| 94 | + return SudtResponse.ok(tokenEntityToDto(token, '0', this.#explorerHost)) |
| 95 | + } else { |
| 96 | + throw new NotFound() |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + @Get('/tokens') |
| 101 | + async listTokens() { |
| 102 | + const tokens = await this._dataSource.getRepository(Token).find() |
| 103 | + |
| 104 | + return SudtResponse.ok(tokens.map((token) => tokenEntityToDto(token, '0', this.#explorerHost))) |
| 105 | + } |
42 | 106 | } |
0 commit comments