Skip to content

Commit

Permalink
Merge pull request #202 from craigmoore1/CLI_Update
Browse files Browse the repository at this point in the history
Update the Client Library for clarity.
  • Loading branch information
rado0x54 authored Dec 8, 2022
2 parents bc93a75 + bdc444b commit 601808d
Showing 1 changed file with 38 additions and 32 deletions.
70 changes: 38 additions & 32 deletions sol-did/client/packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,24 @@ The `sol-did-client` library provides the following features:

## Client library
### Installation
In TS/JS project:
In the command line of the project folder, type the following and then press **Enter**:
```shell
yarn add @identity.com/sol-did-client # or npm install @identity.com/sol-did-client
yarn add @identity.com/sol-did-client #
```

or

```shell
npm install @identity.com/sol-did-client
```

### Usage - Setup and Resolution

Use the following TypeScript code to complete the listed commands.

#### Create a Service

Create a service for a SOL-DID by using the following code snippet:
```ts
const authority = Keypair.generate();
const cluster: ExtendedCluster = 'localnet';
Expand All @@ -60,12 +69,14 @@ yarn add @identity.com/sol-did-client # or npm install @identity.com/sol-did-cli
```

### Resolving a DID:

Resolve a SOL-DID with the following code snippet:
```ts
const didDoc = await service.resolve();
console.log(JSON.stringify(didDoc, null, 2));
```

### Information about DID resolution
### DID resolution information
`did:sol` DIDs are resolved in the following way:
1. `Generative` DIDs are DIDs that have no persisted DID data account. (e.g. every valid Solana Account/Wallet is in this state).
This will return a generative DID document where only the public key of the Account is a valid Verification Method.
Expand All @@ -76,16 +87,16 @@ on-chain.
## Usage - `did:sol` Manipulation
The following are instructions that can be executed against a DID.

When manipulating a DID one generally needs three authoritative elements:
When manipulating a DID, three elements are generally required:

1. An `authority`, a (native) Verification Method with a `Capability Invocation` flag, that is allowed to manipulate the DID.
2. A `fee payer`, a Solana account that covers the cost of the transaction execution.
3. A `(rent) payer`, a Solana account that covers an (eventual) initialization or resize of the DID data account.

Generally, all these entities are required for successful DID manipulation. Except when increasing the DID account size,
then only a `rent payer` is needed. Often all these accounts are represented by the same account, but this is
not a requirement. For the example, this enables the implementation of a permissionless proxy that satisfies
`2` and `3` to submit an authority-signed instruction/transaction to chain.
Often, all of these entities are required for successful DID manipulation. However, when increasing the DID account size,
then only a `rent payer` is needed. In most cases, all three elements are represented by the same account, but this is
not a requirement. It is possible to implement a permissionless proxy that satisfies the fee payer and the rent payer to submit an authority-signed instruction/transaction to the chain. For example, a dApp might opt to pay fees to encourage user onboarding.


Generally, a manipulative DID operation has the following form:

Expand Down Expand Up @@ -138,7 +149,7 @@ Here's a breakdown of all exposed Builder functions:
9. `async instructions(): Promise<TransactionInstruction[]>`: Terminal method that creates and returns the instruction(s) (Eth signing will be applied if applicable).

### Changing of DID Operations
Generally, `DidSolService` allows to chain multiple operations after one another. For example
`DidSolService` allows chaining multiple operations one after another. For example:
```ts
await service
.removeService('service-4', nonAuthoritySigner.publicKey) // remove
Expand All @@ -157,12 +168,11 @@ Generally, `DidSolService` allows to chain multiple operations after one another
.withAutomaticAlloc(nonAuthoritySigner.publicKey)
.rpc();
```
This operation chains 1 removeService and 2 addService operations that are signed
This operation chains one(1) `removeService` and two(2) `addService` operations that are signed
by and `ethSigner` and optionally resizes the account.

### Init a DID Account
Generally, all DID operations can be performed with `withAutomaticAlloc(payer: PublicKey)`, which automatically creates a DID data account of the required size. However, the API still supports manually initializing a DID account of any size.
Allocating a sufficiently sized account upfront would allow not to use any payers for subsequent operations.
All DID operations can be performed with `withAutomaticAlloc(payer: PublicKey)`, which automatically creates a DID data account of the required size. However, the API still supports manually initializing a DID account of any size. Allocating an account upfront that is large enough for future modifications might prevent the need to use payers for subsequent operations. However, allocating a larger account increases the rent fees for that account.

```ts
await service.initialize(1_000, payer.publicKey).rpc();
Expand All @@ -171,15 +181,15 @@ The `initialize` operation does not support `withAutomaticAlloc` OR `withEthSig
argument will set the default DID authority as `payer` and size it to the minimal initial size required.

### Resize a DID Account
Generally, all DID operations can be performed with `withAutomaticAlloc(payer: PublicKey)`, which automatically creates or resizes a DID data account of the required size. However, the API still supports manually resizing a DID account of any size.
Generally, all DID operations can be performed with `withAutomaticAlloc(payer: PublicKey)`, which automatically creates or resizes a DID data account of the required size. However, the API also supports manually resizing a DID account of any size.

```ts
await service.resize(1_500, payer.publicKey).rpc();
```
The `resize` operation does not support `withAutomaticAlloc`. Using `initialize` without an argument will set the default DID authority as `payer`.
The `resize` operation does not support `withAutomaticAlloc`. Using `initialize` without an argument will set the default DID authority as `payer`.

### Add a Verification Method
The operation will add a new Verification Method to the DID. The `keyData` can be a generically size `UInt8Array`, but logically it must match the methodType specified.
This operation adds a new Verification Method to the DID. The `keyData` can be a generically sized `UInt8Array`, but logically it must match the `methodType` specified.

```ts
await service.addVerificationMethod({
Expand All @@ -193,8 +203,7 @@ The operation will add a new Verification Method to the DID. The `keyData` can b
```

### Remove a Verification Method
Removes a Verification Method with the given `fragment` from the DID. Note, that at least one valid Verification Method with
a `Capability Invocation` flag must remain to prevent a lockout.
This code removes a Verification Method with the given `fragment` from the DID. It is important to keep at least one valid Verification Method with a Capability Invocation flag to prevent a lockout.

```ts
await service
Expand All @@ -211,8 +220,9 @@ that specific VM). `VerificationMethodFlags.OwnershipProof` is supported for the
- `EcdsaSecp256k1RecoveryMethod2020`
- `EcdsaSecp256k1VerificationKey2019`

In this example, the 'default" VM must match the `authority.publicKey`.

```ts
// Note in this example the 'default" VM must match authority.publicKey
await service
.setVerificationMethodFlags('default',
[VerificationMethodFlags.CapabilityInvocation, VerificationMethodFlags.OwnershipProof],
Expand Down Expand Up @@ -301,11 +311,10 @@ which are not allowed to be specified within the bulk update.
.withAutomaticAlloc(authority.publicKey)
.rpc();
```
Note, that the `default` Verification Method can never be removed. Therefore not setting it within the update Method will cause all flags to be removed from it.
The `default` Verification Method can never be removed, therefore not setting it within the update Method will cause all flags to be removed from it.

### Update all properties of a DID with a DID Document
This operation allows for bulk updates of all changeable properties of a DID by passing an existing DidSolDocument.
Please note, that this is a more destructive operation and should be handled with care. Furthermore, by overwriting all Verification Methods it removes ANY existing `VerificationMethodFlags.OwnershipProof`,
This operation allows for bulk updates of all changeable properties of a DID by passing an existing DidSolDocument.This is a destructive operation and should be handled with care. Furthermore, by overwriting all Verification Methods it removes ANY existing `VerificationMethodFlags.OwnershipProof`,
which are not allowed to be specified within the bulk update.

```ts
Expand Down Expand Up @@ -357,16 +366,16 @@ which are not allowed to be specified within the bulk update.
```

### Close a DID Account
This transaction closes a DID account. With that, it implicitly reverts to its generative state.
This transaction closes a DID account, reverting it to its generative state.

```ts
await service.close(rentDestination.publicKey).rpc();
```

The rent for the DID data account will be return to `rentDestination`.
The rent for the DID data account will be return to `rentDestination`. Closing a DID account requires using an `AuthoritySigner`.

### Migrate a persisted legacy DID to the new Program
Legacy DIDs are resolved fine with the current `did:sol` resolver, however, if you want to migrate a legacy DID (e.g. because you want to make use of all the new features), you can do so in the following way:
Legacy DIDs resolve without issues with the current `did:sol` resolver, however, if you want to migrate a legacy DID (e.g. to use the new features), you can do so with the following code:

In order to migrate a DID the following requirements need to be met:
- Persisted DID data account in the legacy program.
Expand All @@ -390,16 +399,13 @@ if (canMigrate) {
}
```
Note, that the migrate function works with a `nonAuthoritySigner`, e.g. that means ANYONE
can migrate any DID to the new program. But don't worry, since the migration keeps the state,
you can be happy if someone else does it for you.

In this example, however, `nonAuthoritySigner` is the `rent payer` for the new account.
can migrate any DID to the new program. However, the migration keeps the state, costs no more rent, and adds functionality, so no harm is done through the DID migration. Since legacy DIDs often automatically allocated a lot of space and new migrated DIDs are optimally space efficient, the migration to a new DID can actually save SOL.
In this example, however,
`nonAuthoritySigner` is the `rent payer` for the new account.

Furthermore, migrate takes an optional `legacyAuthority` argument. If specified, it closes
In this example, migrate takes an optional `legacyAuthority` argument. If specified, it closes
the legacy DID account automatically and recovers the rent to the `rent payer` of the new
account (`nonAuthoritySigner` in this example). Since legacy DIDs often automatically
allocated **a lot** of space and new migrated DIDs are optimally space efficient,
the migration to a new DID can actually make you `SOL` back.
account (`nonAuthoritySigner` in this example). This action can only be done by an AuthoritySigner, which protects the owner’s rent payer fees from being stolen.


## Contributing
Expand Down

0 comments on commit 601808d

Please sign in to comment.