Skip to content

Commit 13d557b

Browse files
committed
fix(express): construct pending approval type codec
Ticket: WP-6717
1 parent b967950 commit 13d557b

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

modules/express/src/typedRoutes/api/v1/constructPendingApprovalTx.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,19 @@ export const ConstructPendingApprovalTxResponse = t.type({
3535
/** The signed transaction hex */
3636
tx: t.string,
3737
/** The fee amount in satoshis */
38-
fee: optional(t.number),
38+
fee: t.number,
3939
/** The fee rate in satoshis per kilobyte */
40-
feeRate: optional(t.number),
40+
feeRate: t.number,
4141
/** Whether the transaction is instant */
4242
instant: optional(t.boolean),
4343
/** The BitGo fee amount */
4444
bitgoFee: optional(t.unknown),
4545
/** Travel information */
4646
travelInfos: optional(t.unknown),
4747
/** Estimated transaction size in bytes */
48-
estimatedSize: optional(t.number),
48+
estimatedSize: t.number,
4949
/** Unspent transaction outputs used */
50-
unspents: optional(t.array(t.unknown)),
50+
unspents: t.array(t.unknown),
5151
});
5252

5353
/**

modules/express/test/unit/typedRoutes/constructPendingApprovalTx.ts

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,21 @@ describe('ConstructPendingApprovalTx codec tests', function () {
192192
});
193193

194194
describe('ConstructPendingApprovalTxResponse', function () {
195-
it('should validate response with required tx field', function () {
195+
it('should validate response with all required fields', function () {
196196
const validResponse = {
197197
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
198+
fee: 10000,
199+
feeRate: 20000,
200+
estimatedSize: 256,
201+
unspents: [],
198202
};
199203

200204
const decoded = assertDecode(ConstructPendingApprovalTxResponse, validResponse);
201205
assert.strictEqual(decoded.tx, validResponse.tx);
206+
assert.strictEqual(decoded.fee, validResponse.fee);
207+
assert.strictEqual(decoded.feeRate, validResponse.feeRate);
208+
assert.strictEqual(decoded.estimatedSize, validResponse.estimatedSize);
209+
assert.deepStrictEqual(decoded.unspents, validResponse.unspents);
202210
});
203211

204212
it('should validate response with all fields', function () {
@@ -234,6 +242,62 @@ describe('ConstructPendingApprovalTx codec tests', function () {
234242
});
235243
});
236244

245+
it('should reject response with missing fee', function () {
246+
const invalidResponse = {
247+
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
248+
// Missing fee (required)
249+
feeRate: 20000,
250+
estimatedSize: 256,
251+
unspents: [],
252+
};
253+
254+
assert.throws(() => {
255+
assertDecode(ConstructPendingApprovalTxResponse, invalidResponse);
256+
});
257+
});
258+
259+
it('should reject response with missing feeRate', function () {
260+
const invalidResponse = {
261+
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
262+
fee: 10000,
263+
// Missing feeRate (required)
264+
estimatedSize: 256,
265+
unspents: [],
266+
};
267+
268+
assert.throws(() => {
269+
assertDecode(ConstructPendingApprovalTxResponse, invalidResponse);
270+
});
271+
});
272+
273+
it('should reject response with missing estimatedSize', function () {
274+
const invalidResponse = {
275+
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
276+
fee: 10000,
277+
feeRate: 20000,
278+
// Missing estimatedSize (required)
279+
unspents: [],
280+
};
281+
282+
assert.throws(() => {
283+
assertDecode(ConstructPendingApprovalTxResponse, invalidResponse);
284+
});
285+
});
286+
287+
it('should reject response with missing unspents', function () {
288+
const invalidResponse = {
289+
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
290+
fee: 10000,
291+
feeRate: 20000,
292+
estimatedSize: 256,
293+
// Missing unspents (required)
294+
};
295+
296+
assert.throws(() => {
297+
assertDecode(ConstructPendingApprovalTxResponse, invalidResponse);
298+
});
299+
});
300+
237301
it('should reject response with non-string tx', function () {
238302
const invalidResponse = {
239303
tx: 123, // number instead of string
@@ -248,6 +312,9 @@ describe('ConstructPendingApprovalTx codec tests', function () {
248312
const invalidResponse = {
249313
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
250314
fee: '10000', // string instead of number
315+
feeRate: 20000,
316+
estimatedSize: 256,
317+
unspents: [],
251318
};
252319

253320
assert.throws(() => {
@@ -258,7 +325,10 @@ describe('ConstructPendingApprovalTx codec tests', function () {
258325
it('should reject response with non-number feeRate', function () {
259326
const invalidResponse = {
260327
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
328+
fee: 10000,
261329
feeRate: '20000', // string instead of number
330+
estimatedSize: 256,
331+
unspents: [],
262332
};
263333

264334
assert.throws(() => {
@@ -279,7 +349,10 @@ describe('ConstructPendingApprovalTx codec tests', function () {
279349
it('should reject response with non-number estimatedSize', function () {
280350
const invalidResponse = {
281351
tx: '0100000001c7dad3d9607a23c45a6c1c5ad7bce02acff71a0f21eb4a72a59d0c0e19402d0f0000000000ffffffff0180a21900000000001976a914c918e1b36f2c72b1aaef94dbb7f578a4b68b542788ac00000000',
352+
fee: 10000,
353+
feeRate: 20000,
282354
estimatedSize: '256', // string instead of number
355+
unspents: [],
283356
};
284357

285358
assert.throws(() => {
@@ -386,6 +459,8 @@ describe('ConstructPendingApprovalTx codec tests', function () {
386459
fee: 10000,
387460
feeRate: 20000,
388461
instant: false,
462+
estimatedSize: 256,
463+
unspents: [{ id: 'unspent1', value: 1000000 }],
389464
};
390465

391466
afterEach(function () {

0 commit comments

Comments
 (0)