- Overview
- Setup
- Tutorials
- How Tos
- Reference
- DAR Versions
- API Reference
- Commercials API
- Credential API
- Registry API
- Utility.Registry
- Utility.Registry.V0.Configuration.AppReward
- Utility.Registry.V0.Configuration.Instrument
- Utility.Registry.V0.Holding.Allocation
- Utility.Registry.V0.Holding.Burn
- Utility.Registry.V0.Holding.Lock
- Utility.Registry.V0.Holding.Mint
- Utility.Registry.V0.Holding.Transfer
- Utility.Registry.V0.Holding.Unlock
- Utility.Registry.V0.Rule.Transfer
- Utility.Registry.V0.Types
- Utility.Registry.V0.Util
- Utility.Registry.App
- Utility.Holding
- Utility.Registry
- Settlement Utility API
- Collateral Utility API
- Operator Backend API
Registry Utility - Retrieve Holdings API Example¶
This example shows how to retrieve holdings using the HTTP JSON API.
The example below retrieves all holdings of a user for a specific registrar, instrument, and minimum amount.
Prerequisites¶
A running validator node connected to one of DevNet, TestNet, or MainNet
The Utility DARs installed on your validator node
A valid business user token (
<user-token>) obtained from the IAM of the validator nodeA business user and associated party (
<user-party>) created through the Validator APIThe JSON API endpoint (
<http-json-api>) of the participant nodecurlandjqinstalled on your system
Preparation¶
Add all the required information to the source.sh file:
1#!/usr/bin/env bash
2
3## =================================================================================================
4## Purpose: Configurations for this example, amend variables as needed.
5## Script: source.sh
6## =================================================================================================
7
8# users's details
9USER_TOKEN="eyJhbGciOiJIUzI1NiJ9.eyJzY29wZSI6ImRhbWxfbGVkZ2VyX2FwaSIsImlhdCI6MTc1OTk5MjE0NiwiYXVkIjoiaHR0cHM6Ly91dGlsaXR5LmNhbnRvbi5uZXR3b3JrIiwic3ViIjoiaG9sZGVyIn0.4zuioSDoiysXfNLmobyW0xqXmJEY1tnvX7QOnHv1ASU"
10USER_PARTY_ID="holder::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567"
11
12# filtering criteria
13ADMIN_PARTY_ID="registrar::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567"
14INSTRUMENT_ID="INST"
15MIN_AMOUNT="5.0"
16
17# endpoint for json-api
18HTTP_JSON_API="http://localhost:8001/api/json-api"
19
20# token standard holding interface, may change when new versions of splice exists
21HOLDING_INTERFACE="718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding"
22
23# utility holding template, may change when a new version of the utility exists
24HOLDING_TEMPLATE="dd3a9f2d51cc4c52d9ec2e1d7ff235298dcfb3afd1d50ab44328b1aaa9a18587:Utility.Registry.Holding.V0.Holding:Holding"
The required information is:
Details of |
Description |
|---|---|
User |
JWT, user ID, and party ID of the user |
Registrar |
Party ID of the registrar you want to query holdings for. |
Instrument |
The identifier of the specific instrument you want to query holdings for. |
Minimum amount |
The minimum amount for the holdings you want to query. |
Retrieve Holdings¶
1. Obtain the Ledger End Offset¶
Run the following script to obtain the ledger end offset:
1#!/usr/bin/env bash
2
3# obtain-ledger-offset.sh - Obtains the ledger end offset
4
5DATAFILE="source.sh"
6source "$DATAFILE"
7
8OFFSET=$(curl -s GET \
9 --url "${HTTP_JSON_API}/v2/state/ledger-end" \
10 --header "Accept: application/json" \
11 --header "Authorization: Bearer ${USER_TOKEN}")
12
13echo "$OFFSET" | jq
14
15OUTPUTFILE="response-obtain-ledger-offset.json"
16echo "$OFFSET" > "$OUTPUTFILE"
The result is the ledger end offset at this moment, stored in response-obtain-ledger-offset.json. For example:
1{
2 "offset": 4308
3}
2. Retrieve Utility Holdings¶
Run the following script to retrieve the Utility Holdings of the user, filtered by the specified instrument ID and minimum amount:
1#!/usr/bin/env bash
2
3## =================================================================================================
4## Purpose: Retrieves holdings of the user for a specific instrument and minimum amount
5## Authorized by: User
6## Script: retrieve-utility-holdings.sh
7## =================================================================================================
8
9DATAFILE="source.sh"
10source "$DATAFILE"
11
12# Get offset from previous step
13if [[ -f "response-obtain-ledger-offset.json" ]]; then
14 JSONCONTENT=$(cat "response-obtain-ledger-offset.json")
15 OFFSET=$(echo "$JSONCONTENT" | jq -r ".offset")
16else
17 echo "Error: response-obtain-ledger-offset.json not found"
18 exit 1
19fi
20
21RESULT=$(curl -s \
22 --url "${HTTP_JSON_API}/v2/state/active-contracts" \
23 --header "Authorization: Bearer ${USER_TOKEN}" \
24 --header "Content-Type: application/json" \
25 --request POST \
26 --data @- <<EOF
27{
28 "verbose": false,
29 "activeAtOffset": "${OFFSET}",
30 "filter": {
31 "filtersByParty": {
32 "${USER_PARTY_ID}": {
33 "cumulative": [{
34 "identifierFilter": {
35 "TemplateFilter": {
36 "value": {
37 "templateId": "${HOLDING_TEMPLATE}",
38 "includeCreatedEventBlob": false
39 }
40 }
41 }
42 }]
43 }
44 }
45 }
46}
47EOF
48)
49
50# Filter holdings for a specific holder, instrument ID, admin, and minimum amount
51FILTERED=$(echo "$RESULT" | jq \
52 --arg USER_PARTY_ID "$USER_PARTY_ID" \
53 --arg INSTRUMENT_ID "$INSTRUMENT_ID" \
54 --arg ADMIN_PARTY_ID "$ADMIN_PARTY_ID" \
55 --arg MIN_AMOUNT "$MIN_AMOUNT" \
56 '[
57 .[]
58 | .contractEntry.JsActiveContract.createdEvent.createArgument
59 | select(
60 .registrar == $ADMIN_PARTY_ID and
61 .owner == $USER_PARTY_ID and
62 .instrument.id == $INSTRUMENT_ID and
63 .instrument.source == $ADMIN_PARTY_ID and
64 (.amount | tonumber) >= ($MIN_AMOUNT | tonumber)
65 )
66 ]'
67)
68
69echo "--- All utility holdings of ${USER_PARTY_ID} with amount>=${MIN_AMOUNT} as of offset ${OFFSET} ---"
70echo "$FILTERED" | jq
71
72OUTPUTFILE="response-retrieve-utility-holdings.json"
73echo "$FILTERED" > "$OUTPUTFILE"
The result is the Holding Cids, stored in response-retrieve-utility-holdings.json. For example:
1[
2 {
3 "operator": "operator::1220b39df5ed0e3c584cd97e86e779def933d545bf9a4fab3c0fd3e4ad3f7a36b8fe",
4 "provider": "provider::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567",
5 "registrar": "registrar::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567",
6 "owner": "holder::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567",
7 "instrument": {
8 "source": "registrar::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567",
9 "id": "INST",
10 "scheme": "RegistrarInternalScheme"
11 },
12 "label": "",
13 "amount": "10.0000000000"
14 }
15]
3. Retrieve Canton Network Token Standard Holdings¶
Run the following script to retrieve the Canton Network Token Standard Holdings of the user, filtered by the specified instrument ID and minimum amount:
1#!/usr/bin/env bash
2
3## =================================================================================================
4## Purpose: Retrieves holdings of the user for a specific instrument and minimum amount
5## Authorized by: User
6## Script: retrieve-holdings.sh
7## =================================================================================================
8
9DATAFILE="source.sh"
10source "$DATAFILE"
11
12# Get offset from previous step
13if [[ -f "response-obtain-ledger-offset.json" ]]; then
14 JSONCONTENT=$(cat "response-obtain-ledger-offset.json")
15 OFFSET=$(echo "$JSONCONTENT" | jq -r ".offset")
16else
17 echo "Error: response-obtain-ledger-offset.json not found"
18 exit 1
19fi
20
21RESULT=$(curl -s \
22 --url "${HTTP_JSON_API}/v2/state/active-contracts" \
23 --header "Authorization: Bearer ${USER_TOKEN}" \
24 --header "Content-Type: application/json" \
25 --request POST \
26 --data @- <<EOF
27{
28 "verbose": false,
29 "activeAtOffset": "${OFFSET}",
30 "filter": {
31 "filtersByParty": {
32 "${USER_PARTY_ID}": {
33 "cumulative": [{
34 "identifierFilter": {
35 "InterfaceFilter": {
36 "value": {
37 "interfaceId":"$HOLDING_INTERFACE",
38 "includeInterfaceView": true,
39 "includeCreatedEventBlob": false
40 }
41 }
42 }
43 }]
44 }
45 }
46 }
47}
48EOF
49)
50
51# Filter holdings for a specific holder, instrument ID, admin, and minimum amount
52FILTERED=$(echo "$RESULT" | jq \
53 --arg USER_PARTY_ID "$USER_PARTY_ID" \
54 --arg INSTRUMENT_ID "$INSTRUMENT_ID" \
55 --arg ADMIN_PARTY_ID "$ADMIN_PARTY_ID" \
56 --arg MIN_AMOUNT "$MIN_AMOUNT" \
57 '[
58 .[]
59 | .contractEntry.JsActiveContract.createdEvent.interfaceViews[]
60 | select(
61 .viewValue.owner == $USER_PARTY_ID and
62 .viewValue.instrumentId.id == $INSTRUMENT_ID and
63 .viewValue.instrumentId.admin == $ADMIN_PARTY_ID and
64 (.viewValue.amount | tonumber) > ($MIN_AMOUNT | tonumber)
65 )
66 ]'
67)
68
69echo "--- All interface holdings of ${USER_PARTY_ID} with amount>=${MIN_AMOUNT} as of offset ${OFFSET} ---"
70echo "$FILTERED" | jq
71
72OUTPUTFILE="response-retrieve-holdings.json"
73echo "$FILTERED" > "$OUTPUTFILE"
The result is the Holding Cids, stored in response-retrieve-holdings.json. For example:
1[
2 {
3 "interfaceId": "718a0f77e505a8de22f188bd4c87fe74101274e9d4cb1bfac7d09aec7158d35b:Splice.Api.Token.HoldingV1:Holding",
4 "viewStatus": {
5 "code": 0,
6 "message": "",
7 "details": []
8 },
9 "viewValue": {
10 "owner": "holder::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567",
11 "instrumentId": {
12 "admin": "registrar::1220d301ababbed7bc8d6f6a80ce16f33933a7274a3013241b7fb373ca7e4f0d6567",
13 "id": "INST"
14 },
15 "amount": "10.0000000000",
16 "lock": null,
17 "meta": {
18 "values": {
19 "utility.digitalasset.com/holding-label": ""
20 }
21 }
22 }
23 }
24]
Note
In Canton 3, the JSON API no longer supports direct querying as in Canton 2. As a result, any filtering of holdings must be performed client-side after retrieving the data. For advanced querying and filtering, it is recommended to use the PQS.