Skip to content

Commit

Permalink
feat: extensible bitsacco shares
Browse files Browse the repository at this point in the history
  • Loading branch information
okjodom committed Dec 30, 2024
1 parent 60e14eb commit 33a0d1d
Show file tree
Hide file tree
Showing 11 changed files with 603 additions and 160 deletions.
81 changes: 57 additions & 24 deletions apps/api/src/shares/shares.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { BuySharesDto, GetShareDetailDto } from '@bitsacco/common';
import { Body, Controller, Get, Logger, Post, Query } from '@nestjs/common';
import { ApiOperation, ApiBody, ApiQuery } from '@nestjs/swagger';
import {
OfferSharesDto,
SubscribeSharesDto,
TransferSharesDto,
} from '@bitsacco/common';
import {
Body,
Controller,
Get,
Logger,
Param,
Post,
Query,
} from '@nestjs/common';
import { ApiOperation, ApiBody, ApiQuery, ApiParam } from '@nestjs/swagger';
import { SharesService } from './shares.service';

@Controller('shares')
Expand All @@ -11,32 +23,53 @@ export class SharesController {
this.logger.log('SharesController initialized');
}

@Get('detail')
@ApiOperation({ summary: 'Get share details' })
@ApiQuery({ name: 'user', type: String, required: true })
getShareDetail(@Query('user') user: string) {
return this.sharesService.getShareDetail({ userId: user });
@Post('offer')
@ApiOperation({ summary: 'Offer Bitsacco shares' })
@ApiBody({
type: OfferSharesDto,
})
offerShares(@Body() req: OfferSharesDto) {
return this.sharesService.offerShares(req);
}

@Get('offers')
@ApiOperation({ summary: 'List all share offers' })
getShareOffers() {
return this.sharesService.getSharesOffers({});
}

@Post('subscribe')
@ApiOperation({ summary: 'Subscribe Bitsacco shares' })
@ApiBody({
type: SubscribeSharesDto,
})
subscribeShares(@Body() req: SubscribeSharesDto) {
return this.sharesService.subscribeShares(req);
}

@Post('buy')
@ApiOperation({ summary: 'Buy Bitsacco shares' })
@Post('transfer')
@ApiOperation({ summary: 'Transfer Bitsacco shares' })
@ApiBody({
type: BuySharesDto,
type: TransferSharesDto,
})
buyShares(@Body() req: BuySharesDto) {
return this.sharesService.buyShares(req);
transferShares(@Body() req: TransferSharesDto) {
return this.sharesService.transferShares(req);
}

@Get('subscription')
@ApiOperation({ summary: 'Show Bitsacco share subscription levels' })
getShareSubscription() {
return this.sharesService.getShareSubscription({});
@Get('transactions')
@ApiOperation({ summary: 'List all Bitsacco share transactions' })
allSharesTransactions() {
return this.sharesService.allSharesTransactions({});
}
}

// @ApiQuery({ name: 'currency', enum: SupportedCurrencies, required: true })
// @ApiQuery({ name: 'amount', type: Number, required: false })
// getOnrampQuote(
// @Query('currency') currency: SupportedCurrencyType,
// @Query('amount') amount?: number,
// ) {
@Get('transactions/:userId')
@ApiOperation({
summary: 'List all Bitsacco share transactions for user with given ID',
})
@ApiParam({ name: 'userId', type: 'string', description: 'User ID' })
userSharesTransactions(@Param('userId') userId: string) {
return this.sharesService.userSharesTransactions({
userId,
});
}
}
30 changes: 22 additions & 8 deletions apps/api/src/shares/shares.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import {
SharesServiceClient,
SHARES_SERVICE_NAME,
BuySharesDto,
Empty,
GetShareDetailDto,
OfferSharesDto,
SubscribeSharesDto,
TransferSharesDto,
UserSharesDto,
} from '@bitsacco/common';
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { type ClientGrpc } from '@nestjs/microservices';
Expand All @@ -19,15 +21,27 @@ export class SharesService implements OnModuleInit {
this.grpc.getService<SharesServiceClient>(SHARES_SERVICE_NAME);
}

getShareDetail(req: GetShareDetailDto) {
return this.client.getShareDetail(req);
offerShares(req: OfferSharesDto) {
return this.client.offerShares(req);
}

buyShares(req: BuySharesDto) {
return this.client.buyShares(req);
getSharesOffers(req: Empty) {
return this.client.getSharesOffers(req);
}

getShareSubscription(req: Empty) {
return this.client.getShareSubscription({});
subscribeShares(req: SubscribeSharesDto) {
return this.client.subscribeShares(req);
}

transferShares(req: TransferSharesDto) {
return this.client.transferShares(req);
}

userSharesTransactions(req: UserSharesDto) {
return this.client.userSharesTransactions(req);
}

allSharesTransactions(req: Empty) {
return this.client.allSharesTransactions(req);
}
}
2 changes: 1 addition & 1 deletion apps/api/src/swap/swap.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class SwapController {
}

@Get('offramp/all')
@ApiOperation({ summary: 'List offramp swaps' })
@ApiOperation({ summary: 'List all offramp swaps' })
@ApiQuery({
name: 'page',
example: '0',
Expand Down
14 changes: 13 additions & 1 deletion apps/shares/src/db/shares.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@ import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { Injectable, Logger } from '@nestjs/common';
import { AbstractRepository } from '@bitsacco/common';
import { SharesDocument } from './shares.schema';
import { SharesDocument, SharesOfferDocument } from './shares.schema';

@Injectable()
export class SharesOfferRepository extends AbstractRepository<SharesOfferDocument> {
protected readonly logger = new Logger(SharesOfferRepository.name);

constructor(
@InjectModel(SharesOfferDocument.name)
reservationModel: Model<SharesOfferDocument>,
) {
super(reservationModel);
}
}

@Injectable()
export class SharesRepository extends AbstractRepository<SharesDocument> {
Expand Down
54 changes: 53 additions & 1 deletion apps/shares/src/db/shares.schema.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,65 @@
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { AbstractDocument } from '@bitsacco/common';
import {
AbstractDocument,
SharesTx,
SharesTxStatus,
type SharesTxTransferMeta,
} from '@bitsacco/common';

@Schema({ versionKey: false })
export class SharesOfferDocument extends AbstractDocument {
@Prop({ type: Number, required: true })
quantity: number;

@Prop({ type: Number, required: true, default: 0 })
subscribedQuantity: number;

@Prop({ type: Date, required: true, default: Date.now })
availableFrom: Date;

@Prop({ type: Date, required: false })
availableTo?: Date;
}

export const SharesOfferSchema =
SchemaFactory.createForClass(SharesOfferDocument);

@Schema({ versionKey: false })
export class SharesDocument extends AbstractDocument {
@Prop({ type: String, required: true })
userId: string;

@Prop({ type: String, required: true })
offerId: string;

@Prop({
type: String,
required: true,
enum: Object.values(SharesTxStatus),
})
status: SharesTxStatus;

@Prop({
type: Object,
required: false,
})
transfer?: SharesTxTransferMeta;

@Prop({ type: Number, required: true })
quantity: number;
}

export const SharesSchema = SchemaFactory.createForClass(SharesDocument);

export function toSharesTx(share: SharesDocument): SharesTx {
return {
id: share._id,
userId: share.userId,
offerId: share.offerId,
quantity: share.quantity,
status: share.status,
transfer: share.transfer,
createdAt: share.createdAt.toDateString(),
updatedAt: share.updatedAt.toDateString(),
};
}
33 changes: 25 additions & 8 deletions apps/shares/src/shares.controller.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Controller } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
import {
BuySharesDto,
type Empty,
GetShareDetailDto,
OfferSharesDto,
SharesServiceControllerMethods,
SubscribeSharesDto,
TransferSharesDto,
UserTxsRequestDto,
} from '@bitsacco/common';
import { SharesService } from './shares.service';

Expand All @@ -14,17 +16,32 @@ export class SharesController {
constructor(private readonly sharesService: SharesService) {}

@GrpcMethod()
getShareDetail(request: GetShareDetailDto) {
return this.sharesService.getShareDetail(request);
offerShares(request: OfferSharesDto) {
return this.sharesService.offerShares(request);
}

@GrpcMethod()
buyShares(request: BuySharesDto) {
return this.sharesService.buyShares(request);
getSharesOffers(_: Empty) {
return this.sharesService.getSharesOffers();
}

@GrpcMethod()
getShareSubscription(request: Empty) {
return this.sharesService.getShareSubscrition(request);
subscribeShares(request: SubscribeSharesDto) {
return this.sharesService.subscribeShares(request);
}

@GrpcMethod()
transferShares(request: TransferSharesDto) {
return this.sharesService.transferShares(request);
}

@GrpcMethod()
userSharesTransactions(request: UserTxsRequestDto) {
return this.sharesService.userSharesTransactions(request);
}

@GrpcMethod()
allSharesTransactions(_: Empty) {
return this.sharesService.allSharesTransactions();
}
}
17 changes: 15 additions & 2 deletions apps/shares/src/shares.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { DatabaseModule, LoggerModule } from '@bitsacco/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { SharesController } from './shares.controller';
import { SharesService } from './shares.service';
import { SharesDocument, SharesRepository, SharesSchema } from './db';
import {
SharesDocument,
SharesOfferDocument,
SharesOfferRepository,
SharesOfferSchema,
SharesRepository,
SharesSchema,
} from './db';

@Module({
imports: [
Expand All @@ -19,11 +26,17 @@ import { SharesDocument, SharesRepository, SharesSchema } from './db';
}),
DatabaseModule,
DatabaseModule.forFeature([
{ name: SharesOfferDocument.name, schema: SharesOfferSchema },
{ name: SharesDocument.name, schema: SharesSchema },
]),
LoggerModule,
],
controllers: [SharesController],
providers: [SharesService, ConfigService, SharesRepository],
providers: [
SharesService,
ConfigService,
SharesOfferRepository,
SharesRepository,
],
})
export class SharesModule {}
Loading

0 comments on commit 33a0d1d

Please sign in to comment.