Last active
February 27, 2025 19:34
-
-
Save pkieltyka/9da8da113deb9b99d87be5ef5d105171 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.webrpc.client | |
import com.squareup.moshi.* | |
import java.time.OffsetDateTime | |
import com.squareup.moshi.JsonReader.Token | |
import com.squareup.moshi.adapters.EnumJsonAdapter | |
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory | |
import java.time.format.DateTimeFormatter | |
import io.ktor.client.* | |
import io.ktor.client.plugins.logging.* | |
import io.ktor.client.request.* | |
import io.ktor.client.statement.* | |
import io.ktor.http.* | |
import io.ktor.http.parsing.* | |
import java.lang.reflect.Type | |
import kotlin.coroutines.cancellation.CancellationException | |
// sequence-indexer v0.4.0 5be5b8237a5f9ee70f4c98b5bd0a367974e2f785 | |
// -- | |
// Code generated by [email protected] with kotlin generator. DO NOT EDIT. | |
// | |
// webrpc-gen -schema=indexer.ridl -service=Indexer -target=kotlin -client -out=./clients/indexer.kt | |
// WebRPC description and code-gen version | |
const val WEBRPC_VERSION = "v1" | |
// Schema version of your RIDL schema | |
const val WEBRPC_SCHEMA_VERSION = "v0.4.0" | |
// Schema hash generated from your RIDL schema | |
const val WEBRPC_SCHEMA_HASH = "5be5b8237a5f9ee70f4c98b5bd0a367974e2f785" | |
// region Types | |
@JsonClass(generateAdapter = true) | |
enum class ResourceStatus { | |
@Json(name = "NOT_AVAILABLE") | |
NOT_AVAILABLE, | |
@Json(name = "STALE") | |
STALE, | |
@Json(name = "AVAILABLE") | |
AVAILABLE, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
data class ContractInfo( | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "address") val address: String, | |
@Json(name = "name") val name: String, | |
@Json(name = "type") val type: String, | |
@Json(name = "symbol") val symbol: String, | |
@Json(name = "decimals") val decimals: ULong?, | |
@Json(name = "logoURI") val logoUri: String, | |
@Json(name = "deployed") val deployed: Boolean, | |
@Json(name = "bytecodeHash") val bytecodeHash: String, | |
@Json(name = "extensions") val extensions: ContractInfoExtensions, | |
@Json(name = "updatedAt") val updatedAt: OffsetDateTime, | |
@Json(name = "notFound") val notFound: Boolean, | |
@Json(name = "queuedAt") val queuedAt: OffsetDateTime?, | |
@Json(name = "status") val status: ResourceStatus, | |
) | |
@JsonClass(generateAdapter = true) | |
data class ContractInfoExtensions( | |
@Json(name = "link") val link: String, | |
@Json(name = "description") val description: String, | |
@Json(name = "categories") val categories: List<String>, | |
@Json(name = "ogImage") val ogImage: String, | |
@Json(name = "ogName") val ogName: String, | |
@Json(name = "originChainId") val originChainId: ULong, | |
@Json(name = "originAddress") val originAddress: String, | |
@Json(name = "blacklist") val blacklist: Boolean, | |
@Json(name = "verified") val verified: Boolean, | |
@Json(name = "verifiedBy") val verifiedBy: String, | |
@Json(name = "featured") val featured: Boolean, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenMetadata( | |
@Json(name = "tokenId") val tokenId: String, | |
@Json(name = "name") val name: String, | |
@Json(name = "description") val description: String?, | |
@Json(name = "image") val image: String?, | |
@Json(name = "video") val video: String?, | |
@Json(name = "audio") val audio: String?, | |
@Json(name = "properties") val properties: Map<String, Any>?, | |
@Json(name = "attributes") val attributes: List<Map<String, Any>>, | |
@Json(name = "image_data") val imageData: String?, | |
@Json(name = "external_url") val externalUrl: String?, | |
@Json(name = "background_color") val backgroundColor: String?, | |
@Json(name = "animation_url") val animationUrl: String?, | |
@Json(name = "decimals") val decimals: ULong?, | |
@Json(name = "updatedAt") val updatedAt: OffsetDateTime?, | |
@Json(name = "assets") val assets: List<Asset>?, | |
@Json(name = "status") val status: ResourceStatus, | |
@Json(name = "queuedAt") val queuedAt: OffsetDateTime?, | |
@Json(name = "lastFetched") val lastFetched: OffsetDateTime?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class Asset( | |
@Json(name = "id") val id: ULong, | |
@Json(name = "collectionId") val collectionId: ULong, | |
@Json(name = "tokenId") val tokenId: String?, | |
@Json(name = "url") val url: String?, | |
@Json(name = "metadataField") val metadataField: String, | |
@Json(name = "name") val filename: String?, | |
@Json(name = "filesize") val filesize: UInt?, | |
@Json(name = "mimeType") val mimeType: String?, | |
@Json(name = "width") val width: UShort?, | |
@Json(name = "height") val height: UShort?, | |
@Json(name = "updatedAt") val updatedAt: OffsetDateTime?, | |
) | |
@JsonClass(generateAdapter = true) | |
enum class ContractType { | |
@Json(name = "UNKNOWN") | |
UNKNOWN, | |
@Json(name = "NATIVE") | |
NATIVE, | |
@Json(name = "ERC20") | |
ERC20, | |
@Json(name = "ERC721") | |
ERC721, | |
@Json(name = "ERC1155") | |
ERC1155, | |
@Json(name = "SEQUENCE_WALLET") | |
SEQUENCE_WALLET, | |
@Json(name = "ERC20_BRIDGE") | |
ERC20_BRIDGE, | |
@Json(name = "ERC721_BRIDGE") | |
ERC721_BRIDGE, | |
@Json(name = "ERC1155_BRIDGE") | |
ERC1155_BRIDGE, | |
@Json(name = "SEQ_MARKETPLACE") | |
SEQ_MARKETPLACE, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class EventLogType { | |
@Json(name = "UNKNOWN") | |
UNKNOWN, | |
@Json(name = "BLOCK_ADDED") | |
BLOCK_ADDED, | |
@Json(name = "BLOCK_REMOVED") | |
BLOCK_REMOVED, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class EventLogDataType { | |
@Json(name = "EVENT") | |
EVENT, | |
@Json(name = "TOKEN_TRANSFER") | |
TOKEN_TRANSFER, | |
@Json(name = "NATIVE_TOKEN_TRANSFER") | |
NATIVE_TOKEN_TRANSFER, | |
@Json(name = "SEQUENCE_TXN") | |
SEQUENCE_TXN, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class OrderStatus { | |
@Json(name = "OPEN") | |
OPEN, | |
@Json(name = "CLOSED") | |
CLOSED, | |
@Json(name = "CANCELLED") | |
CANCELLED, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class TxnTransferType { | |
@Json(name = "UNKNOWN") | |
UNKNOWN, | |
@Json(name = "SEND") | |
SEND, | |
@Json(name = "RECEIVE") | |
RECEIVE, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class TransactionStatus { | |
@Json(name = "FAILED") | |
FAILED, | |
@Json(name = "SUCCESSFUL") | |
SUCCESSFUL, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class TransactionType { | |
@Json(name = "LegacyTxnType") | |
LEGACY_TXN_TYPE, | |
@Json(name = "AccessListTxnType") | |
ACCESS_LIST_TXN_TYPE, | |
@Json(name = "DynamicFeeTxnType") | |
DYNAMIC_FEE_TXN_TYPE, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class SortOrder { | |
@Json(name = "DESC") | |
DESC, | |
@Json(name = "ASC") | |
ASC, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
enum class ContractVerificationStatus { | |
@Json(name = "VERIFIED") | |
VERIFIED, | |
@Json(name = "UNVERIFIED") | |
UNVERIFIED, | |
@Json(name = "ALL") | |
ALL, | |
@Json(name = "UNKNOWN_DEFAULT") | |
UNKNOWN_DEFAULT, | |
} | |
@JsonClass(generateAdapter = true) | |
data class Version( | |
@Json(name = "webrpcVersion") val webrpcVersion: String, | |
@Json(name = "schemaVersion") val schemaVersion: String, | |
@Json(name = "schemaHash") val schemaHash: String, | |
@Json(name = "appVersion") val appVersion: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class RuntimeStatus( | |
@Json(name = "healthOK") val healthOk: Boolean, | |
@Json(name = "indexerEnabled") val indexerEnabled: Boolean, | |
@Json(name = "startTime") val startTime: OffsetDateTime, | |
@Json(name = "uptime") val uptime: ULong, | |
@Json(name = "ver") val ver: String, | |
@Json(name = "branch") val branch: String, | |
@Json(name = "commitHash") val commitHash: String, | |
@Json(name = "chainID") val chainId: ULong, | |
@Json(name = "checks") val checks: RuntimeChecks, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayBackendResponseTime( | |
@Json(name = "percentiles") val percentiles: Map<String, Double>, | |
@Json(name = "average") val average: Double, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayBackendRuntimeStatus( | |
@Json(name = "name") val name: String, | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "responseTime") val responseTime: GatewayBackendResponseTime, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayRuntimeStatus( | |
@Json(name = "healthOK") val healthOk: Boolean, | |
@Json(name = "startTime") val startTime: OffsetDateTime, | |
@Json(name = "uptime") val uptime: ULong, | |
@Json(name = "ver") val ver: String, | |
@Json(name = "branch") val branch: String, | |
@Json(name = "commitHash") val commitHash: String, | |
@Json(name = "backends") val backends: List<GatewayBackendRuntimeStatus>, | |
) | |
@JsonClass(generateAdapter = true) | |
data class WALWriterRuntimeStatus( | |
@Json(name = "healthOK") val healthOk: Boolean, | |
@Json(name = "startTime") val startTime: OffsetDateTime, | |
@Json(name = "uptime") val uptime: ULong, | |
@Json(name = "ver") val ver: String, | |
@Json(name = "branch") val branch: String, | |
@Json(name = "commitHash") val commitHash: String, | |
@Json(name = "chainID") val chainId: ULong, | |
@Json(name = "percentWALWritten") val percentWalwRitten: Double, | |
) | |
@JsonClass(generateAdapter = true) | |
data class RuntimeChecks( | |
@Json(name = "running") val running: Boolean, | |
@Json(name = "runnables") val runnables: Any, | |
@Json(name = "cgoEnabled") val cgoEnabled: Boolean, | |
@Json(name = "quotaControlEnabled") val quotaControlEnabled: Boolean, | |
@Json(name = "syncMode") val syncMode: String, | |
@Json(name = "percentIndexed") val percentIndexed: Double, | |
@Json(name = "lastBlockNum") val lastBlockNum: ULong, | |
@Json(name = "lastBlockNumWithState") val lastBlockNumWithState: ULong, | |
@Json(name = "bloomStatus") val bloomStatus: BloomStatus, | |
@Json(name = "bond") val bond: Bond, | |
@Json(name = "diskUsage") val diskUsage: DiskUsage, | |
) | |
@JsonClass(generateAdapter = true) | |
data class DiskUsage( | |
@Json(name = "humanReadable") val humanReadable: String, | |
@Json(name = "used") val used: ULong, | |
@Json(name = "size") val size: ULong, | |
@Json(name = "percent") val percent: Float, | |
@Json(name = "dirs") val dirs: Map<String, String>, | |
) | |
@JsonClass(generateAdapter = true) | |
data class Bond( | |
@Json(name = "pebble") val pebble: PebbleMetrics, | |
@Json(name = "estimatedDiskUsagePerTable") val estimatedDiskUsagePerTable: Any, | |
@Json(name = "estimatedDiskUsageTotal") val estimatedDiskUsageTotal: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class PebbleMetrics( | |
@Json(name = "compactionCount") val compactionCount: Long, | |
@Json(name = "compactionEstimatedDebt") val compactionEstimatedDebt: ULong, | |
@Json(name = "compactionInProgressBytes") val compactionInProgressBytes: Long, | |
@Json(name = "compactionNumInProgress") val compactionNumInProgress: Long, | |
@Json(name = "compactionMarkedFiles") val compactionMarkedFiles: Int, | |
) | |
@JsonClass(generateAdapter = true) | |
data class BloomStatus( | |
@Json(name = "enabled") val enabled: Boolean, | |
@Json(name = "initialized") val initialized: Boolean, | |
@Json(name = "bloomInitElapsedTime") val bloomInitElapsedTime: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class EtherBalance( | |
@Json(name = "accountAddress") val accountAddress: String, | |
@Json(name = "balanceWei") val balanceWei: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class NativeTokenBalance( | |
@Json(name = "accountAddress") val accountAddress: String, | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "balance") val balance: String, | |
@Json(name = "error") val error: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class IndexState( | |
@Json(name = "chainId") val chainId: String, | |
@Json(name = "lastBlockNum") val lastBlockNum: ULong, | |
@Json(name = "lastBlockHash") val lastBlockHash: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class IndexedBlock( | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "blockShortHash") val blockShortHash: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TxnInfo( | |
@Json(name = "from") val from: String, | |
@Json(name = "to") val to: String, | |
@Json(name = "value") val value: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class EventLog( | |
@Json(name = "id") val id: ULong, | |
@Json(name = "uid") val uid: String, | |
@Json(name = "type") val type: EventLogType, | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "blockHash") val blockHash: String, | |
@Json(name = "parentBlockHash") val parentBlockHash: String, | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "txnHash") val txnHash: String, | |
@Json(name = "txnIndex") val txnIndex: UInt, | |
@Json(name = "txnLogIndex") val txnLogIndex: UInt, | |
@Json(name = "logDataType") val logDataType: EventLogDataType, | |
@Json(name = "ts") val ts: OffsetDateTime, | |
@Json(name = "txnInfo") val txnInfo: TxnInfo?, | |
@Json(name = "rawLog") val rawLog: Map<String, Any>?, | |
@Json(name = "event") val event: EventDecoded?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class EventDecoded( | |
@Json(name = "topicHash") val topicHash: String, | |
@Json(name = "eventSig") val eventSig: String, | |
@Json(name = "types") val types: List<String>, | |
@Json(name = "names") val names: List<String>, | |
@Json(name = "values") val values: List<String>, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenBalance( | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "accountAddress") val accountAddress: String, | |
@Json(name = "tokenID") val tokenId: String?, | |
@Json(name = "balance") val balance: String, | |
@Json(name = "blockHash") val blockHash: String, | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "uniqueCollectibles") val uniqueCollectibles: String, | |
@Json(name = "isSummary") val isSummary: Boolean, | |
@Json(name = "contractInfo") val contractInfo: ContractInfo?, | |
@Json(name = "tokenMetadata") val tokenMetadata: TokenMetadata?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class OrderbookOrder( | |
@Json(name = "orderId") val orderId: String, | |
@Json(name = "tokenContract") val tokenContract: String, | |
@Json(name = "tokenId") val tokenId: String, | |
@Json(name = "isListing") val isListing: Boolean, | |
@Json(name = "quantity") val quantity: String, | |
@Json(name = "quantityRemaining") val quantityRemaining: String, | |
@Json(name = "currencyAddress") val currencyAddress: String, | |
@Json(name = "pricePerToken") val pricePerToken: String, | |
@Json(name = "expiry") val expiry: String, | |
@Json(name = "orderStatus") val orderStatus: OrderStatus, | |
@Json(name = "createdBy") val createdBy: String, | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "orderbookContractAddress") val orderbookContractAddress: String, | |
@Json(name = "createdAt") val createdAt: ULong, | |
) | |
@JsonClass(generateAdapter = true) | |
data class OrderbookOrderFilter( | |
@Json(name = "isListing") val isListing: Boolean?, | |
@Json(name = "userAddresses") val userAddresses: List<String>?, | |
@Json(name = "tokenIds") val tokenIds: List<String>, | |
@Json(name = "excludeUserAddresses") val excludeUserAddresses: List<String>?, | |
@Json(name = "afterBlockNumber") val afterBlockNumber: ULong, | |
@Json(name = "afterCreatedAt") val afterCreatedAt: Long, | |
@Json(name = "beforeExpiry") val beforeExpiry: Long, | |
@Json(name = "userAddress") val userAddress: String?, | |
@Json(name = "excludeUserAddress") val excludeUserAddress: String?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenHistory( | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "blockHash") val blockHash: String, | |
@Json(name = "accountAddress") val accountAddress: String, | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "fromAddress") val fromAddress: String, | |
@Json(name = "toAddress") val toAddress: String, | |
@Json(name = "txnHash") val txnHash: String, | |
@Json(name = "txnIndex") val txnIndex: UInt, | |
@Json(name = "txnLogIndex") val txnLogIndex: UInt, | |
@Json(name = "logData") val logData: String, | |
@Json(name = "tokenIDs") val tokenIdS: String, | |
@Json(name = "Amounts") val amounts: String, | |
@Json(name = "ts") val ts: OffsetDateTime, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenSupply( | |
@Json(name = "tokenID") val tokenId: String, | |
@Json(name = "supply") val supply: String, | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "contractInfo") val contractInfo: ContractInfo?, | |
@Json(name = "tokenMetadata") val tokenMetadata: TokenMetadata?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class Transaction( | |
@Json(name = "txnHash") val txnHash: String, | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "blockHash") val blockHash: String, | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "metaTxnID") val metaTxnId: String?, | |
@Json(name = "transfers") val transfers: List<TxnTransfer>?, | |
@Json(name = "timestamp") val timestamp: OffsetDateTime, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TxnTransfer( | |
@Json(name = "transferType") val transferType: TxnTransferType, | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "from") val from: String, | |
@Json(name = "to") val to: String, | |
@Json(name = "tokenIds") val tokenIds: List<String>?, | |
@Json(name = "amounts") val amounts: List<String>, | |
@Json(name = "logIndex") val logIndex: UInt, | |
@Json(name = "contractInfo") val contractInfo: ContractInfo?, | |
@Json(name = "tokenMetadata") val tokenMetadata: Map<String, TokenMetadata>?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TransactionHistoryFilter( | |
@Json(name = "accountAddress") val accountAddress: String?, | |
@Json(name = "contractAddress") val contractAddress: String?, | |
@Json(name = "accountAddresses") val accountAddresses: List<String>?, | |
@Json(name = "contractAddresses") val contractAddresses: List<String>?, | |
@Json(name = "transactionHashes") val transactionHashes: List<String>?, | |
@Json(name = "metaTransactionIDs") val metaTransactionIdS: List<String>?, | |
@Json(name = "fromBlock") val fromBlock: ULong?, | |
@Json(name = "toBlock") val toBlock: ULong?, | |
@Json(name = "tokenID") val tokenId: String?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TransactionFilter( | |
@Json(name = "txnHash") val txnHash: String?, | |
@Json(name = "from") val from: String?, | |
@Json(name = "to") val to: String?, | |
@Json(name = "contractAddress") val contractAddress: String?, | |
@Json(name = "event") val event: String?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TransactionReceipt( | |
@Json(name = "txnHash") val txnHash: String, | |
@Json(name = "txnStatus") val txnStatus: TransactionStatus, | |
@Json(name = "txnIndex") val txnIndex: ULong, | |
@Json(name = "txnType") val txnType: TransactionType, | |
@Json(name = "blockHash") val blockHash: String, | |
@Json(name = "blockNumber") val blockNumber: ULong, | |
@Json(name = "gasUsed") val gasUsed: ULong, | |
@Json(name = "effectiveGasPrice") val effectiveGasPrice: String, | |
@Json(name = "from") val from: String, | |
@Json(name = "to") val to: String, | |
@Json(name = "logs") val logs: List<TransactionLog>, | |
@Json(name = "final") val `final`: Boolean, | |
@Json(name = "reorged") val reorged: Boolean, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TransactionLog( | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "topics") val topics: List<String>, | |
@Json(name = "data") val `data`: String, | |
@Json(name = "index") val index: ULong, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenIDRange( | |
@Json(name = "start") val start: String, | |
@Json(name = "end") val end: String, | |
) | |
@JsonClass(generateAdapter = true) | |
data class Page( | |
@Json(name = "page") val page: UInt?, | |
@Json(name = "column") val column: String?, | |
@Json(name = "before") val before: Any?, | |
@Json(name = "after") val after: Any?, | |
@Json(name = "sort") val sort: List<SortBy>?, | |
@Json(name = "pageSize") val pageSize: UInt?, | |
@Json(name = "more") val more: Boolean?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class SortBy( | |
@Json(name = "column") val column: String, | |
@Json(name = "order") val order: SortOrder, | |
) | |
@JsonClass(generateAdapter = true) | |
data class WebhookListener( | |
@Json(name = "id") val id: ULong, | |
@Json(name = "projectID") val projectId: ULong, | |
@Json(name = "url") val url: String, | |
@Json(name = "filters") val filters: EventFilter, | |
@Json(name = "name") val name: String, | |
@Json(name = "updatedAt") val updatedAt: OffsetDateTime, | |
@Json(name = "active") val active: Boolean, | |
) | |
@JsonClass(generateAdapter = true) | |
data class EventFilter( | |
@Json(name = "events") val events: List<String>?, | |
@Json(name = "contractAddresses") val contractAddresses: List<String>?, | |
@Json(name = "accounts") val accounts: List<String>?, | |
@Json(name = "tokenIDs") val tokenIdS: List<String>?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenBalanceFilter( | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "sinceBlockNumber") val sinceBlockNumber: ULong, | |
) | |
@JsonClass(generateAdapter = true) | |
data class MetadataOptions( | |
@Json(name = "verifiedOnly") val verifiedOnly: Boolean?, | |
@Json(name = "unverifiedOnly") val unverifiedOnly: Boolean?, | |
@Json(name = "includeContracts") val includeContracts: List<String>?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenBalancesFilter( | |
@Json(name = "accountAddresses") val accountAddresses: List<String>, | |
@Json(name = "contractStatus") val contractStatus: ContractVerificationStatus?, | |
@Json(name = "contractWhitelist") val contractWhitelist: List<String>?, | |
@Json(name = "contractBlacklist") val contractBlacklist: List<String>?, | |
@Json(name = "omitNativeBalances") val omitNativeBalances: Boolean, | |
) | |
@JsonClass(generateAdapter = true) | |
data class TokenBalancesByContractFilter( | |
@Json(name = "contractAddresses") val contractAddresses: List<String>, | |
@Json(name = "accountAddresses") val accountAddresses: List<String>?, | |
@Json(name = "contractStatus") val contractStatus: ContractVerificationStatus?, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayEtherBalance( | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "error") val error: String, | |
@Json(name = "result") val result: EtherBalance, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayNativeTokenBalance( | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "error") val error: String, | |
@Json(name = "result") val result: NativeTokenBalance, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayNativeTokenBalances( | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "error") val error: String, | |
@Json(name = "results") val results: List<NativeTokenBalance>, | |
) | |
@JsonClass(generateAdapter = true) | |
data class GatewayTokenBalance( | |
@Json(name = "chainId") val chainId: ULong, | |
@Json(name = "error") val error: String, | |
@Json(name = "results") val results: List<TokenBalance>, | |
) | |
// endregion | |
// region Client | |
interface Indexer { | |
@Throws(WebRpcError::class) | |
suspend fun ping(): Boolean | |
@Throws(WebRpcError::class) | |
suspend fun version(): Version | |
@Throws(WebRpcError::class) | |
suspend fun runtimeStatus(): RuntimeStatus | |
@Throws(WebRpcError::class) | |
suspend fun getChainID(): ULong | |
@Throws(WebRpcError::class) | |
suspend fun getEtherBalance(accountAddress: String?): EtherBalance | |
@Throws(WebRpcError::class) | |
suspend fun getNativeTokenBalance(accountAddress: String?): NativeTokenBalance | |
@Throws(WebRpcError::class) | |
suspend fun getTokenBalancesSummary(filter: TokenBalancesFilter, omitMetadata: Boolean?, page: Page?): Indexer.GetTokenBalancesSummaryResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTokenBalancesDetails(filter: TokenBalancesFilter, omitMetadata: Boolean?, page: Page?): Indexer.GetTokenBalancesDetailsResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTokenBalancesByContract(filter: TokenBalancesByContractFilter, omitMetadata: Boolean?, page: Page?): Indexer.GetTokenBalancesByContractResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTokenBalances(accountAddress: String?, contractAddress: String?, tokenId: String?, includeMetadata: Boolean?, metadataOptions: MetadataOptions?, includeCollectionTokens: Boolean?, page: Page?): Indexer.GetTokenBalancesResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTokenSupplies(contractAddress: String, includeMetadata: Boolean?, metadataOptions: MetadataOptions?, page: Page?): Indexer.GetTokenSuppliesResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTokenSuppliesMap(tokenMap: Map<String, List<String>>, includeMetadata: Boolean?, metadataOptions: MetadataOptions?): Map<String, List<TokenSupply>> | |
@Throws(WebRpcError::class) | |
suspend fun getTokenIDs(contractAddress: String, page: Page?): Indexer.GetTokenIDsResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTokenIDRanges(contractAddress: String): Indexer.GetTokenIDRangesResponse | |
@Throws(WebRpcError::class) | |
suspend fun getBalanceUpdates(contractAddress: String, lastBlockNumber: ULong, lastBlockHash: String?, page: Page?): Indexer.GetBalanceUpdatesResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTransactionHistory(filter: TransactionHistoryFilter, page: Page?, includeMetadata: Boolean?, metadataOptions: MetadataOptions?): Indexer.GetTransactionHistoryResponse | |
@Throws(WebRpcError::class) | |
suspend fun fetchTransactionReceipt(txnHash: String, maxBlockWait: Int?): TransactionReceipt | |
@Throws(WebRpcError::class) | |
suspend fun fetchTransactionReceiptWithFilter(filter: TransactionFilter, maxBlockWait: Int?): TransactionReceipt | |
@Throws(WebRpcError::class) | |
suspend fun subscribeReceipts(filter: TransactionFilter): TransactionReceipt | |
@Throws(WebRpcError::class) | |
suspend fun subscribeEvents(filter: EventFilter): EventLog | |
@Throws(WebRpcError::class) | |
suspend fun subscribeBalanceUpdates(contractAddress: String): TokenBalance | |
@Throws(WebRpcError::class) | |
suspend fun syncBalance(accountAddress: String, contractAddress: String, tokenId: String?) | |
@Throws(WebRpcError::class) | |
suspend fun getAllWebhookListeners(projectId: ULong?): List<WebhookListener> | |
@Throws(WebRpcError::class) | |
suspend fun getWebhookListener(id: ULong, projectId: ULong?): WebhookListener | |
@Throws(WebRpcError::class) | |
suspend fun addWebhookListener(url: String, filters: EventFilter, projectId: ULong?): Indexer.AddWebhookListenerResponse | |
@Throws(WebRpcError::class) | |
suspend fun updateWebhookListener(listener: WebhookListener, projectId: ULong?): Boolean | |
@Throws(WebRpcError::class) | |
suspend fun removeWebhookListener(id: ULong, projectId: ULong?): Boolean | |
@Throws(WebRpcError::class) | |
suspend fun removeAllWebhookListeners(projectId: ULong?): Boolean | |
@Throws(WebRpcError::class) | |
suspend fun toggleWebhookListener(id: ULong, projectId: ULong?): WebhookListener | |
@Throws(WebRpcError::class) | |
suspend fun pauseAllWebhookListeners(projectId: ULong?): Boolean | |
@Throws(WebRpcError::class) | |
suspend fun resumeAllWebhookListeners(projectId: ULong?): Boolean | |
@Throws(WebRpcError::class) | |
suspend fun getOrderbookOrders(page: Page?, orderbookContractAddress: String, collectionAddress: String, currencyAddresses: List<String>, filter: OrderbookOrderFilter, orderStatuses: List<OrderStatus>, filters: List<OrderbookOrderFilter>, beforeExpiryTimestamp: Long, blockNumberAfter: Long, createdAtAfter: Long): Indexer.GetOrderbookOrdersResponse | |
@Throws(WebRpcError::class) | |
suspend fun getTopOrders(orderbookContractAddress: String, collectionAddress: String, currencyAddresses: List<String>, tokenIdS: List<String>, isListing: Boolean, priceSort: SortOrder, excludeUser: String?): List<OrderbookOrder> | |
data class PingResponse( | |
@Json(name = "status") val status: Boolean, | |
) | |
data class VersionResponse( | |
@Json(name = "version") val version: Version, | |
) | |
data class RuntimeStatusResponse( | |
@Json(name = "status") val status: RuntimeStatus, | |
) | |
data class GetChainIDResponse( | |
@Json(name = "chainID") val chainId: ULong, | |
) | |
data class GetEtherBalanceRequest( | |
@Json(name = "accountAddress") val accountAddress: String?, | |
) | |
data class GetEtherBalanceResponse( | |
@Json(name = "balance") val balance: EtherBalance, | |
) | |
data class GetNativeTokenBalanceRequest( | |
@Json(name = "accountAddress") val accountAddress: String?, | |
) | |
data class GetNativeTokenBalanceResponse( | |
@Json(name = "balance") val balance: NativeTokenBalance, | |
) | |
data class GetTokenBalancesSummaryRequest( | |
@Json(name = "filter") val filter: TokenBalancesFilter, | |
@Json(name = "omitMetadata") val omitMetadata: Boolean?, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetTokenBalancesSummaryResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "nativeBalances") val nativeBalances: List<NativeTokenBalance>, | |
@Json(name = "balances") val balances: List<TokenBalance>, | |
) | |
data class GetTokenBalancesDetailsRequest( | |
@Json(name = "filter") val filter: TokenBalancesFilter, | |
@Json(name = "omitMetadata") val omitMetadata: Boolean?, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetTokenBalancesDetailsResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "nativeBalances") val nativeBalances: List<NativeTokenBalance>, | |
@Json(name = "balances") val balances: List<TokenBalance>, | |
) | |
data class GetTokenBalancesByContractRequest( | |
@Json(name = "filter") val filter: TokenBalancesByContractFilter, | |
@Json(name = "omitMetadata") val omitMetadata: Boolean?, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetTokenBalancesByContractResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "balances") val balances: List<TokenBalance>, | |
) | |
data class GetTokenBalancesRequest( | |
@Json(name = "accountAddress") val accountAddress: String?, | |
@Json(name = "contractAddress") val contractAddress: String?, | |
@Json(name = "tokenID") val tokenId: String?, | |
@Json(name = "includeMetadata") val includeMetadata: Boolean?, | |
@Json(name = "metadataOptions") val metadataOptions: MetadataOptions?, | |
@Json(name = "includeCollectionTokens") val includeCollectionTokens: Boolean?, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetTokenBalancesResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "balances") val balances: List<TokenBalance>, | |
) | |
data class GetTokenSuppliesRequest( | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "includeMetadata") val includeMetadata: Boolean?, | |
@Json(name = "metadataOptions") val metadataOptions: MetadataOptions?, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetTokenSuppliesResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "tokenIDs") val tokenIdS: List<TokenSupply>, | |
) | |
data class GetTokenSuppliesMapRequest( | |
@Json(name = "tokenMap") val tokenMap: Map<String, List<String>>, | |
@Json(name = "includeMetadata") val includeMetadata: Boolean?, | |
@Json(name = "metadataOptions") val metadataOptions: MetadataOptions?, | |
) | |
data class GetTokenSuppliesMapResponse( | |
@Json(name = "supplies") val supplies: Map<String, List<TokenSupply>>, | |
) | |
data class GetTokenIDsRequest( | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetTokenIDsResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "tokenIDs") val tokenIdS: List<String>, | |
) | |
data class GetTokenIDRangesRequest( | |
@Json(name = "contractAddress") val contractAddress: String, | |
) | |
data class GetTokenIDRangesResponse( | |
@Json(name = "contractType") val contractType: ContractType, | |
@Json(name = "tokenIDRanges") val tokenIdrAnges: List<TokenIDRange>, | |
@Json(name = "moreRanges") val moreRanges: Boolean, | |
) | |
data class GetBalanceUpdatesRequest( | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "lastBlockNumber") val lastBlockNumber: ULong, | |
@Json(name = "lastBlockHash") val lastBlockHash: String?, | |
@Json(name = "page") val page: Page?, | |
) | |
data class GetBalanceUpdatesResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "balances") val balances: List<TokenBalance>, | |
) | |
data class GetTransactionHistoryRequest( | |
@Json(name = "filter") val filter: TransactionHistoryFilter, | |
@Json(name = "page") val page: Page?, | |
@Json(name = "includeMetadata") val includeMetadata: Boolean?, | |
@Json(name = "metadataOptions") val metadataOptions: MetadataOptions?, | |
) | |
data class GetTransactionHistoryResponse( | |
@Json(name = "page") val page: Page, | |
@Json(name = "transactions") val transactions: List<Transaction>, | |
) | |
data class FetchTransactionReceiptRequest( | |
@Json(name = "txnHash") val txnHash: String, | |
@Json(name = "maxBlockWait") val maxBlockWait: Int?, | |
) | |
data class FetchTransactionReceiptResponse( | |
@Json(name = "receipt") val receipt: TransactionReceipt, | |
) | |
data class FetchTransactionReceiptWithFilterRequest( | |
@Json(name = "filter") val filter: TransactionFilter, | |
@Json(name = "maxBlockWait") val maxBlockWait: Int?, | |
) | |
data class FetchTransactionReceiptWithFilterResponse( | |
@Json(name = "receipt") val receipt: TransactionReceipt, | |
) | |
data class SubscribeReceiptsRequest( | |
@Json(name = "filter") val filter: TransactionFilter, | |
) | |
data class SubscribeReceiptsResponse( | |
@Json(name = "receipt") val receipt: TransactionReceipt, | |
) | |
data class SubscribeEventsRequest( | |
@Json(name = "filter") val filter: EventFilter, | |
) | |
data class SubscribeEventsResponse( | |
@Json(name = "log") val log: EventLog, | |
) | |
data class SubscribeBalanceUpdatesRequest( | |
@Json(name = "contractAddress") val contractAddress: String, | |
) | |
data class SubscribeBalanceUpdatesResponse( | |
@Json(name = "balance") val balance: TokenBalance, | |
) | |
data class SyncBalanceRequest( | |
@Json(name = "accountAddress") val accountAddress: String, | |
@Json(name = "contractAddress") val contractAddress: String, | |
@Json(name = "tokenID") val tokenId: String?, | |
) | |
data class GetAllWebhookListenersRequest( | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class GetAllWebhookListenersResponse( | |
@Json(name = "listeners") val listeners: List<WebhookListener>, | |
) | |
data class GetWebhookListenerRequest( | |
@Json(name = "id") val id: ULong, | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class GetWebhookListenerResponse( | |
@Json(name = "listener") val listener: WebhookListener, | |
) | |
data class AddWebhookListenerRequest( | |
@Json(name = "url") val url: String, | |
@Json(name = "filters") val filters: EventFilter, | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class AddWebhookListenerResponse( | |
@Json(name = "status") val status: Boolean, | |
@Json(name = "listener") val listener: WebhookListener, | |
) | |
data class UpdateWebhookListenerRequest( | |
@Json(name = "listener") val listener: WebhookListener, | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class UpdateWebhookListenerResponse( | |
@Json(name = "status") val status: Boolean, | |
) | |
data class RemoveWebhookListenerRequest( | |
@Json(name = "id") val id: ULong, | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class RemoveWebhookListenerResponse( | |
@Json(name = "status") val status: Boolean, | |
) | |
data class RemoveAllWebhookListenersRequest( | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class RemoveAllWebhookListenersResponse( | |
@Json(name = "status") val status: Boolean, | |
) | |
data class ToggleWebhookListenerRequest( | |
@Json(name = "id") val id: ULong, | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class ToggleWebhookListenerResponse( | |
@Json(name = "webhookListener") val webhookListener: WebhookListener, | |
) | |
data class PauseAllWebhookListenersRequest( | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class PauseAllWebhookListenersResponse( | |
@Json(name = "status") val status: Boolean, | |
) | |
data class ResumeAllWebhookListenersRequest( | |
@Json(name = "projectId") val projectId: ULong?, | |
) | |
data class ResumeAllWebhookListenersResponse( | |
@Json(name = "status") val status: Boolean, | |
) | |
data class GetOrderbookOrdersRequest( | |
@Json(name = "page") val page: Page?, | |
@Json(name = "orderbookContractAddress") val orderbookContractAddress: String, | |
@Json(name = "collectionAddress") val collectionAddress: String, | |
@Json(name = "currencyAddresses") val currencyAddresses: List<String>, | |
@Json(name = "filter") val filter: OrderbookOrderFilter, | |
@Json(name = "orderStatuses") val orderStatuses: List<OrderStatus>, | |
@Json(name = "filters") val filters: List<OrderbookOrderFilter>, | |
@Json(name = "beforeExpiryTimestamp") val beforeExpiryTimestamp: Long, | |
@Json(name = "blockNumberAfter") val blockNumberAfter: Long, | |
@Json(name = "createdAtAfter") val createdAtAfter: Long, | |
) | |
data class GetOrderbookOrdersResponse( | |
@Json(name = "page") val page: Page?, | |
@Json(name = "orders") val orders: List<OrderbookOrder>, | |
) | |
data class GetTopOrdersRequest( | |
@Json(name = "orderbookContractAddress") val orderbookContractAddress: String, | |
@Json(name = "collectionAddress") val collectionAddress: String, | |
@Json(name = "currencyAddresses") val currencyAddresses: List<String>, | |
@Json(name = "tokenIDs") val tokenIdS: List<String>, | |
@Json(name = "isListing") val isListing: Boolean, | |
@Json(name = "priceSort") val priceSort: SortOrder, | |
@Json(name = "excludeUser") val excludeUser: String?, | |
) | |
data class GetTopOrdersResponse( | |
@Json(name = "orders") val orders: List<OrderbookOrder>, | |
) | |
} | |
open class WebRpcKtorClient { | |
@Suppress("RethrowCaughtException") | |
@Throws(WebRpcError::class) | |
protected suspend inline fun <reified I, reified O> request( | |
client: HttpClient, | |
baseUrl: String, | |
method: String, | |
body: I?, | |
serialize: (I) -> String, | |
deserialize: (String) -> O, | |
deserializeError: (String) -> WebRpcError, | |
extraHttpBuilder: HttpRequestBuilder.() -> Unit = {}, | |
): O { | |
return try { | |
val response = client.post(baseUrl) { | |
url { | |
appendPathSegments(method) | |
} | |
contentType(ContentType.Application.Json) | |
setBody(body?.let { serialize(body) } ?: "{}") | |
extraHttpBuilder() | |
} | |
val responseBody = response.bodyAsText(fallbackCharset = Charsets.UTF_8) | |
if (response.status.isSuccess()) { | |
if (O::class.java != Unit::class.java) { | |
deserialize(responseBody) | |
} else Unit as O | |
} else { | |
throw deserializeError(responseBody) | |
} | |
} catch (e: CancellationException) { | |
// CancellationException must be propagated to ensure correct cancellation of coroutines | |
throw e | |
} catch (e: WebRpcError) { | |
// Propagate original WebRpcError out of the function | |
throw e | |
} catch (e: Throwable) { | |
throw createUnknownError(exception = e) | |
} | |
} | |
protected fun createUnknownError(exception: Throwable? = null) = WebRpcError( | |
error = "Unknown error", | |
code = ErrorKind.UNKNOWN.code, | |
message = exception?.message ?: "", | |
causeString = exception?.cause?.toString() ?: "", | |
status = ErrorKind.UNKNOWN.code, | |
errorKind = ErrorKind.UNKNOWN, | |
cause = exception, | |
) | |
} | |
private object Serializer { | |
@JvmStatic | |
val moshiBuilder: Moshi.Builder = SerializerHelper.addEnumUnknownDefaultCase(Moshi.Builder()) | |
} | |
private object SerializerHelper { | |
fun addEnumUnknownDefaultCase(moshiBuilder: Moshi.Builder): Moshi.Builder { | |
return moshiBuilder | |
.add( | |
ResourceStatus::class.java, | |
EnumJsonAdapter.create(ResourceStatus::class.java).withUnknownFallback(ResourceStatus.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
ContractType::class.java, | |
EnumJsonAdapter.create(ContractType::class.java).withUnknownFallback(ContractType.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
EventLogType::class.java, | |
EnumJsonAdapter.create(EventLogType::class.java).withUnknownFallback(EventLogType.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
EventLogDataType::class.java, | |
EnumJsonAdapter.create(EventLogDataType::class.java).withUnknownFallback(EventLogDataType.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
OrderStatus::class.java, | |
EnumJsonAdapter.create(OrderStatus::class.java).withUnknownFallback(OrderStatus.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
TxnTransferType::class.java, | |
EnumJsonAdapter.create(TxnTransferType::class.java).withUnknownFallback(TxnTransferType.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
TransactionStatus::class.java, | |
EnumJsonAdapter.create(TransactionStatus::class.java).withUnknownFallback(TransactionStatus.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
TransactionType::class.java, | |
EnumJsonAdapter.create(TransactionType::class.java).withUnknownFallback(TransactionType.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
SortOrder::class.java, | |
EnumJsonAdapter.create(SortOrder::class.java).withUnknownFallback(SortOrder.UNKNOWN_DEFAULT).nullSafe(), | |
) | |
.add( | |
ContractVerificationStatus::class.java, | |
EnumJsonAdapter.create(ContractVerificationStatus::class.java).withUnknownFallback(ContractVerificationStatus.UNKNOWN_DEFAULT).nullSafe(), | |
).add(UnsignedNumberJsonAdapter.Factory) | |
.add(IsoDateAdapter()) | |
.addLast(KotlinJsonAdapterFactory()) | |
} | |
} | |
private class UnsignedNumberJsonAdapter<UnsignedT : Any> private constructor( | |
private val toUnsignedT: ULong.() -> UnsignedT, | |
) : JsonAdapter<UnsignedT>() { | |
override fun toJson(writer: JsonWriter, value: UnsignedT?) { | |
when (value) { | |
null -> writer.nullValue() | |
else -> writer.valueSink().use { it.writeUtf8(value.toString()) } | |
} | |
} | |
override fun fromJson(reader: JsonReader): UnsignedT? = when (val next = reader.peek()) { | |
Token.NUMBER -> { | |
try { | |
reader.nextString().toULong().toUnsignedT() | |
} catch (numberFormatException: NumberFormatException) { | |
throw JsonDataException( | |
"${numberFormatException.message} for unsigned number at ${reader.path}" | |
) | |
} | |
} | |
Token.NULL -> reader.nextNull() | |
else -> throw JsonDataException( | |
"Expected an unsigned number but was ${reader.readJsonValue()}, " + | |
"a $next, at path ${reader.path}", | |
IllegalArgumentException(next.name) | |
) | |
} | |
object Factory : JsonAdapter.Factory { | |
private val unsignedTypesMapperMap: Map<Class<*>, ULong.() -> Any> = mapOf( | |
ULong::class.java to { this }, | |
UInt::class.java to { | |
if (this > UInt.MAX_VALUE) throw NumberFormatException("Invalid number format: '$this'") else toUInt() | |
}, | |
UShort::class.java to { | |
if (this > UShort.MAX_VALUE) throw NumberFormatException("Invalid number format: '$this'") else toUShort() | |
}, | |
UByte::class.java to { | |
if (this > UByte.MAX_VALUE) throw NumberFormatException("Invalid number format: '$this'") else toUByte() | |
} | |
) | |
private val Type.isUnsignedType: Boolean | |
get() = unsignedTypesMapperMap.keys.contains(rawType) | |
private val Type.mapper: ULong.() -> Any | |
get() = unsignedTypesMapperMap[rawType]!! | |
override fun create( | |
type: Type, | |
annotations: Set<Annotation>, | |
moshi: Moshi, | |
): JsonAdapter<*>? = if (type.isUnsignedType) UnsignedNumberJsonAdapter(type.mapper) else null | |
} | |
} | |
class IsoDateAdapter { | |
@ToJson | |
fun toJson(value: OffsetDateTime): String { | |
return value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) | |
} | |
@FromJson | |
fun fromJson(value: String): OffsetDateTime { | |
return OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME) | |
} | |
} | |
open class IndexerClient( | |
baseUrl: String, | |
httpClientBuilder: () -> HttpClient, | |
private val httpRequestBuilder: HttpRequestBuilder.() -> Unit = {}, | |
moshiBuilder: Moshi.Builder = Serializer.moshiBuilder, | |
): WebRpcKtorClient(), Indexer { | |
private val baseUrl = baseUrl.normalizeUrl() + "rpc/Indexer" | |
private val ktorClient by lazy { httpClientBuilder() } | |
private val moshi by lazy { moshiBuilder.build() } | |
@Throws(WebRpcError::class) | |
private suspend inline fun <reified O> request(method: String, body: Any? = null): O { | |
return request( | |
client = ktorClient, | |
baseUrl = baseUrl, | |
method = method, | |
body = body, | |
serialize = this::toJson, | |
deserialize = { json -> fromJson(json, O::class.java) }, | |
deserializeError = { json -> fromJson(json, WebRpcError::class.java) }, | |
extraHttpBuilder = httpRequestBuilder, | |
) | |
} | |
private fun toJson(obj: Any): String { | |
return moshi.adapter(obj.javaClass).toJson(obj) | |
} | |
private fun <T> fromJson(json: String, type: Type): T { | |
return moshi.adapter<T>(type).fromJson(json) ?: throw createUnknownError( | |
ParseException("Cannot parse JSON body.", cause = IllegalStateException(json)) | |
) | |
} | |
private fun String.normalizeUrl() = this.takeIf { it.endsWith("/") } ?: "$this/" | |
@Throws(WebRpcError::class) | |
override suspend fun ping(): Boolean { | |
return request<Indexer.PingResponse>( | |
method = "Ping", | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun version(): Version { | |
return request<Indexer.VersionResponse>( | |
method = "Version", | |
).version | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun runtimeStatus(): RuntimeStatus { | |
return request<Indexer.RuntimeStatusResponse>( | |
method = "RuntimeStatus", | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getChainID(): ULong { | |
return request<Indexer.GetChainIDResponse>( | |
method = "GetChainID", | |
).chainID | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getEtherBalance(accountAddress: String?): EtherBalance { | |
return request<Indexer.GetEtherBalanceResponse>( | |
method = "GetEtherBalance", | |
body = Indexer.GetEtherBalanceRequest( | |
accountAddress = accountAddress, | |
) | |
).balance | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getNativeTokenBalance(accountAddress: String?): NativeTokenBalance { | |
return request<Indexer.GetNativeTokenBalanceResponse>( | |
method = "GetNativeTokenBalance", | |
body = Indexer.GetNativeTokenBalanceRequest( | |
accountAddress = accountAddress, | |
) | |
).balance | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenBalancesSummary(filter: TokenBalancesFilter, omitMetadata: Boolean?, page: Page?): Indexer.GetTokenBalancesSummaryResponse { | |
return request<Indexer.GetTokenBalancesSummaryResponse>( | |
method = "GetTokenBalancesSummary", | |
body = Indexer.GetTokenBalancesSummaryRequest( | |
filter = filter,omitMetadata = omitMetadata,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenBalancesDetails(filter: TokenBalancesFilter, omitMetadata: Boolean?, page: Page?): Indexer.GetTokenBalancesDetailsResponse { | |
return request<Indexer.GetTokenBalancesDetailsResponse>( | |
method = "GetTokenBalancesDetails", | |
body = Indexer.GetTokenBalancesDetailsRequest( | |
filter = filter,omitMetadata = omitMetadata,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenBalancesByContract(filter: TokenBalancesByContractFilter, omitMetadata: Boolean?, page: Page?): Indexer.GetTokenBalancesByContractResponse { | |
return request<Indexer.GetTokenBalancesByContractResponse>( | |
method = "GetTokenBalancesByContract", | |
body = Indexer.GetTokenBalancesByContractRequest( | |
filter = filter,omitMetadata = omitMetadata,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenBalances(accountAddress: String?, contractAddress: String?, tokenId: String?, includeMetadata: Boolean?, metadataOptions: MetadataOptions?, includeCollectionTokens: Boolean?, page: Page?): Indexer.GetTokenBalancesResponse { | |
return request<Indexer.GetTokenBalancesResponse>( | |
method = "GetTokenBalances", | |
body = Indexer.GetTokenBalancesRequest( | |
accountAddress = accountAddress,contractAddress = contractAddress,tokenId = tokenId,includeMetadata = includeMetadata,metadataOptions = metadataOptions,includeCollectionTokens = includeCollectionTokens,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenSupplies(contractAddress: String, includeMetadata: Boolean?, metadataOptions: MetadataOptions?, page: Page?): Indexer.GetTokenSuppliesResponse { | |
return request<Indexer.GetTokenSuppliesResponse>( | |
method = "GetTokenSupplies", | |
body = Indexer.GetTokenSuppliesRequest( | |
contractAddress = contractAddress,includeMetadata = includeMetadata,metadataOptions = metadataOptions,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenSuppliesMap(tokenMap: Map<String, List<String>>, includeMetadata: Boolean?, metadataOptions: MetadataOptions?): Map<String, List<TokenSupply>> { | |
return request<Indexer.GetTokenSuppliesMapResponse>( | |
method = "GetTokenSuppliesMap", | |
body = Indexer.GetTokenSuppliesMapRequest( | |
tokenMap = tokenMap,includeMetadata = includeMetadata,metadataOptions = metadataOptions, | |
) | |
).supplies | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenIDs(contractAddress: String, page: Page?): Indexer.GetTokenIDsResponse { | |
return request<Indexer.GetTokenIDsResponse>( | |
method = "GetTokenIDs", | |
body = Indexer.GetTokenIDsRequest( | |
contractAddress = contractAddress,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTokenIDRanges(contractAddress: String): Indexer.GetTokenIDRangesResponse { | |
return request<Indexer.GetTokenIDRangesResponse>( | |
method = "GetTokenIDRanges", | |
body = Indexer.GetTokenIDRangesRequest( | |
contractAddress = contractAddress, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getBalanceUpdates(contractAddress: String, lastBlockNumber: ULong, lastBlockHash: String?, page: Page?): Indexer.GetBalanceUpdatesResponse { | |
return request<Indexer.GetBalanceUpdatesResponse>( | |
method = "GetBalanceUpdates", | |
body = Indexer.GetBalanceUpdatesRequest( | |
contractAddress = contractAddress,lastBlockNumber = lastBlockNumber,lastBlockHash = lastBlockHash,page = page, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTransactionHistory(filter: TransactionHistoryFilter, page: Page?, includeMetadata: Boolean?, metadataOptions: MetadataOptions?): Indexer.GetTransactionHistoryResponse { | |
return request<Indexer.GetTransactionHistoryResponse>( | |
method = "GetTransactionHistory", | |
body = Indexer.GetTransactionHistoryRequest( | |
filter = filter,page = page,includeMetadata = includeMetadata,metadataOptions = metadataOptions, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun fetchTransactionReceipt(txnHash: String, maxBlockWait: Int?): TransactionReceipt { | |
return request<Indexer.FetchTransactionReceiptResponse>( | |
method = "FetchTransactionReceipt", | |
body = Indexer.FetchTransactionReceiptRequest( | |
txnHash = txnHash,maxBlockWait = maxBlockWait, | |
) | |
).receipt | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun fetchTransactionReceiptWithFilter(filter: TransactionFilter, maxBlockWait: Int?): TransactionReceipt { | |
return request<Indexer.FetchTransactionReceiptWithFilterResponse>( | |
method = "FetchTransactionReceiptWithFilter", | |
body = Indexer.FetchTransactionReceiptWithFilterRequest( | |
filter = filter,maxBlockWait = maxBlockWait, | |
) | |
).receipt | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun subscribeReceipts(filter: TransactionFilter): TransactionReceipt { | |
return request<Indexer.SubscribeReceiptsResponse>( | |
method = "SubscribeReceipts", | |
body = Indexer.SubscribeReceiptsRequest( | |
filter = filter, | |
) | |
).receipt | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun subscribeEvents(filter: EventFilter): EventLog { | |
return request<Indexer.SubscribeEventsResponse>( | |
method = "SubscribeEvents", | |
body = Indexer.SubscribeEventsRequest( | |
filter = filter, | |
) | |
).log | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun subscribeBalanceUpdates(contractAddress: String): TokenBalance { | |
return request<Indexer.SubscribeBalanceUpdatesResponse>( | |
method = "SubscribeBalanceUpdates", | |
body = Indexer.SubscribeBalanceUpdatesRequest( | |
contractAddress = contractAddress, | |
) | |
).balance | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun syncBalance(accountAddress: String, contractAddress: String, tokenId: String?) { | |
request<Unit>( | |
method = "SyncBalance", | |
body = Indexer.SyncBalanceRequest( | |
accountAddress = accountAddress,contractAddress = contractAddress,tokenId = tokenId, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getAllWebhookListeners(projectId: ULong?): List<WebhookListener> { | |
return request<Indexer.GetAllWebhookListenersResponse>( | |
method = "GetAllWebhookListeners", | |
body = Indexer.GetAllWebhookListenersRequest( | |
projectId = projectId, | |
) | |
).listeners | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getWebhookListener(id: ULong, projectId: ULong?): WebhookListener { | |
return request<Indexer.GetWebhookListenerResponse>( | |
method = "GetWebhookListener", | |
body = Indexer.GetWebhookListenerRequest( | |
id = id,projectId = projectId, | |
) | |
).listener | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun addWebhookListener(url: String, filters: EventFilter, projectId: ULong?): Indexer.AddWebhookListenerResponse { | |
return request<Indexer.AddWebhookListenerResponse>( | |
method = "AddWebhookListener", | |
body = Indexer.AddWebhookListenerRequest( | |
url = url,filters = filters,projectId = projectId, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun updateWebhookListener(listener: WebhookListener, projectId: ULong?): Boolean { | |
return request<Indexer.UpdateWebhookListenerResponse>( | |
method = "UpdateWebhookListener", | |
body = Indexer.UpdateWebhookListenerRequest( | |
listener = listener,projectId = projectId, | |
) | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun removeWebhookListener(id: ULong, projectId: ULong?): Boolean { | |
return request<Indexer.RemoveWebhookListenerResponse>( | |
method = "RemoveWebhookListener", | |
body = Indexer.RemoveWebhookListenerRequest( | |
id = id,projectId = projectId, | |
) | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun removeAllWebhookListeners(projectId: ULong?): Boolean { | |
return request<Indexer.RemoveAllWebhookListenersResponse>( | |
method = "RemoveAllWebhookListeners", | |
body = Indexer.RemoveAllWebhookListenersRequest( | |
projectId = projectId, | |
) | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun toggleWebhookListener(id: ULong, projectId: ULong?): WebhookListener { | |
return request<Indexer.ToggleWebhookListenerResponse>( | |
method = "ToggleWebhookListener", | |
body = Indexer.ToggleWebhookListenerRequest( | |
id = id,projectId = projectId, | |
) | |
).webhookListener | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun pauseAllWebhookListeners(projectId: ULong?): Boolean { | |
return request<Indexer.PauseAllWebhookListenersResponse>( | |
method = "PauseAllWebhookListeners", | |
body = Indexer.PauseAllWebhookListenersRequest( | |
projectId = projectId, | |
) | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun resumeAllWebhookListeners(projectId: ULong?): Boolean { | |
return request<Indexer.ResumeAllWebhookListenersResponse>( | |
method = "ResumeAllWebhookListeners", | |
body = Indexer.ResumeAllWebhookListenersRequest( | |
projectId = projectId, | |
) | |
).status | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getOrderbookOrders(page: Page?, orderbookContractAddress: String, collectionAddress: String, currencyAddresses: List<String>, filter: OrderbookOrderFilter, orderStatuses: List<OrderStatus>, filters: List<OrderbookOrderFilter>, beforeExpiryTimestamp: Long, blockNumberAfter: Long, createdAtAfter: Long): Indexer.GetOrderbookOrdersResponse { | |
return request<Indexer.GetOrderbookOrdersResponse>( | |
method = "GetOrderbookOrders", | |
body = Indexer.GetOrderbookOrdersRequest( | |
page = page,orderbookContractAddress = orderbookContractAddress,collectionAddress = collectionAddress,currencyAddresses = currencyAddresses,filter = filter,orderStatuses = orderStatuses,filters = filters,beforeExpiryTimestamp = beforeExpiryTimestamp,blockNumberAfter = blockNumberAfter,createdAtAfter = createdAtAfter, | |
) | |
) | |
} | |
@Throws(WebRpcError::class) | |
override suspend fun getTopOrders(orderbookContractAddress: String, collectionAddress: String, currencyAddresses: List<String>, tokenIdS: List<String>, isListing: Boolean, priceSort: SortOrder, excludeUser: String?): List<OrderbookOrder> { | |
return request<Indexer.GetTopOrdersResponse>( | |
method = "GetTopOrders", | |
body = Indexer.GetTopOrdersRequest( | |
orderbookContractAddress = orderbookContractAddress,collectionAddress = collectionAddress,currencyAddresses = currencyAddresses,tokenIdS = tokenIdS,isListing = isListing,priceSort = priceSort,excludeUser = excludeUser, | |
) | |
).orders | |
} | |
} | |
// endregion | |
// region Errors | |
enum class ErrorKind(val code: Int) { | |
WEBRPC_ENDPOINT(0), | |
WEBRPC_REQUEST_FAILED(-1), | |
WEBRPC_BAD_ROUTE(-2), | |
WEBRPC_BAD_METHOD(-3), | |
WEBRPC_BAD_REQUEST(-4), | |
WEBRPC_BAD_RESPONSE(-5), | |
WEBRPC_SERVER_PANIC(-6), | |
WEBRPC_INTERNAL_ERROR(-7), | |
WEBRPC_CLIENT_DISCONNECTED(-8), | |
WEBRPC_STREAM_LOST(-9), | |
WEBRPC_STREAM_FINISHED(-10), | |
UNAUTHORIZED(1000), | |
PERMISSION_DENIED(1001), | |
SESSION_EXPIRED(1002), | |
METHOD_NOT_FOUND(1003), | |
REQUEST_CONFLICT(1004), | |
ABORTED(1005), | |
GEOBLOCKED(1006), | |
RATE_LIMITED(1007), | |
PROJECT_NOT_FOUND(1100), | |
ACCESS_KEY_NOT_FOUND(1101), | |
ACCESS_KEY_MISMATCH(1102), | |
INVALID_ORIGIN(1103), | |
INVALID_SERVICE(1104), | |
UNAUTHORIZED_USER(1105), | |
QUOTA_EXCEEDED(1200), | |
RATE_LIMIT(1201), | |
NO_DEFAULT_KEY(1300), | |
MAX_ACCESS_KEYS(1301), | |
AT_LEAST_ONE_KEY(1302), | |
TIMEOUT(1900), | |
INVALID_ARGUMENT(2001), | |
UNAVAILABLE(2002), | |
QUERY_FAILED(2003), | |
RESOURCE_EXHAUSTED(2004), | |
NOT_FOUND(3000), | |
METADATA_CALL_FAILED(3003), | |
UNKNOWN(-999); | |
companion object { | |
fun fromCode(code: Int): ErrorKind { | |
return ErrorKind.values().find { it.code == code } ?: UNKNOWN | |
} | |
} | |
} | |
@JsonClass(generateAdapter = true) | |
data class WebRpcError( | |
@Json(name = "error") val error: String, | |
@Json(name = "code") val code: Int, | |
@Json(name = "msg") override val message: String, | |
@Json(name = "cause") val causeString: String, | |
@Json(name = "status") val status: Int, | |
@Transient val errorKind: ErrorKind = ErrorKind.fromCode(code), | |
@Transient override val cause: Throwable? = null, | |
) : Throwable() | |
// endregion | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment