Skip to content

Latest commit

 

History

History
1141 lines (789 loc) · 26.4 KB

README.md

File metadata and controls

1141 lines (789 loc) · 26.4 KB

GBM WEB2.0 API

Last update: 8/09/2024

Quick Intro

The GBM Algorithm, aka Bid-To Earn Auctions, is an auction mechanism that allows everyone (Bidder, Sellers, Auction Winner) to win. More details can be found at https://www.gbm.auction

This Repo

This repo is a backend API that allows you to integrate and run GBM auctions in your frontend. It also comes with example Frontend and Middleware.

Architecture

With a GBM auction, the order of the bid is extremely important. Henceforth, any DB modification need to be done trough a transaction to prevent concurrent override. The core of the API use is hence :

  • Submit a transaction request to the API
  • The API instantly store your transaction request, and you can consult it trough read to the database.
  • The API run a single threaded, FIFO transaction request processor. These transactions and then consequence are then processed (or rejected)
  • Any webhook registered with the API receive the corresponding JSON objects following a transaction being processed.

The API should NOT be directly accessed by your frontend. It is very agnostic regarding user represntation/auth (a simple string/userID) and doesn't do any auth. No other software than the API should have write access to the associated mongoDB cluster. A read access is possible and even recommended. As such, a middleware need to exist in front of the API, doing the following :

  • User Auth
  • Payment processing (OpenBanking, Bank Card, Video Game Currency, Crypto, etc...) and making the backend aware of any committed funds each user have
  • Passtrough of read request from the frontend
  • Propagating the backend webhook to frontend websockets when a payment is succesful, a user have been outbid, etc...

The API is completely frontend agnostic, however the frontend should not query the API directly, only the middleware. The DB being a mongodb database, it is extremely easy and intuitive for even non-initiated people (eg: Frontend Dev)

Project Structure

API

The core of the software.

Frontend

This is just a simple frontend example showcasing what the UX should be. Because of the immense varitery of currency settlement system as well as user authentification mechanism, we can not at this time provide something that for sure can be instantly plug and played into your platform. However, feel free to copy paste components from this frontend to your own system. Additionally, the admin dashboard can be used as is, in order to interract with the API or edit other conf.

Middleware

The middleware that should be used with the API. Feel free to peek at it's code (it's very simple) and adapt it to your own needs. It is implemented as a node server, but again, YOU MUST MAKE YOUR OWN. No specifc implementation of user auth have been implemented. If you deploy it as is, anyone could place a bid on behalf of anyone else. Please make this middleware properly use YOUR OWN AUTH method. eg: Wallet signing for web3, session cookies for traditional web2, SSO, etc...

API Routes

Do not reccklessly add/edit/delete objects from the DB. Most of those routes are meant for admin/dashboard purposes. Your end-user frontend middleware should only be doing "List" instruction from the API for most uses cases, with potentially adding assets.

Listed below are all the routes for the API. These are meant to follow the pattern of //, and commands are shared for all types. Pretty much every parameter to be sent will be of type string, and type conversions if necessary are handled under the hood.

Classes:

  • Assets
  • Auctions
  • Balances
  • Bids
  • Currencies
  • Configurations
  • Ownerships
  • Portefeuilles
  • Presets
  • Royalties
  • Transactions

Instructions:

  • Add (POST)
  • AddBatch (POST)
  • List (GET)
  • Update (POST)
  • Delete (POST)

With the above, we can perform basic database manipulations by just calling the relevant route with GET/POST. For example, if we want to get a list of all auctions, then a GET request to /auctions/list/ is that's necessary to retrieve a json array of all auctions present in the database.

However, there is one notable exception to the above - the transactions route, and it ties in to how the API is expected to be called by a frontend middleware. While reading all info is a fairly straightforward process by just firing a GET to the list instruction of your requested class,you do not want to have everyone hitting an endpoint that directly modifies data. To save developers from dealing with the hassle of batch processing updates to the database, this is already being done - all transactions to the database are stored in a table of their own, which will then be worked on by a separate transaction processor that ensures that:

  • All actions are dealt with in proper order
  • Invalid actions are rejected before any database update is made

As such, it is extremely important to default to using the transactions route over any manual update route. The direct routes are there for both the transaction processor and an admin to use, such as for updating presets and configuration options.


Examples for each route independently


Assets
[GET] List
"http://example.com/assets/list"

Basic GET route that returns an array of all assets.

Optional parameter only:

  • assetId - Returns the specified asset.
"http://example.com/assets/list?assetId=test"

Returns:

[
    {
        "assetId": "",
        "name":"",
        "description": "",
        "image": "",
        "thumbnail": "",
    },
    ...
]
[POST] Add
"http://example.com/assets/add"

Post route to add a new asset to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • assetId - Needs to be unique
    • name
    • description
    • image - The URL to the image
    • thumbnail - The URL to a thumbnail image

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/assets/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/assets/delete"

Post route to remove an asset from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • assetId

Returns:

{ 
    "success": "true" or "false"
}

Balances
[GET] List
"http://example.com/balances/list"

Basic GET route that returns an array of all userBalances.

Optional parameter only:

  • userId - Returns the specified user's balances.
"http://example.com/balances/list?userId=test"

Returns:

[
    {
        "userId": "",
        "currencyName":"",
        "currencyAmount": "",
    },
    ...
]
[POST] Add
"http://example.com/balances/add"

Post route to add a new user balance to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • userId
    • currencyName
    • currencyAmount

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/balances/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/balances/delete"

Post route to remove a user balance from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • userId

Returns:

{ 
    "success": "true" or "false"
}
[POST] Update
"http://example.com/balances/update"

Post route to update a user balance.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • userId
    • currencyName
    • currencyAmount

Returns:

{ 
    "success": "true" or "false"
}

Bids
[GET] List
"http://example.com/bids/list"

Basic GET route that returns an array of all bids.

No parameters are required

Returns:

[
    {
        "bidId": "", 
        "auctionId":"",
        "bidder": "",
        "bidAmount": "",
        "currencyId": "",
        "incentiveDue": "",
        "displaced": false
    },
    ...
]
[POST] Add
"http://example.com/bids/add"

Post route to add a new bid to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • bidId - Needs to be unique
    • auctionId - The ID of the related auction
    • bidder
    • bidAmount - As a string
    • currencyId - The ID of the currency used
    • incentiveDue - Calculated on the GBM side

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/bids/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/bids/delete"

Post route to remove a bid from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • bidId - Needs to be unique

Returns:

{ 
    "success": "true" or "false"
}
[POST] Update
"http://example.com/bids/update"

Post route to update a bid's displaced status.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • bidId - Needs to be unique

Returns:

{ 
    "success": "true" or "false"
}

Configurations (Missing) NOT IMPLEMENTED YET

Currencies
[GET] List
"http://example.com/currencies/list"

Basic GET route that returns an array of all currencies.

No parameters are required

Returns:

[
    {
        "currencyId": "",
        "name":"",
        "symbol": "",
        "icon": "",
    },
    ...
]
[POST] Add
"http://example.com/currencies/add"

Post route to add a new currency to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • currencyId - Needs to be unique
    • name
    • symbol - i.e. USD
    • icon - The URL to the icon

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/currencies/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/currencies/delete"

Post route to remove a currency from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • currencyId

Returns:

{ 
    "success": "true" or "false"
}
[POST] Update
"http://example.com/currencies/update"

Post route to update a currency's information.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • currencyId - The id of the one we wish to update
    • name - The new name
    • symbol - The new symbol i.e. USD
    • icon - The new URL to the icon

Returns:

{ 
    "success": "true" or "false"
}

Ownerships
[GET] List
"http://example.com/ownerships/list"

Basic GET route that returns an array of all ownership entities.

Optional parameter only:

  • ownerId - Filter the returned ownerships to the specified owner.
"http://example.com/ownerships/list?ownerId=test"

Returns:

[
    {
        "assetId": "", 
        "ownerId":"",
        "amountOwned": "",
        "amountLocked": "",
        "amountUnderSale": "",
    },
    ...
]
[POST] Add
"http://example.com/ownerships/add"

Post route to add a new ownership entity to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • assetId - The ID of the held asset
    • ownerId - The ID of the owning user
    • amountOwned - How many of the assets are in the user's wallet
    • amountLocked - How many of the assets are in escrow
    • amountUnderSale - How many are under sale

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/ownerships/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/ownerships/delete"

Post route to remove an ownership entity from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • assetId - The ID of the held asset
    • ownerId - The ID of the owning user

Returns:

{ 
    "success": "true" or "false"
}
[POST] Update
"http://example.com/ownerships/update"

Post route to update an ownership entity's information.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • assetId - The ID of the held asset
    • ownerId - The ID of the owning user
    • amountOwned - How many of the assets are in the user's wallet
    • amountLocked - How many of the assets are in escrow
    • amountUnderSale - How many are under sale

Returns:

{ 
    "success": "true" or "false"
}

Portefeuilles
[GET] List
"http://example.com/portefeuilles/list"

Basic GET route that returns an array of all portefeuilles.

Optional parameter only:

  • ownerId - Filter the returned portefeuilles to the specified owner.
"http://example.com/portefeuilles/list?ownerId=test"

Returns:

[
    {
        "currencyId": "", 
        "ownerId":"",
        "amountOwned": "",
        "amountLocked": "",
    },
    ...
]
[POST] Add
"http://example.com/portefeuilles/add"

Post route to add a new portefeuille to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • currencyId - The ID of the held currency
    • ownerId - The ID of the owning user
    • amountOwned - Amount of the currency owned
    • amountLocked - Amount of the currency in escrow

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/portefeuilles/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/portefeuilles/delete"

Post route to remove a portefeuille from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • currencyId - The ID of the held currency
    • ownerId - The ID of the owning user

Returns:

{ 
    "success": "true" or "false"
}
[POST] Update
"http://example.com/portefeuilles/update"

Post route to update a portefeuille's information.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • currencyId - The ID of the held currency
    • ownerId - The ID of the owning user
    • amountOwned - Amount of the currency owned
    • amountLocked - Amount of the currency in escrow

Returns:

{ 
    "success": "true" or "false"
}

Presets (Missing) NOT IMPLEMENTED YET

Royalties
[GET] List
"http://example.com/royalties/list"

Basic GET route that returns an array of all royalty entities.

Optional parameter only:

  • royaltyId - Returns the specified royalty entity.
"http://example.com/royalties/list?royaltyId=test"

Returns:

[
    {
        "royaltyId": "", 
        "name":"",
        "percent": "",
        "destinationUser": "",
    },
    ...
]
[POST] Add
"http://example.com/royalties/add"

Post route to add a new royalty to the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • royaltyId - The ID of the royalty
    • name
    • percent
    • destinationUser - Who will receive the royalty

Returns:

{ 
    "success": "true" or "false"
}
[POST] AddBatch
"http://example.com/royalties/addBatch"

Same use as the previous one, just ensure the request body contains an array of JSON objects rather than sending a single one.

[POST] Delete
"http://example.com/royalties/delete"

Post route to remove a royalty entity from the database.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • royaltyId - The ID of the royalty

Returns:

{ 
    "success": "true" or "false"
}
[POST] Update
"http://example.com/royalties/update"

Post route to update a royalty's information.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

    • royaltyId - The ID of the royalty
    • name
    • percent
    • destinationUser - Who will receive the royalty

Returns:

{ 
    "success": "true" or "false"
}

Transactions

The /transactions/ endpoint operates with its own routes, with each named according to the purpose it serves:

  • createAuction - For starting an auction
  • placeBid - For placing a bid on an auction
  • topUp - For a user to top up their balance
  • withdraw - For a user to withdraw from their balance

Each of those transactions fire back on a webhook when processed, as JSON, the entities impacted by the transaction in their final state at the end of the transaction. This is not meant to be sent directly to end user, but instead to be parsed by your middleware so that each user websocket/other notification method you implemented get notified independently with the relevant data.

Transactions are also currently being expanded to support better non-comitted payment intents (eg: Placing a bid but paying with Card/Open banking, and waiting for payment confirmation before processing the bid).
topUp is to be called by the middleware everytime capital is confirmed as commited. Without enough capital commited in the relevant currency, a bid will fail.
withdraw is to be called by the middleware everytime every time capital is uncommited.


[POST] Create Auction
"http://example.com/transactions/createAuction"

Tells the transaction processor to start an auction with the requested parameters.

  • Required:

    • requestingUser - The user starting the auction
    • nonce
    • signature - A signature verifying the user
    • arg_assetId - The id of the asset to put on auction
    • arg_assetAmount - How many of the assets will be put on sale
    • arg_startingBid - The minimum bid
    • arg_reservePrice
    • arg_baseCurrency - The currency the auction will default to
    • arg_startTimestamp - The starting time of the auction (UNIX timestamp)
    • arg_incentiveMin - To be fetched from the GBM Preset
    • arg_incentiveMax - To be fetched from the GBM Preset
    • arg_stepMin - To be fetched from the GBM Preset
    • arg_bidMultiplier - To be fetched from the GBM Preset
    • arg_duration - To be fetched from the Duration Preset
    • arg_hammerTimeDuration - To be fetched from the Duration Preset
    • arg_gracePeriodDuration - To be fetched from the Duration Preset

Returns:

{ 
    "success": "true" or "false"
}
[POST] Place Bid
"http://example.com/transactions/placeBid"

Tells the transaction processor to place a bid on an auction, with all the balance locking / bid displacing / incentive paying / etc. that entails.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

  • requestingUser - The user starting the auction

  • nonce

  • signature - A signature verifying the user

  • arg_auctionId - The id of the auction to bid on

  • arg_bidAmount - The amount on the new bid

  • arg_bidCurrencyId - The currencyId for the currency the new bid is under

Returns:

{ 
    "success": "true" or "false"
}
[POST] Top Up
"http://example.com/transactions/topUp"

Tells the transaction processor to top up a user's balance by a requested amount.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

  • requestingUser - The user starting the auction

  • nonce

  • signature - A signature verifying the user

  • arg_userBeingToppedUp - ownerId of the balance to top up

  • arg_amountToTopUp - The amount to top up

  • arg_currencyId - The currencyId for the currency added

Returns:

{ 
    "success": "true" or "false"
}
[POST] Withdraw
"http://example.com/transactions/withdraw"

Tells the transaction processor to top up a user's balance by a requested amount.

A JSON body must be sent, with an object holding the required parameters:

  • Required:

  • requestingUser - The user starting the auction

  • nonce

  • signature - A signature verifying the user

  • arg_userWithdrawing - ownerId of the balance to withdraw from

  • arg_amountToWithdraw - The amount to withdraw

  • arg_currencyId - The currencyId for the currency withdrawn

Returns:

{ 
    "success": "true" or "false"
}

SETUP

Your infra will look as follow :

  • A mongodb cluster. Either use MongoDB Atlas or launch your own. A cluster is necessary, a standalone MongoDB lack the transaction features being used.
  • The API node server. This doesn't need to be open to the wider internet, only to your middleware. For better performance, host it near the DB (ie: Same Cloud VPC and physical location, maybe even same machine if reactivity is super important to you).
  • A middleware for communicating with the API. This middleware is the only piece of software that should have API access that is not an admin tool. This middleware is for >YOU< to implement. We do however provide several example implementations that can be forkd, including one for FIAT Payment Processor, a barebone one, etc...
  • Your choice of end-user frontend/backend. We expect most of our client to already have an existing website/marketplace/auth. However, it's highly advised to stick to the bidding UX provided in the example frontend, as it handle GBM in a way intutive for bidders to understand.

Please look into each repo for their separate docs, including how to setup a localhost test environement.