Skip to content

Commit

Permalink
Add invoice uuid field to PayRequest, and add it to the bolt11 invoic…
Browse files Browse the repository at this point in the history
…e metadata. (#41)
  • Loading branch information
zhenlu authored Jul 16, 2024
1 parent 0d6057d commit 79965e4
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
4 changes: 4 additions & 0 deletions uma/protocol/pay_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type PayRequest struct {
// if the receiver included the `commentAllowed` field in the lnurlp response. The length of
// the comment must be less than or equal to the value of `commentAllowed`.
Comment *string `json:"comment,omitempty"`
// InvoiceUUID is the invoice UUID that the sender is paying.
// This only exists in the v1 pay request since the v0 SDK won't support invoices.
InvoiceUUID *string `json:"invoiceUUID,omitempty"`
// UmaMajorVersion is the major version of the UMA protocol that the VASP supports for this currency. This is used
// for serialization, but is not serialized itself.
UmaMajorVersion int `json:"-"`
Expand All @@ -65,6 +68,7 @@ type v1PayRequest struct {
PayerData *PayerData `json:"payerData,omitempty"`
RequestedPayeeData *CounterPartyDataOptions `json:"payeeData,omitempty"`
Comment *string `json:"comment,omitempty"`
InvoiceUUID *string `json:"invoiceUUID,omitempty"`
}

// IsUmaRequest returns true if the request is a valid UMA request, otherwise, if any fields are missing, it returns false.
Expand Down
95 changes: 95 additions & 0 deletions uma/uma.go
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,78 @@ func GetUmaPayRequest(
utxoCallback string,
requestedPayeeData *protocol.CounterPartyDataOptions,
comment *string,
) (*protocol.PayRequest, error) {
return GetUmaPayRequestWithInvoice(
amount,
receiverEncryptionPubKey,
sendingVaspPrivateKey,
receivingCurrencyCode,
isAmountInReceivingCurrency,
payerIdentifier,
umaMajorVersion,
payerName,
payerEmail,
trInfo,
trInfoFormat,
payerKycStatus,
payerUtxos,
payerNodePubKey,
utxoCallback,
requestedPayeeData,
comment,
nil,
)
}

// GetUmaPayRequestWithInvoice Creates a signed UMA pay request to pay an UMA invoice. For non-UMA LNURL requests, just construct a protocol.PayRequest directly.
//
// Args:
//
// amount: the amount of the payment in the smallest unit of the specified currency (i.e. cents for USD).
// receiverEncryptionPubKey: the public key of the receiver that will be used to encrypt the travel rule information.
// sendingVaspPrivateKey: the private key of the VASP that is sending the payment. This will be used to sign the request.
// receivingCurrencyCode: the code of the currency that the receiver will receive for this payment.
// isAmountInReceivingCurrency: whether the amount field is specified in the smallest unit of the receiving
// currency or in msats (if false).
// payerIdentifier: the identifier of the sender. For example, [email protected]
// umaMajorVersion: the major version of UMA used for this request. If non-UMA, this version is still relevant
// for which LUD-21 spec to follow. For the older LUD-21 spec, this should be 0. For the newer LUD-21 spec,
// this should be 1.
// payerName: the name of the sender (optional).
// payerEmail: the email of the sender (optional).
// trInfo: the travel rule information. This will be encrypted before sending to the receiver.
// trInfoFormat: the standardized format of the travel rule information (e.g. IVMS). Null indicates raw json or a
// custom format, or no travel rule information.
// payerKycStatus: whether the sender is a KYC'd customer of the sending VASP.
// payerUtxos: the list of UTXOs of the sender's channels that might be used to fund the payment.
// payerNodePubKey: If known, the public key of the sender's node. If supported by the receiving VASP's compliance provider,
// this will be used to pre-screen the sender's UTXOs for compliance purposes.
// utxoCallback: the URL that the receiver will call to send UTXOs of the channel that the receiver used to receive
// the payment once it completes.
// requestedPayeeData: the payer data options that the sender is requesting about the receiver.
// comment: a comment that the sender would like to include with the payment. This can only be included
// if the receiver included the `commentAllowed` field in the lnurlp response. The length of
// the comment must be less than or equal to the value of `commentAllowed`.
// invoiceUUID: the UUID of the invoice that the sender is paying.
func GetUmaPayRequestWithInvoice(
amount int64,
receiverEncryptionPubKey []byte,
sendingVaspPrivateKey []byte,
receivingCurrencyCode string,
isAmountInReceivingCurrency bool,
payerIdentifier string,
umaMajorVersion int,
payerName *string,
payerEmail *string,
trInfo *string,
trInfoFormat *protocol.TravelRuleFormat,
payerKycStatus protocol.KycStatus,
payerUtxos *[]string,
payerNodePubKey *string,
utxoCallback string,
requestedPayeeData *protocol.CounterPartyDataOptions,
comment *string,
invoiceUUID *string,
) (*protocol.PayRequest, error) {
complianceData, err := getSignedCompliancePayerData(
receiverEncryptionPubKey,
Expand Down Expand Up @@ -584,6 +656,7 @@ func GetUmaPayRequest(
RequestedPayeeData: requestedPayeeData,
Comment: comment,
UmaMajorVersion: umaMajorVersion,
InvoiceUUID: invoiceUUID,
}, nil
}

Expand Down Expand Up @@ -657,6 +730,21 @@ type InvoiceCreator interface {
CreateInvoice(amountMsats int64, metadata string) (*string, error)
}

func addInvoiceUUIDToMetadata(metadata string, invoiceUUID string) (string, error) {
var data [][]interface{}
err := json.Unmarshal([]byte(metadata), &data)
if err != nil {
return "", err
}
invoice := []interface{}{"text/plain", invoiceUUID}
data = append(data, invoice)
updatedJSON, err := json.Marshal(data)
if err != nil {
return "", err
}
return string(updatedJSON), nil
}

// GetPayReqResponse Creates an uma pay request response with an encoded invoice.
//
// Args:
Expand Down Expand Up @@ -732,6 +820,13 @@ func GetPayReqResponse(
}
payerDataStr = string(encodedPayerData)
}
if request.InvoiceUUID != nil {
var err error
metadata, err = addInvoiceUUIDToMetadata(metadata, *request.InvoiceUUID)
if err != nil {
return nil, err
}
}
encodedInvoice, err := invoiceCreator.CreateInvoice(msatsAmount, metadata+payerDataStr)
if err != nil {
return nil, err
Expand Down

0 comments on commit 79965e4

Please sign in to comment.