@smartledger/bsv 9.0.0 → 9.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.
- package/CHANGELOG.md +164 -0
- package/README.md +152 -1041
- package/STABILITY.md +134 -0
- package/bsv-gdaf.min.js +53 -48
- package/bsv-ltp.min.js +23 -18
- package/bsv-smartcontract.min.js +18 -18
- package/bsv.bundle.js +53 -48
- package/bsv.min.js +53 -48
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/docs/proposals/10.0.0-package-split.md +131 -0
- package/index.js +5 -0
- package/lib/block/merkleblock.js +53 -9
- package/lib/hdprivatekey.js +15 -0
- package/lib/script/interpreter.js +109 -1
- package/lib/smart_contract/builder.js +14 -0
- package/lib/util/deprecate.js +159 -0
- package/package.json +19 -82
- package/version.js +1 -1
- package/.mocharc.json +0 -5
- package/test/address.js +0 -629
- package/test/block/block.js +0 -239
- package/test/block/blockheader.js +0 -270
- package/test/block/merkleblock.js +0 -207
- package/test/build/bundle_crypto_shim.js +0 -104
- package/test/build/bundle_externals.js +0 -125
- package/test/build/bundle_smoke.js +0 -55
- package/test/build/esbuild_main.js +0 -65
- package/test/build/esm_wrapper.js +0 -97
- package/test/build/exports_resolution.js +0 -84
- package/test/build/version_sync.js +0 -14
- package/test/cli/smoke.js +0 -261
- package/test/consensus/base58-vectors.js +0 -120
- package/test/consensus/sv-script-vectors.js +0 -81
- package/test/consensus/sv-sighash-vectors.js +0 -51
- package/test/consensus/sv-tx-vectors.js +0 -48
- package/test/credentials-test.js +0 -332
- package/test/crypto/backend_selection.js +0 -126
- package/test/crypto/bn.js +0 -168
- package/test/crypto/ecdsa.js +0 -426
- package/test/crypto/elliptic-fixed.js +0 -61
- package/test/crypto/hash.browser.js +0 -121
- package/test/crypto/hash.js +0 -122
- package/test/crypto/point.js +0 -193
- package/test/crypto/random.js +0 -105
- package/test/crypto/security.js +0 -176
- package/test/crypto/shamir.js +0 -177
- package/test/crypto/shamir_rngcap.js +0 -29
- package/test/crypto/signature.js +0 -399
- package/test/data/bip69.json +0 -215
- package/test/data/bitcoin-sv/README.md +0 -170
- package/test/data/bitcoin-sv/base58_encode_decode.json +0 -14
- package/test/data/bitcoin-sv/base58_keys_invalid.json +0 -152
- package/test/data/bitcoin-sv/base58_keys_valid.json +0 -452
- package/test/data/bitcoin-sv/script_tests.json +0 -2591
- package/test/data/bitcoin-sv/sighash.json +0 -1003
- package/test/data/bitcoin-sv/tx_invalid.json +0 -285
- package/test/data/bitcoin-sv/tx_valid.json +0 -367
- package/test/data/bitcoind/base58_keys_invalid.json +0 -152
- package/test/data/bitcoind/base58_keys_valid.json +0 -452
- package/test/data/bitcoind/blocks.json +0 -27
- package/test/data/bitcoind/script_tests.json +0 -2244
- package/test/data/bitcoind/sig_canonical.json +0 -7
- package/test/data/bitcoind/sig_noncanonical.json +0 -22
- package/test/data/bitcoind/tx_invalid.json +0 -177
- package/test/data/bitcoind/tx_valid.json +0 -224
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +0 -12
- package/test/data/blk86756-testnet.json +0 -684
- package/test/data/brc220-batch-vector.json +0 -129
- package/test/data/ecdsa.json +0 -230
- package/test/data/merkleblocks.js +0 -486
- package/test/data/messages.json +0 -22
- package/test/data/sighash.json +0 -1004
- package/test/data/tx_creation.json +0 -85
- package/test/didweb/relationships.js +0 -144
- package/test/ecies/bitcore-ecies.js +0 -178
- package/test/ecies/electrum-ecies.js +0 -206
- package/test/encoding/base58.js +0 -131
- package/test/encoding/base58check.js +0 -145
- package/test/encoding/bufferreader.js +0 -328
- package/test/encoding/bufferwriter.js +0 -160
- package/test/encoding/varint.js +0 -104
- package/test/gdaf/anchor_no_key_leak.js +0 -146
- package/test/gdaf/anchor_spv.js +0 -163
- package/test/gdaf/canonicalization.js +0 -106
- package/test/gdaf/canonicalize.js +0 -140
- package/test/gdaf/zk_prover.js +0 -204
- package/test/hdkeys.js +0 -365
- package/test/hdprivatekey.js +0 -339
- package/test/hdpublickey.js +0 -293
- package/test/index.js +0 -16
- package/test/ltp/ids.js +0 -74
- package/test/ltp/right.js +0 -198
- package/test/ltp/verify_failclosed.js +0 -134
- package/test/message/message.js +0 -190
- package/test/mnemonic/data/fixtures.json +0 -300
- package/test/mnemonic/mnemonic.js +0 -277
- package/test/mnemonic/mocha.opts +0 -1
- package/test/mnemonic/pbkdf2.test.js +0 -43
- package/test/networks.js +0 -207
- package/test/notaryhash/batch_leaf.js +0 -140
- package/test/notaryhash/batch_vector.js +0 -282
- package/test/notaryhash/certificate.js +0 -249
- package/test/notaryhash/encoding.js +0 -186
- package/test/notaryhash/interop.js +0 -112
- package/test/notaryhash/merkle.js +0 -181
- package/test/notaryhash/script.js +0 -270
- package/test/notaryhash/verify.js +0 -342
- package/test/opcode.js +0 -186
- package/test/ordinals/bsv20.js +0 -337
- package/test/ordinals/inscription.js +0 -329
- package/test/ordinals/ordlock.js +0 -567
- package/test/privatekey.js +0 -540
- package/test/publickey.js +0 -411
- package/test/regressions.js +0 -215
- package/test/script/chronicle.js +0 -543
- package/test/script/defaults.js +0 -160
- package/test/script/genesis_limits.js +0 -203
- package/test/script/interpreter.js +0 -776
- package/test/script/script.js +0 -1259
- package/test/script/string_ops.js +0 -88
- package/test/security/fail_closed_contracts.js +0 -104
- package/test/security/threat_model_coverage.js +0 -31
- package/test/smart_contract/covenants.js +0 -207
- package/test/smart_contract/dsl_debugger.js +0 -92
- package/test/smart_contract/extract_field.js +0 -61
- package/test/smart_contract/nonenforcing_guard.js +0 -44
- package/test/smart_contract/ordinal_transfer.js +0 -71
- package/test/smart_contract/preimage.js +0 -98
- package/test/smart_contract/sighash_marketplace.js +0 -98
- package/test/smart_contract/token_generalized.js +0 -175
- package/test/spv/headerchain.js +0 -86
- package/test/spv/merkleproof.js +0 -133
- package/test/statuslist/failclosed.js +0 -78
- package/test/transaction/deserialize.js +0 -33
- package/test/transaction/input/input.js +0 -92
- package/test/transaction/input/multisig.js +0 -174
- package/test/transaction/input/multisigscripthash.js +0 -111
- package/test/transaction/input/publickey.js +0 -68
- package/test/transaction/input/publickeyhash.js +0 -59
- package/test/transaction/output.js +0 -185
- package/test/transaction/sighash.js +0 -91
- package/test/transaction/signature.js +0 -127
- package/test/transaction/transaction.js +0 -1299
- package/test/transaction/unspentoutput.js +0 -97
- package/test/types/dts_drift.js +0 -124
- package/test/types/surface_honesty.js +0 -102
- package/test/util/id.js +0 -72
- package/test/util/js.js +0 -76
- package/test/util/preconditions.js +0 -79
- package/test/vcjwt/interop.js +0 -126
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var bsv = require('../..')
|
|
4
|
-
var should = require('chai').should()
|
|
5
|
-
var BufferWriter = bsv.encoding.BufferWriter
|
|
6
|
-
var BufferReader = bsv.encoding.BufferReader
|
|
7
|
-
var BN = bsv.crypto.BN
|
|
8
|
-
|
|
9
|
-
describe('BufferWriter', function () {
|
|
10
|
-
it('should create a new buffer writer', function () {
|
|
11
|
-
var bw = new BufferWriter()
|
|
12
|
-
should.exist(bw)
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe('#set', function () {
|
|
16
|
-
it('set bufs', function () {
|
|
17
|
-
var buf1 = Buffer.from([0])
|
|
18
|
-
var buf2 = Buffer.from([1])
|
|
19
|
-
var bw = new BufferWriter().set({ bufs: [buf1, buf2] })
|
|
20
|
-
bw.concat().toString('hex').should.equal('0001')
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
describe('#toBuffer', function () {
|
|
25
|
-
it('should concat these two bufs', function () {
|
|
26
|
-
var buf1 = Buffer.from([0])
|
|
27
|
-
var buf2 = Buffer.from([1])
|
|
28
|
-
var bw = new BufferWriter({ bufs: [buf1, buf2] })
|
|
29
|
-
bw.toBuffer().toString('hex').should.equal('0001')
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
describe('#concat', function () {
|
|
34
|
-
it('should concat these two bufs', function () {
|
|
35
|
-
var buf1 = Buffer.from([0])
|
|
36
|
-
var buf2 = Buffer.from([1])
|
|
37
|
-
var bw = new BufferWriter({ bufs: [buf1, buf2] })
|
|
38
|
-
bw.concat().toString('hex').should.equal('0001')
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
describe('#write', function () {
|
|
43
|
-
it('should write a buffer', function () {
|
|
44
|
-
var buf = Buffer.from([0])
|
|
45
|
-
var bw = new BufferWriter()
|
|
46
|
-
bw.write(buf)
|
|
47
|
-
bw.concat().toString('hex').should.equal('00')
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
describe('#writeUInt8', function () {
|
|
52
|
-
it('should write 1', function () {
|
|
53
|
-
var bw = new BufferWriter()
|
|
54
|
-
bw.writeUInt8(1).concat().toString('hex').should.equal('01')
|
|
55
|
-
})
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
describe('#writeUInt16BE', function () {
|
|
59
|
-
it('should write 1', function () {
|
|
60
|
-
var bw = new BufferWriter()
|
|
61
|
-
bw.writeUInt16BE(1).concat().toString('hex').should.equal('0001')
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
describe('#writeUInt16LE', function () {
|
|
66
|
-
it('should write 1', function () {
|
|
67
|
-
var bw = new BufferWriter()
|
|
68
|
-
bw.writeUInt16LE(1).concat().toString('hex').should.equal('0100')
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
describe('#writeUInt32BE', function () {
|
|
73
|
-
it('should write 1', function () {
|
|
74
|
-
var bw = new BufferWriter()
|
|
75
|
-
bw.writeUInt32BE(1).concat().toString('hex').should.equal('00000001')
|
|
76
|
-
})
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
describe('#writeUInt32LE', function () {
|
|
80
|
-
it('should write 1', function () {
|
|
81
|
-
var bw = new BufferWriter()
|
|
82
|
-
bw.writeUInt32LE(1).concat().toString('hex').should.equal('01000000')
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
describe('#writeUInt64BEBN', function () {
|
|
87
|
-
it('should write 1', function () {
|
|
88
|
-
var bw = new BufferWriter()
|
|
89
|
-
bw.writeUInt64BEBN(new BN(1)).concat().toString('hex').should.equal('0000000000000001')
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
describe('#writeUInt64LEBN', function () {
|
|
94
|
-
it('should write 1', function () {
|
|
95
|
-
var bw = new BufferWriter()
|
|
96
|
-
bw.writeUInt64LEBN(new BN(1)).concat().toString('hex').should.equal('0100000000000000')
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
describe('#writeVarint', function () {
|
|
101
|
-
it('should write a 1 byte varint', function () {
|
|
102
|
-
var bw = new BufferWriter()
|
|
103
|
-
bw.writeVarintNum(1)
|
|
104
|
-
bw.concat().length.should.equal(1)
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
it('should write a 3 byte varint', function () {
|
|
108
|
-
var bw = new BufferWriter()
|
|
109
|
-
bw.writeVarintNum(1000)
|
|
110
|
-
bw.concat().length.should.equal(3)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('should write a 5 byte varint', function () {
|
|
114
|
-
var bw = new BufferWriter()
|
|
115
|
-
bw.writeVarintNum(Math.pow(2, 16 + 1))
|
|
116
|
-
bw.concat().length.should.equal(5)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
it('should write a 9 byte varint', function () {
|
|
120
|
-
var bw = new BufferWriter()
|
|
121
|
-
bw.writeVarintNum(Math.pow(2, 32 + 1))
|
|
122
|
-
bw.concat().length.should.equal(9)
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
it('should read back the same value it wrote for a 9 byte varint', function () {
|
|
126
|
-
var bw = new BufferWriter()
|
|
127
|
-
var n = Math.pow(2, 53)
|
|
128
|
-
n.should.equal(n + 1) // javascript number precision limit
|
|
129
|
-
bw.writeVarintNum(n)
|
|
130
|
-
var br = new BufferReader({ buf: bw.concat() })
|
|
131
|
-
br.readVarintBN().toNumber().should.equal(n)
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
describe('#writeVarintBN', function () {
|
|
136
|
-
it('should write a 1 byte varint', function () {
|
|
137
|
-
var bw = new BufferWriter()
|
|
138
|
-
bw.writeVarintBN(new BN(1))
|
|
139
|
-
bw.concat().length.should.equal(1)
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('should write a 3 byte varint', function () {
|
|
143
|
-
var bw = new BufferWriter()
|
|
144
|
-
bw.writeVarintBN(new BN(1000))
|
|
145
|
-
bw.concat().length.should.equal(3)
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('should write a 5 byte varint', function () {
|
|
149
|
-
var bw = new BufferWriter()
|
|
150
|
-
bw.writeVarintBN(new BN(Math.pow(2, 16 + 1)))
|
|
151
|
-
bw.concat().length.should.equal(5)
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
it('should write a 9 byte varint', function () {
|
|
155
|
-
var bw = new BufferWriter()
|
|
156
|
-
bw.writeVarintBN(new BN(Math.pow(2, 32 + 1)))
|
|
157
|
-
bw.concat().length.should.equal(9)
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
})
|
package/test/encoding/varint.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var should = require('chai').should()
|
|
4
|
-
var bsv = require('../..')
|
|
5
|
-
var BN = bsv.crypto.BN
|
|
6
|
-
var BufferReader = bsv.encoding.BufferReader
|
|
7
|
-
var BufferWriter = bsv.encoding.BufferWriter
|
|
8
|
-
var Varint = bsv.encoding.Varint
|
|
9
|
-
|
|
10
|
-
describe('Varint', function () {
|
|
11
|
-
it('should make a new varint', function () {
|
|
12
|
-
var buf = Buffer.from('00', 'hex')
|
|
13
|
-
var varint = new Varint(buf)
|
|
14
|
-
should.exist(varint)
|
|
15
|
-
varint.buf.toString('hex').should.equal('00')
|
|
16
|
-
varint = Varint(buf)
|
|
17
|
-
should.exist(varint)
|
|
18
|
-
varint.buf.toString('hex').should.equal('00')
|
|
19
|
-
|
|
20
|
-
// various ways to use the constructor
|
|
21
|
-
Varint(Varint(0).toBuffer()).toNumber().should.equal(0)
|
|
22
|
-
Varint(0).toNumber().should.equal(0)
|
|
23
|
-
Varint(new BN(0)).toNumber().should.equal(0)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
describe('#set', function () {
|
|
27
|
-
it('should set a buffer', function () {
|
|
28
|
-
var buf = Buffer.from('00', 'hex')
|
|
29
|
-
var varint = Varint().set({ buf: buf })
|
|
30
|
-
varint.buf.toString('hex').should.equal('00')
|
|
31
|
-
varint.set({})
|
|
32
|
-
varint.buf.toString('hex').should.equal('00')
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
describe('#fromString', function () {
|
|
37
|
-
it('should set a buffer', function () {
|
|
38
|
-
var buf = BufferWriter().writeVarintNum(5).concat()
|
|
39
|
-
var varint = Varint().fromString(buf.toString('hex'))
|
|
40
|
-
varint.toNumber().should.equal(5)
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
describe('#toString', function () {
|
|
45
|
-
it('should return a buffer', function () {
|
|
46
|
-
var buf = BufferWriter().writeVarintNum(5).concat()
|
|
47
|
-
var varint = Varint().fromString(buf.toString('hex'))
|
|
48
|
-
varint.toString().should.equal('05')
|
|
49
|
-
})
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
describe('#fromBuffer', function () {
|
|
53
|
-
it('should set a buffer', function () {
|
|
54
|
-
var buf = BufferWriter().writeVarintNum(5).concat()
|
|
55
|
-
var varint = Varint().fromBuffer(buf)
|
|
56
|
-
varint.toNumber().should.equal(5)
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe('#fromBufferReader', function () {
|
|
61
|
-
it('should set a buffer reader', function () {
|
|
62
|
-
var buf = BufferWriter().writeVarintNum(5).concat()
|
|
63
|
-
var br = BufferReader(buf)
|
|
64
|
-
var varint = Varint().fromBufferReader(br)
|
|
65
|
-
varint.toNumber().should.equal(5)
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('#fromBN', function () {
|
|
70
|
-
it('should set a number', function () {
|
|
71
|
-
var varint = Varint().fromBN(new BN(5))
|
|
72
|
-
varint.toNumber().should.equal(5)
|
|
73
|
-
})
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
describe('#fromNumber', function () {
|
|
77
|
-
it('should set a number', function () {
|
|
78
|
-
var varint = Varint().fromNumber(5)
|
|
79
|
-
varint.toNumber().should.equal(5)
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
describe('#toBuffer', function () {
|
|
84
|
-
it('should return a buffer', function () {
|
|
85
|
-
var buf = BufferWriter().writeVarintNum(5).concat()
|
|
86
|
-
var varint = Varint(buf)
|
|
87
|
-
varint.toBuffer().toString('hex').should.equal(buf.toString('hex'))
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
describe('#toBN', function () {
|
|
92
|
-
it('should return a buffer', function () {
|
|
93
|
-
var varint = Varint(5)
|
|
94
|
-
varint.toBN().toString().should.equal(new BN(5).toString())
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
describe('#toNumber', function () {
|
|
99
|
-
it('should return a buffer', function () {
|
|
100
|
-
var varint = Varint(5)
|
|
101
|
-
varint.toNumber().should.equal(5)
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
})
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
// The GDAF anchoring wrappers take (payload, privateKey, options) while the underlying
|
|
6
|
-
// SmartLedgerAnchor methods take (payload, metadata, utxos). Every wrapper forwarded
|
|
7
|
-
// `privateKey` into a slot that is not a key. For anchorCredential/anchorBatch it landed
|
|
8
|
-
// in `metadata`, which is JSON.stringify-ed straight into the OP_RETURN — so the secret
|
|
9
|
-
// scalar was broadcast, and the key was recoverable from chain data with an identical WIF.
|
|
10
|
-
|
|
11
|
-
require('chai').should()
|
|
12
|
-
var bsv = require('../..')
|
|
13
|
-
|
|
14
|
-
describe('GDAF anchoring never publishes key material', function () {
|
|
15
|
-
var key = bsv.PrivateKey.fromBuffer(Buffer.alloc(32, 7))
|
|
16
|
-
var utxos = [{
|
|
17
|
-
txId: '11'.repeat(32),
|
|
18
|
-
outputIndex: 0,
|
|
19
|
-
script: bsv.Script.buildPublicKeyHashOut(key.toAddress()).toHex(),
|
|
20
|
-
satoshis: 100000
|
|
21
|
-
}]
|
|
22
|
-
var HASH = 'ab'.repeat(32)
|
|
23
|
-
|
|
24
|
-
function gdaf () { return new bsv.GDAF() }
|
|
25
|
-
|
|
26
|
-
// Pull every OP_RETURN payload out of a built transaction, as UTF-8.
|
|
27
|
-
function payloadsOf (result) {
|
|
28
|
-
var tx = new bsv.Transaction((result.transaction || result.tx || result).toString())
|
|
29
|
-
return tx.outputs.map(function (o) {
|
|
30
|
-
var asm = o.script.toASM().split(' ')
|
|
31
|
-
return Buffer.from(asm[asm.length - 1], 'hex').toString('utf8')
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function assertNoSecret (result) {
|
|
36
|
-
var scalarHex = key.bn.toString('hex')
|
|
37
|
-
var raw = (result.transaction || result.tx || result).toString()
|
|
38
|
-
raw.indexOf(Buffer.from(scalarHex, 'utf8').toString('hex')).should.equal(-1)
|
|
39
|
-
raw.indexOf(Buffer.from('"bn"', 'utf8').toString('hex')).should.equal(-1)
|
|
40
|
-
payloadsOf(result).forEach(function (p) {
|
|
41
|
-
p.indexOf(scalarHex).should.equal(-1)
|
|
42
|
-
p.indexOf('"bn"').should.equal(-1)
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
it('anchorCredential does not put the key in the OP_RETURN', function () {
|
|
47
|
-
return gdaf().anchorCredential(HASH, key, utxos).then(assertNoSecret)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('anchorBatch does not put the key in the OP_RETURN', function () {
|
|
51
|
-
return gdaf().anchorBatch([HASH, 'cd'.repeat(32)], key, utxos).then(assertNoSecret)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('accepts the documented { utxos, metadata } options shape', function () {
|
|
55
|
-
return gdaf().anchorCredential(HASH, key, { utxos: utxos, metadata: { issuer: 'did:web:example' } })
|
|
56
|
-
.then(function (r) {
|
|
57
|
-
assertNoSecret(r)
|
|
58
|
-
// The caller's own metadata still reaches the chain.
|
|
59
|
-
payloadsOf(r).join('').indexOf('did:web:example').should.not.equal(-1)
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('still accepts a bare UTXO array, the only shape that used to work', function () {
|
|
64
|
-
return gdaf().anchorCredential(HASH, key, utxos).then(function (r) {
|
|
65
|
-
r.should.be.an('object')
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
// Defence in depth: even reaching the payload builder with key material must fail
|
|
70
|
-
// loudly rather than broadcast it.
|
|
71
|
-
it('refuses to anchor metadata containing a PrivateKey instance', function () {
|
|
72
|
-
return gdaf().anchorCredential(HASH, key, { utxos: utxos, metadata: { signer: key } })
|
|
73
|
-
.then(function () { throw new Error('should not have anchored') },
|
|
74
|
-
function (err) { err.message.should.match(/Refusing to anchor/) })
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('refuses to anchor metadata carrying a key-shaped field', function () {
|
|
78
|
-
return gdaf().anchorCredential(HASH, key, { utxos: utxos, metadata: { wif: key.toWIF() } })
|
|
79
|
-
.then(function () { throw new Error('should not have anchored') },
|
|
80
|
-
function (err) { err.message.should.match(/key material/) })
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('leaves ordinary metadata alone', function () {
|
|
84
|
-
return gdaf().anchorCredential(HASH, key, {
|
|
85
|
-
utxos: utxos, metadata: { id: 'urn:uuid:1', nested: { note: 'fine' } }
|
|
86
|
-
}).then(function (r) { assertNoSecret(r) })
|
|
87
|
-
})
|
|
88
|
-
// The guard keyed off field NAMES alone, which was wrong in both directions: it
|
|
89
|
-
// rejected `{ d: '2026-01-01' }` as key material while publishing a real WIF stored
|
|
90
|
-
// under `note`. Detection is now by value as well as name.
|
|
91
|
-
describe('detects key material by value, not just by field name', function () {
|
|
92
|
-
var Anchor = require('../../lib/gdaf/smartledger-anchor.js')
|
|
93
|
-
var other = bsv.PrivateKey.fromBuffer(Buffer.alloc(32, 99))
|
|
94
|
-
var HASH_BUF = bsv.crypto.Hash.sha256(Buffer.from('doc'))
|
|
95
|
-
|
|
96
|
-
function build (metadata) {
|
|
97
|
-
return new Anchor(key, {})._createAnchorPayload('CREDENTIAL', HASH_BUF, metadata)
|
|
98
|
-
}
|
|
99
|
-
function refuses (label, metadata) {
|
|
100
|
-
it('refuses ' + label, function () {
|
|
101
|
-
;(function () { build(metadata) }).should.throw(/Refusing to anchor/)
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
function accepts (label, metadata) {
|
|
105
|
-
it('accepts ' + label, function () {
|
|
106
|
-
var payload = Buffer.from(build(metadata)).toString('utf8')
|
|
107
|
-
payload.indexOf(key.toWIF()).should.equal(-1)
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Self-identifying secrets: the encoding says "private key" whatever the field is
|
|
112
|
-
// called. Naming a WIF `note` does not make it safe to publish.
|
|
113
|
-
refuses('a WIF under an innocuous name', { note: other.toWIF() })
|
|
114
|
-
refuses('an xprv under an innocuous name', {
|
|
115
|
-
ref: bsv.HDPrivateKey.fromSeed(Buffer.alloc(32, 1)).toString()
|
|
116
|
-
})
|
|
117
|
-
refuses('a BIP39 mnemonic under an innocuous name', {
|
|
118
|
-
memo: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
|
|
119
|
-
})
|
|
120
|
-
refuses('a secret nested in an array', { signers: [other.toWIF()] })
|
|
121
|
-
|
|
122
|
-
// The anchor's OWN key, in any representation — the exact defect this guard exists
|
|
123
|
-
// for. A bare hex scalar is otherwise indistinguishable from a hash, so knowing our
|
|
124
|
-
// own key is what makes this catchable.
|
|
125
|
-
refuses("the anchor's own key as a raw hex scalar", { backup: key.toString() })
|
|
126
|
-
refuses("the anchor's own key as a WIF", { backup: key.toWIF() })
|
|
127
|
-
|
|
128
|
-
// Ambiguous names are refused only when the value really is secret.
|
|
129
|
-
refuses('d holding a private scalar', { d: other.toString() })
|
|
130
|
-
refuses('seed holding a mnemonic', {
|
|
131
|
-
seed: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
// ...and left alone otherwise. Anchoring a document hash is the module's purpose,
|
|
135
|
-
// and a 64-hex hash cannot be told apart from a scalar, so it must not be rejected.
|
|
136
|
-
accepts('d as a date', { d: '2026-01-01' })
|
|
137
|
-
accepts('seed as a campaign name', { seed: 'spring-campaign' })
|
|
138
|
-
accepts('a SHA-256 document hash', { docHash: bsv.crypto.Hash.sha256(Buffer.from('x')).toString('hex') })
|
|
139
|
-
accepts('key used as an ordinary label', { key: 'value' })
|
|
140
|
-
|
|
141
|
-
// Public material is not secret and an anchor legitimately references it.
|
|
142
|
-
accepts('an address', { payTo: key.toAddress().toString() })
|
|
143
|
-
accepts('a public key', { pub: key.toPublicKey().toString() })
|
|
144
|
-
accepts('an xpub', { xpub: bsv.HDPrivateKey.fromSeed(Buffer.alloc(32, 1)).hdPublicKey.toString() })
|
|
145
|
-
})
|
|
146
|
-
})
|
package/test/gdaf/anchor_spv.js
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
// Trustless SPV anchor verification end-to-end: build a real anchoring tx with an
|
|
6
|
-
// OP_RETURN commitment, place it in a block, prove its inclusion with a Merkle
|
|
7
|
-
// branch + header, and verify through SmartLedgerAnchor.verifyAnchor with NO trusted
|
|
8
|
-
// provider. Replaces the old {verified:true} stub / trust-the-caller-txData path.
|
|
9
|
-
|
|
10
|
-
require('chai').should()
|
|
11
|
-
var bsv = require('../..')
|
|
12
|
-
var Anchor = require('../../lib/gdaf/smartledger-anchor')
|
|
13
|
-
var Hash = bsv.crypto.Hash
|
|
14
|
-
|
|
15
|
-
function rev (b) { return Buffer.from(b).reverse() }
|
|
16
|
-
function buildTree (leaves) {
|
|
17
|
-
var tree = leaves.slice(); var j = 0
|
|
18
|
-
for (var size = leaves.length; size > 1; size = Math.floor((size + 1) / 2)) {
|
|
19
|
-
for (var i = 0; i < size; i += 2) {
|
|
20
|
-
var i2 = Math.min(i + 1, size - 1)
|
|
21
|
-
tree.push(Hash.sha256sha256(Buffer.concat([tree[j + i], tree[j + i2]])))
|
|
22
|
-
}
|
|
23
|
-
j += size
|
|
24
|
-
}
|
|
25
|
-
return tree
|
|
26
|
-
}
|
|
27
|
-
function rootOf (l) { var t = buildTree(l); return t[t.length - 1] }
|
|
28
|
-
function branchFor (leaves, index) {
|
|
29
|
-
var tree = buildTree(leaves); var branch = []; var j = 0; var idx = index
|
|
30
|
-
for (var size = leaves.length; size > 1; size = Math.floor((size + 1) / 2)) {
|
|
31
|
-
var sib = idx ^ 1; if (sib >= size) sib = idx
|
|
32
|
-
branch.push(rev(tree[j + sib]).toString('hex'))
|
|
33
|
-
j += size; idx = Math.floor(idx / 2)
|
|
34
|
-
}
|
|
35
|
-
return branch
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function anchorTxFor (hashHex) {
|
|
39
|
-
var tx = new bsv.Transaction()
|
|
40
|
-
tx.addOutput(new bsv.Transaction.Output({
|
|
41
|
-
script: bsv.Script.buildDataOut(Buffer.from(hashHex, 'hex')),
|
|
42
|
-
satoshis: 0
|
|
43
|
-
}))
|
|
44
|
-
return tx
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function blockOf (rootInternal) {
|
|
48
|
-
return new bsv.BlockHeader({
|
|
49
|
-
version: 1, prevHash: Buffer.alloc(32), merkleRoot: rootInternal,
|
|
50
|
-
time: 1231006505, bits: 0x1d00ffff, nonce: 0
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// "Mine" a regtest-difficulty header (PoW passes after trivial nonce grinding).
|
|
55
|
-
function minedHeader (prevHashInternal, merkleInternal) {
|
|
56
|
-
for (var nonce = 0; nonce < 100000; nonce++) {
|
|
57
|
-
var h = new bsv.BlockHeader({
|
|
58
|
-
version: 1, prevHash: prevHashInternal, merkleRoot: merkleInternal,
|
|
59
|
-
time: 1231006505 + nonce, bits: 0x207fffff, nonce: nonce
|
|
60
|
-
})
|
|
61
|
-
if (h.validProofOfWork()) return h
|
|
62
|
-
}
|
|
63
|
-
throw new Error('could not mine header')
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
describe('SPV anchor verification (trustless)', function () {
|
|
67
|
-
var anchorHash = Hash.sha256(Buffer.from('anchor me')).toString('hex')
|
|
68
|
-
var atx = anchorTxFor(anchorHash)
|
|
69
|
-
var rawTx = atx.uncheckedSerialize()
|
|
70
|
-
var txid = atx.hash
|
|
71
|
-
// Place the anchor tx at index 2 among 5 leaves.
|
|
72
|
-
var leaves = [
|
|
73
|
-
bsv.crypto.Random.getRandomBuffer(32),
|
|
74
|
-
bsv.crypto.Random.getRandomBuffer(32),
|
|
75
|
-
atx._getHash(),
|
|
76
|
-
bsv.crypto.Random.getRandomBuffer(32),
|
|
77
|
-
bsv.crypto.Random.getRandomBuffer(32)
|
|
78
|
-
]
|
|
79
|
-
var header = blockOf(rootOf(leaves))
|
|
80
|
-
var spvProof = { index: 2, nodes: branchFor(leaves, 2) }
|
|
81
|
-
|
|
82
|
-
it('verifies inclusion + commitment with a valid proof', async function () {
|
|
83
|
-
var res = await Anchor.verifyAnchor(txid, anchorHash, {
|
|
84
|
-
spvProof: spvProof, header: header, rawTx: rawTx, requirePow: false
|
|
85
|
-
})
|
|
86
|
-
res.verified.should.equal(true)
|
|
87
|
-
res.chainVerified.should.equal(true)
|
|
88
|
-
res.committed.should.equal(true)
|
|
89
|
-
res.txidBound.should.equal(true)
|
|
90
|
-
res.proof.type.should.equal('spv_merkle_inclusion')
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
it('rejects when the tx does not commit to the expected hash', async function () {
|
|
94
|
-
var otherHash = Hash.sha256(Buffer.from('something else')).toString('hex')
|
|
95
|
-
var res = await Anchor.verifyAnchor(txid, otherHash, {
|
|
96
|
-
spvProof: spvProof, header: header, rawTx: rawTx, requirePow: false
|
|
97
|
-
})
|
|
98
|
-
res.committed.should.equal(false)
|
|
99
|
-
res.verified.should.equal(false)
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('rejects a tampered Merkle branch (inclusion fails)', async function () {
|
|
103
|
-
var bad = { index: 2, nodes: branchFor(leaves, 2).slice() }
|
|
104
|
-
bad.nodes[0] = rev(bsv.crypto.Random.getRandomBuffer(32)).toString('hex')
|
|
105
|
-
var res = await Anchor.verifyAnchor(txid, anchorHash, {
|
|
106
|
-
spvProof: bad, header: header, rawTx: rawTx, requirePow: false
|
|
107
|
-
})
|
|
108
|
-
res.chainVerified.should.equal(false)
|
|
109
|
-
res.verified.should.equal(false)
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
it('rejects rawTx that does not hash to txid', async function () {
|
|
113
|
-
var otherRaw = anchorTxFor(Hash.sha256(Buffer.from('decoy')).toString('hex')).uncheckedSerialize()
|
|
114
|
-
var res = await Anchor.verifyAnchor(txid, anchorHash, {
|
|
115
|
-
spvProof: spvProof, header: header, rawTx: otherRaw, requirePow: false
|
|
116
|
-
})
|
|
117
|
-
res.txidBound.should.equal(false)
|
|
118
|
-
res.verified.should.equal(false)
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('still refuses to fabricate a result with neither an SPV proof nor a provider', async function () {
|
|
122
|
-
var threw = false
|
|
123
|
-
try { await Anchor.verifyAnchor(txid, anchorHash, {}) } catch (e) { threw = true }
|
|
124
|
-
threw.should.equal(true)
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
describe('with a header chain (confirmations under real PoW)', function () {
|
|
128
|
-
this.timeout(10000)
|
|
129
|
-
// Block containing the tx must carry the real merkle root; then descendants.
|
|
130
|
-
var h0 = minedHeader(Buffer.alloc(32), rootOf(leaves))
|
|
131
|
-
var h1 = minedHeader(h0._getHash(), bsv.crypto.Random.getRandomBuffer(32))
|
|
132
|
-
var h2 = minedHeader(h1._getHash(), bsv.crypto.Random.getRandomBuffer(32))
|
|
133
|
-
var headerChain = [h0, h1, h2]
|
|
134
|
-
|
|
135
|
-
it('verifies inclusion + 3 confirmations under real proof-of-work', async function () {
|
|
136
|
-
var res = await Anchor.verifyAnchor(txid, anchorHash, {
|
|
137
|
-
spvProof: spvProof, headerChain: headerChain, rawTx: rawTx, minConfirmations: 3
|
|
138
|
-
})
|
|
139
|
-
res.verified.should.equal(true)
|
|
140
|
-
res.confirmations.should.equal(3)
|
|
141
|
-
res.headerChainValid.should.equal(true)
|
|
142
|
-
res.powValid.should.equal(true)
|
|
143
|
-
res.tipHash.should.equal(h2.id)
|
|
144
|
-
res.proof.type.should.equal('spv_merkle_inclusion_with_confirmations')
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
it('rejects when confirmations are below the required minimum', async function () {
|
|
148
|
-
var res = await Anchor.verifyAnchor(txid, anchorHash, {
|
|
149
|
-
spvProof: spvProof, headerChain: headerChain, rawTx: rawTx, minConfirmations: 6
|
|
150
|
-
})
|
|
151
|
-
res.confirmations.should.equal(3)
|
|
152
|
-
res.verified.should.equal(false)
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
it('rejects a header chain with a broken link', async function () {
|
|
156
|
-
var res = await Anchor.verifyAnchor(txid, anchorHash, {
|
|
157
|
-
spvProof: spvProof, headerChain: [h0, h2], rawTx: rawTx, minConfirmations: 1
|
|
158
|
-
})
|
|
159
|
-
res.headerChainValid.should.equal(false)
|
|
160
|
-
res.verified.should.equal(false)
|
|
161
|
-
})
|
|
162
|
-
})
|
|
163
|
-
})
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
// GDAF signs a hash of canonical JSON, so the canonicalization IS part of the signature
|
|
6
|
-
// scheme. It was sorted-key JSON that rebuilt the object, which loses the sort: V8 orders
|
|
7
|
-
// integer-like own properties numerically, ahead of string keys, whatever order they were
|
|
8
|
-
// inserted in.
|
|
9
|
-
//
|
|
10
|
-
// Within this library that was deterministic — signing and verification agreed, and no
|
|
11
|
-
// forgery followed. Across implementations it was a verification failure, which for
|
|
12
|
-
// credentials that exist to be checked by other parties is the thing that matters.
|
|
13
|
-
|
|
14
|
-
require('chai').should()
|
|
15
|
-
var Signer = require('../../lib/gdaf/attestation-signer')
|
|
16
|
-
|
|
17
|
-
describe('GDAF canonicalization', function () {
|
|
18
|
-
describe('RFC 8785 conformance', function () {
|
|
19
|
-
// The concrete divergence. JCS sorts by UTF-16 code unit, where '10' < '2'.
|
|
20
|
-
it('sorts integer-like keys lexicographically, not numerically', function () {
|
|
21
|
-
var o = {}
|
|
22
|
-
o['10'] = 'ten'
|
|
23
|
-
o['2'] = 'two'
|
|
24
|
-
Signer._canonicalizeJCS(o).should.equal('{"10":"ten","2":"two"}')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('is what the legacy form got wrong, which is why both exist', function () {
|
|
28
|
-
var o = {}
|
|
29
|
-
o['10'] = 'ten'
|
|
30
|
-
o['2'] = 'two'
|
|
31
|
-
Signer._canonicalizeJSON(o).should.equal('{"2":"two","10":"ten"}')
|
|
32
|
-
Signer._canonicalizeJCS(o).should.not.equal(Signer._canonicalizeJSON(o))
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('sorts at every depth and leaves arrays in order', function () {
|
|
36
|
-
Signer._canonicalizeJCS({ z: { b: 1, a: 2 }, a: [3, { d: 1, c: 2 }] })
|
|
37
|
-
.should.equal('{"a":[3,{"c":2,"d":1}],"z":{"a":2,"b":1}}')
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('is insensitive to key insertion order', function () {
|
|
41
|
-
var x = {}; x.b = 1; x.a = 2
|
|
42
|
-
var y = {}; y.a = 2; y.b = 1
|
|
43
|
-
Signer._canonicalizeJCS(x).should.equal(Signer._canonicalizeJCS(y))
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
// These are the same IEEE-754 double, so collapsing them is correct rather than a
|
|
47
|
-
// weakness — JavaScript has one number type. Pinned so nobody "fixes" it.
|
|
48
|
-
it('treats 1847, 1847.0 and 1.847e3 as the one number they are', function () {
|
|
49
|
-
Signer._canonicalizeJCS({ a: 1847 }).should.equal('{"a":1847}')
|
|
50
|
-
Signer._canonicalizeJCS({ a: 1847.0 }).should.equal('{"a":1847}')
|
|
51
|
-
Signer._canonicalizeJCS({ a: 1.847e3 }).should.equal('{"a":1847}')
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('keeps a number distinct from its string form', function () {
|
|
55
|
-
Signer._canonicalizeJCS({ a: 1847 }).should.not.equal(Signer._canonicalizeJCS({ a: '1847' }))
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
// JSON.stringify would emit `null` here, silently signing a different document.
|
|
59
|
-
it('refuses non-finite numbers rather than emitting null', function () {
|
|
60
|
-
;(function () { Signer._canonicalizeJCS({ a: NaN }) }).should.throw(/non-finite/)
|
|
61
|
-
;(function () { Signer._canonicalizeJCS({ a: Infinity }) }).should.throw(/non-finite/)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('emits unicode and non-BMP characters directly', function () {
|
|
65
|
-
Signer._canonicalizeJCS({ a: 'é' }).should.equal('{"a":"é"}')
|
|
66
|
-
Signer._canonicalizeJCS({ a: '😀' }).should.equal('{"a":"😀"}')
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
it('drops undefined members, which JSON cannot represent', function () {
|
|
70
|
-
Signer._canonicalizeJCS({ a: 1, b: undefined }).should.equal('{"a":1}')
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('nulls undefined array elements, as JSON.stringify does', function () {
|
|
74
|
-
Signer._canonicalizeJCS([1, undefined, 2]).should.equal('[1,null,2]')
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
describe('hashing and migration', function () {
|
|
79
|
-
var CRED = { id: 'urn:x', credentialSubject: { name: 'Alice', age: 41 } }
|
|
80
|
-
|
|
81
|
-
it('hashes with JCS by default', function () {
|
|
82
|
-
Signer._hashCredential(CRED).toString('hex')
|
|
83
|
-
.should.equal(Signer._hashCredential(CRED, Signer.CANONICALIZATION.JCS).toString('hex'))
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
// The migration path. A credential whose keys make the two forms differ must hash
|
|
87
|
-
// differently, or the legacy fallback in the verifier would be pointless.
|
|
88
|
-
it('gives a different hash under the legacy form when the forms diverge', function () {
|
|
89
|
-
var withIntKeys = { '10': 'ten', '2': 'two' }
|
|
90
|
-
Signer._hashCredential(withIntKeys, Signer.CANONICALIZATION.JCS).toString('hex')
|
|
91
|
-
.should.not.equal(
|
|
92
|
-
Signer._hashCredential(withIntKeys, Signer.CANONICALIZATION.LEGACY).toString('hex')
|
|
93
|
-
)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('agrees between the forms when no integer-like keys are present', function () {
|
|
97
|
-
Signer._hashCredential(CRED, Signer.CANONICALIZATION.JCS).toString('hex')
|
|
98
|
-
.should.equal(Signer._hashCredential(CRED, Signer.CANONICALIZATION.LEGACY).toString('hex'))
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('exposes both forms by name', function () {
|
|
102
|
-
Signer.CANONICALIZATION.JCS.should.equal('jcs')
|
|
103
|
-
Signer.CANONICALIZATION.LEGACY.should.equal('legacy')
|
|
104
|
-
})
|
|
105
|
-
})
|
|
106
|
-
})
|