From 691e4d15d14353017aa8ed73bd01c332223afa06 Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Fri, 14 Jun 2019 15:25:07 +0900
Subject: [PATCH] Create Signer interface and use it

---
 src/transaction_builder.js     |  3 ++-
 ts_src/ecpair.ts               | 19 +++++++++++++++----
 ts_src/index.ts                |  2 +-
 ts_src/transaction_builder.ts  | 13 +++++++------
 types/ecpair.d.ts              | 17 +++++++++++++----
 types/index.d.ts               |  2 +-
 types/transaction_builder.d.ts |  6 +++---
 7 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/src/transaction_builder.js b/src/transaction_builder.js
index 252e7c1..c299e29 100644
--- a/src/transaction_builder.js
+++ b/src/transaction_builder.js
@@ -1007,7 +1007,8 @@ function getSigningData(
   ) {
     throw new Error('Inconsistent redeemScript');
   }
-  const ourPubKey = keyPair.publicKey || keyPair.getPublicKey();
+  const ourPubKey =
+    keyPair.publicKey || (keyPair.getPublicKey && keyPair.getPublicKey());
   if (!canSign(input)) {
     if (witnessValue !== undefined) {
       if (input.value !== undefined && input.value !== witnessValue)
diff --git a/ts_src/ecpair.ts b/ts_src/ecpair.ts
index 3d74433..c951f76 100644
--- a/ts_src/ecpair.ts
+++ b/ts_src/ecpair.ts
@@ -19,15 +19,26 @@ interface ECPairOptions {
   rng?(arg0: number): Buffer;
 }
 
-export interface ECPairInterface {
+export interface Signer {
+  publicKey: Buffer;
+  network?: Network;
+  sign(hash: Buffer, lowR?: boolean): Buffer;
+  getPublicKey?(): Buffer;
+}
+
+export interface SignerAsync {
+  publicKey: Buffer;
+  network?: Network;
+  sign(hash: Buffer, lowR?: boolean): Promise<Buffer>;
+  getPublicKey?(): Buffer;
+}
+
+export interface ECPairInterface extends Signer {
   compressed: boolean;
   network: Network;
-  publicKey: Buffer;
   privateKey?: Buffer;
   toWIF(): string;
-  sign(hash: Buffer, lowR?: boolean): Buffer;
   verify(hash: Buffer, signature: Buffer): boolean;
-  getPublicKey?(): Buffer;
 }
 
 class ECPair implements ECPairInterface {
diff --git a/ts_src/index.ts b/ts_src/index.ts
index 1068839..4f2d498 100644
--- a/ts_src/index.ts
+++ b/ts_src/index.ts
@@ -14,7 +14,7 @@ export { Transaction } from './transaction';
 export { TransactionBuilder } from './transaction_builder';
 
 export { BIP32Interface } from 'bip32';
-export { ECPairInterface } from './ecpair';
+export { ECPairInterface, Signer, SignerAsync } from './ecpair';
 export { Network } from './networks';
 export { Payment, PaymentOpts, Stack, StackElement } from './payments';
 export { OpCode } from './script';
diff --git a/ts_src/transaction_builder.ts b/ts_src/transaction_builder.ts
index fede01b..7d47ad3 100644
--- a/ts_src/transaction_builder.ts
+++ b/ts_src/transaction_builder.ts
@@ -2,7 +2,7 @@ import * as baddress from './address';
 import { reverseBuffer } from './bufferutils';
 import * as classify from './classify';
 import * as bcrypto from './crypto';
-import { ECPairInterface } from './ecpair';
+import { Signer } from './ecpair';
 import * as ECPair from './ecpair';
 import { Network } from './networks';
 import * as networks from './networks';
@@ -74,7 +74,7 @@ interface TxbOutput {
 interface TxbSignArg {
   prevOutScriptType: string;
   vin: number;
-  keyPair: ECPairInterface;
+  keyPair: Signer;
   redeemScript?: Buffer;
   hashType?: number;
   witnessValue?: number;
@@ -237,7 +237,7 @@ export class TransactionBuilder {
 
   sign(
     signParams: number | TxbSignArg,
-    keyPair?: ECPairInterface,
+    keyPair?: Signer,
     redeemScript?: Buffer,
     hashType?: number,
     witnessValue?: number,
@@ -1186,7 +1186,7 @@ function trySign({
 interface SigningData {
   input: TxbInput;
   ourPubKey: Buffer;
-  keyPair: ECPairInterface;
+  keyPair: Signer;
   signatureHash: Buffer;
   hashType: number;
   useLowR: boolean;
@@ -1200,7 +1200,7 @@ function getSigningData(
   needsOutputs: HashTypeCheck,
   tx: Transaction,
   signParams: number | TxbSignArg,
-  keyPair?: ECPairInterface,
+  keyPair?: Signer,
   redeemScript?: Buffer,
   hashType?: number,
   witnessValue?: number,
@@ -1251,7 +1251,8 @@ function getSigningData(
     throw new Error('Inconsistent redeemScript');
   }
 
-  const ourPubKey = keyPair.publicKey || keyPair.getPublicKey!();
+  const ourPubKey =
+    keyPair.publicKey || (keyPair.getPublicKey && keyPair.getPublicKey());
   if (!canSign(input)) {
     if (witnessValue !== undefined) {
       if (input.value !== undefined && input.value !== witnessValue)
diff --git a/types/ecpair.d.ts b/types/ecpair.d.ts
index 5f301b2..8b7d193 100644
--- a/types/ecpair.d.ts
+++ b/types/ecpair.d.ts
@@ -5,15 +5,24 @@ interface ECPairOptions {
     network?: Network;
     rng?(arg0: number): Buffer;
 }
-export interface ECPairInterface {
+export interface Signer {
+    publicKey: Buffer;
+    network?: Network;
+    sign(hash: Buffer, lowR?: boolean): Buffer;
+    getPublicKey?(): Buffer;
+}
+export interface SignerAsync {
+    publicKey: Buffer;
+    network?: Network;
+    sign(hash: Buffer, lowR?: boolean): Promise<Buffer>;
+    getPublicKey?(): Buffer;
+}
+export interface ECPairInterface extends Signer {
     compressed: boolean;
     network: Network;
-    publicKey: Buffer;
     privateKey?: Buffer;
     toWIF(): string;
-    sign(hash: Buffer, lowR?: boolean): Buffer;
     verify(hash: Buffer, signature: Buffer): boolean;
-    getPublicKey?(): Buffer;
 }
 declare class ECPair implements ECPairInterface {
     private __D?;
diff --git a/types/index.d.ts b/types/index.d.ts
index 28046df..93d72e4 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -11,7 +11,7 @@ export { OPS as opcodes } from './script';
 export { Transaction } from './transaction';
 export { TransactionBuilder } from './transaction_builder';
 export { BIP32Interface } from 'bip32';
-export { ECPairInterface } from './ecpair';
+export { ECPairInterface, Signer, SignerAsync } from './ecpair';
 export { Network } from './networks';
 export { Payment, PaymentOpts, Stack, StackElement } from './payments';
 export { OpCode } from './script';
diff --git a/types/transaction_builder.d.ts b/types/transaction_builder.d.ts
index d57e4eb..2799464 100644
--- a/types/transaction_builder.d.ts
+++ b/types/transaction_builder.d.ts
@@ -1,11 +1,11 @@
 /// <reference types="node" />
-import { ECPairInterface } from './ecpair';
+import { Signer } from './ecpair';
 import { Network } from './networks';
 import { Transaction } from './transaction';
 interface TxbSignArg {
     prevOutScriptType: string;
     vin: number;
-    keyPair: ECPairInterface;
+    keyPair: Signer;
     redeemScript?: Buffer;
     hashType?: number;
     witnessValue?: number;
@@ -27,7 +27,7 @@ export declare class TransactionBuilder {
     addOutput(scriptPubKey: string | Buffer, value: number): number;
     build(): Transaction;
     buildIncomplete(): Transaction;
-    sign(signParams: number | TxbSignArg, keyPair?: ECPairInterface, redeemScript?: Buffer, hashType?: number, witnessValue?: number, witnessScript?: Buffer): void;
+    sign(signParams: number | TxbSignArg, keyPair?: Signer, redeemScript?: Buffer, hashType?: number, witnessValue?: number, witnessScript?: Buffer): void;
     private __addInputUnsafe;
     private __build;
     private __canModifyInputs;