-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpayment.go
105 lines (87 loc) · 3.94 KB
/
payment.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package payment
import (
"bytes"
"time"
"github.com/code-payments/code-server/pkg/kin"
"github.com/code-payments/code-server/pkg/solana/token"
"github.com/code-payments/code-server/pkg/code/data/transaction"
"github.com/mr-tron/base58"
"github.com/pkg/errors"
)
type ByBlock []*Record
func (a ByBlock) Len() int { return len(a) }
func (a ByBlock) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByBlock) Less(i, j int) bool { return a[i].BlockId < a[j].BlockId }
// The structure for metadata behind a payment or token transfer between two
// parties. This data is considered untrusted as it comes from the client apps
// directly and not from the blockchain. It gives us the intended native
// currencies for the agreed upon exchange between two app users. This data
// cannot be derived from the blockchain alone. We could guess at it, but then
// we would definitely be off by a couple decimal points every now and then when
// reporting the booking cost back to the user.
//
// Note: This is generally unused right now and should be deprecated with the
// new intent system and external data models. There's a few use cases still
// hitting this which, in particular, need to know the order of transfers.
type Record struct {
Id uint64 // The internal database id for this transaction
BlockId uint64
BlockTime time.Time
TransactionId string // The signature of the Solana transaction, which could contain multiple payments
TransactionIndex uint32 // The index that the transfer (payment) instruction appears at inside the Solana transaction
Rendezvous string // The public key of the party that is the rendezvous point for this payment (might be empty)
IsExternal bool // External payments are deprecated, in favour of the new deposit store
Source string // The source account id for this payment
Destination string // The destination account id for this payment
Quantity uint64 // The amount of Kin (in Quarks)
ExchangeCurrency string // The (external) agreed upon currency for the exchange
ExchangeRate float64 // The (external) agreed upon exchange rate for determining the amount of Kin to transfer
UsdMarketValue float64 // The (internal) market value of this transfer based on the internal exchange rate record
Region *string // The (external) agreed upon country flag for the currency
IsWithdraw bool
ConfirmationState transaction.Confirmation
CreatedAt time.Time
}
type PaymentType uint32
const (
PaymentType_Send PaymentType = iota
PaymentType_Receive
)
func NewFromTransfer(transfer *token.DecompiledTransfer, sig string, index int, rate float64, now time.Time) *Record {
source_id := base58.Encode(transfer.Source)
destination_id := base58.Encode(transfer.Destination)
return &Record{
TransactionId: sig,
TransactionIndex: uint32(index),
Source: source_id,
Destination: destination_id,
Quantity: transfer.Amount,
ExchangeCurrency: "kin",
ExchangeRate: 1,
UsdMarketValue: rate * float64(kin.FromQuarks(transfer.Amount)),
ConfirmationState: transaction.ConfirmationPending,
CreatedAt: now,
}
}
func NewFromTransferChecked(transfer *token.DecompiledTransfer2, sig string, index int, rate float64, now time.Time) (*Record, error) {
if !bytes.Equal(transfer.Mint, kin.TokenMint) {
return nil, errors.New("invalid token mint")
}
if transfer.Decimals != kin.Decimals {
return nil, errors.New("invalid kin token decimals")
}
source_id := base58.Encode(transfer.Source)
destination_id := base58.Encode(transfer.Destination)
return &Record{
TransactionId: sig,
TransactionIndex: uint32(index),
Source: source_id,
Destination: destination_id,
Quantity: transfer.Amount,
ExchangeCurrency: "kin",
ExchangeRate: 1,
UsdMarketValue: rate * float64(kin.FromQuarks(transfer.Amount)),
ConfirmationState: transaction.ConfirmationPending,
CreatedAt: now,
}, nil
}