Skip to content

Commit

Permalink
Merge branch 'main' into feat/ecdsa-verifier-wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
UMR1352 committed Sep 5, 2024
2 parents 11b94a2 + deecc7e commit ba063d1
Show file tree
Hide file tree
Showing 42 changed files with 1,262 additions and 90 deletions.
13 changes: 8 additions & 5 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,18 @@ jobs:
run: cargo clean

# Build the library, tests, and examples without running them to avoid recompilation in the run tests step
- name: Build with all features
run: cargo build --workspace --tests --examples --all-features --release
- name: Build with default features
run: cargo build --workspace --tests --examples --release

- name: Start iota sandbox
if: matrix.os == 'ubuntu-latest'
uses: './.github/actions/iota-sandbox/setup'

- name: Run tests
run: cargo test --workspace --all-features --release
- name: Run tests excluding `custom_time` feature
run: cargo test --workspace --release

- name: Run tests with `custom_time` feature
run: cargo test --test custom_time --features="custom_time"

- name: Run Rust examples
# run examples only on ubuntu for now
Expand All @@ -157,7 +160,7 @@ jobs:
- name: Tear down iota sandbox
if: matrix.os == 'ubuntu-latest' && always()
uses: './.github/actions/iota-sandbox/tear-down'

- name: Stop sccache
uses: './.github/actions/rust/sccache/stop-sccache'
with:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ members = [
exclude = ["bindings/wasm", "bindings/grpc"]

[workspace.dependencies]
bls12_381_plus = { version = "=0.8.15" }
bls12_381_plus = { version = "0.8.17" }
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
thiserror = { version = "1.0", default-features = false }
strum = { version = "0.25", default-features = false, features = ["std", "derive"] }
Expand Down
2 changes: 1 addition & 1 deletion bindings/wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ crate-type = ["cdylib", "rlib"]

[dependencies]
async-trait = { version = "0.1", default-features = false }
bls12_381_plus = "=0.8.15"
bls12_381_plus = "0.8.17"
console_error_panic_hook = { version = "0.1" }
futures = { version = "0.3" }
identity_ecdsa_verifier = { path = "../../identity_ecdsa_verifier", default-features = false, features = ["es256", "es256k"] }
Expand Down
174 changes: 162 additions & 12 deletions bindings/wasm/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ if the object is being concurrently modified.</p>
<dt><a href="#CustomMethodData">CustomMethodData</a></dt>
<dd><p>A custom verification method data format.</p>
</dd>
<dt><a href="#DIDJwk">DIDJwk</a></dt>
<dd><p><code>did:jwk</code> DID.</p>
</dd>
<dt><a href="#DIDUrl">DIDUrl</a></dt>
<dd><p>A method agnostic DID Url.</p>
</dd>
Expand Down Expand Up @@ -318,6 +321,12 @@ This variant is the default.</p>
## Functions

<dl>
<dt><a href="#encodeB64">encodeB64(data)</a> ⇒ <code>string</code></dt>
<dd><p>Encode the given bytes in url-safe base64.</p>
</dd>
<dt><a href="#decodeB64">decodeB64(data)</a> ⇒ <code>Uint8Array</code></dt>
<dd><p>Decode the given url-safe base64-encoded slice into its raw bytes.</p>
</dd>
<dt><a href="#verifyEd25519">verifyEd25519(alg, signingInput, decodedSignature, publicKey)</a></dt>
<dd><p>Verify a JWS signature secured with the <code>EdDSA</code> algorithm and curve <code>Ed25519</code>.</p>
<p>This function is useful when one is composing a <code>IJwsVerifier</code> that delegates
Expand Down Expand Up @@ -572,6 +581,7 @@ if the object is being concurrently modified.
* [.createPresentationJwt(storage, fragment, presentation, signature_options, presentation_options)](#CoreDocument+createPresentationJwt)[<code>Promise.&lt;Jwt&gt;</code>](#Jwt)
* _static_
* [.fromJSON(json)](#CoreDocument.fromJSON)[<code>CoreDocument</code>](#CoreDocument)
* [.expandDIDJwk(did)](#CoreDocument.expandDIDJwk)[<code>CoreDocument</code>](#CoreDocument)

<a name="new_CoreDocument_new"></a>

Expand Down Expand Up @@ -1010,6 +1020,17 @@ Deserializes an instance from a plain JS representation.
| --- | --- |
| json | <code>any</code> |

<a name="CoreDocument.expandDIDJwk"></a>

### CoreDocument.expandDIDJwk(did) ⇒ [<code>CoreDocument</code>](#CoreDocument)
Creates a [CoreDocument](#CoreDocument) from the given [DIDJwk](#DIDJwk).

**Kind**: static method of [<code>CoreDocument</code>](#CoreDocument)

| Param | Type |
| --- | --- |
| did | [<code>DIDJwk</code>](#DIDJwk) |

<a name="Credential"></a>

## Credential
Expand Down Expand Up @@ -1262,6 +1283,136 @@ Deserializes an instance from a JSON object.
| --- | --- |
| json | <code>any</code> |

<a name="DIDJwk"></a>

## DIDJwk
`did:jwk` DID.

**Kind**: global class

* [DIDJwk](#DIDJwk)
* [new DIDJwk(did)](#new_DIDJwk_new)
* _instance_
* [.jwk()](#DIDJwk+jwk)[<code>Jwk</code>](#Jwk)
* [.scheme()](#DIDJwk+scheme) ⇒ <code>string</code>
* [.authority()](#DIDJwk+authority) ⇒ <code>string</code>
* [.method()](#DIDJwk+method) ⇒ <code>string</code>
* [.methodId()](#DIDJwk+methodId) ⇒ <code>string</code>
* [.toString()](#DIDJwk+toString) ⇒ <code>string</code>
* [.toCoreDid()](#DIDJwk+toCoreDid)[<code>CoreDID</code>](#CoreDID)
* [.toJSON()](#DIDJwk+toJSON) ⇒ <code>any</code>
* [.clone()](#DIDJwk+clone)[<code>DIDJwk</code>](#DIDJwk)
* _static_
* [.parse(input)](#DIDJwk.parse)[<code>DIDJwk</code>](#DIDJwk)
* [.fromJSON(json)](#DIDJwk.fromJSON)[<code>DIDJwk</code>](#DIDJwk)

<a name="new_DIDJwk_new"></a>

### new DIDJwk(did)
Creates a new [DIDJwk](#DIDJwk) from a [CoreDID](#CoreDID).

### Errors
Throws an error if the given did is not a valid `did:jwk` DID.


| Param | Type |
| --- | --- |
| did | [<code>CoreDID</code>](#CoreDID) \| <code>IToCoreDID</code> |

<a name="DIDJwk+jwk"></a>

### didJwk.jwk() ⇒ [<code>Jwk</code>](#Jwk)
Returns the JSON WEB KEY (JWK) encoded inside this `did:jwk`.

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+scheme"></a>

### didJwk.scheme() ⇒ <code>string</code>
Returns the [CoreDID](#CoreDID) scheme.

E.g.
- `"did:example:12345678" -> "did"`
- `"did:iota:smr:12345678" -> "did"`

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+authority"></a>

### didJwk.authority() ⇒ <code>string</code>
Returns the [CoreDID](#CoreDID) authority: the method name and method-id.

E.g.
- `"did:example:12345678" -> "example:12345678"`
- `"did:iota:smr:12345678" -> "iota:smr:12345678"`

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+method"></a>

### didJwk.method() ⇒ <code>string</code>
Returns the [CoreDID](#CoreDID) method name.

E.g.
- `"did:example:12345678" -> "example"`
- `"did:iota:smr:12345678" -> "iota"`

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+methodId"></a>

### didJwk.methodId() ⇒ <code>string</code>
Returns the [CoreDID](#CoreDID) method-specific ID.

E.g.
- `"did:example:12345678" -> "12345678"`
- `"did:iota:smr:12345678" -> "smr:12345678"`

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+toString"></a>

### didJwk.toString() ⇒ <code>string</code>
Returns the [CoreDID](#CoreDID) as a string.

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+toCoreDid"></a>

### didJwk.toCoreDid() ⇒ [<code>CoreDID</code>](#CoreDID)
**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+toJSON"></a>

### didJwk.toJSON() ⇒ <code>any</code>
Serializes this to a JSON object.

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk+clone"></a>

### didJwk.clone() ⇒ [<code>DIDJwk</code>](#DIDJwk)
Deep clones the object.

**Kind**: instance method of [<code>DIDJwk</code>](#DIDJwk)
<a name="DIDJwk.parse"></a>

### DIDJwk.parse(input) ⇒ [<code>DIDJwk</code>](#DIDJwk)
Parses a [DIDJwk](#DIDJwk) from the given `input`.

### Errors

Throws an error if the input is not a valid [DIDJwk](#DIDJwk).

**Kind**: static method of [<code>DIDJwk</code>](#DIDJwk)

| Param | Type |
| --- | --- |
| input | <code>string</code> |

<a name="DIDJwk.fromJSON"></a>

### DIDJwk.fromJSON(json) ⇒ [<code>DIDJwk</code>](#DIDJwk)
Deserializes an instance from a JSON object.

**Kind**: static method of [<code>DIDJwk</code>](#DIDJwk)

| Param | Type |
| --- | --- |
| json | <code>any</code> |

<a name="DIDUrl"></a>

## DIDUrl
Expand Down Expand Up @@ -7591,24 +7742,23 @@ Declares how credential subjects must relate to the presentation holder.
See also the [Subject-Holder Relationship](https://www.w3.org/TR/vc-data-model/#subject-holder-relationships) section of the specification.
## CredentialStatus
**Kind**: global variable
<a name="AlwaysSubject"></a>
<a name="encodeB64"></a>
## AlwaysSubject
The holder must always match the subject on all credentials, regardless of their [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property.
This variant is the default.
## encodeB64(data) ⇒ <code>string</code>
Encode the given bytes in url-safe base64.
**Kind**: global variable
<a name="SubjectOnNonTransferable"></a>
**Kind**: global function
## SubjectOnNonTransferable
The holder must match the subject only for credentials where the [`nonTransferable`](https://www.w3.org/TR/vc-data-model/#nontransferable-property) property is `true`.
| Param | Type |
| --- | --- |
| data | <code>Uint8Array</code> |
**Kind**: global variable
<a name="Any"></a>
<a name="decodeB64"></a>
## Any
The holder is not required to have any kind of relationship to any credential subject.
## decodeB64(data) ⇒ <code>Uint8Array</code>
Decode the given url-safe base64-encoded slice into its raw bytes.
**Kind**: global variable
<a name="PresentationProofAlgorithm"></a>
Expand Down
27 changes: 26 additions & 1 deletion bindings/wasm/examples/src/0_basic/2_resolve_did.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
// Copyright 2020-2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { IotaDocument, IotaIdentityClient, JwkMemStore, KeyIdMemStore, Storage } from "@iota/identity-wasm/node";
import {
CoreDocument,
DIDJwk,
IotaDocument,
IotaIdentityClient,
IToCoreDocument,
JwkMemStore,
KeyIdMemStore,
Resolver,
Storage,
} from "@iota/identity-wasm/node";
import { AliasOutput, Client, MnemonicSecretManager, Utils } from "@iota/sdk-wasm/node";
import { API_ENDPOINT, createDid } from "../util";

const DID_JWK: string =
"did:jwk:eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6ImFjYklRaXVNczNpOF91c3pFakoydHBUdFJNNEVVM3l6OTFQSDZDZEgyVjAiLCJ5IjoiX0tjeUxqOXZXTXB0bm1LdG00NkdxRHo4d2Y3NEk1TEtncmwyR3pIM25TRSJ9";

/** Demonstrates how to resolve an existing DID in an Alias Output. */
export async function resolveIdentity() {
const client = new Client({
Expand Down Expand Up @@ -34,4 +47,16 @@ export async function resolveIdentity() {
// We can also resolve the Alias Output directly.
const aliasOutput: AliasOutput = await didClient.resolveDidOutput(did);
console.log("The Alias Output holds " + aliasOutput.getAmount() + " tokens");

// did:jwk can be resolved as well.
const handlers = new Map<string, (did: string) => Promise<CoreDocument | IToCoreDocument>>();
handlers.set("jwk", didJwkHandler);
const resolver = new Resolver({ handlers });
const did_jwk_resolved_doc = await resolver.resolve(DID_JWK);
console.log(`DID ${DID_JWK} resolves to:\n ${JSON.stringify(did_jwk_resolved_doc, null, 2)}`);
}

const didJwkHandler = async (did: string) => {
let did_jwk = DIDJwk.parse(did);
return CoreDocument.expandDIDJwk(did_jwk);
};
Loading

0 comments on commit ba063d1

Please sign in to comment.