mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-11 19:04:35 +00:00
add nft assets endpoint (#298)
This commit is contained in:
103
nft/domain/opensea.go
Normal file
103
nft/domain/opensea.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package domain
|
||||
|
||||
type AssetResponse struct {
|
||||
Assets []*Asset `json:"assets"`
|
||||
}
|
||||
|
||||
type Asset struct {
|
||||
Id int32 `json:"id"`
|
||||
TokenId string `json:"token_id"`
|
||||
Sales int32 `json:"num_sales"`
|
||||
ImageUrl string `json:"image_url"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Permalink string `json:"permalink"`
|
||||
Contract *Contract `json:"asset_contract"`
|
||||
Collection *Collection `json:"collection"`
|
||||
Creator *User `json:"creator"`
|
||||
Owner *User `json:"owner"`
|
||||
LastSale *Sale `json:"last_sale,omitempty"`
|
||||
Presale bool `json:"is_presale"`
|
||||
ListingDate string `json:"listing_date,omitempty"`
|
||||
}
|
||||
|
||||
type Contract struct {
|
||||
// name of contract
|
||||
Name string `json:"name,omitempty"`
|
||||
// ethereum address
|
||||
Address string `json:"address,omitempty"`
|
||||
// type of contract e.g "semi-fungible"
|
||||
Type string `json:"asset_contract_type,omitempty"`
|
||||
// timestamp of creation
|
||||
CreatedAt string `json:"created_date,omitempty"`
|
||||
// owner id
|
||||
Owner int32 `json:"owner,omitempty"`
|
||||
// aka "ERC1155"
|
||||
Schema string `json:"schema_name,omitempty"`
|
||||
// related symbol
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
// description of contract
|
||||
Description string `json:"description,omitempty"`
|
||||
// payout address
|
||||
PayoutAddress string `json:"payout_address,omitempty"`
|
||||
// seller fees
|
||||
SellerFees string `json:"seller_fees_basis_points,omitempty"`
|
||||
}
|
||||
|
||||
type Collection struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
ImageUrl string `json:"image_url,omitempty"`
|
||||
CreatedAt string `json:"created_date,omitempty"`
|
||||
PayoutAddress string `json:"payout_address,omitempty"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
User *Username `json:"user"`
|
||||
ProfileUrl string `json:"profile_img_url,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
}
|
||||
|
||||
type Username struct {
|
||||
Username string `json:"username",omitempty"`
|
||||
}
|
||||
|
||||
type SaleAsset struct {
|
||||
TokenId string `json:"token_id"`
|
||||
Decimals int32 `json:"decimals"`
|
||||
}
|
||||
|
||||
type Sale struct {
|
||||
Asset *SaleAsset `json:"asset"`
|
||||
EventType string `json:"event_type,omitempty"`
|
||||
EventTimestamp string `json:"event_timestamp,omitempty"`
|
||||
TotalPrice string `json:"total_price,omitempty"`
|
||||
Quantity string `json:"quantity,omitempty"`
|
||||
CreatedAt string `json:"created_date,omitempty"`
|
||||
Transaction *Transaction `json:"transaction,omitempty"`
|
||||
PaymentToken *Token `json:"payment_token,omitempty"`
|
||||
}
|
||||
|
||||
type Transaction struct {
|
||||
Id int32 `json:"id,omitempty"`
|
||||
Timestamp string `json:"timestamp,omitempty"`
|
||||
BlockHash string `json:"block_hash,omitempty"`
|
||||
BlockNumber string `json:"block_number,omitempty"`
|
||||
FromAccount *User `json:"from_account,omitempty"`
|
||||
ToAccount *User `json:"to_account,omitempty"`
|
||||
TransactionHash string `json:"transaction_hash,omitempty"`
|
||||
TransactionIndex string `json:"transaction_index,omitempty"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Id int32 `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
Address string `json:"address,omitempty"`
|
||||
ImageUrl string `json:"image_url,omitempty"`
|
||||
Decimals int32 `json:"decimals,omitempty"`
|
||||
EthPrice string `json:"eth_price,omitempty"`
|
||||
UsdPrice string `json:"usd_price,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,13 +1,105 @@
|
||||
{
|
||||
"vote": [
|
||||
"assets": [
|
||||
{
|
||||
"title": "Vote for the API",
|
||||
"title": "Get a list of assets",
|
||||
"run_check": false,
|
||||
"request": {
|
||||
"message": "Launch it!"
|
||||
"order_by": "sale_date",
|
||||
"limit": 1
|
||||
},
|
||||
"response": {
|
||||
"message": "Thanks for the vote!"
|
||||
"assets": [
|
||||
{
|
||||
"id": 96959754,
|
||||
"token_id": "24",
|
||||
"name": "The Bitcoin Price Crash",
|
||||
"description": "\"The Bitcoin Price Crash\" from CryptoCards collection",
|
||||
"image_url": "https://lh3.googleusercontent.com/QKCsg3W-71eFbFSHl_4sVV89gxzZvgX8sls9r8PCyJIwYkEKVm1VJVcWdCEm5IxpqYgpcLDNm9JaiF13jKxWvOflVnYW5KIs8GhIdXg",
|
||||
"sales": 7,
|
||||
"permalink": "https://opensea.io/assets/0x3a7dc718eaf31f0a55988161f3d75d7ca785b034/24",
|
||||
"contract": {
|
||||
"name": "Cryptocards",
|
||||
"address": "0x3a7dc718eaf31f0a55988161f3d75d7ca785b034",
|
||||
"type": "semi-fungible",
|
||||
"created_at": "2021-11-10T08:31:01.405462",
|
||||
"owner": 63182848,
|
||||
"schema": "ERC1155",
|
||||
"symbol": "CC",
|
||||
"description": "The Cryptocards collection was created at the dawn of what is considered cryptoart or NFTs today being minted on January 2018. \n\nIt is the only NFT collection chronicling the history of Bitcoin including over 50 cards with a total supply of 7.851.\n\nThe initial CryptoCards were issued as a ERC-20, but we developed an ERC1155 wrapper to make them available on OpenSea.\n\nBeware of other fake collections on OS. Stay safe and join the community: https://discord.gg/m9nUKEzcWJ",
|
||||
"payout_address": "0xb7e0c211fb088e42aa9fd936b0a9c52985fbd273",
|
||||
"seller_fees": ""
|
||||
},
|
||||
"collection": {
|
||||
"name": "The CryptoCards Collection (2018)",
|
||||
"description": "The Cryptocards collection was created at the dawn of what is considered cryptoart or NFTs today being minted on January 2018. \n\nIt is the only NFT collection chronicling the history of Bitcoin including over 50 cards with a total supply of 7.851.\n\nThe initial CryptoCards were issued as a ERC-20, but we developed an ERC1155 wrapper to make them available on OpenSea.\n\nBeware of other fake collections on OS. Stay safe and join the community: https://discord.gg/m9nUKEzcWJ",
|
||||
"slug": "cryptocards-collection",
|
||||
"image_url": "https://lh3.googleusercontent.com/ByPl14lqRv2VsFm_drrTcxM7qE4pDRH3A3beQ2lPtes2gJ7gl4qFH1-v-8Vn7I47yLDN4F_QGLT1-Qqi1IIsuM20AkXZUKZX9l800LI=s120",
|
||||
"created_at": "2021-11-10T08:44:55.811633",
|
||||
"payout_address": "0xb7e0c211fb088e42aa9fd936b0a9c52985fbd273"
|
||||
},
|
||||
"creator": {
|
||||
"username": "",
|
||||
"profile_url": "",
|
||||
"address": ""
|
||||
},
|
||||
"owner": {
|
||||
"username": "NullAddress",
|
||||
"profile_url": "https://storage.googleapis.com/opensea-static/opensea-profile/1.png",
|
||||
"address": "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"presale": false,
|
||||
"last_sale": {
|
||||
"asset_token_id": "24",
|
||||
"asset_decimals": 0,
|
||||
"event_type": "successful",
|
||||
"event_timestamp": "2021-12-08T13:52:33",
|
||||
"total_price": "75000000000000000",
|
||||
"quantity": "1",
|
||||
"created_at": "2021-12-08T13:52:54.475811",
|
||||
"transaction": {
|
||||
"id": 218344593,
|
||||
"timestamp": "2021-12-08T13:52:33",
|
||||
"block_hash": "0xe168736f9f7f9bf610c04c0705165ef2ca470ddfc5fedb6d0337701f1d083d32",
|
||||
"block_number": "13765159",
|
||||
"from_account": {
|
||||
"username": "austincountach",
|
||||
"profile_url": "https://storage.googleapis.com/opensea-static/opensea-profile/31.png",
|
||||
"address": "0x12ad5707401114453020a92a7384f267c9c559f2"
|
||||
},
|
||||
"to_account": {
|
||||
"username": "OpenSea-Orders",
|
||||
"profile_url": "https://storage.googleapis.com/opensea-static/opensea-profile/22.png",
|
||||
"address": "0x7be8076f4ea4a4ad08075c2508e481d6c946d12b"
|
||||
},
|
||||
"transaction_hash": "0xd3bfa0ffe5d37af6854f485606ceb349634e957ff5778570ea396288fe8914db",
|
||||
"transaction_index": "176"
|
||||
},
|
||||
"payment_token": {
|
||||
"id": 1,
|
||||
"name": "Ether",
|
||||
"symbol": "ETH",
|
||||
"address": "0x0000000000000000000000000000000000000000",
|
||||
"image_url": "https://storage.opensea.io/files/6f8e2979d428180222796ff4a33ab929.svg",
|
||||
"decimals": 18,
|
||||
"eth_price": "1.000000000000000",
|
||||
"usd_price": "4274.930000000000291000"
|
||||
}
|
||||
},
|
||||
"listing_date": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"create": [
|
||||
{
|
||||
"title": "Create an NFT",
|
||||
"run_check": false,
|
||||
"request": {
|
||||
"name": "Guybrush Threepwood",
|
||||
"description": "The epic monkey island character"
|
||||
},
|
||||
"response": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2,49 +2,14 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
||||
"github.com/micro/services/pkg/tenant"
|
||||
"github.com/micro/micro/v3/service/store"
|
||||
pb "github.com/micro/services/nft/proto"
|
||||
)
|
||||
|
||||
type Nft struct{}
|
||||
|
||||
var (
|
||||
mtx sync.RWMutex
|
||||
|
||||
voteKey = "votes/"
|
||||
)
|
||||
|
||||
type Vote struct {
|
||||
Id string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
VotedAt time.Time `json:"voted_at"`
|
||||
}
|
||||
|
||||
func (n *Nft) Vote(ctx context.Context, req *pb.VoteRequest, rsp *pb.VoteResponse) error {
|
||||
mtx.Lock()
|
||||
defer mtx.Unlock()
|
||||
|
||||
id, ok := tenant.FromContext(ctx)
|
||||
if !ok {
|
||||
id = "micro"
|
||||
}
|
||||
|
||||
rec := store.NewRecord(voteKey + id, &Vote{
|
||||
Id: id,
|
||||
Message: req.Message,
|
||||
VotedAt: time.Now(),
|
||||
})
|
||||
|
||||
// we don't need to check the error
|
||||
store.Write(rec)
|
||||
|
||||
rsp.Message = "Thanks for the vote!"
|
||||
|
||||
func (n *Nft) Assets(ctx context.Context, req *pb.AssetsRequest, rsp *pb.AssetsResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
227
nft/handler/opensea.go
Normal file
227
nft/handler/opensea.go
Normal file
@@ -0,0 +1,227 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/micro/services/pkg/api"
|
||||
"github.com/micro/services/nft/domain"
|
||||
"github.com/micro/micro/v3/service/config"
|
||||
"github.com/micro/micro/v3/service/logger"
|
||||
"github.com/micro/micro/v3/service/errors"
|
||||
pb "github.com/micro/services/nft/proto"
|
||||
)
|
||||
|
||||
// OpenSea handler
|
||||
type OpenSea struct {
|
||||
apiKey string
|
||||
// embed nft api
|
||||
*Nft
|
||||
}
|
||||
|
||||
var (
|
||||
openseaURL = "https://api.opensea.io/api/v1"
|
||||
)
|
||||
|
||||
|
||||
func New() *OpenSea {
|
||||
v, err := config.Get("nft.key")
|
||||
if err != nil {
|
||||
logger.Fatal("nft.key config not found: %v", err)
|
||||
}
|
||||
|
||||
key := v.String("")
|
||||
if len(key) == 0 {
|
||||
logger.Fatal("nft.key config not found")
|
||||
}
|
||||
|
||||
// set the api key
|
||||
api.SetKey("X-API-KEY", key)
|
||||
|
||||
return &OpenSea {
|
||||
apiKey: key,
|
||||
Nft: new(Nft),
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OpenSea) Assets(ctx context.Context, req *pb.AssetsRequest, rsp *pb.AssetsResponse) error {
|
||||
uri := openseaURL + "/assets"
|
||||
params := "?"
|
||||
|
||||
limit := int32(20)
|
||||
offset := int32(0)
|
||||
order := "desc"
|
||||
orderBy := ""
|
||||
|
||||
if req.Limit > 0 {
|
||||
limit = req.Limit
|
||||
}
|
||||
|
||||
if req.Offset > 0 {
|
||||
offset = req.Offset
|
||||
}
|
||||
|
||||
if req.Order == "asc" {
|
||||
order = "asc"
|
||||
}
|
||||
|
||||
switch req.OrderBy {
|
||||
case "sale_date", "sale_count", "sale_price", "total_price":
|
||||
orderBy = req.OrderBy
|
||||
}
|
||||
|
||||
params += fmt.Sprintf("limit=%d&offset=%d&order_direction=%s",
|
||||
limit, offset, order)
|
||||
|
||||
if len(orderBy) > 0 {
|
||||
params += "&order_by=" + orderBy
|
||||
}
|
||||
|
||||
if len(req.Collection) > 0 {
|
||||
params += "&collection=" + req.Collection
|
||||
}
|
||||
|
||||
var resp domain.AssetResponse
|
||||
|
||||
if err := api.Get(uri + params, &resp); err != nil {
|
||||
return errors.InternalServerError("nft.assets", "failed to get assets: %v", err)
|
||||
}
|
||||
|
||||
for _, asset := range resp.Assets {
|
||||
if asset.Creator == nil {
|
||||
asset.Creator = &domain.User{
|
||||
User: &domain.Username{},
|
||||
}
|
||||
}
|
||||
if asset.Creator.User == nil {
|
||||
asset.Creator.User = &domain.Username{}
|
||||
}
|
||||
if asset.Owner == nil {
|
||||
asset.Owner = &domain.User{
|
||||
User: &domain.Username{},
|
||||
}
|
||||
}
|
||||
if asset.Owner.User == nil {
|
||||
asset.Owner.User = &domain.Username{}
|
||||
}
|
||||
if asset.Collection == nil {
|
||||
asset.Collection = new(domain.Collection)
|
||||
}
|
||||
if asset.Contract == nil {
|
||||
asset.Contract = new(domain.Contract)
|
||||
}
|
||||
|
||||
lastSale := new(pb.Sale)
|
||||
|
||||
if asset.LastSale != nil {
|
||||
if asset.LastSale.Transaction == nil {
|
||||
asset.LastSale.Transaction = &domain.Transaction{
|
||||
FromAccount: &domain.User{User: new(domain.Username)},
|
||||
ToAccount: &domain.User{User: new(domain.Username)},
|
||||
}
|
||||
}
|
||||
if asset.LastSale.Transaction.FromAccount == nil {
|
||||
asset.LastSale.Transaction.FromAccount = &domain.User{User: new(domain.Username)}
|
||||
}
|
||||
if asset.LastSale.Transaction.FromAccount.User == nil {
|
||||
asset.LastSale.Transaction.FromAccount.User = new(domain.Username)
|
||||
}
|
||||
if asset.LastSale.Transaction.ToAccount == nil {
|
||||
asset.LastSale.Transaction.ToAccount = &domain.User{User: new(domain.Username)}
|
||||
}
|
||||
if asset.LastSale.Transaction.ToAccount.User == nil {
|
||||
asset.LastSale.Transaction.ToAccount.User = new(domain.Username)
|
||||
}
|
||||
if asset.LastSale.PaymentToken == nil {
|
||||
asset.LastSale.PaymentToken = new(domain.Token)
|
||||
}
|
||||
|
||||
lastSale = &pb.Sale{
|
||||
AssetTokenId: asset.LastSale.Asset.TokenId,
|
||||
AssetDecimals: asset.LastSale.Asset.Decimals,
|
||||
EventType: asset.LastSale.EventType,
|
||||
EventTimestamp: asset.LastSale.EventTimestamp,
|
||||
TotalPrice: asset.LastSale.TotalPrice,
|
||||
Quantity: asset.LastSale.Quantity,
|
||||
CreatedAt: asset.LastSale.CreatedAt,
|
||||
Transaction: &pb.Transaction{
|
||||
Id: asset.LastSale.Transaction.Id,
|
||||
Timestamp: asset.LastSale.Transaction.Timestamp,
|
||||
BlockHash: asset.LastSale.Transaction.BlockHash,
|
||||
BlockNumber: asset.LastSale.Transaction.BlockNumber,
|
||||
FromAccount: &pb.User{
|
||||
Username: asset.LastSale.Transaction.FromAccount.User.Username,
|
||||
ProfileUrl: asset.LastSale.Transaction.FromAccount.ProfileUrl,
|
||||
Address: asset.LastSale.Transaction.FromAccount.Address,
|
||||
},
|
||||
ToAccount: &pb.User{
|
||||
Username: asset.LastSale.Transaction.ToAccount.User.Username,
|
||||
ProfileUrl: asset.LastSale.Transaction.ToAccount.ProfileUrl,
|
||||
Address: asset.LastSale.Transaction.ToAccount.Address,
|
||||
},
|
||||
TransactionHash: asset.LastSale.Transaction.TransactionHash,
|
||||
TransactionIndex: asset.LastSale.Transaction.TransactionIndex,
|
||||
},
|
||||
PaymentToken: &pb.Token{
|
||||
Id: asset.LastSale.PaymentToken.Id,
|
||||
Name: asset.LastSale.PaymentToken.Name,
|
||||
Symbol: asset.LastSale.PaymentToken.Symbol,
|
||||
Address: asset.LastSale.PaymentToken.Address,
|
||||
ImageUrl: asset.LastSale.PaymentToken.ImageUrl,
|
||||
Decimals: asset.LastSale.PaymentToken.Decimals,
|
||||
EthPrice: asset.LastSale.PaymentToken.EthPrice,
|
||||
UsdPrice: asset.LastSale.PaymentToken.UsdPrice,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
rsp.Assets = append(rsp.Assets, &pb.Asset{
|
||||
Name: asset.Name,
|
||||
Description: asset.Description,
|
||||
Id: asset.Id,
|
||||
TokenId: asset.TokenId,
|
||||
ImageUrl: asset.ImageUrl,
|
||||
Sales: asset.Sales,
|
||||
Permalink: asset.Permalink,
|
||||
Contract: &pb.Contract{
|
||||
Name: asset.Contract.Name,
|
||||
Description: asset.Contract.Description,
|
||||
Address: asset.Contract.Address,
|
||||
Type: asset.Contract.Type,
|
||||
CreatedAt: asset.Contract.CreatedAt,
|
||||
Owner: asset.Contract.Owner,
|
||||
Schema: asset.Contract.Schema,
|
||||
Symbol: asset.Contract.Symbol,
|
||||
PayoutAddress: asset.Contract.PayoutAddress,
|
||||
SellerFees: asset.Contract.SellerFees,
|
||||
},
|
||||
Collection: &pb.Collection{
|
||||
Name: asset.Collection.Name,
|
||||
Description: asset.Collection.Description,
|
||||
Slug: asset.Collection.Slug,
|
||||
ImageUrl: asset.Collection.ImageUrl,
|
||||
CreatedAt: asset.Collection.CreatedAt,
|
||||
PayoutAddress: asset.Collection.PayoutAddress,
|
||||
},
|
||||
Owner: &pb.User{
|
||||
Username: asset.Owner.User.Username,
|
||||
ProfileUrl: asset.Owner.ProfileUrl,
|
||||
Address: asset.Owner.Address,
|
||||
},
|
||||
Creator: &pb.User{
|
||||
Username: asset.Creator.User.Username,
|
||||
ProfileUrl: asset.Creator.ProfileUrl,
|
||||
Address: asset.Creator.Address,
|
||||
},
|
||||
LastSale: lastSale,
|
||||
Presale: asset.Presale,
|
||||
ListingDate: asset.ListingDate,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpenSea) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error {
|
||||
return errors.BadRequest("nft.create", "coming soon")
|
||||
}
|
||||
@@ -15,7 +15,7 @@ func main() {
|
||||
)
|
||||
|
||||
// Register handler
|
||||
pb.RegisterNftHandler(srv.Server(), new(handler.Nft))
|
||||
pb.RegisterNftHandler(srv.Server(), handler.New())
|
||||
|
||||
// Run service
|
||||
if err := srv.Run(); err != nil {
|
||||
|
||||
1287
nft/proto/nft.pb.go
1287
nft/proto/nft.pb.go
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,8 @@ func NewNftEndpoints() []*api.Endpoint {
|
||||
// Client API for Nft service
|
||||
|
||||
type NftService interface {
|
||||
Vote(ctx context.Context, in *VoteRequest, opts ...client.CallOption) (*VoteResponse, error)
|
||||
Assets(ctx context.Context, in *AssetsRequest, opts ...client.CallOption) (*AssetsResponse, error)
|
||||
Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error)
|
||||
}
|
||||
|
||||
type nftService struct {
|
||||
@@ -57,9 +58,19 @@ func NewNftService(name string, c client.Client) NftService {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *nftService) Vote(ctx context.Context, in *VoteRequest, opts ...client.CallOption) (*VoteResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Nft.Vote", in)
|
||||
out := new(VoteResponse)
|
||||
func (c *nftService) Assets(ctx context.Context, in *AssetsRequest, opts ...client.CallOption) (*AssetsResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Nft.Assets", in)
|
||||
out := new(AssetsResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *nftService) Create(ctx context.Context, in *CreateRequest, opts ...client.CallOption) (*CreateResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "Nft.Create", in)
|
||||
out := new(CreateResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -70,12 +81,14 @@ func (c *nftService) Vote(ctx context.Context, in *VoteRequest, opts ...client.C
|
||||
// Server API for Nft service
|
||||
|
||||
type NftHandler interface {
|
||||
Vote(context.Context, *VoteRequest, *VoteResponse) error
|
||||
Assets(context.Context, *AssetsRequest, *AssetsResponse) error
|
||||
Create(context.Context, *CreateRequest, *CreateResponse) error
|
||||
}
|
||||
|
||||
func RegisterNftHandler(s server.Server, hdlr NftHandler, opts ...server.HandlerOption) error {
|
||||
type nft interface {
|
||||
Vote(ctx context.Context, in *VoteRequest, out *VoteResponse) error
|
||||
Assets(ctx context.Context, in *AssetsRequest, out *AssetsResponse) error
|
||||
Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error
|
||||
}
|
||||
type Nft struct {
|
||||
nft
|
||||
@@ -88,6 +101,10 @@ type nftHandler struct {
|
||||
NftHandler
|
||||
}
|
||||
|
||||
func (h *nftHandler) Vote(ctx context.Context, in *VoteRequest, out *VoteResponse) error {
|
||||
return h.NftHandler.Vote(ctx, in, out)
|
||||
func (h *nftHandler) Assets(ctx context.Context, in *AssetsRequest, out *AssetsResponse) error {
|
||||
return h.NftHandler.Assets(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *nftHandler) Create(ctx context.Context, in *CreateRequest, out *CreateResponse) error {
|
||||
return h.NftHandler.Create(ctx, in, out)
|
||||
}
|
||||
|
||||
@@ -5,16 +5,144 @@ package nft;
|
||||
option go_package = "./proto;nft";
|
||||
|
||||
service Nft {
|
||||
rpc Vote(VoteRequest) returns (VoteResponse) {}
|
||||
rpc Assets(AssetsRequest) returns (AssetsResponse) {}
|
||||
rpc Create(CreateRequest) returns (CreateResponse) {}
|
||||
}
|
||||
|
||||
// Vote to have the NFT api launched faster!
|
||||
message VoteRequest {
|
||||
// optional message
|
||||
string message = 1;
|
||||
// Create your own NFT (coming soon)
|
||||
message CreateRequest {
|
||||
// name of the NFT
|
||||
string name = 1;
|
||||
// description
|
||||
string description = 2;
|
||||
// image data
|
||||
bytes image = 3;
|
||||
// data if not image
|
||||
bytes data = 4;
|
||||
}
|
||||
|
||||
message VoteResponse {
|
||||
// response message
|
||||
string message = 2;
|
||||
message CreateResponse {
|
||||
Asset asset = 1;
|
||||
}
|
||||
|
||||
message Asset {
|
||||
// id of the asset
|
||||
int32 id = 1;
|
||||
// the token id
|
||||
string token_id = 2;
|
||||
// name of the asset
|
||||
string name = 3;
|
||||
// related description
|
||||
string description = 4;
|
||||
// the image url
|
||||
string image_url = 5;
|
||||
// number of sales
|
||||
int32 sales = 6;
|
||||
// the permalink
|
||||
string permalink = 7;
|
||||
// asset contract
|
||||
Contract contract = 8;
|
||||
// associated collection
|
||||
Collection collection = 9;
|
||||
// Creator of the NFT
|
||||
User creator = 10;
|
||||
// Owner of the NFT
|
||||
User owner = 11;
|
||||
// is it a presale
|
||||
bool presale = 12;
|
||||
// last time sold
|
||||
Sale last_sale = 13;
|
||||
// listing date
|
||||
string listing_date = 14;
|
||||
}
|
||||
|
||||
message Contract {
|
||||
// name of contract
|
||||
string name = 1;
|
||||
// ethereum address
|
||||
string address = 2;
|
||||
// type of contract e.g "semi-fungible"
|
||||
string type = 3;
|
||||
// timestamp of creation
|
||||
string created_at = 4;
|
||||
// owner id
|
||||
int32 owner = 5;
|
||||
// aka "ERC1155"
|
||||
string schema = 6;
|
||||
// related symbol
|
||||
string symbol = 7;
|
||||
// description of contract
|
||||
string description = 8;
|
||||
// payout address
|
||||
string payout_address = 9;
|
||||
// seller fees
|
||||
string seller_fees = 10;
|
||||
}
|
||||
|
||||
message Collection {
|
||||
string name = 1;
|
||||
string description = 2;
|
||||
string slug = 3;
|
||||
string image_url = 4;
|
||||
string created_at = 5;
|
||||
string payout_address = 6;
|
||||
}
|
||||
|
||||
message User {
|
||||
string username = 1;
|
||||
string profile_url = 2;
|
||||
string address = 3;
|
||||
}
|
||||
|
||||
message Sale {
|
||||
string asset_token_id = 1;
|
||||
int32 asset_decimals = 2;
|
||||
string event_type = 3;
|
||||
string event_timestamp = 4;
|
||||
string total_price = 5;
|
||||
string quantity = 6;
|
||||
string created_at = 7;
|
||||
Transaction transaction = 8;
|
||||
Token payment_token = 9;
|
||||
}
|
||||
|
||||
message Transaction {
|
||||
int32 id = 1;
|
||||
string timestamp = 2;
|
||||
string block_hash = 3;
|
||||
string block_number = 4;
|
||||
User from_account = 5;
|
||||
User to_account = 6;
|
||||
string transaction_hash = 7;
|
||||
string transaction_index = 8;
|
||||
}
|
||||
|
||||
message Token {
|
||||
int32 id = 1;
|
||||
string name = 2;
|
||||
string symbol = 3;
|
||||
string address = 4;
|
||||
string image_url = 5;
|
||||
int32 decimals = 6;
|
||||
string eth_price = 7;
|
||||
string usd_price = 8;
|
||||
}
|
||||
|
||||
// Return a list of NFT assets
|
||||
message AssetsRequest {
|
||||
// limit returned assets
|
||||
int32 limit = 1;
|
||||
// offset for pagination
|
||||
int32 offset = 2;
|
||||
// order "asc" or "desc"
|
||||
string order = 3;
|
||||
// order by "sale_date", "sale_count", "sale_price", "total_price"
|
||||
string order_by = 4;
|
||||
// limit to members of a collection by slug name (case sensitive)
|
||||
string collection = 5;
|
||||
}
|
||||
|
||||
message AssetsResponse {
|
||||
// list of assets
|
||||
repeated Asset assets = 1;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "nft",
|
||||
"icon": "🪙",
|
||||
"category": "coming soon",
|
||||
"display_name": "NFTs (Coming Soon)"
|
||||
"category": "crypto",
|
||||
"display_name": "NFTs"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user