All files / lib/lightning ScriptFactory.ts

33.33% Statements 3/9
100% Branches 0/0
0% Functions 0/5
37.5% Lines 3/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 1511x 1x   1x                                                                                                                                                                                                                                                                                                      
import { OpCode, Script } from '@node-dlc/bitcoin';
import { hash160, ripemd160 } from '@node-dlc/crypto';
 
export class ScriptFactory {
  /**
   * Constructs the P2MS commit script used in in the funding transaction
   * as defined in BOLT3. The pubkeys must be sorted in lexicographical
   * order.
   *
   * @param openPubKey funding_pubkey sent in open_channel
   * @param acceptPubKey funding_pubkey sent in accept_channel
   */
  public static fundingScript(
    openPubKey: Buffer,
    acceptPubKey: Buffer,
  ): Script {
    const pubkeys = [openPubKey, acceptPubKey].sort((a, b) => a.compare(b));
    return Script.p2msLock(2, ...pubkeys);
  }
 
  /**
   * Constructs an revocable sequence maturing contract using the
   * provided keys and delay. This script is used in the `to_local`
   * output of the commmitment transaction as well as the secondary
   * HTLC-Success and HTLC-Timeout transactions.
   *
   * @param revocationPubKey the revocation pubkey that has the ability
   * to perform a penalty transaction should a revoked version of this
   * output be spend.
   * @param delayedPubKey the delayed pubkey spendable after the
   * sequence delay
   * @param toSelfDelay the sequence delay in blocks
   */
  public static toLocalScript(
    revocationPubKey: Buffer,
    delayedPubKey: Buffer,
    toSelfDelay: number,
  ): Script {
    return new Script(
            OpCode.OP_IF,
                revocationPubKey,
            OpCode.OP_ELSE,
                Script.number(toSelfDelay),
                OpCode.OP_CHECKSEQUENCEVERIFY,
                OpCode.OP_DROP,
                delayedPubKey,
            OpCode.OP_ENDIF,
            OpCode.OP_CHECKSIG,
        ); // prettier-ignore
  }
 
  /**
   * Constructs the script for an offered HTLC output of a  commitment
   * transaction as defined in BOLT3. This enables on-chain resolution
   * of an HTLC to the local node via the secondary HTLC-Timeout
   * transaction. This secondary transaction is both sequence delayed
   * and timelocked and requires signatures by both parties to prevent
   * premature spending. The remote node can immediately resolve the
   * transaction wit knowledge of the preimage.
   *
   * Revocable with witness:
   * [revocationSig, revocationPubKey]
   *
   * Pay to local via the HTLC-Timeout transaction by using witness
   * [0, remoteHtlcSig, localHtlcSig, <>]
   *
   * Pay to remote counterparty without delay using witness
   * [remoteHtlcSig, preimage]
   *
   * @param paymentHash
   * @param revocationPubKey
   * @param localHtlcPubKey
   * @param remoteHtlcPubKey
   */
  public static offeredHtlcScript(
    paymentHash: Buffer,
    revocationPubKey: Buffer,
    localHtlcPubKey: Buffer,
    remoteHtlcPubKey: Buffer,
  ): Script {
    return new Script(
            // to remote with revocation key
            OpCode.OP_DUP, OpCode.OP_HASH160, hash160(revocationPubKey), OpCode.OP_EQUAL,
            OpCode.OP_IF,
                OpCode.OP_CHECKSIG,
            OpCode.OP_ELSE,
                remoteHtlcPubKey, OpCode.OP_SWAP, OpCode.OP_SIZE, Script.number(32), OpCode.OP_EQUAL,
                OpCode.OP_NOTIF,
                    // to local via HTLC-Timeout transaction (timelocked)
                    OpCode.OP_DROP, OpCode.OP_2, OpCode.OP_SWAP, localHtlcPubKey, OpCode.OP_2, OpCode.OP_CHECKMULTISIG,
                OpCode.OP_ELSE,
                    // to remote with preimage and signature
                    OpCode.OP_HASH160, ripemd160(paymentHash), OpCode.OP_EQUALVERIFY,
                    OpCode.OP_CHECKSIG,
                OpCode.OP_ENDIF,
            OpCode.OP_ENDIF,
        ); // prettier-ignore
  }
 
  /**
   * Constructs the script for a received HTLC output of a commitment
   * transaction as defined in BOLT3. This enables on-chain resolution
   * of an HTLC to the local node via the secondary HTLC-Success
   * transaction. This secondary transaction is sequence delayed and
   * thus local spends require both parties signatures. The remote
   * node can perform a timeout of this output after the timelock
   * expires.
   *
   * Revocable with witness:
   * [revocationSig, revocationPubKey]
   *
   * Pay to local via the HTLC-Success transaction by using witness
   * [0, remoteHtlcSig, localHtlcSig, preimage]
   *
   * Pay to remote counterparty after the CLTV expiry using witness
   * [remoteHtlcSig, <>]
   *
   * @param paymentHash
   * @param cltvExpiry
   * @param revocationPubKey
   * @param localHtlcPubKey
   * @param remoteHtlcPubKey
   */
  public static receivedHtlcScript(
    paymentHash: Buffer,
    cltvExpiry: number,
    revocationPubKey: Buffer,
    localHtlcPubKey: Buffer,
    remoteHtlcPubKey: Buffer,
  ): Script {
    return new Script(
            // to remote with revocation key
            OpCode.OP_DUP, OpCode.OP_HASH160, hash160(revocationPubKey), OpCode.OP_EQUAL,
            OpCode.OP_IF,
                OpCode.OP_CHECKSIG,
            OpCode.OP_ELSE,
                remoteHtlcPubKey, OpCode.OP_SWAP, OpCode.OP_SIZE, Script.number(32), OpCode.OP_EQUAL,
                OpCode.OP_IF,
                    // to local via HTLC-Success transaction
                    OpCode.OP_HASH160, ripemd160(paymentHash), OpCode.OP_EQUALVERIFY,
                    OpCode.OP_2, OpCode.OP_SWAP, localHtlcPubKey, OpCode.OP_2, OpCode.OP_CHECKMULTISIG,
                OpCode.OP_ELSE,
                    // to remote after cltv expiry with signature
                    OpCode.OP_DROP, Script.number(cltvExpiry), OpCode.OP_CHECKLOCKTIMEVERIFY, OpCode.OP_DROP,
                    OpCode.OP_CHECKSIG,
                OpCode.OP_ENDIF,
            OpCode.OP_ENDIF,
        ); // prettier-ignore
  }
}