Skip to content

Đặc tả: NFT Management Feature

Module: web (port 8080) + webmarketplace (port 8084) Status: Production

1. Tổng quan

Feature quản lý lifecycle của 3 loại NFT (Hunter, Gauntlet, Bounty Ball) và rental marketplace cho Bounty Ball.

2. Phạm vi

In-scope - NFT APIs (web module)

HunterController (/api/nft-hunter)

Endpoint Method Mô tả
/ GET Danh sách Hunter của user
/{id} GET Chi tiết Hunter
(CRUD endpoints) POST/PUT/DELETE Quản lý Hunter

NftGauntletController (/api/nft-gauntlet)

Endpoint Method Mô tả
/ GET Danh sách Gauntlet của user
/{id} GET Chi tiết Gauntlet

NftBountyBallController (/api/nft-bounty-ball)

Endpoint Method Mô tả
/ GET Danh sách Bounty Ball của user
/{id} GET Chi tiết Bounty Ball
(lifecycle endpoints) POST/PUT Manage Bounty Ball state

In-scope - Rental Market (webmarketplace module)

NftRentalController (/api/nft-rental)

Endpoint Method Mô tả
/ POST Tạo rental order (owner listing NFT)
/verify-order-creation/{id} PUT Verify creation (on-chain confirm)
/my-bounty-balls GET Bounty balls của owner (paginated + filtered)
/my-bounty-balls/{id} GET Bounty ball detail của owner
/my-rental-order GET Rental orders của owner (paginated)
/get-rental-order-by-ball-id/{id} GET Rental order by Bounty Ball ID
/get-sale-order-by-ball-id/{id} GET Sale order by Bounty Ball token ID
/market-rental GET Thị trường rental (tất cả NEW orders, exclude owner)
/{rentalOrderId} GET Rental order detail
/confirm-rent/{rentalOrderId} PUT Renter confirm thuê NFT
/cancel-rental-order/{id} PUT Owner cancel rental listing
/finish-rental-order/{id} PUT Kết thúc rental (test endpoint)
/return-rental-early/{id} PUT Renter trả về sớm
/rental-duration GET Danh sách rental duration + fee suggestions
/rental-data GET Tổng hợp rental data của user

Out-of-scope

Mục Lý do
NFT minting process Xử lý qua webhook + node server
NFT trading (buy/sell) Thuộc payment-marketplace feature
Gacha NFT rewards Thuộc prize-allocation feature

3. User stories

ID Role Story Acceptance
NFT-US-01 Owner List Bounty Ball lên rental market với giá và thời hạn status=NEW, product RENTING
NFT-US-02 Renter Browse market → confirm rent → NFT available trong inventory của renter B-Coin trừ, owner nhận deposit
NFT-US-03 Renter Trả về sớm → nhận lại phần coin còn lại (pro-rated) status=RETURN_EARLY
NFT-US-04 Owner Cancel listing trước khi có renter → NFT trở lại AVAILABLE status=CANCELLED
NFT-US-05 System Rental hết hạn → batch job tự động xử lý return processExpiredRental() called
NFT-US-06 Player Xem Hunter/Gauntlet inventory + attribute points Correct stats displayed

4. Functional requirements

ID Requirement Chi tiết
NFT-F-01 Rental order create Validate status=AVAILABLE, set product RENTING, tạo NftRentalOrderModel{status=NEW}
NFT-F-02 Verify creation On-chain confirm via transactionHash; nếu fail → rollback product AVAILABLE
NFT-F-03 Confirm rent Charge renter B-Coin, deposit owner (B-Coin), deduct admin fee; set status=RENTING
NFT-F-04 Cancel rental Chỉ cho phép khi status=NEW; set product AVAILABLE, order CANCELLED
NFT-F-05 Return early Pro-rated refund, owner nhận phần đã dùng; status=RETURN_EARLY
NFT-F-06 Expiry batch NftRentalExpirationCheckBatch chạy định kỳ, call processExpiredRental()
NFT-F-07 Minted/unminted branch Nếu NFT minted → call NodeServerService.confirmSolanaNftRental(); unminted → DB only
NFT-F-08 Rental duration suggestions Fee = coefficientA(rarity) × duration: COMMON=50, UNCOMMON=100, RARE=300, EPIC=500, LEGENDARY=1000
NFT-F-09 Market filtering /market-rental filter: status=NEW, exclude ownerId=loginUser, sort by NEWEST
NFT-F-10 Equipment/gimmick sync NFT state change → update user equipment records

5. Business rules

Rental status lifecycle

NEW → RENTING → FINISHED
NEW → CANCELLED
RENTING → RETURN_EARLY
RENTING → EXPIRED_HANDLED (by batch)

Rental fee formula

rentalFeeSuggest = coefficientA(rarity) × duration(days)
Rarity: COMMON=50, UNCOMMON=100, RARE=300, EPIC=500, LEGENDARY=1000

Concurrency guard

  • Confirm rent: transaction + status lock (phải status=NEW để confirm).
  • Cancel: phải status=NEW để cancel.

6. Data contracts

Request - Create rental order

{
  "bounty_ball_id": "<nftId>",
  "rental_duration": 7,
  "rental_fee": 350,
  "rental_currency": "BCOIN"
}

Response - NftRentalOrderModel

{
  "id": "<orderId>",
  "owner_id": "<ownerId>",
  "renter_id": null,
  "bounty_ball_id": "<nftId>",
  "rental_status": "NEW",
  "rental_duration": 7,
  "rental_fee": 350,
  "rental_start_time": null,
  "rental_end_time": null,
  "ball_of_user": { ... }
}

Response - Rental duration suggestions

[
  { "rental_duration": 7, "rarity": "COMMON", "rental_fee_suggest": 350 },
  { "rental_duration": 7, "rarity": "RARE", "rental_fee_suggest": 2100 },
  ...
]

7. Acceptance criteria

  • [ ] Create rental order: product status=RENTING, order status=NEW
  • [ ] Verify order fail: product rollback AVAILABLE, order CANCELLED
  • [ ] Confirm rent: renter B-Coin charged, owner received, admin fee deducted, status=RENTING
  • [ ] Cancel (status=NEW): product AVAILABLE, order CANCELLED
  • [ ] Return early: pro-rated refund calculated correctly
  • [ ] Market listing: không hiển thị item của chính owner
  • [ ] Batch expiry: expired rentals processed, NFT returned
  • [ ] Minted NFT: confirmSolanaNftRental() called
  • [ ] Rental fee suggestions: match formula per rarity × duration

8. Constraints

  • Sort market-rental: hỗ trợ RentalOrderSortType enum: NEWEST, và các giá trị khác.
  • my-bounty-balls: filter lang_key là bắt buộc (throw LANG_KEY_IS_INVALID nếu thiếu).
  • Exclude chain IDs: 80002, 137 trong Bounty Ball filter.

9. Code references

webmarketplace/
  controllers/nft_rental/NftRentalController.java
  controllers/nft_rental/dto/NftRentalOrderDto.java
  controllers/nft_rental/dto/NftRentalOrderResponse.java

web/
  controllers/hunter/NftHunterController.java
  controllers/nft_gauntlet/NftGauntletController.java
  controllers/nft_bounty_ball/NftBountyBallController.java

application-core/
  service/nft_rental/nft_rental_order/NftRentalOrderService.java
  service/nft_rental/nft_rental_order/NftRentalOrderModel.java
  service/nft_bounty_ball/NftBountyBallService.java
  service/nft_hunter/NftHunterService.java
  service/nft_gauntlet/NftGauntletService.java

batch/
  job/nft_rental/NftRentalExpirationCheckBatch.java