@smartledger/bsv 9.0.0 → 9.1.0
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 +137 -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 +19 -5
- 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,97 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var chai = require('chai')
|
|
4
|
-
var expect = chai.expect
|
|
5
|
-
/* global structuredClone */
|
|
6
|
-
// structuredClone, not the former clone-deep dependency: the fixture below is plain
|
|
7
|
-
// JSON (strings and numbers), where the two are equivalent. The interpreter's stack
|
|
8
|
-
// clone is NOT — it holds Buffers, which structuredClone would return as Uint8Array.
|
|
9
|
-
// The global comment is for standard@12's eslint, which predates the API.
|
|
10
|
-
var cloneDeep = structuredClone
|
|
11
|
-
|
|
12
|
-
var bsv = require('../..')
|
|
13
|
-
var UnspentOutput = bsv.Transaction.UnspentOutput
|
|
14
|
-
|
|
15
|
-
describe('UnspentOutput', function () {
|
|
16
|
-
var sampleData1 = {
|
|
17
|
-
'address': 'mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1',
|
|
18
|
-
'txId': 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
|
|
19
|
-
'outputIndex': 0,
|
|
20
|
-
'script': 'OP_DUP OP_HASH160 20 0x88d9931ea73d60eaf7e5671efc0552b912911f2a OP_EQUALVERIFY OP_CHECKSIG',
|
|
21
|
-
'satoshis': 1020000
|
|
22
|
-
}
|
|
23
|
-
var sampleData2 = {
|
|
24
|
-
'txid': 'e42447187db5a29d6db161661e4bc66d61c3e499690fe5ea47f87b79ca573986',
|
|
25
|
-
'vout': 1,
|
|
26
|
-
'address': 'mgBCJAsvzgT2qNNeXsoECg2uPKrUsZ76up',
|
|
27
|
-
'scriptPubKey': '76a914073b7eae2823efa349e3b9155b8a735526463a0f88ac',
|
|
28
|
-
'amount': 0.01080000
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
it('roundtrip from raw data', function () {
|
|
32
|
-
expect(UnspentOutput(sampleData2).toObject()).to.deep.equal(sampleData2)
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('can be created without "new" operand', function () {
|
|
36
|
-
expect(UnspentOutput(sampleData1) instanceof UnspentOutput).to.equal(true)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('fails if no tx id is provided', function () {
|
|
40
|
-
expect(function () {
|
|
41
|
-
return new UnspentOutput({})
|
|
42
|
-
}).to.throw()
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('fails if vout is not a number', function () {
|
|
46
|
-
var sample = cloneDeep(sampleData2)
|
|
47
|
-
sample.vout = '1'
|
|
48
|
-
expect(function () {
|
|
49
|
-
return new UnspentOutput(sample)
|
|
50
|
-
}).to.throw()
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('displays nicely on the console', function () {
|
|
54
|
-
var expected = '<UnspentOutput: a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458:0' +
|
|
55
|
-
', satoshis: 1020000, address: mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1>'
|
|
56
|
-
expect(new UnspentOutput(sampleData1).inspect()).to.equal(expected)
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
describe('checking the constructor parameters', function () {
|
|
60
|
-
var notDefined = {
|
|
61
|
-
'txId': 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
|
|
62
|
-
'outputIndex': 0,
|
|
63
|
-
'script': 'OP_DUP OP_HASH160 20 0x88d9931ea73d60eaf7e5671efc0552b912911f2a OP_EQUALVERIFY OP_CHECKSIG'
|
|
64
|
-
}
|
|
65
|
-
var zero = {
|
|
66
|
-
'txId': 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
|
|
67
|
-
'outputIndex': 0,
|
|
68
|
-
'script': 'OP_DUP OP_HASH160 20 0x88d9931ea73d60eaf7e5671efc0552b912911f2a OP_EQUALVERIFY OP_CHECKSIG',
|
|
69
|
-
'amount': 0
|
|
70
|
-
}
|
|
71
|
-
it('fails when no amount is defined', function () {
|
|
72
|
-
expect(function () {
|
|
73
|
-
return new UnspentOutput(notDefined)
|
|
74
|
-
}).to.throw('Must provide an amount for the output')
|
|
75
|
-
})
|
|
76
|
-
it('does not fail when amount is zero', function () {
|
|
77
|
-
expect(function () {
|
|
78
|
-
return new UnspentOutput(zero)
|
|
79
|
-
}).to.not.throw()
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('toString returns txid:vout', function () {
|
|
84
|
-
var expected = 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458:0'
|
|
85
|
-
expect(new UnspentOutput(sampleData1).toString()).to.equal(expected)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('to/from JSON roundtrip', function () {
|
|
89
|
-
var utxo = new UnspentOutput(sampleData2)
|
|
90
|
-
var obj = UnspentOutput.fromObject(utxo.toJSON()).toObject()
|
|
91
|
-
expect(obj).to.deep.equal(sampleData2)
|
|
92
|
-
var str = JSON.stringify(UnspentOutput.fromObject(obj))
|
|
93
|
-
expect(JSON.parse(str)).to.deep.equal(sampleData2)
|
|
94
|
-
var str2 = JSON.stringify(new UnspentOutput(JSON.parse(str)))
|
|
95
|
-
expect(JSON.parse(str2)).to.deep.equal(sampleData2)
|
|
96
|
-
})
|
|
97
|
-
})
|
package/test/types/dts_drift.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it, before */
|
|
4
|
-
|
|
5
|
-
// TYPE-DRIFT GATE — mechanically proves the hand-maintained `bsv.d.ts` does not lie
|
|
6
|
-
// about the runtime. `bsv.d.ts` is a curated public-API surface (better than anything
|
|
7
|
-
// auto-generated from the spotty JSDoc), but nothing stopped it drifting — its own
|
|
8
|
-
// header said "3.4.x" on a 6.x package. This test parses the .d.ts with the real
|
|
9
|
-
// TypeScript AST and asserts:
|
|
10
|
-
// (1) every declared value symbol (class / function / const, at any nesting) EXISTS
|
|
11
|
-
// at runtime — no phantom APIs that the types promise but the code doesn't have;
|
|
12
|
-
// (2) for the audited namespaces (Ordinals, Ordinals.BSV20, SPV) every runtime
|
|
13
|
-
// function is DECLARED — so new APIs there can't ship untyped.
|
|
14
|
-
// Interfaces and type aliases are compile-time only and are ignored.
|
|
15
|
-
|
|
16
|
-
require('chai').should()
|
|
17
|
-
var path = require('path')
|
|
18
|
-
var fs = require('fs')
|
|
19
|
-
var ts = require('typescript')
|
|
20
|
-
var bsv = require('../..')
|
|
21
|
-
|
|
22
|
-
var DTS_PATH = path.join(__dirname, '../../bsv.d.ts')
|
|
23
|
-
var MODULE_NAME = '@smartledger/bsv'
|
|
24
|
-
|
|
25
|
-
// Walk the `declare module '@smartledger/bsv'` block and collect the dotted path of
|
|
26
|
-
// every value declaration (class / function / const), recursing into namespaces.
|
|
27
|
-
function collectDeclaredPaths (source) {
|
|
28
|
-
var sf = ts.createSourceFile('bsv.d.ts', source, ts.ScriptTarget.Latest, true)
|
|
29
|
-
var paths = []
|
|
30
|
-
var moduleBody = null
|
|
31
|
-
|
|
32
|
-
sf.forEachChild(function (node) {
|
|
33
|
-
if (ts.isModuleDeclaration(node) && node.name && ts.isStringLiteral(node.name) &&
|
|
34
|
-
node.name.text === MODULE_NAME && node.body && ts.isModuleBlock(node.body)) {
|
|
35
|
-
moduleBody = node.body
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
if (!moduleBody) throw new Error('could not find `declare module "' + MODULE_NAME + '"` in bsv.d.ts')
|
|
39
|
-
|
|
40
|
-
function walk (statements, prefix) {
|
|
41
|
-
statements.forEach(function (node) {
|
|
42
|
-
if (ts.isModuleDeclaration(node) && node.name && node.body && ts.isModuleBlock(node.body)) {
|
|
43
|
-
// A namespace: recurse (the namespace itself is checked via its members' paths).
|
|
44
|
-
walk(node.body.statements, prefix.concat(node.name.text))
|
|
45
|
-
} else if (ts.isClassDeclaration(node) && node.name) {
|
|
46
|
-
paths.push(prefix.concat(node.name.text))
|
|
47
|
-
} else if (ts.isFunctionDeclaration(node) && node.name) {
|
|
48
|
-
var p = prefix.concat(node.name.text)
|
|
49
|
-
p.returnType = node.type ? node.type.getText() : null
|
|
50
|
-
paths.push(p)
|
|
51
|
-
} else if (ts.isVariableStatement(node)) {
|
|
52
|
-
node.declarationList.declarations.forEach(function (d) {
|
|
53
|
-
if (ts.isIdentifier(d.name)) paths.push(prefix.concat(d.name.text))
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
// InterfaceDeclaration / TypeAliasDeclaration: compile-time only — ignored.
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
walk(moduleBody.statements, [])
|
|
60
|
-
return paths
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Resolve a dotted path on the runtime object; returns undefined if any segment is missing.
|
|
64
|
-
function resolve (root, segments) {
|
|
65
|
-
return segments.reduce(function (o, k) { return (o == null) ? undefined : o[k] }, root)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
describe('types: bsv.d.ts does not drift from runtime', function () {
|
|
69
|
-
var declaredPaths
|
|
70
|
-
|
|
71
|
-
before(function () {
|
|
72
|
-
declaredPaths = collectDeclaredPaths(fs.readFileSync(DTS_PATH, 'utf8'))
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('parses a non-trivial number of declared symbols', function () {
|
|
76
|
-
// Sanity: if the parse silently produced nothing, the whole gate would be a no-op.
|
|
77
|
-
declaredPaths.length.should.be.above(50)
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('every declared class / function / const exists at runtime (no phantom API)', function () {
|
|
81
|
-
var missing = declaredPaths
|
|
82
|
-
.filter(function (segs) { return resolve(bsv, segs) === undefined })
|
|
83
|
-
.map(function (segs) { return segs.join('.') })
|
|
84
|
-
missing.should.deep.equal([], 'bsv.d.ts declares these but runtime does not expose them:\n ' + missing.join('\n '))
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
// Reverse direction where it matters most: the modules added in 6.x must stay fully typed.
|
|
88
|
-
var AUDITED = [
|
|
89
|
-
{ label: 'Ordinals', obj: bsv.Ordinals, decl: 'Ordinals' },
|
|
90
|
-
{ label: 'Ordinals.BSV20', obj: bsv.Ordinals && bsv.Ordinals.BSV20, decl: 'Ordinals.BSV20' },
|
|
91
|
-
{ label: 'SPV', obj: bsv.SPV, decl: 'SPV' }
|
|
92
|
-
]
|
|
93
|
-
|
|
94
|
-
// An `async` runtime function declared with a non-Promise return type is the most
|
|
95
|
-
// dangerous kind of drift, because the type checker actively hides the bug rather than
|
|
96
|
-
// merely failing to catch it: `StatusList.getCredentialStatusEntry` was declared
|
|
97
|
-
// `: CredentialStatus` while being async, so `if (fn(...) === 'revoked')` compiled clean
|
|
98
|
-
// and was ALWAYS false — every revoked credential passed as valid.
|
|
99
|
-
it('no async runtime function is declared with a synchronous return type', function () {
|
|
100
|
-
var lies = []
|
|
101
|
-
declaredPaths.forEach(function (segs) {
|
|
102
|
-
if (!segs.returnType) return
|
|
103
|
-
var fn = resolve(bsv, segs)
|
|
104
|
-
if (typeof fn !== 'function') return
|
|
105
|
-
var isAsync = fn.constructor && fn.constructor.name === 'AsyncFunction'
|
|
106
|
-
var declaresPromise = /\bPromise\s*</.test(segs.returnType)
|
|
107
|
-
if (isAsync && !declaresPromise) {
|
|
108
|
-
lies.push(segs.join('.') + ' is async but is declared `: ' + segs.returnType + '`')
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
lies.should.deep.equal([], 'these declarations hide a Promise:\n ' + lies.join('\n '))
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
AUDITED.forEach(function (ns) {
|
|
115
|
-
it('every runtime function on ' + ns.label + ' is declared in bsv.d.ts', function () {
|
|
116
|
-
ns.obj.should.be.an('object')
|
|
117
|
-
var declaredSet = {}
|
|
118
|
-
declaredPaths.forEach(function (segs) { declaredSet[segs.join('.')] = true })
|
|
119
|
-
var runtimeFns = Object.keys(ns.obj).filter(function (k) { return typeof ns.obj[k] === 'function' })
|
|
120
|
-
var untyped = runtimeFns.filter(function (k) { return !declaredSet[ns.decl + '.' + k] })
|
|
121
|
-
untyped.should.deep.equal([], ns.label + ' exposes these functions but bsv.d.ts does not declare them:\n ' + untyped.join('\n '))
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
})
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
// Runtime half of a field review that found declarations disagreeing with the code.
|
|
6
|
-
// The declarations themselves are gated by dts_drift.js and by the tsc check in CI; the
|
|
7
|
-
// cases below are the ones where the RUNTIME also had to change, because a declaration
|
|
8
|
-
// that merely matched the old behaviour would have been documenting a bug.
|
|
9
|
-
|
|
10
|
-
var should = require('chai').should()
|
|
11
|
-
var bsv = require('../..')
|
|
12
|
-
var SC = bsv.SmartContract
|
|
13
|
-
|
|
14
|
-
describe('public surface tells the truth about itself', function () {
|
|
15
|
-
describe('SmartContract.ownershipToken forwards its authorizer', function () {
|
|
16
|
-
it('is not a two-argument alias that drops the third', function () {
|
|
17
|
-
// The top-level alias took (fee, ownerPubKeyHash) and called through with only
|
|
18
|
-
// those two, so a co-signed token built via this path came out single-key — the
|
|
19
|
-
// authorizer was accepted and silently discarded.
|
|
20
|
-
var auth = SC.Authorizers.multisig(2, 3)
|
|
21
|
-
var withAuth = SC.ownershipToken(1, Buffer.alloc(20), auth).toHex()
|
|
22
|
-
var without = SC.ownershipToken(1, Buffer.alloc(20)).toHex()
|
|
23
|
-
withAuth.should.not.equal(without)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('agrees with SmartContract.Token.ownershipToken', function () {
|
|
27
|
-
var auth = SC.Authorizers.multisig(2, 3)
|
|
28
|
-
SC.ownershipToken(1, Buffer.alloc(20), auth).toHex()
|
|
29
|
-
.should.equal(SC.Token.ownershipToken(1, Buffer.alloc(20), auth).toHex())
|
|
30
|
-
})
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
describe('Authorizers.multisig takes a key COUNT', function () {
|
|
34
|
-
it('rejects an array of keys instead of silently building a broken authorizer', function () {
|
|
35
|
-
// `m > nKeys` compared a number to an array, which coerces to NaN, so the guard
|
|
36
|
-
// passed and the array was interpolated into the authorizer's name.
|
|
37
|
-
var keys = [1, 2, 3].map(function () {
|
|
38
|
-
return bsv.PrivateKey.fromRandom().toPublicKey().toBuffer()
|
|
39
|
-
})
|
|
40
|
-
;(function () { SC.Authorizers.multisig(2, keys) }).should.throw(/NUMBER of keys/)
|
|
41
|
-
// The message names the fix.
|
|
42
|
-
;(function () { SC.Authorizers.multisig(2, keys) }).should.throw(/pass 3 instead/)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('still accepts the documented count form', function () {
|
|
46
|
-
SC.Authorizers.multisig(2, 3).n.should.equal(3)
|
|
47
|
-
SC.Authorizers.multisig(2, 3).m.should.equal(2)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('rejects non-integer m', function () {
|
|
51
|
-
(function () { SC.Authorizers.multisig('2', 3) }).should.throw(/m must be an integer/)
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
describe('StatusList refuses to record a suspension as a revocation', function () {
|
|
56
|
-
it('throws on status: suspended rather than setting the revocation bit', function () {
|
|
57
|
-
// Both statuses set the SAME bit and read back as 'revoked', so a suspension was
|
|
58
|
-
// silently recorded — and later reported — as a permanent revocation.
|
|
59
|
-
return bsv.StatusList.updateStatusList({
|
|
60
|
-
listVcJwt: 'x', index: 1, status: 'suspended', privateJwk: {}
|
|
61
|
-
}).then(
|
|
62
|
-
function () { throw new Error('should not have accepted suspended') },
|
|
63
|
-
function (err) { err.message.should.match(/'suspended' is not supported/) }
|
|
64
|
-
)
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
describe('securityFeatures describes what is actually shipped', function () {
|
|
69
|
-
it('no longer claims elliptic patches, since elliptic is not a dependency', function () {
|
|
70
|
-
var pkg = require('../../package.json')
|
|
71
|
-
var deps = Object.keys(pkg.dependencies || {})
|
|
72
|
-
deps.indexOf('elliptic').should.equal(-1)
|
|
73
|
-
bsv.securityFeatures.indexOf('elliptic-patches').should.equal(-1)
|
|
74
|
-
bsv.securityFeatures.should.be.an('array')
|
|
75
|
-
bsv.securityFeatures.length.should.be.above(0)
|
|
76
|
-
})
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
describe('documented sub-path entry points resolve', function () {
|
|
80
|
-
// Every one of these was MODULE_NOT_FOUND: the package `exports` map had no aliases
|
|
81
|
-
// for the *-entry.js files, so a documented deep import could not be loaded at all.
|
|
82
|
-
var SUBPATHS = ['didweb', 'vcjwt', 'gdaf', 'ltp', 'statuslist', 'shamir',
|
|
83
|
-
'anchor', 'covenant', 'security', 'smartcontract', 'script-helper']
|
|
84
|
-
|
|
85
|
-
SUBPATHS.forEach(function (name) {
|
|
86
|
-
it('@smartledger/bsv/' + name, function () {
|
|
87
|
-
var mod = require('@smartledger/bsv/' + name)
|
|
88
|
-
// Some entry points export a class (a function), others a namespace object.
|
|
89
|
-
var t = typeof mod
|
|
90
|
-
t.should.be.oneOf(['object', 'function'])
|
|
91
|
-
should.exist(mod)
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it('still resolves the package root and lib deep imports', function () {
|
|
96
|
-
require('@smartledger/bsv').should.be.an('object')
|
|
97
|
-
require('@smartledger/bsv/version').should.be.a('string')
|
|
98
|
-
// Directory deep-imports need the explicit file — a documented 7.0 exports break.
|
|
99
|
-
require('@smartledger/bsv/lib/ordinals/index.js').should.be.an('object')
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
})
|
package/test/util/id.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
require('chai').should()
|
|
6
|
-
var expect = require('chai').expect
|
|
7
|
-
|
|
8
|
-
var Id = require('../../lib/util/id')
|
|
9
|
-
|
|
10
|
-
var UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
|
|
11
|
-
|
|
12
|
-
describe('util/id', function () {
|
|
13
|
-
describe('#uuid4', function () {
|
|
14
|
-
it('produces a well-formed RFC 4122 v4 uuid', function () {
|
|
15
|
-
Id.uuid4().should.match(UUID_V4)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('sets the version and variant bits on every draw', function () {
|
|
19
|
-
for (var i = 0; i < 200; i++) {
|
|
20
|
-
Id.uuid4().should.match(UUID_V4)
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('does not repeat', function () {
|
|
25
|
-
var seen = {}
|
|
26
|
-
for (var i = 0; i < 2000; i++) {
|
|
27
|
-
var id = Id.uuid4()
|
|
28
|
-
expect(seen[id], 'duplicate uuid: ' + id).to.equal(undefined)
|
|
29
|
-
seen[id] = true
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
describe('#randomHex', function () {
|
|
35
|
-
it('returns the requested number of hex characters', function () {
|
|
36
|
-
Id.randomHex(16).should.match(/^[0-9a-f]{16}$/)
|
|
37
|
-
Id.randomHex(12).should.match(/^[0-9a-f]{12}$/)
|
|
38
|
-
Id.randomHex(1).should.match(/^[0-9a-f]$/)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('does not repeat', function () {
|
|
42
|
-
var seen = {}
|
|
43
|
-
for (var i = 0; i < 2000; i++) {
|
|
44
|
-
var id = Id.randomHex(16)
|
|
45
|
-
expect(seen[id], 'duplicate id: ' + id).to.equal(undefined)
|
|
46
|
-
seen[id] = true
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
describe('entropy source', function () {
|
|
52
|
-
// Identifiers must come from the CSPRNG. Freezing the engine PRNG must not
|
|
53
|
-
// affect them; if it does, they are predictable from observed output.
|
|
54
|
-
var withFrozenMathRandom = function (fn) {
|
|
55
|
-
var original = Math.random
|
|
56
|
-
Math.random = function () { return 0.5 }
|
|
57
|
-
try { return fn() } finally { Math.random = original }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
it('uuid4 is unaffected by the engine PRNG', function () {
|
|
61
|
-
withFrozenMathRandom(function () {
|
|
62
|
-
Id.uuid4().should.not.equal(Id.uuid4())
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('randomHex is unaffected by the engine PRNG', function () {
|
|
67
|
-
withFrozenMathRandom(function () {
|
|
68
|
-
Id.randomHex(16).should.not.equal(Id.randomHex(16))
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
})
|
package/test/util/js.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
require('chai').should()
|
|
4
|
-
|
|
5
|
-
var bsv = require('../..')
|
|
6
|
-
var JSUtil = bsv.util.js
|
|
7
|
-
|
|
8
|
-
describe('js utils', function () {
|
|
9
|
-
describe('isValidJSON', function () {
|
|
10
|
-
var hexa = '8080808080808080808080808080808080808080808080808080808080808080'
|
|
11
|
-
var json = '{"key": ["value", "value2"]}'
|
|
12
|
-
var json2 = '["value", "value2", {"key": "value"}]'
|
|
13
|
-
|
|
14
|
-
it('does not mistake an integer as valid json object', function () {
|
|
15
|
-
var valid = JSUtil.isValidJSON(hexa)
|
|
16
|
-
valid.should.equal(false)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('correctly validates a json object', function () {
|
|
20
|
-
var valid = JSUtil.isValidJSON(json)
|
|
21
|
-
valid.should.equal(true)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('correctly validates an array json object', function () {
|
|
25
|
-
var valid = JSUtil.isValidJSON(json2)
|
|
26
|
-
valid.should.equal(true)
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
describe('isNaturalNumber', function () {
|
|
31
|
-
it('false for float', function () {
|
|
32
|
-
var a = JSUtil.isNaturalNumber(0.1)
|
|
33
|
-
a.should.equal(false)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('false for string float', function () {
|
|
37
|
-
var a = JSUtil.isNaturalNumber('0.1')
|
|
38
|
-
a.should.equal(false)
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('false for string integer', function () {
|
|
42
|
-
var a = JSUtil.isNaturalNumber('1')
|
|
43
|
-
a.should.equal(false)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('false for negative integer', function () {
|
|
47
|
-
var a = JSUtil.isNaturalNumber(-1)
|
|
48
|
-
a.should.equal(false)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('false for negative integer string', function () {
|
|
52
|
-
var a = JSUtil.isNaturalNumber('-1')
|
|
53
|
-
a.should.equal(false)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('false for infinity', function () {
|
|
57
|
-
var a = JSUtil.isNaturalNumber(Infinity)
|
|
58
|
-
a.should.equal(false)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('false for NaN', function () {
|
|
62
|
-
var a = JSUtil.isNaturalNumber(NaN)
|
|
63
|
-
a.should.equal(false)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('true for zero', function () {
|
|
67
|
-
var a = JSUtil.isNaturalNumber(0)
|
|
68
|
-
a.should.equal(true)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('true for positive integer', function () {
|
|
72
|
-
var a = JSUtil.isNaturalNumber(1000)
|
|
73
|
-
a.should.equal(true)
|
|
74
|
-
})
|
|
75
|
-
})
|
|
76
|
-
})
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var should = require('chai').should()
|
|
4
|
-
|
|
5
|
-
var bsv = require('../..')
|
|
6
|
-
var errors = bsv.errors
|
|
7
|
-
var $ = bsv.util.preconditions
|
|
8
|
-
var PrivateKey = bsv.PrivateKey
|
|
9
|
-
|
|
10
|
-
describe('preconditions', function () {
|
|
11
|
-
it('can be used to assert state', function () {
|
|
12
|
-
(function () {
|
|
13
|
-
$.checkState(false, 'testing')
|
|
14
|
-
}).should.throw(errors.InvalidState)
|
|
15
|
-
})
|
|
16
|
-
it('throws no false negative', function () {
|
|
17
|
-
(function () {
|
|
18
|
-
$.checkState(true, 'testing')
|
|
19
|
-
}).should.not.throw()
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('can be used to check an argument', function () {
|
|
23
|
-
(function () {
|
|
24
|
-
$.checkArgument(false, 'testing')
|
|
25
|
-
}).should.throw(errors.InvalidArgument);
|
|
26
|
-
|
|
27
|
-
(function () {
|
|
28
|
-
$.checkArgument(true, 'testing')
|
|
29
|
-
}).should.not.throw(errors.InvalidArgument)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('can be used to check an argument type', function () {
|
|
33
|
-
var error
|
|
34
|
-
try {
|
|
35
|
-
$.checkArgumentType(1, 'string', 'argumentName')
|
|
36
|
-
} catch (e) {
|
|
37
|
-
error = e
|
|
38
|
-
e.message.should.equal('Invalid Argument for argumentName, expected string but got number')
|
|
39
|
-
}
|
|
40
|
-
should.exist(error)
|
|
41
|
-
})
|
|
42
|
-
it('has no false negatives when used to check an argument type', function () {
|
|
43
|
-
(function () {
|
|
44
|
-
$.checkArgumentType('a String', 'string', 'argumentName')
|
|
45
|
-
}).should.not.throw()
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('can be used to check an argument type for a class', function () {
|
|
49
|
-
var error
|
|
50
|
-
try {
|
|
51
|
-
$.checkArgumentType(1, PrivateKey)
|
|
52
|
-
} catch (e) {
|
|
53
|
-
error = e
|
|
54
|
-
var fail = !(~e.message.indexOf('Invalid Argument for (unknown name)'))
|
|
55
|
-
fail.should.equal(false)
|
|
56
|
-
}
|
|
57
|
-
should.exist(error)
|
|
58
|
-
})
|
|
59
|
-
it('has no false negatives when checking a type for a class', function () {
|
|
60
|
-
(function () {
|
|
61
|
-
$.checkArgumentType(new PrivateKey(), PrivateKey)
|
|
62
|
-
}).should.not.throw()
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('formats correctly a message on InvalidArgument()', function () {
|
|
66
|
-
var error = new errors.InvalidArgument()
|
|
67
|
-
error.message.should.equal('Invalid Argument')
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('formats correctly a message on checkArgument', function () {
|
|
71
|
-
var error
|
|
72
|
-
try {
|
|
73
|
-
$.checkArgument(null, 'parameter must be provided')
|
|
74
|
-
} catch (e) {
|
|
75
|
-
error = e
|
|
76
|
-
}
|
|
77
|
-
error.message.should.equal('Invalid Argument: parameter must be provided')
|
|
78
|
-
})
|
|
79
|
-
})
|
package/test/vcjwt/interop.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
// Proves the VC-JWT module is interoperable with the standards-compliant
|
|
6
|
-
// `jose` library in BOTH directions, for ES256 (P-256) and ES256K (secp256k1),
|
|
7
|
-
// and that algorithm pinning / curve binding reject substitution attacks.
|
|
8
|
-
|
|
9
|
-
var assert = require('assert')
|
|
10
|
-
var crypto = require('crypto')
|
|
11
|
-
var jose = require('jose')
|
|
12
|
-
var vcjwt = require('../../lib/vcjwt')
|
|
13
|
-
|
|
14
|
-
function genKeys (alg, namedCurve) {
|
|
15
|
-
var pair = crypto.generateKeyPairSync('ec', { namedCurve: namedCurve })
|
|
16
|
-
var privateJwk = pair.privateKey.export({ format: 'jwk' })
|
|
17
|
-
var publicJwk = pair.publicKey.export({ format: 'jwk' })
|
|
18
|
-
privateJwk.kid = publicJwk.kid = 'test-key-1'
|
|
19
|
-
privateJwk.alg = publicJwk.alg = alg
|
|
20
|
-
return { privateJwk: privateJwk, publicJwk: publicJwk }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function resolverFor (publicJwk) {
|
|
24
|
-
return function () {
|
|
25
|
-
return Promise.resolve({ jwks: { keys: [publicJwk] } })
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
var CASES = [
|
|
30
|
-
{ alg: 'ES256', curve: 'prime256v1' },
|
|
31
|
-
{ alg: 'ES256K', curve: 'secp256k1' }
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
describe('vcjwt JOSE interop', function () {
|
|
35
|
-
CASES.forEach(function (c) {
|
|
36
|
-
it('issues a token that ' + c.alg + ' jose can verify (P1363 encoding)', async function () {
|
|
37
|
-
var keys = genKeys(c.alg, c.curve)
|
|
38
|
-
var issued = await vcjwt.issueVcJwt({
|
|
39
|
-
issuerDid: 'did:web:example.com',
|
|
40
|
-
subjectId: 'did:web:subject.example',
|
|
41
|
-
credentialSubject: { name: 'Alice' },
|
|
42
|
-
privateJwk: keys.privateJwk,
|
|
43
|
-
alg: c.alg
|
|
44
|
-
})
|
|
45
|
-
var joseKey = await jose.importJWK(keys.publicJwk, c.alg)
|
|
46
|
-
var result = await jose.jwtVerify(issued.jwt, joseKey) // throws if non-compliant
|
|
47
|
-
assert.strictEqual(result.payload.iss, 'did:web:example.com')
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('verifies a ' + c.alg + ' token issued by jose', async function () {
|
|
51
|
-
var keys = genKeys(c.alg, c.curve)
|
|
52
|
-
var josePriv = await jose.importJWK(keys.privateJwk, c.alg)
|
|
53
|
-
var joseJwt = await new jose.SignJWT({ vc: { type: ['VerifiableCredential'] } })
|
|
54
|
-
.setProtectedHeader({ alg: c.alg, typ: 'JWT', kid: keys.publicJwk.kid })
|
|
55
|
-
.setIssuer('did:web:example.com')
|
|
56
|
-
.setSubject('did:web:subject.example')
|
|
57
|
-
.setIssuedAt()
|
|
58
|
-
.setExpirationTime('1y')
|
|
59
|
-
.sign(josePriv)
|
|
60
|
-
var res = await vcjwt.verifyVcJwt(joseJwt, { didResolver: resolverFor(keys.publicJwk) })
|
|
61
|
-
assert.strictEqual(res.valid, true, res.error)
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('rejects a token whose alg is not in the allowlist', async function () {
|
|
66
|
-
var keys = genKeys('ES256', 'prime256v1')
|
|
67
|
-
var issued = await vcjwt.issueVcJwt({
|
|
68
|
-
issuerDid: 'did:web:example.com', subjectId: 's', credentialSubject: {}, privateJwk: keys.privateJwk, alg: 'ES256'
|
|
69
|
-
})
|
|
70
|
-
var res = await vcjwt.verifyVcJwt(issued.jwt, {
|
|
71
|
-
allowedAlgs: ['ES256K'],
|
|
72
|
-
didResolver: resolverFor(keys.publicJwk)
|
|
73
|
-
})
|
|
74
|
-
assert.strictEqual(res.valid, false)
|
|
75
|
-
assert.ok(/Algorithm not allowed/.test(res.error), res.error)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('rejects when the resolved key curve does not match the algorithm', async function () {
|
|
79
|
-
// ES256 token, but the JWKS serves a secp256k1 key under the same kid.
|
|
80
|
-
var p256 = genKeys('ES256', 'prime256v1')
|
|
81
|
-
var k1 = genKeys('ES256K', 'secp256k1')
|
|
82
|
-
var issued = await vcjwt.issueVcJwt({
|
|
83
|
-
issuerDid: 'did:web:example.com', subjectId: 's', credentialSubject: {}, privateJwk: p256.privateJwk, alg: 'ES256'
|
|
84
|
-
})
|
|
85
|
-
var res = await vcjwt.verifyVcJwt(issued.jwt, { didResolver: resolverFor(k1.publicJwk) })
|
|
86
|
-
assert.strictEqual(res.valid, false)
|
|
87
|
-
assert.ok(/curve does not match/.test(res.error), res.error)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
it('refuses to sign when the key curve does not match the algorithm', async function () {
|
|
91
|
-
var k1 = genKeys('ES256K', 'secp256k1')
|
|
92
|
-
var threw = false
|
|
93
|
-
try {
|
|
94
|
-
await vcjwt.issueVcJwt({
|
|
95
|
-
issuerDid: 'did:web:example.com', subjectId: 's', credentialSubject: {}, privateJwk: k1.privateJwk, alg: 'ES256'
|
|
96
|
-
})
|
|
97
|
-
} catch (e) {
|
|
98
|
-
threw = /does not match alg/.test(e.message)
|
|
99
|
-
}
|
|
100
|
-
assert.ok(threw, 'expected curve/alg mismatch to throw')
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('accepts a legacy DER-encoded token only when allowLegacyDER is set', async function () {
|
|
104
|
-
// Simulate a <=4.6.0 token: same signing input, but DER-encoded signature.
|
|
105
|
-
var keys = genKeys('ES256', 'prime256v1')
|
|
106
|
-
var header = { alg: 'ES256', typ: 'JWT', kid: keys.publicJwk.kid }
|
|
107
|
-
var payload = { iss: 'did:web:example.com', sub: 's', iat: 1700000000, exp: 4102444800, vc: {} }
|
|
108
|
-
var headerB64 = vcjwt.base64UrlEncode(Buffer.from(JSON.stringify(header)))
|
|
109
|
-
var payloadB64 = vcjwt.base64UrlEncode(Buffer.from(JSON.stringify(payload)))
|
|
110
|
-
var signingInput = headerB64 + '.' + payloadB64
|
|
111
|
-
var derSig = crypto.sign('sha256', Buffer.from(signingInput), {
|
|
112
|
-
key: crypto.createPrivateKey({ key: keys.privateJwk, format: 'jwk' }),
|
|
113
|
-
dsaEncoding: 'der'
|
|
114
|
-
})
|
|
115
|
-
var legacyJwt = signingInput + '.' + vcjwt.base64UrlEncode(derSig)
|
|
116
|
-
|
|
117
|
-
var rejected = await vcjwt.verifyVcJwt(legacyJwt, { didResolver: resolverFor(keys.publicJwk) })
|
|
118
|
-
assert.strictEqual(rejected.valid, false, 'legacy DER token must fail by default')
|
|
119
|
-
|
|
120
|
-
var accepted = await vcjwt.verifyVcJwt(legacyJwt, {
|
|
121
|
-
allowLegacyDER: true,
|
|
122
|
-
didResolver: resolverFor(keys.publicJwk)
|
|
123
|
-
})
|
|
124
|
-
assert.strictEqual(accepted.valid, true, accepted.error)
|
|
125
|
-
})
|
|
126
|
-
})
|