fix vendor folder

This commit is contained in:
Juan Pablo Civile
2019-12-16 17:59:11 -03:00
parent 240b7f00bd
commit a60e97ace6
72 changed files with 1551 additions and 6487 deletions

54
vendor/github.com/muun/libwallet/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,54 @@
Microsoft Reference Source License (Ms-RSL)
===========================================
This license governs use of the accompanying software. If you use the software,
you accept this license. If you do not accept the license, do not use the
software.
1. Definitions
--------------
The terms "reproduce", "reproduction" and "distribution" have the same meaning
here as under U.S. copyright law.
"You" means the licensee of the software.
"Your company" means the company you worked for when you downloaded the
software.
"Reference use" means use of the software within your company as a reference, in
read only form, for the sole purposes of debugging your products, maintaining
your products, or enhancing the interoperability of your products with the
software, and specifically excludes the right to distribute the software outside
of your company.
Licensed patents" means any Licensor patent claims which read directly on the
software as distributed by the Licensor under this license.
2. Grant of Rights
------------------
(A) Copyright Grant - Subject to the terms of this license, the Licensor grants
you a non-transferable, non-exclusive, worldwide, royalty-free copyright license
to reproduce the software for reference use.
(B) Patent Grant - Subject to the terms of this license, the Licensor grants you
a non-transferable, non-exclusive, worldwide, royalty-free patent license under
licensed patents for reference use.
3. Limitations
--------------
(A) No Trademark License - This license does not grant you any rights to use the
Licensor's name, logo, or trademarks.
(B) If you begin patent litigation against the Licensor over patents that you
think may apply to the software (including a cross-claim or counterclaim in a
lawsuit), your license to the software ends automatically.
(C) The software is licensed "as-is." You bear the risk of using it. The
Licensor gives no express warranties, guarantees or conditions. You may have
additional consumer rights under your local laws which this license cannot
change. To the extent permitted under your local laws, the Licensor excludes the
implied warranties of merchantability, fitness for a particular purpose and
non-infringement.

View File

@@ -24,7 +24,6 @@ func CreateAddressV2(userKey, muunKey *HDPublicKey) (MuunAddress, error) {
address: address.String(),
version: addressV2,
derivationPath: userKey.Path,
redeemScript: script,
}, nil
}

View File

@@ -24,7 +24,6 @@ func CreateAddressV3(userKey, muunKey *HDPublicKey) (MuunAddress, error) {
address: address.EncodeAddress(),
version: addressV3,
derivationPath: userKey.Path,
redeemScript: redeemScript,
}, nil
}
@@ -48,7 +47,6 @@ func addUserSignatureInputV3(input Input, index int, tx *wire.MsgTx, privateKey
return nil, errors.Errorf("muun signature must be present")
}
witnessScript, err := createWitnessScriptV3(privateKey.PublicKey(), muunKey)
if err != nil {
return nil, err
@@ -77,7 +75,7 @@ func signInputV3(input Input, index int, tx *wire.MsgTx, userKey *HDPublicKey, m
redeemScript, err := createRedeemScriptV3(userKey, muunKey)
if err != nil {
return nil, errors.Wrapf(err, "failed to build reedem script for signing")
return nil, errors.Wrapf(err, "failed to build reedem script for signing")
}
return signNonNativeSegwitInput(input, index, tx, signingKey, redeemScript, witnessScript)

71
vendor/github.com/muun/libwallet/V4.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
package libwallet
import (
"crypto/sha256"
"github.com/btcsuite/btcutil"
"github.com/pkg/errors"
"github.com/btcsuite/btcd/wire"
)
func CreateAddressV4(userKey, muunKey *HDPublicKey) (MuunAddress, error) {
witnessScript, err := createWitnessScriptV4(userKey, muunKey)
if err != nil {
return nil, errors.Wrapf(err, "failed to generate witness script v4")
}
witnessScript256 := sha256.Sum256(witnessScript)
address, err := btcutil.NewAddressWitnessScriptHash(witnessScript256[:], userKey.Network.network)
if err != nil {
return nil, err
}
return &muunAddress{
address: address.EncodeAddress(),
version: addressV4,
derivationPath: userKey.Path,
}, nil
}
func createWitnessScriptV4(userKey, muunKey *HDPublicKey) ([]byte, error) {
// createRedeemScriptV2 creates a valid script for V2, V3 and V4 schemes
return createRedeemScriptV2(userKey, muunKey)
}
func addUserSignatureInputV4(input Input, index int, tx *wire.MsgTx, privateKey *HDPrivateKey, muunKey *HDPublicKey) (*wire.TxIn, error) {
if len(input.MuunSignature()) == 0 {
return nil, errors.Errorf("muun signature must be present")
}
witnessScript, err := createWitnessScriptV4(privateKey.PublicKey(), muunKey)
if err != nil {
return nil, err
}
sig, err := signInputV4(input, index, tx, privateKey.PublicKey(), muunKey, privateKey)
if err != nil {
return nil, err
}
zeroByteArray := []byte{}
txInput := tx.TxIn[index]
txInput.Witness = wire.TxWitness{zeroByteArray, sig, input.MuunSignature(), witnessScript}
return txInput, nil
}
func signInputV4(input Input, index int, tx *wire.MsgTx, userKey *HDPublicKey, muunKey *HDPublicKey,
signingKey *HDPrivateKey) ([]byte, error) {
witnessScript, err := createWitnessScriptV4(userKey, muunKey)
if err != nil {
return nil, err
}
return signNativeSegwitInput(input, index, tx, signingKey, witnessScript)
}

View File

@@ -13,20 +13,27 @@ import (
"github.com/pkg/errors"
)
// These constants are here for clients usage.
const (
AddressVersionSwapsV1 = 101
AddressVersionSwapsV2 = 102
)
type AddressVersion int
const (
addressV1 AddressVersion = 1
addressV2 AddressVersion = 2
addressV3 AddressVersion = 3
addressSubmarineSwap AddressVersion = 101
addressV1 AddressVersion = 1
addressV2 AddressVersion = 2
addressV3 AddressVersion = 3
addressV4 AddressVersion = 4
addressSubmarineSwapV1 AddressVersion = AddressVersionSwapsV1
addressSubmarineSwapV2 AddressVersion = AddressVersionSwapsV2
)
type muunAddress struct {
version AddressVersion
derivationPath string
address string
redeemScript []byte
}
func newMuunAddress(version AddressVersion, userPublicKey, muunPublicKey *HDPublicKey) (MuunAddress, error) {
@@ -41,8 +48,12 @@ func newMuunAddress(version AddressVersion, userPublicKey, muunPublicKey *HDPubl
return CreateAddressV2(userPublicKey, muunPublicKey)
case addressV3:
return CreateAddressV3(userPublicKey, muunPublicKey)
case addressSubmarineSwap:
return CreateAddressSubmarineSwap(userPublicKey)
case addressV4:
return CreateAddressV4(userPublicKey, muunPublicKey)
case addressSubmarineSwapV1:
return nil, errors.Errorf("can't manually create a submarine swap v1 address")
case addressSubmarineSwapV2:
return nil, errors.Errorf("can't manually create a submarine swap v2 address")
}
return nil, errors.Errorf("unknown version %v", version)
@@ -60,10 +71,6 @@ func (a *muunAddress) Address() string {
return a.address
}
func (a *muunAddress) RedeemScript() []byte {
return a.redeemScript
}
// MuunPaymentURI is muun's uri struct
type MuunPaymentURI struct {
Address string
@@ -127,7 +134,7 @@ func GetPaymentURI(address string, network *Network) (*MuunPaymentURI, error) {
invoice, err := ParseInvoice(queryValues["lightning"][0], network)
if err == nil {
return &MuunPaymentURI{Invoice:invoice}, nil
return &MuunPaymentURI{Invoice: invoice}, nil
}
}
@@ -240,9 +247,7 @@ func getAddressFromScript(script []byte, network *Network) (string, error) {
func normalizeAddress(rawAddress string) string {
newAddress := rawAddress
if strings.Contains(newAddress, muunScheme) {
newAddress = strings.Replace(newAddress, muunScheme, bitcoinScheme, 1)
}
newAddress = strings.Replace(newAddress, muunScheme, bitcoinScheme, 1)
if !strings.Contains(newAddress, bitcoinScheme) {
newAddress = bitcoinScheme + rawAddress

View File

@@ -55,22 +55,6 @@ func (m *Output) XXX_DiscardUnknown() {
var xxx_messageInfo_Output proto.InternalMessageInfo
const Default_Output_Amount uint64 = 0
func (m *Output) GetAmount() uint64 {
if m != nil && m.Amount != nil {
return *m.Amount
}
return Default_Output_Amount
}
func (m *Output) GetScript() []byte {
if m != nil {
return m.Script
}
return nil
}
type PaymentDetails struct {
Network *string `protobuf:"bytes,1,opt,name=network,def=main" json:"network,omitempty"`
Outputs []*Output `protobuf:"bytes,2,rep,name=outputs" json:"outputs,omitempty"`
@@ -153,13 +137,6 @@ func (m *PaymentDetails) GetPaymentUrl() string {
return ""
}
func (m *PaymentDetails) GetMerchantData() []byte {
if m != nil {
return m.MerchantData
}
return nil
}
type PaymentRequest struct {
PaymentDetailsVersion *uint32 `protobuf:"varint,1,opt,name=payment_details_version,json=paymentDetailsVersion,def=1" json:"payment_details_version,omitempty"`
PkiType *string `protobuf:"bytes,2,opt,name=pki_type,json=pkiType,def=none" json:"pki_type,omitempty"`
@@ -213,26 +190,6 @@ func (m *PaymentRequest) GetPkiType() string {
return Default_PaymentRequest_PkiType
}
func (m *PaymentRequest) GetPkiData() []byte {
if m != nil {
return m.PkiData
}
return nil
}
func (m *PaymentRequest) GetSerializedPaymentDetails() []byte {
if m != nil {
return m.SerializedPaymentDetails
}
return nil
}
func (m *PaymentRequest) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
type X509Certificates struct {
Certificate [][]byte `protobuf:"bytes,1,rep,name=certificate" json:"certificate,omitempty"`
@@ -308,12 +265,6 @@ func (m *Payment) XXX_DiscardUnknown() {
var xxx_messageInfo_Payment proto.InternalMessageInfo
func (m *Payment) GetMerchantData() []byte {
if m != nil {
return m.MerchantData
}
return nil
}
func (m *Payment) GetTransactions() [][]byte {
if m != nil {
@@ -369,13 +320,6 @@ func (m *PaymentACK) XXX_DiscardUnknown() {
var xxx_messageInfo_PaymentACK proto.InternalMessageInfo
func (m *PaymentACK) GetPayment() *Payment {
if m != nil {
return m.Payment
}
return nil
}
func (m *PaymentACK) GetMemo() string {
if m != nil && m.Memo != nil {
return *m.Memo

View File

@@ -3,10 +3,11 @@ module github.com/muun/libwallet
go 1.12
require (
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/go-errors/errors v1.0.1
github.com/golang/protobuf v1.3.2
github.com/lightningnetwork/lnd v0.7.1-beta-rc2
github.com/lightningnetwork/lnd v0.8.0-beta
github.com/pkg/errors v0.8.1
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7
)

View File

@@ -1,6 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
git.schwanenlied.me/yawning/bsaes.git v0.0.0-20180720073208-c0276d75487e/go.mod h1:BWqTsj8PgcPriQJGl7el20J/7TuT1d/hSyFDXMEpoEo=
github.com/NebulousLabs/fastrand v0.0.0-20180208210444-3cf7173006a0/go.mod h1:Bdzq+51GR4/0DIhaICZEOm+OHvXGwwB2trKZ8B4Y6eQ=
github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e/go.mod h1:Bdzq+51GR4/0DIhaICZEOm+OHvXGwwB2trKZ8B4Y6eQ=
github.com/NebulousLabs/go-upnp v0.0.0-20180202185039-29b680b06c82/go.mod h1:GbuBk21JqF+driLX3XtJYNZjGa45YDoa9IqCTzNSfEc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Yawning/aez v0.0.0-20180114000226-4dad034d9db2/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk=
@@ -10,25 +10,22 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/btcsuite/btcd v0.0.0-20180823030728-d81d8877b8f3/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
github.com/btcsuite/btcd v0.0.0-20181130015935-7d2daa5bfef2/go.mod h1:Jr9bmNVGZ7TH2Ux1QuP0ec+yGgh0gE9FIlkzQiI5bR0=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
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-20180706230648-ab6388e0c60a/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcwallet v0.0.0-20180904010540-284e2e0e696e33d5be388f7f3d9a26db703e0c06/go.mod h1:/d7QHZsfUAruXuBhyPITqoYOmJ+nq35qPsJjz/aSpCg=
github.com/btcsuite/btcwallet v0.0.0-20190313032608-acf3b04b0273/go.mod h1:mkOYY8/psBiL5E+Wb0V7M0o+N7NXi2SZJz6+RKkncIc=
github.com/btcsuite/btcwallet v0.0.0-20190319010515-89ab2044f962/go.mod h1:qMi4jGpAO6YRsd81RYDG7o5pBIGqN9faCioJdagLu64=
github.com/btcsuite/btcwallet v0.0.0-20190712034938-7a3a3e82cbb6/go.mod h1:sXVxjjP5YeWqWsiQbQDXvAw6J6Qvr8swu7MONoNaF9k=
github.com/btcsuite/btcwallet v0.10.0/go.mod h1:4TqBEuceheGNdeLNrelliLHJzmXauMM2vtWfuy1pFiM=
github.com/btcsuite/btcwallet/wallet/txauthor v1.0.0/go.mod h1:VufDts7bd/zs3GV13f/lXc/0lXrPnvxD/NvmpG/FEKU=
github.com/btcsuite/btcwallet/wallet/txrules v1.0.0/go.mod h1:UwQE78yCerZ313EXZwEiu3jNAtfXj2n2+c8RWiE/WNA=
github.com/btcsuite/btcwallet/wallet/txsizes v1.0.0/go.mod h1:pauEU8UuMFiThe5PB3EO+gO5kx87Me5NvdQDsTuq6cs=
github.com/btcsuite/btcwallet/walletdb v1.0.0/go.mod h1:bZTy9RyYZh9fLnSua+/CD48TJtYJSHjjYcSaszuxCCk=
github.com/btcsuite/btcwallet/walletdb v1.1.0/go.mod h1:bZTy9RyYZh9fLnSua+/CD48TJtYJSHjjYcSaszuxCCk=
github.com/btcsuite/btcwallet/wtxmgr v1.0.0/go.mod h1:vc4gBprll6BP0UJ+AIGDaySoc7MdAmZf8kelfNb8CFY=
github.com/btcsuite/fastsha256 v0.0.0-20160815193821-637e65642941/go.mod h1:QcFA8DZHtuIAdYKCq/BzELOaznRsCvwf4zTPmaYwaig=
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=
@@ -40,12 +37,12 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v0.0.0-20180223184059-7ee3ded59d4835e10f3e7d0f7603c42aa5e83820/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@@ -57,11 +54,11 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v0.0.0-20180821051752-b27b920f9e71/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v0.0.0-20170724004829-f2862b476edc/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
@@ -71,11 +68,11 @@ github.com/jackpal/go-nat-pmp v0.0.0-20170405195558-28a68d0c24ad/go.mod h1:QPH04
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/juju/clock v0.0.0-20180808021310-bab88fc67299/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA=
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA=
github.com/juju/errors v0.0.0-20190806202954-0232dcc7464d/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/retry v0.0.0-20180821225755-9058e192b216/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4=
github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/juju/testing v0.0.0-20190723135506-ce30eb24acd2/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/juju/utils v0.0.0-20180820210520-bf9cc5bdd62d/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk=
github.com/juju/version v0.0.0-20180108022336-b64dbd566305/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
@@ -87,18 +84,13 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightninglabs/gozmq v0.0.0-20180324010646-462a8a753885/go.mod h1:KUh15naRlx/TmUMFS/p4JJrCrE6F7RGF7rsnvuu45E4=
github.com/lightninglabs/gozmq v0.0.0-20190710231225-cea2a031735d/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
github.com/lightninglabs/neutrino v0.0.0-20181017011010-4d6069299130/go.mod h1:KJq43Fu9ceitbJsSXMILcT4mGDNI/crKmPIkDOZXFyM=
github.com/lightninglabs/neutrino v0.0.0-20190213031021-ae4583a89cfb/go.mod h1:g6cMQd+hfAU8pQTJAdjm6/EQREhupyd22f+CL0qYFOE=
github.com/lightninglabs/neutrino v0.0.0-20190313035638-e1ad4c33fb18/go.mod h1:v6tz6jbuAubTrRpX8ke2KH9sJxml8KlPQTKgo9mAp1Q=
github.com/lightninglabs/neutrino v0.0.0-20190725230401-ddf667a8b5c4/go.mod h1:vzLU75ll8qbRJIzW5dvK/UXtR9c2FecJ6VNOM8chyVM=
github.com/lightningnetwork/lightning-onion v0.0.0-20190703000913-ecc936dc56c9/go.mod h1:Sooe/CoCqa85JxqHV+IBR2HW+6t2Cv+36awSmoccswM=
github.com/lightningnetwork/lnd v0.7.1-beta-rc2 h1:N0AuHo4wI6TogabvOfpwg1LkR3RxGCvqYq0Wb7GL+ck=
github.com/lightningnetwork/lnd v0.7.1-beta-rc2/go.mod h1:ODASBFcJwVlb4aqO3m090whpP2kfA9zEvmG/pj+fOfg=
github.com/lightninglabs/neutrino v0.10.0/go.mod h1:C3KhCMk1Mcx3j8v0qRVWM1Ow6rIJSvSPnUAq00ZNAfk=
github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4=
github.com/lightningnetwork/lnd v0.8.0-beta h1:HmmhSRTq48qobqQF8YLqNa8eKU8dDBNbWWpr2VzycJM=
github.com/lightningnetwork/lnd v0.8.0-beta/go.mod h1:nq06y2BDv7vwWeMmwgB7P3pT7/Uj7sGf5FzHISVD6t4=
github.com/lightningnetwork/lnd/queue v1.0.1/go.mod h1:vaQwexir73flPW43Mrm7JOgJHmcEFBWWSl9HlyASoms=
github.com/lightningnetwork/lnd/ticker v1.0.0/go.mod h1:iaLXJiVgI1sPANIF2qYYUJXjoksPNvGNYowB8aRbpX0=
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw=
github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796/go.mod h1:3p7ZTf9V1sNPI5H8P3NkTFF4LuwMdPl2DodF60qAKqY=
github.com/ltcsuite/ltcutil v0.0.0-20181217130922-17f3b04680b6/go.mod h1:8Vg/LTOO0KYa/vlHWJ6XZAevPQThGH5sufO0Hrou/lA=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -123,19 +115,16 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tv42/zbase32 v0.0.0-20160707012821-501572607d02/go.mod h1:tHlrkM198S068ZqfrO6S8HsoJq2bF3ETfTL+kt4tInY=
github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
go.etcd.io/bbolt v1.3.0/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU=
@@ -144,7 +133,6 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180821023952-922f4815f713/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -156,16 +144,15 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180821140842-3b58ed4ad339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -173,18 +160,16 @@ golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGm
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.18.0 h1:IZl7mfBGfbhYx2p2rKRtYgDFw6SBz+kclmxYrCksPPA=
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v1 v1.0.0/go.mod h1:CxwszS/Xz1C49Ucd2i6Zil5UToP1EmyrFhKaMVbg1mk=
gopkg.in/errgo.v1 v1.0.1/go.mod h1:3NjfXwocQRYAPTq4/fzX+CwUhPRcR/azYRhj8G+LqMo=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/macaroon-bakery.v2 v2.0.1/go.mod h1:B4/T17l+ZWGwxFSZQmlBwp25x+og7OkhETfr3S9MbIA=
gopkg.in/macaroon.v2 v2.0.0/go.mod h1:+I6LnTMkm/uV5ew/0nsulNjL16SK4+C8yDmRUzHR17I=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -39,9 +39,9 @@ func NewHDPrivateKeyFromBytes(rawKey, chainCode []byte, network *Network) (*HDPr
// NewHDPrivateKeyFromString creates an HD priv key from a base58-encoded string
// If the parsed key is public, it returns an error
func NewHDPrivateKeyFromString(str, path string) (*HDPrivateKey, error) {
func NewHDPrivateKeyFromString(str, path string, network *Network) (*HDPrivateKey, error) {
key, network, err := keyFromString(str)
key, _, err := keyFromString(str)
if err != nil {
return nil, err
}

View File

@@ -18,9 +18,9 @@ type HDPublicKey struct {
// NewHDPublicKeyFromString creates an HD pub key from a base58-encoded string
// If the parsed key is private, it returns an error
func NewHDPublicKeyFromString(str, path string) (*HDPublicKey, error) {
func NewHDPublicKeyFromString(str, path string, network *Network) (*HDPublicKey, error) {
key, network, err := keyFromString(str)
key, _, err := keyFromString(str)
if err != nil {
return nil, err
}

View File

@@ -27,7 +27,7 @@ func ParseInvoice(invoice string, network *Network) (*Invoice, error) {
if strings.HasPrefix(strings.ToLower(invoice), lightningScheme) {
// Remove lightning scheme from rawInvoice
invoice = invoice[len(lightningScheme):len(invoice)]
invoice = invoice[len(lightningScheme):]
}
parsedInvoice, err := zpay32.Decode(invoice, network.network)

View File

@@ -64,7 +64,7 @@ func KeyEncrypt(key *HDPrivateKey, passphrase string) (string, error) {
}
// KeyDecrypt decrypts a key encrypted with KeyEncrypt
func KeyDecrypt(value, passphrase string) (*DecryptedKey, error) {
func KeyDecrypt(value, passphrase string, network *Network) (*DecryptedKey, error) {
elements := strings.Split(value, seperator)
@@ -126,7 +126,7 @@ func KeyDecrypt(value, passphrase string) (*DecryptedKey, error) {
encodedPrivateKey := string(decryptedBytes[:])
path := string(pathBytes[:])
privateKey, err := NewHDPrivateKeyFromString(encodedPrivateKey, path)
privateKey, err := NewHDPrivateKeyFromString(encodedPrivateKey, path, network)
if err != nil {
return nil, errors.New("KeyCrypter: failed to decode pk: " + err.Error())
}

View File

@@ -25,19 +25,29 @@ type Outpoint interface {
Amount() int64
}
type InputSubmarineSwap interface {
type InputSubmarineSwapV1 interface {
RefundAddress() string
PaymentHash256() []byte
ServerPublicKey() []byte
LockTime() int64
}
type InputSubmarineSwapV2 interface {
PaymentHash256() []byte
UserPublicKey() []byte
MuunPublicKey() []byte
ServerPublicKey() []byte
BlocksForExpiration() int64
ServerSignature() []byte
}
type Input interface {
OutPoint() Outpoint
Address() MuunAddress
UserSignature() []byte
MuunSignature() []byte
SubmarineSwap() InputSubmarineSwap
SubmarineSwapV1() InputSubmarineSwapV1
SubmarineSwapV2() InputSubmarineSwapV2
}
type PartiallySignedTransaction struct {
@@ -93,8 +103,12 @@ func (p *PartiallySignedTransaction) Sign(key *HDPrivateKey, muunKey *HDPublicKe
txIn, err = addUserSignatureInputV2(input, i, p.tx, derivedKey, derivedMuunKey)
case addressV3:
txIn, err = addUserSignatureInputV3(input, i, p.tx, derivedKey, derivedMuunKey)
case addressSubmarineSwap:
txIn, err = addUserSignatureInputSubmarineSwap(input, i, p.tx, derivedKey, derivedMuunKey)
case addressV4:
txIn, err = addUserSignatureInputV4(input, i, p.tx, derivedKey, derivedMuunKey)
case addressSubmarineSwapV1:
txIn, err = addUserSignatureInputSubmarineSwapV1(input, i, p.tx, derivedKey, derivedMuunKey)
case addressSubmarineSwapV2:
txIn, err = addUserSignatureInputSubmarineSwapV2(input, i, p.tx, derivedKey, derivedMuunKey)
default:
return nil, errors.Errorf("cant sign transaction of version %v", input.Address().Version())
}
@@ -141,9 +155,13 @@ func (p *PartiallySignedTransaction) MuunSignatureForInput(index int, userKey *H
return signInputV2(input, index, p.tx, derivedUserKey, derivedMuunKey.PublicKey(), derivedMuunKey)
case addressV3:
return signInputV3(input, index, p.tx, derivedUserKey, derivedMuunKey.PublicKey(), derivedMuunKey)
case addressSubmarineSwap:
return nil, errors.New("cant sign arbitrary submarine swap inputs")
case addressV4:
return signInputV4(input, index, p.tx, derivedUserKey, derivedMuunKey.PublicKey(), derivedMuunKey)
case addressSubmarineSwapV1:
return nil, errors.New("cant sign arbitrary submarine swap v1 inputs")
case addressSubmarineSwapV2:
return nil, errors.New("cant sign arbitrary submarine swap v2 inputs")
}
return nil, errors.New("unknown address scheme")
}
}

View File

@@ -1,7 +1,7 @@
package libwallet
import (
hash "golang.org/x/crypto/ripemd160"
hash "golang.org/x/crypto/ripemd160" //lint:ignore SA1019 using deprecated hash function for compatibility
)
func ripemd160(data []byte) []byte {

View File

@@ -8,6 +8,22 @@ import (
"github.com/pkg/errors"
)
func signNativeSegwitInput(input Input, index int, tx *wire.MsgTx, privateKey *HDPrivateKey, witnessScript []byte) ([]byte, error) {
privKey, err := privateKey.key.ECPrivKey()
if err != nil {
return nil, errors.Wrapf(err, "failed to produce EC priv key for signing")
}
sigHashes := txscript.NewTxSigHashes(tx)
sig, err := txscript.RawTxInWitnessSignature(tx, sigHashes, index, input.OutPoint().Amount(), witnessScript, txscript.SigHashAll, privKey)
if err != nil {
return nil, errors.Wrapf(err, "failed to sign V4 input")
}
return sig, nil
}
func createNonNativeSegwitRedeemScript(witnessScript []byte) ([]byte, error) {
witnessScriptHash := sha256.Sum256(witnessScript)

View File

@@ -1,14 +1,7 @@
package libwallet
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/pkg/errors"
"github.com/go-errors/errors"
)
type SubmarineSwap interface {
@@ -26,190 +19,33 @@ type SubmarineSwapReceiver interface {
}
type SubmarineSwapFundingOutput interface {
ScriptVersion() int64
OutputAddress() string
OutputAmount() int64
ConfirmationsNeeded() int
UserLockTime() int64
UserRefundAddress() MuunAddress
ServerPaymentHashInHex() string
ServerPublicKeyInHex() string
UserLockTime() int64
// v1 only
UserRefundAddress() MuunAddress
// v2 only
ExpirationInBlocks() int64
UserPublicKey() *HDPublicKey
MuunPublicKey() *HDPublicKey
}
func CreateAddressSubmarineSwap(publicKey *HDPublicKey) (MuunAddress, error) {
pubkey, err := btcutil.NewAddressPubKey(publicKey.Raw(), publicKey.Network.network)
if err != nil {
return nil, err
func ValidateSubmarineSwap(rawInvoice string, userPublicKey *HDPublicKey, muunPublicKey *HDPublicKey, swap SubmarineSwap, originalExpirationInBlocks int64, network *Network) error {
switch AddressVersion(swap.FundingOutput().ScriptVersion()) {
case addressSubmarineSwapV1:
return ValidateSubmarineSwapV1(rawInvoice, userPublicKey, muunPublicKey, swap, network)
case addressSubmarineSwapV2:
return ValidateSubmarineSwapV2(rawInvoice, userPublicKey, muunPublicKey, swap, originalExpirationInBlocks, network)
}
pubkeyHash := pubkey.AddressPubKeyHash()
address := pubkeyHash.String()
return &muunAddress{address: address, version: addressSubmarineSwap, derivationPath: publicKey.Path}, nil
}
func addUserSignatureInputSubmarineSwap(input Input, index int, tx *wire.MsgTx, privateKey *HDPrivateKey,
muunKey *HDPublicKey) (*wire.TxIn, error) {
submarineSwap := input.SubmarineSwap()
if submarineSwap == nil {
return nil, errors.Errorf("submarine swap data is nil for ss input")
}
witnessScript, err := createWitnessScriptSubmarineSwap(submarineSwap.RefundAddress(),
submarineSwap.PaymentHash256(),
submarineSwap.ServerPublicKey(),
submarineSwap.LockTime(),
privateKey.Network)
if err != nil {
return nil, err
}
redeemScript, err := createNonNativeSegwitRedeemScript(witnessScript)
if err != nil {
return nil, errors.Wrapf(err, "failed to build reedem script for signing")
}
sig, err := signNonNativeSegwitInput(input, index, tx, privateKey, redeemScript, witnessScript)
if err != nil {
return nil, err
}
txInput := tx.TxIn[index]
txInput.Witness = wire.TxWitness{sig, privateKey.PublicKey().Raw(), witnessScript}
return txInput, nil
}
func createRedeemScriptSubmarineSwapForUser(publicKey *HDPublicKey) {
}
func createWitnessScriptSubmarineSwap(refundAddress string, paymentHash []byte, swapServerPubKey []byte, lockTime int64, network *Network) ([]byte, error) {
// It turns out that the payment hash present in an invoice is just the SHA256 of the
// payment preimage, so we still have to do a pass of RIPEMD160 before pushing it to the
// script
paymentHash160 := ripemd160(paymentHash)
decodedRefundAddress, err := btcutil.DecodeAddress(refundAddress, network.network)
if err != nil {
return nil, errors.Wrapf(err, "refund address is invalid")
}
refundAddressHash := decodedRefundAddress.ScriptAddress()
builder := txscript.NewScriptBuilder()
builder.AddOp(txscript.OP_DUP)
// Condition to decide which branch to follow:
builder.AddOp(txscript.OP_HASH160).
AddData(paymentHash160).
AddOp(txscript.OP_EQUAL)
// SubmarineSwap service spending script, for successful LN payments:
builder.AddOp(txscript.OP_IF).
AddOp(txscript.OP_DROP).
AddData(swapServerPubKey)
// User spending script, for failed LN payments:
builder.AddOp(txscript.OP_ELSE).
AddInt64(lockTime).
AddOp(txscript.OP_CHECKLOCKTIMEVERIFY).
AddOp(txscript.OP_DROP).
AddOp(txscript.OP_DUP).
AddOp(txscript.OP_HASH160).
AddData(refundAddressHash).
AddOp(txscript.OP_EQUALVERIFY)
// Final verification for both branches:
builder.AddOp(txscript.OP_ENDIF).
AddOp(txscript.OP_CHECKSIG)
return builder.Script()
}
func ValidateSubmarineSwap(rawInvoice string, userPublicKey *HDPublicKey, muunPublicKey *HDPublicKey, swap SubmarineSwap, network *Network) error {
invoice, err := ParseInvoice(rawInvoice, network)
if err != nil {
return errors.Wrapf(err, "failed to decode invoice")
}
// Check the payment hash matches
serverPaymentHash, err := hex.DecodeString(swap.FundingOutput().ServerPaymentHashInHex())
if err != nil {
return errors.Wrapf(err, "server payment hash is not valid hex")
}
if !bytes.Equal(invoice.PaymentHash[:], serverPaymentHash) {
return errors.Errorf("payment hash doesn't match %v != %v", invoice.PaymentHash, swap.FundingOutput().ServerPaymentHashInHex())
}
// TODO: check that timelock is acceptable
// Validate that the refund address is one we can derive
swapRefundAddress := swap.FundingOutput().UserRefundAddress()
derivedUserKey, err := userPublicKey.DeriveTo(swapRefundAddress.DerivationPath())
if err != nil {
return errors.Wrapf(err, "failed to derive user key")
}
derivedMuunKey, err := muunPublicKey.DeriveTo(swapRefundAddress.DerivationPath())
if err != nil {
return errors.Wrapf(err, "failed to derive muun key")
}
refundAddress, err := newMuunAddress(AddressVersion(swapRefundAddress.Version()), derivedUserKey, derivedMuunKey)
if err != nil {
return errors.Wrapf(err, "failed to generate refund address")
}
if refundAddress.Address() != swapRefundAddress.Address() {
return errors.Errorf("refund address doesn't match generated (%v != %v)", swapRefundAddress.Address(), refundAddress.Address())
}
// Check the swap's witness script is a valid swap script
serverPubKey, err := hex.DecodeString(swap.FundingOutput().ServerPublicKeyInHex())
if err != nil {
return errors.Wrapf(err, "server pub key is not hex")
}
witnessScript, err := createWitnessScriptSubmarineSwap(
swapRefundAddress.Address(),
serverPaymentHash,
serverPubKey,
swap.FundingOutput().UserLockTime(),
network)
if err != nil {
return errors.Wrapf(err, "failed to compute witness script")
}
redeemScript, err := createNonNativeSegwitRedeemScript(witnessScript)
if err != nil {
return errors.Wrapf(err, "failed to build redeem script")
}
address, err := btcutil.NewAddressScriptHash(redeemScript, network.network)
if err != nil {
return errors.Wrapf(err, "failed to build address for swap script")
}
if address.EncodeAddress() != swap.FundingOutput().OutputAddress() {
return errors.Errorf("address for swap script mismatch (%v != %v)", address.EncodeAddress(), swap.FundingOutput().OutputAddress())
}
if len(swap.PreimageInHex()) > 0 {
preimage, err := hex.DecodeString(swap.PreimageInHex())
if err != nil {
return errors.Wrapf(err, "preimagehex is not actually hex 🤔")
}
calculatedPaymentHash := sha256.Sum256(preimage)
if !bytes.Equal(invoice.PaymentHash[:], calculatedPaymentHash[:]) {
return errors.Errorf("payment hash doesn't match preimage (%v != hash(%v)", invoice.PaymentHash, swap.PreimageInHex())
}
}
return nil
return errors.Errorf("unknown swap version %v", swap.FundingOutput().ScriptVersion())
}

180
vendor/github.com/muun/libwallet/submarineSwapV1.go generated vendored Normal file
View File

@@ -0,0 +1,180 @@
package libwallet
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/pkg/errors"
)
func addUserSignatureInputSubmarineSwapV1(input Input, index int, tx *wire.MsgTx, privateKey *HDPrivateKey,
muunKey *HDPublicKey) (*wire.TxIn, error) {
submarineSwap := input.SubmarineSwapV1()
if submarineSwap == nil {
return nil, errors.Errorf("submarine swap data is nil for ss input")
}
witnessScript, err := createWitnessScriptSubmarineSwapV1(submarineSwap.RefundAddress(),
submarineSwap.PaymentHash256(),
submarineSwap.ServerPublicKey(),
submarineSwap.LockTime(),
privateKey.Network)
if err != nil {
return nil, err
}
redeemScript, err := createNonNativeSegwitRedeemScript(witnessScript)
if err != nil {
return nil, errors.Wrapf(err, "failed to build reedem script for signing")
}
sig, err := signNonNativeSegwitInput(input, index, tx, privateKey, redeemScript, witnessScript)
if err != nil {
return nil, err
}
txInput := tx.TxIn[index]
txInput.Witness = wire.TxWitness{sig, privateKey.PublicKey().Raw(), witnessScript}
return txInput, nil
}
//lint:ignore U1000 unused function for consistency with other schemes
func createRedeemScriptSubmarineSwapForUser(publicKey *HDPublicKey) {
}
func createWitnessScriptSubmarineSwapV1(refundAddress string, paymentHash []byte, swapServerPubKey []byte, lockTime int64, network *Network) ([]byte, error) {
// It turns out that the payment hash present in an invoice is just the SHA256 of the
// payment preimage, so we still have to do a pass of RIPEMD160 before pushing it to the
// script
paymentHash160 := ripemd160(paymentHash)
decodedRefundAddress, err := btcutil.DecodeAddress(refundAddress, network.network)
if err != nil {
return nil, errors.Wrapf(err, "refund address is invalid")
}
refundAddressHash := decodedRefundAddress.ScriptAddress()
builder := txscript.NewScriptBuilder()
builder.AddOp(txscript.OP_DUP)
// Condition to decide which branch to follow:
builder.AddOp(txscript.OP_HASH160).
AddData(paymentHash160).
AddOp(txscript.OP_EQUAL)
// SubmarineSwap service spending script, for successful LN payments:
builder.AddOp(txscript.OP_IF).
AddOp(txscript.OP_DROP).
AddData(swapServerPubKey)
// User spending script, for failed LN payments:
builder.AddOp(txscript.OP_ELSE).
AddInt64(lockTime).
AddOp(txscript.OP_CHECKLOCKTIMEVERIFY).
AddOp(txscript.OP_DROP).
AddOp(txscript.OP_DUP).
AddOp(txscript.OP_HASH160).
AddData(refundAddressHash).
AddOp(txscript.OP_EQUALVERIFY)
// Final verification for both branches:
builder.AddOp(txscript.OP_ENDIF).
AddOp(txscript.OP_CHECKSIG)
return builder.Script()
}
func ValidateSubmarineSwapV1(rawInvoice string, userPublicKey *HDPublicKey, muunPublicKey *HDPublicKey, swap SubmarineSwap, network *Network) error {
invoice, err := ParseInvoice(rawInvoice, network)
if err != nil {
return errors.Wrapf(err, "failed to decode invoice")
}
// Check the payment hash matches
serverPaymentHash, err := hex.DecodeString(swap.FundingOutput().ServerPaymentHashInHex())
if err != nil {
return errors.Wrapf(err, "server payment hash is not valid hex")
}
if !bytes.Equal(invoice.PaymentHash[:], serverPaymentHash) {
return errors.Errorf("payment hash doesn't match %v != %v", invoice.PaymentHash, swap.FundingOutput().ServerPaymentHashInHex())
}
// TODO: check that timelock is acceptable
// Validate that the refund address is one we can derive
swapRefundAddress := swap.FundingOutput().UserRefundAddress()
derivedUserKey, err := userPublicKey.DeriveTo(swapRefundAddress.DerivationPath())
if err != nil {
return errors.Wrapf(err, "failed to derive user key")
}
derivedMuunKey, err := muunPublicKey.DeriveTo(swapRefundAddress.DerivationPath())
if err != nil {
return errors.Wrapf(err, "failed to derive muun key")
}
refundAddress, err := newMuunAddress(AddressVersion(swapRefundAddress.Version()), derivedUserKey, derivedMuunKey)
if err != nil {
return errors.Wrapf(err, "failed to generate refund address")
}
if refundAddress.Address() != swapRefundAddress.Address() {
return errors.Errorf("refund address doesn't match generated (%v != %v)", swapRefundAddress.Address(), refundAddress.Address())
}
// Check the swap's witness script is a valid swap script
serverPubKey, err := hex.DecodeString(swap.FundingOutput().ServerPublicKeyInHex())
if err != nil {
return errors.Wrapf(err, "server pub key is not hex")
}
witnessScript, err := createWitnessScriptSubmarineSwapV1(
swapRefundAddress.Address(),
serverPaymentHash,
serverPubKey,
swap.FundingOutput().UserLockTime(),
network)
if err != nil {
return errors.Wrapf(err, "failed to compute witness script")
}
redeemScript, err := createNonNativeSegwitRedeemScript(witnessScript)
if err != nil {
return errors.Wrapf(err, "failed to build redeem script")
}
address, err := btcutil.NewAddressScriptHash(redeemScript, network.network)
if err != nil {
return errors.Wrapf(err, "failed to build address for swap script")
}
if address.EncodeAddress() != swap.FundingOutput().OutputAddress() {
return errors.Errorf("address for swap script mismatch (%v != %v)", address.EncodeAddress(), swap.FundingOutput().OutputAddress())
}
if len(swap.PreimageInHex()) > 0 {
preimage, err := hex.DecodeString(swap.PreimageInHex())
if err != nil {
return errors.Wrapf(err, "preimagehex is not actually hex 🤔")
}
calculatedPaymentHash := sha256.Sum256(preimage)
if !bytes.Equal(invoice.PaymentHash[:], calculatedPaymentHash[:]) {
return errors.Errorf("payment hash doesn't match preimage (%v != hash(%v)", invoice.PaymentHash, swap.PreimageInHex())
}
}
return nil
}

231
vendor/github.com/muun/libwallet/submarineSwapV2.go generated vendored Normal file
View File

@@ -0,0 +1,231 @@
package libwallet
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/pkg/errors"
)
func addUserSignatureInputSubmarineSwapV2(input Input, index int, tx *wire.MsgTx, privateKey *HDPrivateKey,
muunKey *HDPublicKey) (*wire.TxIn, error) {
submarineSwap := input.SubmarineSwapV2()
if submarineSwap == nil {
return nil, errors.Errorf("submarine swap data is nil for ss input")
}
if len(submarineSwap.ServerSignature()) == 0 {
return nil, errors.Errorf("Swap server must provide signature")
}
witnessScript, err := createWitnessScriptSubmarineSwapV2(
submarineSwap.PaymentHash256(),
submarineSwap.UserPublicKey(),
submarineSwap.MuunPublicKey(),
submarineSwap.ServerPublicKey(),
submarineSwap.BlocksForExpiration())
if err != nil {
return nil, err
}
sig, err := signNativeSegwitInput(input, index, tx, privateKey, witnessScript)
if err != nil {
return nil, err
}
txInput := tx.TxIn[index]
txInput.Witness = wire.TxWitness{
sig,
submarineSwap.ServerSignature(),
witnessScript,
}
return txInput, nil
}
func createWitnessScriptSubmarineSwapV2(paymentHash, userPubKey, muunPubKey, swapServerPubKey []byte, blocksForExpiration int64) ([]byte, error) {
// It turns out that the payment hash present in an invoice is just the SHA256 of the
// payment preimage, so we still have to do a pass of RIPEMD160 before pushing it to the
// script
paymentHash160 := ripemd160(paymentHash)
muunPublicKeyHash160 := btcutil.Hash160(muunPubKey)
// Equivalent miniscript (http://bitcoin.sipa.be/miniscript/):
// or(
// and(pk(userPublicKey), pk(swapServerPublicKey)),
// or(
// and(pk(swapServerPublicKey), hash160(swapPaymentHash160)),
// and(pk(userPublicKey), and(pk(muunPublicKey), older(numBlocksForExpiration)))
// )
// )
//
// However, we differ in that the size of the script was heavily optimized for spending the
// first two branches (the collaborative close and the unilateral close by swapper), which
// are the most probable to be used.
builder := txscript.NewScriptBuilder().
// Push the user public key to the second position of the stack
AddData(userPubKey).
AddOp(txscript.OP_SWAP).
// Check whether the first stack item was a valid swap server signature
AddData(swapServerPubKey).
AddOp(txscript.OP_CHECKSIG).
// If the swap server signature was correct
AddOp(txscript.OP_IF).
AddOp(txscript.OP_SWAP).
// Check whether the second stack item was the payment preimage
AddOp(txscript.OP_DUP).
AddOp(txscript.OP_HASH160).
AddData(paymentHash160).
AddOp(txscript.OP_EQUAL).
// If the preimage was correct
AddOp(txscript.OP_IF).
// We are done, leave just one true-ish item in the stack (there're 2
// remaining items)
AddOp(txscript.OP_DROP).
// If the second stack item wasn't a valid payment preimage
AddOp(txscript.OP_ELSE).
// Validate that the second stack item was a valid user signature
AddOp(txscript.OP_SWAP).
AddOp(txscript.OP_CHECKSIG).
AddOp(txscript.OP_ENDIF).
// If the first stack item wasn't a valid server signature
AddOp(txscript.OP_ELSE).
// Validate that the blockchain height is big enough
AddInt64(blocksForExpiration).
AddOp(txscript.OP_CHECKSEQUENCEVERIFY).
AddOp(txscript.OP_DROP).
// Validate that the second stack item was a valid user signature
AddOp(txscript.OP_CHECKSIGVERIFY).
// Validate that the third stack item was the muun public key
AddOp(txscript.OP_DUP).
AddOp(txscript.OP_HASH160).
AddData(muunPublicKeyHash160).
AddOp(txscript.OP_EQUALVERIFY).
// Notice that instead of directly pushing the public key here and checking the
// signature P2PK-style, we pushed the hash of the public key, and require an
// extra stack item with the actual public key, verifying the signature and
// public key P2PKH-style.
//
// This trick reduces the on-chain footprint of the muun key from 33 bytes to
// 20 bytes for the collaborative, and swap server's non-collaborative branches,
// which are the most frequent ones.
// Validate that the fourth stack item was a valid server signature
AddOp(txscript.OP_CHECKSIG).
AddOp(txscript.OP_ENDIF)
return builder.Script()
}
func ValidateSubmarineSwapV2(rawInvoice string, userPublicKey *HDPublicKey, muunPublicKey *HDPublicKey, swap SubmarineSwap, originalExpirationInBlocks int64, network *Network) error {
fundingOutput := swap.FundingOutput()
invoice, err := ParseInvoice(rawInvoice, network)
if err != nil {
return errors.Wrapf(err, "failed to decode invoice")
}
// Check the payment hash matches
serverPaymentHash, err := hex.DecodeString(fundingOutput.ServerPaymentHashInHex())
if err != nil {
return errors.Wrapf(err, "server payment hash is not valid hex")
}
if !bytes.Equal(invoice.PaymentHash[:], serverPaymentHash) {
return errors.Errorf("payment hash doesn't match %v != %v", invoice.PaymentHash, fundingOutput.ServerPaymentHashInHex())
}
destination, err := hex.DecodeString(swap.Receiver().PublicKey())
if err != nil {
return errors.Wrapf(err, "destination is not valid hex")
}
if !bytes.Equal(invoice.Destination[:], destination) {
return errors.Errorf("destination doesnt match %v != %v", invoice.Destination, swap.Receiver().PublicKey())
}
if fundingOutput.ExpirationInBlocks() != originalExpirationInBlocks {
return errors.Errorf("expiration in blocks doesnt match %v != %v", originalExpirationInBlocks, fundingOutput.ExpirationInBlocks())
}
// Validate that we can derive the addresses involved
derivationPath := fundingOutput.UserPublicKey().Path
derivedUserKey, err := userPublicKey.DeriveTo(derivationPath)
if err != nil {
return errors.Wrapf(err, "failed to derive user key")
}
if !bytes.Equal(derivedUserKey.Raw(), fundingOutput.UserPublicKey().Raw()) {
return errors.Errorf("user pub keys dont match %v != %v", derivedUserKey.String(), fundingOutput.UserPublicKey().String())
}
derivedMuunKey, err := muunPublicKey.DeriveTo(derivationPath)
if err != nil {
return errors.Wrapf(err, "failed to derive muun key")
}
if !bytes.Equal(derivedMuunKey.Raw(), fundingOutput.MuunPublicKey().Raw()) {
return errors.Errorf("muun pub keys dont match %v != %v", derivedMuunKey.String(), fundingOutput.MuunPublicKey().String())
}
// Check the swap's witness script is a valid swap script
serverPubKey, err := hex.DecodeString(swap.FundingOutput().ServerPublicKeyInHex())
if err != nil {
return errors.Wrapf(err, "server pub key is not hex")
}
witnessScript, err := createWitnessScriptSubmarineSwapV2(
serverPaymentHash,
derivedUserKey.Raw(),
derivedMuunKey.Raw(),
serverPubKey,
swap.FundingOutput().ExpirationInBlocks())
if err != nil {
return errors.Wrapf(err, "failed to compute witness script")
}
witnessScriptHash := sha256.Sum256(witnessScript)
address, err := btcutil.NewAddressWitnessScriptHash(witnessScriptHash[:], network.network)
if err != nil {
return errors.Wrapf(err, "failed to build address for swap script")
}
if address.EncodeAddress() != swap.FundingOutput().OutputAddress() {
return errors.Errorf("address for swap script mismatch (%v != %v)", address.EncodeAddress(), swap.FundingOutput().OutputAddress())
}
if len(swap.PreimageInHex()) > 0 {
preimage, err := hex.DecodeString(swap.PreimageInHex())
if err != nil {
return errors.Wrapf(err, "preimagehex is not actually hex 🤔")
}
calculatedPaymentHash := sha256.Sum256(preimage)
if !bytes.Equal(invoice.PaymentHash[:], calculatedPaymentHash[:]) {
return errors.Errorf("payment hash doesn't match preimage (%v != hash(%v)", invoice.PaymentHash, swap.PreimageInHex())
}
}
return nil
}