diff --git a/alby/alby_oauth_service.go b/alby/alby_oauth_service.go index 031a370a..f9ebdbda 100644 --- a/alby/alby_oauth_service.go +++ b/alby/alby_oauth_service.go @@ -17,6 +17,7 @@ import ( decodepay "github.com/nbd-wtf/ln-decodepay" "github.com/sirupsen/logrus" + "github.com/tyler-smith/go-bip32" "golang.org/x/oauth2" "gorm.io/gorm" @@ -723,46 +724,58 @@ func (svc *albyOAuthService) ConsumeEvent(ctx context.Context, event *events.Eve } } -func (svc *albyOAuthService) backupChannels(ctx context.Context, event *events.Event) error { - bkpEvent, ok := event.Properties.(*events.StaticChannelsBackupEvent) - if !ok { - return fmt.Errorf("invalid nwc_backup_channels event properties, could not cast to the expected type: %+v", event.Properties) +type channelsBackup struct { + Description string `json:"description"` + Data string `json:"data"` +} + +func (svc *albyOAuthService) createEncryptedChannelBackup(event *events.StaticChannelsBackupEvent) (*channelsBackup, error) { + + eventData := bytes.NewBuffer([]byte{}) + err := json.NewEncoder(eventData).Encode(event) + if err != nil { + return nil, fmt.Errorf("failed to encode channels backup data: %w", err) } - token, err := svc.fetchUserToken(ctx) + path := []uint32{bip32.FirstHardenedChild} + backupKey, err := svc.keys.DeriveKey(path) if err != nil { - return fmt.Errorf("failed to fetch user token: %w", err) + logger.Logger.WithError(err).Error("Failed to generate channels backup key") + return nil, err } - client := svc.oauthConf.Client(ctx, token) + encrypted, err := config.AesGcmEncryptWithKey(eventData.String(), backupKey.Key) + if err != nil { + return nil, fmt.Errorf("failed to encrypt channels backup data: %w", err) + } - type channelsBackup struct { - Description string `json:"description"` - Data string `json:"data"` + backup := &channelsBackup{ + Description: "channels_v2", + Data: encrypted, } + return backup, nil +} - eventData := bytes.NewBuffer([]byte{}) - err = json.NewEncoder(eventData).Encode(bkpEvent) - if err != nil { - return fmt.Errorf("failed to encode channels backup data: %w", err) +func (svc *albyOAuthService) backupChannels(ctx context.Context, event *events.Event) error { + bkpEvent, ok := event.Properties.(*events.StaticChannelsBackupEvent) + if !ok { + return fmt.Errorf("invalid nwc_backup_channels event properties, could not cast to the expected type: %+v", event.Properties) } - // use the encrypted mnemonic as the password to encrypt the backup data - encryptedMnemonic, err := svc.cfg.Get("Mnemonic", "") + backup, err := svc.createEncryptedChannelBackup(bkpEvent) if err != nil { - return fmt.Errorf("failed to fetch encryption key: %w", err) + return fmt.Errorf("failed to encrypt channel backup: %w", err) } - encrypted, err := config.AesGcmEncrypt(eventData.String(), encryptedMnemonic) + token, err := svc.fetchUserToken(ctx) if err != nil { - return fmt.Errorf("failed to encrypt channels backup data: %w", err) + return fmt.Errorf("failed to fetch user token: %w", err) } + client := svc.oauthConf.Client(ctx, token) + body := bytes.NewBuffer([]byte{}) - err = json.NewEncoder(body).Encode(&channelsBackup{ - Description: "channels", - Data: encrypted, - }) + err = json.NewEncoder(body).Encode(backup) if err != nil { return fmt.Errorf("failed to encode channels backup request payload: %w", err) } diff --git a/alby/alby_oauth_service_test.go b/alby/alby_oauth_service_test.go new file mode 100644 index 00000000..f24e820a --- /dev/null +++ b/alby/alby_oauth_service_test.go @@ -0,0 +1,75 @@ +package alby + +import ( + "testing" + + "github.com/getAlby/hub/config" + "github.com/getAlby/hub/events" + "github.com/getAlby/hub/tests" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tyler-smith/go-bip32" + "github.com/tyler-smith/go-bip39" +) + +func TestExistingEncryptedBackup(t *testing.T) { + defer tests.RemoveTestService() + svc, err := tests.CreateTestService() + require.NoError(t, err) + + mnemonic := "limit reward expect search tissue call visa fit thank cream brave jump" + unlockPassword := "123" + svc.Cfg.SetUpdate("Mnemonic", mnemonic, unlockPassword) + err = svc.Keys.Init(svc.Cfg, unlockPassword) + assert.NoError(t, err) + + encryptedBackup := "3fd21f9a393d8345ddbdd449-ba05c3dbafdfb7eea574373b7763d0c81c599b2cd1735e59a1c5571379498f4da8fe834c3403824ab02b61005abc1f563c638f425c65420e82941efe94794555c8b145a0603733ee115277f860011e6a17fd8c22f1d73a096ff7275582aac19b430940b40a2559c7ff59a063305290ef7c9ba46f9de17b0ddbac9030b0" + + masterKey, err := bip32.NewMasterKey(bip39.NewSeed(mnemonic, "")) + assert.NoError(t, err) + + appKey, err := masterKey.NewChildKey(bip32.FirstHardenedChild + 128029 /* 🐝 */) + assert.NoError(t, err) + encryptedChannelsBackupKey, err := appKey.NewChildKey(bip32.FirstHardenedChild) + assert.NoError(t, err) + + decrypted, err := config.AesGcmDecryptWithKey(encryptedBackup, encryptedChannelsBackupKey.Key) + assert.NoError(t, err) + + assert.Equal(t, "{\"node_id\":\"037e702144c4fa485d42f0f69864e943605823763866cf4bf619d2d2cf2eda420b\",\"channels\":[],\"monitors\":[]}\n", decrypted) +} + +func TestEncryptedBackup(t *testing.T) { + defer tests.RemoveTestService() + svc, err := tests.CreateTestService() + require.NoError(t, err) + + mnemonic := "limit reward expect search tissue call visa fit thank cream brave jump" + unlockPassword := "123" + svc.Cfg.SetUpdate("Mnemonic", mnemonic, unlockPassword) + err = svc.Keys.Init(svc.Cfg, unlockPassword) + assert.NoError(t, err) + + albyOAuthSvc := NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher) + encryptedBackup, err := albyOAuthSvc.createEncryptedChannelBackup(&events.StaticChannelsBackupEvent{ + NodeID: "037e702144c4fa485d42f0f69864e943605823763866cf4bf619d2d2cf2eda420b", + Channels: []events.ChannelBackup{}, + Monitors: []events.EncodedChannelMonitorBackup{}, + }) + + assert.NoError(t, err) + assert.Equal(t, "channels_v2", encryptedBackup.Description) + + masterKey, err := bip32.NewMasterKey(bip39.NewSeed(mnemonic, "")) + assert.NoError(t, err) + + appKey, err := masterKey.NewChildKey(bip32.FirstHardenedChild + 128029 /* 🐝 */) + assert.NoError(t, err) + encryptedChannelsBackupKey, err := appKey.NewChildKey(bip32.FirstHardenedChild) + assert.NoError(t, err) + + decrypted, err := config.AesGcmDecryptWithKey(encryptedBackup.Data, encryptedChannelsBackupKey.Key) + assert.NoError(t, err) + + assert.Equal(t, "{\"node_id\":\"037e702144c4fa485d42f0f69864e943605823763866cf4bf619d2d2cf2eda420b\",\"channels\":[],\"monitors\":[]}\n", decrypted) +} diff --git a/config/aesgcm.go b/config/aesgcm.go index 250db437..f088857b 100644 --- a/config/aesgcm.go +++ b/config/aesgcm.go @@ -5,6 +5,7 @@ import ( "crypto/cipher" "crypto/rand" "encoding/hex" + "fmt" "strings" "golang.org/x/crypto/argon2" @@ -23,14 +24,40 @@ func DeriveKey(password string, salt []byte) ([]byte, []byte, error) { return key, salt, nil } -func AesGcmEncrypt(plaintext string, password string) (string, error) { +func AesGcmEncryptWithPassword(plaintext string, password string) (string, error) { secretKey, salt, err := DeriveKey(password, nil) if err != nil { return "", err } + + ciphertext, err := AesGcmEncryptWithKey(plaintext, secretKey) + if err != nil { + return "", err + } + + return hex.EncodeToString(salt) + "-" + ciphertext, nil +} + +func AesGcmDecryptWithPassword(ciphertext string, password string) (string, error) { + arr := strings.Split(ciphertext, "-") + salt, _ := hex.DecodeString(arr[0]) + secretKey, _, err := DeriveKey(password, salt) + if err != nil { + return "", err + } + + return AesGcmDecryptWithKey(arr[1]+"-"+arr[2], secretKey) +} + +func AesGcmEncryptWithKey(plaintext string, key []byte) (string, error) { + // require a 32 bytes key (256 bits) + if len(key) != 32 { + return "", fmt.Errorf("key must be at least 32 bytes, got %d", len(key)) + } + plaintextBytes := []byte(plaintext) - aes, err := aes.NewCipher([]byte(secretKey)) + aes, err := aes.NewCipher(key) if err != nil { return "", err } @@ -48,20 +75,20 @@ func AesGcmEncrypt(plaintext string, password string) (string, error) { ciphertext := aesgcm.Seal(nil, nonce, plaintextBytes, nil) - return hex.EncodeToString(salt) + "-" + hex.EncodeToString(nonce) + "-" + hex.EncodeToString(ciphertext), nil + return hex.EncodeToString(nonce) + "-" + hex.EncodeToString(ciphertext), nil } -func AesGcmDecrypt(ciphertext string, password string) (string, error) { +func AesGcmDecryptWithKey(ciphertext string, key []byte) (string, error) { + // require a 32 bytes key (256 bits) + if len(key) != 32 { + return "", fmt.Errorf("key must be at least 32 bytes, got %d", len(key)) + } + arr := strings.Split(ciphertext, "-") - salt, _ := hex.DecodeString(arr[0]) - nonce, _ := hex.DecodeString(arr[1]) - data, _ := hex.DecodeString(arr[2]) + nonce, _ := hex.DecodeString(arr[0]) + data, _ := hex.DecodeString(arr[1]) - secretKey, _, err := DeriveKey(password, salt) - if err != nil { - return "", err - } - aes, err := aes.NewCipher([]byte(secretKey)) + aes, err := aes.NewCipher([]byte(key)) if err != nil { return "", err } diff --git a/config/aesgcm_test.go b/config/aesgcm_test.go new file mode 100644 index 00000000..1ab473bd --- /dev/null +++ b/config/aesgcm_test.go @@ -0,0 +1,49 @@ +package config + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tyler-smith/go-bip32" + "github.com/tyler-smith/go-bip39" +) + +func TestDecryptExistingCiphertextWithPassword(t *testing.T) { + value, err := AesGcmDecryptWithPassword("323f41394d3175b72454ccae9c0081f94df5fb4c2fb0b9283a87e5aafba81839-c335b9eeea75c28a6f823354-5055b90dadbdd01c52fbdbb7efb80609e4410357481651e89ceb1501c8e1dea1f33a8e3322a1cef4f641773667423bca5154dfeccac390cfcd719b36965adc3e6ae56fd5d6c82819596e9ef4ff07193ae345eb291fa412a1ce6066864b", "123") + assert.NoError(t, err) + assert.Equal(t, "connect maximum march lava ignore resist visa kind kiwi kidney develop animal", value) +} + +func TestEncryptDecryptWithPassword(t *testing.T) { + mnemonic := "connect maximum march lava ignore resist visa kind kiwi kidney develop animal" + encrypted, err := AesGcmEncryptWithPassword(mnemonic, "123") + assert.NoError(t, err) + value, err := AesGcmDecryptWithPassword(encrypted, "123") + assert.NoError(t, err) + assert.Equal(t, mnemonic, value) +} + +func TestDecryptExistingCiphertextWithKey(t *testing.T) { + mnemonic := "connect maximum march lava ignore resist visa kind kiwi kidney develop animal" + masterKey, err := bip32.NewMasterKey(bip39.NewSeed(mnemonic, "")) + assert.NoError(t, err) + value, err := AesGcmDecryptWithKey("22ad485dea4f49696594c7c4-afe35ce65fc5a45249bf1b9078472fb28395fc88c30a79c76c7d8d37cf", masterKey.Key) + assert.NoError(t, err) + assert.Equal(t, "Hello, world!", value) +} + +func TestEncryptDecryptWithKey(t *testing.T) { + plaintext := "Hello, world!" + mnemonic := "connect maximum march lava ignore resist visa kind kiwi kidney develop animal" + masterKey, err := bip32.NewMasterKey(bip39.NewSeed(mnemonic, "")) + assert.NoError(t, err) + + assert.Equal(t, "409e902eafba273b21dff921f0eb4bec6cbb0b657fdce8d245ca78d2920f8b73", hex.EncodeToString(masterKey.Key)) + + encrypted, err := AesGcmEncryptWithKey(plaintext, masterKey.Key) + assert.NoError(t, err) + value, err := AesGcmDecryptWithKey(encrypted, masterKey.Key) + assert.NoError(t, err) + assert.Equal(t, plaintext, value) +} diff --git a/config/config.go b/config/config.go index 84eeeec5..ce663193 100644 --- a/config/config.go +++ b/config/config.go @@ -154,7 +154,7 @@ func (cfg *config) get(key string, encryptionKey string, gormDB *gorm.DB) (strin value := userConfig.Value if userConfig.Value != "" && encryptionKey != "" && userConfig.Encrypted { - decrypted, err := AesGcmDecrypt(value, encryptionKey) + decrypted, err := AesGcmDecryptWithPassword(value, encryptionKey) if err != nil { return "", err } @@ -165,7 +165,7 @@ func (cfg *config) get(key string, encryptionKey string, gormDB *gorm.DB) (strin func (cfg *config) set(key string, value string, clauses clause.OnConflict, encryptionKey string, gormDB *gorm.DB) error { if encryptionKey != "" { - encrypted, err := AesGcmEncrypt(value, encryptionKey) + encrypted, err := AesGcmEncryptWithPassword(value, encryptionKey) if err != nil { return fmt.Errorf("failed to encrypt: %v", err) } diff --git a/frontend/src/screens/BackupMnemonic.tsx b/frontend/src/screens/BackupMnemonic.tsx index 81a04b29..9c512abf 100644 --- a/frontend/src/screens/BackupMnemonic.tsx +++ b/frontend/src/screens/BackupMnemonic.tsx @@ -135,19 +135,15 @@ export function BackupMnemonic() { backs up your wallet savings balance.  {info?.albyAccountConnected && ( <> - You also need to make sure you do not forget your{" "} - unlock password as this will be used to recover funds - from channels. Encrypted channel backups are saved - automatically to your Alby Account. + Channel backups are saved automatically to your Alby + Account, encrypted with your recovery phrase. )} {!info?.albyAccountConnected && ( <> Make sure to also backup your data directory as this is required to recover funds on your channels. You can also - connect your Alby Account for automatic encrypted backups - (you still need your seed and unlock password to decrypt - those). + connect your Alby Account for automatic encrypted backups. )} @@ -166,14 +162,9 @@ export function BackupMnemonic() { If you lose access to your hub and do not have your{" "} - recovery phrase  - {info?.albyAccountConnected && ( - <> - or your unlock password - - )} + recovery phrase {!info?.albyAccountConnected && ( - <>or do not backup your data directory + <> or do not backup your data directory )} , you will lose access to your funds. @@ -201,7 +192,7 @@ export function BackupMnemonic() { secure place - {backedUp && ( + {backedUp && !info?.albyAccountConnected && (
)} diff --git a/go.mod b/go.mod index 51d93e48..932166ab 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,8 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/DataDog/datadog-go/v5 v5.3.0 // indirect github.com/DataDog/gostackparse v0.7.0 // indirect + github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect @@ -237,6 +239,7 @@ require ( github.com/labstack/echo-jwt/v4 v4.2.0 github.com/lightningnetwork/lnd v0.18.2-beta github.com/sirupsen/logrus v1.9.3 + github.com/tyler-smith/go-bip32 v1.0.0 golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect gorm.io/datatypes v1.2.4 ) diff --git a/go.sum b/go.sum index 1f507f75..a87bcae3 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,10 @@ github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/ github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/DataDog/sketches-go v1.4.5 h1:ki7VfeNz7IcNafq7yI/j5U/YCkO3LJiMDtXz9OMQbyE= github.com/DataDog/sketches-go v1.4.5/go.mod h1:7Y8GN8Jf66DLyDhc94zuWA3uHEt/7ttt8jHOBWWrSOg= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= @@ -106,6 +110,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= @@ -601,6 +606,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -634,6 +640,8 @@ github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQ github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -720,6 +728,7 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -947,6 +956,7 @@ gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk= modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA= diff --git a/nip47/controllers/get_balance_controller_test.go b/nip47/controllers/get_balance_controller_test.go index 001c797f..1db1f09c 100644 --- a/nip47/controllers/get_balance_controller_test.go +++ b/nip47/controllers/get_balance_controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -26,7 +27,7 @@ func TestHandleGetBalanceEvent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBalanceJson), nip47Request) @@ -58,7 +59,7 @@ func TestHandleGetBalanceEvent_IsolatedApp_NoTransactions(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBalanceJson), nip47Request) @@ -91,7 +92,7 @@ func TestHandleGetBalanceEvent_IsolatedApp_Transactions(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBalanceJson), nip47Request) diff --git a/nip47/controllers/get_budget_controller_test.go b/nip47/controllers/get_budget_controller_test.go index e007c3b2..64df460d 100644 --- a/nip47/controllers/get_budget_controller_test.go +++ b/nip47/controllers/get_budget_controller_test.go @@ -8,6 +8,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -27,7 +28,7 @@ func TestHandleGetBudgetEvent_NoRenewal(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBudgetJson), nip47Request) @@ -72,7 +73,7 @@ func TestHandleGetBudgetEvent_NoneUsed(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBudgetJson), nip47Request) @@ -119,7 +120,7 @@ func TestHandleGetBudgetEvent_HalfUsed(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBudgetJson), nip47Request) @@ -173,7 +174,7 @@ func TestHandleGetBudgetEvent_NoBudget(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBudgetJson), nip47Request) @@ -220,7 +221,7 @@ func TestHandleGetBudgetEvent_NoPayInvoicePermission(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47GetBudgetJson), nip47Request) diff --git a/nip47/controllers/get_info_controller_test.go b/nip47/controllers/get_info_controller_test.go index d8498c99..0ec97f4a 100644 --- a/nip47/controllers/get_info_controller_test.go +++ b/nip47/controllers/get_info_controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -26,7 +27,7 @@ func TestHandleGetInfoEvent_NoPermission(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -75,7 +76,7 @@ func TestHandleGetInfoEvent_WithPermission(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -123,7 +124,7 @@ func TestHandleGetInfoEvent_WithNotifications(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/nip47/controllers/list_transactions_controller_test.go b/nip47/controllers/list_transactions_controller_test.go index 8a29d718..2463b7b1 100644 --- a/nip47/controllers/list_transactions_controller_test.go +++ b/nip47/controllers/list_transactions_controller_test.go @@ -8,6 +8,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -34,7 +35,7 @@ func TestHandleListTransactionsEvent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47ListTransactionsJson), nip47Request) diff --git a/nip47/controllers/lookup_invoice_controller_test.go b/nip47/controllers/lookup_invoice_controller_test.go index 6062aa49..8cc61d64 100644 --- a/nip47/controllers/lookup_invoice_controller_test.go +++ b/nip47/controllers/lookup_invoice_controller_test.go @@ -8,6 +8,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/db" "github.com/getAlby/hub/nip47/models" @@ -29,7 +30,7 @@ func TestHandleLookupInvoiceEvent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47LookupInvoiceJson), nip47Request) diff --git a/nip47/controllers/make_invoice_controller_test.go b/nip47/controllers/make_invoice_controller_test.go index e95cfcfe..980cba3b 100644 --- a/nip47/controllers/make_invoice_controller_test.go +++ b/nip47/controllers/make_invoice_controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/db" "github.com/getAlby/hub/nip47/models" @@ -42,7 +43,7 @@ func TestHandleMakeInvoiceEvent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47Request := &models.Request{} err = json.Unmarshal([]byte(nip47MakeInvoiceJson), nip47Request) diff --git a/nip47/controllers/multi_pay_invoice_controller_test.go b/nip47/controllers/multi_pay_invoice_controller_test.go index 1c2322b0..f3ab7275 100644 --- a/nip47/controllers/multi_pay_invoice_controller_test.go +++ b/nip47/controllers/multi_pay_invoice_controller_test.go @@ -10,6 +10,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -57,7 +58,7 @@ func TestHandleMultiPayInvoiceEvent_Success(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) var preimages = []string{"123preimage", "123preimage2"} @@ -135,7 +136,7 @@ func TestHandleMultiPayInvoiceEvent_OneMalformedInvoice(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -197,7 +198,7 @@ func TestHandleMultiPayInvoiceEvent_IsolatedApp_OneBudgetExceeded(t *testing.T) defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -279,7 +280,7 @@ func TestHandleMultiPayInvoiceEvent_LNClient_OnePaymentFailed(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) svc.LNClient.(*tests.MockLn).PayInvoiceResponses = []*lnclient.PayInvoiceResponse{{ Preimage: "123preimage", }, nil} diff --git a/nip47/controllers/multi_pay_keysend_controller_test.go b/nip47/controllers/multi_pay_keysend_controller_test.go index 0ddfcb4e..9fdbbb1c 100644 --- a/nip47/controllers/multi_pay_keysend_controller_test.go +++ b/nip47/controllers/multi_pay_keysend_controller_test.go @@ -8,6 +8,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -72,7 +73,7 @@ func TestHandleMultiPayKeysendEvent_Success(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -123,7 +124,7 @@ func TestHandleMultiPayKeysendEvent_OneBudgetExceeded(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/nip47/controllers/pay_invoice_controller_test.go b/nip47/controllers/pay_invoice_controller_test.go index 87f17ba1..e578fcce 100644 --- a/nip47/controllers/pay_invoice_controller_test.go +++ b/nip47/controllers/pay_invoice_controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -38,7 +39,7 @@ func TestHandlePayInvoiceEvent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -77,7 +78,7 @@ func TestHandlePayInvoiceEvent_MalformedInvoice(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/nip47/controllers/pay_keysend_controller_test.go b/nip47/controllers/pay_keysend_controller_test.go index f87032bb..a5e2c476 100644 --- a/nip47/controllers/pay_keysend_controller_test.go +++ b/nip47/controllers/pay_keysend_controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/getAlby/hub/constants" "github.com/getAlby/hub/db" @@ -49,7 +50,7 @@ func TestHandlePayKeysendEvent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -90,7 +91,7 @@ func TestHandlePayKeysendEvent_WithPreimage(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/nip47/event_handler_test.go b/nip47/event_handler_test.go index ed3cef55..0fe4d8b8 100644 --- a/nip47/event_handler_test.go +++ b/nip47/event_handler_test.go @@ -14,6 +14,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip04" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // TODO: test HandleEvent @@ -23,7 +24,7 @@ import ( func TestCreateResponse(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) reqPrivateKey := nostr.GeneratePrivateKey() reqPubkey, err := nostr.GetPublicKey(reqPrivateKey) @@ -75,7 +76,7 @@ func TestCreateResponse(t *testing.T) { func TestHandleResponse_WithPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher) reqPrivateKey := nostr.GeneratePrivateKey() @@ -148,7 +149,7 @@ func TestHandleResponse_WithPermission(t *testing.T) { func TestHandleResponse_DuplicateRequest(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher) reqPrivateKey := nostr.GeneratePrivateKey() @@ -204,7 +205,7 @@ func TestHandleResponse_DuplicateRequest(t *testing.T) { func TestHandleResponse_NoPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher) reqPrivateKey := nostr.GeneratePrivateKey() @@ -260,7 +261,7 @@ func TestHandleResponse_NoPermission(t *testing.T) { func TestHandleResponse_NoApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher) reqPrivateKey := nostr.GeneratePrivateKey() @@ -320,7 +321,7 @@ func TestHandleResponse_NoApp(t *testing.T) { func TestHandleResponse_IncorrectPubkey(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher) reqPrivateKey := nostr.GeneratePrivateKey() diff --git a/nip47/notifications/nip47_notifier_test.go b/nip47/notifications/nip47_notifier_test.go index 70c6bec9..90e48496 100644 --- a/nip47/notifications/nip47_notifier_test.go +++ b/nip47/notifications/nip47_notifier_test.go @@ -15,6 +15,7 @@ import ( "github.com/getAlby/hub/transactions" "github.com/nbd-wtf/go-nostr/nip04" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) type mockConsumer struct { @@ -35,7 +36,7 @@ func TestSendNotification_PaymentReceived(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, ss, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -115,7 +116,7 @@ func TestSendNotification_PaymentSent(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, ss, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -194,7 +195,7 @@ func TestSendNotificationNoPermission(t *testing.T) { ctx := context.TODO() defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) _, _, err = tests.CreateApp(svc) assert.NoError(t, err) diff --git a/nip47/permissions/permissions_test.go b/nip47/permissions/permissions_test.go index 56e72131..8424c53e 100644 --- a/nip47/permissions/permissions_test.go +++ b/nip47/permissions/permissions_test.go @@ -9,12 +9,13 @@ import ( "github.com/getAlby/hub/nip47/models" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestHasPermission_NoPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -29,7 +30,7 @@ func TestHasPermission_NoPermission(t *testing.T) { func TestHasPermission_Expired(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -58,7 +59,7 @@ func TestHasPermission_Expired(t *testing.T) { /*func TestHasPermission_Exceeded(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -86,7 +87,7 @@ func TestHasPermission_Expired(t *testing.T) { func TestHasPermission_OK(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -117,7 +118,7 @@ func TestRequestMethodToScope_GetBudget(t *testing.T) { assert.NoError(t, err) scope, err := RequestMethodToScope(models.GET_BUDGET_METHOD) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, "", scope) } @@ -146,7 +147,7 @@ func TestRequestMethodsToScopes_GetInfo(t *testing.T) { func TestGetPermittedMethods_AlwaysGranted(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -159,7 +160,7 @@ func TestGetPermittedMethods_AlwaysGranted(t *testing.T) { func TestGetPermittedMethods_PayInvoiceScopeGivesAllPaymentMethods(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/service/keys/keys.go b/service/keys/keys.go index 803f3846..e43f8e9c 100644 --- a/service/keys/keys.go +++ b/service/keys/keys.go @@ -1,22 +1,29 @@ package keys import ( + "errors" + "github.com/getAlby/hub/config" "github.com/getAlby/hub/logger" "github.com/nbd-wtf/go-nostr" + "github.com/tyler-smith/go-bip32" + "github.com/tyler-smith/go-bip39" ) type Keys interface { Init(cfg config.Config, encryptionKey string) error - // Wallet Service Nostr pubkey + // Wallet Service Nostr pubkey (DEPRECATED) GetNostrPublicKey() string - // Wallet Service Nostr secret key + // Wallet Service Nostr secret key (DEPRECATED) GetNostrSecretKey() string + // Derives a child BIP-32 key from the app key (derived from the mnemonic) + DeriveKey(path []uint32) (*bip32.Key, error) } type keys struct { nostrSecretKey string nostrPublicKey string + appKey *bip32.Key } func NewKeys() *keys { @@ -41,6 +48,29 @@ func (keys *keys) Init(cfg config.Config, encryptionKey string) error { } keys.nostrSecretKey = nostrSecretKey keys.nostrPublicKey = nostrPublicKey + + mnemonic, err := cfg.Get("Mnemonic", encryptionKey) + if err != nil { + logger.Logger.WithError(err).Error("Failed to decrypt mnemonic") + return err + } + + if mnemonic != "" { + masterKey, err := bip32.NewMasterKey(bip39.NewSeed(mnemonic, "")) + if err != nil { + logger.Logger.WithError(err).Error("Failed to create seed from mnemonic") + return err + } + + albyHubIndex := uint32(bip32.FirstHardenedChild + 128029 /* 🐝 */) + appKey, err := masterKey.NewChildKey(albyHubIndex) + if err != nil { + logger.Logger.WithError(err).Error("Failed to create seed from mnemonic") + return err + } + keys.appKey = appKey + } + return nil } @@ -51,3 +81,19 @@ func (keys *keys) GetNostrPublicKey() string { func (keys *keys) GetNostrSecretKey() string { return keys.nostrSecretKey } + +func (keys *keys) DeriveKey(path []uint32) (*bip32.Key, error) { + if keys.appKey == nil { + return nil, errors.New("app key not set") + } + key := keys.appKey + for _, index := range path { + var err error + key, err = key.NewChildKey(index) + if err != nil { + return nil, err + } + } + + return key, nil +} diff --git a/service/start.go b/service/start.go index b3bd21a6..a8353cb8 100644 --- a/service/start.go +++ b/service/start.go @@ -24,16 +24,10 @@ import ( "github.com/getAlby/hub/logger" ) -func (svc *service) startNostr(ctx context.Context, encryptionKey string) error { +func (svc *service) startNostr(ctx context.Context) error { relayUrl := svc.cfg.GetRelayUrl() - err := svc.keys.Init(svc.cfg, encryptionKey) - if err != nil { - logger.Logger.WithError(err).Error("Failed to init nostr keys") - return err - } - npub, err := nip19.EncodePublicKey(svc.keys.GetNostrPublicKey()) if err != nil { logger.Logger.WithError(err).Error("Error converting nostr privkey to pubkey") @@ -130,7 +124,14 @@ func (svc *service) StartApp(encryptionKey string) error { ctx, cancelFn := context.WithCancel(svc.ctx) - err := svc.launchLNBackend(ctx, encryptionKey) + err := svc.keys.Init(svc.cfg, encryptionKey) + if err != nil { + logger.Logger.WithError(err).Error("Failed to init nostr keys") + cancelFn() + return err + } + + err = svc.launchLNBackend(ctx, encryptionKey) if err != nil { logger.Logger.Errorf("Failed to launch LN backend: %v", err) svc.eventPublisher.Publish(&events.Event{ @@ -140,7 +141,7 @@ func (svc *service) StartApp(encryptionKey string) error { return err } - err = svc.startNostr(ctx, encryptionKey) + err = svc.startNostr(ctx) if err != nil { cancelFn() return err diff --git a/transactions/app_payments_test.go b/transactions/app_payments_test.go index e4314d29..7b30e389 100644 --- a/transactions/app_payments_test.go +++ b/transactions/app_payments_test.go @@ -9,6 +9,7 @@ import ( "github.com/getAlby/hub/db" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSendPaymentSync_App_NoPermission(t *testing.T) { @@ -16,7 +17,7 @@ func TestSendPaymentSync_App_NoPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -37,7 +38,7 @@ func TestSendPaymentSync_App_WithPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -70,7 +71,7 @@ func TestSendPaymentSync_App_BudgetExceeded(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -110,7 +111,7 @@ func TestSendPaymentSync_App_BudgetExceeded_SettledPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -149,7 +150,7 @@ func TestSendPaymentSync_App_BudgetExceeded_UnsettledPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -189,7 +190,7 @@ func TestSendPaymentSync_App_BudgetNotExceeded_FailedPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/transactions/check_unsettled_transaction_test.go b/transactions/check_unsettled_transaction_test.go index edc53713..593f7d4b 100644 --- a/transactions/check_unsettled_transaction_test.go +++ b/transactions/check_unsettled_transaction_test.go @@ -10,12 +10,13 @@ import ( "github.com/getAlby/hub/lnclient" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestCheckUnsettledTransaction(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) dbTransaction := db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, @@ -41,7 +42,7 @@ func TestCheckUnsettledTransaction(t *testing.T) { svc.LNClient.(*tests.MockLn).SupportedNotificationTypes = &[]string{} transactionsService.checkUnsettledTransaction(context.TODO(), &dbTransaction, svc.LNClient) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State) assert.Equal(t, 1, len(mockEventConsumer.GetConsumeEvents())) assert.Equal(t, "nwc_payment_sent", mockEventConsumer.GetConsumeEvents()[0].Event) @@ -52,7 +53,7 @@ func TestCheckUnsettledTransaction(t *testing.T) { func TestCheckUnsettledTransactions(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) dbTransaction := db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, @@ -87,7 +88,7 @@ func TestCheckUnsettledTransactions(t *testing.T) { svc.DB.Find(&dbTransaction, db.Transaction{ ID: dbTransaction.ID, }) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State) assert.Equal(t, 1, len(mockEventConsumer.GetConsumeEvents())) assert.Equal(t, "nwc_payment_sent", mockEventConsumer.GetConsumeEvents()[0].Event) diff --git a/transactions/isolated_app_payments_test.go b/transactions/isolated_app_payments_test.go index 915e3330..5817f683 100644 --- a/transactions/isolated_app_payments_test.go +++ b/transactions/isolated_app_payments_test.go @@ -8,6 +8,7 @@ import ( "github.com/getAlby/hub/db" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSendPaymentSync_IsolatedApp_NoBalance(t *testing.T) { @@ -15,7 +16,7 @@ func TestSendPaymentSync_IsolatedApp_NoBalance(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -47,7 +48,7 @@ func TestSendPaymentSync_IsolatedApp_BalanceInsufficient(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -95,7 +96,7 @@ func TestSendPaymentSync_IsolatedApp_BalanceSufficient(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -137,7 +138,7 @@ func TestSendPaymentSync_IsolatedApp_BalanceInsufficient_OutstandingPayment(t *t defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -183,7 +184,7 @@ func TestSendPaymentSync_IsolatedApp_BalanceInsufficient_SettledPayment(t *testi defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -229,7 +230,7 @@ func TestSendPaymentSync_IsolatedApp_BalanceSufficient_UnrelatedPayment(t *testi defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -277,7 +278,7 @@ func TestSendPaymentSync_IsolatedApp_BalanceSufficient_FailedPayment(t *testing. defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/transactions/keysend_test.go b/transactions/keysend_test.go index 017cc60d..720952c5 100644 --- a/transactions/keysend_test.go +++ b/transactions/keysend_test.go @@ -13,6 +13,7 @@ import ( "github.com/getAlby/hub/lnclient" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSendKeysend(t *testing.T) { @@ -20,7 +21,7 @@ func TestSendKeysend(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockEventConsumer := tests.NewMockEventConsumer() svc.EventPublisher.RegisterSubscriber(mockEventConsumer) @@ -52,7 +53,7 @@ func TestSendKeysend_CustomPreimage(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) customPreimage := "018465013e2337234a7e5530a21c4a8cf70d84231f4a8ff0b1e2cce3cb2bd03b" transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) @@ -78,7 +79,7 @@ func TestSendKeysend_App_NoPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -100,7 +101,7 @@ func TestSendKeysend_App_WithPermission(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -142,7 +143,7 @@ func TestSendKeysend_App_BudgetExceeded(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -180,7 +181,7 @@ func TestSendKeysend_App_BudgetNotExceeded(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -223,7 +224,7 @@ func TestSendKeysend_App_BalanceExceeded(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -261,7 +262,7 @@ func TestSendKeysend_App_BalanceSufficient(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) @@ -312,7 +313,7 @@ func TestSendKeysend_TLVs(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) transaction, err := transactionsService.SendKeysend(ctx, uint64(1000), "fake destination", []lnclient.TLVRecord{ @@ -360,7 +361,7 @@ func TestSendKeysend_IsolatedAppToNoApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // setup for self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -425,7 +426,7 @@ func TestSendKeysend_IsolatedAppToIsolatedApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // setup for self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" diff --git a/transactions/list_transactions_test.go b/transactions/list_transactions_test.go index 5d75849b..34a7c1a2 100644 --- a/transactions/list_transactions_test.go +++ b/transactions/list_transactions_test.go @@ -9,6 +9,7 @@ import ( "github.com/getAlby/hub/db" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestListTransactions_Paid(t *testing.T) { @@ -16,7 +17,7 @@ func TestListTransactions_Paid(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -60,7 +61,7 @@ func TestListTransactions_UnpaidIncoming(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -127,7 +128,7 @@ func TestListTransactions_UnpaidOutgoing(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -194,7 +195,7 @@ func TestListTransactions_Unpaid(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -255,7 +256,7 @@ func TestListTransactions_Limit(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -291,7 +292,7 @@ func TestListTransactions_Offset(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -347,7 +348,7 @@ func TestListTransactions_FromUntil(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -397,7 +398,7 @@ func TestListTransactions_FromUntilUnpaidOutgoing(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -459,7 +460,7 @@ func TestListTransactions_FromUntilUnpaidIncoming(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ diff --git a/transactions/lookup_transaction_test.go b/transactions/lookup_transaction_test.go index c490baa3..af64507c 100644 --- a/transactions/lookup_transaction_test.go +++ b/transactions/lookup_transaction_test.go @@ -8,6 +8,7 @@ import ( "github.com/getAlby/hub/db" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestLookupTransaction_IncomingPayment(t *testing.T) { @@ -15,7 +16,7 @@ func TestLookupTransaction_IncomingPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -42,7 +43,7 @@ func TestLookupTransaction_OutgoingPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ diff --git a/transactions/make_invoice_test.go b/transactions/make_invoice_test.go index c421bd92..58781c49 100644 --- a/transactions/make_invoice_test.go +++ b/transactions/make_invoice_test.go @@ -11,6 +11,7 @@ import ( "github.com/getAlby/hub/db" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestMakeInvoice_NoApp(t *testing.T) { @@ -18,7 +19,7 @@ func TestMakeInvoice_NoApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) txMetadata := make(map[string]interface{}) txMetadata["randomkey"] = strings.Repeat("a", constants.INVOICE_METADATA_MAX_LENGTH-16) // json encoding adds 16 characters - {"randomkey":""} @@ -42,7 +43,7 @@ func TestMakeInvoice_MetadataTooLarge(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) metadata := make(map[string]interface{}) metadata["randomkey"] = strings.Repeat("a", constants.INVOICE_METADATA_MAX_LENGTH-15) // json encoding adds 16 characters @@ -60,7 +61,7 @@ func TestMakeInvoice_App(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) app, _, err := tests.CreateApp(svc) assert.NoError(t, err) diff --git a/transactions/notifications_test.go b/transactions/notifications_test.go index 4c97b434..fe5c7407 100644 --- a/transactions/notifications_test.go +++ b/transactions/notifications_test.go @@ -11,6 +11,7 @@ import ( "github.com/getAlby/hub/lnclient" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNotifications_ReceivedKnownPayment(t *testing.T) { @@ -18,7 +19,7 @@ func TestNotifications_ReceivedKnownPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) mockPreimage := tests.MockLNClientTransaction.Preimage svc.DB.Create(&db.Transaction{ @@ -54,7 +55,7 @@ func TestNotifications_ReceivedUnknownPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) @@ -81,7 +82,7 @@ func TestNotifications_ReceivedKeysend(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) @@ -147,7 +148,7 @@ func TestNotifications_SentKnownPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) svc.DB.Create(&db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, @@ -183,7 +184,7 @@ func TestNotifications_SentUnknownPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) @@ -207,7 +208,7 @@ func TestNotifications_FailedKnownPayment(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) svc.DB.Create(&db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, diff --git a/transactions/payments_test.go b/transactions/payments_test.go index 5c56d36c..a0914023 100644 --- a/transactions/payments_test.go +++ b/transactions/payments_test.go @@ -11,6 +11,7 @@ import ( "github.com/getAlby/hub/lnclient" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "gorm.io/gorm" ) @@ -19,7 +20,7 @@ func TestSendPaymentSync_NoApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) transaction, err := transactionsService.SendPaymentSync(ctx, tests.MockLNClientTransaction.Invoice, svc.LNClient, nil, nil) @@ -36,7 +37,7 @@ func TestSendPaymentSync_Duplicate(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) svc.DB.Create(&db.Transaction{ State: constants.TRANSACTION_STATE_SETTLED, @@ -56,7 +57,7 @@ func TestSendPaymentSync_Duplicate(t *testing.T) { func TestMarkSettled_Sent(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) dbTransaction := db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, @@ -74,7 +75,7 @@ func TestMarkSettled_Sent(t *testing.T) { return err }) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State) assert.Equal(t, 1, len(mockEventConsumer.GetConsumeEvents())) assert.Equal(t, "nwc_payment_sent", mockEventConsumer.GetConsumeEvents()[0].Event) @@ -85,7 +86,7 @@ func TestMarkSettled_Sent(t *testing.T) { func TestMarkSettled_Received(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) dbTransaction := db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, @@ -103,7 +104,7 @@ func TestMarkSettled_Received(t *testing.T) { return err }) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State) assert.Equal(t, 1, len(mockEventConsumer.GetConsumeEvents())) assert.Equal(t, "nwc_payment_received", mockEventConsumer.GetConsumeEvents()[0].Event) @@ -114,7 +115,7 @@ func TestMarkSettled_Received(t *testing.T) { func TestDoNotMarkSettledTwice(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) settledAt := time.Now().Add(time.Duration(-1) * time.Minute) dbTransaction := db.Transaction{ @@ -134,14 +135,14 @@ func TestDoNotMarkSettledTwice(t *testing.T) { return err }) - assert.Nil(t, err) + assert.NoError(t, err) assert.Zero(t, len(mockEventConsumer.GetConsumeEvents())) } func TestMarkFailed(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) dbTransaction := db.Transaction{ State: constants.TRANSACTION_STATE_PENDING, @@ -158,7 +159,7 @@ func TestMarkFailed(t *testing.T) { return transactionsService.markPaymentFailed(tx, &dbTransaction, "some routing error") }) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, constants.TRANSACTION_STATE_FAILED, dbTransaction.State) assert.Equal(t, 1, len(mockEventConsumer.GetConsumeEvents())) assert.Equal(t, "nwc_payment_failed", mockEventConsumer.GetConsumeEvents()[0].Event) @@ -170,7 +171,7 @@ func TestMarkFailed(t *testing.T) { func TestDoNotMarkFailedTwice(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) updatedAt := time.Now().Add(time.Duration(-1) * time.Minute) dbTransaction := db.Transaction{ @@ -189,7 +190,7 @@ func TestDoNotMarkFailedTwice(t *testing.T) { return transactionsService.markPaymentFailed(tx, &dbTransaction, "some routing error") }) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, updatedAt, dbTransaction.UpdatedAt) assert.Zero(t, len(mockEventConsumer.GetConsumeEvents())) } @@ -199,7 +200,7 @@ func TestSendPaymentSync_FailedRemovesFeeReserve(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) svc.LNClient.(*tests.MockLn).PayInvoiceErrors = append(svc.LNClient.(*tests.MockLn).PayInvoiceErrors, errors.New("Some error")) svc.LNClient.(*tests.MockLn).PayInvoiceResponses = append(svc.LNClient.(*tests.MockLn).PayInvoiceResponses, nil) @@ -215,7 +216,7 @@ func TestSendPaymentSync_FailedRemovesFeeReserve(t *testing.T) { transactionType := constants.TRANSACTION_TYPE_OUTGOING transaction, err = transactionsService.LookupTransaction(ctx, tests.MockLNClientTransaction.PaymentHash, &transactionType, svc.LNClient, nil) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, uint64(123000), transaction.AmountMsat) assert.Equal(t, constants.TRANSACTION_STATE_FAILED, transaction.State) @@ -231,7 +232,7 @@ func TestSendPaymentSync_PendingHasFeeReserve(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // timeout will leave the payment as pending svc.LNClient.(*tests.MockLn).PayInvoiceErrors = append(svc.LNClient.(*tests.MockLn).PayInvoiceErrors, lnclient.NewTimeoutError()) @@ -245,7 +246,7 @@ func TestSendPaymentSync_PendingHasFeeReserve(t *testing.T) { transactionType := constants.TRANSACTION_TYPE_OUTGOING transaction, err = transactionsService.LookupTransaction(ctx, tests.MockLNClientTransaction.PaymentHash, &transactionType, svc.LNClient, nil) - assert.Nil(t, err) + assert.NoError(t, err) assert.Equal(t, uint64(123000), transaction.AmountMsat) assert.Equal(t, constants.TRANSACTION_STATE_PENDING, transaction.State) diff --git a/transactions/receive_keysend_test.go b/transactions/receive_keysend_test.go index 1b8a630d..3c07cb9e 100644 --- a/transactions/receive_keysend_test.go +++ b/transactions/receive_keysend_test.go @@ -10,6 +10,7 @@ import ( "github.com/getAlby/hub/lnclient" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestReceiveKeysendWithCustomKey(t *testing.T) { @@ -17,7 +18,7 @@ func TestReceiveKeysendWithCustomKey(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) app, _, err := tests.CreateApp(svc) @@ -64,7 +65,7 @@ func TestReceiveKeysend(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) _, _, err = tests.CreateApp(svc) diff --git a/transactions/self_payments_test.go b/transactions/self_payments_test.go index b4938871..c368fad0 100644 --- a/transactions/self_payments_test.go +++ b/transactions/self_payments_test.go @@ -9,6 +9,7 @@ import ( "github.com/getAlby/hub/db/queries" "github.com/getAlby/hub/tests" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestSendPaymentSync_SelfPayment_NoAppToNoApp(t *testing.T) { @@ -16,7 +17,7 @@ func TestSendPaymentSync_SelfPayment_NoAppToNoApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -58,7 +59,7 @@ func TestSendPaymentSync_SelfPayment_NoAppToIsolatedApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -113,7 +114,7 @@ func TestSendPaymentSync_SelfPayment_NoAppToApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -164,7 +165,7 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToNoApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -236,7 +237,7 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -312,7 +313,7 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToIsolatedApp(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578" @@ -405,7 +406,7 @@ func TestSendPaymentSync_SelfPayment_IsolatedAppToSelf(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() - assert.NoError(t, err) + require.NoError(t, err) // pubkey matches mock invoice = self payment svc.LNClient.(*tests.MockLn).Pubkey = "02a5056398235568fc049a5d563f1adf666041d590b268167e4fa145fbf71aa578"