Search
⌃K

Manage Records

Facilitating general non-secrets storage and management within the wallet
The Wallet SDK provides several APIs to create and manage records that allow for generic non-secrets data storage and management. These records can be used to securely store data related to DIDComm connections, Verifiable Credentials, and much more. Each Record contains a record identifier and record type (which they are uniquely identified by), along with a value (containing the primary data of the record), and a set of tags.
Record values are encrypted by the wallet for security. Tags can be assigned to records such that records can be queried and searched based on their tags.
More information about Records can be found in the Aries Wallet RFC.

Store a Record in a Wallet

The addRecord API can be used to store a record inside a wallet using the AddRecordInput object.
Tags can be assigned to a record to allow for records to be queried and searched according to the tags assigned to them. These tag values can be encrypted for additional security by specifying the 'encrypted' tag type.
The SDK will dispatch the addRecord call on a background thread by default.
Swift
Kotlin
The following code demonstrates adding a "connection" record with an automatically generated recordId into a wallet identified by walletId. It also has a record tag describing the peer's DID.
let client: SudoDIWalletClient = // Instantiated client
let walletId: String = // Wallet identifier of an open wallet
let value: Data = // Record data to store
​
let recordId = UUID().uuidString
​
let tag = RecordTagInput(
tagType: .plaintext,
name: "peerDid",
value: "did:example:thePeersDid"
)
let input = AddRecordInput(
walletId: walletId,
recordType: "connection",
recordId: recordId,
value: value,
tags: [tag]
)
​
do {
let record = try await client.addRecord(input)
} catch {
// Handle error
}
The following code demonstrates adding a "connection" record with an automatically generated recordId into a wallet identified by walletId. It also has a record tag describing the peer's DID.
val client: SudoDIWalletClient = // Instantiated client
val walletId: String = // Wallet identifier of an open wallet
val value: ByteArray = // Record data to store
​
val recordId = UUID.randomUUID().toString()
​
val recordTags = listOf(
RecordTag(RecordTagType.PLAINTEXT, name = "peerDid", value = "did:example:thePeersDid")
)
​
val input = AddRecordInput(
walletId = walletId,
recordType = "connection",
recordId = recordId,
value = value,
tags = recordTags
)
​
launch {
try {
val record: Record = client.addRecord(input)
} catch (e: DIWalletException) {
// Handle/notify user of exception
}
}

Update a Record from a Wallet

A record that has been stored inside a wallet can be updated via the updateRecord API using the UpdateRecordInput object. The input object allows users to change the record value and tags associated with the record.
The SDK will dispatch the updateRecord call on a background thread by default.
Note that when new tags are provided, the current tags are overridden. If null is provided for the new tags input, the record tags will not be updated, likewise for the record value.
Swift
Kotlin
Using the record added in the above section, the following example shows how the record can be updated using the updateRecord API.
let client: SudoDIWalletClient = // Instantiated client
let walletId: String = // Wallet identifier of an open wallet
let recordId: String = // Previously generated record identifier
​
let updatedValue: Data = // New updated value for record
let updatedTag = RecordTagInput(
tagType: .plaintext,
name: "peerEndpoint",
value: "peerEndpoint.example.com"
)
​
let input = UpdateRecordInput(
walletId: walletId,
recordType: "connection",
recordId: recordId,
newValue: updatedValue,
newTags: [updatedTag]
)
​
do {
let updatedRecord = try await client.updateRecord(input)
} catch {
// Handle error
}
Using the record added in the above section, the following example shows how the record can be updated using the updateRecord API.
val client: SudoDIWalletClient = // Instantiated client
val walletId: String = // Wallet identifier of an open wallet
val recordId: String = // Identifier of the existing record
​
val newValue: ByteArray = // New record data to store
​
val newRecordTags = listOf(
RecordTag(RecordTagType.PLAINTEXT, name = "peerEndpoint", value = "peerEndpoint.example.com")
)
​
val input = UpdateRecordInput(
walletId = openWalletId,
recordType = "connection",
recordId = recordId,
newValue = newValue,
newTags = newRecordTags
)
​
launch {
try {
val updatedRecord: Record = client.updateRecord(input)
} catch (e: DIWalletException) {
// Handle/notify user of exception
}
}

Get a Record from a Wallet

A record can be retrieved from an open wallet by calling the getRecord API with the record's ID and type.
The SDK will dispatch the getRecord call on a background thread by default.
Swift
Kotlin
let client: SudoDIWalletClient = // Instantiated client
let walletId: String = // Wallet identifier of an open wallet
let recordId: String = // Existing record identifier
let recordType: String = // Type of record to get
​
do {
let record = try await client.getRecord(fromWallet: walletId, withId: recordId, recordType: recordType)
} catch {
// Handle error
}
val client: SudoDIWalletClient = // Instantiated client
val walletId: String = // Wallet identifier of an open wallet
val recordId: String = // Identifier of the existing record
val recordType: String = // Type of the existing record
​
launch {
try {
val record: Record? = client.getRecord(walletId, recordType, recordId)
} catch (e: DIWalletException) {
// Handle/notify user of exception
}
}

Delete a Record from a Wallet

A record can be deleted from an open wallet via the deleteRecord API provided the wallet identifier, walletId, record identifier, recordId, and type of record, recordType.
The SDK will dispatch the deleteRecord call on a background thread by default.
Swift
Kotlin
let client: SudoDIWalletClient = // Instantiated client
let walletId: String = // Wallet identifier of an open wallet
let recordId: String = // Existing record identifier
let recordType: String = // Type of record to get
​
do {
let record = try await client.deleteRecord(fromWallet: walletId, withId: recordId, recordType: recordType)
} catch {
// Handle error
}
val client: SudoDIWalletClient = // Instantiated client
val walletId: String = // Wallet identifier of an open wallet
val recordId: String = // Identifier of the existing record
val recordType: String = // Type of the existing record
​
launch {
try {
client.deleteRecord(walletId, recordType, recordId)
} catch (e: DIWalletException) {
// Handle/notify user of exception
}
}

Find Records in a Wallet

The findRecords API allows wallets to be searched for records that match a certain record type, recordType. These results can also be filtered according to tags via a variety of tag filters. When no tag filters are provided, all records with the specified record type will be returned.
The tag filters available depend on whether the records have tags that are encrypted or in plaintext. Certain filters such as Equal are available for all tag types, whereas others such as GreaterThan can only be applied to plaintext tags. More information on tag filters is described below.
The SDK will dispatch the findRecords call on a background thread by default.
Swift
Kotlin
The following code demonstrates how to use the findRecords API to find the record created in the Store a Record in a Wallet section.
let client: SudoDIWalletClient = // Instantiated client
let walletId: String = // Wallet identifier of an open wallet
let recordType: String = "connection" // Type of record stored previously
​
let tagFilter = TagFilter.equal(
tagName: "peerDid",
tagEncrypted: false,
value: "did:example:thePeersDid"
)
​
let input = FindRecordsInput(
walletId: walletId,
recordType: recordType,
tagFilter: tagFilter
)
​
do {
let records = try await client.findRecords(input)
} catch {
// Handle error
}
The following code demonstrates how to use the findRecords API to find the record created in the Store a Record in a Wallet section.
val client: SudoDIWalletClient = // Instantiated client
val walletId: String = // Wallet identifier of an open wallet
val recordType: String = "connection" // Type of record stored previously
​
val tagFilter = TagFilter.Equal(
tagName = "peerDid",
tagEncrypted = false,
value = "did:example:thePeersDid"
)
​
val input = FindRecordsInput(
walletId = walletId,
recordType = recordType,
tagFilter = tagFilter
)
​
launch {
try {
val record: List<Record> = client.findRecords(input)
} catch (e: DIWalletException) {
// Handle/notify user of exception
}
}

Tag Filters

Tag Filters allow for records to be queried and searched in various flexible, yet secure, ways. Tag filters provided by the Wallet SDK fall into the following categories:

Absolute Filters

  • Equal - finds records where the tag's value is equal to the provided value.
  • Exists - finds records where the record has the given tag.
Absolute filters can be used on both encrypted and plaintext filters. However, whether they are encrypted or not must be specified in the filter constructor.

Comparative Filters

  • GreaterThan - finds records where the tag's value is greater than the provided value.
  • GreaterThanOrEqual - finds records where the tag's value is greater or equal to the provided value.
  • LessThan - finds records where the tag's value is less than the provided value.
  • LessThanOrEqual - finds records where the tag's value is less or equal to the provided value.
Comparative filters can only be used on plaintext filters due to their nature. All tag values are strings, so comparisons are made alphabetically.

Compound Filters

  • Not(filter: TagFilter) - finds records that do not match the condition of the provided inner filter.
  • And(filters: [Filters]) - finds records that match the conditions of all the provided inner filters.
  • Or(filters: [Filters]) - finds records that match any of the conditions of the provided inner filters.
Compound filters are the building blocks to allow for complex and extremely flexible queries to be made on a set of records. These compound filters are recursively defined such that multiple absolute, comparative, or even more compound filters can be applied together to your queries.

Check if Record Exists

The existence of a record can be checked by using the recordExists API. The SDK will dispatch the recordExists call on a background thread by default.
Swift
Kotlin
let client: SudoDIWalletClient = // Instantiated client
let walletId: String = // Wallet identifier of an open wallet
let recordId: String = // Record identifier to check
let recordType: String = // Type of record
​
do {
let status = try await client.recordExists(fromWallet: walletId, recordType: recordType, recordId: recordId)
} catch {
// Handle error
}
val client: SudoDIWalletClient = // Instantiated client
val walletId: String = // Wallet identifier of an open wallet
val recordId: String = // Record identifier to check
val recordType: String = // Type of record
​
launch {
try {
val status = client.recordExists(walletId, recordType, recordId)
} catch (e: DIWalletException) {
// Handle/notify user of exception
}
}