Parse an OP_m ... OP_CHECKMULTISIG redeem script (used by multisig PSBT flows).
()
| 371 | |
| 372 | /** Parse an OP_m ... OP_CHECKMULTISIG redeem script (used by multisig PSBT flows). */ |
| 373 | public parseMultisigRedeemScript(): { |
| 374 | numSignatures: number; |
| 375 | numPubkeys: number; |
| 376 | pubkeys: Uint8Array[]; |
| 377 | } { |
| 378 | const ops: Op[] = []; |
| 379 | const iter = this.ops(); |
| 380 | let op: Op | undefined; |
| 381 | while ((op = iter.next()) !== undefined) { |
| 382 | ops.push(op); |
| 383 | } |
| 384 | if (ops.length < 4) { |
| 385 | throw new Error('Invalid multisig redeem script'); |
| 386 | } |
| 387 | const first = ops[0]; |
| 388 | const lastBeforeCheck = ops[ops.length - 2]; |
| 389 | const numSignatures = Number(parseNumberFromOp(first)); |
| 390 | const numPubkeys = Number(parseNumberFromOp(lastBeforeCheck)); |
| 391 | const pubkeys = ops |
| 392 | .slice(1, -2) |
| 393 | .filter((op): op is { opcode: number; data: Uint8Array } => |
| 394 | isPushOp(op), |
| 395 | ) |
| 396 | .map(op => op.data); |
| 397 | if (pubkeys.length !== numPubkeys) { |
| 398 | throw new Error( |
| 399 | `Invalid multisig redeem script: expected ${numPubkeys} pubkeys, got ${pubkeys.length}`, |
| 400 | ); |
| 401 | } |
| 402 | return { numSignatures, numPubkeys, pubkeys }; |
| 403 | } |
| 404 | |
| 405 | private static parseMultisigScriptSig( |
| 406 | ops: Op[], |
no test coverage detected