Skip to content

Commit

Permalink
Merge pull request #6263 from guggero/schnorr-taproot-signet
Browse files Browse the repository at this point in the history
Taproot: integrate btcec/v2 and btcwallet changes to support Taproot key spend paths in lnd's wallet
  • Loading branch information
Roasbeef committed Mar 25, 2022
2 parents 0dcaa51 + f500892 commit dceb101
Show file tree
Hide file tree
Showing 61 changed files with 1,881 additions and 373 deletions.
44 changes: 44 additions & 0 deletions chainntnfs/txnotifier.go
Expand Up @@ -39,6 +39,19 @@ var (
// notifier to match _and_ dispatch upon detecting the spend of the
// script on-chain, rather than the outpoint.
ZeroOutPoint wire.OutPoint

// zeroV1KeyPush is a pkScript that pushes an all-zero 32-byte Taproot
// SegWit v1 key to the stack.
zeroV1KeyPush = [34]byte{
txscript.OP_1, txscript.OP_DATA_32, // 32 byte of zeroes here
}

// ZeroTaprootPkScript is the parsed txscript.PkScript of an empty
// Taproot SegWit v1 key being pushed to the stack. This allows the
// notifier to match _and_ dispatch upon detecting the spend of the
// outpoint on-chain, rather than the pkScript (which cannot be derived
// from the witness alone in the SegWit v1 case).
ZeroTaprootPkScript, _ = txscript.ParsePkScript(zeroV1KeyPush[:])
)

var (
Expand Down Expand Up @@ -322,6 +335,24 @@ func NewSpendRequest(op *wire.OutPoint, pkScript []byte) (SpendRequest, error) {
}
r.PkScript = outputScript

// For Taproot spends we have the main problem that for the key spend
// path we cannot derive the pkScript from only looking at the input's
// witness. So we need to rely on the outpoint information alone.
//
// TODO(guggero): For script path spends we can derive the pkScript from
// the witness, since we have the full control block and the spent
// script available.
if outputScript.Class() == txscript.WitnessV1TaprootTy {
if op == nil {
return r, fmt.Errorf("cannot register witness v1 " +
"spend request without outpoint")
}

// We have an outpoint, so we can set the pkScript to an all
// zero Taproot key that we'll compare this spend request to.
r.PkScript = ZeroTaprootPkScript
}

return r, nil
}

Expand Down Expand Up @@ -1488,6 +1519,19 @@ func (n *TxNotifier) filterTx(tx *btcutil.Tx, blockHash *chainhash.Hash,
if _, ok := n.spendNotifications[spendRequest]; ok {
notifyDetails(spendRequest, prevOut, uint32(i))
}

// Now try with an empty taproot key pkScript, since we
// cannot derive the spent pkScript directly from the
// witness. But we have the outpoint, which should be
// enough.
spendRequest.PkScript = ZeroTaprootPkScript
if _, ok := n.spendNotifications[spendRequest]; ok {
notifyDetails(spendRequest, prevOut, uint32(i))
}

// Restore the pkScript but try with a zero outpoint
// instead (won't be possible for Taproot).
spendRequest.PkScript = pkScript
spendRequest.OutPoint = ZeroOutPoint
if _, ok := n.spendNotifications[spendRequest]; ok {
notifyDetails(spendRequest, prevOut, uint32(i))
Expand Down
5 changes: 4 additions & 1 deletion cmd/lncli/commands.go
Expand Up @@ -139,7 +139,8 @@ var newAddressCommand = cli.Command{
Description: `
Generate a wallet new address. Address-types has to be one of:
- p2wkh: Pay to witness key hash
- np2wkh: Pay to nested witness key hash`,
- np2wkh: Pay to nested witness key hash
- p2tr: Pay to taproot pubkey`,
Action: actionDecorator(newAddress),
}

Expand All @@ -161,6 +162,8 @@ func newAddress(ctx *cli.Context) error {
addrType = lnrpc.AddressType_WITNESS_PUBKEY_HASH
case "np2wkh":
addrType = lnrpc.AddressType_NESTED_PUBKEY_HASH
case "p2tr":
addrType = lnrpc.AddressType_TAPROOT_PUBKEY
default:
return fmt.Errorf("invalid address type %v, support address type "+
"are: p2wkh and np2wkh", stringAddrType)
Expand Down
9 changes: 8 additions & 1 deletion config_builder.go
Expand Up @@ -1112,7 +1112,14 @@ func importWatchOnlyAccounts(wallet *wallet.Wallet,

for _, scope := range scopes {
addrSchema := waddrmgr.ScopeAddrMap[waddrmgr.KeyScopeBIP0084]
if scope.Scope.Purpose == waddrmgr.KeyScopeBIP0049Plus.Purpose {

// We want witness pubkey hash by default, except for BIP49
// where we want mixed and BIP86 where we want taproot address
// formats.
switch scope.Scope.Purpose {
case waddrmgr.KeyScopeBIP0049Plus.Purpose,
waddrmgr.KeyScopeBIP0086.Purpose:

addrSchema = waddrmgr.ScopeAddrMap[scope.Scope]
}

Expand Down
32 changes: 20 additions & 12 deletions contractcourt/breacharbiter.go
Expand Up @@ -1096,11 +1096,15 @@ func (bo *breachedOutput) SignDesc() *input.SignDescriptor {
// sign descriptor. The method then returns the witness computed by invoking
// this function on the first and subsequent calls.
func (bo *breachedOutput) CraftInputScript(signer input.Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) (*input.Script, error) {
hashCache *txscript.TxSigHashes,
prevOutputFetcher txscript.PrevOutputFetcher,
txinIdx int) (*input.Script, error) {

// First, we ensure that the witness generation function has been
// initialized for this breached output.
bo.witnessFunc = bo.witnessType.WitnessGenerator(signer, bo.SignDesc())
signDesc := bo.SignDesc()
signDesc.PrevOutputFetcher = prevOutputFetcher
bo.witnessFunc = bo.witnessType.WitnessGenerator(signer, signDesc)

// Now that we have ensured that the witness generation function has
// been initialized, we can proceed to execute it and generate the
Expand Down Expand Up @@ -1397,8 +1401,8 @@ func (b *BreachArbiter) sweepSpendableOutputsTxn(txWeight int64,

// Compute the total amount contained in the inputs.
var totalAmt btcutil.Amount
for _, input := range inputs {
totalAmt += btcutil.Amount(input.SignDesc().Output.Value)
for _, inp := range inputs {
totalAmt += btcutil.Amount(inp.SignDesc().Output.Value)
}

// We'll actually attempt to target inclusion within the next two
Expand All @@ -1424,10 +1428,10 @@ func (b *BreachArbiter) sweepSpendableOutputsTxn(txWeight int64,

// Next, we add all of the spendable outputs as inputs to the
// transaction.
for _, input := range inputs {
for _, inp := range inputs {
txn.AddTxIn(&wire.TxIn{
PreviousOutPoint: *input.OutPoint(),
Sequence: input.BlocksToMaturity(),
PreviousOutPoint: *inp.OutPoint(),
Sequence: inp.BlocksToMaturity(),
})
}

Expand All @@ -1440,7 +1444,11 @@ func (b *BreachArbiter) sweepSpendableOutputsTxn(txWeight int64,

// Create a sighash cache to improve the performance of hashing and
// signing SigHashAll inputs.
hashCache := txscript.NewTxSigHashes(txn)
prevOutputFetcher, err := input.MultiPrevOutFetcher(inputs)
if err != nil {
return nil, err
}
hashCache := txscript.NewTxSigHashes(txn, prevOutputFetcher)

// Create a closure that encapsulates the process of initializing a
// particular output's witness generation function, computing the
Expand All @@ -1452,7 +1460,7 @@ func (b *BreachArbiter) sweepSpendableOutputsTxn(txWeight int64,
// transaction using the SpendableOutput's witness generation
// function.
inputScript, err := so.CraftInputScript(
b.cfg.Signer, txn, hashCache, idx,
b.cfg.Signer, txn, hashCache, prevOutputFetcher, idx,
)
if err != nil {
return err
Expand All @@ -1467,8 +1475,8 @@ func (b *BreachArbiter) sweepSpendableOutputsTxn(txWeight int64,

// Finally, generate a witness for each output and attach it to the
// transaction.
for i, input := range inputs {
if err := addWitness(i, input); err != nil {
for i, inp := range inputs {
if err := addWitness(i, inp); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -1648,7 +1656,7 @@ func (ret *retributionInfo) Encode(w io.Writer) error {
return nil
}

// Dencode deserializes a retribution from the passed byte stream.
// Decode deserializes a retribution from the passed byte stream.
func (ret *retributionInfo) Decode(r io.Reader) error {
var scratch [32]byte

Expand Down
7 changes: 5 additions & 2 deletions contractcourt/breacharbiter_test.go
Expand Up @@ -1377,7 +1377,7 @@ func getSpendTransactions(signer input.Signer, chanPoint *wire.OutPoint,
// sign and add the witness to the HTLC sweep.
retInfo := newRetributionInfo(chanPoint, retribution)

hashCache := txscript.NewTxSigHashes(htlcSweep)
hashCache := input.NewTxSigHashesV0Only(htlcSweep)
for i := range retInfo.breachedOutputs {
inp := &retInfo.breachedOutputs[i]

Expand All @@ -1386,8 +1386,11 @@ func getSpendTransactions(signer input.Signer, chanPoint *wire.OutPoint,
case input.HtlcAcceptedRevoke:
fallthrough
case input.HtlcOfferedRevoke:
cannedFetcher := txscript.NewCannedPrevOutputFetcher(
nil, 0,
)
inputScript, err := inp.CraftInputScript(
signer, htlcSweep, hashCache, 0,
signer, htlcSweep, hashCache, cannedFetcher, 0,
)
if err != nil {
return nil, err
Expand Down
9 changes: 9 additions & 0 deletions docs/release-notes/release-notes-0.15.0.md
Expand Up @@ -5,6 +5,15 @@
* [Misconfigured ZMQ
setup now gets reported](https://github.com/lightningnetwork/lnd/pull/5710).

## Taproot

The internal on-chain wallet of `lnd` is now able to create and spend from
[Taproot (SegWit v1)
addresses](https://github.com/lightningnetwork/lnd/pull/6263). Using
`lncli newaddress p2tr` will create a new BIP-0086 keyspend only address and
then watch it on chain. Taproot script spends are also supported through the
`signrpc.SignOutputRaw` RPC (`/v2/signer/signraw` in REST).

## `lncli`

* Add [auto-generated command-line completions](https://github.com/lightningnetwork/lnd/pull/4177)
Expand Down
15 changes: 8 additions & 7 deletions go.mod
Expand Up @@ -4,15 +4,16 @@ require (
github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e // indirect
github.com/NebulousLabs/go-upnp v0.0.0-20180202185039-29b680b06c82
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344
github.com/btcsuite/btcd v0.22.0-beta.0.20220207191057-4dc4ff7963b4
github.com/btcsuite/btcd/btcec/v2 v2.1.0
github.com/btcsuite/btcd/btcutil v1.1.0
github.com/btcsuite/btcd/btcutil/psbt v1.1.0
github.com/btcsuite/btcd v0.22.0-beta.0.20220316175102-8d5c75c28923
github.com/btcsuite/btcd/btcec/v2 v2.1.3
github.com/btcsuite/btcd/btcutil v1.1.1
github.com/btcsuite/btcd/btcutil/psbt v1.1.1
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcwallet v0.14.0
github.com/btcsuite/btcwallet/wallet/txauthor v1.2.1
github.com/btcsuite/btcwallet v0.14.1-0.20220322182735-b0001c262734
github.com/btcsuite/btcwallet/wallet/txauthor v1.2.3
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0
github.com/btcsuite/btcwallet/walletdb v1.3.6-0.20210803004036-eebed51155ec
github.com/btcsuite/btcwallet/walletdb v1.4.0
github.com/btcsuite/btcwallet/wtxmgr v1.5.0
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/davecgh/go-spew v1.1.1
Expand Down
31 changes: 20 additions & 11 deletions go.sum
Expand Up @@ -73,39 +73,46 @@ github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcug
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
github.com/btcsuite/btcd v0.22.0-beta.0.20220204213055-eaf0459ff879/go.mod h1:osu7EoKiL36UThEgzYPqdRaxeo0NU8VoXqgcnwpey0g=
github.com/btcsuite/btcd v0.22.0-beta.0.20220207191057-4dc4ff7963b4 h1:CEGr/598C/0LZQUoioaT6sdGGcJgu4+ck0PDeJ/QkKs=
github.com/btcsuite/btcd v0.22.0-beta.0.20220207191057-4dc4ff7963b4/go.mod h1:7alexyj/lHlOtr2PJK7L/+HDJZpcGDn/pAU98r7DY08=
github.com/btcsuite/btcd/btcec/v2 v2.1.0 h1:Whmbo9yShKKG+WrUfYGFfgj77vYBiwhwBSJnM66TMKI=
github.com/btcsuite/btcd v0.22.0-beta.0.20220316175102-8d5c75c28923 h1:6H47xWODLXYDuzHapvx4dauPqFjegX4+rHgUkFQPvfw=
github.com/btcsuite/btcd v0.22.0-beta.0.20220316175102-8d5c75c28923/go.mod h1:taIcYprAW2g6Z9S0gGUxyR+zDwimyDMK5ePOX+iJ2ds=
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
github.com/btcsuite/btcd/btcec/v2 v2.1.1/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcec/v2 v2.1.3 h1:xM/n3yIhHAhHy04z4i43C8p4ehixJZMsnrVJkgl+MTE=
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
github.com/btcsuite/btcd/btcutil v1.1.0 h1:MO4klnGY+EWJdoWF12Wkuf4AWDBPMpZNeN/jRLrklUU=
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/btcutil/psbt v1.1.0 h1:1LxDjz2ar4L2mrviBdxrzxesMMcAtj4nuBlX4FdqjOA=
github.com/btcsuite/btcd/btcutil/psbt v1.1.0/go.mod h1:xMuACsIKDzcE3kWMxqK+aLrAWZ8bMdn7YjYEwNs5q8k=
github.com/btcsuite/btcd/btcutil v1.1.1 h1:hDcDaXiP0uEzR8Biqo2weECKqEw0uHDZ9ixIWevVQqY=
github.com/btcsuite/btcd/btcutil v1.1.1/go.mod h1:nbKlBMNm9FGsdvKvu0essceubPiAcI57pYBNnsLAa34=
github.com/btcsuite/btcd/btcutil/psbt v1.1.1 h1:t8yNrashLB1ZLqOapxtWy/d8jMfMDgwPKwf70sgnSac=
github.com/btcsuite/btcd/btcutil/psbt v1.1.1/go.mod h1:KsGzRAzAdEimzgERpK9Xm+RhuCMvc4j2ctK0BEQ8JV0=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcwallet v0.14.0 h1:+Nwf0GkRUwDjd/F3i9HgrRhDp8RHZFbBZ3kQaZr6zD0=
github.com/btcsuite/btcwallet v0.14.0/go.mod h1:KFR1x3ZH7c31i4qA34XIvcsnhrEBLK1SHli52lN8E54=
github.com/btcsuite/btcwallet/wallet/txauthor v1.2.1 h1:oxIaFiF8gmOLJh7wNkXYkyLWT7Pj5igSrn5HthPVDYg=
github.com/btcsuite/btcwallet v0.14.1-0.20220322182735-b0001c262734 h1:gG2UgzXLiMiT4sw74161AEf0LE/mxDM8Ia6TaoV0VBw=
github.com/btcsuite/btcwallet v0.14.1-0.20220322182735-b0001c262734/go.mod h1:QN2tl1ipATUQRo9RtgvMHLSspqx7QWsj30qL+7AXuAo=
github.com/btcsuite/btcwallet/wallet/txauthor v1.2.1/go.mod h1:/74bubxX5Js48d76nf/TsNabpYp/gndUuJw4chzCmhU=
github.com/btcsuite/btcwallet/wallet/txauthor v1.2.3 h1:M2yr5UlULvpqtxUqpMxTME/pA92Z9cpqeyvAFk9lAg0=
github.com/btcsuite/btcwallet/wallet/txauthor v1.2.3/go.mod h1:T2xSiKGpUkSLCh68aF+FMXmKK9mFqNdHl9VaqOr+JjU=
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0 h1:BtEN5Empw62/RVnZ0VcJaVtVlBijnLlJY+dwjAye2Bg=
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0/go.mod h1:AtkqiL7ccKWxuLYtZm8Bu8G6q82w4yIZdgq6riy60z0=
github.com/btcsuite/btcwallet/wallet/txsizes v1.1.0 h1:wZnOolEAeNOHzHTnznw/wQv+j35ftCIokNrnOTOU5o8=
github.com/btcsuite/btcwallet/wallet/txsizes v1.1.0/go.mod h1:pauEU8UuMFiThe5PB3EO+gO5kx87Me5NvdQDsTuq6cs=
github.com/btcsuite/btcwallet/walletdb v1.3.5/go.mod h1:oJDxAEUHVtnmIIBaa22wSBPTVcs6hUp5NKWmI8xDwwU=
github.com/btcsuite/btcwallet/walletdb v1.3.6-0.20210803004036-eebed51155ec h1:zcAU3Ij8SmqaE+ITtS76fua2Niq7DRNp46sJRhi8PiI=
github.com/btcsuite/btcwallet/walletdb v1.3.6-0.20210803004036-eebed51155ec/go.mod h1:oJDxAEUHVtnmIIBaa22wSBPTVcs6hUp5NKWmI8xDwwU=
github.com/btcsuite/btcwallet/walletdb v1.4.0 h1:/C5JRF+dTuE2CNMCO/or5N8epsrhmSM4710uBQoYPTQ=
github.com/btcsuite/btcwallet/walletdb v1.4.0/go.mod h1:oJDxAEUHVtnmIIBaa22wSBPTVcs6hUp5NKWmI8xDwwU=
github.com/btcsuite/btcwallet/wtxmgr v1.5.0 h1:WO0KyN4l6H3JWnlFxfGR7r3gDnlGT7W2cL8vl6av4SU=
github.com/btcsuite/btcwallet/wtxmgr v1.5.0/go.mod h1:TQVDhFxseiGtZwEPvLgtfyxuNUDsIdaJdshvWzR0HJ4=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/golangcrypto v0.0.0-20150304025918-53f62d9b43e8/go.mod h1:tYvUd8KLhm/oXvUeSEs2VlLghFjQt9+ZaF9ghH0JNjc=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4=
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE=
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
Expand Down Expand Up @@ -631,6 +638,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
Expand Down

0 comments on commit dceb101

Please sign in to comment.