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
Empty file.
5 changes: 5 additions & 0 deletions java-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ Below is a list of all Java code examples currently supported in this repo:
- Get account balance
- Get account from the latest block
- Get account from block by height
- Get account key at latest block
- Get account keys at latest block
- Get account key at block height
- Get account keys at block height

#### Get Events

Expand Down Expand Up @@ -80,6 +84,7 @@ Below is a list of all Java code examples currently supported in this repo:

- Get transaction
- Get transaction result
- Get transaction result by index
lealobanov marked this conversation as resolved.
Show resolved Hide resolved

#### Sending Transactions

Expand Down
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
Expand Up @@ -31,4 +31,14 @@ public FlowTransactionResult getTransactionResult(FlowId txID) {
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
}

public FlowTransactionResult getTransactionResultByIndex(FlowId blockId, Integer index) {
FlowAccessApi.AccessApiCallResponse<FlowTransactionResult> response = accessAPI.getTransactionResultByIndex(blockId, index);
if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
return ((FlowAccessApi.AccessApiCallResponse.Success<FlowTransactionResult>) 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
Expand Up @@ -7,14 +7,9 @@
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.FlowId;
import org.onflow.flow.sdk.FlowTransaction;
import org.onflow.flow.sdk.FlowTransactionResult;
import org.onflow.flow.sdk.FlowTransactionStatus;
import org.onflow.flow.sdk.*;
import org.onflow.flow.sdk.crypto.Crypto;
import org.onflow.flow.sdk.crypto.PublicKey;
import org.onflow.flow.sdk.SignatureAlgorithm;

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

Expand All @@ -26,6 +21,7 @@ public class GetTransactionAccessAPIConnectorTest {
private FlowAccessApi accessAPI;
private GetTransactionAccessAPIConnector connector;
private FlowId txID;
private FlowBlock block;

@BeforeEach
public void setup() {
Expand All @@ -38,6 +34,14 @@ public void setup() {
serviceAccount.getFlowAddress(),
publicKey
);

FlowAccessApi.AccessApiCallResponse<FlowBlock> response = accessAPI.getLatestBlock(true, false);
if (response instanceof FlowAccessApi.AccessApiCallResponse.Success) {
block = ((FlowAccessApi.AccessApiCallResponse.Success<FlowBlock>) response).getData();
} else {
FlowAccessApi.AccessApiCallResponse.Error errorResponse = (FlowAccessApi.AccessApiCallResponse.Error) response;
throw new RuntimeException(errorResponse.getMessage(), errorResponse.getThrowable());
}
lealobanov marked this conversation as resolved.
Show resolved Hide resolved
}

@Test
Expand All @@ -55,4 +59,12 @@ public void canFetchTransactionResult() {
assertNotNull(transactionResult, "Transaction result should not be null");
assertSame(transactionResult.getStatus(), FlowTransactionStatus.SEALED, "Transaction should be sealed");
}

@Test
public void canFetchTransactionResultByIndex() {
FlowTransactionResult transactionResult = connector.getTransactionResultByIndex(block.getId(),0);

assertNotNull(transactionResult, "Transaction result should not be null");
assertSame(transactionResult.getStatus(), FlowTransactionStatus.SEALED, "Transaction should be sealed");
}
lealobanov marked this conversation as resolved.
Show resolved Hide resolved
}
5 changes: 5 additions & 0 deletions kotlin-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Below is a list of all Kotlin code examples currently supported in this repo:
- Get account balance
- Get account from the latest block
- Get account from block by height
- Get account key at latest block
- Get account keys at latest block
- Get account key at block height
- Get account keys at block height

#### Get Events

Expand Down Expand Up @@ -81,6 +85,7 @@ Below is a list of all Kotlin code examples currently supported in this repo:

- Get transaction
- Get transaction result
- Get transaction result by index

#### Sending Transactions

Expand Down
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
Expand Up @@ -16,4 +16,10 @@ class GetTransactionAccessAPIConnector(
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}

fun getTransactionResultByIndex(blockId: FlowId, index: Int): FlowTransactionResult =
when (val response = accessAPI.getTransactionResultByIndex(blockId, index)) {
is FlowAccessApi.AccessApiCallResponse.Success -> response.data
is FlowAccessApi.AccessApiCallResponse.Error -> throw Exception(response.message, response.throwable)
}
}
Loading
Loading