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

Get account key endpoints #136

Merged
merged 18 commits into from
Oct 30, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.onflow.examples.java.getAccountKeys;

import org.onflow.flow.sdk.FlowAccessApi;
import org.onflow.flow.sdk.FlowAccountKey;
import org.onflow.flow.sdk.FlowAddress;

import java.util.List;
franklywatson marked this conversation as resolved.
Show resolved Hide resolved

public class GetAccountKeysAccessAPIConnector {
private final FlowAccessApi accessAPI;

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

public FlowAccountKey getAccountKeyAtLatestBlock(FlowAddress address, int keyIndex) {
FlowAccessApi.AccessApiCallResponse<FlowAccountKey> response = accessAPI.getAccountKeyAtLatestBlock(address, keyIndex);

if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<FlowAccountKey>) response).getData();
} else {
FlowAccessApi.AccessApiCallResponse.Error errorResponse = (FlowAccessApi.AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved

public FlowAccountKey getAccountKeyAtBlockHeight(FlowAddress address, int keyIndex, long height) {
FlowAccessApi.AccessApiCallResponse<FlowAccountKey> response = accessAPI.getAccountKeyAtBlockHeight(address, keyIndex, height);

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

public List<FlowAccountKey> getAccountKeysAtLatestBlock(FlowAddress address) {
FlowAccessApi.AccessApiCallResponse<List<FlowAccountKey>> response = accessAPI.getAccountKeysAtLatestBlock(address);

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

public List<FlowAccountKey> getAccountKeysAtBlockHeight(FlowAddress address, long height) {
FlowAccessApi.AccessApiCallResponse<List<FlowAccountKey>> response = accessAPI.getAccountKeysAtBlockHeight(address, height);

if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<List<FlowAccountKey>>) 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
@@ -0,0 +1,114 @@
package org.onflow.examples.java.getAccountKeys;

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.FlowServiceAccountCredentials;
import org.onflow.flow.common.test.FlowTestClient;
import org.onflow.flow.sdk.FlowAccessApi;
import org.onflow.flow.sdk.FlowAddress;
import org.onflow.flow.sdk.FlowAccountKey;
import org.onflow.flow.common.test.TestAccount;
import org.onflow.flow.sdk.FlowBlock;

import java.util.List;

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

@FlowServiceAccountCredentials
private TestAccount serviceAccount;

private GetAccountKeysAccessAPIConnector keysAPIConnector;

@BeforeEach
public void setup() {
keysAPIConnector = new GetAccountKeysAccessAPIConnector(accessAPI);
}

@Test
public void testCanFetchAccountKeyAtLatestBlock() {
FlowAddress address = serviceAccount.getFlowAddress();
int keyIndex = 0;

FlowAccountKey accountKey = keysAPIConnector.getAccountKeyAtLatestBlock(address, keyIndex);

Assertions.assertNotNull(accountKey, "Account key should not be null");
Assertions.assertEquals(keyIndex, accountKey.getSequenceNumber(), "Account key index should match the requested index");
Assertions.assertTrue(accountKey.getWeight() > 0, "Account key weight should be positive");
}

@Test
public void testCanFetchAccountKeyAtSpecificBlockHeight() {
FlowAddress address = serviceAccount.getFlowAddress();
int keyIndex = 0;

FlowAccessApi.AccessApiCallResponse<FlowBlock> latestBlockResponse = accessAPI.getLatestBlock(true, false);

if (latestBlockResponse instanceof FlowAccessApi.AccessApiCallResponse.Success) {
FlowBlock latestBlock = ((FlowAccessApi.AccessApiCallResponse.Success<FlowBlock>) latestBlockResponse).getData();
FlowAccountKey accountKey = keysAPIConnector.getAccountKeyAtBlockHeight(address, keyIndex, latestBlock.getHeight());

Assertions.assertNotNull(accountKey, "Account key at specific block height should not be null");
Assertions.assertEquals(keyIndex, accountKey.getSequenceNumber(), "Account key index at specific block height should match requested index");
Assertions.assertTrue(accountKey.getWeight() > 0, "Account key weight should be positive");

} else if (latestBlockResponse instanceof FlowAccessApi.AccessApiCallResponse.Error error) {
throw new RuntimeException("Failed to retrieve the latest block: " + error.getMessage(), error.getThrowable());
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved
}

@Test
public void testCanFetchAllAccountKeysAtLatestBlock() {
FlowAddress address = serviceAccount.getFlowAddress();

List<FlowAccountKey> accountKeys = keysAPIConnector.getAccountKeysAtLatestBlock(address);

Assertions.assertNotNull(accountKeys, "Account keys list should not be null");
Assertions.assertFalse(accountKeys.isEmpty(), "Account keys list should not be empty");
accountKeys.forEach(key -> Assertions.assertTrue(key.getWeight() > 0, "Each account key weight should be positive"));
}

@Test
public void testCanFetchAllAccountKeysAtSpecificBlockHeight() {
FlowAddress address = serviceAccount.getFlowAddress();

FlowAccessApi.AccessApiCallResponse<FlowBlock> latestBlockResponse = accessAPI.getLatestBlock(true, false);

if (latestBlockResponse instanceof FlowAccessApi.AccessApiCallResponse.Success) {
FlowBlock latestBlock = ((FlowAccessApi.AccessApiCallResponse.Success<FlowBlock>) latestBlockResponse).getData();
List<FlowAccountKey> accountKeys = keysAPIConnector.getAccountKeysAtBlockHeight(address, latestBlock.getHeight());

Assertions.assertNotNull(accountKeys, "Account keys list at specific block height should not be null");
Assertions.assertFalse(accountKeys.isEmpty(), "Account keys list at specific block height should not be empty");
accountKeys.forEach(key -> Assertions.assertTrue(key.getWeight() > 0, "Each account key weight should be positive"));
} else if (latestBlockResponse instanceof FlowAccessApi.AccessApiCallResponse.Error error) {
throw new RuntimeException("Failed to retrieve the latest block: " + error.getMessage(), error.getThrowable());
}
}

@Test
public void testAccountKeysMatchAtLatestBlockAndSpecificBlockHeight() {
FlowAddress address = serviceAccount.getFlowAddress();

List<FlowAccountKey> keysAtLatestBlock = keysAPIConnector.getAccountKeysAtLatestBlock(address);

FlowAccessApi.AccessApiCallResponse<FlowBlock> latestBlockResponse = accessAPI.getLatestBlock(true, false);

if (latestBlockResponse instanceof FlowAccessApi.AccessApiCallResponse.Success) {
FlowBlock latestBlock = ((FlowAccessApi.AccessApiCallResponse.Success<FlowBlock>) latestBlockResponse).getData();
List<FlowAccountKey> keysAtSpecificHeight = keysAPIConnector.getAccountKeysAtBlockHeight(address, latestBlock.getHeight());

Assertions.assertEquals(keysAtLatestBlock.size(), keysAtSpecificHeight.size(), "Number of account keys should match at latest block and specific block height");

for (int i = 0; i < keysAtLatestBlock.size(); i++) {
Assertions.assertEquals(keysAtLatestBlock.get(i), keysAtSpecificHeight.get(i), "Account key at index " + i + " should match between latest block and specific block height");
}
} else if (latestBlockResponse instanceof FlowAccessApi.AccessApiCallResponse.Error error) {
throw new RuntimeException("Failed to retrieve the latest block: " + error.getMessage(), error.getThrowable());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.onflow.examples.kotlin.getAccountKeys

import org.onflow.flow.sdk.*

internal class GetAccountKeysAccessAPIConnector(
private val accessAPI: FlowAccessApi
) {
fun getAccountKeyAtLatestBlock(address: FlowAddress, keyIndex: Int): FlowAccountKey =
when (val response = accessAPI.getAccountKeyAtLatestBlock(address, keyIndex)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getAccountKeyAtBlockHeight(address: FlowAddress, keyIndex: Int, height: Long): FlowAccountKey =
when (val response = accessAPI.getAccountKeyAtBlockHeight(address, keyIndex, height)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getAccountKeysAtLatestBlock(address: FlowAddress): List<FlowAccountKey> =
when (val response = accessAPI.getAccountKeysAtLatestBlock(address)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getAccountKeysAtBlockHeight(address: FlowAddress, height: Long): List<FlowAccountKey> =
when (val response = accessAPI.getAccountKeysAtBlockHeight(address, height)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.onflow.examples.kotlin.getAccountKeys

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.FlowServiceAccountCredentials
import org.onflow.flow.common.test.FlowTestClient
import org.onflow.flow.common.test.TestAccount
import org.onflow.flow.sdk.FlowAccessApi

@FlowEmulatorProjectTest(flowJsonLocation = "../flow/flow.json")
internal class GetAccountKeysAccessAPIConnectorTest {
@FlowServiceAccountCredentials
lateinit var serviceAccount: TestAccount

@FlowTestClient
lateinit var accessAPI: FlowAccessApi

private lateinit var keysAPIConnector: GetAccountKeysAccessAPIConnector

@BeforeEach
fun setup() {
keysAPIConnector = GetAccountKeysAccessAPIConnector(accessAPI)
}

@Test
fun `Can fetch account key at latest block`() {
val address = serviceAccount.flowAddress
val keyIndex = 0

val accountKey = keysAPIConnector.getAccountKeyAtLatestBlock(address, keyIndex)

Assertions.assertNotNull(accountKey, "Account key should not be null")
Assertions.assertEquals(keyIndex, accountKey.sequenceNumber, "Account key index should match requested index")
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved

@Test
fun `Can fetch account key at a specific block height`() {
val address = serviceAccount.flowAddress
val keyIndex = 0
when (val latestBlock = accessAPI.getLatestBlock(true)) {
is FlowAccessApi.AccessApiCallResponse.Success -> {
val accountKey = keysAPIConnector.getAccountKeyAtBlockHeight(address, keyIndex, latestBlock.data.height)

Assertions.assertNotNull(accountKey, "Account key at specific block height should not be null")
Assertions.assertEquals(keyIndex, accountKey.sequenceNumber, "Account key index at specific block height should match requested index")
}
is FlowAccessApi.AccessApiCallResponse.Error -> Assertions.fail("Failed to retrieve the latest block: ${latestBlock.message}")
}
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved

@Test
fun `Can fetch all account keys at latest block`() {
val address = serviceAccount.flowAddress
val accountKeys = keysAPIConnector.getAccountKeysAtLatestBlock(address)

Assertions.assertNotNull(accountKeys, "Account keys should not be null")
Assertions.assertTrue(accountKeys.isNotEmpty(), "Account keys should not be empty")
}

@Test
fun `Can fetch all account keys at a specific block height`() {
val address = serviceAccount.flowAddress
val latestBlock = accessAPI.getLatestBlock(true)

when (latestBlock) {
is FlowAccessApi.AccessApiCallResponse.Success -> {
val accountKeys = keysAPIConnector.getAccountKeysAtBlockHeight(address, latestBlock.data.height)

Assertions.assertNotNull(accountKeys, "Account keys at specific block height should not be null")
Assertions.assertTrue(accountKeys.isNotEmpty(), "Account keys at specific block height should not be empty")
}
is FlowAccessApi.AccessApiCallResponse.Error -> Assertions.fail("Failed to retrieve the latest block: ${latestBlock.message}")
}
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved

@Test
fun `Account keys at the latest block and specific block height should match`() {
val address = serviceAccount.flowAddress

// Fetch account keys at latest block
val keysAtLatest = keysAPIConnector.getAccountKeysAtLatestBlock(address)

// Fetch latest block height
val latestBlock = accessAPI.getLatestBlock(true)
when (latestBlock) {
is FlowAccessApi.AccessApiCallResponse.Success -> {
val blockHeight = latestBlock.data.height

// Fetch account keys at the same block height
val keysAtHeight = keysAPIConnector.getAccountKeysAtBlockHeight(address, blockHeight)

Assertions.assertEquals(keysAtLatest.size, keysAtHeight.size, "Number of account keys should match at latest block and specific block height")

keysAtLatest.forEachIndexed { index, key ->
Assertions.assertEquals(key, keysAtHeight[index], "Account key at index $index should match between latest block and specific block height")
}
}
is FlowAccessApi.AccessApiCallResponse.Error -> Assertions.fail("Failed to retrieve the latest block: ${latestBlock.message}")
}
}
franklywatson marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading