Documentation ¶
Index ¶
- Constants
- Variables
- func AddFirstPartyCaveats(m *macaroon.Macaroon, caveats ...Caveat) error
- func EncodeCaveat(c Caveat) string
- func EncodeIdentifier(w io.Writer, id *Identifier) error
- func HasCaveat(m *macaroon.Macaroon, cond string) (string, bool)
- func UseLogger(logger btclog.Logger)
- func VerifyCaveats(caveats []Caveat, satisfiers ...Satisfier) error
- type Caveat
- type FileStore
- type Identifier
- type Interceptor
- type Satisfier
- type Service
- type ServiceTier
- type Store
- type Token
- type TokenID
Constants ¶
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 )
const ( // GRPCErrCode is the error code we receive from a gRPC call if the // server expects a payment. GRPCErrCode = codes.Internal // GRPCErrMessage is the error message we receive from a gRPC call in // conjunction with the GRPCErrCode to signal the client that a payment // is required to access the service. GRPCErrMessage = "payment required" // AuthHeader is is the HTTP response header that contains the payment // challenge. AuthHeader = "WWW-Authenticate" // DefaultMaxCostSats is the default maximum amount in satoshis that we // are going to pay for an LSAT automatically. Does not include routing // fees. DefaultMaxCostSats = 1000 // DefaultMaxRoutingFeeSats is the default maximum routing fee in // satoshis that we are going to pay to acquire an LSAT token. DefaultMaxRoutingFeeSats = 10 // PaymentTimeout is the maximum time we allow a payment to take before // we stop waiting for it. PaymentTimeout = 60 * time.Second )
const ( // CondServices is the condition used for a services caveat. CondServices = "services" // CondCapabilitiesSuffix is the condition suffix used for a service's // capabilities caveat. For example, the condition of a capabilities // caveat for a service named `loop` would be `loop_capabilities`. CondCapabilitiesSuffix = "_capabilities" )
const (
// PreimageKey is the key used for a payment preimage caveat.
PreimageKey = "preimage"
)
const Subsystem = "LSAT"
Subsystem defines the sub system name of this package.
Variables ¶
var ( // ErrNoServices is an error returned when we attempt to decode the // services included in a caveat. ErrNoServices = errors.New("no services found") // ErrInvalidService is an error returned when we attempt to decode a // service with an invalid format. ErrInvalidService = errors.New("service must be of the form " + "\"name:tier\"") )
var ( // ErrInvalidCaveat is an error returned when we attempt to decode a // caveat with an invalid format. ErrInvalidCaveat = errors.New("caveat must be of the form " + "\"condition=value\"") )
var ( // ErrNoToken is the error returned when the store doesn't contain a // token yet. ErrNoToken = errors.New("no token in store") )
var ( // ErrUnknownVersion is an error returned when attempting to decode an // LSAT identifier with an unknown version. ErrUnknownVersion = errors.New("unknown LSAT version") )
Functions ¶
func AddFirstPartyCaveats ¶
AddFirstPartyCaveats adds a set of caveats as first-party caveats to a macaroon.
func EncodeCaveat ¶
EncodeCaveat encodes a caveat into its string representation.
func EncodeIdentifier ¶
func EncodeIdentifier(w io.Writer, id *Identifier) error
EncodeIdentifier encodes an LSAT's identifier according to its version.
func HasCaveat ¶
HasCaveat checks whether the given macaroon has a caveat with the given condition, and if so, returns its value. If multiple caveats with the same condition exist, then the value of the last one is returned.
func UseLogger ¶
UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.
func VerifyCaveats ¶
VerifyCaveats determines whether every relevant caveat of an LSAT holds true. A caveat is considered relevant if a satisfier is provided for it, which is what we'll use as their evaluation.
NOTE: The caveats provided should be in the same order as in the LSAT to ensure the correctness of each satisfier's SatisfyPrevious.
Types ¶
type Caveat ¶
type Caveat struct { // Condition serves as a way to identify a caveat and how to satisfy it. Condition string // Value is what will be used to satisfy a caveat. This can be as // flexible as needed, as long as it can be encoded into a string. Value string }
Caveat is a predicate that can be applied to an LSAT in order to restrict its use in some form. Caveats are evaluated during LSAT verification after the LSAT's signature is verified. The predicate of each caveat must hold true in order to successfully validate an LSAT.
func DecodeCaveat ¶
DecodeCaveat decodes a caveat from its string representation.
func NewCapabilitiesCaveat ¶
NewCapabilitiesCaveat creates a new capabilities caveat for the given service.
func NewServicesCaveat ¶
NewServicesCaveat creates a new services caveat with the provided caveats.
type FileStore ¶
type FileStore struct {
// contains filtered or unexported fields
}
FileStore is an implementation of the Store interface that files to save the serialized tokens. There is always just one current token that is either pending or fully paid.
func NewFileStore ¶
NewFileStore creates a new file based token store, creating its file in the provided directory. If the directory does not exist, it will be created.
func (*FileStore) AllTokens ¶
AllTokens returns all tokens that the store has knowledge of, even if they might be expired. The tokens are mapped by their identifying attribute like file name or storage key.
NOTE: This is part of the Store interface.
func (*FileStore) CurrentToken ¶
CurrentToken returns the token that is currently contained in the store or an error if there is none.
NOTE: This is part of the Store interface.
func (*FileStore) StoreToken ¶
StoreToken saves a token to the store, overwriting any old token if there is one.
NOTE: This is part of the Store interface.
type Identifier ¶
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 TokenID }
Identifier contains the static identifying details of an LSAT. This is intended to be used as the identifier of the macaroon within an LSAT.
func DecodeIdentifier ¶
func DecodeIdentifier(r io.Reader) (*Identifier, error)
DecodeIdentifier decodes an LSAT's identifier according to its version.
type Interceptor ¶
type Interceptor struct {
// contains filtered or unexported fields
}
Interceptor is a gRPC client interceptor that can handle LSAT authentication challenges with embedded payment requests. It uses a connection to lnd to automatically pay for an authentication token.
func NewInterceptor ¶
func NewInterceptor(lnd *lndclient.LndServices, store Store, rpcCallTimeout time.Duration, maxCost, maxFee btcutil.Amount) *Interceptor
NewInterceptor creates a new gRPC client interceptor that uses the provided lnd connection to automatically acquire and pay for LSAT tokens, unless the indicated store already contains a usable token.
func (*Interceptor) StreamInterceptor ¶
func (i *Interceptor) StreamInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error)
StreamInterceptor is an interceptor method that can be used directly by gRPC for streaming calls. If the store contains a token, it is attached as credentials to every stream establishment call before patching it through. The response error is also intercepted for every initial stream initiation. If there is an error returned and it is indicating a payment challenge, a token is acquired and paid for automatically. The original request is then repeated back to the server, now with the new token attached.
func (*Interceptor) UnaryInterceptor ¶
func (i *Interceptor) UnaryInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error
UnaryInterceptor is an interceptor method that can be used directly by gRPC for unary calls. If the store contains a token, it is attached as credentials to every call before patching it through. The response error is also intercepted for every call. If there is an error returned and it is indicating a payment challenge, a token is acquired and paid for automatically. The original request is then repeated back to the server, now with the new token attached.
type Satisfier ¶
type Satisfier struct { // Condition is the condition of the caveat we'll attempt to satisfy. Condition string // SatisfyPrevious ensures a caveat is in accordance with a previous one // with the same condition. This is needed since caveats of the same // condition can be used multiple times as long as they enforce more // permissions than the previous. // // For example, we have a caveat that only allows us to use an LSAT for // 7 more days. We can add another caveat that only allows for 3 more // days of use and lend it to another party. SatisfyPrevious func(previous Caveat, current Caveat) error // SatisfyFinal satisfies the final caveat of an LSAT. If multiple // caveats with the same condition exist, this will only be executed // once all previous caveats are also satisfied. SatisfyFinal func(Caveat) error }
Satisfier provides a generic interface to satisfy a caveat based on its condition.
func NewCapabilitiesSatisfier ¶
NewCapabilitiesSatisfier implements a satisfier to determine whether the target capability for a service is authorized for a given LSAT.
func NewServicesSatisfier ¶
NewServicesSatisfier implements a satisfier to determine whether the target service is authorized for a given LSAT.
TODO(wilmer): Add tier verification?
type Service ¶
type Service struct { // Name is the name of the LSAT-enabled service. Name string // Tier is the tier of the LSAT-enabled service. Tier ServiceTier }
Service contains the details of an LSAT-enabled service.
type ServiceTier ¶
type ServiceTier uint8
ServiceTier represents the different possible tiers of an LSAT-enabled service.
const ( // BaseTier is the base tier of an LSAT-enabled service. This tier // should be used for any new LSATs that are not part of a service tier // upgrade. BaseTier ServiceTier = iota )
type Store ¶
type Store interface { // CurrentToken returns the token that is currently contained in the // store or an error if there is none. CurrentToken() (*Token, error) // AllTokens returns all tokens that the store has knowledge of, even // if they might be expired. The tokens are mapped by their identifying // attribute like file name or storage key. AllTokens() (map[string]*Token, error) // StoreToken saves a token to the store. Old tokens should be kept for // accounting purposes but marked as invalid somehow. StoreToken(*Token) error }
Store is an interface that allows users to store and retrieve an LSAT token.
type Token ¶
type Token struct { // PaymentHash is the hash of the LSAT invoice that needs to be paid. // Knowing the preimage to this hash is seen as proof of payment by the // authentication server. PaymentHash lntypes.Hash // Preimage is the proof of payment indicating that the token has been // paid for if set. If the preimage is empty, the payment might still // be in transit. Preimage lntypes.Preimage // AmountPaid is the total amount in msat that the user paid to get the // token. This does not include routing fees. AmountPaid lnwire.MilliSatoshi // RoutingFeePaid is the total amount in msat that the user paid in // routing fee to get the token. RoutingFeePaid lnwire.MilliSatoshi // TimeCreated is the moment when this token was created. TimeCreated time.Time // contains filtered or unexported fields }
Token is the main type to store an LSAT token in.
func (*Token) BaseMacaroon ¶
func (t *Token) BaseMacaroon() *macaroon.Macaroon
BaseMacaroon returns the base macaroon as received from the authentication server.
func (*Token) IsValid ¶
IsValid returns true if the timestamp contained in the base macaroon is not yet expired.
func (*Token) PaidMacaroon ¶
PaidMacaroon returns the base macaroon with the proof of payment (preimage) added as a first-party-caveat.
type TokenID ¶
type TokenID [TokenIDSize]byte
TokenID is the type that stores the token identifier of an LSAT token.
func MakeIDFromString ¶
MakeIDFromString parses the hex encoded string and parses it into a token ID.