@bsv/sdk 2.0.12 → 2.0.13
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/dist/cjs/package.json +1 -1
- package/dist/cjs/src/auth/clients/__tests__/AuthFetch.additional.test.js +827 -0
- package/dist/cjs/src/auth/clients/__tests__/AuthFetch.additional.test.js.map +1 -0
- package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js +654 -0
- package/dist/cjs/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js.map +1 -0
- package/dist/cjs/src/transaction/MerklePath.js +132 -0
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/auth/clients/__tests__/AuthFetch.additional.test.js +825 -0
- package/dist/esm/src/auth/clients/__tests__/AuthFetch.additional.test.js.map +1 -0
- package/dist/esm/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js +619 -0
- package/dist/esm/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.js.map +1 -0
- package/dist/esm/src/transaction/MerklePath.js +132 -0
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/auth/clients/__tests__/AuthFetch.additional.test.d.ts +21 -0
- package/dist/types/src/auth/clients/__tests__/AuthFetch.additional.test.d.ts.map +1 -0
- package/dist/types/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.d.ts +2 -0
- package/dist/types/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.d.ts.map +1 -0
- package/dist/types/src/transaction/MerklePath.d.ts +27 -0
- package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/storage.md +1 -1
- package/docs/reference/transaction.md +40 -0
- package/package.json +1 -1
- package/src/auth/clients/__tests__/AuthFetch.additional.test.ts +1131 -0
- package/src/auth/transports/__tests__/SimplifiedFetchTransport.additional.test.ts +770 -0
- package/src/compat/__tests/Mnemonic.additional.test.ts +64 -0
- package/src/identity/__tests/IdentityClient.additional.test.ts +767 -0
- package/src/kvstore/__tests/LocalKVStore.additional.test.ts +611 -0
- package/src/kvstore/__tests/kvStoreInterpreter.test.ts +327 -0
- package/src/overlay-tools/__tests/HostReputationTracker.additional.test.ts +561 -0
- package/src/overlay-tools/__tests/LookupResolver.additional.test.ts +612 -0
- package/src/overlay-tools/__tests/withDoubleSpendRetry.test.ts +278 -0
- package/src/primitives/__tests/BigNumber.additional.test.ts +79 -0
- package/src/primitives/__tests/Curve.additional.test.ts +208 -0
- package/src/primitives/__tests/ECDSA.additional.test.ts +122 -0
- package/src/primitives/__tests/Hash.additional.test.ts +59 -0
- package/src/primitives/__tests/JacobianPoint.test.ts +308 -0
- package/src/primitives/__tests/Point.additional.test.ts +503 -0
- package/src/primitives/__tests/PublicKey.additional.test.ts +383 -0
- package/src/primitives/__tests/Random.additional.test.ts +262 -0
- package/src/primitives/__tests/Signature.test.ts +333 -0
- package/src/primitives/__tests/TransactionSignature.additional.test.ts +241 -0
- package/src/registry/__tests/RegistryClient.additional.test.ts +750 -0
- package/src/remittance/__tests/BasicBRC29.additional.test.ts +657 -0
- package/src/remittance/__tests/RemittanceManager.additional.test.ts +1272 -0
- package/src/script/__tests/LockingUnlockingScript.test.ts +79 -0
- package/src/script/__tests/Script.additional.test.ts +100 -0
- package/src/script/__tests/ScriptEvaluationError.test.ts +98 -0
- package/src/script/__tests/Spend.additional.test.ts +837 -0
- package/src/script/templates/__tests/RPuzzle.test.ts +134 -0
- package/src/transaction/MerklePath.ts +155 -0
- package/src/transaction/__tests/BeefParty.additional.test.ts +22 -0
- package/src/transaction/__tests/Broadcaster.test.ts +159 -0
- package/src/transaction/__tests/MerklePath.bench.test.ts +105 -0
- package/src/transaction/__tests/MerklePath.test.ts +80 -0
- package/src/transaction/__tests/Transaction.additional.test.ts +225 -0
- package/src/transaction/broadcasters/__tests/ARC.additional.test.ts +585 -0
- package/src/transaction/broadcasters/__tests/Teranode.test.ts +349 -0
- package/src/transaction/chaintrackers/__tests/BlockHeadersService.test.ts +253 -0
- package/src/transaction/chaintrackers/__tests/DefaultChainTracker.test.ts +44 -0
- package/src/transaction/chaintrackers/__tests/WhatsOnChain.additional.test.ts +193 -0
- package/src/transaction/fee-models/__tests/SatoshisPerKilobyte.test.ts +262 -0
- package/src/transaction/http/__tests/BinaryFetchClient.test.ts +212 -0
- package/src/transaction/http/__tests/DefaultHttpClient.additional.test.ts +192 -0
- package/src/transaction/http/__tests/DefaultHttpClient.test.ts +71 -0
- package/src/wallet/__tests/ProtoWallet.additional.test.ts +134 -0
- package/src/wallet/__tests/WERR.test.ts +212 -0
- package/src/wallet/__tests/WalletClient.additional.test.ts +699 -0
- package/src/wallet/__tests/WalletClient.substrate.test.ts +759 -0
- package/src/wallet/__tests/WalletError.test.ts +290 -0
- package/src/wallet/__tests/validationHelpers.test.ts +1218 -0
- package/src/wallet/substrates/__tests/HTTPWalletJSON.test.ts +496 -0
- package/src/wallet/substrates/__tests/HTTPWalletWire.test.ts +273 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/** eslint-env jest */
|
|
2
|
+
import { kvStoreInterpreter, KVContext } from '../kvStoreInterpreter'
|
|
3
|
+
import { kvProtocol } from '../types'
|
|
4
|
+
import Transaction from '../../transaction/Transaction'
|
|
5
|
+
import PushDrop from '../../script/templates/PushDrop'
|
|
6
|
+
import * as Utils from '../../primitives/utils'
|
|
7
|
+
|
|
8
|
+
// --- Module mocks -----------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
jest.mock('../../script/templates/PushDrop.js', () => {
|
|
11
|
+
const mockPushDropDecode = jest.fn()
|
|
12
|
+
return Object.assign(
|
|
13
|
+
jest.fn(() => ({})),
|
|
14
|
+
{ decode: mockPushDropDecode }
|
|
15
|
+
)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
jest.mock('../../primitives/utils.js', () => ({
|
|
19
|
+
toArray: jest.fn((str: string) => Array.from(Buffer.from(str, 'utf8'))),
|
|
20
|
+
toUTF8: jest.fn((arr: number[] | Uint8Array) => Buffer.from(arr).toString('utf8'))
|
|
21
|
+
}))
|
|
22
|
+
|
|
23
|
+
// --- Typed mock refs --------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
const MockedPushDrop = PushDrop as jest.MockedClass<typeof PushDrop> & {
|
|
26
|
+
decode: jest.Mock<any, any>
|
|
27
|
+
}
|
|
28
|
+
const MockedPushDropDecode = MockedPushDrop.decode
|
|
29
|
+
const MockedUtils = Utils as jest.Mocked<typeof Utils>
|
|
30
|
+
|
|
31
|
+
// --- Helpers ----------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Number of fields in the new format (all kvProtocol keys).
|
|
35
|
+
* Old format has one fewer (no tags field).
|
|
36
|
+
*/
|
|
37
|
+
const expectedFieldCount = Object.keys(kvProtocol).length // 6
|
|
38
|
+
|
|
39
|
+
function makeMockTransaction (outputs: Array<{ lockingScript?: any } | null>): Transaction {
|
|
40
|
+
return {
|
|
41
|
+
outputs
|
|
42
|
+
} as unknown as Transaction
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function makeFieldArray (
|
|
46
|
+
protocolID: string,
|
|
47
|
+
key: string,
|
|
48
|
+
value: string,
|
|
49
|
+
controller: string = 'controller',
|
|
50
|
+
includeTagsField: boolean = true
|
|
51
|
+
): Array<number[]> {
|
|
52
|
+
// Fields in kvProtocol order: protocolID(0), key(1), value(2), controller(3), tags(4), signature(5)
|
|
53
|
+
const fields: Array<number[]> = [
|
|
54
|
+
Array.from(Buffer.from(protocolID)),
|
|
55
|
+
Array.from(Buffer.from(key)),
|
|
56
|
+
Array.from(Buffer.from(value)),
|
|
57
|
+
Array.from(Buffer.from(controller))
|
|
58
|
+
]
|
|
59
|
+
if (includeTagsField) {
|
|
60
|
+
fields.push(Array.from(Buffer.from('[]'))) // tags
|
|
61
|
+
fields.push(Array.from(Buffer.from('sig'))) // signature
|
|
62
|
+
} else {
|
|
63
|
+
// Old format: no tags, signature at position 4
|
|
64
|
+
fields.push(Array.from(Buffer.from('sig'))) // signature
|
|
65
|
+
}
|
|
66
|
+
return fields
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
import { SecurityLevel, WalletProtocol } from '../../wallet/Wallet.interfaces'
|
|
70
|
+
|
|
71
|
+
function makeCtx (key: string, protocolID: WalletProtocol = [2 as SecurityLevel, 'kvstore']): KVContext {
|
|
72
|
+
return { key, protocolID }
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// --- Tests ------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
describe('kvStoreInterpreter', () => {
|
|
78
|
+
const testKey = 'my-key'
|
|
79
|
+
const testValue = 'my-value'
|
|
80
|
+
const testProtocolID: WalletProtocol = [2 as SecurityLevel, 'kvstore']
|
|
81
|
+
const testCtx = makeCtx(testKey, testProtocolID)
|
|
82
|
+
const protocolIDStr = JSON.stringify(testProtocolID)
|
|
83
|
+
|
|
84
|
+
beforeEach(() => {
|
|
85
|
+
jest.clearAllMocks()
|
|
86
|
+
// Default toUTF8 implementation: convert byte array to string
|
|
87
|
+
MockedUtils.toUTF8.mockImplementation((arr: number[] | Uint8Array) =>
|
|
88
|
+
Buffer.from(arr).toString('utf8')
|
|
89
|
+
)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
// --- Missing / null guard cases -------------------------------------------
|
|
93
|
+
|
|
94
|
+
describe('returns undefined for missing/invalid inputs', () => {
|
|
95
|
+
it('returns undefined when output at index does not exist', async () => {
|
|
96
|
+
const tx = makeMockTransaction([])
|
|
97
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
98
|
+
expect(result).toBeUndefined()
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('returns undefined when output lockingScript is null', async () => {
|
|
102
|
+
const tx = makeMockTransaction([{ lockingScript: null }])
|
|
103
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
104
|
+
expect(result).toBeUndefined()
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('returns undefined when output is null', async () => {
|
|
108
|
+
const tx = makeMockTransaction([null])
|
|
109
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
110
|
+
expect(result).toBeUndefined()
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('returns undefined when ctx is undefined', async () => {
|
|
114
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
115
|
+
const result = await kvStoreInterpreter(tx, 0, undefined)
|
|
116
|
+
expect(result).toBeUndefined()
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('returns undefined when ctx is null', async () => {
|
|
120
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
121
|
+
const result = await kvStoreInterpreter(tx, 0, null as any)
|
|
122
|
+
expect(result).toBeUndefined()
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('returns undefined when ctx.key is null', async () => {
|
|
126
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
127
|
+
const result = await kvStoreInterpreter(tx, 0, { key: null as any, protocolID: testProtocolID })
|
|
128
|
+
expect(result).toBeUndefined()
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it('returns undefined when ctx.key is undefined', async () => {
|
|
132
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
133
|
+
const result = await kvStoreInterpreter(tx, 0, { key: undefined as any, protocolID: testProtocolID })
|
|
134
|
+
expect(result).toBeUndefined()
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
// --- PushDrop.decode error cases ------------------------------------------
|
|
139
|
+
|
|
140
|
+
describe('returns undefined when PushDrop.decode throws', () => {
|
|
141
|
+
it('returns undefined when decode throws due to malformed script', async () => {
|
|
142
|
+
MockedPushDropDecode.mockImplementation(() => {
|
|
143
|
+
throw new Error('Malformed script')
|
|
144
|
+
})
|
|
145
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
146
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
147
|
+
expect(result).toBeUndefined()
|
|
148
|
+
expect(MockedPushDropDecode).toHaveBeenCalledTimes(1)
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
// --- Wrong field count cases -----------------------------------------------
|
|
153
|
+
|
|
154
|
+
describe('returns undefined when field count is wrong', () => {
|
|
155
|
+
it('returns undefined when decoded fields length is too short (< expectedFieldCount - 1)', async () => {
|
|
156
|
+
// e.g., only 3 fields — neither old nor new format
|
|
157
|
+
MockedPushDropDecode.mockReturnValue({
|
|
158
|
+
fields: [
|
|
159
|
+
Array.from(Buffer.from('id')),
|
|
160
|
+
Array.from(Buffer.from('key')),
|
|
161
|
+
Array.from(Buffer.from('val'))
|
|
162
|
+
]
|
|
163
|
+
})
|
|
164
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
165
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
166
|
+
expect(result).toBeUndefined()
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('returns undefined when decoded fields length is too long (> expectedFieldCount)', async () => {
|
|
170
|
+
// More fields than the new format
|
|
171
|
+
const fields = makeFieldArray(protocolIDStr, testKey, testValue)
|
|
172
|
+
fields.push(Array.from(Buffer.from('extra')))
|
|
173
|
+
MockedPushDropDecode.mockReturnValue({ fields })
|
|
174
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
175
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
176
|
+
expect(result).toBeUndefined()
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
// --- Key / protocolID mismatch cases --------------------------------------
|
|
181
|
+
|
|
182
|
+
describe('returns undefined when key or protocolID does not match ctx', () => {
|
|
183
|
+
it('returns undefined when key does not match ctx.key (new format)', async () => {
|
|
184
|
+
MockedPushDropDecode.mockReturnValue({
|
|
185
|
+
fields: makeFieldArray(protocolIDStr, 'different-key', testValue)
|
|
186
|
+
})
|
|
187
|
+
// toUTF8 returns the string content of the byte arrays
|
|
188
|
+
MockedUtils.toUTF8
|
|
189
|
+
.mockReturnValueOnce(protocolIDStr) // protocolID field
|
|
190
|
+
.mockReturnValueOnce('different-key') // key field
|
|
191
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
192
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
193
|
+
expect(result).toBeUndefined()
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it('returns undefined when key does not match ctx.key (old format)', async () => {
|
|
197
|
+
MockedPushDropDecode.mockReturnValue({
|
|
198
|
+
fields: makeFieldArray(protocolIDStr, 'wrong-key', testValue, 'controller', false)
|
|
199
|
+
})
|
|
200
|
+
MockedUtils.toUTF8
|
|
201
|
+
.mockReturnValueOnce('wrong-key') // key field
|
|
202
|
+
.mockReturnValueOnce(protocolIDStr) // protocolID field
|
|
203
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
204
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
205
|
+
expect(result).toBeUndefined()
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
it('returns undefined when protocolID does not match ctx.protocolID (new format)', async () => {
|
|
209
|
+
const differentProtocol: [number, string] = [1, 'other']
|
|
210
|
+
MockedPushDropDecode.mockReturnValue({
|
|
211
|
+
fields: makeFieldArray(JSON.stringify(differentProtocol), testKey, testValue)
|
|
212
|
+
})
|
|
213
|
+
MockedUtils.toUTF8
|
|
214
|
+
.mockReturnValueOnce(testKey) // key field
|
|
215
|
+
.mockReturnValueOnce(JSON.stringify(differentProtocol)) // protocolID field
|
|
216
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
217
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
218
|
+
expect(result).toBeUndefined()
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
// --- Happy path: new format (expectedFieldCount fields) --------------------
|
|
223
|
+
|
|
224
|
+
describe('returns decoded value string for matching outputs', () => {
|
|
225
|
+
it('returns value for new format (expectedFieldCount fields) matching key and protocolID', async () => {
|
|
226
|
+
const newFormatFields = makeFieldArray(protocolIDStr, testKey, testValue, 'controller', true)
|
|
227
|
+
expect(newFormatFields.length).toBe(expectedFieldCount)
|
|
228
|
+
|
|
229
|
+
MockedPushDropDecode.mockReturnValue({ fields: newFormatFields })
|
|
230
|
+
MockedUtils.toUTF8
|
|
231
|
+
.mockReturnValueOnce(testKey) // key field — kvProtocol.key = 1
|
|
232
|
+
.mockReturnValueOnce(protocolIDStr) // protocolID field — kvProtocol.protocolID = 0
|
|
233
|
+
.mockReturnValueOnce(testValue) // value field — kvProtocol.value = 2
|
|
234
|
+
|
|
235
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
236
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
237
|
+
|
|
238
|
+
expect(result).toBe(testValue)
|
|
239
|
+
expect(MockedPushDropDecode).toHaveBeenCalledTimes(1)
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
it('returns value for old format (expectedFieldCount - 1 fields) matching key and protocolID', async () => {
|
|
243
|
+
const oldFormatFields = makeFieldArray(protocolIDStr, testKey, testValue, 'controller', false)
|
|
244
|
+
expect(oldFormatFields.length).toBe(expectedFieldCount - 1)
|
|
245
|
+
|
|
246
|
+
MockedPushDropDecode.mockReturnValue({ fields: oldFormatFields })
|
|
247
|
+
MockedUtils.toUTF8
|
|
248
|
+
.mockReturnValueOnce(testKey) // key field
|
|
249
|
+
.mockReturnValueOnce(protocolIDStr) // protocolID field
|
|
250
|
+
.mockReturnValueOnce(testValue) // value field
|
|
251
|
+
|
|
252
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
253
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
254
|
+
|
|
255
|
+
expect(result).toBe(testValue)
|
|
256
|
+
expect(MockedPushDropDecode).toHaveBeenCalledTimes(1)
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
it('uses the output at the correct outputIndex', async () => {
|
|
260
|
+
const newFormatFields = makeFieldArray(protocolIDStr, testKey, testValue)
|
|
261
|
+
MockedPushDropDecode.mockReturnValue({ fields: newFormatFields })
|
|
262
|
+
MockedUtils.toUTF8
|
|
263
|
+
.mockReturnValueOnce(testKey)
|
|
264
|
+
.mockReturnValueOnce(protocolIDStr)
|
|
265
|
+
.mockReturnValueOnce(testValue)
|
|
266
|
+
|
|
267
|
+
const tx = makeMockTransaction([
|
|
268
|
+
null, // index 0: non-existent
|
|
269
|
+
{ lockingScript: {} } // index 1: valid
|
|
270
|
+
])
|
|
271
|
+
const result = await kvStoreInterpreter(tx, 1, testCtx)
|
|
272
|
+
|
|
273
|
+
expect(result).toBe(testValue)
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
// --- Inner catch: Utils.toUTF8 throws on value field ----------------------
|
|
278
|
+
|
|
279
|
+
describe('returns undefined when Utils.toUTF8 throws on value field', () => {
|
|
280
|
+
it('returns undefined when toUTF8 throws during value extraction (inner catch)', async () => {
|
|
281
|
+
const newFormatFields = makeFieldArray(protocolIDStr, testKey, testValue)
|
|
282
|
+
MockedPushDropDecode.mockReturnValue({ fields: newFormatFields })
|
|
283
|
+
|
|
284
|
+
// First two calls succeed (key and protocolID match), third throws
|
|
285
|
+
MockedUtils.toUTF8
|
|
286
|
+
.mockReturnValueOnce(testKey)
|
|
287
|
+
.mockReturnValueOnce(protocolIDStr)
|
|
288
|
+
.mockImplementationOnce(() => {
|
|
289
|
+
throw new Error('toUTF8 failed on value')
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
293
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
294
|
+
|
|
295
|
+
expect(result).toBeUndefined()
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
it('returns undefined when toUTF8 throws during key extraction (outer catch)', async () => {
|
|
299
|
+
const newFormatFields = makeFieldArray(protocolIDStr, testKey, testValue)
|
|
300
|
+
MockedPushDropDecode.mockReturnValue({ fields: newFormatFields })
|
|
301
|
+
|
|
302
|
+
// First call (key extraction) throws
|
|
303
|
+
MockedUtils.toUTF8.mockImplementationOnce(() => {
|
|
304
|
+
throw new Error('toUTF8 failed on key')
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
const tx = makeMockTransaction([{ lockingScript: {} }])
|
|
308
|
+
const result = await kvStoreInterpreter(tx, 0, testCtx)
|
|
309
|
+
|
|
310
|
+
expect(result).toBeUndefined()
|
|
311
|
+
})
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
// --- Field index alignment check ------------------------------------------
|
|
315
|
+
|
|
316
|
+
describe('kvProtocol field indices', () => {
|
|
317
|
+
it('has the expected field indices for new format', () => {
|
|
318
|
+
expect(kvProtocol.protocolID).toBe(0)
|
|
319
|
+
expect(kvProtocol.key).toBe(1)
|
|
320
|
+
expect(kvProtocol.value).toBe(2)
|
|
321
|
+
expect(kvProtocol.controller).toBe(3)
|
|
322
|
+
expect(kvProtocol.tags).toBe(4)
|
|
323
|
+
expect(kvProtocol.signature).toBe(5)
|
|
324
|
+
expect(Object.keys(kvProtocol).length).toBe(6)
|
|
325
|
+
})
|
|
326
|
+
})
|
|
327
|
+
})
|