Skip to content

Wallet Service

The wallet service is the main interface for interacting with a cloud wallet. The service endpoints are designed to closely match the recommendations of the Universal Wallet 2020 specification by W3C Community Credentials Group. The service exposes a gRPC interface and a set of data contracts as described in the specification. Our intention with this design is to bring it closer to interoperability as more implementations of this wallet appear in production.

Wallets vs Accounts

Wallets and accounts are related and often interchangeable -- each account has an associated wallet, and operations on a wallet are performed using an account's access token.

Every account has exactly one wallet.

Create Wallet

Wallets can be created directly by the user or through an invitation by the ecosystem provider. Depending on the ecosystem settings, direct wallet creation may not be enabled for your provider. The wallet is created automatically upon user signin. For more information on that, see the link below:

Insert Item

Trinsic supports the ability to insert verifiable credentials into a wallet simply using JSON data.

trinsic wallet insert-item --item <INPUT_JSON_FILE>

When using an SDK to perform this operation, you will need to supply an Insert Item Request object that follows the structure below:

Request to insert a JSON document into a wallet

Field Type Description
item_json string Document to insert; must be stringified JSON
item_type string Item type (ex. "VerifiableCredential")

Then you can supply it to the SDKs:

let insertItemResponse = await walletService.insertItem(
  InsertItemRequest.fromPartial({
    itemJson: issueResponse.signedDocumentJson,
  })
);
var insertItemResponse = await walletService.InsertItemAsync(new() {ItemJson = credentialJson.DocumentJson});
insert_response = await wallet_service.insert_item(
    request=InsertItemRequest(item_json=credential)
)
itemID, err := walletService.InsertItem(context.Background(), &sdk.InsertItemRequest{ItemJson: credential.SignedDocumentJson})
var insertItemResponse = walletService.insertItem(UniversalWalletOuterClass.InsertItemRequest.newBuilder().setItemJson(credential).build()).get();

The output of this method will be a unique itemId that can be used as input where required. The response model looks like this:

Response to InsertItemRequest

Field Type Description
item_id string ID of item inserted into wallet

Search / Query

Querying wallet data in our SDK is enabled through the use of familiar SQL syntax. All data is stored in JSON-LD format, so it can be easily searched. This approach allows us to give developers full control over how data is retrieved. In addition to customizable sorting, paging and filtering, developers have the ability to construct projections, combine result sets, and even run user-defined functions over their queries.

This endpoint will support querying using Verifiable Presentation Request Spec . This feature is still in development.

The default query used in the commands below returns the first 100 items in the wallet result set. The query is SELECT * FROM c OFFSET 0 LIMIT 100.

trinsic wallet search
let items = await walletService.search();
var walletItems = await walletService.SearchAsync(new());
wallet_items = await wallet_service.search()
items, err := walletService.Search(context.Background(), &sdk.SearchRequest{})
var searchResponse = walletService.search(UniversalWalletOuterClass.SearchRequest.getDefaultInstance()).get();  

To pass custom query to the search function, use the query parameter or the available overload.

trinsic wallet search \
    --query "SELECT * FROM c WHERE c.type = 'VerifiableCredential'"
let items2 = await walletService.search(
  SearchRequest.fromPartial({
    query:
      "SELECT c.id, c.type, c.data FROM c WHERE c.type = 'VerifiableCredential'",
  })
);
var walletItems2 = await walletService.SearchAsync(new() {Query = "SELECT c.id, c.type, c.data FROM c WHERE c.type = 'VerifiableCredential'"});
wallet_items2 = await wallet_service.search(
    request=SearchRequest(
        query="SELECT c.id, c.type, c.data FROM c WHERE c.type = 'VerifiableCredential'"
    )
)
items2, err := walletService.Search(context.Background(), &sdk.SearchRequest{Query: "SELECT c.id, c.type, c.data FROM c WHERE c.type = 'VerifiableCredential'"})
var searchResponse2 = walletService.search(UniversalWalletOuterClass.SearchRequest.newBuilder().setQuery("SELECT c.id, c.type, c.data FROM c WHERE c.type = 'VerifiableCredential'").build()).get();

Common SQL Queries

Paging

Paging uses the OFFSET clause that takes in a value indicating how many records should be skipped in the returned query. To specify the size of the result set (page size) use the LIMIT clause.

SELECT * FROM c OFFSET 10 LIMIT 5

Sorting

The optional ORDER BY clause specifies the sorting order for results returned by the query. To control sorting order, specify ASC or DESC at the end; if not specified ascending order is used by default.

SELECT * FROM c ORDER BY c.credential.issued DESC

Filtering

The optional WHERE clause (WHERE <filter_condition>) specifies condition(s) that the source JSON items must satisfy for the query to include them in results. A JSON item must evaluate the specified conditions to true to be considered for the result. The index layer uses the WHERE clause to determine the smallest subset of source items that can be part of the result.

SELECT * FROM c WHERE c.name = 'Trinsic' AND c.dateCreated >= "2020-09-30T23:14:25.7251173Z"

Grouping

The GROUP BY clause divides the query's results according to the values of one or more specified properties. Examples and detailed description on working with grouped results can be found here

Additional Resources

You can read the full documentation on working with SQL queries on the Azure Cosmos DB website .