From 2c8890a3b3df901023caa820ad6e9205860972b9 Mon Sep 17 00:00:00 2001 From: Marcin Gorzynski Date: Thu, 23 Jan 2025 13:42:13 +0100 Subject: [PATCH] bump metadata proto gen --- metadata/metadata.gen.go | 3631 +++++++++++++++++++++++++++++++++++--- 1 file changed, 3412 insertions(+), 219 deletions(-) diff --git a/metadata/metadata.gen.go b/metadata/metadata.gen.go index 721428b2..30a90129 100644 --- a/metadata/metadata.gen.go +++ b/metadata/metadata.gen.go @@ -1,8 +1,8 @@ -// sequence-metadata v0.4.0 7cd2d21d284379078f35906687a348ebecb44a36 +// sequence-metadata v0.4.0 aee251b319e9f74a15e9f3a1610f9f5d201c7600 // -- -// Code generated by webrpc-gen@v0.21.0 with golang generator. DO NOT EDIT. +// Code generated by webrpc-gen@v0.21.1 with golang generator. DO NOT EDIT. // -// webrpc-gen -schema=metadata.ridl -target=golang -pkg=metadata -client -out=./clients/metadata.gen.go +// webrpc-gen -schema=metadata.ridl -target=golang -pkg=proto -server -client -out=./metadata.gen.go package metadata import ( @@ -22,7 +22,7 @@ import ( const WebrpcHeader = "Webrpc" -const WebrpcHeaderValue = "webrpc@v0.21.0;gen-golang@v0.16.0;sequence-metadata@v0.4.0" +const WebrpcHeaderValue = "webrpc@v0.21.1;gen-golang@v0.16.0;sequence-metadata@v0.4.0" // WebRPC description and code-gen version func WebRPCVersion() string { @@ -36,7 +36,7 @@ func WebRPCSchemaVersion() string { // Schema hash generated from your RIDL schema func WebRPCSchemaHash() string { - return "7cd2d21d284379078f35906687a348ebecb44a36" + return "aee251b319e9f74a15e9f3a1610f9f5d201c7600" } type WebrpcGenVersions struct { @@ -142,6 +142,51 @@ func (x *ContractType) Is(values ...ContractType) bool { return false } +type ResourceStatus uint32 + +const ( + ResourceStatus_NOT_AVAILABLE ResourceStatus = 0 + ResourceStatus_STALE ResourceStatus = 1 + ResourceStatus_AVAILABLE ResourceStatus = 2 +) + +var ResourceStatus_name = map[uint32]string{ + 0: "NOT_AVAILABLE", + 1: "STALE", + 2: "AVAILABLE", +} + +var ResourceStatus_value = map[string]uint32{ + "NOT_AVAILABLE": 0, + "STALE": 1, + "AVAILABLE": 2, +} + +func (x ResourceStatus) String() string { + return ResourceStatus_name[uint32(x)] +} + +func (x ResourceStatus) MarshalText() ([]byte, error) { + return []byte(ResourceStatus_name[uint32(x)]), nil +} + +func (x *ResourceStatus) UnmarshalText(b []byte) error { + *x = ResourceStatus(ResourceStatus_value[string(b)]) + return nil +} + +func (x *ResourceStatus) Is(values ...ResourceStatus) bool { + if x == nil { + return false + } + for _, v := range values { + if *x == v { + return true + } + } + return false +} + type PropertyType uint32 const ( @@ -291,13 +336,23 @@ type Version struct { } type RuntimeStatus struct { - HealthOK bool `json:"healthOK"` - StartTime time.Time `json:"startTime"` - Uptime uint64 `json:"uptime"` - Ver string `json:"ver"` - Branch string `json:"branch"` - CommitHash string `json:"commitHash"` - Checks *RuntimeChecks `json:"checks"` + HealthOK bool `json:"healthOK"` + StartTime time.Time `json:"startTime"` + Uptime uint64 `json:"uptime"` + UptimeString string `json:"uptimeString"` + Ver string `json:"ver"` + Branch string `json:"branch"` + CommitHash string `json:"commitHash"` + Checks *RuntimeChecks `json:"checks"` + Runnable map[string]*RunnableStatus `json:"runnable,omitempty"` +} + +type RunnableStatus struct { + Running bool `json:"running"` + Restarts int `json:"restarts"` + StartTime time.Time `json:"startTime"` + EndTime *time.Time `json:"endTime"` + LastError interface{} `json:"lastError"` } type RuntimeChecks struct { @@ -313,8 +368,10 @@ type ContractIndex struct { ContentHash uint64 `json:"contentHash,omitempty" db:"content_hash,omitempty"` Deployed bool `json:"deployed" db:"deployed"` BytecodeHash prototyp.Hash `json:"bytecodeHash" db:"bytecode_hash"` - NotFound bool `json:"notFound,omitempty"` + NotFound bool `json:"notFound,omitempty" db:"not_found"` UpdatedAt time.Time `json:"updatedAt" db:"updated_at"` + QueuedAt *time.Time `json:"queuedAt" db:"queued_at"` + Status ResourceStatus `json:"status"` } // TokenIndex is a database type to track the index of token metadata which @@ -329,6 +386,7 @@ type TokenIndex struct { LastFetched *time.Time `json:"lastFetched,omitempty" db:"last_fetched"` FetchCount *uint8 `json:"fetchCount,omitempty" db:"fetch_count"` UpdatedAt time.Time `json:"updatedAt" db:"updated_at"` + QueuedAt *time.Time `json:"queuedAt"` } // ContractInfo is RPC type for responding to clients that represents @@ -346,19 +404,23 @@ type ContractInfo struct { Extensions *ContractInfoExtensions `json:"extensions" cbor:"-"` ContentHash uint64 `json:"-" cbor:"-"` UpdatedAt time.Time `json:"updatedAt" cbor:"-"` + NotFound bool `json:"notFound"` + QueuedAt *time.Time `json:"queuedAt"` + Status ResourceStatus `json:"status"` } type ContractInfoExtensions struct { - Link string `json:"link" cbor:"-"` - Description string `json:"description" cbor:"-"` - OgImage string `json:"ogImage" cbor:"-"` - OgName string `json:"ogName" cbor:"-"` - OriginChainID uint64 `json:"originChainId" cbor:"-"` - OriginAddress string `json:"originAddress" cbor:"-"` - Blacklist bool `json:"blacklist,omitempty" cbor:"-"` - Verified bool `json:"verified" cbor:"-"` - VerifiedBy string `json:"verifiedBy,omitempty" cbor:"-"` - Featured bool `json:"featured,omitempty" cbor:"-"` + Link string `json:"link" cbor:"-"` + Description string `json:"description" cbor:"-"` + Categories []string `json:"categories,omitempty" cbor:"-"` + OgImage string `json:"ogImage" cbor:"-"` + OgName string `json:"ogName" cbor:"-"` + OriginChainID uint64 `json:"originChainId" cbor:"-"` + OriginAddress string `json:"originAddress" cbor:"-"` + Blacklist bool `json:"blacklist,omitempty" cbor:"-"` + Verified bool `json:"verified" cbor:"-"` + VerifiedBy string `json:"verifiedBy,omitempty" cbor:"-"` + Featured bool `json:"featured,omitempty" cbor:"-"` } // TokenMetadata based on 721/1155 standards, as well including some @@ -397,7 +459,10 @@ type TokenMetadata struct { Decimals *uint64 `json:"decimals,omitempty" cbor:"-"` UpdatedAt time.Time `json:"updatedAt" cbor:"-"` // Assets associated to this token metadata - Assets []*Asset `json:"assets,omitempty" cbor:"-"` + Assets []*Asset `json:"assets,omitempty" cbor:"-"` + Status ResourceStatus `json:"status"` + QueuedAt *time.Time `json:"queuedAt"` + LastFetched *time.Time `json:"lastFetched,omitempty"` } // PropertyFilter @@ -602,17 +667,17 @@ var ( "/rpc/Metadata/GetTokenRefreshStatus": { Name: "GetTokenRefreshStatus", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/GetTokenRefreshResult": { Name: "GetTokenRefreshResult", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/CancelRefreshJob": { Name: "CancelRefreshJob", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/RefreshContractInfo": { Name: "RefreshContractInfo", @@ -687,52 +752,52 @@ var ( "/rpc/Metadata/GetNiftyswapTokenQuantity": { Name: "GetNiftyswapTokenQuantity", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/GetNiftyswapUnitPrices": { Name: "GetNiftyswapUnitPrices", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/GetNiftyswapUnitPricesWithQuantities": { Name: "GetNiftyswapUnitPricesWithQuantities", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/AddContractToMintMonitor": { Name: "AddContractToMintMonitor", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/RemoveContractFromMintMonitor": { Name: "RemoveContractFromMintMonitor", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/MintMonitorJobStatus": { Name: "MintMonitorJobStatus", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/MintMonitorTriggerJob": { Name: "MintMonitorTriggerJob", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/SyncContractTokens": { Name: "SyncContractTokens", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/AbortContractSync": { Name: "AbortContractSync", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/ContractSyncJobStatus": { Name: "ContractSyncJobStatus", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Metadata/DirectoryGetNetworks": { Name: "DirectoryGetNetworks", @@ -747,7 +812,7 @@ var ( "/rpc/Metadata/DirectorySearchCollections": { Name: "DirectorySearchCollections", Service: "Metadata", - Annotations: map[string]string{}, + Annotations: map[string]string{"internal": ""}, }, "/rpc/Collections/CreateCollection": { Name: "CreateCollection", @@ -953,194 +1018,3313 @@ var WebRPCServices = map[string][]string{ }, } -// -// Server types -// +// +// Server types +// + +type Metadata interface { + Ping(ctx context.Context) (bool, error) + Version(ctx context.Context) (*Version, error) + RuntimeStatus(ctx context.Context) (*RuntimeStatus, error) + // GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs + GetTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) ([]*TokenMetadata, error) + // Deprecated -> Use RefreshContractInfo, RefreshContractTokens or RefreshAllContractTokens + // Deprecated: + RefreshTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) + // Deprecated -> RefreshContractTokens or RefreshAllContractTokens + // Deprecated: + EnqueueTokensForRefresh(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) + GetTokenRefreshStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) + GetTokenRefreshResult(ctx context.Context, taskId uint64) (*TaskStatus, map[string]bool, map[string]string, error) + CancelRefreshJob(ctx context.Context, taskId uint64) (bool, error) + RefreshContractInfo(ctx context.Context, chainHandle string, contractAddress string) error + RefreshContractTokens(ctx context.Context, chainHandle string, contractAddress string, tokenIDs []string) (*Task, error) + RefreshAllContractTokens(ctx context.Context, chainHandle string, contractAddress string) (*Task, uint64, error) + // GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs + // where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata + // + // Note, we limit each request to 50 contracts max and 50 tokens max per contract. + GetTokenMetadataBatch(ctx context.Context, chainID string, contractTokenMap map[string][]string) (map[string][]*TokenMetadata, error) + SearchTokenMetadata(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []*TokenMetadata, error) + SearchTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) + TokenCollectionFilters(ctx context.Context, chainID string, contractAddress string) ([]*PropertyFilter, error) + // Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists + GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, *Task, error) + GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, *Task, error) + // Search Contract Info across all chains token-lists. Similar to GetContractInfo above, + // but it will traverse all chains and results from all. + SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) + // map of contractAddress :: []ContractInfo + SearchContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) + // Deprecated: Use SearchTokens() and SearchContracts() instead. + // Deprecated: + SearchMetadata(ctx context.Context, filter string, chainID *string, types []ContractType, excludeTokenMetadata *bool) ([]*TokenMetadata, []*ContractInfo, error) + SearchTokens(ctx context.Context, q string, chainID *string, page *Page) ([]*TokenMetadata, *Page, error) + SearchContracts(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) + // Niftyswap querying data + GetNiftyswapTokenQuantity(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) (map[string]string, error) + // map of tokenID :: quantity + GetNiftyswapUnitPrices(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]string, error) + // map of tokenID :: price + GetNiftyswapUnitPricesWithQuantities(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]*GetNiftyswapUnitPricesResponse, error) + AddContractToMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) + RemoveContractFromMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) + MintMonitorJobStatus(ctx context.Context, chainID string, contractAddress string) (*Task, error) + MintMonitorTriggerJob(ctx context.Context, chainID string, contractAddress string) (bool, error) + SyncContractTokens(ctx context.Context, chainID string, contractAddress string) (uint64, error) + AbortContractSync(ctx context.Context, taskID uint64) (bool, error) + ContractSyncJobStatus(ctx context.Context, taskID uint64) (*Task, *Task, error) + // Token Directory. + // NOTE: this only searches the 'token-directory' items. Use 'SearchContracts' or 'SearchTokens' for everything else. + DirectoryGetNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, error) + DirectoryGetCollections(ctx context.Context, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + DirectorySearchCollections(ctx context.Context, query string, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) +} + +type Collections interface { + CreateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) + GetCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) + ListCollections(ctx context.Context, projectId *uint64, page *Page) (*Page, []*Collection, error) + UpdateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) + DeleteCollection(ctx context.Context, projectId *uint64, collectionId uint64) (bool, error) + PublishCollection(ctx context.Context, projectId *uint64, collectionId uint64, recursive *bool) (*Collection, error) + UnpublishCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) + CreateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (*ContractCollection, error) + GetContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (*ContractCollection, error) + ListContractCollections(ctx context.Context, projectId uint64, collectionId *uint64, page *Page) ([]*ContractCollection, []*Collection, *Page, error) + UpdateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (bool, error) + DeleteContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (bool, error) + CreateToken(ctx context.Context, projectId *uint64, collectionId uint64, token *TokenMetadata, private *bool) (*TokenMetadata, []*Asset, error) + GetToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (*TokenMetadata, []*Asset, error) + ListTokens(ctx context.Context, projectId *uint64, collectionId uint64, page *Page) (*Page, []*TokenMetadata, error) + UpdateToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string, token *TokenMetadata, private *bool) (*TokenMetadata, error) + DeleteToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (bool, error) + CreateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) + GetAsset(ctx context.Context, projectId *uint64, assetId uint64) (*Asset, error) + UpdateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) + DeleteAsset(ctx context.Context, projectId *uint64, assetId uint64) (bool, error) +} + +type Admin interface { + AddContractsToTokenDirectory(ctx context.Context, contracts []*ContractInfo, featureIndexes []uint8) (bool, error) + RemoveContractsFromTokenDirectory(ctx context.Context, chainHandle string, contracts []string) (bool, error) + ModifyFeatureIndex(ctx context.Context, chainHandle string, contractAddress string, featured uint8) (bool, error) + GetFeatureIndex(ctx context.Context, chainHandle string, contractAddress string) (uint8, error) + ListTokenDirectory(ctx context.Context, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) (*Page, []*ContractInfo, error) +} + +// +// Client types +// + +type MetadataClient interface { + Ping(ctx context.Context) (bool, error) + Version(ctx context.Context) (*Version, error) + RuntimeStatus(ctx context.Context) (*RuntimeStatus, error) + // GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs + GetTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) ([]*TokenMetadata, error) + // Deprecated -> Use RefreshContractInfo, RefreshContractTokens or RefreshAllContractTokens + // Deprecated: + RefreshTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) + // Deprecated -> RefreshContractTokens or RefreshAllContractTokens + // Deprecated: + EnqueueTokensForRefresh(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) + GetTokenRefreshStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) + GetTokenRefreshResult(ctx context.Context, taskId uint64) (*TaskStatus, map[string]bool, map[string]string, error) + CancelRefreshJob(ctx context.Context, taskId uint64) (bool, error) + RefreshContractInfo(ctx context.Context, chainHandle string, contractAddress string) error + RefreshContractTokens(ctx context.Context, chainHandle string, contractAddress string, tokenIDs []string) (*Task, error) + RefreshAllContractTokens(ctx context.Context, chainHandle string, contractAddress string) (*Task, uint64, error) + // GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs + // where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata + // + // Note, we limit each request to 50 contracts max and 50 tokens max per contract. + GetTokenMetadataBatch(ctx context.Context, chainID string, contractTokenMap map[string][]string) (map[string][]*TokenMetadata, error) + SearchTokenMetadata(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []*TokenMetadata, error) + SearchTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) + TokenCollectionFilters(ctx context.Context, chainID string, contractAddress string) ([]*PropertyFilter, error) + // Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists + GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, *Task, error) + GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, *Task, error) + // Search Contract Info across all chains token-lists. Similar to GetContractInfo above, + // but it will traverse all chains and results from all. + SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) + // map of contractAddress :: []ContractInfo + SearchContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) + // Deprecated: Use SearchTokens() and SearchContracts() instead. + // Deprecated: + SearchMetadata(ctx context.Context, filter string, chainID *string, types []ContractType, excludeTokenMetadata *bool) ([]*TokenMetadata, []*ContractInfo, error) + SearchTokens(ctx context.Context, q string, chainID *string, page *Page) ([]*TokenMetadata, *Page, error) + SearchContracts(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) + // Niftyswap querying data + GetNiftyswapTokenQuantity(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) (map[string]string, error) + // map of tokenID :: quantity + GetNiftyswapUnitPrices(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]string, error) + // map of tokenID :: price + GetNiftyswapUnitPricesWithQuantities(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]*GetNiftyswapUnitPricesResponse, error) + AddContractToMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) + RemoveContractFromMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) + MintMonitorJobStatus(ctx context.Context, chainID string, contractAddress string) (*Task, error) + MintMonitorTriggerJob(ctx context.Context, chainID string, contractAddress string) (bool, error) + SyncContractTokens(ctx context.Context, chainID string, contractAddress string) (uint64, error) + AbortContractSync(ctx context.Context, taskID uint64) (bool, error) + ContractSyncJobStatus(ctx context.Context, taskID uint64) (*Task, *Task, error) + // Token Directory. + // NOTE: this only searches the 'token-directory' items. Use 'SearchContracts' or 'SearchTokens' for everything else. + DirectoryGetNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, error) + DirectoryGetCollections(ctx context.Context, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + DirectorySearchCollections(ctx context.Context, query string, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) +} + +type CollectionsClient interface { + CreateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) + GetCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) + ListCollections(ctx context.Context, projectId *uint64, page *Page) (*Page, []*Collection, error) + UpdateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) + DeleteCollection(ctx context.Context, projectId *uint64, collectionId uint64) (bool, error) + PublishCollection(ctx context.Context, projectId *uint64, collectionId uint64, recursive *bool) (*Collection, error) + UnpublishCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) + CreateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (*ContractCollection, error) + GetContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (*ContractCollection, error) + ListContractCollections(ctx context.Context, projectId uint64, collectionId *uint64, page *Page) ([]*ContractCollection, []*Collection, *Page, error) + UpdateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (bool, error) + DeleteContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (bool, error) + CreateToken(ctx context.Context, projectId *uint64, collectionId uint64, token *TokenMetadata, private *bool) (*TokenMetadata, []*Asset, error) + GetToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (*TokenMetadata, []*Asset, error) + ListTokens(ctx context.Context, projectId *uint64, collectionId uint64, page *Page) (*Page, []*TokenMetadata, error) + UpdateToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string, token *TokenMetadata, private *bool) (*TokenMetadata, error) + DeleteToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (bool, error) + CreateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) + GetAsset(ctx context.Context, projectId *uint64, assetId uint64) (*Asset, error) + UpdateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) + DeleteAsset(ctx context.Context, projectId *uint64, assetId uint64) (bool, error) +} + +type AdminClient interface { + AddContractsToTokenDirectory(ctx context.Context, contracts []*ContractInfo, featureIndexes []uint8) (bool, error) + RemoveContractsFromTokenDirectory(ctx context.Context, chainHandle string, contracts []string) (bool, error) + ModifyFeatureIndex(ctx context.Context, chainHandle string, contractAddress string, featured uint8) (bool, error) + GetFeatureIndex(ctx context.Context, chainHandle string, contractAddress string) (uint8, error) + ListTokenDirectory(ctx context.Context, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) (*Page, []*ContractInfo, error) +} + +// +// Server +// + +type WebRPCServer interface { + http.Handler +} + +type metadataServer struct { + Metadata + OnError func(r *http.Request, rpcErr *WebRPCError) + OnRequest func(w http.ResponseWriter, r *http.Request) error +} + +func NewMetadataServer(svc Metadata) *metadataServer { + return &metadataServer{ + Metadata: svc, + } +} + +func (s *metadataServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + defer func() { + // In case of a panic, serve a HTTP 500 error and then panic. + if rr := recover(); rr != nil { + s.sendErrorJSON(w, r, ErrWebrpcServerPanic.WithCausef("%v", rr)) + panic(rr) + } + }() + + w.Header().Set(WebrpcHeader, WebrpcHeaderValue) + + ctx := r.Context() + ctx = context.WithValue(ctx, HTTPResponseWriterCtxKey, w) + ctx = context.WithValue(ctx, HTTPRequestCtxKey, r) + ctx = context.WithValue(ctx, ServiceNameCtxKey, "Metadata") + + r = r.WithContext(ctx) + + var handler func(ctx context.Context, w http.ResponseWriter, r *http.Request) + switch r.URL.Path { + case "/rpc/Metadata/Ping": + handler = s.servePingJSON + case "/rpc/Metadata/Version": + handler = s.serveVersionJSON + case "/rpc/Metadata/RuntimeStatus": + handler = s.serveRuntimeStatusJSON + case "/rpc/Metadata/GetTokenMetadata": + handler = s.serveGetTokenMetadataJSON + case "/rpc/Metadata/RefreshTokenMetadata": + handler = s.serveRefreshTokenMetadataJSON + case "/rpc/Metadata/EnqueueTokensForRefresh": + handler = s.serveEnqueueTokensForRefreshJSON + case "/rpc/Metadata/GetTokenRefreshStatus": + handler = s.serveGetTokenRefreshStatusJSON + case "/rpc/Metadata/GetTokenRefreshResult": + handler = s.serveGetTokenRefreshResultJSON + case "/rpc/Metadata/CancelRefreshJob": + handler = s.serveCancelRefreshJobJSON + case "/rpc/Metadata/RefreshContractInfo": + handler = s.serveRefreshContractInfoJSON + case "/rpc/Metadata/RefreshContractTokens": + handler = s.serveRefreshContractTokensJSON + case "/rpc/Metadata/RefreshAllContractTokens": + handler = s.serveRefreshAllContractTokensJSON + case "/rpc/Metadata/GetTokenMetadataBatch": + handler = s.serveGetTokenMetadataBatchJSON + case "/rpc/Metadata/SearchTokenMetadata": + handler = s.serveSearchTokenMetadataJSON + case "/rpc/Metadata/SearchTokenIDs": + handler = s.serveSearchTokenIDsJSON + case "/rpc/Metadata/TokenCollectionFilters": + handler = s.serveTokenCollectionFiltersJSON + case "/rpc/Metadata/GetContractInfo": + handler = s.serveGetContractInfoJSON + case "/rpc/Metadata/GetContractInfoBatch": + handler = s.serveGetContractInfoBatchJSON + case "/rpc/Metadata/SearchContractInfo": + handler = s.serveSearchContractInfoJSON + case "/rpc/Metadata/SearchContractInfoBatch": + handler = s.serveSearchContractInfoBatchJSON + case "/rpc/Metadata/SearchMetadata": + handler = s.serveSearchMetadataJSON + case "/rpc/Metadata/SearchTokens": + handler = s.serveSearchTokensJSON + case "/rpc/Metadata/SearchContracts": + handler = s.serveSearchContractsJSON + case "/rpc/Metadata/GetNiftyswapTokenQuantity": + handler = s.serveGetNiftyswapTokenQuantityJSON + case "/rpc/Metadata/GetNiftyswapUnitPrices": + handler = s.serveGetNiftyswapUnitPricesJSON + case "/rpc/Metadata/GetNiftyswapUnitPricesWithQuantities": + handler = s.serveGetNiftyswapUnitPricesWithQuantitiesJSON + case "/rpc/Metadata/AddContractToMintMonitor": + handler = s.serveAddContractToMintMonitorJSON + case "/rpc/Metadata/RemoveContractFromMintMonitor": + handler = s.serveRemoveContractFromMintMonitorJSON + case "/rpc/Metadata/MintMonitorJobStatus": + handler = s.serveMintMonitorJobStatusJSON + case "/rpc/Metadata/MintMonitorTriggerJob": + handler = s.serveMintMonitorTriggerJobJSON + case "/rpc/Metadata/SyncContractTokens": + handler = s.serveSyncContractTokensJSON + case "/rpc/Metadata/AbortContractSync": + handler = s.serveAbortContractSyncJSON + case "/rpc/Metadata/ContractSyncJobStatus": + handler = s.serveContractSyncJobStatusJSON + case "/rpc/Metadata/DirectoryGetNetworks": + handler = s.serveDirectoryGetNetworksJSON + case "/rpc/Metadata/DirectoryGetCollections": + handler = s.serveDirectoryGetCollectionsJSON + case "/rpc/Metadata/DirectorySearchCollections": + handler = s.serveDirectorySearchCollectionsJSON + default: + err := ErrWebrpcBadRoute.WithCausef("no WebRPC method defined for path %v", r.URL.Path) + s.sendErrorJSON(w, r, err) + return + } + + if r.Method != "POST" { + w.Header().Add("Allow", "POST") // RFC 9110. + err := ErrWebrpcBadMethod.WithCausef("unsupported method %v (only POST is allowed)", r.Method) + s.sendErrorJSON(w, r, err) + return + } + + contentType := r.Header.Get("Content-Type") + if i := strings.Index(contentType, ";"); i >= 0 { + contentType = contentType[:i] + } + contentType = strings.TrimSpace(strings.ToLower(contentType)) + + switch contentType { + case "application/json": + if s.OnRequest != nil { + if err := s.OnRequest(w, r); err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + } + + handler(ctx, w, r) + default: + err := ErrWebrpcBadRequest.WithCausef("unsupported Content-Type %q (only application/json is allowed)", r.Header.Get("Content-Type")) + s.sendErrorJSON(w, r, err) + } +} + +func (s *metadataServer) servePingJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "Ping") + + // Call service method implementation. + ret0, err := s.Metadata.Ping(ctx) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"status"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveVersionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "Version") + + // Call service method implementation. + ret0, err := s.Metadata.Version(ctx) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Version `json:"version"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveRuntimeStatusJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RuntimeStatus") + + // Call service method implementation. + ret0, err := s.Metadata.RuntimeStatus(ctx) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *RuntimeStatus `json:"status"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetTokenMetadataJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetTokenMetadata") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.GetTokenMetadata(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveRefreshTokenMetadataJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RefreshTokenMetadata") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + Arg3 *bool `json:"refreshAll"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.RefreshTokenMetadata(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 uint64 `json:"taskId"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveEnqueueTokensForRefreshJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "EnqueueTokensForRefresh") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + Arg3 *bool `json:"refreshAll"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.EnqueueTokensForRefresh(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 uint64 `json:"taskId"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetTokenRefreshStatusJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetTokenRefreshStatus") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"taskId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.GetTokenRefreshStatus(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *TaskStatus `json:"status"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetTokenRefreshResultJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetTokenRefreshResult") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"taskId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, ret2, err := s.Metadata.GetTokenRefreshResult(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *TaskStatus `json:"status"` + Ret1 map[string]bool `json:"tokens"` + Ret2 map[string]string `json:"failureReasons"` + }{ret0, ret1, ret2} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveCancelRefreshJobJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "CancelRefreshJob") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"taskId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.CancelRefreshJob(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveRefreshContractInfoJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RefreshContractInfo") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + err = s.Metadata.RefreshContractInfo(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write([]byte("{}")) +} + +func (s *metadataServer) serveRefreshContractTokensJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RefreshContractTokens") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.RefreshContractTokens(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Task `json:"task"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveRefreshAllContractTokensJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RefreshAllContractTokens") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.RefreshAllContractTokens(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Task `json:"task"` + Ret1 uint64 `json:"retryAfter"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetTokenMetadataBatchJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetTokenMetadataBatch") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 map[string][]string `json:"contractTokenMap"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.GetTokenMetadataBatch(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 map[string][]*TokenMetadata `json:"contractTokenMetadata"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchTokenMetadataJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchTokenMetadata") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *Filter `json:"filter"` + Arg3 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.SearchTokenMetadata(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Page `json:"page"` + Ret1 []*TokenMetadata `json:"tokenMetadata"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchTokenIDsJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchTokenIDs") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *Filter `json:"filter"` + Arg3 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.SearchTokenIDs(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Page `json:"page"` + Ret1 []string `json:"tokenIds"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveTokenCollectionFiltersJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "TokenCollectionFilters") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.TokenCollectionFilters(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*PropertyFilter `json:"filters"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetContractInfoJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetContractInfo") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.GetContractInfo(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *ContractInfo `json:"contractInfo"` + Ret1 *Task `json:"task"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetContractInfoBatchJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetContractInfoBatch") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 []string `json:"contractAddresses"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.GetContractInfoBatch(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 map[string]*ContractInfo `json:"contractInfoMap"` + Ret1 *Task `json:"task"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchContractInfoJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchContractInfo") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.SearchContractInfo(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*ContractInfo `json:"contractInfoList"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchContractInfoBatchJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchContractInfoBatch") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 []string `json:"contractAddresses"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.SearchContractInfoBatch(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 map[string][]*ContractInfo `json:"contractInfoByChain"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchMetadataJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchMetadata") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"filter"` + Arg1 *string `json:"chainID"` + Arg2 []ContractType `json:"types"` + Arg3 *bool `json:"excludeTokenMetadata"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.SearchMetadata(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + Ret1 []*ContractInfo `json:"contractInfo"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchTokensJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchTokens") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"q"` + Arg1 *string `json:"chainID"` + Arg2 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.SearchTokens(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + Ret1 *Page `json:"nextPage"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSearchContractsJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SearchContracts") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"q"` + Arg1 *string `json:"chainID"` + Arg2 []string `json:"chainIDs"` + Arg3 []ContractType `json:"types"` + Arg4 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.SearchContracts(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3, reqPayload.Arg4) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*ContractInfo `json:"contractInfo"` + Ret1 *Page `json:"nextPage"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetNiftyswapTokenQuantityJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetNiftyswapTokenQuantity") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.GetNiftyswapTokenQuantity(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 map[string]string `json:"quantity"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetNiftyswapUnitPricesJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetNiftyswapUnitPrices") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *GetNiftyswapUnitPricesRequest `json:"req"` + Arg3 bool `json:"fresh"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.GetNiftyswapUnitPrices(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 map[string]string `json:"prices"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveGetNiftyswapUnitPricesWithQuantitiesJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetNiftyswapUnitPricesWithQuantities") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *GetNiftyswapUnitPricesRequest `json:"req"` + Arg3 bool `json:"fresh"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.GetNiftyswapUnitPricesWithQuantities(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 map[string]*GetNiftyswapUnitPricesResponse `json:"prices"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveAddContractToMintMonitorJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "AddContractToMintMonitor") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.AddContractToMintMonitor(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveRemoveContractFromMintMonitorJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RemoveContractFromMintMonitor") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.RemoveContractFromMintMonitor(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveMintMonitorJobStatusJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "MintMonitorJobStatus") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.MintMonitorJobStatus(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Task `json:"task"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveMintMonitorTriggerJobJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "MintMonitorTriggerJob") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.MintMonitorTriggerJob(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveSyncContractTokensJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "SyncContractTokens") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.SyncContractTokens(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 uint64 `json:"taskID"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveAbortContractSyncJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "AbortContractSync") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"taskID"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.AbortContractSync(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveContractSyncJobStatusJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "ContractSyncJobStatus") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"taskID"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.ContractSyncJobStatus(ctx, reqPayload.Arg0) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Task `json:"refreshTask"` + Ret1 *Task `json:"syncTask"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveDirectoryGetNetworksJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DirectoryGetNetworks") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *bool `json:"includeTestnets"` + Arg1 *bool `json:"onlyFeatured"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Metadata.DirectoryGetNetworks(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []uint64 `json:"networks"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveDirectoryGetCollectionsJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DirectoryGetCollections") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"chainId"` + Arg1 *bool `json:"includeTestnets"` + Arg2 *bool `json:"onlyFeatured"` + Arg3 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.DirectoryGetCollections(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*ContractInfo `json:"collections"` + Ret1 *Page `json:"page"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) serveDirectorySearchCollectionsJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DirectorySearchCollections") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"query"` + Arg1 *uint64 `json:"chainId"` + Arg2 *bool `json:"includeTestnets"` + Arg3 *bool `json:"onlyFeatured"` + Arg4 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Metadata.DirectorySearchCollections(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3, reqPayload.Arg4) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*ContractInfo `json:"collections"` + Ret1 *Page `json:"page"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *metadataServer) sendErrorJSON(w http.ResponseWriter, r *http.Request, rpcErr WebRPCError) { + if s.OnError != nil { + s.OnError(r, &rpcErr) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(rpcErr.HTTPStatus) + + respBody, _ := json.Marshal(rpcErr) + w.Write(respBody) +} + +type collectionsServer struct { + Collections + OnError func(r *http.Request, rpcErr *WebRPCError) + OnRequest func(w http.ResponseWriter, r *http.Request) error +} + +func NewCollectionsServer(svc Collections) *collectionsServer { + return &collectionsServer{ + Collections: svc, + } +} + +func (s *collectionsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + defer func() { + // In case of a panic, serve a HTTP 500 error and then panic. + if rr := recover(); rr != nil { + s.sendErrorJSON(w, r, ErrWebrpcServerPanic.WithCausef("%v", rr)) + panic(rr) + } + }() + + w.Header().Set(WebrpcHeader, WebrpcHeaderValue) + + ctx := r.Context() + ctx = context.WithValue(ctx, HTTPResponseWriterCtxKey, w) + ctx = context.WithValue(ctx, HTTPRequestCtxKey, r) + ctx = context.WithValue(ctx, ServiceNameCtxKey, "Collections") + + r = r.WithContext(ctx) + + var handler func(ctx context.Context, w http.ResponseWriter, r *http.Request) + switch r.URL.Path { + case "/rpc/Collections/CreateCollection": + handler = s.serveCreateCollectionJSON + case "/rpc/Collections/GetCollection": + handler = s.serveGetCollectionJSON + case "/rpc/Collections/ListCollections": + handler = s.serveListCollectionsJSON + case "/rpc/Collections/UpdateCollection": + handler = s.serveUpdateCollectionJSON + case "/rpc/Collections/DeleteCollection": + handler = s.serveDeleteCollectionJSON + case "/rpc/Collections/PublishCollection": + handler = s.servePublishCollectionJSON + case "/rpc/Collections/UnpublishCollection": + handler = s.serveUnpublishCollectionJSON + case "/rpc/Collections/CreateContractCollection": + handler = s.serveCreateContractCollectionJSON + case "/rpc/Collections/GetContractCollection": + handler = s.serveGetContractCollectionJSON + case "/rpc/Collections/ListContractCollections": + handler = s.serveListContractCollectionsJSON + case "/rpc/Collections/UpdateContractCollection": + handler = s.serveUpdateContractCollectionJSON + case "/rpc/Collections/DeleteContractCollection": + handler = s.serveDeleteContractCollectionJSON + case "/rpc/Collections/CreateToken": + handler = s.serveCreateTokenJSON + case "/rpc/Collections/GetToken": + handler = s.serveGetTokenJSON + case "/rpc/Collections/ListTokens": + handler = s.serveListTokensJSON + case "/rpc/Collections/UpdateToken": + handler = s.serveUpdateTokenJSON + case "/rpc/Collections/DeleteToken": + handler = s.serveDeleteTokenJSON + case "/rpc/Collections/CreateAsset": + handler = s.serveCreateAssetJSON + case "/rpc/Collections/GetAsset": + handler = s.serveGetAssetJSON + case "/rpc/Collections/UpdateAsset": + handler = s.serveUpdateAssetJSON + case "/rpc/Collections/DeleteAsset": + handler = s.serveDeleteAssetJSON + default: + err := ErrWebrpcBadRoute.WithCausef("no WebRPC method defined for path %v", r.URL.Path) + s.sendErrorJSON(w, r, err) + return + } + + if r.Method != "POST" { + w.Header().Add("Allow", "POST") // RFC 9110. + err := ErrWebrpcBadMethod.WithCausef("unsupported method %v (only POST is allowed)", r.Method) + s.sendErrorJSON(w, r, err) + return + } + + contentType := r.Header.Get("Content-Type") + if i := strings.Index(contentType, ";"); i >= 0 { + contentType = contentType[:i] + } + contentType = strings.TrimSpace(strings.ToLower(contentType)) + + switch contentType { + case "application/json": + if s.OnRequest != nil { + if err := s.OnRequest(w, r); err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + } + + handler(ctx, w, r) + default: + err := ErrWebrpcBadRequest.WithCausef("unsupported Content-Type %q (only application/json is allowed)", r.Header.Get("Content-Type")) + s.sendErrorJSON(w, r, err) + } +} + +func (s *collectionsServer) serveCreateCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "CreateCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Collection `json:"collection"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.CreateCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Collection `json:"collection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveGetCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.GetCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Collection `json:"collection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveListCollectionsJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "ListCollections") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Collections.ListCollections(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Page `json:"page"` + Ret1 []*Collection `json:"collections"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveUpdateCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "UpdateCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Collection `json:"collection"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.UpdateCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Collection `json:"collection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveDeleteCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DeleteCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.DeleteCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"status"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) servePublishCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "PublishCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 *bool `json:"recursive"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.PublishCollection(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Collection `json:"collection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveUnpublishCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "UnpublishCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.UnpublishCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Collection `json:"collection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveCreateContractCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "CreateContractCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"projectId"` + Arg1 *ContractCollection `json:"contractCollection"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.CreateContractCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *ContractCollection `json:"contractCollection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveGetContractCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetContractCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"projectId"` + Arg1 uint64 `json:"chainId"` + Arg2 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.GetContractCollection(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *ContractCollection `json:"contractCollection"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveListContractCollectionsJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "ListContractCollections") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"projectId"` + Arg1 *uint64 `json:"collectionId"` + Arg2 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, ret2, err := s.Collections.ListContractCollections(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 []*ContractCollection `json:"contractCollections"` + Ret1 []*Collection `json:"collections"` + Ret2 *Page `json:"page"` + }{ret0, ret1, ret2} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveUpdateContractCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "UpdateContractCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"projectId"` + Arg1 *ContractCollection `json:"contractCollection"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.UpdateContractCollection(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveDeleteContractCollectionJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DeleteContractCollection") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 uint64 `json:"projectId"` + Arg1 uint64 `json:"chainId"` + Arg2 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.DeleteContractCollection(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveCreateTokenJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "CreateToken") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 *TokenMetadata `json:"token"` + Arg3 *bool `json:"private"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Collections.CreateToken(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *TokenMetadata `json:"token"` + Ret1 []*Asset `json:"assets"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveGetTokenJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetToken") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 string `json:"tokenId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Collections.GetToken(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *TokenMetadata `json:"token"` + Ret1 []*Asset `json:"assets"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveListTokensJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "ListTokens") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Collections.ListTokens(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Page `json:"page"` + Ret1 []*TokenMetadata `json:"tokens"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveUpdateTokenJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "UpdateToken") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 string `json:"tokenId"` + Arg3 *TokenMetadata `json:"token"` + Arg4 *bool `json:"private"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.UpdateToken(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3, reqPayload.Arg4) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *TokenMetadata `json:"token"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveDeleteTokenJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DeleteToken") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 string `json:"tokenId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.DeleteToken(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"status"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveCreateAssetJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "CreateAsset") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Asset `json:"asset"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.CreateAsset(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Asset `json:"asset"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveGetAssetJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetAsset") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"assetId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.GetAsset(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Asset `json:"asset"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveUpdateAssetJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "UpdateAsset") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Asset `json:"asset"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.UpdateAsset(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Asset `json:"asset"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) serveDeleteAssetJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "DeleteAsset") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"assetId"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Collections.DeleteAsset(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"status"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *collectionsServer) sendErrorJSON(w http.ResponseWriter, r *http.Request, rpcErr WebRPCError) { + if s.OnError != nil { + s.OnError(r, &rpcErr) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(rpcErr.HTTPStatus) + + respBody, _ := json.Marshal(rpcErr) + w.Write(respBody) +} + +type adminServer struct { + Admin + OnError func(r *http.Request, rpcErr *WebRPCError) + OnRequest func(w http.ResponseWriter, r *http.Request) error +} + +func NewAdminServer(svc Admin) *adminServer { + return &adminServer{ + Admin: svc, + } +} + +func (s *adminServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + defer func() { + // In case of a panic, serve a HTTP 500 error and then panic. + if rr := recover(); rr != nil { + s.sendErrorJSON(w, r, ErrWebrpcServerPanic.WithCausef("%v", rr)) + panic(rr) + } + }() + + w.Header().Set(WebrpcHeader, WebrpcHeaderValue) + + ctx := r.Context() + ctx = context.WithValue(ctx, HTTPResponseWriterCtxKey, w) + ctx = context.WithValue(ctx, HTTPRequestCtxKey, r) + ctx = context.WithValue(ctx, ServiceNameCtxKey, "Admin") + + r = r.WithContext(ctx) + + var handler func(ctx context.Context, w http.ResponseWriter, r *http.Request) + switch r.URL.Path { + case "/rpc/Admin/AddContractsToTokenDirectory": + handler = s.serveAddContractsToTokenDirectoryJSON + case "/rpc/Admin/RemoveContractsFromTokenDirectory": + handler = s.serveRemoveContractsFromTokenDirectoryJSON + case "/rpc/Admin/ModifyFeatureIndex": + handler = s.serveModifyFeatureIndexJSON + case "/rpc/Admin/GetFeatureIndex": + handler = s.serveGetFeatureIndexJSON + case "/rpc/Admin/ListTokenDirectory": + handler = s.serveListTokenDirectoryJSON + default: + err := ErrWebrpcBadRoute.WithCausef("no WebRPC method defined for path %v", r.URL.Path) + s.sendErrorJSON(w, r, err) + return + } + + if r.Method != "POST" { + w.Header().Add("Allow", "POST") // RFC 9110. + err := ErrWebrpcBadMethod.WithCausef("unsupported method %v (only POST is allowed)", r.Method) + s.sendErrorJSON(w, r, err) + return + } + + contentType := r.Header.Get("Content-Type") + if i := strings.Index(contentType, ";"); i >= 0 { + contentType = contentType[:i] + } + contentType = strings.TrimSpace(strings.ToLower(contentType)) + + switch contentType { + case "application/json": + if s.OnRequest != nil { + if err := s.OnRequest(w, r); err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + } + + handler(ctx, w, r) + default: + err := ErrWebrpcBadRequest.WithCausef("unsupported Content-Type %q (only application/json is allowed)", r.Header.Get("Content-Type")) + s.sendErrorJSON(w, r, err) + } +} + +func (s *adminServer) serveAddContractsToTokenDirectoryJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "AddContractsToTokenDirectory") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 []*ContractInfo `json:"contracts"` + Arg1 []uint8 `json:"featureIndexes"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Admin.AddContractsToTokenDirectory(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) +} + +func (s *adminServer) serveRemoveContractsFromTokenDirectoryJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "RemoveContractsFromTokenDirectory") -type Metadata interface { - Ping(ctx context.Context) (bool, error) - Version(ctx context.Context) (*Version, error) - RuntimeStatus(ctx context.Context) (*RuntimeStatus, error) - // GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs - GetTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) ([]*TokenMetadata, error) - // Deprecated -> Use RefreshContractInfo, RefreshContractTokens or RefreshAllContractTokens - // Deprecated: - RefreshTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) - // Deprecated -> RefreshContractTokens or RefreshAllContractTokens - // Deprecated: - EnqueueTokensForRefresh(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) - GetTokenRefreshStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) - GetTokenRefreshResult(ctx context.Context, taskId uint64) (*TaskStatus, map[string]bool, map[string]string, error) - CancelRefreshJob(ctx context.Context, taskId uint64) (bool, error) - RefreshContractInfo(ctx context.Context, chainHandle string, contractAddress string) error - RefreshContractTokens(ctx context.Context, chainHandle string, contractAddress string, tokenIDs []string) (*Task, error) - RefreshAllContractTokens(ctx context.Context, chainHandle string, contractAddress string) (*Task, uint64, error) - // GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs - // where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata - // - // Note, we limit each request to 50 contracts max and 50 tokens max per contract. - GetTokenMetadataBatch(ctx context.Context, chainID string, contractTokenMap map[string][]string) (map[string][]*TokenMetadata, error) - SearchTokenMetadata(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []*TokenMetadata, error) - SearchTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) - TokenCollectionFilters(ctx context.Context, chainID string, contractAddress string) ([]*PropertyFilter, error) - // Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists - GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, error) - GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, error) - // Search Contract Info across all chains token-lists. Similar to GetContractInfo above, - // but it will traverse all chains and results from all. - SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) - // map of contractAddress :: []ContractInfo - SearchContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) - // Deprecated: Use SearchTokens() and SearchContracts() instead. - // Deprecated: - SearchMetadata(ctx context.Context, filter string, chainID *string, types []ContractType, excludeTokenMetadata *bool) ([]*TokenMetadata, []*ContractInfo, error) - SearchTokens(ctx context.Context, q string, chainID *string, page *Page) ([]*TokenMetadata, *Page, error) - SearchContracts(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) - // Niftyswap querying data - // map of tokenID :: quantity - GetNiftyswapTokenQuantity(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) (map[string]string, error) - // map of tokenID :: price - GetNiftyswapUnitPrices(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]string, error) - GetNiftyswapUnitPricesWithQuantities(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]*GetNiftyswapUnitPricesResponse, error) - AddContractToMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) - RemoveContractFromMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) - MintMonitorJobStatus(ctx context.Context, chainID string, contractAddress string) (*Task, error) - MintMonitorTriggerJob(ctx context.Context, chainID string, contractAddress string) (bool, error) - SyncContractTokens(ctx context.Context, chainID string, contractAddress string) (uint64, error) - AbortContractSync(ctx context.Context, taskID uint64) (bool, error) - ContractSyncJobStatus(ctx context.Context, taskID uint64) (*Task, *Task, error) - // Token Directory. - // NOTE: this only searches the 'token-directory' items. Use 'SearchContracts' or 'SearchTokens' for everything else. - DirectoryGetNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, error) - DirectoryGetCollections(ctx context.Context, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) - DirectorySearchCollections(ctx context.Context, query string, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainHandle"` + Arg1 []string `json:"contracts"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Admin.RemoveContractsFromTokenDirectory(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) } -type Collections interface { - CreateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) - GetCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) - ListCollections(ctx context.Context, projectId *uint64, page *Page) (*Page, []*Collection, error) - UpdateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) - DeleteCollection(ctx context.Context, projectId *uint64, collectionId uint64) (bool, error) - PublishCollection(ctx context.Context, projectId *uint64, collectionId uint64, recursive *bool) (*Collection, error) - UnpublishCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) - CreateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (*ContractCollection, error) - GetContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (*ContractCollection, error) - ListContractCollections(ctx context.Context, projectId uint64, collectionId *uint64, page *Page) ([]*ContractCollection, []*Collection, *Page, error) - UpdateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (bool, error) - DeleteContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (bool, error) - CreateToken(ctx context.Context, projectId *uint64, collectionId uint64, token *TokenMetadata, private *bool) (*TokenMetadata, []*Asset, error) - GetToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (*TokenMetadata, []*Asset, error) - ListTokens(ctx context.Context, projectId *uint64, collectionId uint64, page *Page) (*Page, []*TokenMetadata, error) - UpdateToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string, token *TokenMetadata, private *bool) (*TokenMetadata, error) - DeleteToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (bool, error) - CreateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) - GetAsset(ctx context.Context, projectId *uint64, assetId uint64) (*Asset, error) - UpdateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) - DeleteAsset(ctx context.Context, projectId *uint64, assetId uint64) (bool, error) +func (s *adminServer) serveModifyFeatureIndexJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "ModifyFeatureIndex") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + Arg2 uint8 `json:"featured"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Admin.ModifyFeatureIndex(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 bool `json:"ok"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) } -type Admin interface { - AddContractsToTokenDirectory(ctx context.Context, contracts []*ContractInfo, featureIndexes []uint8) (bool, error) - RemoveContractsFromTokenDirectory(ctx context.Context, chainHandle string, contracts []string) (bool, error) - ModifyFeatureIndex(ctx context.Context, chainHandle string, contractAddress string, featured uint8) (bool, error) - GetFeatureIndex(ctx context.Context, chainHandle string, contractAddress string) (uint8, error) - ListTokenDirectory(ctx context.Context, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) (*Page, []*ContractInfo, error) +func (s *adminServer) serveGetFeatureIndexJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "GetFeatureIndex") + + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, err := s.Admin.GetFeatureIndex(ctx, reqPayload.Arg0, reqPayload.Arg1) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 uint8 `json:"featured"` + }{ret0} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) } -// -// Client types -// +func (s *adminServer) serveListTokenDirectoryJSON(ctx context.Context, w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, MethodNameCtxKey, "ListTokenDirectory") -type MetadataClient interface { - Ping(ctx context.Context) (bool, error) - Version(ctx context.Context) (*Version, error) - RuntimeStatus(ctx context.Context) (*RuntimeStatus, error) - // GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs - GetTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) ([]*TokenMetadata, error) - // Deprecated -> Use RefreshContractInfo, RefreshContractTokens or RefreshAllContractTokens - // Deprecated: - RefreshTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) - // Deprecated -> RefreshContractTokens or RefreshAllContractTokens - // Deprecated: - EnqueueTokensForRefresh(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, refreshAll *bool) (uint64, error) - GetTokenRefreshStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) - GetTokenRefreshResult(ctx context.Context, taskId uint64) (*TaskStatus, map[string]bool, map[string]string, error) - CancelRefreshJob(ctx context.Context, taskId uint64) (bool, error) - RefreshContractInfo(ctx context.Context, chainHandle string, contractAddress string) error - RefreshContractTokens(ctx context.Context, chainHandle string, contractAddress string, tokenIDs []string) (*Task, error) - RefreshAllContractTokens(ctx context.Context, chainHandle string, contractAddress string) (*Task, uint64, error) - // GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs - // where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata - // - // Note, we limit each request to 50 contracts max and 50 tokens max per contract. - GetTokenMetadataBatch(ctx context.Context, chainID string, contractTokenMap map[string][]string) (map[string][]*TokenMetadata, error) - SearchTokenMetadata(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []*TokenMetadata, error) - SearchTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) - TokenCollectionFilters(ctx context.Context, chainID string, contractAddress string) ([]*PropertyFilter, error) - // Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists - GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, error) - GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, error) - // Search Contract Info across all chains token-lists. Similar to GetContractInfo above, - // but it will traverse all chains and results from all. - SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) - // map of contractAddress :: []ContractInfo - SearchContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) - // Deprecated: Use SearchTokens() and SearchContracts() instead. - // Deprecated: - SearchMetadata(ctx context.Context, filter string, chainID *string, types []ContractType, excludeTokenMetadata *bool) ([]*TokenMetadata, []*ContractInfo, error) - SearchTokens(ctx context.Context, q string, chainID *string, page *Page) ([]*TokenMetadata, *Page, error) - SearchContracts(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) - // Niftyswap querying data - // map of tokenID :: quantity - GetNiftyswapTokenQuantity(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) (map[string]string, error) - // map of tokenID :: price - GetNiftyswapUnitPrices(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]string, error) - GetNiftyswapUnitPricesWithQuantities(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]*GetNiftyswapUnitPricesResponse, error) - AddContractToMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) - RemoveContractFromMintMonitor(ctx context.Context, chainID string, contractAddress string) (bool, error) - MintMonitorJobStatus(ctx context.Context, chainID string, contractAddress string) (*Task, error) - MintMonitorTriggerJob(ctx context.Context, chainID string, contractAddress string) (bool, error) - SyncContractTokens(ctx context.Context, chainID string, contractAddress string) (uint64, error) - AbortContractSync(ctx context.Context, taskID uint64) (bool, error) - ContractSyncJobStatus(ctx context.Context, taskID uint64) (*Task, *Task, error) - // Token Directory. - // NOTE: this only searches the 'token-directory' items. Use 'SearchContracts' or 'SearchTokens' for everything else. - DirectoryGetNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, error) - DirectoryGetCollections(ctx context.Context, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) - DirectorySearchCollections(ctx context.Context, query string, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + reqBody, err := io.ReadAll(r.Body) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to read request data: %w", err)) + return + } + defer r.Body.Close() + + reqPayload := struct { + Arg0 *uint64 `json:"chainID"` + Arg1 *bool `json:"includeTestnets"` + Arg2 *bool `json:"onlyFeatured"` + Arg3 *Page `json:"page"` + }{} + if err := json.Unmarshal(reqBody, &reqPayload); err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadRequest.WithCausef("failed to unmarshal request data: %w", err)) + return + } + + // Call service method implementation. + ret0, ret1, err := s.Admin.ListTokenDirectory(ctx, reqPayload.Arg0, reqPayload.Arg1, reqPayload.Arg2, reqPayload.Arg3) + if err != nil { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + s.sendErrorJSON(w, r, rpcErr) + return + } + + respPayload := struct { + Ret0 *Page `json:"page"` + Ret1 []*ContractInfo `json:"collections"` + }{ret0, ret1} + respBody, err := json.Marshal(respPayload) + if err != nil { + s.sendErrorJSON(w, r, ErrWebrpcBadResponse.WithCausef("failed to marshal json response: %w", err)) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(respBody) } -type CollectionsClient interface { - CreateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) - GetCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) - ListCollections(ctx context.Context, projectId *uint64, page *Page) (*Page, []*Collection, error) - UpdateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) - DeleteCollection(ctx context.Context, projectId *uint64, collectionId uint64) (bool, error) - PublishCollection(ctx context.Context, projectId *uint64, collectionId uint64, recursive *bool) (*Collection, error) - UnpublishCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) - CreateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (*ContractCollection, error) - GetContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (*ContractCollection, error) - ListContractCollections(ctx context.Context, projectId uint64, collectionId *uint64, page *Page) ([]*ContractCollection, []*Collection, *Page, error) - UpdateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (bool, error) - DeleteContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (bool, error) - CreateToken(ctx context.Context, projectId *uint64, collectionId uint64, token *TokenMetadata, private *bool) (*TokenMetadata, []*Asset, error) - GetToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (*TokenMetadata, []*Asset, error) - ListTokens(ctx context.Context, projectId *uint64, collectionId uint64, page *Page) (*Page, []*TokenMetadata, error) - UpdateToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string, token *TokenMetadata, private *bool) (*TokenMetadata, error) - DeleteToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (bool, error) - CreateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) - GetAsset(ctx context.Context, projectId *uint64, assetId uint64) (*Asset, error) - UpdateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) - DeleteAsset(ctx context.Context, projectId *uint64, assetId uint64) (bool, error) +func (s *adminServer) sendErrorJSON(w http.ResponseWriter, r *http.Request, rpcErr WebRPCError) { + if s.OnError != nil { + s.OnError(r, &rpcErr) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(rpcErr.HTTPStatus) + + respBody, _ := json.Marshal(rpcErr) + w.Write(respBody) } -type AdminClient interface { - AddContractsToTokenDirectory(ctx context.Context, contracts []*ContractInfo, featureIndexes []uint8) (bool, error) - RemoveContractsFromTokenDirectory(ctx context.Context, chainHandle string, contracts []string) (bool, error) - ModifyFeatureIndex(ctx context.Context, chainHandle string, contractAddress string, featured uint8) (bool, error) - GetFeatureIndex(ctx context.Context, chainHandle string, contractAddress string) (uint8, error) - ListTokenDirectory(ctx context.Context, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) (*Page, []*ContractInfo, error) +func RespondWithError(w http.ResponseWriter, err error) { + rpcErr, ok := err.(WebRPCError) + if !ok { + rpcErr = ErrWebrpcEndpoint.WithCause(err) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(rpcErr.HTTPStatus) + + respBody, _ := json.Marshal(rpcErr) + w.Write(respBody) } // @@ -1519,13 +4703,14 @@ func (c *metadataClient) TokenCollectionFilters(ctx context.Context, chainID str return out.Ret0, err } -func (c *metadataClient) GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, error) { +func (c *metadataClient) GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, *Task, error) { in := struct { Arg0 string `json:"chainID"` Arg1 string `json:"contractAddress"` }{chainID, contractAddress} out := struct { Ret0 *ContractInfo `json:"contractInfo"` + Ret1 *Task `json:"task"` }{} resp, err := doHTTPRequest(ctx, c.client, c.urls[16], in, &out) @@ -1536,16 +4721,17 @@ func (c *metadataClient) GetContractInfo(ctx context.Context, chainID string, co } } - return out.Ret0, err + return out.Ret0, out.Ret1, err } -func (c *metadataClient) GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, error) { +func (c *metadataClient) GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, *Task, error) { in := struct { Arg0 string `json:"chainID"` Arg1 []string `json:"contractAddresses"` }{chainID, contractAddresses} out := struct { Ret0 map[string]*ContractInfo `json:"contractInfoMap"` + Ret1 *Task `json:"task"` }{} resp, err := doHTTPRequest(ctx, c.client, c.urls[17], in, &out) @@ -1556,7 +4742,7 @@ func (c *metadataClient) GetContractInfoBatch(ctx context.Context, chainID strin } } - return out.Ret0, err + return out.Ret0, out.Ret1, err } func (c *metadataClient) SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) { @@ -2673,7 +5859,9 @@ func (k *contextKey) String() string { var ( HTTPClientRequestHeadersCtxKey = &contextKey{"HTTPClientRequestHeaders"} - HTTPRequestCtxKey = &contextKey{"HTTPRequest"} + HTTPResponseWriterCtxKey = &contextKey{"HTTPResponseWriter"} + + HTTPRequestCtxKey = &contextKey{"HTTPRequest"} ServiceNameCtxKey = &contextKey{"ServiceName"} @@ -2709,6 +5897,11 @@ func MethodCtx(ctx context.Context) (method, bool) { return m, true } +func ResponseWriterFromContext(ctx context.Context) http.ResponseWriter { + w, _ := ctx.Value(HTTPResponseWriterCtxKey).(http.ResponseWriter) + return w +} + // // Errors //