self_payments_test.go raw

   1  package transactions
   2  
   3  import (
   4  	"context"
   5  	"testing"
   6  
   7  	"github.com/stretchr/testify/assert"
   8  	"github.com/stretchr/testify/require"
   9  
  10  	"github.com/getAlby/hub/constants"
  11  	"github.com/getAlby/hub/db"
  12  	"github.com/getAlby/hub/db/queries"
  13  	"github.com/getAlby/hub/tests"
  14  )
  15  
  16  func TestSendPaymentSync_SelfPayment_NoAppToNoApp(t *testing.T) {
  17  	ctx := context.TODO()
  18  
  19  	svc, err := tests.CreateTestService(t)
  20  	require.NoError(t, err)
  21  	defer svc.Remove()
  22  
  23  	// pubkey matches mock invoice = self payment
  24  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
  25  
  26  	mockPreimage := "123preimage"
  27  	svc.DB.Create(&db.Transaction{
  28  		State:          constants.TRANSACTION_STATE_PENDING,
  29  		Type:           constants.TRANSACTION_TYPE_INCOMING,
  30  		PaymentRequest: tests.MockInvoice,
  31  		PaymentHash:    tests.MockPaymentHash,
  32  		Preimage:       &mockPreimage,
  33  		AmountMsat:     123000,
  34  	})
  35  
  36  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
  37  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, nil, nil)
  38  
  39  	assert.NoError(t, err)
  40  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
  41  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
  42  	assert.Equal(t, mockPreimage, *transaction.Preimage)
  43  	assert.True(t, transaction.SelfPayment)
  44  
  45  	transactionType := constants.TRANSACTION_TYPE_INCOMING
  46  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
  47  	assert.NoError(t, err)
  48  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
  49  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
  50  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
  51  	assert.True(t, incomingTransaction.SelfPayment)
  52  
  53  	transactions := []db.Transaction{}
  54  	result := svc.DB.Find(&transactions)
  55  	assert.Equal(t, int64(2), result.RowsAffected)
  56  }
  57  
  58  func TestSendPaymentSync_SelfPayment_NoAppToIsolatedApp(t *testing.T) {
  59  	ctx := context.TODO()
  60  
  61  	svc, err := tests.CreateTestService(t)
  62  	require.NoError(t, err)
  63  	defer svc.Remove()
  64  
  65  	// pubkey matches mock invoice = self payment
  66  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
  67  
  68  	app, _, err := tests.CreateApp(svc)
  69  	assert.NoError(t, err)
  70  	app.Isolated = true
  71  	svc.DB.Save(&app)
  72  
  73  	dbRequestEvent := &db.RequestEvent{}
  74  	err = svc.DB.Create(&dbRequestEvent).Error
  75  	assert.NoError(t, err)
  76  
  77  	mockPreimage := "123preimage"
  78  	svc.DB.Create(&db.Transaction{
  79  		State:          constants.TRANSACTION_STATE_PENDING,
  80  		Type:           constants.TRANSACTION_TYPE_INCOMING,
  81  		PaymentRequest: tests.MockInvoice,
  82  		PaymentHash:    tests.MockPaymentHash,
  83  		Preimage:       &mockPreimage,
  84  		AmountMsat:     123000,
  85  		AppId:          &app.ID,
  86  	})
  87  
  88  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
  89  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, nil, nil)
  90  
  91  	assert.NoError(t, err)
  92  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
  93  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
  94  	assert.Equal(t, mockPreimage, *transaction.Preimage)
  95  	assert.True(t, transaction.SelfPayment)
  96  
  97  	transactionType := constants.TRANSACTION_TYPE_INCOMING
  98  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
  99  	assert.NoError(t, err)
 100  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 101  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 102  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 103  	assert.Equal(t, app.ID, *incomingTransaction.AppId)
 104  	assert.True(t, incomingTransaction.SelfPayment)
 105  
 106  	transactions := []db.Transaction{}
 107  	result := svc.DB.Find(&transactions)
 108  	assert.Equal(t, int64(2), result.RowsAffected)
 109  	// expect balance to be increased
 110  	balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID)
 111  	assert.NoError(t, err)
 112  	assert.Equal(t, int64(123000), balanceMsat)
 113  }
 114  
 115  func TestSendPaymentSync_SelfPayment_NoAppToApp(t *testing.T) {
 116  	ctx := context.TODO()
 117  
 118  	svc, err := tests.CreateTestService(t)
 119  	require.NoError(t, err)
 120  	defer svc.Remove()
 121  
 122  	// pubkey matches mock invoice = self payment
 123  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
 124  
 125  	app, _, err := tests.CreateApp(svc)
 126  	assert.NoError(t, err)
 127  
 128  	dbRequestEvent := &db.RequestEvent{}
 129  	err = svc.DB.Create(&dbRequestEvent).Error
 130  	assert.NoError(t, err)
 131  
 132  	mockPreimage := "123preimage"
 133  	svc.DB.Create(&db.Transaction{
 134  		State:          constants.TRANSACTION_STATE_PENDING,
 135  		Type:           constants.TRANSACTION_TYPE_INCOMING,
 136  		PaymentRequest: tests.MockInvoice,
 137  		PaymentHash:    tests.MockPaymentHash,
 138  		Preimage:       &mockPreimage,
 139  		AmountMsat:     123000,
 140  		AppId:          &app.ID,
 141  	})
 142  
 143  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 144  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, nil, nil)
 145  
 146  	assert.NoError(t, err)
 147  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 148  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 149  	assert.Equal(t, mockPreimage, *transaction.Preimage)
 150  	assert.True(t, transaction.SelfPayment)
 151  
 152  	transactionType := constants.TRANSACTION_TYPE_INCOMING
 153  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
 154  	assert.NoError(t, err)
 155  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 156  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 157  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 158  	assert.Equal(t, app.ID, *incomingTransaction.AppId)
 159  	assert.True(t, incomingTransaction.SelfPayment)
 160  
 161  	transactions := []db.Transaction{}
 162  	result := svc.DB.Find(&transactions)
 163  	assert.Equal(t, int64(2), result.RowsAffected)
 164  }
 165  
 166  func TestSendPaymentSync_SelfPayment_IsolatedAppToNoApp(t *testing.T) {
 167  	ctx := context.TODO()
 168  
 169  	svc, err := tests.CreateTestService(t)
 170  	require.NoError(t, err)
 171  	defer svc.Remove()
 172  
 173  	// pubkey matches mock invoice = self payment
 174  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
 175  
 176  	app, _, err := tests.CreateApp(svc)
 177  	assert.NoError(t, err)
 178  	app.Isolated = true
 179  	err = svc.DB.Save(&app).Error
 180  	assert.NoError(t, err)
 181  
 182  	appPermission := &db.AppPermission{
 183  		AppId: app.ID,
 184  		App:   *app,
 185  		Scope: constants.PAY_INVOICE_SCOPE,
 186  	}
 187  	err = svc.DB.Create(appPermission).Error
 188  	assert.NoError(t, err)
 189  
 190  	// give the isolated app 123 sats (fee reserve not applied for self payments)
 191  	svc.DB.Create(&db.Transaction{
 192  		AppId:      &app.ID,
 193  		State:      constants.TRANSACTION_STATE_SETTLED,
 194  		Type:       constants.TRANSACTION_TYPE_INCOMING,
 195  		AmountMsat: 123000, // invoice is 123000 msat
 196  	})
 197  
 198  	dbRequestEvent := &db.RequestEvent{}
 199  	err = svc.DB.Create(&dbRequestEvent).Error
 200  	assert.NoError(t, err)
 201  
 202  	mockPreimage := "123preimage"
 203  	svc.DB.Create(&db.Transaction{
 204  		State:          constants.TRANSACTION_STATE_PENDING,
 205  		Type:           constants.TRANSACTION_TYPE_INCOMING,
 206  		PaymentRequest: tests.MockInvoice,
 207  		PaymentHash:    tests.MockPaymentHash,
 208  		Preimage:       &mockPreimage,
 209  		AmountMsat:     123000,
 210  	})
 211  
 212  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 213  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, &app.ID, &dbRequestEvent.ID)
 214  
 215  	assert.NoError(t, err)
 216  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 217  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 218  	assert.Equal(t, mockPreimage, *transaction.Preimage)
 219  	assert.Equal(t, app.ID, *transaction.AppId)
 220  	assert.Equal(t, dbRequestEvent.ID, *transaction.RequestEventId)
 221  	assert.True(t, transaction.SelfPayment)
 222  
 223  	transactionType := constants.TRANSACTION_TYPE_INCOMING
 224  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
 225  	assert.NoError(t, err)
 226  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 227  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 228  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 229  	assert.True(t, incomingTransaction.SelfPayment)
 230  
 231  	transactions := []db.Transaction{}
 232  	result := svc.DB.Find(&transactions)
 233  	assert.Equal(t, int64(3), result.RowsAffected)
 234  	// expect balance to be decreased
 235  	balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID)
 236  	assert.NoError(t, err)
 237  	assert.Equal(t, int64(0), balanceMsat)
 238  }
 239  
 240  func TestSendPaymentSync_SelfPayment_IsolatedAppToApp(t *testing.T) {
 241  	ctx := context.TODO()
 242  
 243  	svc, err := tests.CreateTestService(t)
 244  	require.NoError(t, err)
 245  	defer svc.Remove()
 246  
 247  	// pubkey matches mock invoice = self payment
 248  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
 249  
 250  	app, _, err := tests.CreateApp(svc)
 251  	assert.NoError(t, err)
 252  	app.Isolated = true
 253  	err = svc.DB.Save(&app).Error
 254  	assert.NoError(t, err)
 255  	app2, _, err := tests.CreateApp(svc)
 256  	assert.NoError(t, err)
 257  
 258  	appPermission := &db.AppPermission{
 259  		AppId: app.ID,
 260  		App:   *app,
 261  		Scope: constants.PAY_INVOICE_SCOPE,
 262  	}
 263  	err = svc.DB.Create(appPermission).Error
 264  	assert.NoError(t, err)
 265  
 266  	// give the isolated app 123 sats (fee reserve not applied for self payments)
 267  	svc.DB.Create(&db.Transaction{
 268  		AppId:      &app.ID,
 269  		State:      constants.TRANSACTION_STATE_SETTLED,
 270  		Type:       constants.TRANSACTION_TYPE_INCOMING,
 271  		AmountMsat: 123000, // invoice is 123000 msat
 272  	})
 273  
 274  	dbRequestEvent := &db.RequestEvent{}
 275  	err = svc.DB.Create(&dbRequestEvent).Error
 276  	assert.NoError(t, err)
 277  
 278  	mockPreimage := "123preimage"
 279  	svc.DB.Create(&db.Transaction{
 280  		State:          constants.TRANSACTION_STATE_PENDING,
 281  		Type:           constants.TRANSACTION_TYPE_INCOMING,
 282  		PaymentRequest: tests.MockInvoice,
 283  		PaymentHash:    tests.MockPaymentHash,
 284  		Preimage:       &mockPreimage,
 285  		AmountMsat:     123000,
 286  		AppId:          &app2.ID,
 287  	})
 288  
 289  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 290  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, &app.ID, &dbRequestEvent.ID)
 291  
 292  	assert.NoError(t, err)
 293  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 294  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 295  	assert.Equal(t, mockPreimage, *transaction.Preimage)
 296  	assert.Equal(t, app.ID, *transaction.AppId)
 297  	assert.Equal(t, dbRequestEvent.ID, *transaction.RequestEventId)
 298  	assert.True(t, transaction.SelfPayment)
 299  
 300  	transactionType := constants.TRANSACTION_TYPE_INCOMING
 301  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
 302  	assert.NoError(t, err)
 303  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 304  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 305  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 306  	assert.Equal(t, app2.ID, *incomingTransaction.AppId)
 307  	assert.True(t, incomingTransaction.SelfPayment)
 308  
 309  	transactions := []db.Transaction{}
 310  	result := svc.DB.Find(&transactions)
 311  	assert.Equal(t, int64(3), result.RowsAffected)
 312  	// expect balance to be decreased
 313  	balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID)
 314  	assert.NoError(t, err)
 315  	assert.Equal(t, int64(0), balanceMsat)
 316  }
 317  
 318  func TestSendPaymentSync_SelfPayment_IsolatedAppToIsolatedApp(t *testing.T) {
 319  	ctx := context.TODO()
 320  
 321  	svc, err := tests.CreateTestService(t)
 322  	require.NoError(t, err)
 323  	defer svc.Remove()
 324  
 325  	// pubkey matches mock invoice = self payment
 326  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
 327  
 328  	app, _, err := tests.CreateApp(svc)
 329  	assert.NoError(t, err)
 330  	app.Isolated = true
 331  	err = svc.DB.Save(&app).Error
 332  	assert.NoError(t, err)
 333  	app2, _, err := tests.CreateApp(svc)
 334  	assert.NoError(t, err)
 335  	app2.Isolated = true
 336  	err = svc.DB.Save(&app2).Error
 337  	assert.NoError(t, err)
 338  
 339  	appPermission := &db.AppPermission{
 340  		AppId: app.ID,
 341  		App:   *app,
 342  		Scope: constants.PAY_INVOICE_SCOPE,
 343  	}
 344  	err = svc.DB.Create(appPermission).Error
 345  	assert.NoError(t, err)
 346  
 347  	// give the isolated app 123 sats (fee reserve not applied for self payments)
 348  	svc.DB.Create(&db.Transaction{
 349  		AppId:      &app.ID,
 350  		State:      constants.TRANSACTION_STATE_SETTLED,
 351  		Type:       constants.TRANSACTION_TYPE_INCOMING,
 352  		AmountMsat: 123000, // invoice is 123000 msat
 353  	})
 354  
 355  	dbRequestEvent := &db.RequestEvent{}
 356  	err = svc.DB.Create(&dbRequestEvent).Error
 357  	assert.NoError(t, err)
 358  
 359  	mockPreimage := "123preimage"
 360  	svc.DB.Create(&db.Transaction{
 361  		State:          constants.TRANSACTION_STATE_PENDING,
 362  		Type:           constants.TRANSACTION_TYPE_INCOMING,
 363  		PaymentRequest: tests.MockInvoice,
 364  		PaymentHash:    tests.MockPaymentHash,
 365  		Preimage:       &mockPreimage,
 366  		AmountMsat:     123000,
 367  		AppId:          &app2.ID,
 368  	})
 369  
 370  	mockEventConsumer := tests.NewMockEventConsumer()
 371  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 372  
 373  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 374  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, &app.ID, &dbRequestEvent.ID)
 375  
 376  	assert.NoError(t, err)
 377  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 378  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 379  	assert.Equal(t, mockPreimage, *transaction.Preimage)
 380  	assert.Equal(t, app.ID, *transaction.AppId)
 381  	assert.Equal(t, dbRequestEvent.ID, *transaction.RequestEventId)
 382  	assert.True(t, transaction.SelfPayment)
 383  
 384  	transactionType := constants.TRANSACTION_TYPE_INCOMING
 385  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
 386  	assert.NoError(t, err)
 387  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 388  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 389  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 390  	assert.Equal(t, app2.ID, *incomingTransaction.AppId)
 391  	assert.True(t, incomingTransaction.SelfPayment)
 392  
 393  	transactions := []db.Transaction{}
 394  	result := svc.DB.Find(&transactions)
 395  	assert.Equal(t, int64(3), result.RowsAffected)
 396  	// expect balance to be decreased
 397  	balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID)
 398  	assert.NoError(t, err)
 399  	assert.Equal(t, int64(0), balanceMsat)
 400  
 401  	// check notifications
 402  	consumedEvents := mockEventConsumer.WaitForConsumedEvents(2)
 403  	assert.Equal(t, 2, len(consumedEvents))
 404  
 405  	// we can't guarantee which notification was processed first because events are published async
 406  	// so swap them if they are back to front
 407  	if consumedEvents[1].Event == "nwc_payment_received" {
 408  		consumedEvents[0], consumedEvents[1] = consumedEvents[1], consumedEvents[0]
 409  	}
 410  
 411  	assert.Equal(t, "nwc_payment_sent", consumedEvents[1].Event)
 412  	settledTransaction := consumedEvents[1].Properties.(*db.Transaction)
 413  	assert.Equal(t, transaction.ID, settledTransaction.ID)
 414  
 415  	assert.Equal(t, "nwc_payment_received", consumedEvents[0].Event)
 416  	receivedTransaction := consumedEvents[0].Properties.(*db.Transaction)
 417  	assert.Equal(t, incomingTransaction.ID, receivedTransaction.ID)
 418  }
 419  
 420  func TestSendPaymentSync_SelfPayment_IsolatedAppToSelf(t *testing.T) {
 421  	ctx := context.TODO()
 422  
 423  	svc, err := tests.CreateTestService(t)
 424  	require.NoError(t, err)
 425  	defer svc.Remove()
 426  
 427  	// pubkey matches mock invoice = self payment
 428  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
 429  
 430  	app, _, err := tests.CreateApp(svc)
 431  	assert.NoError(t, err)
 432  	app.Isolated = true
 433  	err = svc.DB.Save(&app).Error
 434  	assert.NoError(t, err)
 435  
 436  	appPermission := &db.AppPermission{
 437  		AppId: app.ID,
 438  		App:   *app,
 439  		Scope: constants.PAY_INVOICE_SCOPE,
 440  	}
 441  	err = svc.DB.Create(appPermission).Error
 442  	assert.NoError(t, err)
 443  
 444  	// give the isolated app 123 sats (fee reserve not applied for self payments)
 445  	svc.DB.Create(&db.Transaction{
 446  		AppId:      &app.ID,
 447  		State:      constants.TRANSACTION_STATE_SETTLED,
 448  		Type:       constants.TRANSACTION_TYPE_INCOMING,
 449  		AmountMsat: 123000, // invoice is 123000 msat
 450  	})
 451  
 452  	dbRequestEvent := &db.RequestEvent{}
 453  	err = svc.DB.Create(&dbRequestEvent).Error
 454  	assert.NoError(t, err)
 455  
 456  	mockPreimage := "123preimage"
 457  	svc.DB.Create(&db.Transaction{
 458  		State:          constants.TRANSACTION_STATE_PENDING,
 459  		Type:           constants.TRANSACTION_TYPE_INCOMING,
 460  		PaymentRequest: tests.MockInvoice,
 461  		PaymentHash:    tests.MockPaymentHash,
 462  		Preimage:       &mockPreimage,
 463  		AmountMsat:     123000,
 464  		AppId:          &app.ID,
 465  	})
 466  
 467  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 468  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, nil, nil, svc.LNClient, &app.ID, &dbRequestEvent.ID)
 469  
 470  	assert.NoError(t, err)
 471  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 472  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 473  	assert.Equal(t, mockPreimage, *transaction.Preimage)
 474  	assert.Equal(t, app.ID, *transaction.AppId)
 475  	assert.Equal(t, dbRequestEvent.ID, *transaction.RequestEventId)
 476  	assert.True(t, transaction.SelfPayment)
 477  
 478  	transactionType := constants.TRANSACTION_TYPE_INCOMING
 479  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
 480  	assert.NoError(t, err)
 481  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 482  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 483  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 484  	assert.Equal(t, app.ID, *incomingTransaction.AppId)
 485  	assert.True(t, incomingTransaction.SelfPayment)
 486  
 487  	transactions := []db.Transaction{}
 488  	result := svc.DB.Find(&transactions)
 489  	assert.Equal(t, int64(3), result.RowsAffected)
 490  
 491  	// expect balance to be unchanged
 492  	balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID)
 493  	assert.NoError(t, err)
 494  	assert.Equal(t, int64(123000), balanceMsat)
 495  }
 496  
 497  func TestSendPaymentSync_SelfPayment_IsolatedAppToApp_AmountProvidedIgnoredOnNonZeroAmountInvoice(t *testing.T) {
 498  	ctx := context.TODO()
 499  
 500  	svc, err := tests.CreateTestService(t)
 501  	require.NoError(t, err)
 502  	defer svc.Remove()
 503  
 504  	// pubkey matches mock invoice = self payment
 505  	svc.LNClient.(*tests.MockLn).Pubkey = "03cbd788f5b22bd56e2714bff756372d2293504c064e03250ed16a4dd80ad70e2c"
 506  
 507  	app, _, err := tests.CreateApp(svc)
 508  	assert.NoError(t, err)
 509  	app.Isolated = true
 510  	err = svc.DB.Save(&app).Error
 511  	assert.NoError(t, err)
 512  	app2, _, err := tests.CreateApp(svc)
 513  	assert.NoError(t, err)
 514  
 515  	appPermission := &db.AppPermission{
 516  		AppId: app.ID,
 517  		App:   *app,
 518  		Scope: constants.PAY_INVOICE_SCOPE,
 519  	}
 520  	err = svc.DB.Create(appPermission).Error
 521  	assert.NoError(t, err)
 522  
 523  	// give the isolated app 123 sats (fee reserve not applied for self payments)
 524  	svc.DB.Create(&db.Transaction{
 525  		AppId:      &app.ID,
 526  		State:      constants.TRANSACTION_STATE_SETTLED,
 527  		Type:       constants.TRANSACTION_TYPE_INCOMING,
 528  		AmountMsat: 123000, // invoice is 123000 msat
 529  	})
 530  
 531  	dbRequestEvent := &db.RequestEvent{}
 532  	err = svc.DB.Create(&dbRequestEvent).Error
 533  	assert.NoError(t, err)
 534  
 535  	mockPreimage := "123preimage"
 536  	svc.DB.Create(&db.Transaction{
 537  		State:          constants.TRANSACTION_STATE_PENDING,
 538  		Type:           constants.TRANSACTION_TYPE_INCOMING,
 539  		PaymentRequest: tests.MockInvoice,
 540  		PaymentHash:    tests.MockPaymentHash,
 541  		Preimage:       &mockPreimage,
 542  		AmountMsat:     123000,
 543  		AppId:          &app2.ID,
 544  	})
 545  
 546  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 547  
 548  	// this amount is wrong, it will just be ignored
 549  	amountMsat := uint64(1000)
 550  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, &amountMsat, nil, svc.LNClient, &app.ID, &dbRequestEvent.ID)
 551  
 552  	assert.NoError(t, err)
 553  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 554  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 555  	assert.Equal(t, mockPreimage, *transaction.Preimage)
 556  	assert.Equal(t, app.ID, *transaction.AppId)
 557  	assert.Equal(t, dbRequestEvent.ID, *transaction.RequestEventId)
 558  	assert.True(t, transaction.SelfPayment)
 559  
 560  	transactionType := constants.TRANSACTION_TYPE_INCOMING
 561  	incomingTransaction, err := transactionsService.LookupTransaction(ctx, tests.MockPaymentHash, &transactionType, svc.LNClient, nil)
 562  	assert.NoError(t, err)
 563  	assert.Equal(t, uint64(123000), incomingTransaction.AmountMsat)
 564  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, incomingTransaction.State)
 565  	assert.Equal(t, mockPreimage, *incomingTransaction.Preimage)
 566  	assert.Equal(t, app2.ID, *incomingTransaction.AppId)
 567  	assert.True(t, incomingTransaction.SelfPayment)
 568  
 569  	transactions := []db.Transaction{}
 570  	result := svc.DB.Find(&transactions)
 571  	assert.Equal(t, int64(3), result.RowsAffected)
 572  	// expect balance to be decreased
 573  	balanceMsat, err := queries.GetIsolatedBalanceMsat(svc.DB, app.ID)
 574  	assert.NoError(t, err)
 575  	assert.Equal(t, int64(0), balanceMsat)
 576  }
 577