com.nftco.flow.sdk.impl.AsyncFlowAccessApiImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of flow-jvm-sdk Show documentation
Show all versions of flow-jvm-sdk Show documentation
The Flow Blockchain JVM SDK
The newest version!
package com.nftco.flow.sdk.impl
import com.google.common.util.concurrent.FutureCallback
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
import com.google.protobuf.ByteString
import com.nftco.flow.sdk.*
import io.grpc.ManagedChannel
import org.onflow.protobuf.access.Access
import org.onflow.protobuf.access.AccessAPIGrpc
import java.io.Closeable
import java.util.concurrent.CompletableFuture
class AsyncFlowAccessApiImpl(
private val api: AccessAPIGrpc.AccessAPIFutureStub
) : AsyncFlowAccessApi, Closeable {
override fun close() {
val chan = api.channel
if (chan is ManagedChannel) {
chan.shutdownNow()
}
}
override fun ping(): CompletableFuture {
return completableFuture(
api.ping(
Access.PingRequest.newBuilder()
.build()
)
).thenApply {
Unit
}
}
override fun getLatestBlockHeader(sealed: Boolean): CompletableFuture {
return completableFuture(
api.getLatestBlockHeader(
Access.GetLatestBlockHeaderRequest.newBuilder()
.setIsSealed(sealed)
.build()
)
).thenApply {
FlowBlockHeader.of(it.block)
}
}
override fun getBlockHeaderById(id: FlowId): CompletableFuture {
return completableFuture(
api.getBlockHeaderByID(
Access.GetBlockHeaderByIDRequest.newBuilder()
.setId(id.byteStringValue)
.build()
)
).thenApply {
if (it.hasBlock()) {
FlowBlockHeader.of(it.block)
} else {
null
}
}
}
override fun getBlockHeaderByHeight(height: Long): CompletableFuture {
return completableFuture(
api.getBlockHeaderByHeight(
Access.GetBlockHeaderByHeightRequest.newBuilder()
.setHeight(height)
.build()
)
).thenApply {
if (it.hasBlock()) {
FlowBlockHeader.of(it.block)
} else {
null
}
}
}
override fun getLatestBlock(sealed: Boolean): CompletableFuture {
return completableFuture(
api.getLatestBlock(
Access.GetLatestBlockRequest.newBuilder()
.setIsSealed(sealed)
.build()
)
).thenApply {
FlowBlock.of(it.block)
}
}
override fun getBlockById(id: FlowId): CompletableFuture {
return completableFuture(
api.getBlockByID(
Access.GetBlockByIDRequest.newBuilder()
.setId(id.byteStringValue)
.build()
)
).thenApply {
if (it.hasBlock()) {
FlowBlock.of(it.block)
} else {
null
}
}
}
override fun getBlockByHeight(height: Long): CompletableFuture {
return completableFuture(
api.getBlockByHeight(
Access.GetBlockByHeightRequest.newBuilder()
.setHeight(height)
.build()
)
).thenApply {
if (it.hasBlock()) {
FlowBlock.of(it.block)
} else {
null
}
}
}
override fun getCollectionById(id: FlowId): CompletableFuture {
return completableFuture(
api.getCollectionByID(
Access.GetCollectionByIDRequest.newBuilder()
.setId(id.byteStringValue)
.build()
)
).thenApply {
if (it.hasCollection()) {
FlowCollection.of(it.collection)
} else {
null
}
}
}
override fun sendTransaction(transaction: FlowTransaction): CompletableFuture {
return completableFuture(
api.sendTransaction(
Access.SendTransactionRequest.newBuilder()
.setTransaction(transaction.builder().build())
.build()
)
).thenApply {
FlowId.of(it.id.toByteArray())
}
}
override fun getTransactionById(id: FlowId): CompletableFuture {
return completableFuture(
api.getTransaction(
Access.GetTransactionRequest.newBuilder()
.setId(id.byteStringValue)
.build()
)
).thenApply {
if (it.hasTransaction()) {
FlowTransaction.of(it.transaction)
} else {
null
}
}
}
override fun getTransactionResultById(id: FlowId): CompletableFuture {
return completableFuture(
api.getTransactionResult(
Access.GetTransactionRequest.newBuilder()
.setId(id.byteStringValue)
.build()
)
).thenApply {
FlowTransactionResult.of(it)
}
}
override fun getAccountByAddress(addresss: FlowAddress): CompletableFuture {
return completableFuture(
api.getAccount(
Access.GetAccountRequest.newBuilder()
.setAddress(addresss.byteStringValue)
.build()
)
).thenApply {
if (it.hasAccount()) {
FlowAccount.of(it.account)
} else {
null
}
}
}
override fun getAccountAtLatestBlock(addresss: FlowAddress): CompletableFuture {
return completableFuture(
api.getAccountAtLatestBlock(
Access.GetAccountAtLatestBlockRequest.newBuilder()
.setAddress(addresss.byteStringValue)
.build()
)
).thenApply {
if (it.hasAccount()) {
FlowAccount.of(it.account)
} else {
null
}
}
}
override fun getAccountByBlockHeight(addresss: FlowAddress, height: Long): CompletableFuture {
return completableFuture(
api.getAccountAtBlockHeight(
Access.GetAccountAtBlockHeightRequest.newBuilder()
.setAddress(addresss.byteStringValue)
.setBlockHeight(height)
.build()
)
).thenApply {
if (it.hasAccount()) {
FlowAccount.of(it.account)
} else {
null
}
}
}
override fun executeScriptAtLatestBlock(script: FlowScript, arguments: Iterable): CompletableFuture {
return completableFuture(
api.executeScriptAtLatestBlock(
Access.ExecuteScriptAtLatestBlockRequest.newBuilder()
.setScript(script.byteStringValue)
.addAllArguments(arguments)
.build()
)
).thenApply {
FlowScriptResponse(it.value.toByteArray())
}
}
override fun executeScriptAtBlockId(script: FlowScript, blockId: FlowId, arguments: Iterable): CompletableFuture {
return completableFuture(
api.executeScriptAtBlockID(
Access.ExecuteScriptAtBlockIDRequest.newBuilder()
.setBlockId(blockId.byteStringValue)
.setScript(script.byteStringValue)
.addAllArguments(arguments)
.build()
)
).thenApply {
FlowScriptResponse(it.value.toByteArray())
}
}
override fun executeScriptAtBlockHeight(
script: FlowScript,
height: Long,
arguments: Iterable
): CompletableFuture {
return completableFuture(
api.executeScriptAtBlockHeight(
Access.ExecuteScriptAtBlockHeightRequest.newBuilder()
.setBlockHeight(height)
.setScript(script.byteStringValue)
.addAllArguments(arguments)
.build()
)
).thenApply {
FlowScriptResponse(it.value.toByteArray())
}
}
override fun getEventsForHeightRange(
type: String,
range: ClosedRange
): CompletableFuture> {
return completableFuture(
api.getEventsForHeightRange(
Access.GetEventsForHeightRangeRequest.newBuilder()
.setType(type)
.setStartHeight(range.start)
.setEndHeight(range.endInclusive)
.build()
)
).thenApply {
it.resultsList
.map { FlowEventResult.of(it) }
}
}
override fun getEventsForBlockIds(type: String, ids: Set): CompletableFuture> {
return completableFuture(
api.getEventsForBlockIDs(
Access.GetEventsForBlockIDsRequest.newBuilder()
.setType(type)
.addAllBlockIds(ids.map { it.byteStringValue })
.build()
)
).thenApply {
it.resultsList
.map { FlowEventResult.of(it) }
}
}
override fun getNetworkParameters(): CompletableFuture {
return completableFuture(
api.getNetworkParameters(
Access.GetNetworkParametersRequest.newBuilder()
.build()
)
).thenApply {
FlowChainId.of(it.chainId)
}
}
override fun getLatestProtocolStateSnapshot(): CompletableFuture {
return completableFuture(
api.getLatestProtocolStateSnapshot(
Access.GetLatestProtocolStateSnapshotRequest.newBuilder()
.build()
)
).thenApply {
FlowSnapshot(it.serializedSnapshot.toByteArray())
}
}
}
fun completableFuture(future: ListenableFuture): CompletableFuture {
val completable: CompletableFuture = object : CompletableFuture() {
override fun cancel(mayInterruptIfRunning: Boolean): Boolean {
val result: Boolean = future.cancel(mayInterruptIfRunning)
super.cancel(mayInterruptIfRunning)
return result
}
}
Futures.addCallback(
future,
object : FutureCallback {
override fun onSuccess(result: T?) {
completable.complete(result)
}
override fun onFailure(t: Throwable) {
completable.completeExceptionally(t)
}
},
MoreExecutors.directExecutor()
)
return completable
}