@xyo-network/xl1-protocol-sdk 1.16.16 → 1.16.17

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.
Files changed (38) hide show
  1. package/package.json +5 -2
  2. package/dist/neutral/block/primitives/frames/spec/calculateFramesFromRange.spec.d.ts +0 -2
  3. package/dist/neutral/block/primitives/frames/spec/calculateFramesFromRange.spec.d.ts.map +0 -1
  4. package/dist/neutral/block/primitives/frames/spec/deepCalculateFramesFromRange.spec.d.ts +0 -2
  5. package/dist/neutral/block/primitives/frames/spec/deepCalculateFramesFromRange.spec.d.ts.map +0 -1
  6. package/dist/neutral/eip-712/spec/signAndVerify.spec.d.ts +0 -2
  7. package/dist/neutral/eip-712/spec/signAndVerify.spec.d.ts.map +0 -1
  8. package/dist/neutral/primitives/step/spec/completedStepRewardAddress.spec.d.ts +0 -2
  9. package/dist/neutral/primitives/step/spec/completedStepRewardAddress.spec.d.ts.map +0 -1
  10. package/dist/neutral/primitives/step/spec/stepTransferIndex.spec.d.ts +0 -2
  11. package/dist/neutral/primitives/step/spec/stepTransferIndex.spec.d.ts.map +0 -1
  12. package/dist/neutral/simple/network/spec/XyoNetwork.spec.d.ts +0 -2
  13. package/dist/neutral/simple/network/spec/XyoNetwork.spec.d.ts.map +0 -1
  14. package/dist/neutral/simple/permissions/spec/SimpleXyoPermissions.spec.d.ts +0 -2
  15. package/dist/neutral/simple/permissions/spec/SimpleXyoPermissions.spec.d.ts.map +0 -1
  16. package/dist/neutral/transaction/primitives/spec/transactionBlockByteCount.spec.d.ts +0 -2
  17. package/dist/neutral/transaction/primitives/spec/transactionBlockByteCount.spec.d.ts.map +0 -1
  18. package/dist/neutral/transaction/spec/signTransaction.spec.d.ts +0 -2
  19. package/dist/neutral/transaction/spec/signTransaction.spec.d.ts.map +0 -1
  20. package/dist/neutral/validation/block/error.spec.d.ts +0 -2
  21. package/dist/neutral/validation/block/error.spec.d.ts.map +0 -1
  22. package/dist/neutral/validation/lib/spec/isLocalhost.spec.d.ts +0 -2
  23. package/dist/neutral/validation/lib/spec/isLocalhost.spec.d.ts.map +0 -1
  24. package/dist/neutral/wallet/spec/paths.spec.d.ts +0 -2
  25. package/dist/neutral/wallet/spec/paths.spec.d.ts.map +0 -1
  26. package/src/block/primitives/frames/spec/__snapshots__/deepCalculateFramesFromRange.spec.ts.snap +0 -19417
  27. package/src/block/primitives/frames/spec/calculateFramesFromRange.spec.ts +0 -72
  28. package/src/block/primitives/frames/spec/deepCalculateFramesFromRange.spec.ts +0 -75
  29. package/src/eip-712/spec/signAndVerify.spec.ts +0 -27
  30. package/src/primitives/step/spec/completedStepRewardAddress.spec.ts +0 -28
  31. package/src/primitives/step/spec/stepTransferIndex.spec.ts +0 -23
  32. package/src/simple/network/spec/XyoNetwork.spec.ts +0 -77
  33. package/src/simple/permissions/spec/SimpleXyoPermissions.spec.ts +0 -93
  34. package/src/transaction/primitives/spec/transactionBlockByteCount.spec.ts +0 -245
  35. package/src/transaction/spec/signTransaction.spec.ts +0 -46
  36. package/src/validation/block/error.spec.ts +0 -20
  37. package/src/validation/lib/spec/isLocalhost.spec.ts +0 -20
  38. package/src/wallet/spec/paths.spec.ts +0 -28
@@ -1,72 +0,0 @@
1
- import {
2
- asXL1BlockRange, stepSize, XL1_BLOCK_NUMBER_ZERO,
3
- } from '@xyo-network/xl1-protocol'
4
- import {
5
- describe, expect, it,
6
- } from 'vitest'
7
-
8
- import { calculateFramesFromRange } from '../calculateFramesFromRange.ts'
9
-
10
- describe('calculateFramesFromRange', () => {
11
- it('handles range aligned with step size', () => {
12
- const step = 1 // 31
13
- const range = asXL1BlockRange([XL1_BLOCK_NUMBER_ZERO, stepSize(step) - 1], true)
14
- const [fitted, remaining] = calculateFramesFromRange(range, step)
15
-
16
- expect(fitted).toEqual([[0, 30]])
17
- expect(remaining).toEqual([])
18
- })
19
-
20
- it('handles range starting at step boundary but incomplete', () => {
21
- const step = 1
22
- const range = asXL1BlockRange([stepSize(step), stepSize(step) + 1], true)
23
- const [fitted, remaining] = calculateFramesFromRange(range, step)
24
-
25
- expect(fitted).toEqual([])
26
- expect(remaining).toEqual([range])
27
- })
28
-
29
- it('handles range starting at step boundary (step 1)', () => {
30
- const step = 1
31
- const multiplier = 2
32
- const additional = 1
33
- const range = asXL1BlockRange([stepSize(step), (stepSize(step) + additional) * multiplier], true)
34
- const [fitted, remaining] = calculateFramesFromRange(range, step)
35
-
36
- expect(fitted).toEqual([[31, 61]])
37
- expect(remaining).toEqual([[62, 64]])
38
- })
39
-
40
- it('handles range starting at step boundary (step 5)', () => {
41
- const step = 5
42
- const multiplier = 2
43
- const additional = 17
44
- const range = asXL1BlockRange([stepSize(step), (stepSize(step) + additional) * multiplier], true)
45
- const [fitted, remaining] = calculateFramesFromRange(range, step)
46
-
47
- expect(fitted).toEqual([[510_511, 1_021_021]])
48
- expect(remaining).toEqual([[1_021_022, 1_021_056]])
49
- })
50
-
51
- it('handles range starting not at step boundary', () => {
52
- const step = 1
53
- const multiplier = 2
54
- const additional = 1
55
- const range = asXL1BlockRange([stepSize(step) - additional, (stepSize(step) + additional) * multiplier], true)
56
- const [fitted, remaining] = calculateFramesFromRange(range, step)
57
-
58
- expect(fitted).toEqual([[31, 61]])
59
- expect(remaining).toEqual([[range[0], 30], [62, range[1]]])
60
- })
61
-
62
- it('handles range starting not at step boundary (step 5)', () => {
63
- const step = 5
64
- const multiplier = 2
65
- const additional = 17
66
- const range = asXL1BlockRange([stepSize(step) - additional, (stepSize(step) + additional) * multiplier], true)
67
- const [fitted, remaining] = calculateFramesFromRange(range, step)
68
-
69
- expect(fitted).toEqual([[510_511, 1_021_021]])
70
- expect(remaining).toEqual([[range[0], 510_510], [1_021_022, range[1]]])
71
- })
72
- })
@@ -1,75 +0,0 @@
1
- import { asXL1BlockRange } from '@xyo-network/xl1-protocol'
2
- import {
3
- describe, expect, it,
4
- } from 'vitest'
5
-
6
- import { deepCalculateFramesFromRange } from '../deepCalculateFramesFromRange.ts'
7
-
8
- describe('deepCalculateFramesFromRange', () => {
9
- it('calculates frames for a simple range with one step level', () => {
10
- const range = asXL1BlockRange([0, 9], true)
11
- const result = deepCalculateFramesFromRange(range)
12
-
13
- // With step 0 (size 10), this should fit in one frame
14
- expect(result).toEqual([[0, 6], [7, 7], [8, 8], [9, 9]])
15
- })
16
-
17
- it('calculates frames for a range spanning multiple step sizes', () => {
18
- const range = asXL1BlockRange([0, 250], true)
19
- const result = deepCalculateFramesFromRange(range)
20
-
21
- expect(result).toContainEqual([0, 210])
22
-
23
- expect(result).toMatchSnapshot(result)
24
- expect(result.length).toEqual(11)
25
- })
26
-
27
- it('calculates frames for range with multiple step levels - [0, 1500]', () => {
28
- const range = asXL1BlockRange([0, 1500], true)
29
- const result = deepCalculateFramesFromRange(range)
30
- expect(result).toMatchSnapshot(result)
31
- expect(result.length).toEqual(19)
32
- })
33
-
34
- it('calculates frames for range with multiple step levels - [0, 3000]', () => {
35
- const range = asXL1BlockRange([0, 3000], true)
36
- const result = deepCalculateFramesFromRange(range)
37
- expect(result).toMatchSnapshot(result)
38
- expect(result.length).toEqual(31)
39
- })
40
-
41
- it('calculates frames for range with multiple step levels = [45, 1599]', () => {
42
- const range = asXL1BlockRange([45, 1599], true)
43
- const result = deepCalculateFramesFromRange(range)
44
- expect(result).toMatchSnapshot(result)
45
- expect(result.length).toEqual(43)
46
- })
47
-
48
- it('calculates frames for range with multiple step levels = [45, 3333]', () => {
49
- const range = asXL1BlockRange([45, 3333], true)
50
- const result = deepCalculateFramesFromRange(range)
51
- expect(result).toMatchSnapshot(result)
52
- expect(result.length).toEqual(85)
53
- })
54
-
55
- it('calculates frames for range with multiple step levels - [23_145, 230_102_040]', () => {
56
- const range = asXL1BlockRange([23_145, 230_102_040], true)
57
- const result = deepCalculateFramesFromRange(range)
58
- expect(result).toMatchSnapshot(result)
59
- expect(result.length).toEqual(742)
60
- })
61
-
62
- it('calculates frames for range with multiple step levels - [23_145, 34_548_554_394]', () => {
63
- const range = asXL1BlockRange([23_145, 34_548_554_394], true)
64
- const result = deepCalculateFramesFromRange(range)
65
- expect(result).toMatchSnapshot(result)
66
- expect(result.length).toEqual(1468)
67
- })
68
-
69
- it('calculates frames for range with multiple step levels - [23_145, 4_598_734_539_845]', () => {
70
- const range = asXL1BlockRange([23_145, 4_598_734_539_845], true)
71
- const result = deepCalculateFramesFromRange(range)
72
- expect(result).toMatchSnapshot(result)
73
- expect(result.length).toEqual(2445)
74
- })
75
- })
@@ -1,27 +0,0 @@
1
- import {
2
- describe, expect, it,
3
- } from 'vitest'
4
-
5
- import { EIP712SignaturePayloadSchema } from '../Payloads/index.ts'
6
- import { signEIP712Message } from '../sign.ts'
7
- import { verifyEIP712Message } from '../verify.ts'
8
- import { samplePayload, wallet } from './fixtures.ts'
9
-
10
- describe('signEIP712Message', () => {
11
- it('should sign an EIP-712 message and return the correct payload', async () => {
12
- const payload = await signEIP712Message(wallet, samplePayload)
13
-
14
- expect(payload.address).toEqual(await wallet.getAddress())
15
- expect(payload.signature).toBeDefined()
16
- expect(payload.schema).toEqual(EIP712SignaturePayloadSchema)
17
- expect(payload.hash).toBeDefined()
18
- })
19
-
20
- it('should verify the signature of an EIP-712 message', async () => {
21
- const payload = await signEIP712Message(wallet, samplePayload)
22
-
23
- const isValidSignature = await verifyEIP712Message(samplePayload, payload)
24
-
25
- expect(isValidSignature).toBe(true)
26
- })
27
- })
@@ -1,28 +0,0 @@
1
- import { asXL1BlockNumber } from '@xyo-network/xl1-protocol'
2
- import {
3
- describe, expect, it,
4
- } from 'vitest'
5
-
6
- import { completedStepRewardAddress } from '../completedStepRewardAddress.ts'
7
-
8
- describe('completedStepRewardAddress', () => {
9
- it('should get index [single entry - step size]', () => {
10
- const address = completedStepRewardAddress({ block: asXL1BlockNumber(2311, true), step: 2311 })
11
- expect (address).toBe('93d321ab2e01ce14bbe601d3c49b330d250c5ab1')
12
- })
13
-
14
- it('should get index [single entry - step ordinal]', () => {
15
- const address = completedStepRewardAddress({ block: asXL1BlockNumber(2311, true), step: 3 })
16
- expect (address).toBe('93d321ab2e01ce14bbe601d3c49b330d250c5ab1')
17
- })
18
-
19
- it('should get index [single entry - step size]', () => {
20
- const address = completedStepRewardAddress({ block: asXL1BlockNumber(2311 * 2, true), step: 2311 })
21
- expect (address).toBe('04c602f975a00794efd01e5fe07266cc1945f321')
22
- })
23
-
24
- it('should get index [single entry - step ordinal]', () => {
25
- const address = completedStepRewardAddress({ block: asXL1BlockNumber(2311 * 2, true), step: 3 })
26
- expect (address).toBe('04c602f975a00794efd01e5fe07266cc1945f321')
27
- })
28
- })
@@ -1,23 +0,0 @@
1
- import { StepSizes } from '@xyo-network/xl1-protocol'
2
- import {
3
- describe, expect, it,
4
- } from 'vitest'
5
-
6
- import { stepTransferIndex } from '../stepTransferIndex.ts'
7
-
8
- describe('getStepTransferIndex', () => {
9
- it('should get index [single entry]', { timeout: 120_000 }, () => {
10
- const index = stepTransferIndex(StepSizes[3], 3)
11
- expect (index[0]).toBe(0)
12
- expect (index[1]).toBe(1)
13
- })
14
- it('should get index [double entry]', { timeout: 120_000 }, () => {
15
- const index3 = stepTransferIndex(StepSizes[3] * StepSizes[4], 3)
16
- expect (index3[0]).toBe(0)
17
- expect (index3[1]).toBe(2)
18
-
19
- const index4 = stepTransferIndex(StepSizes[3] * StepSizes[4], 4)
20
- expect (index4[0]).toBe(1)
21
- expect (index4[1]).toBe(2)
22
- })
23
- })
@@ -1,77 +0,0 @@
1
- import type { NetworkId } from '@xyo-network/xl1-protocol'
2
- import { NetworkStatusSchema } from '@xyo-network/xl1-protocol'
3
- import axios from 'axios'
4
- import type { Mocked } from 'vitest'
5
- import {
6
- beforeEach, describe, expect, it, vitest,
7
- } from 'vitest'
8
-
9
- import {
10
- errorStatus, StatusNetworks, unknownStatus,
11
- } from '../lib/index.ts'
12
- import { SimpleXyoNetwork } from '../SimpleXyoNetwork.ts'
13
-
14
- vitest.mock('axios')
15
- const mockedAxios = axios as Mocked<typeof axios>
16
-
17
- describe('SimpleXyoNetwork', () => {
18
- const mockNetworkStatus = {
19
- description: 'Mock Network Status',
20
- schema: NetworkStatusSchema,
21
- state: 'active',
22
- }
23
-
24
- const networks = Object.values(StatusNetworks)
25
-
26
- beforeEach(() => {
27
- vitest.clearAllMocks()
28
- })
29
-
30
- for (const { id, statusUrl } of networks) {
31
- it(`should fetch the ${id} status successfully`, async () => {
32
- mockedAxios.get.mockResolvedValueOnce({ data: mockNetworkStatus })
33
-
34
- const network = new SimpleXyoNetwork(id)
35
- const status = await network.status()
36
-
37
- expect(mockedAxios.get).toHaveBeenCalledWith(statusUrl)
38
- expect(status).toEqual(mockNetworkStatus)
39
- })
40
-
41
- it(`should return unknownStatus for invalid response data on ${id}`, async () => {
42
- mockedAxios.get.mockResolvedValueOnce({ data: { invalid: 'data' }, status: 200 })
43
-
44
- const network = new SimpleXyoNetwork(id)
45
- const status = await network.status()
46
-
47
- expect(mockedAxios.get).toHaveBeenCalledWith(statusUrl)
48
- expect(status).toEqual(unknownStatus)
49
- })
50
-
51
- it(`should return errorStatus for non-200 response on ${id}`, async () => {
52
- mockedAxios.get.mockResolvedValueOnce({ data: {}, status: 500 })
53
-
54
- const network = new SimpleXyoNetwork(id)
55
- const status = await network.status()
56
-
57
- expect(mockedAxios.get).toHaveBeenCalledWith(statusUrl)
58
- expect(status).toEqual(errorStatus)
59
- })
60
-
61
- it(`should return errorStatus for network errors on ${id}`, async () => {
62
- mockedAxios.get.mockRejectedValueOnce(new Error('Network error'))
63
-
64
- const network = new SimpleXyoNetwork(id)
65
- const status = await network.status()
66
-
67
- expect(mockedAxios.get).toHaveBeenCalledWith(statusUrl)
68
- expect(status).toEqual(errorStatus)
69
- })
70
- }
71
-
72
- it('should throw an error for unknown network ID', async () => {
73
- const network = new SimpleXyoNetwork('invalid' as unknown as NetworkId)
74
-
75
- await expect(network.status()).rejects.toThrow('Unknown status network ID: invalid')
76
- })
77
- })
@@ -1,93 +0,0 @@
1
- import {
2
- beforeEach, describe, expect, it,
3
- } from 'vitest'
4
-
5
- import type { PermissionRequest } from '../../../provider/index.ts'
6
- import { SimpleXyoPermissions } from '../SimpleXyoPermissions.ts'
7
- import { MemoryPermissionsStore } from '../store/index.ts'
8
-
9
- describe('MemoryXyoPermissions', () => {
10
- const invoker = 'https://example.com'
11
- const parentCapability = 'xyoViewer_chainId'
12
- let memoryPermissions: SimpleXyoPermissions
13
-
14
- // Helper to build PermissionRequest
15
- const buildPermissionRequest = (cap: string, caveats: Record<string, unknown> = {}) =>
16
- ({ [cap]: caveats }) as PermissionRequest
17
-
18
- beforeEach(() => {
19
- memoryPermissions = new SimpleXyoPermissions(new MemoryPermissionsStore(invoker))
20
- })
21
-
22
- it('returns an empty list initially', async () => {
23
- const permissions = await memoryPermissions.getPermissions()
24
- expect(permissions).toEqual([])
25
- })
26
-
27
- it('adds and retrieves a permission', async () => {
28
- const req = buildPermissionRequest(parentCapability)
29
- const result = await memoryPermissions.requestPermissions([req])
30
- expect(Array.isArray(result)).toBe(true)
31
- expect(result.length).toBe(1)
32
- expect(result[0].parentCapability).toBe(parentCapability)
33
- expect(typeof result[0].date).toBe('number')
34
-
35
- const permissions = await memoryPermissions.getPermissions()
36
- expect(permissions.length).toBe(1)
37
- expect(permissions[0].parentCapability).toBe(parentCapability)
38
- expect(permissions[0].invoker).toBe(invoker)
39
- expect(typeof permissions[0].date).toBe('number')
40
- })
41
-
42
- it('replaces an existing permission with the same key', async () => {
43
- const req = buildPermissionRequest(parentCapability)
44
- await memoryPermissions.requestPermissions([req])
45
- const originalDate = (await memoryPermissions.getPermissions())[0].date
46
-
47
- await new Promise(r => setTimeout(r, 5)) // ensure timestamp difference
48
- await memoryPermissions.requestPermissions([req])
49
- const updatedDate = (await memoryPermissions.getPermissions())[0].date
50
-
51
- expect(updatedDate).toBeGreaterThan(originalDate!)
52
- })
53
-
54
- it('revokes a previously granted permission', async () => {
55
- const req = buildPermissionRequest(parentCapability)
56
- await memoryPermissions.requestPermissions([req])
57
- expect((await memoryPermissions.getPermissions()).length).toBe(1)
58
-
59
- const result = await memoryPermissions.revokePermissions(req)
60
- expect(Array.isArray(result)).toBe(true)
61
- expect(result.length).toBe(1)
62
- expect(result[0].parentCapability).toBe(parentCapability)
63
-
64
- const permissions = await memoryPermissions.getPermissions()
65
- expect(permissions).toEqual([])
66
- })
67
-
68
- it('revoking a non-existent permission does nothing and returns empty array', async () => {
69
- const req = buildPermissionRequest(parentCapability)
70
- const result = await memoryPermissions.revokePermissions(req)
71
- expect(result).toEqual([])
72
- expect(await memoryPermissions.getPermissions()).toEqual([])
73
- })
74
-
75
- it('can handle multiple permissions from different invokers', async () => {
76
- const memoryPermissionsA = new SimpleXyoPermissions(new MemoryPermissionsStore('https://a.com'))
77
- const memoryPermissionsB = new SimpleXyoPermissions(new MemoryPermissionsStore('https://b.com'))
78
- const reqA1 = buildPermissionRequest('xyo_1')
79
- const reqA2 = buildPermissionRequest('xyo_3')
80
- const reqB = buildPermissionRequest('xyo_2')
81
-
82
- await memoryPermissionsA.requestPermissions([reqA1, reqA2])
83
- await memoryPermissionsB.requestPermissions([reqB])
84
-
85
- const resultsA = await memoryPermissionsA.getPermissions()
86
- const resultsB = await memoryPermissionsB.getPermissions()
87
-
88
- expect(resultsA.length).toBe(2)
89
- expect(resultsB.length).toBe(1)
90
- expect(resultsA.map(p => p.parentCapability).toSorted((a, b) => a.localeCompare(b))).toEqual(['xyo_1', 'xyo_3'])
91
- expect(resultsB[0].parentCapability).toBe('xyo_2')
92
- })
93
- })
@@ -1,245 +0,0 @@
1
- import type {
2
- Address, Hash, Hex,
3
- } from '@xylabs/sdk-js'
4
- import { PayloadBuilder } from '@xyo-network/payload-builder'
5
- import type { AnyPayload, Sequence } from '@xyo-network/payload-model'
6
- import type { SignedHydratedTransactionWithStorageMeta, TransactionBoundWitness } from '@xyo-network/xl1-protocol'
7
- import {
8
- describe, expect, it,
9
- } from 'vitest'
10
-
11
- import { transactionBlockByteCount } from '../transactionBlockByteCount.ts'
12
-
13
- const hydratedTransaction: SignedHydratedTransactionWithStorageMeta<TransactionBoundWitness, AnyPayload> = [
14
- {
15
- schema: 'network.xyo.boundwitness',
16
- addresses: [
17
- '136c12e131f5e3eef708dbde954a2841dd72f9af' as Address,
18
- ],
19
- payload_hashes: [
20
- '6d12a4aae2d7056b5b9b1a5e078c883e7ebf887a86d16a4e5e87b5940658873d' as Hash,
21
- '1f9b639358aefa6f3c2467a7d571cde3b68b8fd5d9c7af6a14d0a4023832286f' as Hash,
22
- ],
23
- payload_schemas: [
24
- 'network.xyo.hash',
25
- 'network.xyo.crypto.asset',
26
- ],
27
- previous_hashes: [
28
- null,
29
- ],
30
- $signatures: [
31
- 'c6c4101d2854046974cebd14a941e61ff969f7cf523f677bec2907d262ad98235e00bf829be6344241b5f25cb313c3cadeb0b0abda618b8cfee359859d4246f4' as Hex,
32
- ],
33
- nbf: 25_383,
34
- exp: 26_383,
35
- fees: {
36
- base: '038d7ea4c68000' as Hex,
37
- gasLimit: '0de0b6b3a7640000' as Hex,
38
- gasPrice: '09184e72a000' as Hex,
39
- priority: '00' as Hex,
40
- },
41
- chain: 'a82920051db4fcbb804463440dd45e03f72442fd' as Address,
42
- from: '136c12e131f5e3eef708dbde954a2841dd72f9af' as Address,
43
- script: [
44
- 'elevate|6d12a4aae2d7056b5b9b1a5e078c883e7ebf887a86d16a4e5e87b5940658873d',
45
- ],
46
- _dataHash: '9c6c0ebf16761fc219d8235b398fa058db05f3b139a821f812683c5434e4d08b' as Hash,
47
- _hash: 'bd5909fa90603cba7c794ce8358140467a2aeee1845feaabcac3ad1d3e0dd48a' as Hash,
48
- _sequence: '0000000000000000000000003e0dd48a' as Sequence,
49
- },
50
- [
51
- {
52
- schema: 'network.xyo.hash',
53
- hash: '1f9b639358aefa6f3c2467a7d571cde3b68b8fd5d9c7af6a14d0a4023832286f',
54
- _dataHash: '6d12a4aae2d7056b5b9b1a5e078c883e7ebf887a86d16a4e5e87b5940658873d' as Hash,
55
- _hash: '6d12a4aae2d7056b5b9b1a5e078c883e7ebf887a86d16a4e5e87b5940658873d' as Hash,
56
- _sequence: '000001975b401332000000030658873d' as Sequence,
57
- },
58
- ],
59
- ]
60
-
61
- describe('transactionBlockByteCount', () => {
62
- it('calculates correct byte count for a transaction with no payloads', () => {
63
- // Expected byte count - transaction only (no payloads)
64
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(hydratedTransaction[0])
65
- const expectedCleanPayloads = PayloadBuilder.omitStorageMeta(hydratedTransaction[1])
66
- const expectedByteCount = JSON.stringify(expectedCleanTransaction).length
67
- + expectedCleanPayloads.reduce((acc, payload) => acc + JSON.stringify(payload).length, 0)
68
-
69
- // Act
70
- const actualByteCount = transactionBlockByteCount(hydratedTransaction)
71
-
72
- // Assert
73
- expect(actualByteCount).toBe(expectedByteCount)
74
- })
75
-
76
- it('calculates correct byte count for a transaction with multiple payloads', () => {
77
- // Expected byte count - transaction + payloads (without $meta)
78
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(hydratedTransaction[0])
79
- const expectedCleanPayloads = PayloadBuilder.omitStorageMeta(hydratedTransaction[1])
80
- const expectedByteCount
81
- = JSON.stringify(expectedCleanTransaction).length
82
- + expectedCleanPayloads.reduce((acc, payload) => acc + JSON.stringify(payload).length, 0)
83
-
84
- // Act
85
- const actualByteCount = transactionBlockByteCount(hydratedTransaction)
86
-
87
- // Assert
88
- expect(actualByteCount).toBe(expectedByteCount)
89
- })
90
-
91
- it('handles transaction with empty payload array', () => {
92
- // Arrange
93
- const emptyPayloadsTransaction: SignedHydratedTransactionWithStorageMeta = [
94
- { ...hydratedTransaction[0] },
95
- [], // Empty payload array
96
- ]
97
-
98
- // Expected byte count - transaction only with no payloads
99
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(emptyPayloadsTransaction[0])
100
- const expectedByteCount = JSON.stringify(expectedCleanTransaction).length
101
-
102
- // Act
103
- const actualByteCount = transactionBlockByteCount(emptyPayloadsTransaction)
104
-
105
- // Assert
106
- expect(actualByteCount).toBe(expectedByteCount)
107
- })
108
-
109
- it('correctly handles payloads with complex nested structures', async () => {
110
- // Arrange
111
- const complexPayload = await PayloadBuilder.addStorageMeta({
112
- schema: 'network.xyo.complex',
113
- data: {
114
- nested: {
115
- array: [1, 2, 3, 4, 5],
116
- objects: [
117
- { id: 1, name: 'item1' },
118
- { id: 2, name: 'item2' },
119
- ],
120
- deepNesting: { level1: { level2: { level3: 'deep value' } } },
121
- },
122
- },
123
- })
124
-
125
- const complexTransaction: SignedHydratedTransactionWithStorageMeta = [
126
- { ...hydratedTransaction[0] },
127
- [complexPayload],
128
- ]
129
-
130
- // Expected byte count
131
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(complexTransaction[0])
132
- const expectedCleanPayloads = PayloadBuilder.omitStorageMeta([complexPayload])
133
- const expectedByteCount
134
- = JSON.stringify(expectedCleanTransaction).length
135
- + JSON.stringify(expectedCleanPayloads[0]).length
136
-
137
- // Act
138
- const actualByteCount = transactionBlockByteCount(complexTransaction)
139
-
140
- // Assert
141
- expect(actualByteCount).toBe(expectedByteCount)
142
- })
143
-
144
- it('returns correct byte count for transaction with multiple large payloads', async () => {
145
- // Arrange
146
- const largePayloads = await PayloadBuilder.addStorageMeta(Array.from({ length: 5 }, (_, i) => ({
147
- schema: `network.xyo.test.${i}`,
148
- data: Array.from({ length: 100 }, (_, j) => `data-item-${j}`),
149
- metadata: {
150
- timestamp: Date.now(),
151
- source: `test-source-${i}`,
152
- tags: Array.from({ length: 10 }, (_, k) => `tag-${k}`),
153
- },
154
- _dataHash: `datahash${i}`,
155
- _hash: `hash${i}`,
156
- })))
157
-
158
- const largeTransaction: SignedHydratedTransactionWithStorageMeta = [
159
- { ...hydratedTransaction[0] },
160
- largePayloads,
161
- ]
162
-
163
- // Expected byte count
164
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(largeTransaction[0])
165
- const expectedCleanPayloads = PayloadBuilder.omitStorageMeta(largePayloads)
166
-
167
- let expectedByteCount = JSON.stringify(expectedCleanTransaction).length
168
- for (const payload of expectedCleanPayloads) {
169
- expectedByteCount += JSON.stringify(payload).length
170
- }
171
-
172
- // Act
173
- const actualByteCount = transactionBlockByteCount(largeTransaction)
174
-
175
- // Assert
176
- expect(actualByteCount).toBe(expectedByteCount)
177
- })
178
-
179
- it('handles transactions with special characters in payloads', async () => {
180
- // Arrange
181
- const specialCharPayload = await PayloadBuilder.addStorageMeta({
182
- schema: 'network.xyo.special',
183
- text: 'Special characters: 你好, ñáéíóú, 🚀 💻 🔗, \u0000\u0001\u0002',
184
- escapes: '\\n\\t\\r\\"\\\'\\\\',
185
- _hash: 'special-hash',
186
- })
187
-
188
- const specialTransaction: SignedHydratedTransactionWithStorageMeta = [
189
- { ...hydratedTransaction[0] },
190
- [specialCharPayload],
191
- ]
192
-
193
- // Expected byte count
194
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(specialTransaction[0])
195
- const expectedCleanPayload = PayloadBuilder.omitStorageMeta([specialCharPayload])
196
- const expectedByteCount
197
- = JSON.stringify(expectedCleanTransaction).length
198
- + JSON.stringify(expectedCleanPayload[0]).length
199
-
200
- // Act
201
- const actualByteCount = transactionBlockByteCount(specialTransaction)
202
-
203
- // Assert
204
- expect(actualByteCount).toBe(expectedByteCount)
205
- })
206
-
207
- it('correctly omits all storage metadata fields from byte count', async () => {
208
- // Arrange
209
- const txWithExtraMeta = await PayloadBuilder.addStorageMeta({
210
- ...hydratedTransaction[0],
211
- _extraMeta1: 'should be omitted',
212
- _extraMeta2: 'should be omitted as well',
213
- })
214
-
215
- const payloadWithExtraMeta = await PayloadBuilder.addStorageMeta({
216
- schema: 'network.xyo.test',
217
- data: 'test data',
218
- _extraMeta1: 'should be omitted',
219
- _extraMeta2: 'should be omitted as well',
220
- })
221
-
222
- const transactionWithExtraMeta: SignedHydratedTransactionWithStorageMeta = [
223
- txWithExtraMeta,
224
- [payloadWithExtraMeta],
225
- ]
226
-
227
- // Expected byte count - all meta fields should be omitted
228
- const expectedCleanTransaction = PayloadBuilder.omitStorageMeta(txWithExtraMeta)
229
- const expectedCleanPayload = PayloadBuilder.omitStorageMeta([payloadWithExtraMeta])
230
- const expectedByteCount
231
- = JSON.stringify(expectedCleanTransaction).length
232
- + JSON.stringify(expectedCleanPayload[0]).length
233
-
234
- // Act
235
- const actualByteCount = transactionBlockByteCount(transactionWithExtraMeta)
236
-
237
- // Assert
238
- expect(actualByteCount).toBe(expectedByteCount)
239
- // Verify meta fields are actually omitted
240
- expect(expectedCleanTransaction).not.toHaveProperty('$meta')
241
- expect(expectedCleanTransaction).not.toHaveProperty('_extraMeta1')
242
- expect(expectedCleanPayload[0]).not.toHaveProperty('$meta')
243
- expect(expectedCleanPayload[0]).not.toHaveProperty('_extraMeta1')
244
- })
245
- })