@xyo-network/xl1-schema 1.7.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 +230 -0
- package/dist/neutral/Executable.d.ts +4 -0
- package/dist/neutral/Executable.d.ts.map +1 -0
- package/dist/neutral/Executable.spec.d.ts +2 -0
- package/dist/neutral/Executable.spec.d.ts.map +1 -0
- package/dist/neutral/StorageMeta.d.ts +4 -0
- package/dist/neutral/StorageMeta.d.ts.map +1 -0
- package/dist/neutral/StorageMeta.spec.d.ts +2 -0
- package/dist/neutral/StorageMeta.spec.d.ts.map +1 -0
- package/dist/neutral/boundwitness/BlockBoundWitness.d.ts +6 -0
- package/dist/neutral/boundwitness/BlockBoundWitness.d.ts.map +1 -0
- package/dist/neutral/boundwitness/BlockBoundWitness.spec.d.ts +2 -0
- package/dist/neutral/boundwitness/BlockBoundWitness.spec.d.ts.map +1 -0
- package/dist/neutral/boundwitness/BlockBoundWitnessWithStorageMeta.d.ts +7 -0
- package/dist/neutral/boundwitness/BlockBoundWitnessWithStorageMeta.d.ts.map +1 -0
- package/dist/neutral/boundwitness/TransactionBoundWitness.d.ts +6 -0
- package/dist/neutral/boundwitness/TransactionBoundWitness.d.ts.map +1 -0
- package/dist/neutral/boundwitness/TransactionBoundWitnessWithStorageMeta.d.ts +6 -0
- package/dist/neutral/boundwitness/TransactionBoundWitnessWithStorageMeta.d.ts.map +1 -0
- package/dist/neutral/boundwitness/index.d.ts +5 -0
- package/dist/neutral/boundwitness/index.d.ts.map +1 -0
- package/dist/neutral/index.d.ts +5 -0
- package/dist/neutral/index.d.ts.map +1 -0
- package/dist/neutral/index.mjs +390 -0
- package/dist/neutral/index.mjs.map +1 -0
- package/dist/neutral/payload/ChainStakeIntent.d.ts +6 -0
- package/dist/neutral/payload/ChainStakeIntent.d.ts.map +1 -0
- package/dist/neutral/payload/ChainStakeIntent.spec.d.ts +2 -0
- package/dist/neutral/payload/ChainStakeIntent.spec.d.ts.map +1 -0
- package/dist/neutral/payload/HashPayload.d.ts +6 -0
- package/dist/neutral/payload/HashPayload.d.ts.map +1 -0
- package/dist/neutral/payload/HashPayload.spec.d.ts +2 -0
- package/dist/neutral/payload/HashPayload.spec.d.ts.map +1 -0
- package/dist/neutral/payload/TransferPayload.d.ts +6 -0
- package/dist/neutral/payload/TransferPayload.d.ts.map +1 -0
- package/dist/neutral/payload/TransferPayload.spec.d.ts +2 -0
- package/dist/neutral/payload/TransferPayload.spec.d.ts.map +1 -0
- package/dist/neutral/payload/index.d.ts +4 -0
- package/dist/neutral/payload/index.d.ts.map +1 -0
- package/package.json +64 -0
- package/src/Executable.spec.ts +43 -0
- package/src/Executable.ts +10 -0
- package/src/StorageMeta.spec.ts +64 -0
- package/src/StorageMeta.ts +14 -0
- package/src/boundwitness/BlockBoundWitness.spec.ts +229 -0
- package/src/boundwitness/BlockBoundWitness.ts +32 -0
- package/src/boundwitness/BlockBoundWitnessWithStorageMeta.ts +26 -0
- package/src/boundwitness/TransactionBoundWitness.ts +41 -0
- package/src/boundwitness/TransactionBoundWitnessWithStorageMeta.ts +30 -0
- package/src/boundwitness/index.ts +4 -0
- package/src/index.ts +4 -0
- package/src/payload/ChainStakeIntent.spec.ts +81 -0
- package/src/payload/ChainStakeIntent.ts +24 -0
- package/src/payload/HashPayload.spec.ts +74 -0
- package/src/payload/HashPayload.ts +23 -0
- package/src/payload/TransferPayload.spec.ts +84 -0
- package/src/payload/TransferPayload.ts +31 -0
- package/src/payload/index.ts +3 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Ajv } from 'ajv'
|
|
2
|
+
import {
|
|
3
|
+
describe, expect, test,
|
|
4
|
+
} from 'vitest'
|
|
5
|
+
|
|
6
|
+
import { StorageMetaJsonSchema } from './StorageMeta.ts'
|
|
7
|
+
|
|
8
|
+
const ajv = new Ajv()
|
|
9
|
+
|
|
10
|
+
describe('StorageMetaJsonSchema', () => {
|
|
11
|
+
test('should have the correct $id', () => {
|
|
12
|
+
expect(StorageMetaJsonSchema.$id).toBe('https://schemas.xyo.network/2.0/storage-meta')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('should validate a valid storage meta payload', () => {
|
|
16
|
+
const validate = ajv.compile(StorageMetaJsonSchema)
|
|
17
|
+
const validPayload = {
|
|
18
|
+
_sequence: 'a1b2c3d4',
|
|
19
|
+
_hash: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
20
|
+
_dataHash: 'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
21
|
+
}
|
|
22
|
+
const result = validate(validPayload)
|
|
23
|
+
expect(result).toBe(true)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('should invalidate a payload with missing required fields', () => {
|
|
27
|
+
const validate = ajv.compile(StorageMetaJsonSchema)
|
|
28
|
+
const invalidPayload = {
|
|
29
|
+
_sequence: 'a1b2c3d4',
|
|
30
|
+
_hash: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
31
|
+
}
|
|
32
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('should invalidate a payload with invalid _sequence pattern', () => {
|
|
36
|
+
const validate = ajv.compile(StorageMetaJsonSchema)
|
|
37
|
+
const invalidPayload = {
|
|
38
|
+
_sequence: 'invalid-sequence',
|
|
39
|
+
_hash: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
40
|
+
_dataHash: 'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
41
|
+
}
|
|
42
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('should invalidate a payload with invalid _hash pattern', () => {
|
|
46
|
+
const validate = ajv.compile(StorageMetaJsonSchema)
|
|
47
|
+
const invalidPayload = {
|
|
48
|
+
_sequence: 'a1b2c3d4',
|
|
49
|
+
_hash: 'invalid-hash',
|
|
50
|
+
_dataHash: 'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
51
|
+
}
|
|
52
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('should invalidate a payload with invalid _dataHash pattern', () => {
|
|
56
|
+
const validate = ajv.compile(StorageMetaJsonSchema)
|
|
57
|
+
const invalidPayload = {
|
|
58
|
+
_sequence: 'a1b2c3d4',
|
|
59
|
+
_hash: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
60
|
+
_dataHash: 'invalid-data-hash',
|
|
61
|
+
}
|
|
62
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
63
|
+
})
|
|
64
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { StorageMeta } from '@xyo-network/payload-model'
|
|
2
|
+
import { HashRegEx, HexRegEx } from '@xyo-network/payload-wrapper'
|
|
3
|
+
import type { JSONSchemaType } from 'ajv'
|
|
4
|
+
|
|
5
|
+
export const StorageMetaJsonSchema: JSONSchemaType<StorageMeta> = {
|
|
6
|
+
$id: 'https://schemas.xyo.network/2.0/storage-meta',
|
|
7
|
+
properties: {
|
|
8
|
+
_sequence: { type: 'string', pattern: HexRegEx },
|
|
9
|
+
_hash: { type: 'string', pattern: HashRegEx },
|
|
10
|
+
_dataHash: { type: 'string', pattern: HashRegEx },
|
|
11
|
+
},
|
|
12
|
+
required: ['_sequence', '_hash', '_dataHash'],
|
|
13
|
+
type: 'object',
|
|
14
|
+
} as const
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { Ajv } from 'ajv'
|
|
3
|
+
import {
|
|
4
|
+
describe, expect, test,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { BlockBoundWitnessJsonSchema } from './BlockBoundWitness.ts'
|
|
8
|
+
|
|
9
|
+
const ajv = new Ajv()
|
|
10
|
+
|
|
11
|
+
describe('BlockBoundWitnessJsonSchema', () => {
|
|
12
|
+
test('should have the correct $id', () => {
|
|
13
|
+
expect(BlockBoundWitnessJsonSchema.$id).toBe('https://schemas.xyo.network/2.0/block')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('should validate a valid BlockBoundWitness payload', () => {
|
|
17
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
18
|
+
const validPayload = {
|
|
19
|
+
addresses: [],
|
|
20
|
+
block: 1,
|
|
21
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
22
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
23
|
+
payload_hashes: [],
|
|
24
|
+
payload_schemas: [],
|
|
25
|
+
previous_hashes: [],
|
|
26
|
+
step_hashes: [
|
|
27
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
28
|
+
'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
29
|
+
],
|
|
30
|
+
$epoch: 1_234_567_890,
|
|
31
|
+
schema: BoundWitnessSchema,
|
|
32
|
+
}
|
|
33
|
+
const result = validate(validPayload)
|
|
34
|
+
expect(validate.errors).toBe(null)
|
|
35
|
+
expect(result).toBe(true)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('should validate a valid BlockBoundWitness payload with payload_hashes, payload_schemas, and previous_hashes', () => {
|
|
39
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
40
|
+
const validPayload = {
|
|
41
|
+
addresses: [],
|
|
42
|
+
block: 1,
|
|
43
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
44
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
45
|
+
payload_hashes: [
|
|
46
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
47
|
+
],
|
|
48
|
+
payload_schemas: ['valid.schema'],
|
|
49
|
+
previous_hashes: [
|
|
50
|
+
'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
51
|
+
],
|
|
52
|
+
step_hashes: [
|
|
53
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
54
|
+
],
|
|
55
|
+
$epoch: 1_234_567_890,
|
|
56
|
+
schema: BoundWitnessSchema,
|
|
57
|
+
}
|
|
58
|
+
const result = validate(validPayload)
|
|
59
|
+
expect(validate.errors).toBe(null)
|
|
60
|
+
expect(result).toBe(true)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('should invalidate a payload with missing required fields', () => {
|
|
64
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
65
|
+
const invalidPayload = {
|
|
66
|
+
block: 1,
|
|
67
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
68
|
+
}
|
|
69
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('should invalidate a payload with invalid chain pattern', () => {
|
|
73
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
74
|
+
const invalidPayload = {
|
|
75
|
+
addresses: [],
|
|
76
|
+
payload_hashes: [],
|
|
77
|
+
payload_schemas: [],
|
|
78
|
+
previous_hashes: [],
|
|
79
|
+
block: 1,
|
|
80
|
+
chain: 'invalid-chain',
|
|
81
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
82
|
+
step_hashes: ['a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2'],
|
|
83
|
+
$epoch: 1_234_567_890,
|
|
84
|
+
schema: 'BoundWitnessSchema',
|
|
85
|
+
}
|
|
86
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('should invalidate a payload with invalid chain pattern (0x prefix)', () => {
|
|
90
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
91
|
+
const invalidPayload = {
|
|
92
|
+
addresses: [],
|
|
93
|
+
payload_hashes: [],
|
|
94
|
+
payload_schemas: [],
|
|
95
|
+
previous_hashes: [],
|
|
96
|
+
block: 1,
|
|
97
|
+
chain: '0x1234567890abcdef1234567890abcdef12345678',
|
|
98
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
99
|
+
step_hashes: ['a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2'],
|
|
100
|
+
$epoch: 1_234_567_890,
|
|
101
|
+
schema: 'BoundWitnessSchema',
|
|
102
|
+
}
|
|
103
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('should invalidate a payload with invalid step_hashes pattern', () => {
|
|
107
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
108
|
+
const invalidPayload = {
|
|
109
|
+
addresses: [],
|
|
110
|
+
payload_hashes: [],
|
|
111
|
+
payload_schemas: [],
|
|
112
|
+
previous_hashes: [],
|
|
113
|
+
block: 1,
|
|
114
|
+
chain: '0x1234567890abcdef1234567890abcdef12345678',
|
|
115
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
116
|
+
step_hashes: ['invalid-hash'],
|
|
117
|
+
$epoch: 1_234_567_890,
|
|
118
|
+
schema: 'BoundWitnessSchema',
|
|
119
|
+
}
|
|
120
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('should invalidate a payload with invalid schema pattern', () => {
|
|
124
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
125
|
+
const invalidPayload = {
|
|
126
|
+
addresses: [],
|
|
127
|
+
payload_hashes: [],
|
|
128
|
+
payload_schemas: [],
|
|
129
|
+
previous_hashes: [],
|
|
130
|
+
block: 1,
|
|
131
|
+
chain: '0x1234567890abcdef1234567890abcdef12345678',
|
|
132
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
133
|
+
step_hashes: [
|
|
134
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
135
|
+
],
|
|
136
|
+
$epoch: 1_234_567_890,
|
|
137
|
+
schema: 'InvalidSchema',
|
|
138
|
+
}
|
|
139
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('should invalidate a payload with invalid payload_hashes', () => {
|
|
143
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
144
|
+
const invalidPayload = {
|
|
145
|
+
addresses: [],
|
|
146
|
+
block: 1,
|
|
147
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
148
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
149
|
+
payload_hashes: ['invalid-hash'],
|
|
150
|
+
payload_schemas: ['valid.schema'],
|
|
151
|
+
previous_hashes: [
|
|
152
|
+
'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
153
|
+
],
|
|
154
|
+
step_hashes: [
|
|
155
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
156
|
+
],
|
|
157
|
+
$epoch: 1_234_567_890,
|
|
158
|
+
schema: BoundWitnessSchema,
|
|
159
|
+
}
|
|
160
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test('should invalidate a payload with invalid payload_schemas', () => {
|
|
164
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
165
|
+
const invalidPayload = {
|
|
166
|
+
addresses: [],
|
|
167
|
+
block: 1,
|
|
168
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
169
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
170
|
+
payload_hashes: [
|
|
171
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
172
|
+
],
|
|
173
|
+
payload_schemas: ['InvalidSchema'],
|
|
174
|
+
previous_hashes: [
|
|
175
|
+
'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
176
|
+
],
|
|
177
|
+
step_hashes: [
|
|
178
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
179
|
+
],
|
|
180
|
+
$epoch: 1_234_567_890,
|
|
181
|
+
schema: BoundWitnessSchema,
|
|
182
|
+
}
|
|
183
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
test('should invalidate a payload with invalid previous_hashes', () => {
|
|
187
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
188
|
+
const invalidPayload = {
|
|
189
|
+
addresses: [],
|
|
190
|
+
block: 1,
|
|
191
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
192
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
193
|
+
payload_hashes: [
|
|
194
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
195
|
+
],
|
|
196
|
+
payload_schemas: ['valid.schema'],
|
|
197
|
+
previous_hashes: ['invalid-hash'],
|
|
198
|
+
step_hashes: [
|
|
199
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
200
|
+
],
|
|
201
|
+
$epoch: 1_234_567_890,
|
|
202
|
+
schema: BoundWitnessSchema,
|
|
203
|
+
}
|
|
204
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
test('should invalidate a payload with invalid $epoch', () => {
|
|
208
|
+
const validate = ajv.compile(BlockBoundWitnessJsonSchema)
|
|
209
|
+
const invalidPayload = {
|
|
210
|
+
addresses: [],
|
|
211
|
+
block: 1,
|
|
212
|
+
chain: '1234567890abcdef1234567890abcdef12345678',
|
|
213
|
+
previous: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
214
|
+
payload_hashes: [
|
|
215
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
216
|
+
],
|
|
217
|
+
payload_schemas: ['valid.schema'],
|
|
218
|
+
previous_hashes: [
|
|
219
|
+
'b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2',
|
|
220
|
+
],
|
|
221
|
+
step_hashes: [
|
|
222
|
+
'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
223
|
+
],
|
|
224
|
+
$epoch: 'invalid-epoch', // Invalid $epoch
|
|
225
|
+
schema: BoundWitnessSchema,
|
|
226
|
+
}
|
|
227
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
228
|
+
})
|
|
229
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { boundWitnessJsonSchema, boundWitnessProperties } from '@xyo-network/boundwitness-wrapper'
|
|
3
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
4
|
+
import { AddressRegEx, HashRegEx } from '@xyo-network/payload-wrapper'
|
|
5
|
+
import type { SchemaPayload } from '@xyo-network/schema-payload-plugin'
|
|
6
|
+
import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
|
|
7
|
+
import type { BlockBoundWitness } from '@xyo-network/xl1-protocol'
|
|
8
|
+
import type { JSONSchemaType } from 'ajv'
|
|
9
|
+
|
|
10
|
+
export const BlockBoundWitnessJsonSchema: JSONSchemaType<BlockBoundWitness> = {
|
|
11
|
+
...boundWitnessJsonSchema,
|
|
12
|
+
$id: 'https://schemas.xyo.network/2.0/block',
|
|
13
|
+
properties: {
|
|
14
|
+
...boundWitnessProperties,
|
|
15
|
+
block: { type: 'integer' },
|
|
16
|
+
chain: { type: 'string', pattern: AddressRegEx },
|
|
17
|
+
previous: {
|
|
18
|
+
type: 'string', pattern: HashRegEx, nullable: true,
|
|
19
|
+
},
|
|
20
|
+
step_hashes: {
|
|
21
|
+
items: { type: 'string', pattern: HashRegEx },
|
|
22
|
+
type: 'array',
|
|
23
|
+
},
|
|
24
|
+
$epoch: { type: 'integer' },
|
|
25
|
+
schema: { type: 'string', pattern: BoundWitnessSchema },
|
|
26
|
+
},
|
|
27
|
+
required: [...boundWitnessJsonSchema.required, 'block', 'chain', 'step_hashes', 'previous', '$epoch'],
|
|
28
|
+
type: 'object',
|
|
29
|
+
} as const
|
|
30
|
+
|
|
31
|
+
export const BlockBoundWitnessSchemaPayload = new PayloadBuilder<SchemaPayload>({ schema: SchemaSchema })
|
|
32
|
+
.fields({ definition: BlockBoundWitnessJsonSchema }).build()
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { boundWitnessJsonSchema, boundWitnessProperties } from '@xyo-network/boundwitness-wrapper'
|
|
3
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
4
|
+
import type { WithStorageMeta } from '@xyo-network/payload-model'
|
|
5
|
+
import type { SchemaPayload } from '@xyo-network/schema-payload-plugin'
|
|
6
|
+
import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
|
|
7
|
+
import type { BlockBoundWitness } from '@xyo-network/xl1-protocol'
|
|
8
|
+
import type { JSONSchemaType } from 'ajv'
|
|
9
|
+
|
|
10
|
+
import { StorageMetaJsonSchema } from '../StorageMeta.ts'
|
|
11
|
+
import { BlockBoundWitnessJsonSchema } from './BlockBoundWitness.ts'
|
|
12
|
+
|
|
13
|
+
export const BlockBoundWitnessWithStorageMetaJsonSchema: JSONSchemaType<WithStorageMeta<BlockBoundWitness>> = {
|
|
14
|
+
$id: 'https://schemas.xyo.network/2.0/block-with-storage-meta',
|
|
15
|
+
properties: {
|
|
16
|
+
...boundWitnessProperties,
|
|
17
|
+
...BlockBoundWitnessJsonSchema.properties,
|
|
18
|
+
...StorageMetaJsonSchema.properties,
|
|
19
|
+
schema: { type: 'string', pattern: BoundWitnessSchema },
|
|
20
|
+
},
|
|
21
|
+
required: [...new Set([...boundWitnessJsonSchema.required, ...BlockBoundWitnessJsonSchema.required, ...StorageMetaJsonSchema.required])],
|
|
22
|
+
type: 'object',
|
|
23
|
+
} as const
|
|
24
|
+
|
|
25
|
+
export const BlockBoundWitnessWithStorageMetaSchemaPayload = new PayloadBuilder<SchemaPayload>({ schema: SchemaSchema })
|
|
26
|
+
.fields({ definition: BlockBoundWitnessWithStorageMetaJsonSchema }).build()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { boundWitnessJsonSchema } from '@xyo-network/boundwitness-wrapper'
|
|
3
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
4
|
+
import { AddressRegEx, Uint256RegEx } from '@xyo-network/payload-wrapper'
|
|
5
|
+
import type { SchemaPayload } from '@xyo-network/schema-payload-plugin'
|
|
6
|
+
import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
|
|
7
|
+
import type { TransactionBoundWitness } from '@xyo-network/xl1-protocol'
|
|
8
|
+
import type { JSONSchemaType } from 'ajv'
|
|
9
|
+
|
|
10
|
+
import { ExecutableJsonSchema } from '../Executable.ts'
|
|
11
|
+
|
|
12
|
+
export const TransactionBoundWitnessJsonSchema: JSONSchemaType<TransactionBoundWitness> = {
|
|
13
|
+
...boundWitnessJsonSchema,
|
|
14
|
+
$id: 'https://schemas.xyo.network/2.0/transaction',
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: {
|
|
17
|
+
...boundWitnessJsonSchema.properties,
|
|
18
|
+
...ExecutableJsonSchema.properties,
|
|
19
|
+
chain: { type: 'string', pattern: AddressRegEx },
|
|
20
|
+
fees: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
base: { type: 'string', pattern: Uint256RegEx },
|
|
24
|
+
gasLimit: { type: 'string', pattern: Uint256RegEx },
|
|
25
|
+
gasPrice: { type: 'string', pattern: Uint256RegEx },
|
|
26
|
+
priority: { type: 'string', pattern: Uint256RegEx },
|
|
27
|
+
},
|
|
28
|
+
required: ['base'],
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
from: { type: 'string', pattern: AddressRegEx },
|
|
32
|
+
nbf: { type: 'integer' },
|
|
33
|
+
exp: { type: 'integer' },
|
|
34
|
+
schema: { type: 'string', pattern: BoundWitnessSchema },
|
|
35
|
+
},
|
|
36
|
+
required: [...boundWitnessJsonSchema.required, 'chain', 'fees', 'nbf', 'exp'],
|
|
37
|
+
type: 'object',
|
|
38
|
+
} as const
|
|
39
|
+
|
|
40
|
+
export const TransactionBoundWitnessSchemaPayload = new PayloadBuilder<SchemaPayload>({ schema: SchemaSchema })
|
|
41
|
+
.fields({ definition: TransactionBoundWitnessJsonSchema }).build()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BoundWitnessSchema } from '@xyo-network/boundwitness-model'
|
|
2
|
+
import { boundWitnessJsonSchema } from '@xyo-network/boundwitness-wrapper'
|
|
3
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
4
|
+
import { AddressRegEx, Uint256RegEx } from '@xyo-network/payload-wrapper'
|
|
5
|
+
import type { SchemaPayload } from '@xyo-network/schema-payload-plugin'
|
|
6
|
+
import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
|
|
7
|
+
import type { TransactionBoundWitness } from '@xyo-network/xl1-protocol'
|
|
8
|
+
import type { JSONSchemaType } from 'ajv'
|
|
9
|
+
|
|
10
|
+
import { StorageMetaJsonSchema } from '../StorageMeta.ts'
|
|
11
|
+
|
|
12
|
+
export const TransactionBoundWitnessWithStorageMetaJsonSchema: JSONSchemaType<TransactionBoundWitness> = {
|
|
13
|
+
...boundWitnessJsonSchema,
|
|
14
|
+
$id: 'https://schemas.xyo.network/2.0/transaction-with-storage-meta',
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: {
|
|
17
|
+
...boundWitnessJsonSchema.properties,
|
|
18
|
+
...StorageMetaJsonSchema.properties,
|
|
19
|
+
chain: { type: 'string', pattern: AddressRegEx },
|
|
20
|
+
gas: { type: 'string', pattern: Uint256RegEx },
|
|
21
|
+
nbf: { type: 'integer' },
|
|
22
|
+
exp: { type: 'integer' },
|
|
23
|
+
schema: { type: 'string', pattern: BoundWitnessSchema },
|
|
24
|
+
},
|
|
25
|
+
required: [...boundWitnessJsonSchema.required, ...StorageMetaJsonSchema.required, 'chain', 'gas', 'nbf', 'exp'],
|
|
26
|
+
type: 'object',
|
|
27
|
+
} as const
|
|
28
|
+
|
|
29
|
+
export const TransactionBoundWitnessWithStorageMetaSchemaPayload = new PayloadBuilder<SchemaPayload>({ schema: SchemaSchema })
|
|
30
|
+
.fields({ definition: TransactionBoundWitnessWithStorageMetaJsonSchema }).build()
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Account } from '@xyo-network/account'
|
|
2
|
+
import { ChainStakeIntentSchema } from '@xyo-network/xl1-protocol'
|
|
3
|
+
import { Ajv } from 'ajv'
|
|
4
|
+
import {
|
|
5
|
+
describe, expect, test,
|
|
6
|
+
} from 'vitest'
|
|
7
|
+
|
|
8
|
+
import { ChainStakeIntentPayloadJsonSchema } from './ChainStakeIntent.ts'
|
|
9
|
+
|
|
10
|
+
const ajv = new Ajv()
|
|
11
|
+
|
|
12
|
+
describe('ChainStakeIntentPayloadJsonSchema', () => {
|
|
13
|
+
test('should have the correct $id', () => {
|
|
14
|
+
expect(ChainStakeIntentPayloadJsonSchema.$id).toBe('https://schemas.xyo.network/2.0/payload/chain-stake-intent')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('should define the correct properties', () => {
|
|
18
|
+
const properties = ChainStakeIntentPayloadJsonSchema.properties
|
|
19
|
+
expect(properties).toHaveProperty('from')
|
|
20
|
+
expect(properties).toHaveProperty('intent')
|
|
21
|
+
expect(properties).toHaveProperty('schema')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('should include required fields', () => {
|
|
25
|
+
expect(ChainStakeIntentPayloadJsonSchema.required).toContain('intent')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('should have type "object"', () => {
|
|
29
|
+
expect(ChainStakeIntentPayloadJsonSchema.type).toBe('object')
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('should validate a valid payload', async () => {
|
|
33
|
+
const fromAddress = (await Account.random()).address
|
|
34
|
+
const validate = ajv.compile(ChainStakeIntentPayloadJsonSchema)
|
|
35
|
+
const validPayload = {
|
|
36
|
+
from: fromAddress,
|
|
37
|
+
intent: 'producer',
|
|
38
|
+
schema: ChainStakeIntentSchema,
|
|
39
|
+
}
|
|
40
|
+
const result = validate(validPayload)
|
|
41
|
+
expect(result).toBe(true)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('should invalidate a payload with an invalid "from" address', () => {
|
|
45
|
+
const validate = ajv.compile(ChainStakeIntentPayloadJsonSchema)
|
|
46
|
+
const invalidPayload = {
|
|
47
|
+
from: 'invalid-address',
|
|
48
|
+
intent: 'producer',
|
|
49
|
+
schema: ChainStakeIntentSchema,
|
|
50
|
+
}
|
|
51
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('should invalidate a payload with an invalid "intent"', async () => {
|
|
55
|
+
const fromAddress = (await Account.random()).address
|
|
56
|
+
const validate = ajv.compile(ChainStakeIntentPayloadJsonSchema)
|
|
57
|
+
const invalidPayload = {
|
|
58
|
+
from: fromAddress,
|
|
59
|
+
intent: 'invalid-intent',
|
|
60
|
+
schema: ChainStakeIntentSchema,
|
|
61
|
+
}
|
|
62
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('should invalidate a payload with an invalid "schema"', async () => {
|
|
66
|
+
const fromAddress = (await Account.random()).address
|
|
67
|
+
const validate = ajv.compile(ChainStakeIntentPayloadJsonSchema)
|
|
68
|
+
const invalidPayload = {
|
|
69
|
+
from: fromAddress,
|
|
70
|
+
intent: 'producer',
|
|
71
|
+
schema: 'invalid-schema',
|
|
72
|
+
}
|
|
73
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('should invalidate a payload missing required fields', () => {
|
|
77
|
+
const validate = ajv.compile(ChainStakeIntentPayloadJsonSchema)
|
|
78
|
+
const invalidPayload = { from: 'valid-address' }
|
|
79
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
80
|
+
})
|
|
81
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
2
|
+
import { AddressRegEx, payloadJsonSchema } from '@xyo-network/payload-wrapper'
|
|
3
|
+
import type { SchemaPayload } from '@xyo-network/schema-payload-plugin'
|
|
4
|
+
import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
|
|
5
|
+
import type { ChainStakeIntent } from '@xyo-network/xl1-protocol'
|
|
6
|
+
import { ChainStakeIntentSchema } from '@xyo-network/xl1-protocol'
|
|
7
|
+
import type { JSONSchemaType } from 'ajv'
|
|
8
|
+
|
|
9
|
+
export const ChainStakeIntentPayloadJsonSchema: JSONSchemaType<ChainStakeIntent> = {
|
|
10
|
+
...payloadJsonSchema,
|
|
11
|
+
$id: 'https://schemas.xyo.network/2.0/payload/chain-stake-intent',
|
|
12
|
+
additionalProperties: false,
|
|
13
|
+
properties: {
|
|
14
|
+
...payloadJsonSchema.properties,
|
|
15
|
+
from: { type: 'string', pattern: AddressRegEx },
|
|
16
|
+
intent: { type: 'string', enum: ['producer'] },
|
|
17
|
+
schema: { type: 'string', pattern: ChainStakeIntentSchema },
|
|
18
|
+
},
|
|
19
|
+
required: [...payloadJsonSchema.required, 'intent'],
|
|
20
|
+
type: 'object',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const ChainStakeIntentPayloadJsonSchemaPayload = new PayloadBuilder<SchemaPayload>({ schema: SchemaSchema })
|
|
24
|
+
.fields({ definition: ChainStakeIntentPayloadJsonSchema }).build()
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { HashSchema } from '@xyo-network/xl1-protocol'
|
|
2
|
+
import { Ajv } from 'ajv'
|
|
3
|
+
import {
|
|
4
|
+
describe, expect, test,
|
|
5
|
+
} from 'vitest'
|
|
6
|
+
|
|
7
|
+
import { HashPayloadJsonSchema } from './HashPayload.ts'
|
|
8
|
+
|
|
9
|
+
const ajv = new Ajv()
|
|
10
|
+
|
|
11
|
+
describe('HashPayloadJsonSchema', () => {
|
|
12
|
+
test('should have the correct $id', () => {
|
|
13
|
+
expect(HashPayloadJsonSchema.$id).toBe('https://schemas.xyo.network/2.0/payload/hash')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('should define the correct properties', () => {
|
|
17
|
+
const properties = HashPayloadJsonSchema.properties
|
|
18
|
+
expect(properties).toHaveProperty('hash')
|
|
19
|
+
expect(properties).toHaveProperty('schema')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('should include required fields', () => {
|
|
23
|
+
expect(HashPayloadJsonSchema.required).toContain('hash')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('should have type "object"', () => {
|
|
27
|
+
expect(HashPayloadJsonSchema.type).toBe('object')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('should validate a valid payload', () => {
|
|
31
|
+
const validate = ajv.compile(HashPayloadJsonSchema)
|
|
32
|
+
const validPayload = {
|
|
33
|
+
hash: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2',
|
|
34
|
+
schema: HashSchema,
|
|
35
|
+
}
|
|
36
|
+
const result = validate(validPayload)
|
|
37
|
+
expect(result).toBe(true)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
test('should invalidate a payload with missing required fields', () => {
|
|
41
|
+
const validate = ajv.compile(HashPayloadJsonSchema)
|
|
42
|
+
const invalidPayload = { schema: HashSchema }
|
|
43
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('should invalidate a payload with invalid hash pattern', () => {
|
|
47
|
+
const validate = ajv.compile(HashPayloadJsonSchema)
|
|
48
|
+
const invalidPayload = {
|
|
49
|
+
hash: 'invalid-hash!',
|
|
50
|
+
schema: HashSchema,
|
|
51
|
+
}
|
|
52
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('should invalidate a payload with additional properties', () => {
|
|
56
|
+
const validate = ajv.compile(HashPayloadJsonSchema)
|
|
57
|
+
const invalidPayload = {
|
|
58
|
+
hash: 'abc123',
|
|
59
|
+
schema: HashSchema,
|
|
60
|
+
extraField: 'not-allowed',
|
|
61
|
+
}
|
|
62
|
+
expect(validate(invalidPayload)).toBe(false)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('should invalidate a payload with an invalid schema', () => {
|
|
66
|
+
const validate = ajv.compile(HashPayloadJsonSchema)
|
|
67
|
+
const invalidPayload = {
|
|
68
|
+
hash: 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2', // Valid 32-byte hash
|
|
69
|
+
schema: 'InvalidSchema', // Invalid schema
|
|
70
|
+
}
|
|
71
|
+
const result = validate(invalidPayload)
|
|
72
|
+
expect(result).toBe(false)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
2
|
+
import { HashRegEx, payloadJsonSchema } from '@xyo-network/payload-wrapper'
|
|
3
|
+
import type { SchemaPayload } from '@xyo-network/schema-payload-plugin'
|
|
4
|
+
import { SchemaSchema } from '@xyo-network/schema-payload-plugin'
|
|
5
|
+
import type { HashPayload } from '@xyo-network/xl1-protocol'
|
|
6
|
+
import { HashSchema } from '@xyo-network/xl1-protocol'
|
|
7
|
+
import type { JSONSchemaType } from 'ajv'
|
|
8
|
+
|
|
9
|
+
export const HashPayloadJsonSchema: JSONSchemaType<HashPayload> = {
|
|
10
|
+
...payloadJsonSchema,
|
|
11
|
+
$id: 'https://schemas.xyo.network/2.0/payload/hash',
|
|
12
|
+
additionalProperties: false,
|
|
13
|
+
properties: {
|
|
14
|
+
...payloadJsonSchema.properties,
|
|
15
|
+
hash: { type: 'string', pattern: HashRegEx },
|
|
16
|
+
schema: { type: 'string', pattern: HashSchema },
|
|
17
|
+
},
|
|
18
|
+
required: [...payloadJsonSchema.required, 'hash'],
|
|
19
|
+
type: 'object',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const HashPayloadJsonSchemaPayload = new PayloadBuilder<SchemaPayload>({ schema: SchemaSchema })
|
|
23
|
+
.fields({ definition: HashPayloadJsonSchema }).build()
|