@xyo-network/boundwitness-validator 2.42.16
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/LICENSE +165 -0
- package/README.md +81 -0
- package/dist/cjs/Validator.d.ts +19 -0
- package/dist/cjs/Validator.d.ts.map +1 -0
- package/dist/cjs/Validator.js +111 -0
- package/dist/cjs/Validator.js.map +1 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/docs.json +968 -0
- package/dist/esm/Validator.d.ts +19 -0
- package/dist/esm/Validator.d.ts.map +1 -0
- package/dist/esm/Validator.js +104 -0
- package/dist/esm/Validator.js.map +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -0
- package/package.json +61 -0
- package/src/Validator.spec.ts +20 -0
- package/src/Validator.ts +117 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { XyoBoundWitness } from '@xyo-network/boundwitness-model';
|
|
2
|
+
import { PayloadValidator } from '@xyo-network/payload-validator';
|
|
3
|
+
export declare class BoundWitnessValidator<T extends XyoBoundWitness<{
|
|
4
|
+
schema: string;
|
|
5
|
+
}> = XyoBoundWitness> extends PayloadValidator<T> {
|
|
6
|
+
get hash(): string;
|
|
7
|
+
static validateSignature(hash: string, address: string, signature?: string): Error[];
|
|
8
|
+
addresses(): Error[];
|
|
9
|
+
addressesUniqueness(): Error[];
|
|
10
|
+
previousHashes(): Error[];
|
|
11
|
+
schema(): Error[];
|
|
12
|
+
schemas(): Error[];
|
|
13
|
+
signatures(): Error[];
|
|
14
|
+
validate(): Error[];
|
|
15
|
+
validateArrayLengths(): Error[];
|
|
16
|
+
validatePayloadHashesLength(): Error[];
|
|
17
|
+
private validateArrayLength;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=Validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.d.ts","sourceRoot":"","sources":["../../src/Validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAyB,MAAM,iCAAiC,CAAA;AAExF,OAAO,EAAE,gBAAgB,EAA0B,MAAM,gCAAgC,CAAA;AAQzF,qBAAa,qBAAqB,CAAC,CAAC,SAAS,eAAe,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,eAAe,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC7H,IAAW,IAAI,WAEd;IAED,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;IAUnE,SAAS;IAQT,mBAAmB;IAQnB,cAAc;IAKd,MAAM;IASN,OAAO;IAcP,UAAU;IAUD,QAAQ;IAYjB,oBAAoB;IAMpB,2BAA2B;IAMlC,OAAO,CAAC,mBAAmB;CAY5B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { AddressValue } from '@xyo-network/account';
|
|
2
|
+
import { XyoBoundWitnessSchema } from '@xyo-network/boundwitness-model';
|
|
3
|
+
import { Hasher } from '@xyo-network/core';
|
|
4
|
+
import { PayloadValidator, XyoSchemaNameValidator } from '@xyo-network/payload-validator';
|
|
5
|
+
import { validateType } from '@xyo-network/typeof';
|
|
6
|
+
import uniq from 'lodash/uniq';
|
|
7
|
+
const validateArraysSameLength = (a, b, message = 'Array length mismatch') => {
|
|
8
|
+
return a.length != b.length ? [Error(`${message} []`)] : [];
|
|
9
|
+
};
|
|
10
|
+
export class BoundWitnessValidator extends PayloadValidator {
|
|
11
|
+
get hash() {
|
|
12
|
+
return new Hasher(this.obj).hash;
|
|
13
|
+
}
|
|
14
|
+
static validateSignature(hash, address, signature) {
|
|
15
|
+
if (!signature) {
|
|
16
|
+
return [Error(`Missing signature [${address}]`)];
|
|
17
|
+
}
|
|
18
|
+
if (!new AddressValue(address).verify(hash, signature)) {
|
|
19
|
+
return [Error(`Invalid signature [${address}] [${signature}]`)];
|
|
20
|
+
}
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
addresses() {
|
|
24
|
+
const errors = [];
|
|
25
|
+
const { addresses } = this.obj;
|
|
26
|
+
if (!addresses?.length)
|
|
27
|
+
errors.push(new Error('addresses missing [at least one address required]'));
|
|
28
|
+
errors.push(...this.addressesUniqueness());
|
|
29
|
+
return errors;
|
|
30
|
+
}
|
|
31
|
+
addressesUniqueness() {
|
|
32
|
+
const errors = [];
|
|
33
|
+
const { addresses } = this.obj;
|
|
34
|
+
const uniqAddresses = uniq(addresses);
|
|
35
|
+
if (addresses?.length !== uniqAddresses?.length)
|
|
36
|
+
errors.push(new Error('addresses must be unique'));
|
|
37
|
+
return errors;
|
|
38
|
+
}
|
|
39
|
+
previousHashes() {
|
|
40
|
+
const errors = [];
|
|
41
|
+
return errors;
|
|
42
|
+
}
|
|
43
|
+
schema() {
|
|
44
|
+
const errors = [];
|
|
45
|
+
const expectedSchema = XyoBoundWitnessSchema;
|
|
46
|
+
if (this.obj.schema !== expectedSchema) {
|
|
47
|
+
errors.push(new Error(`invalid schema [${expectedSchema} !== ${this.obj.schema}]`));
|
|
48
|
+
}
|
|
49
|
+
return errors;
|
|
50
|
+
}
|
|
51
|
+
schemas() {
|
|
52
|
+
const errors = [];
|
|
53
|
+
const Schemas = this.obj.payload_schemas;
|
|
54
|
+
if (Schemas) {
|
|
55
|
+
const schemaValidators = Schemas.map((schema) => {
|
|
56
|
+
return new XyoSchemaNameValidator(schema);
|
|
57
|
+
});
|
|
58
|
+
schemaValidators.forEach((validator) => {
|
|
59
|
+
errors.push(...validator.all());
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return errors;
|
|
63
|
+
}
|
|
64
|
+
signatures() {
|
|
65
|
+
return [
|
|
66
|
+
...validateArraysSameLength(this.obj._signatures ?? [], this.obj.addresses, 'Length mismatch: address/_signature'),
|
|
67
|
+
...this.obj.addresses.reduce((errors, address, index) => {
|
|
68
|
+
errors.push(...BoundWitnessValidator.validateSignature(this.hash, address, this.obj._signatures?.[index]));
|
|
69
|
+
return errors;
|
|
70
|
+
}, []),
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
validate() {
|
|
74
|
+
return [
|
|
75
|
+
...this.signatures(),
|
|
76
|
+
...this.addresses(),
|
|
77
|
+
...this.validateArrayLengths(),
|
|
78
|
+
...this.schemas(),
|
|
79
|
+
...this.previousHashes(),
|
|
80
|
+
...this.schema(),
|
|
81
|
+
...super.validate(),
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
validateArrayLengths() {
|
|
85
|
+
const errors = [];
|
|
86
|
+
errors.push(...this.validatePayloadHashesLength());
|
|
87
|
+
return errors;
|
|
88
|
+
}
|
|
89
|
+
validatePayloadHashesLength() {
|
|
90
|
+
const errors = [];
|
|
91
|
+
errors.push(...this.validateArrayLength('payload_hashes', 'payload_schemas'));
|
|
92
|
+
return errors;
|
|
93
|
+
}
|
|
94
|
+
validateArrayLength(fieldName, compareArrayName) {
|
|
95
|
+
const errors = [];
|
|
96
|
+
const [array, arrayErrors] = validateType('array', this.stringKeyObj[fieldName], true);
|
|
97
|
+
const [compareArray, compareArrayErrors] = validateType('array', this.stringKeyObj[compareArrayName], true);
|
|
98
|
+
if (array?.length !== compareArray?.length) {
|
|
99
|
+
errors.push(new Error(`${fieldName}/${compareArrayName} count mismatch [${array?.length} !== ${compareArray?.length}]`));
|
|
100
|
+
}
|
|
101
|
+
return [...arrayErrors, ...compareArrayErrors, ...errors];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=Validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.js","sourceRoot":"","sources":["../../src/Validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xyo-network/boundwitness-validator",
|
|
3
|
+
"author": {
|
|
4
|
+
"email": "support@xyo.network",
|
|
5
|
+
"name": "XYO Development Team",
|
|
6
|
+
"url": "https://xyo.network"
|
|
7
|
+
},
|
|
8
|
+
"bugs": {
|
|
9
|
+
"email": "support@xyo.network",
|
|
10
|
+
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js/issues"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@xyo-network/account": "^2.42.16",
|
|
14
|
+
"@xyo-network/boundwitness-model": "^2.42.16",
|
|
15
|
+
"@xyo-network/core": "^2.42.16",
|
|
16
|
+
"@xyo-network/payload-validator": "^2.42.15",
|
|
17
|
+
"@xyo-network/typeof": "^2.42.16",
|
|
18
|
+
"lodash": "^4.17.21"
|
|
19
|
+
},
|
|
20
|
+
"description": "Primary SDK for using XYO Protocol 2.0",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/lodash": "^4.14.191",
|
|
23
|
+
"@xylabs/ts-scripts-yarn3": "^2.10.25"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"axios": "^1.2.1"
|
|
27
|
+
},
|
|
28
|
+
"browser": "dist/esm/index.js",
|
|
29
|
+
"docs": "dist/docs.json",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"node": {
|
|
33
|
+
"import": "./dist/esm/index.js",
|
|
34
|
+
"require": "./dist/cjs/index.js"
|
|
35
|
+
},
|
|
36
|
+
"browser": {
|
|
37
|
+
"import": "./dist/esm/index.js",
|
|
38
|
+
"require": "./dist/cjs/index.js"
|
|
39
|
+
},
|
|
40
|
+
"default": "./dist/esm/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./dist/docs.json": {
|
|
43
|
+
"default": "./dist/docs.json"
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"main": "dist/cjs/index.js",
|
|
48
|
+
"module": "dist/esm/index.js",
|
|
49
|
+
"homepage": "https://xyo.network",
|
|
50
|
+
"license": "LGPL-3.0-only",
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
|
|
57
|
+
},
|
|
58
|
+
"sideEffects": false,
|
|
59
|
+
"types": "dist/esm/index.d.ts",
|
|
60
|
+
"version": "2.42.16"
|
|
61
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { XyoBoundWitness, XyoBoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { dumpErrors } from '@xyo-network/core'
|
|
3
|
+
|
|
4
|
+
import { BoundWitnessValidator } from './Validator'
|
|
5
|
+
|
|
6
|
+
const testBoundWitness: XyoBoundWitness = {
|
|
7
|
+
_signatures: ['95100e5fd2012b958e96895870cfac5353c3a33a19314cfd1304ef7d01d052ec2a3ef80d6449cf88d463027fe0d868ed8cfb8b7323d37e93a08570233eea0b17'],
|
|
8
|
+
addresses: ['5346a2ce56ec4177b67092bda710e150ba6fa046'],
|
|
9
|
+
payload_hashes: ['20e14207f952a09f767ff614a648546c037fe524ace0bfe55db31f818aff1f1c'],
|
|
10
|
+
payload_schemas: ['network.xyo.test'],
|
|
11
|
+
previous_hashes: [null],
|
|
12
|
+
schema: XyoBoundWitnessSchema,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
test('all', () => {
|
|
16
|
+
const validator = new BoundWitnessValidator(testBoundWitness)
|
|
17
|
+
const errors = validator.validate()
|
|
18
|
+
dumpErrors(errors)
|
|
19
|
+
expect(errors.length).toBe(0)
|
|
20
|
+
})
|
package/src/Validator.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { AddressValue } from '@xyo-network/account'
|
|
2
|
+
import { XyoBoundWitness, XyoBoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
3
|
+
import { Hasher } from '@xyo-network/core'
|
|
4
|
+
import { PayloadValidator, XyoSchemaNameValidator } from '@xyo-network/payload-validator'
|
|
5
|
+
import { validateType } from '@xyo-network/typeof'
|
|
6
|
+
import uniq from 'lodash/uniq'
|
|
7
|
+
|
|
8
|
+
const validateArraysSameLength = (a: unknown[], b: unknown[], message = 'Array length mismatch') => {
|
|
9
|
+
return a.length != b.length ? [Error(`${message} []`)] : []
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class BoundWitnessValidator<T extends XyoBoundWitness<{ schema: string }> = XyoBoundWitness> extends PayloadValidator<T> {
|
|
13
|
+
public get hash() {
|
|
14
|
+
return new Hasher(this.obj).hash
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static validateSignature(hash: string, address: string, signature?: string) {
|
|
18
|
+
if (!signature) {
|
|
19
|
+
return [Error(`Missing signature [${address}]`)]
|
|
20
|
+
}
|
|
21
|
+
if (!new AddressValue(address).verify(hash, signature)) {
|
|
22
|
+
return [Error(`Invalid signature [${address}] [${signature}]`)]
|
|
23
|
+
}
|
|
24
|
+
return []
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public addresses() {
|
|
28
|
+
const errors: Error[] = []
|
|
29
|
+
const { addresses } = this.obj
|
|
30
|
+
if (!addresses?.length) errors.push(new Error('addresses missing [at least one address required]'))
|
|
31
|
+
errors.push(...this.addressesUniqueness())
|
|
32
|
+
return errors
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public addressesUniqueness() {
|
|
36
|
+
const errors: Error[] = []
|
|
37
|
+
const { addresses } = this.obj
|
|
38
|
+
const uniqAddresses = uniq(addresses)
|
|
39
|
+
if (addresses?.length !== uniqAddresses?.length) errors.push(new Error('addresses must be unique'))
|
|
40
|
+
return errors
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public previousHashes() {
|
|
44
|
+
const errors: Error[] = []
|
|
45
|
+
return errors
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public schema() {
|
|
49
|
+
const errors: Error[] = []
|
|
50
|
+
const expectedSchema = XyoBoundWitnessSchema
|
|
51
|
+
if (this.obj.schema !== expectedSchema) {
|
|
52
|
+
errors.push(new Error(`invalid schema [${expectedSchema} !== ${this.obj.schema}]`))
|
|
53
|
+
}
|
|
54
|
+
return errors
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public schemas() {
|
|
58
|
+
const errors: Error[] = []
|
|
59
|
+
const Schemas = this.obj.payload_schemas
|
|
60
|
+
if (Schemas) {
|
|
61
|
+
const schemaValidators: XyoSchemaNameValidator[] = Schemas.map((schema: string) => {
|
|
62
|
+
return new XyoSchemaNameValidator(schema)
|
|
63
|
+
})
|
|
64
|
+
schemaValidators.forEach((validator) => {
|
|
65
|
+
errors.push(...validator.all())
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
return errors
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public signatures() {
|
|
72
|
+
return [
|
|
73
|
+
...validateArraysSameLength(this.obj._signatures ?? [], this.obj.addresses, 'Length mismatch: address/_signature'),
|
|
74
|
+
...this.obj.addresses.reduce<Error[]>((errors, address, index) => {
|
|
75
|
+
errors.push(...BoundWitnessValidator.validateSignature(this.hash, address, this.obj._signatures?.[index]))
|
|
76
|
+
return errors
|
|
77
|
+
}, []),
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public override validate() {
|
|
82
|
+
return [
|
|
83
|
+
...this.signatures(),
|
|
84
|
+
...this.addresses(),
|
|
85
|
+
...this.validateArrayLengths(),
|
|
86
|
+
...this.schemas(),
|
|
87
|
+
...this.previousHashes(),
|
|
88
|
+
...this.schema(),
|
|
89
|
+
...super.validate(),
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public validateArrayLengths() {
|
|
94
|
+
const errors: Error[] = []
|
|
95
|
+
errors.push(...this.validatePayloadHashesLength())
|
|
96
|
+
return errors
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
public validatePayloadHashesLength() {
|
|
100
|
+
const errors: Error[] = []
|
|
101
|
+
errors.push(...this.validateArrayLength('payload_hashes', 'payload_schemas'))
|
|
102
|
+
return errors
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private validateArrayLength(fieldName: string, compareArrayName: string) {
|
|
106
|
+
const errors: Error[] = []
|
|
107
|
+
|
|
108
|
+
const [array, arrayErrors] = validateType('array', this.stringKeyObj[fieldName] as [], true)
|
|
109
|
+
const [compareArray, compareArrayErrors] = validateType('array', this.stringKeyObj[compareArrayName] as [], true)
|
|
110
|
+
|
|
111
|
+
if (array?.length !== compareArray?.length) {
|
|
112
|
+
errors.push(new Error(`${fieldName}/${compareArrayName} count mismatch [${array?.length} !== ${compareArray?.length}]`))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return [...arrayErrors, ...compareArrayErrors, ...errors]
|
|
116
|
+
}
|
|
117
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Validator'
|