LogoLogo
▼ Other Resources
  • 🏠Atsign Docs
  • atPlatform
    • atSign
    • atRecord
  • atSDK
    • Get Started
    • Authentication
    • atKey Reference
    • CRUD Operations
    • Notifications
    • Additional Features
      • Synchronization
      • Connection Hooks
  • Infrastructure
  • 🗒️Tutorials
    • Dart atSDK Walkthrough
      • Using the atSDK with Dart
      • Get sample code
      • Cutting your atSigns keys
      • Put and Get data asynchronously
      • Send and Receive data synchronously.
      • Remote Procedure Calls (RPC)
      • atTalk - Encrypted chat client
  • Related pages
    • Main site
    • atProtocol specification
    • atSign Registrar
    • NoPorts
Powered by GitBook

© 2025 Atsign

On this page
Export as PDF
  1. atSDK

CRUD Operations

How to do basic CRUD operations on an atServer

PreviousatKey ReferenceNextNotifications

Last updated 9 months ago

In Dart, the AtClient is stored within the AtClientManager. Once an atSign has been , you will be able to access the AtClientManager for its associated atSign.

AtClientManager

AtClientManager is a model. When AtClientManager.getInstance() is called, it will get the AtClientManager instance for the last onboarded atSign.

AtClientManager atClientManager = AtClientManager.getInstance();

If you need simultaneous access to multiple atClients, you need to create a new for each additional atClient, and onboard its atSign within the isolate.

An example of this pattern can be found in .

AtClient

As previously mentioned, the AtClientManager stores the actual AtClient itself. You can retrieve the AtClient by calling atClientManager.atClient.

AtClient atClient = atClientManager.atClient;

atKey

Before you can do anything with an atRecord, you need an to represent it.

If you don't know how to create an atKey, please see the first.

The following examples use the self atKey phone.wavi@<current atSign>

It is up to the developer to modify the atKey according to their use case.

Creating / Updating Data

To create data the put method is used, this method accepts text (String) or binary (List<int>).

String currentAtSign = atClient.getCurrentAtSign()!;
AtKey myID = AtKey.self('phone', namespace: 'wavi',
                        sharedBy: currentAtSign).build();
String dataToStore = "123-456-7890";
bool res = await atClient.put(myID, dataToStore);
put signature
Future<bool> put(
    AtKey key,
    dynamic value,
    {bool  = false,
    PutRequestOptions? putRequestOptions});

Strongly Typed Methods

Since put accepts both String or List<int> as a value, the typing is dynamic. atClient also contains the strongly typed putText which only accepts String for the value, or putBinary which only accepts List<int> for the value.

To update existing data

Updating existing data is done by doing a put to the same atKey, this will overwrite any existing data stored in the atRecord.

List<int> binaryData = [1, 2, 3, 4];
bool res = await atClient.put(myID, binaryData);

The bytes [1, 2, 3, 4] have now replaced the string "123-456-7890".

Reading Data

There are two parts to reading data using the atClient SDK:

  1. Scanning for and listing out the atKeys for atRecords that can be retrieved

  2. Retrieving the atRecord for a given atKey

1. Scanning and listing atKeys

There are two methods available for scanning and listing atKeys:

  1. getAtKeys which provides the list in Class format (i.e. List<AtKey>)

  2. getKeys which provides the list in String format (i.e. List<String>)

Both methods accept the same parameters, only the return type is different. So we will show the more commonly used getAtKeys signature:

getAtKeys signature
Future<List<AtKey>> getAtKeys(
    {String? regex,
    String? sharedBy,
    String? sharedWith,
    bool showHiddenKeys = false});

regex

A regular expression used to filter the list of atKeys.

sharedBy

Filter the list of atKeys to only include ones shared by a particular atSign.

sharedWith

Filter the list of atKeys to only include ones shared with a particular atSign.

showHiddenKeys

A boolean flag to enable the inclusion of hidden atKeys (default = false)

Usage

Get all available (non-hidden) atKeys:

List<AtKey> allIDs = await atClient.getAtKeys();

All atKeys which end with ".wavi" in the record identifier part:

List<AtKey> waviIDs = await atClient.getAtKeys(regex: '^.*\.wavi@.+$');

2. Retrieving atRecords by atKey

To retrieve an atRecord, you must know the atKey and pass it to the get method.

get signature
Future<AtValue> get(
    AtKey key,
    {bool isDedicated = false,
    GetRequestOptions? getRequestOptions});

Calling this function will return an AtValue, and update the atKey passed to it with any changes to the metadata.

Usage

AtValue atValue = await atClient.get(myID);
String? text = atValue.;

Deleting Data

To delete data, simply call the delete method with the atKey for the atRecord to delete.

delete signature
Future<bool> delete(
    AtKey key,
    {bool isDedicated = false});

Usage

bool res = await atClient.delete(myID);

Additional Features

See Additional Features to learn about synchronization, which supports syncing of a local atServer, allowing CRUD operations to work even if the application has no internet access.

API Docs

C

Table of Contents

  • Introduction

  • Put Public atKey

    • 1. Create Public AtKey

    • 2. Call `atclient_put_public_key`

    • Example Application

  • Put Self atKey

    • 1. Create a Self atKey

    • 2. Call `atclient_put_self_key`

    • Example Application

  • Put Shared atKey

    • 1. Create a Shared atKey

    • 2. Call `atclient_put_shared_key`

    • Example Application

  • Get Public atKey

    • 1. Create Public AtKey

    • 2. Call `atclient_get_public_key`

    • 3. Free `value`

    • Example Application

  • Get Self atKey

    • 1. Create a Self atKey

    • 2. Call `atclient_get_self_key`

    • 3. Free `value`

    • Example Application

  • Get Shared atKey

    • 1. Create a Shared atKey

    • 2. Call `atclient_get_shared_key`

    • 3. Free `value`

    • Example Application

  • Delete an atKey

    • 1. Create an AtKey

    • 2. Call `atclient_delete`

    • Example Application

  • Request Options

Introduction

In this section, we will learn how to put, get, and delete an atKey.

Put Public atKey

1. Create Public AtKey

First, create a public atKey. It is important to note that the shared_by atSign should be the same as the authenticated atSign in the application.

atclient_atkey my_public_atkey;
atclient_atkey_init(&my_public_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_namespace = "c_demos";

if (atclient_atkey_create_public_key(&my_public_atkey, atkey_key, atkey_shared_by, atkey_namespace) != 0)
{
  // an error occurred
}

2. Call `atclient_put_public_key`

Next, simply *put* the value into your atServer. Since we are putting a public value into our atServer, no data will be encrypted and this data will be available for any atSign to get.

We will pass NULL into the request_options and commit_id parameters because we want to use the default options for now and we don't particularly care about the commit_id that it returns, but you could receive it if you would like.

This function returns an int for error handling, in which a non-zero exit code indicates an error.

const char *atkey_value = "123-456-7890";

if (atclient_put_public_key(&atclient, &my_public_atkey, atkey_value, NULL, NULL) != 0)
{
    // an error occurred
}

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@soccer99"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_public_atkey;
    atclient_atkey_init(&my_public_atkey);

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_public_key(&my_public_atkey, atkey_key, atkey_shared_by, atkey_namespace)) != 0)
    {
        goto exit;
    }

    const char *atkey_value = "123-456-7890";

    /*
     * atclient_put_self_key lets you put a key-value pair in your atSign's atServer.
     * For our purposes, we will pass `NULL` for the request options and the commit id. 
     * We want to use the default options and we don't want to receive and
     * store the commit id.
     */
    if ((exit_code = atclient_put_public_key(&atclient, &my_public_atkey, atkey_value, NULL, NULL)) != 0)
    {
        goto exit;
    }

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_public_atkey);
    return exit_code;
}
}

Put Self atKey

1. Create a Self atKey

atclient_atkey my_self_atkey;
atclient_atkey_init(&my_self_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_namespace = "c_demos";

if (atclient_atkey_create_self_key(&my_self_atkey, atkey_key, atkey_shared_by, atkey_namespace) != 0)
{
    // an error occurred
}

2. Call `atclient_put_self_key`

This will put a value specially encrypted for your atServer that only the atSign's atKeys can decrypt.

We will pass NULL into the request_options and commit_id parameters because we want to use the default options for now and we don't particularly care about the commit_id that it returns, but you could receive it if you would like.

This function will return an int for error handling, in which a non-zero exit code indicates an error.

const char *atkey_value = "123-456-7890";

if (atclient_put_self_key(&atclient, &my_self_atkey, atkey_value, NULL, NULL) != 0)
{
  // an error occurred
}

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@soccer99"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_self_atkey;
    atclient_atkey_init(&my_self_atkey);

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_self_key(&my_self_atkey, atkey_key, atkey_shared_by, atkey_namespace)) != 0)
    {
        goto exit;
    }

    const char *atkey_value = "123-456-7890";

    /*
     * atclient_put_self_key lets you put a key-value pair in your atSign's atServer.
     * For our purposes, we will pass `NULL` for the request options and the commit id. 
     * We want to use the default options and we don't want to receive and
     * store the commit id.
     */
    if ((exit_code = atclient_put_self_key(&atclient, &my_self_atkey, atkey_value, NULL, NULL)) != 0)
    {
        goto exit;
    }

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_self_atkey);
    return exit_code;
}
}

Put Shared atKey

1. Create a Shared atKey

atclient_atkey my_shared_atkey;
atclient_atkey_init(&my_shared_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_shared_with = "@soccer0";
const char *atkey_namespace = "c_demos";
if (atclient_atkey_create_shared_key(&my_shared_atkey, atkey_key, atkey_shared_by, atkey_shared_with, atkey_namespace) != 0)
{
    // an error occurred
}

2. Call `atclient_put_shared_key`

This function will put our string value into the atServer. Since we are using a Shared atKey, that means only the shared_by and shared_with atSign will be able to decrypt this value.

We will pass NULL into the request_options and commit_id parameters because we want to use the default options for now and we don't particularly care about the commit_id that it returns, but you could receive it if you would like.

This function returns an int for error handling, in which a non-zero exit code indicates an error.

const char *atkey_value = "123-456-7890";
if (atclient_put_shared_key(&atclient, &my_shared_atkey, atkey_value, NULL, NULL) != 0)
{
    // an error occurred
}

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@soccer99"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_shared_atkey;
    atclient_atkey_init(&my_shared_atkey);

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_shared_with = "@soccer0";
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_shared_key(&my_shared_atkey, atkey_key, atkey_shared_by, atkey_shared_with, atkey_namespace)) != 0)
    {
        goto exit;
    }

    const char *atkey_value = "123-456-7890";

    /*
     * atclient_put_self_key lets you put a key-value pair in your atSign's atServer.
     * For our purposes, we will pass `NULL` for the request options and the commit id. 
     * We want to use the default options and we don't want to receive and
     * store the commit id.
     */
    if ((exit_code = atclient_put_shared_key(&atclient, &my_shared_atkey, atkey_value, NULL, NULL)) != 0)
    {
        goto exit;
    }

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_shared_atkey);
    return exit_code;
}
}

Get Public atKey

1. Create Public AtKey

First, create a public atKey. It is important to note that the shared_by atSign should be the same as the authenticated atSign in the application.

atclient_atkey my_public_atkey;
atclient_atkey_init(&my_public_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_namespace = "c_demos";

if (atclient_atkey_create_public_key(&my_public_atkey, atkey_key, atkey_shared_by, atkey_namespace) != 0)
{
  // an error occurred
}

2. Call `atclient_get_public_key`

We will create a variable named value and pass the address to it in our atclient_get_public_key function call. The function will allocate memory for us and populate that variable for us.

We will pass NULL into the request_options parameter because we want to use the default options for now.

This function returns an int for error handling, in which a non-zero exit code indicates an error.

char *value = NULL;
if (atclient_get_public_key(&atclient, &my_public_atkey, &value, NULL) != 0)
{
    // an error occurred
}

3. Free `value`

Once we are done with the value itself, we should free it to avoid any memory leaks.

free(value);

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@soccer99"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_public_atkey;
    atclient_atkey_init(&my_public_atkey);

    /*
     * Let's declare a null pointer which will later be allocated by our `atclient_get_public_key` function. It is our responsibility to free it once we are
     * done with it.
     */
    char *value = NULL;

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_public_key(&my_public_atkey, atkey_key, atkey_shared_by, atkey_namespace)) != 0)
    {
        goto exit;
    }

    /*
     * `atclient_get_public_key` will allocate memory for the `value` pointer. It is our responsibility to free it once we are done with it.
     * We will pass `NULL` into the request_options argument for now and just use the default request options.
     */
    if ((exit_code = atclient_get_public_key(&atclient, &my_public_atkey, &value, NULL)) != 0)
    {
        goto exit;
    }

    atlogger_log("3d-get-public-atkey", ATLOGGER_LOGGING_LEVEL_INFO, "value: \"%s\"\n", value);

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_public_atkey);
    free(value);
    return exit_code;
}
}

Get Self atKey

1. Create a Self atKey

atclient_atkey my_self_atkey;
atclient_atkey_init(&my_self_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_namespace = "c_demos";

if (atclient_atkey_create_self_key(&my_self_atkey, atkey_key, atkey_shared_by, atkey_namespace) != 0)
{
    // an error occurred
}

2. Call `atclient_get_self_key`

We will create a variable named value and pass the address to it in our atclient_get_self_key function call. The function will allocate memory for us and populate that variable for us.

We will pass NULL into the request_options parameter because we want to use the default options for now.

This function returns an int for error handling, in which a non-zero exit code indicates an error.

char *value = NULL;
if (atclient_get_self_key(&atclient, &my_self_atkey, &value, NULL) != 0)
{
    // an error occurred
}

3. Free `value`

Once we are done with the value itself, we should free it to avoid any memory leaks.

free(value);

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@soccer99"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_self_atkey;
    atclient_atkey_init(&my_self_atkey);

    /*
     * Let's declare a null pointer which will later be allocated by our `atclient_get_public_key` function. It is our responsibility to free it once we are
     * done with it.
     */
    char *value = NULL;

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_self_key(&my_self_atkey, atkey_key, atkey_shared_by, atkey_namespace)) != 0)
    {
        goto exit;
    }

    /*
     * `atclient_get_self_key` will allocate memory for the `value` pointer. It is our responsibility to free it once we are done with it.
     * We will pass `NULL` into the request_options argument for now and just use the default request options.
     */
    if ((exit_code = atclient_get_self_key(&atclient, &my_self_atkey, &value, NULL)) != 0)
    {
        goto exit;
    }

    atlogger_log("3E-get-self-atkey", ATLOGGER_LOGGING_LEVEL_INFO, "value: \"%s\"\n", value);

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_self_atkey);
    free(value);
    return exit_code;
}
}

Get Shared atKey

1. Create a Shared atKey

atclient_atkey my_shared_atkey;
atclient_atkey_init(&my_shared_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_shared_with = "@soccer0";
const char *atkey_namespace = "c_demos";
if (atclient_atkey_create_shared_key(&my_shared_atkey, atkey_key, atkey_shared_by, atkey_shared_with, atkey_namespace) != 0)
{
    // an error occurred
}

2. Call `atclient_get_shared_key`

We will create a variable named value and pass the address to it in our atclient_get_shared_key function call. The function will allocate memory for us and populate that variable for us.

We will pass NULL into the request_options parameter because we want to use the default options for now.

This function returns an int for error handling, in which a non-zero exit code indicates an error.

char *value = NULL;
if (atclient_get_shared_key(&atclient, &my_self_atkey, &value, NULL) != 0)
{
    // an error occurred
}

3. Free `value`

Once we are done with the value itself, we should free it to avoid any memory leaks.

free(value)

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@soccer99"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_shared_atkey;
    atclient_atkey_init(&my_shared_atkey);

    /*
     * Let's declare a null pointer which will later be allocated by our `atclient_get_public_key` function. It is our responsibility to free it once we are
     * done with it.
     */
    char *value = NULL;

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_shared_with = "@soccer0";
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_shared_key(&my_shared_atkey, atkey_key, atkey_shared_by, atkey_shared_with, atkey_namespace)) != 0)
    {
        goto exit;
    }

    /*
     * `atclient_get_self_key` will allocate memory for the `value` pointer. It is our responsibility to free it once we are done with it.
     * We will pass `NULL` into the request_options argument for now and just use the default request options.
     */
    if ((exit_code = atclient_get_shared_key(&atclient, &my_shared_atkey, &value, NULL)) != 0)
    {
        goto exit;
    }

    atlogger_log("3E-get-self-atkey", ATLOGGER_LOGGING_LEVEL_INFO, "value: \"%s\"\n", value);

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_shared_atkey);
    free(value);
    return exit_code;
}
}

Delete an atKey

1. Create an AtKey

First step is to create the atKey that you wish to delete. This can be of any atKey type (public, self, or shared). What is important to note is that you can only delete an atKey that you own (which means that the authenticated atSign is the same as the shared_by atSign). This should be obvious because you can only delete atKeys that have once been created by you. Only the rightful owners of the atKey that was created can delete it.

For the sake of this demo, we will create a Shared atKey.

atclient_atkey my_shared_atkey;
atclient_atkey_init(&my_shared_atkey);

const char *atkey_key = "phone";
const char *atkey_shared_by = "@jeremy_0";
const char *atkey_shared_with = "@soccer0";
const char *atkey_namespace = "c_demos";
if (atclient_atkey_create_shared_key(&my_shared_atkey, atkey_key, atkey_shared_by, atkey_shared_with, atkey_namespace) != 0)
{
    // an error occurred
}

2. Call `atclient_delete`

atclient_delete will delete the atKey from your atServer.

We will pass NULL to the request_options and commit_id parameter because we want to use the default options for now and we do not care about the commit_id. You can receive the commit_id if you would like by passing an int pointer.

It is pointless to set any metadata to the atKey when deleting. Metadata is only useful when getting (you can read any metadata that the key possesses) and putting (you can modify the atKey's behavior). When you are deleting, no metadata is used.

This functions returns an int for error handling. A non-zero exit code indicates an error.

if (atclient_delete(&atclient, &my_shared_atkey, NULL, NULL) != 0) {
    // an error occurred
}

Example Application

#include <atclient/atclient.h>
#include <atclient/atclient_utils.h>
#include <atclient/constants.h>
#include <atlogger/atlogger.h>
#include <stdlib.h>

#define ATSIGN "@jeremy_0"

int main()
{
    int exit_code = -1;

    atlogger_set_logging_level(ATLOGGER_LOGGING_LEVEL_DEBUG);

    char *atserver_host = NULL;
    int atserver_port = 0;

    atclient_atkeys atkeys;
    atclient_atkeys_init(&atkeys);

    atclient atclient;
    atclient_init(&atclient);

    atclient_atkey my_shared_atkey;
    atclient_atkey_init(&my_shared_atkey);

    if ((exit_code = atclient_utils_find_atserver_address(ATCLIENT_ATDIRECTORY_PRODUCTION_HOST, ATCLIENT_ATDIRECTORY_PRODUCTION_PORT, ATSIGN, &atserver_host, &atserver_port)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_utils_populate_atkeys_from_homedir(&atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    if ((exit_code = atclient_pkam_authenticate(&atclient, atserver_host, atserver_port, &atkeys, ATSIGN)) != 0)
    {
        goto exit;
    }

    const char *atkey_key = "phone";
    const char *atkey_shared_by = ATSIGN;
    const char *atkey_shared_with = "@soccer0";
    const char *atkey_namespace = "c_demos";

    if ((exit_code = atclient_atkey_create_shared_key(&my_shared_atkey, atkey_key, atkey_shared_by, atkey_shared_with, atkey_namespace)) != 0)
    {
        goto exit;
    }

    /*
     * `atclient_delete` will delete this shared atkey from our atServer. It is important to note that only the `shared_by` atSign can delete the shared atKey
     * When deleting, the `shared_by` atSign should always be the authenticated atSign in the `atclient` object.
     * We will pass `NULL` to the request_options and commit_id parameters because we want to use the default request_options and we don't care about the
     * commit_id we get back.
     */
    if ((exit_code = atclient_delete(&atclient, &my_shared_atkey, NULL, NULL) != 0)) {
        goto exit;
    }

    exit_code = 0;
exit:
{
    free(atserver_host);
    atclient_atkeys_free(&atkeys);
    atclient_free(&atclient);
    atclient_atkey_free(&my_shared_atkey);
    return exit_code;
}
}

Request Options

Under Construction

You can find the API reference for the entire package available on .

The AtClient class API reference is available .

You can find all of these examples on our .

If you are unfamiliar with the different atKey types, check out our documentation on .

pub
here
GitHub
atRecords
onboarded
singleton
isolate
at_daemon_server
reference
atKey