README.md in sidetree-0.1.4 vs README.md in sidetree-0.1.5
- old
+ new
@@ -1,11 +1,10 @@
-# [WIP]Sidetree for Ruby
+# Sidetree for Ruby [![Build Status](https://github.com/azuchi/sidetreerb/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/azuchi/sidetreerb/actions/workflows/main.yml) [![Gem Version](https://badge.fury.io/rb/sidetree.svg)](https://badge.fury.io/rb/sidetree) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
-Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sidetree`. To experiment with that code, run `bin/console` for an interactive prompt.
+This is an experimental library that implements the [Sidetree protocol](https://identity.foundation/sidetree/spec/) in Ruby.
+If you use this library, please test to see if it works properly with [reference implementation](https://github.com/decentralized-identity/sidetree).
-TODO: Delete this and the text above, and describe your gem
-
## Installation
Add this line to your application's Gemfile:
```ruby
@@ -20,10 +19,245 @@
$ gem install sidetree
## Usage
-TODO: Write usage instructions here
+### Environment
+
+Currently, this library support mainnet and testnet.
+If you want to run with testnet, configure the network with the following code.
+
+```ruby
+Sidetree::Params.network = Sidetree::Params::Network::TESTNET
+```
+### Create new DID
+
+```ruby
+# Generate recovery key
+recovery_key = Sidetree::Key.generate
+
+# Generate update key
+update_key = Sidetree::Key.generate
+
+# Generate signing key
+signing_key = Sidetree::Key.generate(id: "signing-key")
+
+# Create DID Document from signing key
+document = Sidetree::Model::Document.new(public_keys: [signing_key])
+
+# Create DID
+did =
+ Sidetree::DID.create(
+ document,
+ update_key,
+ recovery_key
+ )
+=> "did:sidetree:test:EiAw8oTzWzmPyTANALvzeHkCc6-uQ7XxnohqphrwC_jhNg:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiJzaWduaW5nLWtleSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJJQ3BuZXVJZ2ZqZW5UZzhhMmVCeEd1RkVjV1lwZkFTcDRXdHVmbmdGd3owIiwieSI6IlNPbUxzSzhIWlU0bmY5YWZCQmF0SlJUSjVWeGZSMlVRZ1hFVV8xTXVyTzgifSwicHVycG9zZXMiOltdLCJ0eXBlIjoiRWNkc2FTZWNwMjU2azFWZXJpZmljYXRpb25LZXkyMDE5In1dLCJzZXJ2aWNlcyI6W119fV0sInVwZGF0ZUNvbW1pdG1lbnQiOiJFaUExQ1l4NWE5NTlPRGRicThrMG1WUDJwZmVEY0RXaHd3TXhWamNDS2tZOXF3In0sInN1ZmZpeERhdGEiOnsiZGVsdGFIYXNoIjoiRWlDWklRdjlyeVVDR2dLbjMtSjNfTV9ZN0k1VTIyZlpldFRaSTFxSjZqdnVEQSIsInJlY292ZXJ5Q29tbWl0bWVudCI6IkVpQ2dPTGRPb0F5a3A4SzBrMlNwMmlzRUtNOFpmRnBVSWhVcnRLbUEydEcxcWcifX0"
+```
+
+### DID operation
+
+#### Create Operation
+
+```ruby
+# Generate Create Operation
+create_op = did.create_op
+
+# Generate Chunk File from create operation
+chunk_file = Sidetree::Model::ChunkFile.create_from_ops(create_ops: [create_op])
+
+# Write chunk file to IPFS
+# Initialize IPFS client(If the parameter is omitted, the default is to access http://localhost:5001/api/v0.)
+ipfs = Sidetree::CAS::IPFS.new
+
+chunk_file_uri = ipfs.write(chunk_file.to_compress)
+
+# Generate Provisional Index File and write to IPFS
+provisional_index_file = Sidetree::Model::ProvisionalIndexFile.new(chunks: [Sidetree::Model::Chunk.new(chunk_file_uri)])
+provisional_index_file_uri = ipfs.write(provisional_index_file.to_compress)
+
+# Generate Core Index File and write to IPFS
+core_index_file = Sidetree::Model::CoreIndexFile.new(
+ create_ops: [create_op],
+ provisional_index_file_uri: provisional_index_file_uri
+)
+core_index_file_uri = ipfs.write(core_index_file.to_compress)
+
+# Generate Anchor String to anchoring to Bitcoin
+anchor_str = Sidetree::Util::AnchoredDataSerializer.serialize(1, core_index_file_uri)
+```
+
+#### Update Operation
+
+```ruby
+# DID suffix to be updated
+did_suffix = "EiBRrmEha_Q30GieEwLB-XM8CZd_b49dQ7znhaBxfAHTsQ"
+
+# Current update key
+update_key = Sidetree::Key.new(private_key: <private key>)
+
+# Generate new signing key
+new_signing_key = Sidetree::Key.generate(id: "signing-key")
+
+# Create replace DID Document
+document = Sidetree::Model::Document.new(public_keys: [new_signing_key])
+
+# Generate next update key
+next_update_key = Sidetree::Key.generate
+
+# Generate update delta object
+delta =
+ Sidetree::Model::Delta.new(
+ [document.to_replace_patch],
+ next_update_key.to_commitment
+ )
+
+# Generate jws and sign with update key
+claim = { updateKey: update_key.to_jwk.normalize, deltaHash: delta.to_hash }
+jws = Sidetree::Util::JWS.sign(claim, update_key)
+
+# Generate Provisional Proof File and write to IPFS
+provisional_proof = Sidetree::Model::ProvisionalProofFile.new([jws])
+provisional_proof_uri = ipfs.write(provisional_proof.to_compress)
+
+# Create update operation
+update_op =
+ Sidetree::OP::Update.new(did_suffix, delta, jws, update_key.to_reveal_value)
+
+# Generate Chunk File and write to IPFS
+chunk_file =
+ Sidetree::Model::ChunkFile.create_from_ops(update_ops: [update_op])
+chunk_file_uri = ipfs.write(chunk_file.to_compress)
+
+# Generate Provisional Index File and write to IPFS
+provisional_index_file =
+ Sidetree::Model::ProvisionalIndexFile.new(
+ proof_file_uri: provisional_proof_uri,
+ chunks: [Sidetree::Model::Chunk.new(chunk_file_uri)],
+ operations: [update_op]
+ )
+provisional_index_file_uri = ipfs.write(provisional_index_file.to_compress)
+
+# Generate Core Index File and write to IPFS
+core_index_file =
+ Sidetree::Model::CoreIndexFile.new(
+ provisional_index_file_uri: provisional_index_file_uri
+ )
+core_index_file_uri = ipfs.write(core_index_file.to_compress)
+
+anchor_str =
+ Sidetree::Util::AnchoredDataSerializer.serialize(1, core_index_file_uri)
+```
+
+#### Recover Operation
+
+```ruby
+did_suffix = "EiBRrmEha_Q30GieEwLB-XM8CZd_b49dQ7znhaBxfAHTsQ"
+
+# Current recovery key
+recovery_key = Sidetree::Key.new(private_key: <private key>)
+
+# Generate new recovery key
+new_recovery_key = Sidetree::Key.generate
+
+# Generate new update key
+new_update_key = Sidetree::Key.generate
+
+# Generate new signing key
+new_signing_key = Sidetree::Key.generate(id: "signing-key")
+
+# Generate replace DID Document
+document = Sidetree::Model::Document.new(public_keys: [new_signing_key])
+delta =
+ Sidetree::Model::Delta.new(
+ [document.to_replace_patch],
+ new_update_key.to_commitment
+ )
+
+# Generate jws and sign with recovery key
+claim = {
+ recoveryKey: recovery_key.to_jwk.normalize,
+ recoveryCommitment: new_recovery_key.to_commitment,
+ deltaHash: delta.to_hash
+}
+jws = Sidetree::Util::JWS.sign(claim, recovery_key)
+
+# Generate Core Proof File from jws
+core_proof_file = Sidetree::Model::CoreProofFile.new(recover_proofs: [jws])
+core_proof_file_uri = ipfs.write(core_proof_file.to_compress)
+
+# Create recover operation
+recover_op =
+ Sidetree::OP::Recover.new(
+ did_suffix,
+ delta,
+ jws,
+ recovery_key.to_reveal_value
+ )
+
+# Generate Chunk File and write to IPFS
+chunk_file =
+ Sidetree::Model::ChunkFile.create_from_ops(recover_ops: [recover_op])
+chunk_file_uri = ipfs.write(chunk_file.to_compress)
+
+# Generate Provisional Index File and write to IPFS
+provisional_index_file =
+ Sidetree::Model::ProvisionalIndexFile.new(
+ chunks: [Sidetree::Model::Chunk.new(chunk_file_uri)]
+ )
+provisional_index_file_uri = ipfs.write(provisional_index_file.to_compress)
+
+# Generate Core Index File and write to IPFS
+core_index_file =
+ Sidetree::Model::CoreIndexFile.new(
+ provisional_index_file_uri: provisional_index_file_uri,
+ core_proof_file_uri: core_proof_file_uri,
+ recover_ops: [recover_op]
+ )
+core_index_file_uri = ipfs.write(core_index_file.to_compress)
+
+anchor_str =
+ Sidetree::Util::AnchoredDataSerializer.serialize(1, core_index_file_uri)
+```
+
+#### Deactivate operation
+
+```ruby
+# Current recovery key
+recovery_key = Sidetree::Key.new(private_key: <private key>)
+
+# Generate jws and sign with recovery key
+claim = {
+ didSuffix: did_suffix,
+ recoveryKey: recovery_key.to_jwk.normalize
+}
+jws = Sidetree::Util::JWS.sign(claim, recovery_key)
+
+# Generate Core Proof File and write to IPFS
+core_proof_file = Sidetree::Model::CoreProofFile.new(deactivate_proofs: [jws])
+core_proof_file_uri = ipfs.write(core_proof_file.to_compress)
+
+# Create Deactivate Operation
+deactivate_op =
+ Sidetree::OP::Deactivate.new(
+ did_suffix,
+ jws,
+ recovery_key.to_reveal_value
+ )
+
+# Generate Core Index File and write to IPFS
+core_index_file =
+ Sidetree::Model::CoreIndexFile.new(
+ core_proof_file_uri: core_proof_file_uri,
+ deactivate_ops: [deactivate_op]
+ )
+core_index_file_uri = ipfs.write(core_index_file.to_compress)
+
+anchor_str =
+ Sidetree::Util::AnchoredDataSerializer.serialize(1, core_index_file_uri)
+```
+
+The pseudocode above all anchor a single operation, but you can be combined into a batch(i.e. to single anchor string).
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.