sidetree 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/lib/sidetree/did.rb +11 -13
- data/lib/sidetree/key.rb +26 -26
- data/lib/sidetree/model/document.rb +4 -4
- data/lib/sidetree/model/service.rb +6 -6
- data/lib/sidetree/model.rb +4 -4
- data/lib/sidetree/op/create.rb +20 -2
- data/lib/sidetree/op/deactivate.rb +10 -0
- data/lib/sidetree/op/recover.rb +10 -0
- data/lib/sidetree/op.rb +18 -16
- data/lib/sidetree/validator.rb +28 -29
- data/lib/sidetree/version.rb +1 -1
- data/lib/sidetree.rb +18 -18
- data/sidetree.gemspec +2 -3
- metadata +10 -24
- data/exe/ion +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a4b7ce3f8ab94c646d21e2083664437b75877ee43264b172fdcadd8f8c9fffc
|
4
|
+
data.tar.gz: 3ed1dee9aaba4e13f3122d57f9b875c5279c2148a3cbf1e6818d2073e9d7759e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d87cd2fae36188a3e24d37f73f99637a6a55ef8d2e300261f46595811194d2cbccc2ea9b6da3ad77564f3312ce2ee51561814a9cf02c261031b35438b2df0d5
|
7
|
+
data.tar.gz: f9fbb814e7536a672f3f12b2c83fbf9af4f5072a0ee210e9935ce8b627972d659d28d36df9f7425e5b3c44edd7589a8fec7b68cb1b1d34c2af711c3eedd02316
|
data/.github/workflows/main.yml
CHANGED
data/lib/sidetree/did.rb
CHANGED
@@ -6,21 +6,21 @@ module Sidetree
|
|
6
6
|
|
7
7
|
# @raise [Sidetree::Error]
|
8
8
|
def initialize(did)
|
9
|
-
if !did.start_with?(
|
10
|
-
raise Error,
|
9
|
+
if !did.start_with?("did:ion:") && !did.start_with?("did:sidetree:")
|
10
|
+
raise Error, "Expected DID method not given in DID."
|
11
11
|
end
|
12
|
-
if did.count(
|
13
|
-
raise Error,
|
12
|
+
if did.count(":") > (Sidetree::Params.testnet? ? 4 : 3)
|
13
|
+
raise Error, "Unsupported DID format."
|
14
14
|
end
|
15
15
|
if Sidetree::Params.testnet?
|
16
|
-
_, @method, _, @suffix, @long_suffix = did.split(
|
16
|
+
_, @method, _, @suffix, @long_suffix = did.split(":")
|
17
17
|
else
|
18
|
-
_, @method, @suffix, @long_suffix = did.split(
|
18
|
+
_, @method, @suffix, @long_suffix = did.split(":")
|
19
19
|
end
|
20
20
|
|
21
21
|
if @long_suffix
|
22
22
|
unless suffix == create_op.suffix.unique_suffix
|
23
|
-
raise Error,
|
23
|
+
raise Error, "DID document mismatches short-form DID."
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -39,18 +39,16 @@ module Sidetree
|
|
39
39
|
method: Sidetree::Params::DEFAULT_METHOD
|
40
40
|
)
|
41
41
|
unless document.is_a?(Sidetree::Model::Document)
|
42
|
-
raise Error,
|
42
|
+
raise Error, "document must be Sidetree::Model::Document instance."
|
43
43
|
end
|
44
44
|
unless update_key.is_a?(Sidetree::Key)
|
45
|
-
raise Error,
|
45
|
+
raise Error, "update_key must be Sidetree::Key instance."
|
46
46
|
end
|
47
47
|
unless recovery_key.is_a?(Sidetree::Key)
|
48
|
-
raise Error,
|
48
|
+
raise Error, "recovery_key must be Sidetree::Key instance."
|
49
49
|
end
|
50
50
|
|
51
|
-
patches = [
|
52
|
-
{ 'action': OP::PatchAction::REPLACE, 'document': document.to_h }
|
53
|
-
]
|
51
|
+
patches = [{ action: OP::PatchAction::REPLACE, document: document.to_h }]
|
54
52
|
delta = Model::Delta.new(patches, update_key.to_commitment)
|
55
53
|
suffix =
|
56
54
|
Sidetree::Model::Suffix.new(delta.to_hash, recovery_key.to_commitment)
|
data/lib/sidetree/key.rb
CHANGED
@@ -16,14 +16,14 @@ module Sidetree
|
|
16
16
|
)
|
17
17
|
if private_key
|
18
18
|
unless Key.valid_private_key?(private_key)
|
19
|
-
raise Error,
|
19
|
+
raise Error, "private key is invalid range."
|
20
20
|
end
|
21
21
|
|
22
22
|
@private_key = private_key
|
23
23
|
pub = ECDSA::Group::Secp256k1.generator.multiply_by_scalar(private_key)
|
24
24
|
if public_key
|
25
25
|
unless pub == public_key
|
26
|
-
raise Error,
|
26
|
+
raise Error, "Public and private keys do not match."
|
27
27
|
end
|
28
28
|
else
|
29
29
|
public_key = pub
|
@@ -31,13 +31,13 @@ module Sidetree
|
|
31
31
|
end
|
32
32
|
|
33
33
|
unless public_key
|
34
|
-
raise Error,
|
34
|
+
raise Error, "Specify either the private key or the public key"
|
35
35
|
end
|
36
36
|
unless public_key.is_a?(ECDSA::Point)
|
37
|
-
raise Error,
|
37
|
+
raise Error, "public key must be an ECDSA::Point instance."
|
38
38
|
end
|
39
39
|
unless ECDSA::Group::Secp256k1.valid_public_key?(public_key)
|
40
|
-
raise Error,
|
40
|
+
raise Error, "public key is invalid."
|
41
41
|
end
|
42
42
|
|
43
43
|
@public_key = public_key
|
@@ -71,47 +71,47 @@ module Sidetree
|
|
71
71
|
# @return [Sidetree::Key]
|
72
72
|
# @raise [Sidetree::Error]
|
73
73
|
def self.from_hash(data)
|
74
|
-
key_data = data[
|
75
|
-
key_type = key_data[
|
76
|
-
curve = key_data[
|
77
|
-
if key_type.nil? || key_type !=
|
74
|
+
key_data = data["publicKeyJwk"] ? data["publicKeyJwk"] : data
|
75
|
+
key_type = key_data["kty"]
|
76
|
+
curve = key_data["crv"]
|
77
|
+
if key_type.nil? || key_type != "EC"
|
78
78
|
raise Error, "Unsupported key type '#{key_type}' specified."
|
79
79
|
end
|
80
|
-
if curve.nil? || curve !=
|
80
|
+
if curve.nil? || curve != "secp256k1"
|
81
81
|
raise Error, "Unsupported curve '#{curve}' specified."
|
82
82
|
end
|
83
|
-
raise Error,
|
84
|
-
raise Error,
|
83
|
+
raise Error, "x property required." unless key_data["x"]
|
84
|
+
raise Error, "y property required." unless key_data["y"]
|
85
85
|
|
86
86
|
# `x` and `y` need 43 Base64URL encoded bytes to contain 256 bits.
|
87
|
-
unless key_data[
|
87
|
+
unless key_data["x"].length == 43
|
88
88
|
raise Error, "Secp256k1 JWK 'x' property must be 43 bytes."
|
89
89
|
end
|
90
|
-
unless key_data[
|
90
|
+
unless key_data["y"].length == 43
|
91
91
|
raise Error, "Secp256k1 JWK 'y' property must be 43 bytes."
|
92
92
|
end
|
93
93
|
|
94
|
-
x = Base64.urlsafe_decode64(key_data[
|
95
|
-
y = Base64.urlsafe_decode64(key_data[
|
94
|
+
x = Base64.urlsafe_decode64(key_data["x"])
|
95
|
+
y = Base64.urlsafe_decode64(key_data["y"])
|
96
96
|
point =
|
97
97
|
ECDSA::Format::PointOctetString.decode(
|
98
|
-
[
|
98
|
+
["04"].pack("H*") + x + y,
|
99
99
|
ECDSA::Group::Secp256k1
|
100
100
|
)
|
101
101
|
private_key =
|
102
|
-
if key_data[
|
103
|
-
Base64.urlsafe_decode64(key_data[
|
102
|
+
if key_data["d"]
|
103
|
+
Base64.urlsafe_decode64(key_data["d"]).unpack1("H*").to_i(16)
|
104
104
|
else
|
105
105
|
nil
|
106
106
|
end
|
107
107
|
|
108
|
-
purposes = data[
|
108
|
+
purposes = data["purposes"] ? data["purposes"] : []
|
109
109
|
Key.new(
|
110
110
|
public_key: point,
|
111
111
|
private_key: private_key,
|
112
112
|
purposes: purposes,
|
113
|
-
id: data[
|
114
|
-
type: data[
|
113
|
+
id: data["id"],
|
114
|
+
type: data["type"]
|
115
115
|
)
|
116
116
|
end
|
117
117
|
|
@@ -127,8 +127,8 @@ module Sidetree
|
|
127
127
|
def to_jwk
|
128
128
|
jwk =
|
129
129
|
JSON::JWK.new(
|
130
|
-
kty:
|
131
|
-
crv:
|
130
|
+
kty: "EC",
|
131
|
+
crv: "secp256k1",
|
132
132
|
x:
|
133
133
|
Base64.urlsafe_encode64(
|
134
134
|
ECDSA::Format::FieldElementOctetString.encode(
|
@@ -146,7 +146,7 @@ module Sidetree
|
|
146
146
|
padding: false
|
147
147
|
)
|
148
148
|
)
|
149
|
-
jwk[
|
149
|
+
jwk["d"] = encoded_private_key if private_key
|
150
150
|
jwk
|
151
151
|
end
|
152
152
|
|
@@ -170,7 +170,7 @@ module Sidetree
|
|
170
170
|
def encoded_private_key
|
171
171
|
if private_key
|
172
172
|
Base64.urlsafe_encode64(
|
173
|
-
[private_key.to_s(16).rjust(32 * 2,
|
173
|
+
[private_key.to_s(16).rjust(32 * 2, "0")].pack("H*"),
|
174
174
|
padding: false
|
175
175
|
)
|
176
176
|
else
|
@@ -10,22 +10,22 @@ module Sidetree
|
|
10
10
|
def initialize(public_keys: [], services: [])
|
11
11
|
public_keys.each do |public_key|
|
12
12
|
unless public_key.is_a?(Sidetree::Key)
|
13
|
-
raise Error,
|
13
|
+
raise Error, "public_keys should be array of Sidetree::Key objects."
|
14
14
|
end
|
15
15
|
end
|
16
16
|
id_set = public_keys.map(&:id)
|
17
17
|
if (id_set.count - id_set.uniq.count) > 0
|
18
|
-
raise Error
|
18
|
+
raise Error "Public key id has to be unique."
|
19
19
|
end
|
20
20
|
services.each do |service|
|
21
21
|
unless service.is_a?(Sidetree::Model::Service)
|
22
22
|
raise Error,
|
23
|
-
|
23
|
+
"services should be array of Sidetree::Model::Service objects."
|
24
24
|
end
|
25
25
|
end
|
26
26
|
id_set = services.map(&:id)
|
27
27
|
if (id_set.count - id_set.uniq.count) > 0
|
28
|
-
raise Error
|
28
|
+
raise Error "Service id has to be unique."
|
29
29
|
end
|
30
30
|
|
31
31
|
@public_keys = public_keys
|
@@ -10,13 +10,13 @@ module Sidetree
|
|
10
10
|
# @raise [Sidetree::Error]
|
11
11
|
def initialize(id, type, endpoint)
|
12
12
|
Sidetree::Validator.validate_id!(id)
|
13
|
-
raise Error,
|
13
|
+
raise Error, "type should be String." unless type.is_a?(String)
|
14
14
|
if type.length > MAX_TYPE_LENGTH
|
15
15
|
raise Error,
|
16
16
|
"Service endpoint type length #{type.length} exceeds max allowed length of #{MAX_TYPE_LENGTH}."
|
17
17
|
end
|
18
18
|
if endpoint.is_a?(Array)
|
19
|
-
raise Error,
|
19
|
+
raise Error, "Service endpoint value cannot be an array."
|
20
20
|
end
|
21
21
|
|
22
22
|
Sidetree::Validator.validate_uri!(endpoint) if endpoint.is_a?(String)
|
@@ -33,16 +33,16 @@ module Sidetree
|
|
33
33
|
# @raise [Sidetree::Error]
|
34
34
|
# @return [Sidetree::Model::Service]
|
35
35
|
def self.from_hash(data)
|
36
|
-
Service.new(data[
|
36
|
+
Service.new(data["id"], data["type"], data["serviceEndpoint"])
|
37
37
|
end
|
38
38
|
|
39
39
|
# Convert data to Hash object.
|
40
40
|
# @return [Hash]
|
41
41
|
def to_h
|
42
42
|
hash = {}
|
43
|
-
hash[
|
44
|
-
hash[
|
45
|
-
hash[
|
43
|
+
hash["id"] = id if id
|
44
|
+
hash["type"] = type if type
|
45
|
+
hash["serviceEndpoint"] = endpoint if endpoint
|
46
46
|
hash
|
47
47
|
end
|
48
48
|
end
|
data/lib/sidetree/model.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Sidetree
|
2
2
|
module Model
|
3
|
-
autoload :Suffix,
|
4
|
-
autoload :Delta,
|
5
|
-
autoload :Document,
|
6
|
-
autoload :Service,
|
3
|
+
autoload :Suffix, "sidetree/model/suffix"
|
4
|
+
autoload :Delta, "sidetree/model/delta"
|
5
|
+
autoload :Document, "sidetree/model/document"
|
6
|
+
autoload :Service, "sidetree/model/service"
|
7
7
|
end
|
8
8
|
end
|
data/lib/sidetree/op/create.rb
CHANGED
@@ -11,6 +11,24 @@ module Sidetree
|
|
11
11
|
@suffix = suffix
|
12
12
|
end
|
13
13
|
|
14
|
+
# Generate create operation with new generate key.
|
15
|
+
# @param [String] method DID method defined in +Sidetree::Params::METHODS+.
|
16
|
+
# @return [Sidetree::OP::Create]
|
17
|
+
def self.generate(method: Sidetree::Params::METHODS[:ion])
|
18
|
+
recovery_key = Sidetree::Key.generate
|
19
|
+
update_key = Sidetree::Key.generate
|
20
|
+
signing_key = Sidetree::Key.generate(id: "signing-key")
|
21
|
+
document = Sidetree::Model::Document.new(public_keys: [signing_key])
|
22
|
+
did =
|
23
|
+
Sidetree::DID.create(
|
24
|
+
document,
|
25
|
+
update_key,
|
26
|
+
recovery_key,
|
27
|
+
method: method
|
28
|
+
)
|
29
|
+
did.create_op
|
30
|
+
end
|
31
|
+
|
14
32
|
def type
|
15
33
|
Sidetree::OP::Type::CREATE
|
16
34
|
end
|
@@ -31,7 +49,7 @@ module Sidetree
|
|
31
49
|
expected_base64 =
|
32
50
|
Base64.urlsafe_encode64(json.to_json_c14n, padding: false)
|
33
51
|
unless expected_base64 == base64_str
|
34
|
-
raise Error,
|
52
|
+
raise Error, "Initial state object and JCS string mismatch."
|
35
53
|
end
|
36
54
|
|
37
55
|
Create.new(
|
@@ -39,7 +57,7 @@ module Sidetree
|
|
39
57
|
Sidetree::Model::Delta.parse(json[:delta])
|
40
58
|
)
|
41
59
|
rescue JSON::ParserError
|
42
|
-
raise Error,
|
60
|
+
raise Error, "Long form initial state should be encoded jcs."
|
43
61
|
end
|
44
62
|
end
|
45
63
|
|
data/lib/sidetree/op.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
module Sidetree
|
2
2
|
module OP
|
3
3
|
module Type
|
4
|
-
CREATE =
|
5
|
-
UPDATE =
|
6
|
-
RECOVER =
|
7
|
-
DEACTIVATE =
|
4
|
+
CREATE = "create"
|
5
|
+
UPDATE = "update"
|
6
|
+
RECOVER = "recover"
|
7
|
+
DEACTIVATE = "deactivate"
|
8
8
|
end
|
9
9
|
|
10
10
|
# Sidetree patch actions. These are the valid values in the action property of a patch.
|
11
11
|
module PatchAction
|
12
|
-
REPLACE =
|
13
|
-
ADD_PUBLIC_KEYS =
|
14
|
-
REMOVE_PUBLIC_KEYS =
|
15
|
-
ADD_SERVICES =
|
16
|
-
REMOVE_SERVICES =
|
12
|
+
REPLACE = "replace"
|
13
|
+
ADD_PUBLIC_KEYS = "add-public-keys"
|
14
|
+
REMOVE_PUBLIC_KEYS = "remove-public-keys"
|
15
|
+
ADD_SERVICES = "add-services"
|
16
|
+
REMOVE_SERVICES = "remove-services"
|
17
17
|
end
|
18
18
|
|
19
19
|
# DID Document public key purpose.
|
20
20
|
module PublicKeyPurpose
|
21
|
-
AUTHENTICATION =
|
22
|
-
ASSERTION_METHOD =
|
23
|
-
CAPABILITY_INVOCATION =
|
24
|
-
CAPABILITY_DELEGATION =
|
25
|
-
KEY_AGREEMENT =
|
21
|
+
AUTHENTICATION = "authentication"
|
22
|
+
ASSERTION_METHOD = "assertionMethod"
|
23
|
+
CAPABILITY_INVOCATION = "capabilityInvocation"
|
24
|
+
CAPABILITY_DELEGATION = "capabilityDelegation"
|
25
|
+
KEY_AGREEMENT = "keyAgreement"
|
26
26
|
|
27
27
|
module_function
|
28
28
|
|
@@ -31,7 +31,9 @@ module Sidetree
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
autoload :Base,
|
35
|
-
autoload :Create,
|
34
|
+
autoload :Base, "sidetree/op/base"
|
35
|
+
autoload :Create, "sidetree/op/create"
|
36
|
+
autoload :Recover, "sidetree/op/recover"
|
37
|
+
autoload :Deactivate, "sidetree/op/deactivate"
|
36
38
|
end
|
37
39
|
end
|
data/lib/sidetree/validator.rb
CHANGED
@@ -5,7 +5,7 @@ module Sidetree
|
|
5
5
|
# @param [Hash] delta delta object.
|
6
6
|
# @return [Sidetree::Error]
|
7
7
|
def validate_delta!(delta)
|
8
|
-
raise Error,
|
8
|
+
raise Error, "Delta does not defined." unless delta
|
9
9
|
delta_size = delta.to_json_c14n.bytesize
|
10
10
|
if delta_size > Sidetree::Params::MAX_DELTA_SIZE
|
11
11
|
raise Error,
|
@@ -13,7 +13,7 @@ module Sidetree
|
|
13
13
|
end
|
14
14
|
|
15
15
|
if delta.instance_of?(Array)
|
16
|
-
raise Error,
|
16
|
+
raise Error, "Delta object cannot be an array."
|
17
17
|
end
|
18
18
|
delta.keys.each do |k|
|
19
19
|
unless %w[patches updateCommitment].include?(k.to_s)
|
@@ -22,11 +22,11 @@ module Sidetree
|
|
22
22
|
end
|
23
23
|
|
24
24
|
unless delta[:patches].instance_of?(Array)
|
25
|
-
raise Error,
|
25
|
+
raise Error, "Patches object in delta must be an array."
|
26
26
|
end
|
27
27
|
delta[:patches].each { |p| validate_patch!(p) }
|
28
28
|
|
29
|
-
validate_encoded_multi_hash!(delta[:updateCommitment],
|
29
|
+
validate_encoded_multi_hash!(delta[:updateCommitment], "updateCommitment")
|
30
30
|
end
|
31
31
|
|
32
32
|
# @param [Hash] patch patch object.
|
@@ -49,7 +49,7 @@ module Sidetree
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def validate_document!(document)
|
52
|
-
raise Error,
|
52
|
+
raise Error, "Document object missing in patch object" unless document
|
53
53
|
document.keys.each do |k|
|
54
54
|
unless %w[publicKeys services].include?(k.to_s)
|
55
55
|
raise Error, "Property '#{k}' is not allowed in document object."
|
@@ -61,7 +61,7 @@ module Sidetree
|
|
61
61
|
|
62
62
|
def validate_add_public_keys_patch!(patch)
|
63
63
|
unless patch.keys.length == 2
|
64
|
-
raise Error,
|
64
|
+
raise Error, "Patch missing or unknown property."
|
65
65
|
end
|
66
66
|
validate_public_keys!(patch[:publicKeys])
|
67
67
|
end
|
@@ -73,7 +73,7 @@ module Sidetree
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
unless patch[:ids].instance_of?(Array)
|
76
|
-
raise Error,
|
76
|
+
raise Error, "Patch public key ids not an array."
|
77
77
|
end
|
78
78
|
|
79
79
|
patch[:ids].each { |id| validate_id!(id) }
|
@@ -81,10 +81,10 @@ module Sidetree
|
|
81
81
|
|
82
82
|
def validate_add_services_patch!(patch)
|
83
83
|
unless patch.keys.length == 2
|
84
|
-
raise Error,
|
84
|
+
raise Error, "Patch missing or unknown property."
|
85
85
|
end
|
86
86
|
unless patch[:services].instance_of?(Array)
|
87
|
-
raise Error,
|
87
|
+
raise Error, "Patch services not an array."
|
88
88
|
end
|
89
89
|
validate_services!(patch[:services])
|
90
90
|
end
|
@@ -96,7 +96,7 @@ module Sidetree
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
unless patch[:ids].instance_of?(Array)
|
99
|
-
raise Error,
|
99
|
+
raise Error, "Patch service ids not an array."
|
100
100
|
end
|
101
101
|
|
102
102
|
patch[:ids].each { |id| validate_id!(id) }
|
@@ -104,7 +104,7 @@ module Sidetree
|
|
104
104
|
|
105
105
|
def validate_public_keys!(public_keys)
|
106
106
|
unless public_keys.instance_of?(Array)
|
107
|
-
raise Error,
|
107
|
+
raise Error, "publicKeys must be an array."
|
108
108
|
end
|
109
109
|
pubkey_ids = []
|
110
110
|
public_keys.each do |public_key|
|
@@ -114,7 +114,7 @@ module Sidetree
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
if public_key[:publicKeyJwk].instance_of?(Array)
|
117
|
-
raise Error,
|
117
|
+
raise Error, "publicKeyJwk object cannot be an array."
|
118
118
|
end
|
119
119
|
if public_key[:type] && !public_key[:type].is_a?(String)
|
120
120
|
raise Error, "Public key type #{public_key[:type]} is incorrect."
|
@@ -123,16 +123,16 @@ module Sidetree
|
|
123
123
|
validate_id!(public_key[:id])
|
124
124
|
|
125
125
|
if pubkey_ids.include?(public_key[:id])
|
126
|
-
raise Error,
|
126
|
+
raise Error, "Public key id is duplicated."
|
127
127
|
end
|
128
128
|
pubkey_ids << public_key[:id]
|
129
129
|
|
130
130
|
if public_key[:purposes]
|
131
131
|
unless public_key[:purposes].instance_of?(Array)
|
132
|
-
raise Error,
|
132
|
+
raise Error, "purposes must be an array."
|
133
133
|
end
|
134
134
|
unless public_key[:purposes].count == public_key[:purposes].uniq.count
|
135
|
-
raise Error,
|
135
|
+
raise Error, "purpose is duplicated."
|
136
136
|
end
|
137
137
|
public_key[:purposes].each do |purpose|
|
138
138
|
unless OP::PublicKeyPurpose.values.include?(purpose)
|
@@ -145,34 +145,33 @@ module Sidetree
|
|
145
145
|
|
146
146
|
def validate_services!(services)
|
147
147
|
unless services.instance_of?(Array)
|
148
|
-
raise Error,
|
148
|
+
raise Error, "services must be an array."
|
149
149
|
end
|
150
150
|
|
151
151
|
service_ids = []
|
152
152
|
services.each do |service|
|
153
153
|
unless service.keys.length == 3
|
154
|
-
raise Error,
|
154
|
+
raise Error, "Service has missing or unknown property."
|
155
155
|
end
|
156
156
|
|
157
157
|
validate_id!(service[:id])
|
158
158
|
|
159
159
|
if service_ids.include?(service[:id])
|
160
|
-
raise Error,
|
160
|
+
raise Error, "Service id has to be unique."
|
161
161
|
end
|
162
162
|
service_ids << service[:id]
|
163
163
|
|
164
164
|
unless service[:type].is_a?(String)
|
165
165
|
raise Error, "Service type #{service[:type]} is incorrect."
|
166
166
|
end
|
167
|
-
raise Error,
|
167
|
+
raise Error, "Service type too long." if service[:type].length > 30
|
168
168
|
|
169
169
|
endpoint = service[:serviceEndpoint]
|
170
170
|
if endpoint.instance_of?(String)
|
171
171
|
validate_uri!(endpoint)
|
172
172
|
elsif endpoint.instance_of?(Hash)
|
173
|
-
|
174
173
|
else
|
175
|
-
raise Error,
|
174
|
+
raise Error, "ServiceEndpoint must be string or object."
|
176
175
|
end
|
177
176
|
end
|
178
177
|
end
|
@@ -196,10 +195,10 @@ module Sidetree
|
|
196
195
|
end
|
197
196
|
|
198
197
|
def validate_id!(id)
|
199
|
-
raise Error,
|
200
|
-
raise Error,
|
198
|
+
raise Error, "id does not string." unless id.instance_of?(String)
|
199
|
+
raise Error, "id is too long." if id.length > 50
|
201
200
|
unless valid_base64_encoding?(id)
|
202
|
-
raise Error,
|
201
|
+
raise Error, "id does not use base64url character set."
|
203
202
|
end
|
204
203
|
end
|
205
204
|
|
@@ -218,7 +217,7 @@ module Sidetree
|
|
218
217
|
|
219
218
|
def validate_did_type!(type)
|
220
219
|
return unless type
|
221
|
-
raise Error,
|
220
|
+
raise Error, "DID type must be a string." unless type.instance_of?(String)
|
222
221
|
if type.length > 4
|
223
222
|
raise Error,
|
224
223
|
"DID type string '#{type}' cannot be longer than 4 characters."
|
@@ -231,19 +230,19 @@ module Sidetree
|
|
231
230
|
|
232
231
|
def validate_suffix_data!(suffix)
|
233
232
|
if suffix.instance_of?(Array)
|
234
|
-
raise Error,
|
233
|
+
raise Error, "Suffix data can not be an array."
|
235
234
|
end
|
236
235
|
suffix.keys.each do |k|
|
237
236
|
unless %w[deltaHash recoveryCommitment type].include?(k.to_s)
|
238
237
|
raise Error, "Property '#{k}' is not allowed in publicKeys object."
|
239
238
|
end
|
240
239
|
end
|
241
|
-
validate_encoded_multi_hash!(suffix[:deltaHash],
|
240
|
+
validate_encoded_multi_hash!(suffix[:deltaHash], "delta hash")
|
242
241
|
validate_encoded_multi_hash!(
|
243
242
|
suffix[:recoveryCommitment],
|
244
|
-
|
243
|
+
"recovery commitment"
|
245
244
|
)
|
246
|
-
validate_encoded_multi_hash!(suffix[:deltaHash],
|
245
|
+
validate_encoded_multi_hash!(suffix[:deltaHash], "delta hash")
|
247
246
|
validate_did_type!(suffix[:type])
|
248
247
|
end
|
249
248
|
end
|
data/lib/sidetree/version.rb
CHANGED
data/lib/sidetree.rb
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
3
|
+
require_relative "sidetree/version"
|
4
|
+
require "ecdsa"
|
5
|
+
require "json/jwt"
|
6
|
+
require "base64"
|
7
|
+
require "json"
|
8
|
+
require "json/canonicalization"
|
9
|
+
require "uri"
|
10
|
+
require "multihashes"
|
11
11
|
|
12
12
|
module Sidetree
|
13
13
|
class Error < StandardError
|
14
14
|
end
|
15
15
|
|
16
|
-
autoload :Key,
|
17
|
-
autoload :DID,
|
18
|
-
autoload :Model,
|
19
|
-
autoload :OP,
|
20
|
-
autoload :Validator,
|
16
|
+
autoload :Key, "sidetree/key"
|
17
|
+
autoload :DID, "sidetree/did"
|
18
|
+
autoload :Model, "sidetree/model"
|
19
|
+
autoload :OP, "sidetree/op"
|
20
|
+
autoload :Validator, "sidetree/validator"
|
21
21
|
|
22
22
|
module Params
|
23
23
|
# Algorithm for generating hashes of protocol-related values. 0x12 = sha2-256
|
24
24
|
HASH_ALGORITHM = [0x12]
|
25
|
-
HASH_ALGORITH_STRING =
|
25
|
+
HASH_ALGORITH_STRING = "sha2-256"
|
26
26
|
|
27
27
|
# Maximum canonicalized operation delta buffer size.
|
28
28
|
MAX_DELTA_SIZE = 1000
|
29
29
|
|
30
30
|
# Default DID method
|
31
|
-
DEFAULT_METHOD =
|
31
|
+
DEFAULT_METHOD = "sidetree"
|
32
32
|
|
33
33
|
# Supported did methods.
|
34
|
-
METHODS = { default: DEFAULT_METHOD, ion:
|
34
|
+
METHODS = { default: DEFAULT_METHOD, ion: "ion" }
|
35
35
|
|
36
36
|
@network = nil
|
37
37
|
|
@@ -48,8 +48,8 @@ module Sidetree
|
|
48
48
|
end
|
49
49
|
|
50
50
|
module Network
|
51
|
-
MAINNET =
|
52
|
-
TESTNET =
|
51
|
+
MAINNET = "mainnet"
|
52
|
+
TESTNET = "test"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
data/sidetree.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = 'Ruby implementation for Sidetree protocol.'
|
13
13
|
spec.homepage = 'https://github.com/azuchi/sidetreerb'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = '>= 2.
|
15
|
+
spec.required_ruby_version = '>= 2.7.0'
|
16
16
|
|
17
17
|
spec.metadata['homepage_uri'] = spec.homepage
|
18
18
|
spec.metadata['source_code_uri'] = spec.homepage
|
@@ -35,10 +35,9 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.add_dependency 'json-jwt', '~> 1.13.0'
|
36
36
|
spec.add_dependency 'json-canonicalization', '~> 0.3.0'
|
37
37
|
spec.add_dependency 'multihashes', '~> 0.2.0'
|
38
|
-
spec.add_runtime_dependency 'thor'
|
39
38
|
|
40
39
|
# For more information and examples about making a new gem, checkout our
|
41
40
|
# guide at: https://bundler.io/guides/creating_gem.html
|
42
41
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
43
|
-
spec.add_development_dependency 'prettier'
|
42
|
+
spec.add_development_dependency 'prettier', '~> 3.1.2'
|
44
43
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidetree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ecdsa
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.2.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: thor
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rspec
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,21 +84,20 @@ dependencies:
|
|
98
84
|
name: prettier
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
89
|
+
version: 3.1.2
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
96
|
+
version: 3.1.2
|
111
97
|
description: Ruby implementation for Sidetree protocol.
|
112
98
|
email:
|
113
99
|
- azuchi@chaintope.com
|
114
|
-
executables:
|
115
|
-
- ion
|
100
|
+
executables: []
|
116
101
|
extensions: []
|
117
102
|
extra_rdoc_files: []
|
118
103
|
files:
|
@@ -130,7 +115,6 @@ files:
|
|
130
115
|
- Rakefile
|
131
116
|
- bin/console
|
132
117
|
- bin/setup
|
133
|
-
- exe/ion
|
134
118
|
- lib/sidetree.rb
|
135
119
|
- lib/sidetree/did.rb
|
136
120
|
- lib/sidetree/key.rb
|
@@ -142,6 +126,8 @@ files:
|
|
142
126
|
- lib/sidetree/op.rb
|
143
127
|
- lib/sidetree/op/base.rb
|
144
128
|
- lib/sidetree/op/create.rb
|
129
|
+
- lib/sidetree/op/deactivate.rb
|
130
|
+
- lib/sidetree/op/recover.rb
|
145
131
|
- lib/sidetree/validator.rb
|
146
132
|
- lib/sidetree/version.rb
|
147
133
|
- sidetree.gemspec
|
@@ -160,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
146
|
requirements:
|
161
147
|
- - ">="
|
162
148
|
- !ruby/object:Gem::Version
|
163
|
-
version: 2.
|
149
|
+
version: 2.7.0
|
164
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
151
|
requirements:
|
166
152
|
- - ">="
|
data/exe/ion
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'thor'
|
3
|
-
require 'sidetree'
|
4
|
-
|
5
|
-
class ION < Thor
|
6
|
-
class << self
|
7
|
-
def exit_on_failure?
|
8
|
-
true
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
desc 'create', 'Create ION DID.'
|
13
|
-
def create
|
14
|
-
recovery_key = Sidetree::Key.generate
|
15
|
-
update_key = Sidetree::Key.generate
|
16
|
-
signing_key = Sidetree::Key.generate(id: 'signing-key')
|
17
|
-
document = Sidetree::Model::Document.new(public_keys: [signing_key])
|
18
|
-
did = Sidetree::DID.create(document, update_key, recovery_key, method: Sidetree::Params::METHODS[:ion])
|
19
|
-
|
20
|
-
puts "DID: #{did.short_form}"
|
21
|
-
puts
|
22
|
-
puts "Recovery key: #{recovery_key.encoded_private_key}"
|
23
|
-
puts "Update key: #{update_key.encoded_private_key}"
|
24
|
-
puts "Signing key: #{signing_key.encoded_private_key}"
|
25
|
-
puts
|
26
|
-
|
27
|
-
puts "Long-Form DID: #{did.to_s}"
|
28
|
-
op = did.create_op
|
29
|
-
puts "DID suffix data: #{op.suffix.to_h.to_json}"
|
30
|
-
puts "Document delta: #{op.delta.to_h.to_json}"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
ION.start(ARGV)
|