diff --git a/metadata/metadata.gen.go b/metadata/metadata.gen.go new file mode 100644 index 00000000..f7747ff5 --- /dev/null +++ b/metadata/metadata.gen.go @@ -0,0 +1,3332 @@ +// sequence-metadata v0.4.0 aafea951d2110c8e22ca530497358245a22c4cdd +// -- +// Code generated by webrpc-gen@v0.30.2 with golang generator. DO NOT EDIT. +// +// webrpc-gen -schema=metadata.ridl -target=golang -pkg=metadata -client -out=./clients/metadata.gen.go +package metadata + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "github.com/0xsequence/go-sequence/lib/prototyp" +) + +// WebRPC description and code-gen version +func WebRPCVersion() string { + return "v1" +} + +// Schema version of your RIDL schema +func WebRPCSchemaVersion() string { + return "v0.4.0" +} + +// Schema hash generated from your RIDL schema +func WebRPCSchemaHash() string { + return "aafea951d2110c8e22ca530497358245a22c4cdd" +} + +// +// Client interface +// + +type MetadataClient interface { + Ping(ctx context.Context) (bool, error) + Version(ctx context.Context) (*Version, error) + RuntimeStatus(ctx context.Context) (*RuntimeStatus, error) + GetTask(ctx context.Context, taskId uint64) (*Task, error) + GetTaskStatus(ctx context.Context, taskId uint64) (*TaskStatus, 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, *uint64, error) + GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, *uint64, error) + // Find Contract Info across all chains token-lists. Similar to GetContractInfo above, + // but it will traverse all chains and results from all. + FindContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) + // map of contractAddress :: []ContractInfo + FindContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) + // Refresh Contract Info -- refresh contract meta-info + RefreshContractInfo(ctx context.Context, chainID string, contractAddress string) (*uint64, error) + RefreshContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (*uint64, error) + // Search for contract infos using a query string + SearchContractsByQuery(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) + // Deprecated: UseFindContractInfo instead. (renamed). + SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) + // Deprecated: Use FindContractInfoBatch instead. (renamed) + SearchContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) + // Deprecated: Use SearchContractsByQuery instead. (renamed) + SearchContracts(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) + // Deprecated: Use SearchContractsByQuery() and SearchTokenMetadataByQuery() instead. + SearchMetadata(ctx context.Context, filter string, chainID *string, types []ContractType, excludeTokenMetadata *bool) ([]*TokenMetadata, []*ContractInfo, error) + // GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs + GetTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) ([]*TokenMetadata, *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, *uint64, error) + // RefreshTokenMetadata allows you to refresh a contract metadata for contract-level and token-level metadata. + RefreshTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, newMints *bool) (uint64, error) + // Search ERC721 & ERC1155 token metadata by query string 'q' + SearchTokenMetadataByQuery(ctx context.Context, q string, chainID *string, contractAddress *string, page *Page) ([]*TokenMetadata, *Page, error) + // Search ERC721 & ERC1155 token metadata by filter object 'filter' + // which allows to search by text or properties. + SearchTokenMetadata(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []*TokenMetadata, error) + // Search ERC721 & ERC1155 for token IDs by filter object 'filter' + // which allows to search by text or properties. + SearchTokenMetadataTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) + // Get token metadata property filters for a contract address + GetTokenMetadataPropertyFilters(ctx context.Context, chainID string, contractAddress string, excludeProperties []string, excludePropertyValues *bool) ([]*PropertyFilter, error) + // Deprecated: Use RefreshTokenMetadata instead. + RefreshAllContractTokens(ctx context.Context, chainHandle string, contractAddress string) (*uint64, uint64, error) + // Deprecated: Use SearchTokenMetadataByQuery instead. (renamed) + SearchTokens(ctx context.Context, q string, chainID *string, page *Page) ([]*TokenMetadata, *Page, error) + // Deprecated: Use GetTokenMetadataPropertyFilters (renamed) + TokenCollectionFilters(ctx context.Context, chainID string, contractAddress string) ([]*PropertyFilter, error) + // Deprecated: Use GetTaskStatus instead. (its the same thing) + GetTokenRefreshStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) + // Deprecated: Use SearchTokenMetadataTokenIDs instead. (renamed) + SearchTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) + // Gets Token Directory supported networks + GetTokenDirectoryNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, []string, error) + // Gets Token Directory entries + GetTokenDirectory(ctx context.Context, chainID *string, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + // Search in Token Directory + SearchTokenDirectory(ctx context.Context, query string, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + // Deprecated: Use GetTokenDirectoryNetworks instead. + DirectoryGetNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, error) + // Deprecated: Use GetTokenDirectory instead. + DirectoryGetCollections(ctx context.Context, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) + // Deprecated: Use SearchTokenDirectory instead. + DirectorySearchCollections(ctx context.Context, query string, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, 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) +} + +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 { + // ContractInfo + RefreshContractInfoUpdatedBefore(ctx context.Context, before string, maxContractNumber int) ([]uint64, error) + // TokenMetadata + RefreshTokenMetadataUpdatedBefore(ctx context.Context, before string, maxTokenNumber int) ([]uint64, error) + // Contract Info Overrides + GetContractInfoOverride(ctx context.Context, chainID string, contractAddress string) (*ContractInfoOverride, error) + GetContractInfoOverrides(ctx context.Context, chainID *string, page *Page) ([]*ContractInfoOverride, *Page, error) + AddContractInfoOverride(ctx context.Context, chainID string, contractAddress string, contractInfoOverride *ContractInfoOverride) (bool, error) + UpdateContractInfoOverride(ctx context.Context, chainID string, contractAddress string, contractInfoOverride *ContractInfoOverride) (bool, error) + RemoveContractInfoOverride(ctx context.Context, chainID string, contractAddress string) (bool, error) + // Token Directory + IsInTokenDirectory(ctx context.Context, chainID string, contractAddress string) (bool, uint8, error) + SetTokenDirectoryFeatureIndex(ctx context.Context, chainID string, contractAddress string, featureIndex uint8) (bool, error) + AddContractToTokenDirectory(ctx context.Context, chainID string, contractAddress string) (bool, error) + RemoveContractFromTokenDirectory(ctx context.Context, chainID string, contractAddress string) (bool, error) + RefreshTokenDirectory(ctx context.Context) (uint64, error) + // Deprecated: use new admin api + AddContractsToTokenDirectory(ctx context.Context, contracts []*ContractInfo, featureIndexes []uint8) (bool, error) + // Deprecated: use new admin api + RemoveContractsFromTokenDirectory(ctx context.Context, chainHandle string, contracts []string) (bool, error) + // Deprecated: use new admin api + ModifyFeatureIndex(ctx context.Context, chainHandle string, contractAddress string, featured uint8) (bool, error) + // Deprecated: use new admin api + GetFeatureIndex(ctx context.Context, chainHandle string, contractAddress string) (uint8, error) + // Deprecated: use new admin api + ListTokenDirectory(ctx context.Context, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) (*Page, []*ContractInfo, error) +} + +// +// Schema types +// + +type ContractType uint16 + +const ( + ContractType_UNKNOWN ContractType = 0 + ContractType_ERC20 ContractType = 1 + ContractType_ERC721 ContractType = 2 + ContractType_ERC1155 ContractType = 3 + ContractType_ERC6909 ContractType = 4 + ContractType_MISC ContractType = 5 +) + +var ContractType_name = map[uint16]string{ + 0: "UNKNOWN", + 1: "ERC20", + 2: "ERC721", + 3: "ERC1155", + 4: "ERC6909", + 5: "MISC", +} + +var ContractType_value = map[string]uint16{ + "UNKNOWN": 0, + "ERC20": 1, + "ERC721": 2, + "ERC1155": 3, + "ERC6909": 4, + "MISC": 5, +} + +func (x ContractType) String() string { + return ContractType_name[uint16(x)] +} + +func (x ContractType) MarshalText() ([]byte, error) { + return []byte(ContractType_name[uint16(x)]), nil +} + +func (x *ContractType) UnmarshalText(b []byte) error { + *x = ContractType(ContractType_value[string(b)]) + return nil +} + +func (x *ContractType) Is(values ...ContractType) bool { + if x == nil { + return false + } + for _, v := range values { + if *x == v { + return true + } + } + return false +} + +type Source uint8 + +const ( + Source_UNKNOWN Source = 0x00 + Source_FETCHER Source = 0x10 + Source_FETCHER_OPENSEA_API Source = 0x11 + Source_FETCHER_ENS_API Source = 0x12 + Source_FETCHER_ON_CHAIN_ERC20_INTERFACE Source = 0x13 + Source_FETCHER_ON_CHAIN_TOKEN_URI Source = 0x14 + Source_FETCHER_ON_CHAIN_CONTRACT_URI Source = 0x15 + Source_FETCHER_TOKEN_DIRECTORY_ADMIN Source = 0x16 + Source_TOKEN_DIRECTORY Source = 0x40 + Source_TOKEN_DIRECTORY_PUBLIC_TOKEN_LIST Source = 0x41 + Source_TOKEN_DIRECTORY_3RD_PARTY Source = 0x42 + Source_TOKEN_DIRECTORY_SEQUENCE_GITHUB Source = 0x43 + Source_TOKEN_DIRECTORY_SEQUENCE_BUILDER Source = 0x44 + Source_SEQUENCE_BUILDER Source = 0x80 + Source_SEQUENCE_BUILDER_DEPLOYED Source = 0x81 + Source_SEQUENCE_BUILDER_COLLECTIONS Source = 0x82 + Source_SEQUENCE_BUILDER_ADMIN Source = 0x83 +) + +var Source_name = map[uint8]string{ + 0x00: "UNKNOWN", + 0x10: "FETCHER", + 0x11: "FETCHER_OPENSEA_API", + 0x12: "FETCHER_ENS_API", + 0x13: "FETCHER_ON_CHAIN_ERC20_INTERFACE", + 0x14: "FETCHER_ON_CHAIN_TOKEN_URI", + 0x15: "FETCHER_ON_CHAIN_CONTRACT_URI", + 0x16: "FETCHER_TOKEN_DIRECTORY_ADMIN", + 0x40: "TOKEN_DIRECTORY", + 0x41: "TOKEN_DIRECTORY_PUBLIC_TOKEN_LIST", + 0x42: "TOKEN_DIRECTORY_3RD_PARTY", + 0x43: "TOKEN_DIRECTORY_SEQUENCE_GITHUB", + 0x44: "TOKEN_DIRECTORY_SEQUENCE_BUILDER", + 0x80: "SEQUENCE_BUILDER", + 0x81: "SEQUENCE_BUILDER_DEPLOYED", + 0x82: "SEQUENCE_BUILDER_COLLECTIONS", + 0x83: "SEQUENCE_BUILDER_ADMIN", +} + +var Source_value = map[string]uint8{ + "UNKNOWN": 0x00, + "FETCHER": 0x10, + "FETCHER_OPENSEA_API": 0x11, + "FETCHER_ENS_API": 0x12, + "FETCHER_ON_CHAIN_ERC20_INTERFACE": 0x13, + "FETCHER_ON_CHAIN_TOKEN_URI": 0x14, + "FETCHER_ON_CHAIN_CONTRACT_URI": 0x15, + "FETCHER_TOKEN_DIRECTORY_ADMIN": 0x16, + "TOKEN_DIRECTORY": 0x40, + "TOKEN_DIRECTORY_PUBLIC_TOKEN_LIST": 0x41, + "TOKEN_DIRECTORY_3RD_PARTY": 0x42, + "TOKEN_DIRECTORY_SEQUENCE_GITHUB": 0x43, + "TOKEN_DIRECTORY_SEQUENCE_BUILDER": 0x44, + "SEQUENCE_BUILDER": 0x80, + "SEQUENCE_BUILDER_DEPLOYED": 0x81, + "SEQUENCE_BUILDER_COLLECTIONS": 0x82, + "SEQUENCE_BUILDER_ADMIN": 0x83, +} + +func (x Source) String() string { + return Source_name[uint8(x)] +} + +func (x Source) MarshalText() ([]byte, error) { + return []byte(Source_name[uint8(x)]), nil +} + +func (x *Source) UnmarshalText(b []byte) error { + *x = Source(Source_value[string(b)]) + return nil +} + +func (x *Source) Is(values ...Source) bool { + if x == nil { + return false + } + for _, v := range values { + if *x == v { + return true + } + } + return false +} + +type ResourceStatus uint32 + +const ( + ResourceStatus_NOT_AVAILABLE ResourceStatus = 0 + ResourceStatus_REFRESHING ResourceStatus = 1 + ResourceStatus_AVAILABLE ResourceStatus = 2 +) + +var ResourceStatus_name = map[uint32]string{ + 0: "NOT_AVAILABLE", + 1: "REFRESHING", + 2: "AVAILABLE", +} + +var ResourceStatus_value = map[string]uint32{ + "NOT_AVAILABLE": 0, + "REFRESHING": 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 ( + PropertyType_INT PropertyType = 0 + PropertyType_STRING PropertyType = 1 + PropertyType_ARRAY PropertyType = 2 + PropertyType_GENERIC PropertyType = 3 +) + +var PropertyType_name = map[uint32]string{ + 0: "INT", + 1: "STRING", + 2: "ARRAY", + 3: "GENERIC", +} + +var PropertyType_value = map[string]uint32{ + "INT": 0, + "STRING": 1, + "ARRAY": 2, + "GENERIC": 3, +} + +func (x PropertyType) String() string { + return PropertyType_name[uint32(x)] +} + +func (x PropertyType) MarshalText() ([]byte, error) { + return []byte(PropertyType_name[uint32(x)]), nil +} + +func (x *PropertyType) UnmarshalText(b []byte) error { + *x = PropertyType(PropertyType_value[string(b)]) + return nil +} + +func (x *PropertyType) Is(values ...PropertyType) bool { + if x == nil { + return false + } + for _, v := range values { + if *x == v { + return true + } + } + return false +} + +type SwapType uint32 + +const ( + SwapType_UNKNOWN SwapType = 0 + SwapType_BUY SwapType = 1 + SwapType_SELL SwapType = 2 +) + +var SwapType_name = map[uint32]string{ + 0: "UNKNOWN", + 1: "BUY", + 2: "SELL", +} + +var SwapType_value = map[string]uint32{ + "UNKNOWN": 0, + "BUY": 1, + "SELL": 2, +} + +func (x SwapType) String() string { + return SwapType_name[uint32(x)] +} + +func (x SwapType) MarshalText() ([]byte, error) { + return []byte(SwapType_name[uint32(x)]), nil +} + +func (x *SwapType) UnmarshalText(b []byte) error { + *x = SwapType(SwapType_value[string(b)]) + return nil +} + +func (x *SwapType) Is(values ...SwapType) bool { + if x == nil { + return false + } + for _, v := range values { + if *x == v { + return true + } + } + return false +} + +type TaskStatus uint8 + +const ( + TaskStatus_QUEUED TaskStatus = 0 + TaskStatus_PAUSED TaskStatus = 1 + TaskStatus_FAILED TaskStatus = 2 + TaskStatus_DONE TaskStatus = 3 +) + +var TaskStatus_name = map[uint8]string{ + 0: "QUEUED", + 1: "PAUSED", + 2: "FAILED", + 3: "DONE", +} + +var TaskStatus_value = map[string]uint8{ + "QUEUED": 0, + "PAUSED": 1, + "FAILED": 2, + "DONE": 3, +} + +func (x TaskStatus) String() string { + return TaskStatus_name[uint8(x)] +} + +func (x TaskStatus) MarshalText() ([]byte, error) { + return []byte(TaskStatus_name[uint8(x)]), nil +} + +func (x *TaskStatus) UnmarshalText(b []byte) error { + *x = TaskStatus(TaskStatus_value[string(b)]) + return nil +} + +func (x *TaskStatus) Is(values ...TaskStatus) bool { + if x == nil { + return false + } + for _, v := range values { + if *x == v { + return true + } + } + return false +} + +type Version struct { + WebrpcVersion string `json:"webrpcVersion"` + SchemaVersion string `json:"schemaVersion"` + SchemaHash string `json:"schemaHash"` + AppVersion string `json:"appVersion"` +} + +type RuntimeStatus struct { + 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"` + 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"` +} + +// ContractIndex is a database type to track the index of contracts which +// are fetched on-demand through traversing on-chain contract metadata. +type ContractIndex struct { + ChainID uint64 `json:"chainId" db:"chain_id"` + Address prototyp.Hash `json:"address" db:"contract_address"` + Type ContractType `json:"type" db:"type"` + Source Source `json:"source" db:"source"` + Metadata map[string]interface{} `json:"metadata" db:"metadata"` + 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" 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 +// are fetched on-demand through traversing on-chain contract metadata. +type TokenIndex struct { + ChainID uint64 `json:"chainId" db:"chain_id"` + ContractAddress prototyp.Hash `json:"contractAddress,omitempty" db:"contract_address"` + TokenID prototyp.BigInt `json:"tokenId" db:"token_id"` + Source Source `json:"source" db:"source"` + Metadata map[string]interface{} `json:"metadata" db:"metadata"` + NotFound bool `json:"notFound,omitempty" db:"not_found"` + 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 +// the contract-level metadata. +type ContractInfo struct { + ChainID uint64 `json:"chainId" cbor:"-"` + Address string `json:"address" cbor:"-"` + Source string `json:"source" cbor:"-"` + Name string `json:"name" cbor:"-"` + Type string `json:"type" cbor:"-"` + Symbol string `json:"symbol" cbor:"-"` + Decimals *uint64 `json:"decimals,omitempty" cbor:"-"` + LogoURI string `json:"logoURI,omitempty" cbor:"-"` + Deployed bool `json:"deployed" cbor:"-"` + BytecodeHash prototyp.Hash `json:"bytecodeHash" cbor:"-"` + Extensions *ContractInfoExtensions `json:"extensions" cbor:"-"` + ContentHash uint64 `json:"-" cbor:"-"` + UpdatedAt time.Time `json:"updatedAt" cbor:"-"` + QueuedAt *time.Time `json:"queuedAt"` + Status ResourceStatus `json:"status"` +} + +type ContractInfoExtensions struct { + Link string `json:"link,omitempty" cbor:"-"` + Description string `json:"description,omitempty" cbor:"-"` + Categories []string `json:"categories,omitempty" cbor:"-"` + BridgeInfo map[string]ContractInfoExtensionBridgeInfo `json:"bridgeInfo,omitempty" cbor:"-"` + OgImage string `json:"ogImage,omitempty" cbor:"-"` + OgName string `json:"ogName,omitempty" cbor:"-"` + OriginChainID uint64 `json:"originChainId,omitempty" cbor:"-"` + OriginAddress string `json:"originAddress,omitempty" cbor:"-"` + Blacklist bool `json:"blacklist,omitempty" cbor:"-"` + Verified bool `json:"verified,omitempty" cbor:"-"` + VerifiedBy string `json:"verifiedBy,omitempty" cbor:"-"` + Featured bool `json:"featured,omitempty" cbor:"-"` + FeatureIndex uint8 `json:"featureIndex,omitempty" cbor:"-"` +} + +type ContractInfoExtensionBridgeInfo struct { + TokenAddress string `json:"tokenAddress" cbor:"-"` +} + +type ContractInfoOverride struct { + Name *string `json:"name" cbor:"-"` + Type *string `json:"type" cbor:"-"` + Symbol *string `json:"symbol" cbor:"-"` + Decimals *uint64 `json:"decimals,omitempty" cbor:"-"` + LogoURI *string `json:"logoURI,omitempty" cbor:"-"` + Extensions *ContractInfoExtensionsOverride `json:"extensions" cbor:"-"` +} + +type ContractInfoExtensionsOverride struct { + 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:"-"` + FeatureIndex *uint8 `json:"featureIndex,omitempty"` +} + +// TokenMetadata based on 721/1155 standards, as well including some +// fields which are used by OpenSea. +// +// TokenMetadata is RPC type for responding to clients that represents +// the token-level metadata. +type TokenMetadata struct { + ChainID *uint64 `json:"chainId,omitempty" cbor:"-"` + ContractAddress prototyp.Hash `json:"contractAddress,omitempty" cbor:"-"` + TokenID string `json:"tokenId" cbor:"-"` + Source string `json:"source" cbor:"-"` + Name string `json:"name" cbor:"-"` + Description string `json:"description" cbor:"-"` + // url + Image string `json:"image" cbor:"-"` + // non-standard fields we've added for Sequence. Others should adopt + // these too and we should prompt, similar to how `image` field works. + // url + Video string `json:"video,omitempty" cbor:"-"` + // url + Audio string `json:"audio,omitempty" cbor:"-"` + Properties map[string]interface{} `json:"properties" cbor:"-"` + // OpenSea fields + // see https://docs.opensea.io/docs/metadata-standards + // + // NOTE: its a bit unfortunate OpenSea didn't use camelCase, and + // also introduces 'attributes' when 'properties' is actually the correct property name. + Attributes []map[string]interface{} `json:"attributes" cbor:"-"` + ImageData string `json:"image_data,omitempty" cbor:"-"` + ExternalUrl string `json:"external_url,omitempty" cbor:"-"` + BackgroundColor string `json:"background_color,omitempty" cbor:"-"` + AnimationUrl string `json:"animation_url,omitempty" cbor:"-"` + // + // Misc + // + // decimals is deprecated, but still used by some + Decimals *uint64 `json:"decimals,omitempty" cbor:"-"` + UpdatedAt time.Time `json:"updatedAt" cbor:"-"` + // Assets associated to this token metadata + Assets []*Asset `json:"assets,omitempty" cbor:"-"` + Status ResourceStatus `json:"status"` + QueuedAt *time.Time `json:"queuedAt"` + LastFetched *time.Time `json:"lastFetched,omitempty"` +} + +// PropertyFilter +// +// name -> name of the property, eg: hero +// type -> type of the values of the property, eg: Int, string +// min?, max? used if type is int, gives range of values for filtering +// values? -> if string then array of values, eg: ['Ada', 'Ari', 'Axel', 'Banjo' ...] +// NOTE: When Filter has an array of PropertyFilter, the logic used is an 'and' condition +// whereas if the user selects multiple values inside the PropertyFilter, they logic used is the 'or' condition +// this is to achieve the desired effect opensea had on their filters +type PropertyFilter struct { + Name string `json:"name"` + Type PropertyType `json:"type"` + Min *int64 `json:"min"` + Max *int64 `json:"max"` + Values []interface{} `json:"values"` +} + +type Filter struct { + Text *string `json:"text"` + Properties []*PropertyFilter `json:"properties"` +} + +// Collection represents the contract-level metadata for a collection. +// +// the fields here should overlap with https://docs.opensea.io/docs/contract-level-metadata +// such that we can use this object for contract-level metadata. +type Collection struct { + ID uint64 `json:"id,omitempty" db:"id,omitempty"` + ProjectID uint64 `json:"projectId,omitempty" db:"project_id"` + Metadata *CollectionMetadata `json:"metadata,omitempty" db:"metadata"` + Private bool `json:"private" db:"private"` + RevealKey string `json:"revealKey,omitempty" db:"reveal_key"` + TokenCount *uint64 `json:"tokenCount,omitempty" db:"-"` + CreatedAt time.Time `json:"createdAt,omitempty" db:"created_at,omitempty"` + UpdatedAt time.Time `json:"updatedAt,omitempty" db:"updated_at,omitempty"` + DeletedAt *time.Time `json:"deletedAt,omitempty" db:"deleted_at"` + BaseURIs *CollectionBaseURIs `json:"baseURIs,omitempty" db:"-"` + // Assets associated to this collection metadata + Assets []*Asset `json:"assets,omitempty" cbor:"-"` +} + +type CollectionMetadata struct { + Name string `json:"name"` + Description string `json:"description"` + Image string `json:"image,omitempty"` + // NOTE: we use `external_link` for the field name because of OpenSea's + // contract-level metadata https://docs.opensea.io/docs/contract-level-metadata + ExternalLink string `json:"external_link,omitempty"` + Properties map[string]interface{} `json:"properties,omitempty"` + Attributes []map[string]interface{} `json:"attributes,omitempty"` +} + +type CollectionBaseURIs struct { + // contractMetadataURI is the URI to the contract-level metadata for the collection, + // which is the value to set on a contract. Note, we do not store this in the db, but we + // do return it as part of the response. + // + // aka, `contractURI()` on a contract + ContractMetadataURI string `json:"contractMetadataURI"` + // tokenMetadataURI is the URI to the token-level metadata for the collection, + // which is the value to set on a contract's token baseURI. Note, we do not store this + // in the db, but we do return it as part of the response. + // + // aka `uri(uint256 tokenId)` on 721 and 1155 + // + // This base URI which satisfy 721 and 1155 + // + // https://eips.ethereum.org/EIPS/eip-721 + // uri ending with '/ without placeholder for tokenID + // + // also use for 1155 + // https://eips.ethereum.org/EIPS/eip-1155#metadata + TokenMetadataURI string `json:"tokenMetadataURI"` +} + +// ContractCollection represents the relationship between a contract and a collection. +type ContractCollection struct { + ID uint64 `json:"id,omitempty" db:"id,omitempty"` + ChainID uint64 `json:"chainId" db:"chain_id"` + ContractAddress prototyp.Hash `json:"contractAddress" db:"contract_address"` + CollectionID uint64 `json:"collectionId" db:"collection_id"` +} + +// Asset is a database type used by 'collections' to record static assets for +// a particular 'token' for the token metadata. +type Asset struct { + // asset id + ID uint64 `json:"id" db:"id,omitempty"` + // collection id associated to this asset + CollectionID uint64 `json:"collectionId" db:"collection_id"` + // token id associated to this collection + TokenID *prototyp.BigInt `json:"tokenId" db:"token_id,omitempty"` + // url where we can view the asset contents + // ie. https://metadata.sequence.app/projects/1/collections/1/tokens/1/image + URL string `json:"url" db:"url"` + // metadata field related to TokenMetadata, some field names: + // ['image', 'video', 'audio', 'animation_url', ...] + MetadataField string `json:"metadataField,omitempty" db:"metadata_field"` + // asset details + Filename string `json:"filename,omitempty" db:"filename"` + Filesize uint32 `json:"filesize,omitempty" db:"filesize"` + MimeType string `json:"mimeType,omitempty" db:"mime_type"` + Width *uint16 `json:"width,omitempty" db:"width"` + Height *uint16 `json:"height,omitempty" db:"height"` + UpdatedAt time.Time `json:"updatedAt" db:"updated_at"` +} + +// Token is a database type used by 'collections' that represents the token metadata +// for a collection. We use this as an internal type for storage, but it stores +// just TokenMetadata for a particular collectionId/tokenId. +type Token struct { + CollectionID uint64 `json:"collectionId" db:"collection_id"` + TokenID prototyp.BigInt `json:"tokenId" db:"token_id"` + Metadata *TokenMetadata `json:"metadata" db:"metadata"` + Private bool `json:"private" db:"private"` + SearchColumn string `json:"-" db:"search_col"` + UpdatedAt time.Time `json:"updatedAt" db:"updated_at"` +} + +type GetNiftyswapUnitPricesRequest struct { + SwapType SwapType `json:"swapType"` + Ids []prototyp.BigInt `json:"ids"` + Amounts []prototyp.BigInt `json:"amounts"` +} + +type GetNiftyswapUnitPricesResponse struct { + UnitPrice prototyp.BigInt `json:"unitPrice"` + UnitAmount prototyp.BigInt `json:"unitAmount"` + AvailableAmount prototyp.BigInt `json:"availableAmount"` +} + +// Page represents a results page. This can be used both to request a page and +// to store the state of a page. +type Page struct { + // Numbered pages: Page number, this is multiplied by the value of the parameter. + Page *uint32 `json:"page,omitempty"` + // Cursor: column to compare before/after to + Column *string `json:"column,omitempty"` + // Cursor: return column < before - include to get previous page + Before *interface{} `json:"before,omitempty"` + // Cursor: return column > after - include to get next page + After *interface{} `json:"after,omitempty"` + // Number of items per page + PageSize *uint32 `json:"pageSize,omitempty"` + // Indicates if there are more results available + More *bool `json:"more,omitempty"` +} + +type Task struct { + ID uint64 `json:"id" db:"id,omitempty"` + Queue string `json:"queue" db:"queue"` + Status TaskStatus `json:"status" db:"status"` + Try uint32 `json:"try" db:"try"` + RunAt *time.Time `json:"runAt" db:"run_at,omitempty"` + LastRanAt *time.Time `json:"lastRanAt" db:"last_ran_at,omitempty"` + CreatedAt *time.Time `json:"createdAt" db:"created_at,omitempty"` + Payload json.RawMessage `json:"payload" db:"payload"` + Result json.RawMessage `json:"result"` +} + +var methods = map[string]method{ + "/rpc/Metadata/Ping": { + name: "Ping", + service: "Metadata", + annotations: map[string]string{"internal": ""}, + }, + "/rpc/Metadata/Version": { + name: "Version", + service: "Metadata", + annotations: map[string]string{"internal": ""}, + }, + "/rpc/Metadata/RuntimeStatus": { + name: "RuntimeStatus", + service: "Metadata", + annotations: map[string]string{"internal": ""}, + }, + "/rpc/Metadata/GetTask": { + name: "GetTask", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/GetTaskStatus": { + name: "GetTaskStatus", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/GetContractInfo": { + name: "GetContractInfo", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/GetContractInfoBatch": { + name: "GetContractInfoBatch", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/FindContractInfo": { + name: "FindContractInfo", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/FindContractInfoBatch": { + name: "FindContractInfoBatch", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/RefreshContractInfo": { + name: "RefreshContractInfo", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/RefreshContractInfoBatch": { + name: "RefreshContractInfoBatch", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/SearchContractsByQuery": { + name: "SearchContractsByQuery", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/SearchContractInfo": { + name: "SearchContractInfo", + service: "Metadata", + annotations: map[string]string{"deprecated": "UseFindContractInfo instead. (renamed)."}, + }, + "/rpc/Metadata/SearchContractInfoBatch": { + name: "SearchContractInfoBatch", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use FindContractInfoBatch instead. (renamed)"}, + }, + "/rpc/Metadata/SearchContracts": { + name: "SearchContracts", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use SearchContractsByQuery instead. (renamed)"}, + }, + "/rpc/Metadata/SearchMetadata": { + name: "SearchMetadata", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use SearchContractsByQuery() and SearchTokenMetadataByQuery() instead."}, + }, + "/rpc/Metadata/GetTokenMetadata": { + name: "GetTokenMetadata", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/GetTokenMetadataBatch": { + name: "GetTokenMetadataBatch", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/RefreshTokenMetadata": { + name: "RefreshTokenMetadata", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/SearchTokenMetadataByQuery": { + name: "SearchTokenMetadataByQuery", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/SearchTokenMetadata": { + name: "SearchTokenMetadata", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/SearchTokenMetadataTokenIDs": { + name: "SearchTokenMetadataTokenIDs", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/GetTokenMetadataPropertyFilters": { + name: "GetTokenMetadataPropertyFilters", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/RefreshAllContractTokens": { + name: "RefreshAllContractTokens", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use RefreshTokenMetadata instead."}, + }, + "/rpc/Metadata/SearchTokens": { + name: "SearchTokens", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use SearchTokenMetadataByQuery instead. (renamed)"}, + }, + "/rpc/Metadata/TokenCollectionFilters": { + name: "TokenCollectionFilters", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use GetTokenMetadataPropertyFilters (renamed)"}, + }, + "/rpc/Metadata/GetTokenRefreshStatus": { + name: "GetTokenRefreshStatus", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use GetTaskStatus instead. (its the same thing)"}, + }, + "/rpc/Metadata/SearchTokenIDs": { + name: "SearchTokenIDs", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use SearchTokenMetadataTokenIDs instead. (renamed)"}, + }, + "/rpc/Metadata/GetTokenDirectoryNetworks": { + name: "GetTokenDirectoryNetworks", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/GetTokenDirectory": { + name: "GetTokenDirectory", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/SearchTokenDirectory": { + name: "SearchTokenDirectory", + service: "Metadata", + annotations: map[string]string{}, + }, + "/rpc/Metadata/DirectoryGetNetworks": { + name: "DirectoryGetNetworks", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use GetTokenDirectoryNetworks instead."}, + }, + "/rpc/Metadata/DirectoryGetCollections": { + name: "DirectoryGetCollections", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use GetTokenDirectory instead."}, + }, + "/rpc/Metadata/DirectorySearchCollections": { + name: "DirectorySearchCollections", + service: "Metadata", + annotations: map[string]string{"deprecated": "Use SearchTokenDirectory instead."}, + }, + "/rpc/Metadata/GetNiftyswapTokenQuantity": { + name: "GetNiftyswapTokenQuantity", + service: "Metadata", + annotations: map[string]string{"internal": ""}, + }, + "/rpc/Metadata/GetNiftyswapUnitPrices": { + name: "GetNiftyswapUnitPrices", + service: "Metadata", + annotations: map[string]string{"internal": ""}, + }, + "/rpc/Metadata/GetNiftyswapUnitPricesWithQuantities": { + name: "GetNiftyswapUnitPricesWithQuantities", + service: "Metadata", + annotations: map[string]string{"internal": ""}, + }, + "/rpc/Collections/CreateCollection": { + name: "CreateCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/GetCollection": { + name: "GetCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/ListCollections": { + name: "ListCollections", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/UpdateCollection": { + name: "UpdateCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/DeleteCollection": { + name: "DeleteCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/PublishCollection": { + name: "PublishCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/UnpublishCollection": { + name: "UnpublishCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/CreateContractCollection": { + name: "CreateContractCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/GetContractCollection": { + name: "GetContractCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/ListContractCollections": { + name: "ListContractCollections", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/UpdateContractCollection": { + name: "UpdateContractCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/DeleteContractCollection": { + name: "DeleteContractCollection", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/CreateToken": { + name: "CreateToken", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/GetToken": { + name: "GetToken", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/ListTokens": { + name: "ListTokens", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/UpdateToken": { + name: "UpdateToken", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/DeleteToken": { + name: "DeleteToken", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/CreateAsset": { + name: "CreateAsset", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/GetAsset": { + name: "GetAsset", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/UpdateAsset": { + name: "UpdateAsset", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Collections/DeleteAsset": { + name: "DeleteAsset", + service: "Collections", + annotations: map[string]string{}, + }, + "/rpc/Admin/RefreshContractInfoUpdatedBefore": { + name: "RefreshContractInfoUpdatedBefore", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/RefreshTokenMetadataUpdatedBefore": { + name: "RefreshTokenMetadataUpdatedBefore", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/GetContractInfoOverride": { + name: "GetContractInfoOverride", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/GetContractInfoOverrides": { + name: "GetContractInfoOverrides", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/AddContractInfoOverride": { + name: "AddContractInfoOverride", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/UpdateContractInfoOverride": { + name: "UpdateContractInfoOverride", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/RemoveContractInfoOverride": { + name: "RemoveContractInfoOverride", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/IsInTokenDirectory": { + name: "IsInTokenDirectory", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/SetTokenDirectoryFeatureIndex": { + name: "SetTokenDirectoryFeatureIndex", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/AddContractToTokenDirectory": { + name: "AddContractToTokenDirectory", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/RemoveContractFromTokenDirectory": { + name: "RemoveContractFromTokenDirectory", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/RefreshTokenDirectory": { + name: "RefreshTokenDirectory", + service: "Admin", + annotations: map[string]string{}, + }, + "/rpc/Admin/AddContractsToTokenDirectory": { + name: "AddContractsToTokenDirectory", + service: "Admin", + annotations: map[string]string{"deprecated": "use new admin api"}, + }, + "/rpc/Admin/RemoveContractsFromTokenDirectory": { + name: "RemoveContractsFromTokenDirectory", + service: "Admin", + annotations: map[string]string{"deprecated": "use new admin api"}, + }, + "/rpc/Admin/ModifyFeatureIndex": { + name: "ModifyFeatureIndex", + service: "Admin", + annotations: map[string]string{"deprecated": "use new admin api"}, + }, + "/rpc/Admin/GetFeatureIndex": { + name: "GetFeatureIndex", + service: "Admin", + annotations: map[string]string{"deprecated": "use new admin api"}, + }, + "/rpc/Admin/ListTokenDirectory": { + name: "ListTokenDirectory", + service: "Admin", + annotations: map[string]string{"deprecated": "use new admin api"}, + }, +} + +func WebrpcMethods() map[string]method { + res := make(map[string]method, len(methods)) + for k, v := range methods { + res[k] = v + } + + return res +} + +var WebRPCServices = map[string][]string{ + "Metadata": { + "Ping", + "Version", + "RuntimeStatus", + "GetTask", + "GetTaskStatus", + "GetContractInfo", + "GetContractInfoBatch", + "FindContractInfo", + "FindContractInfoBatch", + "RefreshContractInfo", + "RefreshContractInfoBatch", + "SearchContractsByQuery", + "SearchContractInfo", + "SearchContractInfoBatch", + "SearchContracts", + "SearchMetadata", + "GetTokenMetadata", + "GetTokenMetadataBatch", + "RefreshTokenMetadata", + "SearchTokenMetadataByQuery", + "SearchTokenMetadata", + "SearchTokenMetadataTokenIDs", + "GetTokenMetadataPropertyFilters", + "RefreshAllContractTokens", + "SearchTokens", + "TokenCollectionFilters", + "GetTokenRefreshStatus", + "SearchTokenIDs", + "GetTokenDirectoryNetworks", + "GetTokenDirectory", + "SearchTokenDirectory", + "DirectoryGetNetworks", + "DirectoryGetCollections", + "DirectorySearchCollections", + "GetNiftyswapTokenQuantity", + "GetNiftyswapUnitPrices", + "GetNiftyswapUnitPricesWithQuantities", + }, + "Collections": { + "CreateCollection", + "GetCollection", + "ListCollections", + "UpdateCollection", + "DeleteCollection", + "PublishCollection", + "UnpublishCollection", + "CreateContractCollection", + "GetContractCollection", + "ListContractCollections", + "UpdateContractCollection", + "DeleteContractCollection", + "CreateToken", + "GetToken", + "ListTokens", + "UpdateToken", + "DeleteToken", + "CreateAsset", + "GetAsset", + "UpdateAsset", + "DeleteAsset", + }, + "Admin": { + "RefreshContractInfoUpdatedBefore", + "RefreshTokenMetadataUpdatedBefore", + "GetContractInfoOverride", + "GetContractInfoOverrides", + "AddContractInfoOverride", + "UpdateContractInfoOverride", + "RemoveContractInfoOverride", + "IsInTokenDirectory", + "SetTokenDirectoryFeatureIndex", + "AddContractToTokenDirectory", + "RemoveContractFromTokenDirectory", + "RefreshTokenDirectory", + "AddContractsToTokenDirectory", + "RemoveContractsFromTokenDirectory", + "ModifyFeatureIndex", + "GetFeatureIndex", + "ListTokenDirectory", + }, +} + +// +// Client +// + +const MetadataPathPrefix = "/rpc/Metadata/" +const CollectionsPathPrefix = "/rpc/Collections/" +const AdminPathPrefix = "/rpc/Admin/" + +type metadataClient struct { + client HTTPClient + urls [37]string +} + +func NewMetadataClient(addr string, client HTTPClient) MetadataClient { + prefix := urlBase(addr) + MetadataPathPrefix + urls := [37]string{ + prefix + "Ping", + prefix + "Version", + prefix + "RuntimeStatus", + prefix + "GetTask", + prefix + "GetTaskStatus", + prefix + "GetContractInfo", + prefix + "GetContractInfoBatch", + prefix + "FindContractInfo", + prefix + "FindContractInfoBatch", + prefix + "RefreshContractInfo", + prefix + "RefreshContractInfoBatch", + prefix + "SearchContractsByQuery", + prefix + "SearchContractInfo", + prefix + "SearchContractInfoBatch", + prefix + "SearchContracts", + prefix + "SearchMetadata", + prefix + "GetTokenMetadata", + prefix + "GetTokenMetadataBatch", + prefix + "RefreshTokenMetadata", + prefix + "SearchTokenMetadataByQuery", + prefix + "SearchTokenMetadata", + prefix + "SearchTokenMetadataTokenIDs", + prefix + "GetTokenMetadataPropertyFilters", + prefix + "RefreshAllContractTokens", + prefix + "SearchTokens", + prefix + "TokenCollectionFilters", + prefix + "GetTokenRefreshStatus", + prefix + "SearchTokenIDs", + prefix + "GetTokenDirectoryNetworks", + prefix + "GetTokenDirectory", + prefix + "SearchTokenDirectory", + prefix + "DirectoryGetNetworks", + prefix + "DirectoryGetCollections", + prefix + "DirectorySearchCollections", + prefix + "GetNiftyswapTokenQuantity", + prefix + "GetNiftyswapUnitPrices", + prefix + "GetNiftyswapUnitPricesWithQuantities", + } + return &metadataClient{ + client: client, + urls: urls, + } +} + +func (c *metadataClient) Ping(ctx context.Context) (bool, error) { + out := struct { + Ret0 bool `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[0], nil, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) Version(ctx context.Context) (*Version, error) { + out := struct { + Ret0 *Version `json:"version"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[1], nil, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) RuntimeStatus(ctx context.Context) (*RuntimeStatus, error) { + out := struct { + Ret0 *RuntimeStatus `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[2], nil, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) GetTask(ctx context.Context, taskId uint64) (*Task, error) { + in := struct { + Arg0 uint64 `json:"taskId"` + }{taskId} + out := struct { + Ret0 *Task `json:"task"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[3], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) GetTaskStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) { + in := struct { + Arg0 uint64 `json:"taskId"` + }{taskId} + out := struct { + Ret0 *TaskStatus `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[4], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) GetContractInfo(ctx context.Context, chainID string, contractAddress string) (*ContractInfo, *uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 *ContractInfo `json:"contractInfo"` + Ret1 *uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[5], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (map[string]*ContractInfo, *uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 []string `json:"contractAddresses"` + }{chainID, contractAddresses} + out := struct { + Ret0 map[string]*ContractInfo `json:"contractInfoMap"` + Ret1 *uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[6], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) FindContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) { + in := struct { + Arg0 string `json:"contractAddress"` + }{contractAddress} + out := struct { + Ret0 []*ContractInfo `json:"contractInfoList"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[7], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) FindContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) { + in := struct { + Arg0 []string `json:"contractAddresses"` + }{contractAddresses} + out := struct { + Ret0 map[string][]*ContractInfo `json:"contractInfoByChain"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[8], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) RefreshContractInfo(ctx context.Context, chainID string, contractAddress string) (*uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 *uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[9], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) RefreshContractInfoBatch(ctx context.Context, chainID string, contractAddresses []string) (*uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 []string `json:"contractAddresses"` + }{chainID, contractAddresses} + out := struct { + Ret0 *uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[10], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) SearchContractsByQuery(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) { + in := struct { + Arg0 string `json:"q"` + Arg1 *string `json:"chainID"` + Arg2 []string `json:"chainIDs"` + Arg3 []ContractType `json:"types"` + Arg4 *Page `json:"page"` + }{q, chainID, chainIDs, types, page} + out := struct { + Ret0 []*ContractInfo `json:"contractInfo"` + Ret1 *Page `json:"nextPage"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[11], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) SearchContractInfo(ctx context.Context, contractAddress string) ([]*ContractInfo, error) { + in := struct { + Arg0 string `json:"contractAddress"` + }{contractAddress} + out := struct { + Ret0 []*ContractInfo `json:"contractInfoList"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[12], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) SearchContractInfoBatch(ctx context.Context, contractAddresses []string) (map[string][]*ContractInfo, error) { + in := struct { + Arg0 []string `json:"contractAddresses"` + }{contractAddresses} + out := struct { + Ret0 map[string][]*ContractInfo `json:"contractInfoByChain"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[13], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) SearchContracts(ctx context.Context, q string, chainID *string, chainIDs []string, types []ContractType, page *Page) ([]*ContractInfo, *Page, error) { + in := struct { + Arg0 string `json:"q"` + Arg1 *string `json:"chainID"` + Arg2 []string `json:"chainIDs"` + Arg3 []ContractType `json:"types"` + Arg4 *Page `json:"page"` + }{q, chainID, chainIDs, types, page} + out := struct { + Ret0 []*ContractInfo `json:"contractInfo"` + Ret1 *Page `json:"nextPage"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[14], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) SearchMetadata(ctx context.Context, filter string, chainID *string, types []ContractType, excludeTokenMetadata *bool) ([]*TokenMetadata, []*ContractInfo, error) { + in := struct { + Arg0 string `json:"filter"` + Arg1 *string `json:"chainID"` + Arg2 []ContractType `json:"types"` + Arg3 *bool `json:"excludeTokenMetadata"` + }{filter, chainID, types, excludeTokenMetadata} + out := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + Ret1 []*ContractInfo `json:"contractInfo"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[15], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) ([]*TokenMetadata, *uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + }{chainID, contractAddress, tokenIDs} + out := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + Ret1 *uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[16], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetTokenMetadataBatch(ctx context.Context, chainID string, contractTokenMap map[string][]string) (map[string][]*TokenMetadata, *uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 map[string][]string `json:"contractTokenMap"` + }{chainID, contractTokenMap} + out := struct { + Ret0 map[string][]*TokenMetadata `json:"contractTokenMetadata"` + Ret1 *uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[17], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) RefreshTokenMetadata(ctx context.Context, chainID string, contractAddress string, tokenIDs []string, newMints *bool) (uint64, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + Arg3 *bool `json:"newMints"` + }{chainID, contractAddress, tokenIDs, newMints} + out := struct { + Ret0 uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[18], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) SearchTokenMetadataByQuery(ctx context.Context, q string, chainID *string, contractAddress *string, page *Page) ([]*TokenMetadata, *Page, error) { + in := struct { + Arg0 string `json:"q"` + Arg1 *string `json:"chainID"` + Arg2 *string `json:"contractAddress"` + Arg3 *Page `json:"page"` + }{q, chainID, contractAddress, page} + out := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + Ret1 *Page `json:"nextPage"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[19], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) SearchTokenMetadata(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []*TokenMetadata, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *Filter `json:"filter"` + Arg3 *Page `json:"page"` + }{chainID, contractAddress, filter, page} + out := struct { + Ret0 *Page `json:"page"` + Ret1 []*TokenMetadata `json:"tokenMetadata"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[20], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) SearchTokenMetadataTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *Filter `json:"filter"` + Arg3 *Page `json:"page"` + }{chainID, contractAddress, filter, page} + out := struct { + Ret0 *Page `json:"page"` + Ret1 []string `json:"tokenIDs"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[21], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetTokenMetadataPropertyFilters(ctx context.Context, chainID string, contractAddress string, excludeProperties []string, excludePropertyValues *bool) ([]*PropertyFilter, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"excludeProperties"` + Arg3 *bool `json:"excludePropertyValues"` + }{chainID, contractAddress, excludeProperties, excludePropertyValues} + out := struct { + Ret0 []*PropertyFilter `json:"filters"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[22], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) RefreshAllContractTokens(ctx context.Context, chainHandle string, contractAddress string) (*uint64, uint64, error) { + in := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + }{chainHandle, contractAddress} + out := struct { + Ret0 *uint64 `json:"taskID"` + Ret1 uint64 `json:"retryAfter"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[23], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) SearchTokens(ctx context.Context, q string, chainID *string, page *Page) ([]*TokenMetadata, *Page, error) { + in := struct { + Arg0 string `json:"q"` + Arg1 *string `json:"chainID"` + Arg2 *Page `json:"page"` + }{q, chainID, page} + out := struct { + Ret0 []*TokenMetadata `json:"tokenMetadata"` + Ret1 *Page `json:"nextPage"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[24], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) TokenCollectionFilters(ctx context.Context, chainID string, contractAddress string) ([]*PropertyFilter, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 []*PropertyFilter `json:"filters"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[25], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) GetTokenRefreshStatus(ctx context.Context, taskId uint64) (*TaskStatus, error) { + in := struct { + Arg0 uint64 `json:"taskId"` + }{taskId} + out := struct { + Ret0 *TaskStatus `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[26], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) SearchTokenIDs(ctx context.Context, chainID string, contractAddress string, filter *Filter, page *Page) (*Page, []string, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *Filter `json:"filter"` + Arg3 *Page `json:"page"` + }{chainID, contractAddress, filter, page} + out := struct { + Ret0 *Page `json:"page"` + Ret1 []string `json:"tokenIds"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[27], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetTokenDirectoryNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, []string, error) { + in := struct { + Arg0 *bool `json:"includeTestnets"` + Arg1 *bool `json:"onlyFeatured"` + }{includeTestnets, onlyFeatured} + out := struct { + Ret0 []uint64 `json:"chainIDs"` + Ret1 []string `json:"networks"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[28], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetTokenDirectory(ctx context.Context, chainID *string, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) { + in := struct { + Arg0 *string `json:"chainID"` + Arg1 *bool `json:"includeTestnets"` + Arg2 *bool `json:"onlyFeatured"` + Arg3 *Page `json:"page"` + }{chainID, includeTestnets, onlyFeatured, page} + out := struct { + Ret0 []*ContractInfo `json:"contracts"` + Ret1 *Page `json:"page"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[29], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) SearchTokenDirectory(ctx context.Context, query string, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) { + in := struct { + Arg0 string `json:"query"` + Arg1 *uint64 `json:"chainID"` + Arg2 *bool `json:"includeTestnets"` + Arg3 *bool `json:"onlyFeatured"` + Arg4 *Page `json:"page"` + }{query, chainID, includeTestnets, onlyFeatured, page} + out := struct { + Ret0 []*ContractInfo `json:"contracts"` + Ret1 *Page `json:"page"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[30], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) DirectoryGetNetworks(ctx context.Context, includeTestnets *bool, onlyFeatured *bool) ([]uint64, error) { + in := struct { + Arg0 *bool `json:"includeTestnets"` + Arg1 *bool `json:"onlyFeatured"` + }{includeTestnets, onlyFeatured} + out := struct { + Ret0 []uint64 `json:"networks"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[31], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) DirectoryGetCollections(ctx context.Context, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) { + in := struct { + Arg0 *uint64 `json:"chainId"` + Arg1 *bool `json:"includeTestnets"` + Arg2 *bool `json:"onlyFeatured"` + Arg3 *Page `json:"page"` + }{chainId, includeTestnets, onlyFeatured, page} + out := struct { + Ret0 []*ContractInfo `json:"collections"` + Ret1 *Page `json:"page"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[32], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) DirectorySearchCollections(ctx context.Context, query string, chainId *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) ([]*ContractInfo, *Page, error) { + in := struct { + Arg0 string `json:"query"` + Arg1 *uint64 `json:"chainId"` + Arg2 *bool `json:"includeTestnets"` + Arg3 *bool `json:"onlyFeatured"` + Arg4 *Page `json:"page"` + }{query, chainId, includeTestnets, onlyFeatured, page} + out := struct { + Ret0 []*ContractInfo `json:"collections"` + Ret1 *Page `json:"page"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[33], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *metadataClient) GetNiftyswapTokenQuantity(ctx context.Context, chainID string, contractAddress string, tokenIDs []string) (map[string]string, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 []string `json:"tokenIDs"` + }{chainID, contractAddress, tokenIDs} + out := struct { + Ret0 map[string]string `json:"quantity"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[34], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) GetNiftyswapUnitPrices(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]string, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *GetNiftyswapUnitPricesRequest `json:"req"` + Arg3 bool `json:"fresh"` + }{chainID, contractAddress, req, fresh} + out := struct { + Ret0 map[string]string `json:"prices"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[35], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *metadataClient) GetNiftyswapUnitPricesWithQuantities(ctx context.Context, chainID string, contractAddress string, req *GetNiftyswapUnitPricesRequest, fresh bool) (map[string]*GetNiftyswapUnitPricesResponse, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *GetNiftyswapUnitPricesRequest `json:"req"` + Arg3 bool `json:"fresh"` + }{chainID, contractAddress, req, fresh} + out := struct { + Ret0 map[string]*GetNiftyswapUnitPricesResponse `json:"prices"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[36], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +type collectionsClient struct { + client HTTPClient + urls [21]string +} + +func NewCollectionsClient(addr string, client HTTPClient) CollectionsClient { + prefix := urlBase(addr) + CollectionsPathPrefix + urls := [21]string{ + prefix + "CreateCollection", + prefix + "GetCollection", + prefix + "ListCollections", + prefix + "UpdateCollection", + prefix + "DeleteCollection", + prefix + "PublishCollection", + prefix + "UnpublishCollection", + prefix + "CreateContractCollection", + prefix + "GetContractCollection", + prefix + "ListContractCollections", + prefix + "UpdateContractCollection", + prefix + "DeleteContractCollection", + prefix + "CreateToken", + prefix + "GetToken", + prefix + "ListTokens", + prefix + "UpdateToken", + prefix + "DeleteToken", + prefix + "CreateAsset", + prefix + "GetAsset", + prefix + "UpdateAsset", + prefix + "DeleteAsset", + } + return &collectionsClient{ + client: client, + urls: urls, + } +} + +func (c *collectionsClient) CreateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Collection `json:"collection"` + }{projectId, collection} + out := struct { + Ret0 *Collection `json:"collection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[0], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) GetCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + }{projectId, collectionId} + out := struct { + Ret0 *Collection `json:"collection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[1], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) ListCollections(ctx context.Context, projectId *uint64, page *Page) (*Page, []*Collection, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Page `json:"page"` + }{projectId, page} + out := struct { + Ret0 *Page `json:"page"` + Ret1 []*Collection `json:"collections"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[2], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *collectionsClient) UpdateCollection(ctx context.Context, projectId *uint64, collection *Collection) (*Collection, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Collection `json:"collection"` + }{projectId, collection} + out := struct { + Ret0 *Collection `json:"collection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[3], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) DeleteCollection(ctx context.Context, projectId *uint64, collectionId uint64) (bool, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + }{projectId, collectionId} + out := struct { + Ret0 bool `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[4], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) PublishCollection(ctx context.Context, projectId *uint64, collectionId uint64, recursive *bool) (*Collection, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 *bool `json:"recursive"` + }{projectId, collectionId, recursive} + out := struct { + Ret0 *Collection `json:"collection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[5], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) UnpublishCollection(ctx context.Context, projectId *uint64, collectionId uint64) (*Collection, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + }{projectId, collectionId} + out := struct { + Ret0 *Collection `json:"collection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[6], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) CreateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (*ContractCollection, error) { + in := struct { + Arg0 uint64 `json:"projectId"` + Arg1 *ContractCollection `json:"contractCollection"` + }{projectId, contractCollection} + out := struct { + Ret0 *ContractCollection `json:"contractCollection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[7], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) GetContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (*ContractCollection, error) { + in := struct { + Arg0 uint64 `json:"projectId"` + Arg1 uint64 `json:"chainId"` + Arg2 string `json:"contractAddress"` + }{projectId, chainId, contractAddress} + out := struct { + Ret0 *ContractCollection `json:"contractCollection"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[8], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) ListContractCollections(ctx context.Context, projectId uint64, collectionId *uint64, page *Page) ([]*ContractCollection, []*Collection, *Page, error) { + in := struct { + Arg0 uint64 `json:"projectId"` + Arg1 *uint64 `json:"collectionId"` + Arg2 *Page `json:"page"` + }{projectId, collectionId, page} + out := struct { + Ret0 []*ContractCollection `json:"contractCollections"` + Ret1 []*Collection `json:"collections"` + Ret2 *Page `json:"page"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[9], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, out.Ret2, err +} + +func (c *collectionsClient) UpdateContractCollection(ctx context.Context, projectId uint64, contractCollection *ContractCollection) (bool, error) { + in := struct { + Arg0 uint64 `json:"projectId"` + Arg1 *ContractCollection `json:"contractCollection"` + }{projectId, contractCollection} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[10], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) DeleteContractCollection(ctx context.Context, projectId uint64, chainId uint64, contractAddress string) (bool, error) { + in := struct { + Arg0 uint64 `json:"projectId"` + Arg1 uint64 `json:"chainId"` + Arg2 string `json:"contractAddress"` + }{projectId, chainId, contractAddress} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[11], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) CreateToken(ctx context.Context, projectId *uint64, collectionId uint64, token *TokenMetadata, private *bool) (*TokenMetadata, []*Asset, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 *TokenMetadata `json:"token"` + Arg3 *bool `json:"private"` + }{projectId, collectionId, token, private} + out := struct { + Ret0 *TokenMetadata `json:"token"` + Ret1 []*Asset `json:"assets"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[12], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *collectionsClient) GetToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (*TokenMetadata, []*Asset, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 string `json:"tokenId"` + }{projectId, collectionId, tokenId} + out := struct { + Ret0 *TokenMetadata `json:"token"` + Ret1 []*Asset `json:"assets"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[13], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *collectionsClient) ListTokens(ctx context.Context, projectId *uint64, collectionId uint64, page *Page) (*Page, []*TokenMetadata, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 *Page `json:"page"` + }{projectId, collectionId, page} + out := struct { + Ret0 *Page `json:"page"` + Ret1 []*TokenMetadata `json:"tokens"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[14], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *collectionsClient) UpdateToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string, token *TokenMetadata, private *bool) (*TokenMetadata, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 string `json:"tokenId"` + Arg3 *TokenMetadata `json:"token"` + Arg4 *bool `json:"private"` + }{projectId, collectionId, tokenId, token, private} + out := struct { + Ret0 *TokenMetadata `json:"token"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[15], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) DeleteToken(ctx context.Context, projectId *uint64, collectionId uint64, tokenId string) (bool, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"collectionId"` + Arg2 string `json:"tokenId"` + }{projectId, collectionId, tokenId} + out := struct { + Ret0 bool `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[16], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) CreateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Asset `json:"asset"` + }{projectId, asset} + out := struct { + Ret0 *Asset `json:"asset"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[17], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) GetAsset(ctx context.Context, projectId *uint64, assetId uint64) (*Asset, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"assetId"` + }{projectId, assetId} + out := struct { + Ret0 *Asset `json:"asset"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[18], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) UpdateAsset(ctx context.Context, projectId *uint64, asset *Asset) (*Asset, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 *Asset `json:"asset"` + }{projectId, asset} + out := struct { + Ret0 *Asset `json:"asset"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[19], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *collectionsClient) DeleteAsset(ctx context.Context, projectId *uint64, assetId uint64) (bool, error) { + in := struct { + Arg0 *uint64 `json:"projectId"` + Arg1 uint64 `json:"assetId"` + }{projectId, assetId} + out := struct { + Ret0 bool `json:"status"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[20], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +type adminClient struct { + client HTTPClient + urls [17]string +} + +func NewAdminClient(addr string, client HTTPClient) AdminClient { + prefix := urlBase(addr) + AdminPathPrefix + urls := [17]string{ + prefix + "RefreshContractInfoUpdatedBefore", + prefix + "RefreshTokenMetadataUpdatedBefore", + prefix + "GetContractInfoOverride", + prefix + "GetContractInfoOverrides", + prefix + "AddContractInfoOverride", + prefix + "UpdateContractInfoOverride", + prefix + "RemoveContractInfoOverride", + prefix + "IsInTokenDirectory", + prefix + "SetTokenDirectoryFeatureIndex", + prefix + "AddContractToTokenDirectory", + prefix + "RemoveContractFromTokenDirectory", + prefix + "RefreshTokenDirectory", + prefix + "AddContractsToTokenDirectory", + prefix + "RemoveContractsFromTokenDirectory", + prefix + "ModifyFeatureIndex", + prefix + "GetFeatureIndex", + prefix + "ListTokenDirectory", + } + return &adminClient{ + client: client, + urls: urls, + } +} + +func (c *adminClient) RefreshContractInfoUpdatedBefore(ctx context.Context, before string, maxContractNumber int) ([]uint64, error) { + in := struct { + Arg0 string `json:"before"` + Arg1 int `json:"maxContractNumber"` + }{before, maxContractNumber} + out := struct { + Ret0 []uint64 `json:"taskIDs"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[0], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) RefreshTokenMetadataUpdatedBefore(ctx context.Context, before string, maxTokenNumber int) ([]uint64, error) { + in := struct { + Arg0 string `json:"before"` + Arg1 int `json:"maxTokenNumber"` + }{before, maxTokenNumber} + out := struct { + Ret0 []uint64 `json:"taskIDs"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[1], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) GetContractInfoOverride(ctx context.Context, chainID string, contractAddress string) (*ContractInfoOverride, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 *ContractInfoOverride `json:"contractInfoOverride"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[2], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) GetContractInfoOverrides(ctx context.Context, chainID *string, page *Page) ([]*ContractInfoOverride, *Page, error) { + in := struct { + Arg0 *string `json:"chainID"` + Arg1 *Page `json:"page"` + }{chainID, page} + out := struct { + Ret0 []*ContractInfoOverride `json:"contractInfoOverrides"` + Ret1 *Page `json:"page"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[3], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *adminClient) AddContractInfoOverride(ctx context.Context, chainID string, contractAddress string, contractInfoOverride *ContractInfoOverride) (bool, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *ContractInfoOverride `json:"contractInfoOverride"` + }{chainID, contractAddress, contractInfoOverride} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[4], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) UpdateContractInfoOverride(ctx context.Context, chainID string, contractAddress string, contractInfoOverride *ContractInfoOverride) (bool, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 *ContractInfoOverride `json:"contractInfoOverride"` + }{chainID, contractAddress, contractInfoOverride} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[5], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) RemoveContractInfoOverride(ctx context.Context, chainID string, contractAddress string) (bool, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[6], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) IsInTokenDirectory(ctx context.Context, chainID string, contractAddress string) (bool, uint8, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 bool `json:"ok"` + Ret1 uint8 `json:"featureIndex"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[7], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +func (c *adminClient) SetTokenDirectoryFeatureIndex(ctx context.Context, chainID string, contractAddress string, featureIndex uint8) (bool, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + Arg2 uint8 `json:"featureIndex"` + }{chainID, contractAddress, featureIndex} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[8], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) AddContractToTokenDirectory(ctx context.Context, chainID string, contractAddress string) (bool, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[9], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) RemoveContractFromTokenDirectory(ctx context.Context, chainID string, contractAddress string) (bool, error) { + in := struct { + Arg0 string `json:"chainID"` + Arg1 string `json:"contractAddress"` + }{chainID, contractAddress} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[10], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) RefreshTokenDirectory(ctx context.Context) (uint64, error) { + out := struct { + Ret0 uint64 `json:"taskID"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[11], nil, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) AddContractsToTokenDirectory(ctx context.Context, contracts []*ContractInfo, featureIndexes []uint8) (bool, error) { + in := struct { + Arg0 []*ContractInfo `json:"contracts"` + Arg1 []uint8 `json:"featureIndexes"` + }{contracts, featureIndexes} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[12], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) RemoveContractsFromTokenDirectory(ctx context.Context, chainHandle string, contracts []string) (bool, error) { + in := struct { + Arg0 string `json:"chainHandle"` + Arg1 []string `json:"contracts"` + }{chainHandle, contracts} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[13], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) ModifyFeatureIndex(ctx context.Context, chainHandle string, contractAddress string, featured uint8) (bool, error) { + in := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + Arg2 uint8 `json:"featured"` + }{chainHandle, contractAddress, featured} + out := struct { + Ret0 bool `json:"ok"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[14], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) GetFeatureIndex(ctx context.Context, chainHandle string, contractAddress string) (uint8, error) { + in := struct { + Arg0 string `json:"chainHandle"` + Arg1 string `json:"contractAddress"` + }{chainHandle, contractAddress} + out := struct { + Ret0 uint8 `json:"featured"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[15], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, err +} + +func (c *adminClient) ListTokenDirectory(ctx context.Context, chainID *uint64, includeTestnets *bool, onlyFeatured *bool, page *Page) (*Page, []*ContractInfo, error) { + in := struct { + Arg0 *uint64 `json:"chainID"` + Arg1 *bool `json:"includeTestnets"` + Arg2 *bool `json:"onlyFeatured"` + Arg3 *Page `json:"page"` + }{chainID, includeTestnets, onlyFeatured, page} + out := struct { + Ret0 *Page `json:"page"` + Ret1 []*ContractInfo `json:"collections"` + }{} + + resp, err := doHTTPRequest(ctx, c.client, c.urls[16], in, &out) + if resp != nil { + cerr := resp.Body.Close() + if err == nil && cerr != nil { + err = ErrWebrpcRequestFailed.WithCausef("failed to close response body: %w", cerr) + } + } + + return out.Ret0, out.Ret1, err +} + +// +// Client helpers +// + +// HTTPClient is the interface used by generated clients to send HTTP requests. +// It is fulfilled by *(net/http).Client, which is sufficient for most users. +// Users can provide their own implementation for special retry policies. +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) +} + +// urlBase helps ensure that addr specifies a scheme. If it is unparsable +// as a URL, it returns addr unchanged. +func urlBase(addr string) string { + // If the addr specifies a scheme, use it. If not, default to + // http. If url.Parse fails on it, return it unchanged. + url, err := url.Parse(addr) + if err != nil { + return addr + } + if url.Scheme == "" { + url.Scheme = "http" + } + return url.String() +} + +// newRequest makes an http.Request from a client, adding common headers. +func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, "POST", url, reqBody) + if err != nil { + return nil, err + } + req.Header.Set("Accept", contentType) + req.Header.Set("Content-Type", contentType) + req.Header.Set(WebrpcHeader, WebrpcHeaderValue) + if headers, ok := HTTPRequestHeaders(ctx); ok { + for k := range headers { + for _, v := range headers[k] { + req.Header.Add(k, v) + } + } + } + return req, nil +} + +// doHTTPRequest is common code to make a request to the remote service. +func doHTTPRequest(ctx context.Context, client HTTPClient, url string, in, out interface{}) (*http.Response, error) { + reqBody, err := json.Marshal(in) + if err != nil { + return nil, ErrWebrpcRequestFailed.WithCausef("failed to marshal JSON body: %w", err) + } + if err = ctx.Err(); err != nil { + return nil, ErrWebrpcRequestFailed.WithCausef("aborted because context was done: %w", err) + } + + req, err := newRequest(ctx, url, bytes.NewBuffer(reqBody), "application/json") + if err != nil { + return nil, ErrWebrpcRequestFailed.WithCausef("could not build request: %w", err) + } + + resp, err := client.Do(req) + if err != nil { + return nil, ErrWebrpcRequestFailed.WithCause(err) + } + + if resp.StatusCode != 200 { + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, ErrWebrpcBadResponse.WithCausef("failed to read server error response body: %w", err) + } + + var rpcErr WebRPCError + if err := json.Unmarshal(respBody, &rpcErr); err != nil { + return nil, ErrWebrpcBadResponse.WithCausef("failed to unmarshal server error: %w", err) + } + if rpcErr.Cause != "" { + rpcErr.cause = errors.New(rpcErr.Cause) + } + return nil, rpcErr + } + + if out != nil { + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, ErrWebrpcBadResponse.WithCausef("failed to read response body: %w", err) + } + + err = json.Unmarshal(respBody, &out) + if err != nil { + return nil, ErrWebrpcBadResponse.WithCausef("failed to unmarshal JSON response body: %w", err) + } + } + + return resp, nil +} + +func WithHTTPRequestHeaders(ctx context.Context, h http.Header) (context.Context, error) { + if _, ok := h["Accept"]; ok { + return nil, errors.New("provided header cannot set Accept") + } + if _, ok := h["Content-Type"]; ok { + return nil, errors.New("provided header cannot set Content-Type") + } + + copied := make(http.Header, len(h)) + for k, vv := range h { + if vv == nil { + copied[k] = nil + continue + } + copied[k] = make([]string, len(vv)) + copy(copied[k], vv) + } + + return context.WithValue(ctx, HTTPClientRequestHeadersCtxKey, copied), nil +} + +func HTTPRequestHeaders(ctx context.Context) (http.Header, bool) { + h, ok := ctx.Value(HTTPClientRequestHeadersCtxKey).(http.Header) + return h, ok +} + +// +// Webrpc helpers +// + +type method struct { + name string + service string + annotations map[string]string +} + +func (m method) Name() string { + return m.name +} + +func (m method) Service() string { + return m.service +} + +func (m method) Annotations() map[string]string { + res := make(map[string]string, len(m.annotations)) + for k, v := range m.annotations { + res[k] = v + } + + return res +} + +type contextKey struct { + name string +} + +func (k *contextKey) String() string { + return "webrpc context value " + k.name +} + +var ( + HTTPClientRequestHeadersCtxKey = &contextKey{"HTTPClientRequestHeaders"} // client + HTTPRequestCtxKey = &contextKey{"HTTPRequest"} // server + ServiceNameCtxKey = &contextKey{"ServiceName"} // server + MethodNameCtxKey = &contextKey{"MethodName"} // server +) + +func ServiceNameFromContext(ctx context.Context) string { + service, _ := ctx.Value(ServiceNameCtxKey).(string) + return service +} + +func MethodNameFromContext(ctx context.Context) string { + method, _ := ctx.Value(MethodNameCtxKey).(string) + return method +} + +func RequestFromContext(ctx context.Context) *http.Request { + r, _ := ctx.Value(HTTPRequestCtxKey).(*http.Request) + return r +} + +func MethodCtx(ctx context.Context) (method, bool) { + req := RequestFromContext(ctx) + if req == nil { + return method{}, false + } + + m, ok := methods[req.URL.Path] + if !ok { + return method{}, false + } + + return m, true +} + +// PtrTo is a useful helper when constructing values for optional fields. +func PtrTo[T any](v T) *T { return &v } + +// +// Errors +// + +type WebRPCError struct { + Name string `json:"error"` + Code int `json:"code"` + Message string `json:"msg"` + Cause string `json:"cause,omitempty"` + HTTPStatus int `json:"status"` + cause error +} + +var _ error = WebRPCError{} + +func (e WebRPCError) Error() string { + if e.cause != nil { + return fmt.Sprintf("%s %d: %s: %v", e.Name, e.Code, e.Message, e.cause) + } + return fmt.Sprintf("%s %d: %s", e.Name, e.Code, e.Message) +} + +func (e WebRPCError) Is(target error) bool { + if target == nil { + return false + } + if rpcErr, ok := target.(WebRPCError); ok { + return rpcErr.Code == e.Code + } + return errors.Is(e.cause, target) +} + +func (e WebRPCError) Unwrap() error { + return e.cause +} + +func (e WebRPCError) WithCause(cause error) WebRPCError { + err := e + err.cause = cause + err.Cause = cause.Error() + return err +} + +func (e WebRPCError) WithCausef(format string, args ...interface{}) WebRPCError { + cause := fmt.Errorf(format, args...) + err := e + err.cause = cause + err.Cause = cause.Error() + return err +} + +// Deprecated: Use .WithCause() method on WebRPCError. +func ErrorWithCause(rpcErr WebRPCError, cause error) WebRPCError { + return rpcErr.WithCause(cause) +} + +// Webrpc errors +var ( + ErrWebrpcEndpoint = WebRPCError{Code: 0, Name: "WebrpcEndpoint", Message: "endpoint error", HTTPStatus: 400} + ErrWebrpcRequestFailed = WebRPCError{Code: -1, Name: "WebrpcRequestFailed", Message: "request failed", HTTPStatus: 400} + ErrWebrpcBadRoute = WebRPCError{Code: -2, Name: "WebrpcBadRoute", Message: "bad route", HTTPStatus: 404} + ErrWebrpcBadMethod = WebRPCError{Code: -3, Name: "WebrpcBadMethod", Message: "bad method", HTTPStatus: 405} + ErrWebrpcBadRequest = WebRPCError{Code: -4, Name: "WebrpcBadRequest", Message: "bad request", HTTPStatus: 400} + ErrWebrpcBadResponse = WebRPCError{Code: -5, Name: "WebrpcBadResponse", Message: "bad response", HTTPStatus: 500} + ErrWebrpcServerPanic = WebRPCError{Code: -6, Name: "WebrpcServerPanic", Message: "server panic", HTTPStatus: 500} + ErrWebrpcInternalError = WebRPCError{Code: -7, Name: "WebrpcInternalError", Message: "internal error", HTTPStatus: 500} + ErrWebrpcClientAborted = WebRPCError{Code: -8, Name: "WebrpcClientAborted", Message: "request aborted by client", HTTPStatus: 400} + ErrWebrpcStreamLost = WebRPCError{Code: -9, Name: "WebrpcStreamLost", Message: "stream lost", HTTPStatus: 400} + ErrWebrpcStreamFinished = WebRPCError{Code: -10, Name: "WebrpcStreamFinished", Message: "stream finished", HTTPStatus: 200} +) + +// Schema errors +var ( + ErrUnauthorized = WebRPCError{Code: 1000, Name: "Unauthorized", Message: "Unauthorized access", HTTPStatus: 401} + ErrPermissionDenied = WebRPCError{Code: 1001, Name: "PermissionDenied", Message: "Permission denied", HTTPStatus: 403} + ErrSessionExpired = WebRPCError{Code: 1002, Name: "SessionExpired", Message: "Session expired", HTTPStatus: 403} + ErrMethodNotFound = WebRPCError{Code: 1003, Name: "MethodNotFound", Message: "Method not found", HTTPStatus: 404} + ErrRequestConflict = WebRPCError{Code: 1004, Name: "RequestConflict", Message: "Conflict with target resource", HTTPStatus: 409} + ErrFail = WebRPCError{Code: 1005, Name: "Fail", Message: "Request Failed", HTTPStatus: 400} + ErrGeoblocked = WebRPCError{Code: 1006, Name: "Geoblocked", Message: "Geoblocked region", HTTPStatus: 451} + ErrTaskFailed = WebRPCError{Code: 1007, Name: "TaskFailed", Message: "Task failed", HTTPStatus: 400} + ErrDeprecated = WebRPCError{Code: 1008, Name: "Deprecated", Message: "RPC method is deprecated", HTTPStatus: 400} + ErrTimeout = WebRPCError{Code: 2000, Name: "Timeout", Message: "Request timed out", HTTPStatus: 408} + ErrInvalidArgument = WebRPCError{Code: 2001, Name: "InvalidArgument", Message: "Invalid argument", HTTPStatus: 400} + ErrRequiredArgument = WebRPCError{Code: 2002, Name: "RequiredArgument", Message: "Required argument missing", HTTPStatus: 400} + ErrQueryFailed = WebRPCError{Code: 2003, Name: "QueryFailed", Message: "Query failed", HTTPStatus: 400} + ErrValidationFailed = WebRPCError{Code: 2004, Name: "ValidationFailed", Message: "Validation failed", HTTPStatus: 400} + ErrRateLimited = WebRPCError{Code: 2005, Name: "RateLimited", Message: "Rate limited", HTTPStatus: 429} + ErrNotFound = WebRPCError{Code: 3000, Name: "NotFound", Message: "Resource not found", HTTPStatus: 400} + ErrProjectNotFound = WebRPCError{Code: 3002, Name: "ProjectNotFound", Message: "Project not found", HTTPStatus: 400} + ErrChainNotFound = WebRPCError{Code: 3003, Name: "ChainNotFound", Message: "Chain not found", HTTPStatus: 400} + ErrTokenDirectoryDisabled = WebRPCError{Code: 4001, Name: "TokenDirectoryDisabled", Message: "Token Directory is disabled", HTTPStatus: 400} +) + +// +// Webrpc +// + +const WebrpcHeader = "Webrpc" + +const WebrpcHeaderValue = "webrpc@v0.30.2;gen-golang@v0.23.1;sequence-metadata@v0.4.0" + +type WebrpcGenVersions struct { + WebrpcGenVersion string + CodeGenName string + CodeGenVersion string + SchemaName string + SchemaVersion string +} + +func VersionFromHeader(h http.Header) (*WebrpcGenVersions, error) { + if h.Get(WebrpcHeader) == "" { + return nil, fmt.Errorf("header is empty or missing") + } + + versions, err := parseWebrpcGenVersions(h.Get(WebrpcHeader)) + if err != nil { + return nil, fmt.Errorf("webrpc header is invalid: %w", err) + } + + return versions, nil +} + +func parseWebrpcGenVersions(header string) (*WebrpcGenVersions, error) { + versions := strings.Split(header, ";") + if len(versions) < 3 { + return nil, fmt.Errorf("expected at least 3 parts while parsing webrpc header: %v", header) + } + + _, webrpcGenVersion, ok := strings.Cut(versions[0], "@") + if !ok { + return nil, fmt.Errorf("webrpc gen version could not be parsed from: %s", versions[0]) + } + + tmplTarget, tmplVersion, ok := strings.Cut(versions[1], "@") + if !ok { + return nil, fmt.Errorf("tmplTarget and tmplVersion could not be parsed from: %s", versions[1]) + } + + schemaName, schemaVersion, ok := strings.Cut(versions[2], "@") + if !ok { + return nil, fmt.Errorf("schema name and schema version could not be parsed from: %s", versions[2]) + } + + return &WebrpcGenVersions{ + WebrpcGenVersion: webrpcGenVersion, + CodeGenName: tmplTarget, + CodeGenVersion: tmplVersion, + SchemaName: schemaName, + SchemaVersion: schemaVersion, + }, nil +}