Convenience library based on okhttp and gson to interact with aries cloud agent python (aca-py) instances.
It is currently work in progress and not all endpoints of the agent are present in the client.
Client Version | ACA-PY Version |
---|---|
>= 0.15.0 | 0.6.0 |
Method | Endpoint | Implemented |
---|---|---|
action-menu | ||
POST | /action-menu/{conn_id}/close | ✅ |
POST | /action-menu/{conn_id}/fetch | ✅ |
POST | /action-menu/{conn_id}/perform | ✅ |
POST | /action-menu/{conn_id}/request | ✅ |
POST | /action-menu/{conn_id}/send-menu | ✅ |
basicmessage | ||
POST | /connections/{conn_id}/send-message | ✅ |
connection | ||
GET | /connections | ✅ |
POST | /connections/create-invitation | ✅ |
POST | /connections/create-static | ✅ |
POST | /connections/receive-invitation | ✅ |
GET | /connections/{conn_id}} | ✅ |
DELETE | /connections/{conn_id} | ✅ |
POST | /connections/{conn_id}/accept-invitation | ✅ |
POST | /connections/{conn_id}/accept-request | ✅ |
GET | /connections/{conn_id}/endpoints | ✅ |
POST | /connections/{conn_id}/establish-inbound/{ref_id} | ✅ |
GET | /connections/{conn_id}/metadata | ✅ |
POST | /connections/{conn_id}/metadata | ✅ |
credential-definition | ||
POST | /credential-definitions | ✅ |
GET | /credential-definitions/created | ✅ |
GET | /credential-definitions/{cred_def_id} | ✅ |
credentials | ||
GET | /credentials/mime-types/{credential_id} | ✅ |
GET | /credentials/revoked/{credential_id} | ✅ |
GET | /credential/{credential_id} | ✅ |
DELETE | /credential/{credential_id} | ✅ |
GET | /credentials | ✅ |
did-exchange | ||
POST | /didexchange/create-request | ✅ |
POST | /didexchange/receive-request | ✅ |
POST | /didexchange/{conn_id}/accept-invitation | ✅ |
POST | /didexchange/{conn_id}/accept-request | ✅ |
introduction | ||
issue-credential v1.0 | ||
POST | /issue-credential/create | ✅ |
GET | /issue-credential/records | ✅ |
GET | /issue-credential/records/{cred_ex_id} | ✅ |
DELETE | /issue-credential/records/{cred_ex_id} | ✅ |
POST | /issue-credential/records/{cred_ex_id}/issue | ✅ |
POST | /issue-credential/records/{cred_ex_id}/problem-report | ✅ |
POST | /issue-credential/records/{cred_ex_id}/send-offer | ✅ |
POST | /issue-credential/records/{cred_ex_id}/send-request | ✅ |
POST | /issue-credential/records/{cred_ex_id}/store | ✅ |
POST | /issue-credential/send | ✅ |
POST | /issue-credential/send-offer | ✅ |
POST | /issue-credential/send-proposal | ✅ |
issue-credential v2.0 | ||
jsonld | ||
POST | /jsonld/sign | ✅ |
POST | /jsonld/verify | ✅ |
ledger | ||
GET | /ledger/did-endpoint | ✅ |
GET | /ledger/did-verkey | ✅ |
GET | /ledger/taa | ✅ |
POST | /ledger/taa/accept | ✅ |
mediation | ||
multitenancy | ||
POST | /multitenancy/wallet | ✅ |
GET | /multitenancy/wallet/{wallet_id} | ✅ |
PUT | /multitenancy/wallet/{wallet_id} | ✅ |
POST | /multitenancy/wallet/{wallet_id}/remove | ✅ |
POST | /multitenancy/wallet/{wallet_id}/token | ✅ |
GET | /multitenancy/wallets | ✅ |
out-of-band | ||
present-proof | ||
POST | /present-proof/create-request | ✅ |
GET | /present-proof/records | ✅ |
GET | /present-proof/records/{pres_ex_id} | ✅ |
DELETE | /present-proof/records/{pres_ex_id} | ✅ |
GET | /present-proof/records/{pres_ex_id}/credentials | ✅ |
POST | /present-proof/records/{pres_ex_id}/problem-report | ✅ |
POST | /present-proof/records/{pres_ex_id}/send-presentation | ✅ |
POST | /present-proof/records/{pres_ex_id}/send-request | ✅ |
POST | /present-proof/records/{pres_ex_id}/verify-presentation | ✅ |
POST | /present-proof/send-proposal | ✅ |
POST | /present-proof/send-request | ✅ |
resolver | ||
GET | /resolver/resolve/{did} | ✅ |
revocation | ||
GET | /revocation/active-registry/{cred_def_id} | ✅ |
POST | /revocation/clear-pending-revocations | ✅ |
POST | /revocation/create-registry | ✅ |
POST | /revocation/publish-revocations | ✅ |
GET | /revocation/registries/created | ✅ |
GET | /revocation/registry/{rev_reg_id} | ✅ |
PATCH | /revocation/registry/{rev_reg_id} | ✅ |
POST | /revocation/revoke | ✅ |
schema | ||
POST | /schemas | ✅ |
GET | /schemas/{schema_id} | ✅ |
server | ||
GET | /status/config | ✅ |
GET | /status/live | ✅ |
GET | /status/ready | ✅ |
trustping | ||
POST | /connections/{conn_id}/send-ping | ✅ |
wallet | ||
GET | /wallet/did | ✅ |
POST | /wallet/did/create | ✅ |
GET | /wallet/did/public | ✅ |
GET | /wallet/get-did-endpoint | ✅ |
POST | /wallet/set-did-endpoint | ✅ |
The default assumes you are running against a single wallet. In case of multi tenancy with base and sub wallets the bearerToken needs to be set as well.
AriesClient ac = AriesClient
.builder()
.url("https://example.com")
.apiKey("secret") // optional admin api key
.bearerToken("123.456.789") // optional jwt token - only when running in multi tennant mode
.build();
The library assumes credentials, and their related credential definitions are flat Pojo's like:
@Data @NoArgsConstructor
public final class MyCredentialDefinition {
private String street;
@AttributeName("e-mail")
private String email; // schema attribute name is e-mail
@AttributeName(excluded = true)
private String comment; // internal field
}
How fields are serialised/deserialized can be changed by using the @AttributeName annotation.
ac.connectionsReceiveInvitation(
ReceiveInvitationRequest.builder()
.did(did)
.label(label)
.build(), "alias")
.ifPresent(connection -> {
log.debug("{}", connection.getConnectionId());
});
MyCredentialDefinition myCredentialDefinition = new MyCredentialDefinition("test@myexample.com")
ac.issueCredentialSend(new IssueCredentialSend(connectionId, credentialdefinitionId, myCredentialDefinition));
PresentProofRequest proofRequest = PresentProofRequestHelper.buildForEachAttribute(
connectionId,
MySchemaPojo.class,
ProofRestrictions.builder()
.credentialDefinitionId(credentialDefinitionId)
.build());
ac.presentProofSendRequest(PresentProofRequest.build(proofRequest));
Assume you have a rest controller like this to handle aca-py webhook calls
@Controller
public class WebhookController {
@Inject private EventHandler handler;
@Post("/topic/{eventType}")
public void ariesEvent(
@PathVariable String eventType,
@Body String eventBody) {
handler.handleEvent(eventType, eventBody);
}
}
Your event handler implementation can then extend the abstract EventHandler class which takes care of type conversion so that you can immediately implement your business logic.
@Singleton
public class MyHandler extends EventHandler {
@Override
public void handleProof(PresentProofPresentation proof) {
if (proof.isVerified() && "verifier".equals(proof.getRole())) { // received a validated proof
MyCredentialDefinition myCredentialDefinition = proof.from(MyCredentialDefinition.class);
//
}
}
}
Connectionless proofs are more a thing of mobile wallets, because mostly they involve something that is presented to a human like a barcode, but the java client supports this by providing models and builders.
A flow has the usually following steps:
- The user is presented with a QRCode that contains an invite URL like: https://myhost.com/url/1234
- The server side HTTP handler of this URL responds with a HTTP.FOUND response that has the proof request encoded in the m parameter
- The mobile wallet tries to match a credential, and then responds with a proof if possible
- The server side WebhookHandler waits for the proof and then triggers further actions
@Get("/url/{requestId}")
public HttpResponse<Object> connectionLessProof(@QueryValue String requestId) {
boolean matchingRequest = false; // TODO manage request states
String proofRequestBase64 = ""; // TODO on how to build this see the example below
if (matchingRequest) {
return HttpResponse
.status(HttpStatus.FOUND)
.header("location", deploymentUri + "?m=" + proofRequestBase64;
}
return HttpResponse.notFound();
}
Proof Request Builder Example
ProofRequestPresentationBuilder builder = new ProofRequestPresentationBuilder(ariesClient);
PresentProofRequest presentProofRequest = PresentProofRequestHelper.buildForEachAttribute(
connectionId,
List.of("name", "email"),
ProofRestrictions
.builder()
.schemaId("WgWxqztrNooG92RXvxSTWv:2:schema_name:1.0")
.build());
Optional<String> base64 = builder.buildRequest(presentProofRequest);