# Create and update entities

These procedures describe how to submit the main operations (create, update, lock, and unlock) for different entities, such as domains, vaults, and accounts.

For more information about these operations and entities, see [API > Get started](/products/custody/v1.26/api/get-started).

We assume that you have access to Ripple Custody, for example, a Ripple-provided sandbox, and that the environment is initialized and fully functional, that is, system setup is complete, as described in [Run system setup](/products/custody/v1.26/get-started/deployment/system-setup/setup).

## Create an entity

All the `create` type intents passed to the API have a builder object: `{Entity.builder()} -> {build methods} -> {.build}`. You need to use the correct builder for the entity. You can also access builder objects through the action object that represents the entity. The following sections show examples for each entity type.

## Update an entity

Updates are retrieved from their `get/list` representations, and have `set` methods to update their values: `{get} -> {set values} -> {actions} -> {update operation}`.

## Examples

The examples below represent a comprehensive set of operations needed for proposing intents for managing entities.

### Domain

These examples create, update, and lock and unlock domains. All examples result in an intent.

#### Create a domain

This example creates a domain with the `builder` object:


```java
var domainId = "";
var domainName = "";
var parentDomainId = "";

var userId = "";
var userAlias = "";
var userDescription = "";
var userPublicKey = "";
var userRole = "";

var domain = Domains.CreateDomain.builder()
        .id(domainId)
        .alias(domainName)
        .permissions(Domains.Permissions.builder().readAccess(
                Domains.ReadAccess.builder().all("admin").build()
        ).build())
        .policy(Policies.CreateDomainGenesisPolicy.buildDefault())
        .governingStrategy(Domains.GoverningStrategy.CoerceDescendants)
        .user(Users.CreateDomainGenesisUser.builder()
                .id(userId)
                .alias(userAlias)
                .description(userDescription)
                .publicKey(userPublicKey)
                .role(userRole)
                .build())
        .parentId(parentDomainId)
        .build();

harmonize.domains().create(domain, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the domain:


```java
var domainId = "";
var domainName = "";
var parentDomainId = "";

var userId = "";
var userAlias = "";
var userDescription = "";
var userPublicKey = "";
var userRole = "";

harmonize.domains().create()
        .id(domainId)
        .alias(domainName)
        .permissions(Domains.Permissions.builder().readAccess(
                Domains.ReadAccess.builder().all("admin").build()
        ).build())
        .policy(Policies.CreateDomainGenesisPolicy.buildDefault())
        .governingStrategy(Domains.GoverningStrategy.CoerceDescendants)
        .user(Users.CreateDomainGenesisUser.builder()
              .id(userId)
              .alias(userAlias)
              .description(userDescription)
              .publicKey(userPublicKey)
              .role(userRole)
              .build())
        .parentId(parentDomainId)
        .expire(Expire.hours(24))
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

#### Update a domain

The following example updates a domain:


```java
var domainId = "";

// Fetch the entity
var domain = harmonize.domains().get(domainId).orElseThrow();
// Then call the `.asUpdate()` method, which will return an updatable object
var domainUpdate = domain.asUpdate();

// Call the `.set*` methods to make the changes
domainUpdate.setAlias("ABC-")
        .setDescription("Another description");

// And finally, use the Actions object `.update( updateEntity, expire)` method to send the update request to Ripple Custody.
harmonize.domains().update(domainUpdate, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

#### Lock or unlock a domain

The following examples lock and unlock a domain:


```java
// Fetch the entity
var domain = harmonize.domains().get(domainId).orElseThrow();

// Then call the lock method on the actions instance
harmonize.domains().lock(domain, Timeout.minutes(1))
                .waitForSucceed(Timeout.minutes(1))

// Or to unlock we call the `unlock` method:
harmonize.domains().unlock(domain, Timeout.minutes(1))
                .waitForSucceed(Timeout.minutes(1))
```

### Vaults

These examples register, update, and lock and unlock vaults. All examples result in an intent.

#### Register a vault

This example registers a vault with the `builder` object:


```java
var vaultId = "";
var vaultAlias = "";
var vaultDescription = "";
var vaultPublicKey = "";
var vault = Vaults.CreateVault.builder()
        .id(vaultId)
        .alias(vaultAlias)
        .description(vaultDescription)
        .pubKey(vaultPublicKey)
        .build();

harmonize.vaults().create(
        vault,
        Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the vault:


```java
var vaultId = "";
var vaultAlias = "";
var vaultDescription = "";
var vaultPublicKey = "";

harmonize.vaults().create()
        .id(vaultId)
        .alias(vaultAlias)
        .description(vaultDescription)
        .pubKey(vaultPublicKey)
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

#### Update a vault

The following example updates a vault:


```java
var vaultId = "";

// Fetch the entity
var vault = harmonize.vaults().get(vaultId).orElseThrow();
// Then call the `.asUpdate()` method, which will return an updatable object
var vaultUpdate = vault.asUpdate();

// Call the `.set*` methods to make the changes
vaultUpdate.setAlias("Test alias")
        .setDescription("New description")
        .setCustomProperties(Map.of("A", "1"));

// And finally, use the Actions object `.update( updateEntity, expire)` method to send the update request to Harmonize.
harmonize.vaults().update(vaultUpdate, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

#### Lock or unlock a vault

The following examples lock and unlock a vault:


```java
// Fetch the entity
var vault = harmonize.vaults().get(vaultId).orElseThrow();

// Then call the lock method on the actions instance
harmonize.vaults().lock(vault, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));

// Or to unlock we call the `unlock` method:
    harmonize.vaults().unlock(vault, Expire.hours(24))
                    .waitForSucceed(Timeout.minutes(1));
```

### Account

These examples create, update, and lock and unlock accounts. All examples result in an intent.

#### Create an account

This example creates an account with the `builder` object:


```java
var domainId = "";
var accountId = "";
var accountAlias = "";
var accountDescription = "";
var vaultId = "";
var ledgerId = "";

var account = Accounts.CreateAccount.builder()
        .id(accountId)
        .alias(accountAlias)
        .description(accountDescription)
        .ledgerId(ledgerId)
        .vaultId(vaultId)
        .build();

harmonize.accounts(domainId).create(account, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the account:


```java
var domainId = "";
var accountId = "";
var accountAlias = "";
var accountDescription = "";
var vaultId = "";
var ledgerId = "";

harmonize.accounts(domainId)
        .create()
        .id(accountId)
        .alias(accountAlias)
        .description(accountDescription)
        .ledgerId(ledgerId)
        .vaultId(vaultId)
        .expire(Expire.hours(24))
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

#### Update an account

The following example updates an account:


```java
var domainId = "";
var accountId = "";

// Fetch the entity
var account = harmonize.accounts(domainId).get(accountId).orElseThrow();
// Then call the `.asUpdate()` method, which will return an updatable object
var accountUpdate = account.asUpdate();

// Call the `.set*` methods to make the changes
accountUpdate.setAlias("Test alias")
        .setDescription("Test description");

// And finally, use the Actions object `.update( updateEntity, expire)` method to send the update request to Ripple Custody.
harmonize.accounts(domainId)
        .update(accountUpdate, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

#### Lock or unlock an account

The following examples lock and unlock an account:


```java
// Fetch the entity
var account = harmonize.accounts(domainId).get(accountId).orElseThrow();

// Then call the lock method on the actions instance
harmonize.accounts(domainId).lock(account, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));

// Or to unlock we call the `unlock` method:
harmonize.accounts(domainId).unlock(account, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));
```

### Endpoints

These examples register, update, and lock and unlock endpoints. All examples result in an intent.

#### Register an endpoint

This example registers an endpoint with the `builder` object:


```java
var domainId = "";
var endpointId = "";
var endpointAlias = "";
var endpointDescription = "";
var address = "";
var ledgerId = "";

var endpoint = Endpoints.CreateEndpoint.builder()
        .id(endpointId)
        .alias(endpointId)
        .address(address)
        .ledgerId(ledgerId)
        .description(endpointDescription)
        .build();

harmonize.endpoints(domainId)
        .create(endpoint, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the endpoint:


```java
var domainId = "";
var endpointId = "";
var endpointAlias = "";
var endpointDescription = "";
var address = "";
var ledgerId = "";

harmonize.endpoints(domainId).create()
        .id(endpointId)
        .alias(endpointAlias)
        .address(address)
        .ledgerId(ledgerId)
        .description(endpointDescription)
        .expire(Expire.hours(24))
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

#### Update an endpoint

The following example updates an endpoint:


```java
var domainId = "";
var endpointId = "";

// Fetch the entity
var endpoint = harmonize.endpoints(domainId).get(endpointId).orElseThrow()
// Then call the `.asUpdate()` method, which will return an updatable object
var endpointUpdate = endpoint.asUpdate();

// Call the `.set*` methods to make the changes
endpointUpdate.setAlias("TestAlias-")
        .setDescription("Test description");

// And finally, use the Actions object `.update( updateEntity, expire)` method to send the update request to Ripple Custody.
harmonize.endpoints(domainId)
        .update(endpointUpdate, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

#### Lock or unlock an endpoint

The following examples lock and unlock an endpoint:


```java
// Fetch the entity
var endpoint = harmonize.endpoints(domainId).get(endpointId).orElseThrow()

// Then call the lock method on the actions instance
harmonize.endpoints(domainId).lock(endpoint, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));

// Or to unlock we call the `unlock` method:
harmonize.endpoints(domainId).unlock(endpoint, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));
```

### Policies

These examples create, update, and lock and unlock policies. All examples result in an intent.

#### Create a policy

This example creates a policy with the `builder` object:


```java
var domainId = "";
var policyId = "";
var policyAlias = "";

var policyDescription = "";
var conditionExpression = "context.request.author.id != '6ac20654-450e-29e4-65e2-1bdecb7db7c4'";

var policyWorkflow = Policies.WorkflowCondition.simpleBuilder()
        .quorum(1)
        .role("admin")
        .build();

var policyCondition = Policies.PolicyCondition.simpleBuilder()
        .expression(conditionExpression)
        .build();

var policy = Policies.CreatePolicy.builder()
        .id(policyId)
        .alias(policyAlias)
        .intentType(Policies.IntentType.v0_CreateAccount)
        .description(policyDescription)
        .locked(false)
        .rank(1)
        .condition(policyCondition)
        .workflow(policyWorkflow)
        .build();

harmonize.policies(domainId).create(policy, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the policy:


```java
var domainId = "";
var policyId = "";
var policyAlias = "";

var policyDescription = "";
var conditionExpression = "context.request.author.id != '6ac20654-450e-29e4-65e2-1bdecb7db7c4'";

var policyWorkflow = Policies.WorkflowCondition.simpleBuilder()
        .quorum(1)
        .role("admin")
        .build();

var policyCondition = Policies.PolicyCondition.simpleBuilder()
        .expression(conditionExpression)
        .build();

harmonize.policies(domainId).create()
        .id(policyId)
        .alias(policyAlias)
        .intentType(Policies.IntentType.v0_CreateAccount)
        .description(policyDescription)
        .locked(false)
        .rank(1)
        .condition(policyCondition)
        .workflow(policyWorkflow)
        .expire(Expire.hours(24))
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

#### Update a policy

The following example updates an policy:


```java
var domainId = "";
var policyId = "";

var conditionExpression = "context.request.author.id != '6ac20654-450e-29e4-65e2-1bdecb7db7c4'";

// Fetch the entity
var policy = harmonize.policies(domainId).get(policyId).orElseThrow();
// Then call the `.asUpdate()` method, which will return an updatable object
var policyUpdate = policy.asUpdate();

// Call the `.set*` methods to make the changes
policyUpdate.setAlias("Test-Alias")
        .setDescription("ABC");

var policyWorkflow = Policies.WorkflowCondition.simpleBuilder()
        .quorum(1)
        .role("admin")
        .build();

policyUpdate.setWorkflow(policyWorkflow);

var policyCondition = Policies.PolicyCondition.simpleBuilder()
        .expression(conditionExpression)
        .build();

policyUpdate.setCondition(policyCondition);

// And finally, use the Actions object `.update( updateEntity, expire)` method to send the update request to Ripple Custody.
harmonize.policies(domainId)
        .update(policyUpdate, Expire.hours(24))
        .waitForProcessingOrSucceeded(Timeout.minutes(1));
```

#### Lock or unlock a policy

The following examples lock and unlock a policy:


```java
// Fetch the entity
var policy = harmonize.policies(domainId).get(policyId).orElseThrow();

// Then call the lock method on the actions instance
harmonize.policies(domainId).lock(policy, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));

// Or to unlock we call the `unlock` method:
harmonize.policies(domainId).unlock(policy, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));
```

### Transactions

The following example creates a transaction. The example results in an intent.

#### Create a transaction

This example creates a transaction with the `builder` object:


```java
var domainId = "";
var fromAccount = "";
var toAccount = "";
var amount = "5432";
var maxFee = "5432";

var transaction = Transactions.CreateTransactionOrder.builder()
        .fromAccount(fromAccount)
        .orderParameters(Transactions.btcParameters()
                .maxFee(maxFee)
                .priorityHigh()
                .toAccount(domainId, toAccount)
                .amount(amount)
                .build()
        )
        .build();

harmonize.transactions(domainId).create(transaction, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the transaction:


```java
var domainId = "";
var fromAccount = "";
var toAccount = "";
var amount = "5432";
var maxFee = "5432";

harmonize.transactions(domainId)
        .create()
        .fromAccount(fromAccount)
        .orderParameters(Transactions.btcParameters()
                .maxFee(maxFee)
                .priorityHigh()
                .toAccount(domainId, toAccount)
                .amount(amount)
                .build()
        ).expire(Expire.hours(24))
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

### Users

These examples create, update, and lock and unlock users. All examples result in an intent.

#### Create a user

This example creates a policy with the `builder` object:


```java
var domainId = "";
var userId = "";
var userAlias = "";
var userRoles = List.of("admin");
var userPublicKey = "";
var userDescription = "";

var user = Users.CreateUser.builder()
        .id(userId)
        .alias(userAlias)
        .description(userDescription)
        .roles(userRoles)
        .publicKey(userPublicKey)
        .build();

harmonize.users(domainId)
        .create(user, Expire.hours(24))
        .waitForSucceed(Timeout.minutes(1));
```

The following example accesses the `builder` object through the action object that represents the user:


```java
var domainId = "";
var userId = "";
var userAlias = "";
var userRoles = List.of("admin");
var userPublicKey = "";
var userDescription = "";
        
harmonize.users(domainId).create()
        .id(userId)
        .alias(userAlias)
        .description(userDescription)
        .roles(userRoles)
        .publicKey(userPublicKey)
        .submit()
        .waitForSucceed(Timeout.minutes(1));
```

You can use this example to simultaneously create and submit an intent for an entity.

#### Update a user

The following example updates a user:


```java
var domainId = "";
var userId = "";

// Fetch the entity
var user = harmonize.users(domainId).get(userId).orElseThrow();
// Then call the `.asUpdate()` method, which will return an updatable object
var userUpdate = user.asUpdate();

// Call the `.set*` methods to make the changes
userUpdate.setAlias("TestAlias-2")
        .addRole("account");

// And finally, use the Actions object `.update( updateEntity, expire)` method to send the update request to Ripple Custody.
harmonize.users(domainId)
        .update(userUpdate, Expire.hours(24))
        .waitForProcessingOrSucceeded(Timeout.minutes(1));
```

#### Lock or unlock a user

The following examples lock and unlock a user:


```java
// Fetch the entity
var user = harmonize.users(domainId).get(userId).orElseThrow();

// Then call the lock method on the actions instance
harmonize.users(domainId).lock(user, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));

// Or to unlock we call the `unlock` method:
harmonize.users(domainId).unlock(user, Expire.hours(24))
                .waitForSucceed(Timeout.minutes(1));
```

### Ledgers

These examples list all ledgers and return the details of a ledger.

You cannot create or update ledgers with the API.

#### List ledgers

The following operation lists ledgers:


```java
harmonize.ledgers().list().ledgers.forEach(System.out::println)
```

#### Get a ledger

The following operation gets a ledger:


```java
var ledger harmonize.ledgers().get(ledgerId).orElseThrow();
```

### Requests

You cannot create or modify requests directly from the API. They are a result of sending intent proposals via the other actions objects.

#### List requests

The following operation lists requests:


```java
harmonize.requests(domainId).list().forEach(System.out::println);
```

#### Get a request

The following operation gets a request:


```java
var request = harmonize.requests(domainId).get(requestId).orElseThrow();
```

### Events

You cannot create or modify events directly from the API.
You can retrieve events from the Ripple Custody cluster.

#### List events

To list events:


```java
harmonize.events(domainId).list().forEach(System.out::println);
```