Skip to content

Commit

Permalink
Merge pull request #18 from ckb-cell/refactor/update-graphql-model
Browse files Browse the repository at this point in the history
refactor: update graphql model
  • Loading branch information
ahonn authored Jul 29, 2024
2 parents 4741dc3 + 98d9f08 commit a2f8d78
Show file tree
Hide file tree
Showing 21 changed files with 9,365 additions and 6,986 deletions.
3 changes: 3 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@cell-studio/mempool.js": "^2.4.0",
"@ckb-lumos/bi": "^0.23.0",
"@ckb-lumos/lumos": "^0.23.0",
"@ckb-lumos/rpc": "^0.23.0",
"@nestjs/apollo": "^12.2.0",
"@nestjs/cache-manager": "^2.2.2",
"@nestjs/common": "^10.0.0",
Expand All @@ -35,6 +36,8 @@
"@nestjs/platform-express": "^10.0.0",
"@ntegral/nestjs-sentry": "^4.0.1",
"@prisma/client": "^5.16.2",
"@rgbpp-sdk/btc": "^0.0.0-snap-20240727021715",
"@rgbpp-sdk/ckb": "^0.0.0-snap-20240727021715",
"@sentry/node": "^8.17.0",
"@sentry/profiling-node": "^8.17.0",
"@types/ws": "^8.5.11",
Expand Down
20 changes: 19 additions & 1 deletion backend/src/core/ckb-rpc/ckb-rpc-websocket.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { Injectable, Logger } from '@nestjs/common';
import { Client as RpcWebsocketsClient } from 'rpc-websockets';
import { BI } from '@ckb-lumos/bi';
import { Env } from 'src/env';
import { Block, BlockEconomicState, TransactionWithStatusResponse } from './ckb-rpc.interface';
import {
Block,
BlockEconomicState,
GetTransactionsResult,
SearchKey,
TransactionWithStatusResponse,
} from './ckb-rpc.interface';

@Injectable()
export class CkbRpcWebsocketService {
Expand Down Expand Up @@ -48,4 +54,16 @@ export class CkbRpcWebsocketService {
const tipBlockNumber = await this.websocket.call('get_tip_block_number', []);
return BI.from(tipBlockNumber).toNumber();
}

public async getTransactions(
searchKey: SearchKey,
order: 'asc' | 'desc',
limit: string,
): Promise<GetTransactionsResult> {
this.logger.debug(
`get_transactions - searchKey: ${JSON.stringify(searchKey)}, order: ${order}, limit: ${limit}`,
);
const transactions = await this.websocket.call('get_transactions', [searchKey, order, limit]);
return transactions as GetTransactionsResult;
}
}
22 changes: 22 additions & 0 deletions backend/src/core/ckb-rpc/ckb-rpc.interface.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { RPC } from '@ckb-lumos/rpc';

export interface CellDep {
dep_type: string;
out_point: {
Expand Down Expand Up @@ -85,3 +87,23 @@ export interface BlockEconomicState {
};
txs_fee: string;
}

export interface SearchKey {
script: {
code_hash: string;
hash_type: 'data' | 'type' | 'data1' | 'data2';
args: string;
};
script_type: 'lock' | 'type';
}

export interface GetTransactionsResult {
last_cursor: string;
objects: {
block_number: string;
io_index: string;
io_type: string;
tx_hash: string;
tx_index: string;
}[];
}
7 changes: 4 additions & 3 deletions backend/src/modules/bitcoin/address/address.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Field, Float, ObjectType } from '@nestjs/graphql';
import { BitcoinTransaction } from '../transaction/transaction.model';
import { RgbppAddress } from 'src/modules/rgbpp/address/address.model';

export type BitcoinBaseAddress = Pick<BitcoinAddress, 'address'>;

Expand All @@ -14,15 +15,15 @@ export class BitcoinAddress {
@Field(() => Float)
pendingSatoshi: number;

@Field(() => Float)
rgbppUtxosCount: number;

@Field(() => Float)
transactionsCount: number;

@Field(() => [BitcoinTransaction])
transactions: BitcoinTransaction[];

@Field(() => RgbppAddress)
rgbppAddress: RgbppAddress;

public static from(address: string): BitcoinBaseAddress {
return {
address,
Expand Down
3 changes: 1 addition & 2 deletions backend/src/modules/bitcoin/address/address.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Module } from '@nestjs/common';
import { BitcoinApiModule } from 'src/core/bitcoin-api/bitcoin-api.module';
import { CkbExplorerModule } from 'src/core/ckb-explorer/ckb-explorer.module';
import { BitcoinAddressResolver } from './address.resolver';
import { BitcoinAddressLoader, BitcoinAddressTransactionsLoader } from './address.dataloader';

@Module({
imports: [BitcoinApiModule, CkbExplorerModule],
imports: [BitcoinApiModule],
providers: [BitcoinAddressResolver, BitcoinAddressLoader, BitcoinAddressTransactionsLoader],
exports: [BitcoinAddressLoader, BitcoinAddressTransactionsLoader],
})
Expand Down
17 changes: 6 additions & 11 deletions backend/src/modules/bitcoin/address/address.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Loader } from '@applifting-io/nestjs-dataloader';
import { Args, Float, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { CkbExplorerService } from 'src/core/ckb-explorer/ckb-explorer.service';
import { BitcoinBaseTransaction, BitcoinTransaction } from '../transaction/transaction.model';
import { BitcoinAddress, BitcoinBaseAddress } from './address.model';
import {
Expand All @@ -9,11 +8,10 @@ import {
BitcoinAddressTransactionsLoader,
BitcoinAddressTransactionsLoaderType,
} from './address.dataloader';
import { RgbppAddress, RgbppBaseAddress } from 'src/modules/rgbpp/address/address.model';

@Resolver(() => BitcoinAddress)
export class BitcoinAddressResolver {
constructor(private ckbExplorerService: CkbExplorerService) {}

@Query(() => BitcoinAddress, { name: 'btcAddress', nullable: true })
public async getBtcAddress(@Args('address') address: string): Promise<BitcoinBaseAddress> {
return BitcoinAddress.from(address);
Expand All @@ -37,14 +35,6 @@ export class BitcoinAddressResolver {
return addressStats.mempool_stats.funded_txo_sum - addressStats.mempool_stats.spent_txo_sum;
}

@ResolveField(() => Float)
public async rgbppUtxosCount(@Parent() address: BitcoinBaseAddress): Promise<number> {
const cells = await this.ckbExplorerService.getAddressRgbppCells({
address: address.address,
});
return cells.meta.total;
}

@ResolveField(() => Float)
public async transactionsCount(
@Parent() address: BitcoinBaseAddress,
Expand All @@ -67,4 +57,9 @@ export class BitcoinAddressResolver {
afterTxid: afterTxid,
});
}

@ResolveField(() => RgbppAddress)
public async rgbppAddress(@Parent() address: BitcoinBaseAddress): Promise<RgbppBaseAddress> {
return RgbppAddress.from(address.address);
}
}
6 changes: 5 additions & 1 deletion backend/src/modules/bitcoin/transaction/transaction.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Field, Float, Int, ObjectType } from '@nestjs/graphql';
import * as BitcoinApi from 'src/core/bitcoin-api/bitcoin-api.schema';
import { BitcoinBaseOutput, BitcoinOutput } from '../output/output.model';
import { BitcoinInput } from '../input/input.model';
import { RgbppTransaction } from 'src/modules/rgbpp/transaction/transaction.model';

export type BitcoinBaseTransaction = Omit<BitcoinTransaction, 'confirmations'>;
export type BitcoinBaseTransaction = Omit<BitcoinTransaction, 'confirmations' | 'rgbppTransaction'>;

@ObjectType({ description: 'Bitcoin Transaction' })
export class BitcoinTransaction {
Expand Down Expand Up @@ -46,6 +47,9 @@ export class BitcoinTransaction {
@Field(() => Float)
confirmations: number;

@Field(() => RgbppTransaction, { nullable: true })
rgbppTransaction?: RgbppTransaction;

public static from(tx: BitcoinApi.Transaction): BitcoinBaseTransaction {
const vSize = Math.ceil(tx.weight / 4);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {
BitcoinTransactionLoader,
BitcoinTransactionOutSpendsLoader,
} from './transaction.dataloader';
import { RgbppTransactionModule } from 'src/modules/rgbpp/transaction/transaction.module';

@Module({
imports: [BitcoinApiModule],
imports: [BitcoinApiModule, RgbppTransactionModule],
providers: [
BitcoinTransactionResolver,
BitcoinTransactionLoader,
Expand Down
18 changes: 17 additions & 1 deletion backend/src/modules/bitcoin/transaction/transaction.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ import { Args, Float, Parent, Query, ResolveField, Resolver } from '@nestjs/grap
import { BitcoinApiService } from 'src/core/bitcoin-api/bitcoin-api.service';
import { BitcoinBaseTransaction, BitcoinTransaction } from './transaction.model';
import { BitcoinTransactionLoader, BitcoinTransactionLoaderType } from './transaction.dataloader';
import {
RgbppBaseTransaction,
RgbppTransaction,
} from 'src/modules/rgbpp/transaction/transaction.model';
import {
RgbppTransactionLoader,
RgbppTransactionLoaderType,
} from 'src/modules/rgbpp/transaction/transaction.dataloader';

@Resolver(() => BitcoinTransaction)
export class BitcoinTransactionResolver {
constructor(private bitcoinApiService: BitcoinApiService) {}
constructor(private bitcoinApiService: BitcoinApiService) { }

@Query(() => BitcoinTransaction, { name: 'btcTransaction', nullable: true })
public async getTransaction(
Expand All @@ -27,4 +35,12 @@ export class BitcoinTransactionResolver {
const info = await this.bitcoinApiService.getBlockchainInfo();
return info.blocks - tx.blockHeight + 1;
}

@ResolveField(() => RgbppTransaction)
public async rgbppTransaction(
@Parent() tx: BitcoinBaseTransaction,
@Loader(RgbppTransactionLoader) txLoader: RgbppTransactionLoaderType,
): Promise<RgbppBaseTransaction | null> {
return txLoader.load(tx.txid);
}
}
3 changes: 0 additions & 3 deletions backend/src/modules/ckb/address/address.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ export class CkbAddress {
@Field(() => Float)
shannon: number;

@Field(() => Float)
rgbppCellsCount: number;

@Field(() => Float)
transactionsCount: number;

Expand Down
7 changes: 0 additions & 7 deletions backend/src/modules/ckb/address/address.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ export class CkbAddressResolver {
return Number(info.balance);
}

@ResolveField(() => Float)
public async rgbppCellsCount(@Parent() address: CkbBaseAddress): Promise<number> {
// TODO: implement this resolver
// XXX: how to relate ckb address with rgbpp cells? (except the address is rgbpp-lock/btc-time-lock)
return 0;
}

@ResolveField(() => Float)
public async transactionsCount(
@Parent() address: CkbBaseAddress,
Expand Down
21 changes: 21 additions & 0 deletions backend/src/modules/rgbpp/address/address.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Field, Float, ObjectType } from '@nestjs/graphql';

export type RgbppBaseAddress = Pick<RgbppAddress, 'address'>;

@ObjectType({ description: 'Rgbpp Address' })
export class RgbppAddress {
@Field(() => String)
address: string;

@Field(() => Float)
utxosCount: number;

@Field(() => Float)
cellsCount: number;

public static from(address: string): RgbppBaseAddress {
return {
address,
};
}
}
9 changes: 9 additions & 0 deletions backend/src/modules/rgbpp/address/address.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { RgbppAddressResolver } from './address.resolver';
import { CkbExplorerModule } from 'src/core/ckb-explorer/ckb-explorer.module';

@Module({
imports: [CkbExplorerModule],
providers: [RgbppAddressResolver],
})
export class RgbppAddressModule {}
28 changes: 28 additions & 0 deletions backend/src/modules/rgbpp/address/address.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Args, Float, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { CkbExplorerService } from 'src/core/ckb-explorer/ckb-explorer.service';
import { RgbppAddress, RgbppBaseAddress } from './address.model';

@Resolver(() => RgbppAddress)
export class RgbppAddressResolver {
constructor(private ckbExplorerService: CkbExplorerService) {}

@Query(() => RgbppAddress, { name: 'rgbppAddress', nullable: true })
public async getBtcAddress(@Args('address') address: string): Promise<RgbppBaseAddress> {
return RgbppAddress.from(address);
}

@ResolveField(() => Float)
public async utxosCount(@Parent() address: RgbppBaseAddress): Promise<number> {
const cells = await this.ckbExplorerService.getAddressRgbppCells({
address: address.address,
});
return cells.meta.total;
}

@ResolveField(() => Float)
public async cellsCount(@Parent() address: RgbppBaseAddress): Promise<number> {
// TODO: implement this resolver
// XXX: how to relate ckb address with rgbpp cells? (except the address is rgbpp-lock/btc-time-lock)
return 0;
}
}
5 changes: 3 additions & 2 deletions backend/src/modules/rgbpp/rgbpp.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Module } from '@nestjs/common';
import { RgbppCoinModule } from './coin/coin.module';
import { RgbppStatisticModule } from './statistic/statistic.module';
import { RgbppTransactionModule } from './transaction/transaction.module';
import { RgbppAddressModule } from './address/address.module';

@Module({
imports: [RgbppTransactionModule, RgbppCoinModule, RgbppStatisticModule],
imports: [RgbppAddressModule, RgbppTransactionModule, RgbppCoinModule, RgbppStatisticModule],
})
export class RgbppModule {}
export class RgbppModule { }
31 changes: 31 additions & 0 deletions backend/src/modules/rgbpp/transaction/transaction.dataloader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import DataLoader from 'dataloader';
import { Injectable, Logger } from '@nestjs/common';
import { NestDataLoader } from '@applifting-io/nestjs-dataloader';
import { DataLoaderResponse } from 'src/common/type/dataloader';
import { RgbppTransactionService } from './transaction.service';
import { RgbppBaseTransaction } from './transaction.model';

@Injectable()
export class RgbppTransactionLoader
implements NestDataLoader<string, RgbppBaseTransaction | null> {
private logger = new Logger(RgbppTransactionLoader.name);

constructor(private transactionService: RgbppTransactionService) { }

public getBatchFunction() {
return async (ids: string[]) => {
this.logger.debug(`Loading rgbpp transactions: ${ids.join(', ')}`);
const results = await Promise.allSettled(
ids.map((txidOrTxHash) => this.transactionService.getTransaction(txidOrTxHash)),
);
return results.map((result) => {
if (result.status === 'fulfilled') {
return result.value;
}
return null;
});
};
}
}
export type RgbppTransactionLoaderType = DataLoader<string, RgbppBaseTransaction | null>;
export type RgbppTransactionLoaderResponse = DataLoaderResponse<RgbppTransactionLoader>;
7 changes: 5 additions & 2 deletions backend/src/modules/rgbpp/transaction/transaction.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import { CkbExplorerModule } from 'src/core/ckb-explorer/ckb-explorer.module';
import { CkbTransactionModule } from 'src/modules/ckb/transaction/transaction.module';
import { RgbppTransactionResolver } from './transaction.resolver';
import { RgbppTransactionService } from './transaction.service';
import { RgbppTransactionLoader } from './transaction.dataloader';
import { CkbRpcModule } from 'src/core/ckb-rpc/ckb-rpc.module';

@Module({
imports: [CkbExplorerModule, CkbTransactionModule, BitcoinApiModule],
providers: [RgbppTransactionResolver, RgbppTransactionService],
imports: [CkbExplorerModule, CkbRpcModule, CkbTransactionModule, BitcoinApiModule],
providers: [RgbppTransactionResolver, RgbppTransactionService, RgbppTransactionLoader],
exports: [RgbppTransactionLoader],
})
export class RgbppTransactionModule {}
Loading

0 comments on commit a2f8d78

Please sign in to comment.