-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial Invoice implementation (#36)
* Invoice implementation * Sort the strings before encoding so it's deterministic * Fix the other test
- Loading branch information
Showing
8 changed files
with
324 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package protocol | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/btcsuite/btcutil/bech32" | ||
"github.com/uma-universal-money-address/uma-go-sdk/uma/utils" | ||
) | ||
|
||
type InvoiceCurrency struct { | ||
// Code is the ISO 4217 (if applicable) currency code (eg. "USD"). For cryptocurrencies, this will be a ticker | ||
// symbol, such as BTC for Bitcoin. | ||
Code string `tlv:"0"` | ||
|
||
// Name is the full display name of the currency (eg. US Dollars). | ||
Name string `tlv:"1"` | ||
|
||
// Symbol is the symbol of the currency (eg. $ for USD). | ||
Symbol string `tlv:"2"` | ||
} | ||
|
||
func (c *InvoiceCurrency) MarshalTLV() ([]byte, error) { | ||
return utils.MarshalTLV(c) | ||
} | ||
|
||
func (c *InvoiceCurrency) UnmarshalTLV(data []byte) error { | ||
return utils.UnmarshalTLV(c, data) | ||
} | ||
|
||
type UmaInvoice struct { | ||
// Receiving UMA address | ||
ReceiverUma string `tlv:"0"` | ||
|
||
// Invoice UUID Served as both the identifier of the UMA invoice, and the validation of proof of payment. | ||
InvoiceUUID string `tlv:"1"` | ||
|
||
// The amount of invoice to be paid in the smalest unit of the ReceivingCurrency. | ||
Amount uint64 `tlv:"2"` | ||
|
||
// The currency of the invoice | ||
ReceivingCurrency InvoiceCurrency `tlv:"3"` | ||
|
||
// The unix timestamp the UMA invoice expires | ||
Expiration uint64 `tlv:"4"` | ||
|
||
// Indicates whether the VASP is a financial institution that requires travel rule information. | ||
IsSubjectToTravelRule bool `tlv:"5"` | ||
|
||
// RequiredPayerData the data about the payer that the sending VASP must provide in order to send a payment. | ||
RequiredPayerData *CounterPartyDataOptions `tlv:"6"` | ||
|
||
// UmaVersion is a list of UMA versions that the VASP supports for this transaction. It should be | ||
// containing the lowest minor version of each major version it supported, separated by commas. | ||
UmaVersion string `tlv:"7"` | ||
|
||
// CommentCharsAllowed is the number of characters that the sender can include in the comment field of the pay request. | ||
CommentCharsAllowed *int `tlv:"8"` | ||
|
||
// The sender's UMA address. If this field presents, the UMA invoice should directly go to the sending VASP instead of showing in other formats. | ||
SenderUma *string `tlv:"9"` | ||
|
||
// The maximum number of the invoice can be paid | ||
InvoiceLimit *uint64 `tlv:"10"` | ||
|
||
// KYC status of the receiver, default is verified. | ||
KycStatus *KycStatus `tlv:"11"` | ||
|
||
// The signature of the UMA invoice | ||
Signature *[]byte `tlv:"100"` | ||
} | ||
|
||
func (i *UmaInvoice) MarshalTLV() ([]byte, error) { | ||
return utils.MarshalTLV(i) | ||
} | ||
|
||
func (i *UmaInvoice) UnmarshalTLV(data []byte) error { | ||
return utils.UnmarshalTLV(i, data) | ||
} | ||
|
||
func (i *UmaInvoice) ToBech32String() (string, error) { | ||
if i.Signature == nil { | ||
return "", fmt.Errorf("signature is required to encode to bech32") | ||
} | ||
tlv, err := i.MarshalTLV() | ||
if err != nil { | ||
return "", err | ||
} | ||
conv, err := bech32.ConvertBits(tlv, 8, 5, true) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return bech32.Encode("uma", conv) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -251,3 +251,61 @@ usLY8crt6ys3KQ== | |
require.NoError(t, err) | ||
require.Equal(t, keysOnlyPubKeyResponse, reserializedPubKeyResponse) | ||
} | ||
|
||
func TestBinaryCodableForCounterPartyDataOptions(t *testing.T) { | ||
counterPartyDataOptions := umaprotocol.CounterPartyDataOptions{ | ||
"name": umaprotocol.CounterPartyDataOption{Mandatory: false}, | ||
"email": umaprotocol.CounterPartyDataOption{Mandatory: false}, | ||
"compliance": umaprotocol.CounterPartyDataOption{Mandatory: true}, | ||
} | ||
result, err := counterPartyDataOptions.MarshalBytes() | ||
require.NoError(t, err) | ||
|
||
resultStr := string(result) | ||
require.Equal(t, "compliance:1,email:0,name:0", resultStr) | ||
|
||
counterPartyDataOptions2 := umaprotocol.CounterPartyDataOptions{} | ||
err = counterPartyDataOptions2.UnmarshalBytes([]byte(resultStr)) | ||
require.NoError(t, err) | ||
require.Equal(t, counterPartyDataOptions, counterPartyDataOptions2) | ||
} | ||
|
||
func TestUnsignInvoiceTLVCoding(t *testing.T) { | ||
kyc := umaprotocol.KycStatusVerified | ||
signature := []byte("signature") | ||
invoicenvoice := umaprotocol.UmaInvoice{ | ||
ReceiverUma: "[email protected]", | ||
InvoiceUUID: "c7c07fec-cf00-431c-916f-6c13fc4b69f9", | ||
Amount: 1000, | ||
ReceivingCurrency: umaprotocol.InvoiceCurrency{ | ||
Code: "USD", | ||
Name: "US Dollar", | ||
Symbol: "$", | ||
}, | ||
Expiration: 1000000, | ||
IsSubjectToTravelRule: true, | ||
RequiredPayerData: &umaprotocol.CounterPartyDataOptions{ | ||
"name": umaprotocol.CounterPartyDataOption{Mandatory: false}, | ||
"email": umaprotocol.CounterPartyDataOption{Mandatory: false}, | ||
"compliance": umaprotocol.CounterPartyDataOption{Mandatory: true}, | ||
}, | ||
UmaVersion: "0.3", | ||
CommentCharsAllowed: nil, | ||
SenderUma: nil, | ||
InvoiceLimit: nil, | ||
KycStatus: &kyc, | ||
Signature: &signature, | ||
} | ||
|
||
invoiceTLV, err := invoicenvoice.MarshalTLV() | ||
require.NoError(t, err) | ||
|
||
invoice2 := umaprotocol.UmaInvoice{} | ||
err = invoice2.UnmarshalTLV(invoiceTLV) | ||
require.NoError(t, err) | ||
require.Equal(t, invoicenvoice, invoice2) | ||
|
||
bech32String, err := invoice2.ToBech32String() | ||
require.NoError(t, err) | ||
require.Equal(t, "uma1qqxzgen0daqxyctj9e3k7mgpy33nwcesxanx2cedvdnrqvpdxsenzced8ycnve3dxe3nzvmxvv6xyd3evcusypp3xqcrqqcnqqp4256yqyy425eqg3hkcmrpwgpqzfqyqucnqvpsxqcrqpgpqyrpkcm0d4cxc6tpde3k2w3393jk6ctfdsarqtrwv9kk2w3squpnqt3npvqnxeqfwd5kwmnpw36hyega7x5zz", bech32String) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.