14: Add getProgramAccounts(...) API method
This commit is contained in:
@@ -331,6 +331,67 @@ public class SolanaBlockChainImpl implements SolanaBlockChain {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<SolanaAccountInfo> getProgramAccounts(
|
||||||
|
ΩSolanaProgramIdΩ programId,
|
||||||
|
Set<SolanaProgramAccountMemcmpFilter> filters
|
||||||
|
) throws IOException, InterruptedException {
|
||||||
|
String jsonBody = createGetProgramAccountsBody(programId, filters);
|
||||||
|
|
||||||
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(RPC_URL))
|
||||||
|
.header("Content-Type", "application/json")
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(jsonBody))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response = sendThrottled(request);
|
||||||
|
|
||||||
|
if (response.statusCode() != 200) {
|
||||||
|
throw new IOException("RPC call failed: HTTP " + response.statusCode() + "\n" + response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode root = objectMapper.readTree(response.body());
|
||||||
|
|
||||||
|
if (root.has("error")) {
|
||||||
|
throw new IOException("Solana RPC error: " + root.get("error").toPrettyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode result = root.path("result");
|
||||||
|
|
||||||
|
if (!result.isArray()) {
|
||||||
|
throw new IOException("getProgramAccounts response did not contain result array!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<SolanaAccountInfo> accountInfos = new HashSet<>();
|
||||||
|
|
||||||
|
for (JsonNode accountNode : result) {
|
||||||
|
JsonNode pubkeyNode = accountNode.path("pubkey");
|
||||||
|
JsonNode account = accountNode.path("account");
|
||||||
|
|
||||||
|
if (!pubkeyNode.isTextual()) {
|
||||||
|
throw new IOException("getProgramAccounts response contained account without textual pubkey!");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode ownerNode = account.path("owner");
|
||||||
|
if (!ownerNode.isTextual()) {
|
||||||
|
throw new IOException("getProgramAccounts response contained account without textual owner!");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode dataNode = account.path("data");
|
||||||
|
if (!dataNode.isArray() || dataNode.isEmpty() || !dataNode.get(0).isTextual()) {
|
||||||
|
throw new IOException("getProgramAccounts response contained account without base64 data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
accountInfos.add(new SolanaAccountInfo(
|
||||||
|
pubkeyNode.asText(),
|
||||||
|
ownerNode.asText(),
|
||||||
|
dataNode.get(0).asText()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Set.copyOf(accountInfos);
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized HttpResponse<String> sendThrottled(HttpRequest request) throws IOException, InterruptedException {
|
private synchronized HttpResponse<String> sendThrottled(HttpRequest request) throws IOException, InterruptedException {
|
||||||
waitBeforeRemoteCall();
|
waitBeforeRemoteCall();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user