Skip to content

Wallet API

The Wallet API is the main interface for interacting with a cloud wallet. It is primarly used when you're providing custom wallet experience and building your own digital wallet integration. If you'd like to use Trinsic's integrated cloud wallet app, you likely won't need to use this API.

Migrating from Account API?

Check out our migration guide on how to migrate your code that uses the deprecated Account API.


Create Wallet

Create a new wallet and return the authentication token and wallet information about the newly created wallet.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using FluentAssertions;
using Grpc.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Trinsic;
using Trinsic.Sdk.Options.V1;
using Trinsic.Services.Common.V1;
using Trinsic.Services.Connect.V1;
using Trinsic.Services.Provider.V1;
using Trinsic.Services.TrustRegistry.V1;
using Trinsic.Services.UniversalWallet.V1;
using Trinsic.Services.VerifiableCredentials.Templates.V1;
using Xunit;
using Xunit.Abstractions;
using JsonSerializer = System.Text.Json.JsonSerializer;

#pragma warning disable CS0618

namespace Tests;

[SuppressMessage("ReSharper", "MethodHasAsyncOverload")]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public class Tests
{
    // This breaks the CI pipeline, removing DEBUG option.
    // #if DEBUG
    // private const string DefaultEndpoint = "localhost";
    // private const int DefaultPort = 5000;
    // private const bool DefaultUseTls = false;
    // #else
    public const string DefaultEndpoint = "staging-internal.trinsic.cloud";
    public const int DefaultPort = 443;

    // #endif

    private readonly ITestOutputHelper _testOutputHelper;
    private readonly TrinsicOptions _options;

    public Tests(ITestOutputHelper testOutputHelper) {
        _testOutputHelper = testOutputHelper;
        _options = GetTestServiceOptions();

        _testOutputHelper.WriteLine($"Testing endpoint: {_options.FormatUrl()}");
    }

    public static TrinsicOptions GetTestServiceOptions() {
        return new() {
            ServerEndpoint = Environment.GetEnvironmentVariable("TEST_SERVER_ENDPOINT") ?? DefaultEndpoint,
            ServerPort = int.TryParse(Environment.GetEnvironmentVariable("TEST_SERVER_PORT"), out var port)
                ? port
                : DefaultPort,
            ServerUseTls = !bool.TryParse(Environment.GetEnvironmentVariable("TEST_SERVER_USE_TLS"), out var tls) || tls
        };
    }

    [Fact(DisplayName = "SDK Version has 3 decimal places")]
    public void TestGetVersion() {
        Assert.Equal("1.0.0", TrinsicService.GetSdkVersion());
    }

    [Fact(DisplayName = "Demo: wallet and credential sample")]
    public async Task TestWalletService() {
        var trinsic = new TrinsicService(_options.Clone());
        var (ecosystem, _) = trinsic.Provider.CreateEcosystem(new());
        var ecosystemId = ecosystem.Id;

        // SETUP ACTORS
        // Create 3 different profiles for each participant in the scenario
        var allison = await trinsic.Wallet.CreateWalletAsync(new() { EcosystemId = ecosystemId });
        var clinic = await trinsic.Wallet.CreateWalletAsync(new() { EcosystemId = ecosystemId });
        var airline = await trinsic.Wallet.CreateWalletAsync(new() { EcosystemId = ecosystemId });

        allison.AuthToken.Should().NotBeNullOrWhiteSpace();
        clinic.AuthToken.Should().NotBeNullOrWhiteSpace();
        airline.AuthToken.Should().NotBeNullOrWhiteSpace();

        trinsic = new TrinsicService(_options.CloneWithAuthToken(clinic.AuthToken));

        var info = await trinsic.Wallet.GetMyInfoAsync();
        info.Should().NotBeNull();
        info.Wallet.Should().NotBeNull();

        var template = await trinsic.Template.CreateAsync(new() {
            Name = $"dotnet-tests-{Guid.NewGuid()}",
            Fields =
            {
                {
                    "field", new() { Type = FieldType.Number }
                }
            }
        });

        // ISSUE CREDENTIAL
        // Sign a credential as the clinic and send it to Allison
        // Read the JSON credential data

        // issueCredentialSample() {
        var issueResponse = await trinsic.Credential.IssueFromTemplateAsync(new() {
            TemplateId = template.Data.Id,
            ValuesJson = JsonConvert.SerializeObject(new {
                field = 123
            })
        });
        // }

        _testOutputHelper.WriteLine($"Credential:\n{issueResponse.DocumentJson}");

        try
        {
            // sendCredential() {
            var sendResponse = await trinsic.Credential.SendAsync(new() {
                Email = "<EMAIL>",
                DocumentJson = issueResponse.DocumentJson,
                SendNotification = true,
                });
            // }
        } catch
        {
        } // We expect this to fail

        // STORE CREDENTIAL
        trinsic = new TrinsicService(_options.CloneWithAuthToken(allison.AuthToken));

        var insertItemResponse = await trinsic.Wallet.InsertItemAsync(new() {
            ItemJson = issueResponse.DocumentJson
        });
        var itemId = insertItemResponse.ItemId;

        // getItem() {
        var getItemResponse = await trinsic.Wallet.GetItemAsync(new GetItemRequest {
            ItemId = itemId
        });
        //}

        getItemResponse.ItemJson.Should().NotBeEmpty();

        // searchWalletBasic() {
        var walletItems = await trinsic.Wallet.SearchWalletAsync(new());
        // }

        _testOutputHelper.WriteLine($"Last wallet item:\n{walletItems.Items.Last()}");

        // searchWalletSQL() { 
        _ = await trinsic.Wallet.SearchWalletAsync(new() { Query = "SELECT c.id, c.type, c.data FROM c WHERE c.type = 'VerifiableCredential'" });
        // }

        // SHARE CREDENTIAL
        var credentialProof = await trinsic.Credential.CreateProofAsync(new() {
            ItemId = itemId
        });

        _testOutputHelper.WriteLine("Proof:");
        _testOutputHelper.WriteLine(credentialProof.ProofDocumentJson);

        // VERIFY CREDENTIAL
        trinsic = new TrinsicService(_options.CloneWithAuthToken(airline.AuthToken));

        var valid = await trinsic.Credential.VerifyProofAsync(new() {
            ProofDocumentJson = credentialProof.ProofDocumentJson
        });

        _testOutputHelper.WriteLine($"Verification result: {valid.ValidationResults}");
        Assert.True(valid.ValidationResults["SignatureVerification"].IsValid);

        // DELETE CREDENTIAL
        trinsic = new TrinsicService(_options.CloneWithAuthToken(allison.AuthToken));
        // deleteItem() {
        await trinsic.Wallet.DeleteItemAsync(new DeleteItemRequest {
            ItemId = itemId
        });
        //}
    }

    [Fact(DisplayName = "Demo: Wallet deletion")]
    public async Task TestWalletDeletion() {
        var trinsic = new TrinsicService(_options.Clone());
        var (ecosystem, _) = await trinsic.Provider.CreateEcosystemAsync(new());
        var createWalletResponse = await trinsic.Wallet.CreateWalletAsync(new() { EcosystemId = ecosystem.Id });

        // set the auth token to the newly created wallet
        trinsic = new TrinsicService(_options.CloneWithAuthToken(createWalletResponse.AuthToken));

        var newWalletInfo = await trinsic.Wallet.GetMyInfoAsync();
        var walletId = newWalletInfo.Wallet.WalletId;

        // deleteWallet() {
        await trinsic.Wallet.DeleteWalletAsync(new DeleteWalletRequest {
            WalletId = walletId
        });
        //}
    }

    [Fact(DisplayName = "Demo: trust registries")]
    public async Task TestTrustRegistry() {
        _ = $"https://example.com/{Guid.NewGuid():N}";

        // setup
        var trinsic = new TrinsicService(_options.Clone());
        var (_, authToken) = await trinsic.Provider.CreateEcosystemAsync(new());

        // setAuthTokenSample() {
        trinsic = new TrinsicService(_options.CloneWithAuthToken(authToken));
        // }

        var schemaUri = "https://schema.org/Card";

        // registerIssuerSample() {
        var didUri = "did:example:test";
        _ = await trinsic.TrustRegistry.RegisterMemberAsync(new() {
            DidUri = didUri,
            SchemaUri = schemaUri
        });
        // }

        // checkIssuerStatus() {
        var issuerStatus = await trinsic.TrustRegistry.GetMemberAuthorizationStatusAsync(new() {
            DidUri = didUri,
            SchemaUri = schemaUri
        });
        // }

        issuerStatus.Should().NotBeNull();
        issuerStatus.Status.Should().Be(RegistrationStatus.Current);

        // getMember() {
        var member = await trinsic.TrustRegistry.GetMemberAsync(new() {
            DidUri = didUri
        });
        // }

        member.Should().NotBeNull();
        member.AuthorizedMember.Did.Should().Be(didUri);

        // listMembers() {
        var members = await trinsic.TrustRegistry.ListAuthorizedMembersAsync(new() {
            SchemaUri = schemaUri
        });
        // }

        members.AuthorizedMembers[0].Should().Be(member.AuthorizedMember);

        // unregisterIssuer() {
        _ = await trinsic.TrustRegistry.UnregisterMemberAsync(new() {
            DidUri = didUri,
            SchemaUri = schemaUri
        });
        // }
    }

    [Fact(DisplayName = "Demo: ecosystem creation and listing")]
    public async Task EcosystemTests() {
        // setup
        var trinsic = new TrinsicService(_options.Clone());

        // test create ecosystem
        // createEcosystem() {
        var (ecosystem, authToken) = await trinsic.Provider.CreateEcosystemAsync(new() {
            Description = "My ecosystem",
        });
        // }

        ecosystem.Should().NotBeNull();
        ecosystem.Id.Should().NotBeNull();
        ecosystem.Id.Should().StartWith("urn:trinsic:ecosystems:");

        trinsic = new TrinsicService(_options.CloneWithAuthToken(authToken));

        // test get ecosystem info
        // ecosystemInfo() {
        // }

        // inviteParticipant() {
        // }

        // invitationStatus() {
        // }

        // Test upgrading account DID
        var accountInfo = await trinsic.Wallet.GetMyInfoAsync();
        var walletId = accountInfo.Wallet.WalletId;

        // Wrap in try-catch as this ecosystem will not presently have DID upgrade permissions
        try
        {
            // upgradeDid() {
            var upgradeResponse = await trinsic.Provider.UpgradeDIDAsync(new() {
                WalletId = walletId,
                Method = SupportedDidMethod.Ion,
                IonOptions = new() {
                    Network = IonOptions.Types.IonNetwork.TestNet
                }
            });
            // }
        } catch (RpcException e)
        {
            e.StatusCode.Should().Be(StatusCode.PermissionDenied);
        }
    }

    [Fact]
    public async Task ConnectDemo() {
        var trinsic = new TrinsicService(_options.Clone());
        var (ecosystem, authToken) = await trinsic.Provider.CreateEcosystemAsync(new());

        trinsic = new TrinsicService(_options.CloneWithAuthToken(authToken));

        try {
            // createSession() {
            var createResponse = await trinsic.Connect.CreateSessionAsync(new() {
                Verifications = {
                    new RequestedVerification() {
                        Type = VerificationType.GovernmentId
                    }
                }
            });

            var session = createResponse.Session;
            var sessionId = session.Id; // Save this in your database
            var clientToken = session.ClientToken; // Send this to your user's device
            // }


            // getSession() {
            var getResponse = await trinsic.Connect.GetSessionAsync(new() {
                IdvSessionId = sessionId
            });
            // }

            // cancelSession() {
            await trinsic.Connect.CancelSessionAsync(new() {
                IdvSessionId = sessionId
            });
            // }

        } catch {
            // We expect the above calls to fail due to lack of privileges
        }
    }

    [Fact(DisplayName = "Demo: template management and credential issuance from template")]
    public async Task DemoTemplatesWithIssuance() {
        var trinsic = new TrinsicService(_options.Clone());
        var (ecosystem, authToken) = await trinsic.Provider.CreateEcosystemAsync(new());

        trinsic = new TrinsicService(_options.CloneWithAuthToken(authToken));

        // create example template
        // createTemplate() {
        CreateCredentialTemplateRequest createRequest = new() {
            Name = "An Example Credential",
            Title = "Example Credential",
            Description = "A credential for Trinsic's SDK samples",
            AllowAdditionalFields = false,
            Fields =
            {
                { "firstName", new() { Title = "First Name", Description = "Given name of holder" } },
                { "lastName", new() { Title = "Last Name", Description = "Surname of holder", Optional = true } },
                { "age", new() { Title = "Age", Description = "Age in years of holder", Type = FieldType.Number } }
            },
            FieldOrdering =
            {
                { "firstName", new() { Order = 0, Section = "Name" } },
                { "lastName", new() { Order = 1, Section = "Name" } },
                { "age", new() { Order = 2, Section = "Miscellanous" } }
            },
            AppleWalletOptions = new() {
                PrimaryField = "firstName",
                SecondaryFields = { "lastName" },
                AuxiliaryFields = { "age" }
            }
        };

        var template = await trinsic.Template.CreateAsync(createRequest);
        // }

        template.Should().NotBeNull();
        template.Data.Should().NotBeNull();
        template.Data.Id.Should().NotBeNull();
        template.Data.SchemaUri.Should().NotBeNull();

        var templateId = template.Data.Id;

        // update template
        // updateTemplate() {
        UpdateCredentialTemplateRequest updateRequest = new() {
            Id = templateId,
            Title = "New Title",
            Description = "New Description",
            Fields =
            {
                { "firstName", new() { Title = "New title for firstName" } },
                { "lastName", new() { Description = "New description for lastName" } }
            },
            FieldOrdering =
            {
                { "age", new() { Order = 0, Section = "Misc" } },
                { "firstName", new() { Order = 1, Section = "Full Name" } },
                { "lastName", new() { Order = 2, Section = "Full Name" } },
            },
            AppleWalletOptions = new() {
                PrimaryField = "age",
                SecondaryFields = { "firstName", "lastName" }
            }
        };

        var updatedTemplate = await trinsic.Template.UpdateAsync(updateRequest);
        // }

        updatedTemplate.UpdatedTemplate.Title.Should().Be(updateRequest.Title);

        // issue credential from this template
        var values = JsonSerializer.Serialize(new {
            firstName = "Jane",
            lastName = "Doe",
            age = 42
        });

        // issueFromTemplate() {
        var credentialJson = await trinsic.Credential.IssueFromTemplateAsync(new() {
            TemplateId = templateId,
            ValuesJson = values
        });
        // }

        credentialJson.Should().NotBeNull();

        var jsonDocument = JsonDocument.Parse(credentialJson.DocumentJson).RootElement.EnumerateObject();

        jsonDocument.Should().Contain(x => x.Name == "id");
        jsonDocument.Should().Contain(x => x.Name == "credentialSubject");

        // insertItemWallet() {
        var insertItemResponse =
            await trinsic.Wallet.InsertItemAsync(new() { ItemJson = credentialJson.DocumentJson });
        // }

        var itemId = insertItemResponse.ItemId;

        var frame = new JObject
        {
            { "@context", "https://www.w3.org/2018/credentials/v1" },
            { "type", new JArray("VerifiableCredential") }
        };

        // Create proof from input document
        // createProof() {
        var proof = await trinsic.Credential.CreateProofAsync(new() {
            DocumentJson = credentialJson.DocumentJson,
            RevealDocumentJson = frame.ToString(Formatting.None)
        });
        var selectiveProof = await trinsic.Credential.CreateProofAsync(new() {
            DocumentJson = credentialJson.DocumentJson,
            RevealTemplate = new() {
                // The other field, not disclosed, is "age"
                TemplateAttributes = { "firstName", "lastName" }
            }
        });
        // }
        // verifyProof() {
        var valid = await trinsic.Credential.VerifyProofAsync(new() { ProofDocumentJson = proof.ProofDocumentJson });
        // }
        valid.IsValid.Should().BeTrue();

        var selectiveValid =
            await trinsic.Credential.VerifyProofAsync(
                new() { ProofDocumentJson = selectiveProof.ProofDocumentJson });
        selectiveValid.IsValid.Should().BeTrue();

        // Create proof from item id
        var proof2 = await trinsic.Credential.CreateProofAsync(new() {
            ItemId = itemId,
            RevealDocumentJson = frame.ToString(Formatting.None)
        });

        var valid2 =
            await trinsic.Credential.VerifyProofAsync(new() { ProofDocumentJson = proof2.ProofDocumentJson });

        valid2.IsValid.Should().BeTrue();

        try
        {
            // checkCredentialStatus() {
            var checkResponse = await trinsic.Credential.CheckStatusAsync(new() { CredentialStatusId = "" });
            // }
        } catch
        {
        } // We expect this to fail

        try
        {
            // updateCredentialStatus() {
            await trinsic.Credential.UpdateStatusAsync(new() { CredentialStatusId = "", Revoked = true });
            // }
        } catch
        {
        } // We expect this to fail

        // getCredentialTemplate() {
        var getTemplateResponse = await trinsic.Template.GetAsync(new() { Id = template.Data.Id });
        // }
        // searchCredentialTemplate() {
        var searchTemplateResponse = await trinsic.Template.SearchAsync(new() { Query = "SELECT * FROM c" });
        // }
        // deleteCredentialTemplate() {
        var deleteTemplateResponse = await trinsic.Template.DeleteAsync(new() { Id = template.Data.Id });
        // }
    }

    [Fact(DisplayName = "Decode base64 url encoded string")]
    public void DecodeBase64UrlString() {
        const string encoded =
            "CiVodHRwczovL3RyaW5zaWMuaWQvc2VjdXJpdHkvdjEvb2Jlcm9uEnIKKnVybjp0cmluc2ljOndhbGxldHM6Vzl1dG9pVmhDZHp2RXJZRGVyOGlrRxIkODBkMTVlYTYtMTIxOS00MGZmLWE4NTQtZGI1NmZhOTlmNjMwIh51cm46dHJpbnNpYzplY29zeXN0ZW1zOmRlZmF1bHQaMJRXhevRbornRpA-HJ86WaTLGmQlOuoXSnDT_W2O3u3bV5rS5nKpgrfGKFEbRtIgjyIA";

        var actual = Base64Url.Decode(encoded);

        actual.Should().NotBeEmpty();
    }

    [Fact(DisplayName = "Demo: Wallet Service samples")]
    public async Task DemoWalletServiceMethods() {
        // Most part of this service's samples are directly in the wallet-service.md file because it complains on creating/removing duplicate identities/wallets 
        var trinsic = new TrinsicService(_options.Clone());
        var (ecosystem, authToken) = await trinsic.Provider.CreateEcosystemAsync(new());
        var createWalletResponse = await trinsic.Wallet.CreateWalletAsync(new() { EcosystemId = ecosystem.Id });
        trinsic = new TrinsicService(_options.CloneWithAuthToken(authToken));

        // getWalletInfo() {
        var getWalletInfoResponse = await trinsic.Wallet.GetWalletInfoAsync(
            new GetWalletInfoRequest {
                WalletId = createWalletResponse.Wallet.WalletId
            }
        );
        // }
}

ecosystem_id
string
Ecosystem ID of the wallet to create
description
optional string
Wallet name or description. Use this field to add vendor specific information about this wallet, such as email, phone, internal ID, or anything you'd like to associate with this wallet. This field is searchable.
identity
Optional identity to add to the wallet (email or sms). Use this field when inviting participants into an ecosystem. If this field is set, an auth token will not be sent in the response.
Show child attributes

auth_token
string
Auth token for the newly created wallet
token_id
string
Token ID of the newly generated token
wallet
Wallet configuration
Show child attributes


Authenticate

Authenticate and return an auth token for an existing wallet using one of the associated external identities. This endpoint requires that the wallet user has previously added at least one external identity using the above endpoints.

Once a token is obtained, it can be reused for future sessions -- users don't need to authenticate if they already have a valid token. You can store the auth token in secure enclaves on the users device, browser, etc.

When should users authenticate?

  • If your integration solution doesn't manage the wallet tokens, users may need to re-authenticate on their device to get a new auth token
  • Users want to log in to a different device using their email or phone number
  • Returning users that have lost their previous session and require new auth token

AuthenticateInit

identity
string
Identity to add to the wallet
provider
Identity provider
Show enum values
ecosystem_id
string
Ecosystem ID to which the wallet belongs

challenge
string
The challenge received from the AcquireAuthTokenInit endpoint Pass this challenge back to the AcquireAuthTokenConfirm endpoint

AuthenticateConfirm

challenge
string
The challenge received from the AcquireAuthTokenInit endpoint
response
string
The response to the challenge. If using Email or Phone, this is the OTP code sent to the user's email or phone

auth_token
string
Auth token for the wallet


Add External Identity

This service is used to attach external identity, such as email or phone number, to a wallet. The purpose of this process is to allow the user to authenticate to their existing wallet (using the Authenticate endpoint) to get an auth token. This may be needed if the user is logging in on a different device, have lost access to the initial auth token, etc.

The process for adding external identity is based on confirming an OTP code that will be sent to the user's email address or phone number. To do this, you should call the services AddExternalIdentityInit and AddExternalIdentityConfirm.

AddExternalIdentityInit

identity
string
The user identity to add to the wallet This can be an email address or phone number (formatted as +[country code][phone number])
provider
The type of identity provider, like EMAIL or PHONE
Show enum values

challenge
string
Challenge or reference to the challenge to be used in the AddExternalIdentityConfirm endpoint

AddExternalIdentityConfirm

challenge
string
The challenge received from the AddExternalIdentityInit endpoint
response
string
The response to the challenge. If using Email or Phone, this is the OTP code sent to the user's email or phone

This message has no fields


Remove External Identity

Removes an external identity from the associated identities of the authenticated wallet.

identity
string
The user identity to remove from the wallet This can be an email address or phone number (formatted as +[country code][phone number])

This message has no fields


Insert Item

Stores a credential (or any other JSON object) in a wallet.

let insertItemResponse = await trinsic.wallet().insertItem(
    InsertItemRequest.fromPartial({
        itemJson: issueResponse.documentJson,
    }),
);
var insertItemResponse =
    await trinsic.Wallet.InsertItemAsync(new() { ItemJson = credentialJson.DocumentJson });
insert_response = await trinsic.wallet.insert_item(
    request=InsertItemRequest(
        item_json=credential, item_type="VerifiableCredential"
    )
)
insertResponse, err := trinsic.Wallet().InsertItem(context.Background(), &wallet.InsertItemRequest{
    ItemJson: credentialJson,
    ItemType: "VerifiableCredential",
})
var insertResponse =
    trinsic
        .wallet()
        .insertItem(
            InsertItemRequest.newBuilder()
                .setItemJson(credentialJson)
                .setItemType("VerifiableCredential")
                .build())
        .get();

Request to insert a JSON document into a wallet
item_json
string
Document to insert; must be stringified JSON
item_type
optional string
Item type (ex. "VerifiableCredential")

Response to InsertItemRequest
item_id
string
ID of item inserted into wallet

What can be stored in a wallet?

Wallets are mainly intended to hold Verifiable Credentials, but can technically store any JSON blob.

If you store a Verifiable Credential in a Wallet, ensure that its item_type is VerifiableCredential.

Otherwise, ensure its item_type is not VerifiableCredential.


Get Item

Retrieves an item of the wallet by its ID.

let getItemResponse = await trinsic.wallet().getItem({
    itemId: itemId,
});
var getItemResponse = await trinsic.Wallet.GetItemAsync(new GetItemRequest {
    ItemId = itemId
});
item = await trinsic.wallet.get_item(request=GetItemRequest(item_id))
getResponse, err := trinsic.Wallet().GetItem(context.Background(), &wallet.GetItemRequest{
    ItemId: itemId,
})
var getResponse =
    trinsic.wallet().getItem(GetItemRequest.newBuilder().setItemId(itemId).build()).get();

Request to fetch an item from wallet
item_id
string
ID of item in wallet

Response to GetItemRequest
item_json
string
Item data as a JSON string
item_type
string
Type of item specified when item was inserted into wallet


Get Wallet

Retrieves information about wallets in the ecosystem. These endpoints can only be called by a Provider, so make sure you authenticate as it before calling them.

GetWalletInfo

Retrieves information about a wallet by its ID.

//trinsic.options.authToken = trinsic.provider().options.authToken;

let getWalletInfoResponse = await trinsic.wallet().getWalletInfo(
    GetWalletInfoRequest.fromPartial({
        walletId: createWalletResponse.wallet?.walletId,
    }),
);
get_wallet_info_response = await trinsic.wallet.get_wallet_info(
    request=GetWalletInfoRequest(
        wallet_id=create_wallet_response.wallet.wallet_id
    )
)
getWalletInfoResponse, err := trinsic.Wallet().GetWalletInfo(context.Background(),
    &wallet.GetWalletInfoRequest{
        WalletId: createWalletResponse.Wallet.WalletId,
    },
)
    var getWalletInfoResponse = trinsic.wallet().getWalletInfo(
        GetWalletInfoRequest.newBuilder().setWalletId(walletId).build()
    ).get();

Request to retrieve wallet information about a given wallet identified by its wallet ID
wallet_id
string
Wallet ID of the wallet to retrieve

Response to GetWalletInfoRequest
wallet
Wallet configuration
Show child attributes

GetWalletFromExternalIdentity

Retrieves information about a wallet by its External Identity (email or phone number).

//trinsic.options.authToken = trinsic.provider().options.authToken;

let getWalletFromExternalIdentityResponse = await trinsic.wallet().getWalletFromExternalIdentity(
    GetWalletFromExternalIdentityRequest.fromPartial({
        identity: {
            id: "test@trinsic.id",
            provider: IdentityProvider.Email,
        }
    }),
);
get_wallet_from_external_identity_response = await trinsic.wallet.get_wallet_from_external_identity(
    request=GetWalletFromExternalIdentityRequest(
        identity={
            "id": "test@trinsic.id",
            "provider": IdentityProvider.Email
        }
    )
)
getWalletFromExternalIdentityResponse, err := trinsic.Wallet().GetWalletFromExternalIdentity(context.Background(),
    &wallet.GetWalletFromExternalIdentityRequest{
        Identity: &provider.WalletExternalIdentity{
            Id:       "test@trinsic.id",
            Provider: &provider.IdentityProvider.Email,
        },
    },
)
var getWalletFromExternalIdentityResponse = trinsic.wallet().getWalletFromExternalIdentity(
    GetWalletFromExternalIdentityRequest.newBuilder().setIdentity(
        WalletExternalIdentity.newBuilder()
            .setId("test@trinsic.id")
            .setProvider(IdentityProvider.Email)
            .build()).build()
).get();

identity
Show child attributes

Response to GetWalletFromExternalIdentityRequest
wallet
Wallet configuration
Show child attributes


Delete Item

Deletes an item of the wallet by its ID.

await trinsic.wallet().deleteItem({
    itemId: itemId,
});
await trinsic.Wallet.DeleteItemAsync(new DeleteItemRequest {
    ItemId = itemId
});
await trinsic.wallet.delete_item(request=DeleteItemRequest(item_id=item_id))
deleteResponse, err := trinsic.Wallet().DeleteItem(context.Background(),
    &wallet.DeleteItemRequest{
        ItemId: itemId,
    })
trinsic.wallet().deleteItem(DeleteItemRequest.newBuilder().setItemId(itemId).build()).get();

Request to delete an item in a wallet
item_id
string
ID of item to delete

Response to DeleteItemRequest
This message has no fields


Delete Wallet

Deletes a wallet, and all its credentials, permanently.

Any wallet may delete itself by passing its own ID to this call. Only Provider wallets may delete wallets other than themselves.

Wallet deletion is permanent and cannot be undone.

await trinsic.wallet().deleteWallet({
    walletId: walletId,
});
await trinsic.Wallet.DeleteWalletAsync(new DeleteWalletRequest {
    WalletId = walletId
});
await trinsic.wallet.delete_wallet(request=DeleteWalletRequest(wallet_id=wallet_id))
deleteWalletResponse, err := trinsic.Wallet().DeleteWallet(context.Background(),
    &wallet.DeleteWalletRequest{
        Account: &wallet.DeleteWalletRequest_WalletId{
            WalletId: walletId,
        },
    })
trinsic
    .wallet()
    .deleteWallet(DeleteWalletRequest.newBuilder().setWalletId(walletId).build())
    .get();

Request to delete a wallet
email
string
Email address of account to delete. Mutually exclusive with walletId and didUri.
wallet_id
string
Wallet ID of account to delete. Mutually exclusive with email and didUri.
did_uri
string
DID URI of the account to delete. Mutually exclusive with email and walletId.

Response to DeleteWalletRequest. Empty payload.
This message has no fields


Search Wallet

Searches a wallet, returning all matching items, and a continuation_token to paginate large result sets.

If no query is specified, this call by default returns the first 100 items in the wallet.

let items = await trinsic.wallet().searchWallet();
var walletItems = await trinsic.Wallet.SearchWalletAsync(new());
wallet_items = await trinsic.wallet.search_wallet()
searchResponse, err := trinsic.Wallet().SearchWallet(context.Background(), &wallet.SearchRequest{})
var walletItems = trinsic.wallet().searchWallet().get();

Request to search items in wallet
query
string
SQL Query to execute against items in wallet
continuation_token
optional string
Token provided by previous SearchResponse if more data is available for query

Response to SearchRequest
items
string[]
Array of query results, as JSON strings
has_more_results
bool
Whether more results are available for this query via continuation_token
continuation_token
string
Token to fetch next set of results via SearchRequest

Verifiable Presentation Request Spec

In the future, this endpoint will support the Verifiable Presentation Request Spec .

The Search endpoint supports SQL queries through the query parameter.

This allows for arbitrary query predicates, as well as more advanced functionality -- such as modifying the output format.

Schema

Any table name may be used in your query (we use c here) -- it doesn't matter what it is.

Name Type Description
id string Corresponds to the item_id returned when item was inserted into wallet
type string Specified via item_type when item was inserted into wallet
data object The JSON object passed via item_json when item was inserted into wallet

Note that data is an object, not a string; thus, any of its sub-fields may be queried against.

For example, SELECT * FROM c WHERE c.data.someField = 'Hello, World!' would match against the following JSON object inserted via InsertItem:

{
    "someField": "Hello, World!"
}

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 .