mirror of https://github.com/lightninglabs/loop
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.6 KiB
Go
103 lines
2.6 KiB
Go
package lsat
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
)
|
|
|
|
const (
|
|
// LatestVersion is the latest version used for minting new LSATs.
|
|
LatestVersion = 0
|
|
|
|
// SecretSize is the size in bytes of a LSAT's secret, also known as
|
|
// the root key of the macaroon.
|
|
SecretSize = 32
|
|
|
|
// TokenIDSize is the size in bytes of an LSAT's ID encoded in its
|
|
// macaroon identifier.
|
|
TokenIDSize = 32
|
|
)
|
|
|
|
var (
|
|
// byteOrder is the byte order used to encode/decode a macaroon's raw
|
|
// identifier.
|
|
byteOrder = binary.BigEndian
|
|
|
|
// ErrUnknownVersion is an error returned when attempting to decode an
|
|
// LSAT identifier with an unknown version.
|
|
ErrUnknownVersion = errors.New("unknown LSAT version")
|
|
)
|
|
|
|
// Identifier contains the static identifying details of an LSAT. This is
|
|
// intended to be used as the identifier of the macaroon within an LSAT.
|
|
type Identifier struct {
|
|
// Version is the version of an LSAT. Having a version allows us to
|
|
// introduce new fields to the identifier in a backwards-compatible
|
|
// manner.
|
|
Version uint16
|
|
|
|
// PaymentHash is the payment hash linked to an LSAT. Verification of
|
|
// an LSAT depends on a valid payment, which is enforced by ensuring a
|
|
// preimage is provided that hashes to our payment hash.
|
|
PaymentHash lntypes.Hash
|
|
|
|
// TokenID is the unique identifier of an LSAT.
|
|
TokenID [TokenIDSize]byte
|
|
}
|
|
|
|
// EncodeIdentifier encodes an LSAT's identifier according to its version.
|
|
func EncodeIdentifier(w io.Writer, id *Identifier) error {
|
|
if err := binary.Write(w, byteOrder, id.Version); err != nil {
|
|
return err
|
|
}
|
|
|
|
switch id.Version {
|
|
// A version 0 identifier consists of its linked payment hash, followed
|
|
// by the token ID.
|
|
case 0:
|
|
if _, err := w.Write(id.PaymentHash[:]); err != nil {
|
|
return err
|
|
}
|
|
_, err := w.Write(id.TokenID[:])
|
|
return err
|
|
|
|
default:
|
|
return fmt.Errorf("%w: %v", ErrUnknownVersion, id.Version)
|
|
}
|
|
}
|
|
|
|
// DecodeIdentifier decodes an LSAT's identifier according to its version.
|
|
func DecodeIdentifier(r io.Reader) (*Identifier, error) {
|
|
var version uint16
|
|
if err := binary.Read(r, byteOrder, &version); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch version {
|
|
// A version 0 identifier consists of its linked payment hash, followed
|
|
// by the token ID.
|
|
case 0:
|
|
var paymentHash lntypes.Hash
|
|
if _, err := r.Read(paymentHash[:]); err != nil {
|
|
return nil, err
|
|
}
|
|
var tokenID [TokenIDSize]byte
|
|
if _, err := r.Read(tokenID[:]); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Identifier{
|
|
Version: version,
|
|
PaymentHash: paymentHash,
|
|
TokenID: tokenID,
|
|
}, nil
|
|
|
|
default:
|
|
return nil, fmt.Errorf("%w: %v", ErrUnknownVersion, version)
|
|
}
|
|
}
|