Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GetProtocolStateSnapshotByBlockID and GetProtocolStateSnapshotByHeight to the SDK #141

Merged
3 changes: 3 additions & 0 deletions java-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ Below is a list of all Java code examples currently supported in this repo:

[Get collections by ID.](src/main/java/org/onflow/examples/java/getCollection/GetCollectionAccessAPIConnector.java)

- Get collection by id
- Get full collection by id (returns all transactions in collection response)

#### Get Execution Data

[Get execution data by block ID.](src/main/java/org/onflow/examples/java/getExecutionData/GetExecutionDataAccessAPIConnector.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import org.onflow.flow.sdk.FlowAccessApi.AccessApiCallResponse;
import org.onflow.flow.sdk.FlowCollection;
import org.onflow.flow.sdk.FlowId;
import org.onflow.flow.sdk.FlowTransaction;

import java.util.List;

public class GetCollectionAccessAPIConnector {
private final FlowAccessApi accessAPI;
Expand All @@ -21,4 +24,14 @@ public FlowCollection getCollectionById(FlowId collectionId) {
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}

public List<FlowTransaction> getFullCollectionById(FlowId collectionId) {
AccessApiCallResponse<List<FlowTransaction>> response = accessAPI.getFullCollectionById(collectionId);
if (response instanceof AccessApiCallResponse.Success) {
return ((AccessApiCallResponse.Success<List<FlowTransaction>>) response).getData();
} else {
AccessApiCallResponse.Error errorResponse = (AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.onflow.examples.java.getProtocolState;

import org.onflow.flow.sdk.FlowAccessApi;
import org.onflow.flow.sdk.FlowId;
import org.onflow.flow.sdk.FlowSnapshot;

public class GetProtocolStateAccessAPIConnector {
private final FlowAccessApi accessAPI;

public GetProtocolStateAccessAPIConnector(FlowAccessApi accessAPI) {
this.accessAPI = accessAPI;
}

public FlowSnapshot getLatestProtocolStateSnapshot() {
FlowAccessApi.AccessApiCallResponse<FlowSnapshot> response = accessAPI.getLatestProtocolStateSnapshot();
if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<FlowSnapshot>) response).getData();
} else {
FlowAccessApi.AccessApiCallResponse.Error errorResponse = (FlowAccessApi.AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}

public FlowSnapshot getProtocolStateSnapshotByBlockId(FlowId blockId) {
FlowAccessApi.AccessApiCallResponse<FlowSnapshot> response = accessAPI.getProtocolStateSnapshotByBlockId(blockId);
if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<FlowSnapshot>) response).getData();
} else {
FlowAccessApi.AccessApiCallResponse.Error errorResponse = (FlowAccessApi.AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}

public FlowSnapshot getProtocolStateSnapshotByHeight(Long height) {
FlowAccessApi.AccessApiCallResponse<FlowSnapshot> response = accessAPI.getProtocolStateSnapshotByHeight(height);
if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<FlowSnapshot>) response).getData();
} else {
FlowAccessApi.AccessApiCallResponse.Error errorResponse = (FlowAccessApi.AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.onflow.flow.sdk.crypto.Crypto;
import org.onflow.flow.sdk.crypto.PublicKey;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
Expand Down Expand Up @@ -51,4 +53,16 @@ public void canFetchCollectionById() {
assertNotNull(collection, "Collection should not be null");
assertEquals(collectionId, collection.getId(), "Collection ID should match the fetched collection ID");
}

@Test
public void canFetchFullCollectionById() {
List<FlowTransaction> fullCollectionResponse = connector.getFullCollectionById(collectionId);

assertNotNull(fullCollectionResponse, "Collection transactions should not be null");
assertFalse(fullCollectionResponse.isEmpty(), "Collection transactions should not be empty");

FlowTransaction firstTransaction = fullCollectionResponse.get(0);
assertNotNull(firstTransaction.getId(), "Transaction ID should not be null");
assertNotNull(firstTransaction.getScript(), "Transaction script should not be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.onflow.examples.java.getProtocolState;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.onflow.flow.common.test.FlowEmulatorProjectTest;
import org.onflow.flow.common.test.FlowTestClient;
import org.onflow.flow.sdk.FlowAccessApi;
import org.onflow.flow.sdk.FlowBlock;
import org.onflow.flow.sdk.FlowSnapshot;

import static org.junit.jupiter.api.Assertions.*;

@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
public class GetProtocolStateAccessAPIConnectorTest {
@FlowTestClient
private FlowAccessApi accessAPI;
private FlowBlock block;

private GetProtocolStateAccessAPIConnector protocolStateConnector;

@BeforeEach
public void setup() {
protocolStateConnector = new GetProtocolStateAccessAPIConnector(accessAPI);
}

@Test
public void canGetLatestProtocolStateSnapshot() {
FlowSnapshot latestSnapshot = protocolStateConnector.getLatestProtocolStateSnapshot();
assertNotNull(latestSnapshot, "Latest snapshot should not be null");
}

@Test
public void canGetProtocolStateSnapshotByBlockId() {
block = getLatestBlock();
FlowSnapshot snapshot = protocolStateConnector.getProtocolStateSnapshotByBlockId(block.getId());
assertNotNull(snapshot, "Snapshot should not be null");
}

@Test
public void canGetProtocolStateSnapshotByHeight() {
block = getLatestBlock();
FlowSnapshot snapshot = protocolStateConnector.getProtocolStateSnapshotByHeight(block.getHeight());
assertNotNull(snapshot, "Snapshot should not be null");
}

private FlowBlock getLatestBlock() {
FlowAccessApi.AccessApiCallResponse<FlowBlock> response = accessAPI.getLatestBlock(true, false);
if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<FlowBlock>) response).getData();
} else {
FlowAccessApi.AccessApiCallResponse.Error errorResponse = (FlowAccessApi.AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}
}
3 changes: 3 additions & 0 deletions kotlin-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ Below is a list of all Kotlin code examples currently supported in this repo:

[Get collections by ID.](src/main/kotlin/org/onflow/examples/kotlin/getCollection/GetCollectionAccessAPIConnector.kt)

- Get collection by id
- Get full collection by id (returns all transactions in collection response)

#### Get Execution Data

[Get execution data by block ID.](src/main/kotlin/org/onflow/examples/kotlin/getExecutionData/GetExecutionDataAccessAPIConnector.kt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ class GetCollectionAccessAPIConnector(
is AccessApiCallResponse.Success -> response.data
is AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getFullCollectionById(collectionId: FlowId): List<FlowTransaction> =
when (val response = accessAPI.getFullCollectionById(collectionId)) {
is AccessApiCallResponse.Success -> response.data
is AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.onflow.examples.kotlin.getProtocolState

import org.onflow.flow.sdk.FlowAccessApi
import org.onflow.flow.sdk.FlowId
import org.onflow.flow.sdk.FlowSnapshot

internal class GetProtocolStateAccessAPIConnector(
private val accessAPI: FlowAccessApi
) {
fun getLatestProtocolStateSnapshot(): FlowSnapshot =
when (val response = accessAPI.getLatestProtocolStateSnapshot()) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getProtocolStateSnapshotByBlockId(blockId: FlowId): FlowSnapshot =
when (val response = accessAPI.getProtocolStateSnapshotByBlockId(blockId)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getProtocolStateSnapshotByHeight(height: Long): FlowSnapshot =
when (val response = accessAPI.getProtocolStateSnapshotByHeight(height)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import org.onflow.flow.common.test.FlowEmulatorProjectTest
import org.onflow.flow.common.test.FlowServiceAccountCredentials
import org.onflow.flow.common.test.FlowTestClient
import org.onflow.flow.common.test.TestAccount
import org.onflow.flow.sdk.FlowAccessApi
import org.onflow.flow.sdk.FlowCollection
import org.onflow.flow.sdk.FlowId
import org.onflow.flow.sdk.SignatureAlgorithm
import org.onflow.flow.sdk.*
import org.onflow.flow.sdk.crypto.Crypto

@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
Expand Down Expand Up @@ -53,4 +50,16 @@ class GetCollectionAccessAPIConnectorTest {
assertNotNull(collection, "Collection should not be null")
assertEquals(collectionId, collection.id, "Collection ID should match the fetched collection ID")
}

@Test
fun `Can fetch full collection by ID`() {
val collectionTransactions: List<FlowTransaction> = connector.getFullCollectionById(collectionId)

assertNotNull(collectionTransactions, "Collection transactions should not be null")
assertTrue(collectionTransactions.isNotEmpty(), "Collection transactions should not be empty")

val firstTransaction = collectionTransactions.first()
assertNotNull(firstTransaction.id, "Transaction ID should not be null")
assertNotNull(firstTransaction.script, "Transaction script should not be null")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.onflow.flow.sdk.FlowAccessApi
import org.onflow.flow.sdk.FlowChainId

@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
internal class GetNetworkParametersAccessAPIConnectorTest {
internal class GetNetworkParamsAccessAPIConnectorTest {
@FlowTestClient
lateinit var accessAPI: FlowAccessApi

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.onflow.examples.kotlin.getProtocolState

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.onflow.flow.common.test.FlowEmulatorProjectTest
import org.onflow.flow.common.test.FlowTestClient
import org.onflow.flow.sdk.FlowAccessApi
import org.onflow.flow.sdk.FlowBlock
import org.onflow.flow.sdk.FlowSnapshot

@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
internal class GetProtocolStateAccessAPIConnectorTest {
@FlowTestClient
lateinit var accessAPI: FlowAccessApi
lateinit var block: FlowBlock

private lateinit var protocolStateConnector: GetProtocolStateAccessAPIConnector

@BeforeEach
fun setup() {
protocolStateConnector = GetProtocolStateAccessAPIConnector(accessAPI)
}

@Test
fun `Can get latest protocol state snapshot`() {
val latestSnapshot: FlowSnapshot = protocolStateConnector.getLatestProtocolStateSnapshot()
assertNotNull(latestSnapshot, "Latest snapshot should not be null")
}

@Test
fun `Can get protocol state snapshot by blockId`() {
block = when (val response = accessAPI.getLatestBlock()) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

val latestSnapshot: FlowSnapshot = protocolStateConnector.getProtocolStateSnapshotByBlockId(block.id)
assertNotNull(latestSnapshot, ("Snapshot should not be null"))
}

@Test
fun `Can get protocol state snapshot by height`() {
block = when (val response = accessAPI.getLatestBlock()) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

val latestSnapshot: FlowSnapshot = protocolStateConnector.getProtocolStateSnapshotByHeight(block.height)
assertNotNull(latestSnapshot, ("Snapshot should not be null"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class TransactionIntegrationTest {
const val BLOCK_HEIGHT_ERROR = "Failed to get block by height"
const val ACCOUNT_BY_ADDRESS_ERROR = "Failed to get account by address"
const val ACCOUNT_BY_BLOCK_HEIGHT_ERROR = "Failed to get account by block height"
const val PROTOCOL_STATE_HEIGHT_ERROR = "Failed to get protocol state snapshot by height"
const val PROTOCOL_STATE_BLOCK_ERROR = "Failed to get protocol state snapshot by block ID"
const val PROTOCOL_STATE_LATEST_ERROR = "Failed to get latest protocol state snapshot"
}

private fun <T> safelyHandle(action: () -> Result<T>, errorMessage: String): T =
Expand Down Expand Up @@ -86,6 +89,35 @@ class TransactionIntegrationTest {
assertThat(account.keys).isNotEmpty()
}

@Test
fun `Can get latest protocol state snapshot`() {
val snapshot = safelyHandle(
{ Result.success(handleResult(accessAPI.getLatestProtocolStateSnapshot(), PROTOCOL_STATE_LATEST_ERROR)) },
PROTOCOL_STATE_LATEST_ERROR
)
assertThat(snapshot).isNotNull
}

@Test
fun `Can get protocol state snapshot by blockId`() {
val latestBlock = getLatestBlock()
val snapshot = safelyHandle(
{ Result.success(handleResult(accessAPI.getProtocolStateSnapshotByBlockId(latestBlock.id), PROTOCOL_STATE_HEIGHT_ERROR)) },
PROTOCOL_STATE_BLOCK_ERROR
)
assertThat(snapshot).isNotNull
}

@Test
fun `Can get protocol state snapshot by height`() {
val latestBlock = getLatestBlock()
val snapshot = safelyHandle(
{ Result.success(handleResult(accessAPI.getProtocolStateSnapshotByHeight(latestBlock.height), PROTOCOL_STATE_HEIGHT_ERROR)) },
PROTOCOL_STATE_HEIGHT_ERROR
)
assertThat(snapshot).isNotNull
}

@Test
fun `Can get network parameters`() {
val networkParams = safelyHandle(
Expand Down
6 changes: 6 additions & 0 deletions sdk/src/main/kotlin/org/onflow/flow/sdk/AsyncFlowAccessApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ interface AsyncFlowAccessApi {

fun getCollectionById(id: FlowId): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowCollection?>>

fun getFullCollectionById(id: FlowId): CompletableFuture<FlowAccessApi.AccessApiCallResponse<List<FlowTransaction>>>

fun sendTransaction(transaction: FlowTransaction): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowId>>

fun getTransactionById(id: FlowId): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowTransaction?>>
Expand Down Expand Up @@ -64,6 +66,10 @@ interface AsyncFlowAccessApi {

fun getLatestProtocolStateSnapshot(): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowSnapshot>>

fun getProtocolStateSnapshotByBlockId(blockId: FlowId): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowSnapshot>>

fun getProtocolStateSnapshotByHeight(height: Long): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowSnapshot>>

fun getNodeVersionInfo(): CompletableFuture<FlowAccessApi.AccessApiCallResponse<FlowNodeVersionInfo>>

fun getTransactionsByBlockId(id: FlowId): CompletableFuture<FlowAccessApi.AccessApiCallResponse<List<FlowTransaction>>>
Expand Down
6 changes: 6 additions & 0 deletions sdk/src/main/kotlin/org/onflow/flow/sdk/FlowAccessApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ interface FlowAccessApi {

fun getCollectionById(id: FlowId): AccessApiCallResponse<FlowCollection>

fun getFullCollectionById(id: FlowId): AccessApiCallResponse<List<FlowTransaction>>

fun sendTransaction(transaction: FlowTransaction): AccessApiCallResponse<FlowId>

fun getTransactionById(id: FlowId): AccessApiCallResponse<FlowTransaction>
Expand Down Expand Up @@ -76,6 +78,10 @@ interface FlowAccessApi {

fun getLatestProtocolStateSnapshot(): AccessApiCallResponse<FlowSnapshot>

fun getProtocolStateSnapshotByBlockId(blockId: FlowId): AccessApiCallResponse<FlowSnapshot>

fun getProtocolStateSnapshotByHeight(height: Long): AccessApiCallResponse<FlowSnapshot>

fun getNodeVersionInfo(): AccessApiCallResponse<FlowNodeVersionInfo>

fun getTransactionsByBlockId(id: FlowId): AccessApiCallResponse<List<FlowTransaction>>
Expand Down
Loading
Loading