🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

lexe-common

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lexe-common - cargo Package Compare versions

Comparing version
0.1.15
to
0.1.16
+1
-1
.cargo_vcs_info.json
{
"git": {
"sha1": "4b8b1904cc4c047b46048a2028a9b1a90e64f972"
"sha1": "64d6f049576247f7e48a0ef09d191999b14272b9"
},
"path_in_vcs": "public/lexe-common"
}

@@ -16,5 +16,5 @@ # This file is automatically @generated by Cargo.

name = "anyhow"
version = "1.0.102"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"

@@ -506,5 +506,5 @@ [[package]]

name = "lexe-byte-array"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd32388f466c3447698338b958adf0f9efefd0a0be5c1269f61f9e3ab21cc42b"
checksum = "dc728990c344e970e15ef71db3c7ae165b1cb6168d3e772849622e4b9a70f648"
dependencies = [

@@ -516,3 +516,3 @@ "lexe-hex",

name = "lexe-common"
version = "0.1.15"
version = "0.1.16"
dependencies = [

@@ -565,5 +565,5 @@ "anyhow",

name = "lexe-crypto"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c4ac0ac4e73270b57e4473165a3971e640d9956b7dbd21753ce9a4cfa7b5203"
checksum = "9318ef44606022ff7ca7798a747ad126805ad9054a073e3378aaa5a1d5bcd5ec"
dependencies = [

@@ -586,5 +586,5 @@ "bcs",

name = "lexe-enclave"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e2bc1f20c29dd520fa7303e0b4d42fd15911f9a5d416910f8ae1366498ebcd"
checksum = "ff757e0c4d9f0ba7f5c635f2ce53c25cf2aee8cd3dab63acb5cc2eecb0bdb46e"
dependencies = [

@@ -606,11 +606,11 @@ "cfg-if",

name = "lexe-hex"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae0a0220e551b7f089e504cc51194814779e8f1746c67db5b1e8b0d38434ee3"
checksum = "1c08f90b258615b4ada83e4ed35d596cbe6af69cb35512e78460ac8a11b5d753"
[[package]]
name = "lexe-serde"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c6dc6bd468deb4a32ce1b4eab412ca088b078ecfd3b2ae1b0d9c6ce4986ff3a"
checksum = "c5841cf7e9d34aa855ba6a077886980d3a9971a885afd527dfef6a525de009d8"
dependencies = [

@@ -624,5 +624,5 @@ "base64",

name = "lexe-sha256"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a731b44b98afedbf98cd52ecfde6ce783f984a2133ad38185a8c7ee5912cc64"
checksum = "5fb14bba432279681424729b4ed9ab153dad35f760bc744a634e7e31287db461"
dependencies = [

@@ -637,5 +637,5 @@ "lexe-byte-array",

name = "lexe-std"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f3c4d8096e4c718ea823845c65b7cd1a878b929d7c94caefd9e988b167cdbbb"
checksum = "77db2d58961be8209cacea384e9c62c56bb447e6c52e36fb79ba017dd3b82763"
dependencies = [

@@ -659,5 +659,5 @@ "ref-cast",

name = "lightning"
version = "0.2.2"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c90397b635e3ece6b9a723fb470a46cb9b3592f217d72e40540a5fada00289d"
checksum = "63a1ab99a13ab3343a9b4d1d25c455bf72322819fc5a5f05c5182e704528a583"
dependencies = [

@@ -677,5 +677,5 @@ "bech32",

name = "lightning-invoice"
version = "0.34.0"
version = "0.34.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b85e5e14bcdb30d746e9785b04f27938292e8944f78f26517e01e91691f6b3f2"
checksum = "47d83bd798e04ab9eecc8bbef1fa17d3808859bcdc0406bd16c55d51c8834444"
dependencies = [

@@ -700,5 +700,5 @@ "bech32",

name = "lightning-types"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb1aac93f22f2c2eac8a0ee83bb1a1ea58673caa2c82847302710b83364d04e6"
checksum = "c211dfcff95ca308247da8b1e0e81604bc9e568239967cd2c34572558511e869"
dependencies = [

@@ -807,5 +807,5 @@ "bitcoin",

name = "possiblyrandom"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b122a615d72104fb3d8b26523fdf9232cd8ee06949fb37e4ce3ff964d15dffd"
checksum = "9c564dbf654befd49035528299f1208a40508f6e07efb11c163444e304e4484f"
dependencies = [

@@ -812,0 +812,0 @@ "getrandom 0.2.17",

@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO

name = "lexe-common"
version = "0.1.15"
version = "0.1.16"
authors = [

@@ -105,21 +105,21 @@ "Max Fang <max@lexe.app>",

[dependencies.lexe-byte-array]
version = "0.1.15"
version = "0.1.16"
[dependencies.lexe-crypto]
version = "0.1.15"
version = "0.1.16"
[dependencies.lexe-enclave]
version = "0.1.15"
version = "0.1.16"
[dependencies.lexe-hex]
version = "0.1.15"
version = "0.1.16"
[dependencies.lexe-serde]
version = "0.1.15"
version = "0.1.16"
[dependencies.lexe-sha256]
version = "0.1.15"
version = "0.1.16"
[dependencies.lexe-std]
version = "0.1.15"
version = "0.1.16"
features = ["ref-cast"]

@@ -213,7 +213,7 @@

[dev-dependencies.lexe-crypto]
version = "0.1.15"
version = "0.1.16"
features = ["test-utils"]
[dev-dependencies.lexe-enclave]
version = "0.1.15"
version = "0.1.16"
features = ["test-utils"]

@@ -220,0 +220,0 @@

@@ -23,3 +23,3 @@ // bearer auth v1

pub enum Error {
#[error("error verifying signed bearer auth request: {0}")]
#[error("Error verifying signed bearer auth request: {0}")]
UserVerifyError(#[source] ed25519::Error),

@@ -30,21 +30,24 @@

#[error("issued timestamp is too far from current auth server clock")]
#[error("Issued timestamp is too far from current auth server clock")]
ClockDrift,
#[error("auth token or auth request is expired")]
#[error("Auth token or auth request is expired")]
Expired,
#[error("timestamp is not a valid unix timestamp")]
#[error("Auth token is not valid yet")]
NotYetValid,
#[error("Timestamp is not a valid unix timestamp")]
InvalidTimestamp,
#[error("requested token lifetime is too long")]
#[error("Requested token lifetime is too long")]
InvalidLifetime,
#[error("user not signed up yet")]
#[error("User not signed up yet")]
NoUser,
#[error("bearer auth token is not valid base64")]
#[error("Bearer auth token is not valid base64")]
Base64Decode,
#[error("bearer auth token was not provided")]
#[error("Bearer auth token was not provided")]
Missing,

@@ -55,6 +58,9 @@

#[error(
"auth token's granted scope ({granted:?}) is not sufficient for \
"Auth token's granted scope ({granted:?}) is not sufficient for \
requested scope ({requested:?})"
)]
InsufficientScope { granted: Scope, requested: Scope },
InsufficientScope {
granted: LexeScope,
requested: LexeScope,
},
}

@@ -133,7 +139,6 @@

/// The allowed API scope for the bearer auth token. If unset, the issued
/// token currently defaults to [`Scope::All`].
/// The [`LexeScope`] requested for the new bearer auth token.
// TODO(phlip9): implement proper scope attenuation from identity's allowed
// scopes
pub scope: Option<Scope>,
pub scope: LexeScope,
}

@@ -167,15 +172,38 @@

v1: BearerAuthRequestWireV1,
scope: Option<Scope>,
// node-v0.7.9 added this field as `Option` along with the V2 wire format.
//
// We must keep this `Option` so that we can continue deserializing those
// older `None` requests (and assume `LexeScope::All` in such a case);
// current clients always send `Some`.
scope: Option<LexeScope>,
}
/// The allowed API scope for the bearer auth token.
/// An infra-level scope which gates a bearer auth token's access to Lexe-run
/// services and resources.
///
/// This is distinct from the *application-level* authorization that determines
/// which node endpoints a given client credential may call; that lives with the
/// revocable client machinery, not here. A `LexeScope` answers "what may this
/// token do against *Lexe's* infrastructure", e.g. the backend or the gateway
/// CONNECT proxy.
///
/// Scopes form a lattice: a token granted a broader scope is accepted wherever
/// a narrower scope is required (see [`LexeScope::has_permission_for`]).
#[cfg_attr(any(test, feature = "test-utils"), derive(Arbitrary))]
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum Scope {
/// The token is valid for all scopes.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum LexeScope {
/// Full access to all Lexe-run services. Short-lived (max 1 hour).
All,
/// The token is only allowed to connect to a user node via the gateway.
/// Authorizes the gateway to act as the user's proxy, in either of two
/// ways:
/// - a CONNECT tunnel to the user's own node, or
/// - a request the gateway makes to the backend (`AppBackendApi`) on the
/// user's behalf, using its own backend credentials.
///
/// This grants neither direct backend access nor forwarding of this token
/// to the backend; that's [`LexeScope::All`]. May be long-lived (max 20
/// years), so it can back a long-lived client credential.
// TODO(phlip9): should be a fine-grained scope
NodeConnect,
GatewayProxy,
//

@@ -245,3 +273,3 @@ // // TODO(phlip9): fine-grained scopes?

// ownership of a user_pk.
ed25519::verify_signed_struct(ed25519::accept_any_signer, serialized)
ed25519::verify::signed_struct_by_any_signer(serialized)
.map_err(Error::UserVerifyError)

@@ -271,3 +299,3 @@ }

token_lifetime_secs: u32,
scope: Option<Scope>,
scope: LexeScope,
) -> Self {

@@ -299,11 +327,14 @@ Self {

match wire {
// V1 predates scopes; fall back to the broadest scope for these
// (very old) clients.
BearerAuthRequestWire::V1(v1) => Self {
request_timestamp_secs: v1.request_timestamp_secs,
lifetime_secs: v1.lifetime_secs,
scope: None,
scope: LexeScope::All,
},
// A V2 client that omits the scope likewise defaults to `All`.
BearerAuthRequestWire::V2(v2) => Self {
request_timestamp_secs: v2.v1.request_timestamp_secs,
lifetime_secs: v2.v1.lifetime_secs,
scope: v2.scope,
scope: v2.scope.unwrap_or(LexeScope::All),
},

@@ -321,3 +352,3 @@ }

},
scope: req.scope,
scope: Some(req.scope),
})

@@ -335,3 +366,3 @@ }

// of a user_pk.
ed25519::verify_signed_struct(ed25519::accept_any_signer, serialized)
ed25519::verify::signed_struct_by_any_signer(serialized)
.map_err(Error::UserVerifyError)

@@ -401,13 +432,11 @@ }

// --- impl Scope --- //
// --- impl LexeScope --- //
impl Scope {
/// Returns `true` if the `requested_scope` is allowed by this granted
/// scope.
pub fn has_permission_for(&self, requested_scope: &Self) -> bool {
let granted_scope = self;
match (granted_scope, requested_scope) {
(Scope::All, _) => true,
(Scope::NodeConnect, Scope::All) => false,
(Scope::NodeConnect, Scope::NodeConnect) => true,
impl LexeScope {
/// Returns `true` if this granted scope covers the `requested` scope.
pub fn has_permission_for(&self, requested: &Self) -> bool {
match (self, requested) {
(LexeScope::All, _) => true,
(LexeScope::GatewayProxy, LexeScope::All) => false,
(LexeScope::GatewayProxy, LexeScope::GatewayProxy) => true,
}

@@ -472,3 +501,3 @@ }

},
scope: Some(Scope::NodeConnect),
scope: Some(LexeScope::GatewayProxy),
});

@@ -480,3 +509,3 @@ bcs_roundtrip_ok(&hex::decode(input).unwrap(), &req);

fn test_auth_scope_canonical() {
bcs_roundtrip_proptest::<Scope>();
bcs_roundtrip_proptest::<LexeScope>();
}

@@ -487,7 +516,7 @@

let input = b"\x00";
let scope = Scope::All;
let scope = LexeScope::All;
bcs_roundtrip_ok(input, &scope);
let input = b"\x01";
let scope = Scope::NodeConnect;
let scope = LexeScope::GatewayProxy;
bcs_roundtrip_ok(input, &scope);

@@ -494,0 +523,0 @@ }

@@ -16,3 +16,6 @@ //! Information about a client

use crate::{
api::{auth::Scope, user::UserPk},
api::{
auth::{BearerAuthToken, LexeScope},
user::UserPk,
},
time::TimestampMs,

@@ -76,3 +79,3 @@ };

// TODO(max): This scope is currently ineffective.
pub scope: Scope,
pub scope: LexeScope,
/// Whether this client has been revoked. Revocation is permanent.

@@ -123,3 +126,3 @@ pub is_revoked: bool,

/// The authorization scopes allowed for this client.
pub scope: Scope,
pub scope: LexeScope,
}

@@ -137,2 +140,3 @@

pub pubkey: ed25519::PublicKey,
/// When this client was created.

@@ -156,2 +160,7 @@ pub created_at: TimestampMs,

pub rev_client_cert_key_der: Vec<u8>,
/// A long-lived [`LexeScope::GatewayProxy`] token for connecting to the
/// user's node via the gateway proxy. Always `Some` for user nodes.
#[serde(skip_serializing_if = "Option::is_none")]
pub gateway_proxy_token: Option<BearerAuthToken>,
}

@@ -184,3 +193,3 @@

#[serde(skip_serializing_if = "none")]
pub scope: Option<Scope>,
pub scope: Option<LexeScope>,

@@ -288,3 +297,3 @@ /// Set this to revoke or unrevoke the client. Revocation is permanent, so

label: Some("deez".to_string()),
scope: Scope::All,
scope: LexeScope::All,
is_revoked: false,

@@ -291,0 +300,0 @@ };

@@ -249,3 +249,3 @@ use std::{collections::HashSet, fmt, str::FromStr};

fn from(pk: ed25519::PublicKey) -> Self {
Self::new(pk.into_inner())
Self::new(pk.to_array())
}

@@ -252,0 +252,0 @@ }

@@ -81,3 +81,5 @@ use std::{include_bytes, time::Duration};

/// The maximum amount of liquidity that Lexe will supply to a user in one tx.
pub const MAX_LIQUIDITY_SAT: u32 = 10_000_000; // 0.1 BTC
//
// TODO(phlip9): increase once new liquidity model is in
pub const MAX_LIQUIDITY_SAT: u32 = 1_000_000; // 0.01 BTC

@@ -100,6 +102,21 @@ /// User nodes and the LSP will reject new inbound channels with total channel

/// Unconditional extra fee the LSP<->user channel funder will pay for
/// coop-close in order to avoid a potential force-close due to fee
/// disagreement.
///
/// During modern "legacy" (not "simple_close") coop-close, the channel funder
/// proposes a `[min fee, max fee]` range that it's willing to pay. An LDK
/// counterparty then chooses the `max_fee`.
///
/// An LDK funder determines the `max_fee` by estimating the feerate for
/// [`ConfirmationTarget::NonAnchorChannelFee`] plus this
/// `FORCE_CLOSE_AVOIDANCE_MAX_FEE_SATS` value.
///
/// 2026-06-24: Prior to this date, this was 1000 sats, which meant all our
/// LSP<->User coop-closes overpaid on-chain fees by ~7-8x market rate.
///
/// See: [`lightning::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis`]
//
// 1,000 sats = $1.00 assuming $100k/BTC
pub const FORCE_CLOSE_AVOIDANCE_MAX_FEE_SATS: u64 = 1_000;
///
/// [`ConfirmationTarget::NonAnchorChannelFee`]: lightning::chain::chaininterface::ConfirmationTarget::NonAnchorChannelFee
pub const FORCE_CLOSE_AVOIDANCE_MAX_FEE_SATS: u64 = 50;

@@ -106,0 +123,0 @@ // --- Persistence --- //

@@ -8,2 +8,3 @@ use std::{fmt, num::NonZeroU32, str::FromStr};

};
use lexe_byte_array::ByteArray;
use lexe_crypto::{

@@ -201,3 +202,3 @@ aes::{self, AesMasterKey},

pub fn derive_user_pk(&self) -> UserPk {
UserPk::new(self.derive_user_key_pair().public_key().into_inner())
UserPk::new(self.derive_user_key_pair().public_key().to_array())
}

@@ -204,0 +205,0 @@

@@ -69,2 +69,10 @@ //! This module contains [`Arbitrary`]-like [`Strategy`]s for generating various

/// Like [`any_string`], but bounds the UTF-8 byte length to `max_bytes`.
pub fn any_bounded_string(max_bytes: usize) -> impl Strategy<Value = String> {
any_string().prop_map(move |mut s| {
lexe_std::string::truncate_bytes(&mut s, max_bytes);
s
})
}
/// An [`Option`] version of [`any_string`].

@@ -71,0 +79,0 @@ ///

@@ -170,3 +170,4 @@ use std::{

let (ser_value, signed_value) = key_pair.sign_struct(&value).unwrap();
let signed_value2 = pubkey.verify_self_signed_struct(&ser_value).unwrap();
let signed_value2 =
ed25519::verify::signed_struct_by_signer(pubkey, &ser_value).unwrap();
let (ser_value2, _) = key_pair.sign_struct(signed_value2.inner()).unwrap();

@@ -173,0 +174,0 @@

Sorry, the diff of this file is not supported yet