Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/actions/git-credentials/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: 'Set up git credentials for private UTEXO-Protocol repos'
description: 'Configure git to authenticate with private UTEXO-Protocol repositories'
inputs:
token:
description: 'GitHub PAT with read access to private UTEXO-Protocol repositories'
required: false
default: ''
rgb-lib-token:
description: 'Optional read-only token scoped to UTEXO-Protocol/rgb-lib-bfa'
required: false
default: ''
runs:
using: 'composite'
steps:
- name: Configure git credentials
shell: bash
env:
PRIVATE_REPO_TOKEN: ${{ inputs.token }}
BFA_READ_TOKEN: ${{ inputs.rgb-lib-token }}
run: |
set -euo pipefail
if [[ -z "$PRIVATE_REPO_TOKEN" && -z "$BFA_READ_TOKEN" ]]; then
echo "::error::Private dependency credentials are missing. Configure ORG_READ_TOKEN and/or BFA_READ_TOKEN as described in docs/bfa-ci.txt."
exit 1
fi
if [[ -n "$PRIVATE_REPO_TOKEN" ]]; then
git config --global url."https://x-access-token:${PRIVATE_REPO_TOKEN}@github.com/UTEXO-Protocol/".insteadOf "https://github.com/UTEXO-Protocol/"
fi
if [[ -n "$BFA_READ_TOKEN" ]]; then
git config --global url."https://x-access-token:${BFA_READ_TOKEN}@github.com/UTEXO-Protocol/rgb-lib-bfa.git".insteadOf "https://github.com/UTEXO-Protocol/rgb-lib-bfa.git"
fi
echo "CARGO_NET_GIT_FETCH_WITH_CLI=true" >> "$GITHUB_ENV"
if ! GIT_TERMINAL_PROMPT=0 git -c http.https://github.com/.extraheader= ls-remote --exit-code https://github.com/UTEXO-Protocol/rgb-lib-bfa.git HEAD >/dev/null; then
echo "::error::CI cannot read UTEXO-Protocol/rgb-lib-bfa. Grant this dependency Contents: read access to ORG_READ_TOKEN, or add a BFA_READ_TOKEN secret. See docs/bfa-ci.txt."
exit 1
fi
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ jobs:
steps:
- name: Checkout source code
uses: actions/checkout@v4
- uses: ./.github/actions/git-credentials
with:
token: ${{ secrets.ORG_READ_TOKEN || secrets.RGB_LIB_RUST_LIGHTNING_PAT }}
rgb-lib-token: ${{ secrets.BFA_READ_TOKEN }}
- name: Install Rust ${{ matrix.toolchain }} toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ matrix.toolchain }}
Expand All @@ -47,6 +51,10 @@ jobs:
steps:
- name: Checkout source code
uses: actions/checkout@v4
- uses: ./.github/actions/git-credentials
with:
token: ${{ secrets.ORG_READ_TOKEN || secrets.RGB_LIB_RUST_LIGHTNING_PAT }}
rgb-lib-token: ${{ secrets.BFA_READ_TOKEN }}
- name: Install Rust ${{ env.TOOLCHAIN }} toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile=minimal --default-toolchain ${{ env.TOOLCHAIN }}
Expand Down
17 changes: 17 additions & 0 deletions docs/bfa-ci.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
BFA draft CI

Cargo needs read access to the private UTEXO-Protocol/rgb-lib-bfa repository.
The default GITHUB_TOKEN is limited to the current repository. Configure
ORG_READ_TOKEN with Contents: read access to the private dependencies, or
add a BFA_READ_TOKEN secret scoped to rgb-lib-bfa. The existing
RGB_LIB_RUST_LIGHTNING_PAT is used as a fallback for ORG_READ_TOKEN; it
still needs explicit access to the new dependency. Organization approval
or SSO authorization may be required. Never commit a token.

The credential action verifies access before Cargo starts and fails with
a specific diagnostic for missing or unauthorized credentials. No secrets
are exposed to pull requests from forks. Format checks need no credentials.

All build, lint and formatting checks remain enabled. This dependency
migration does not establish Lightning runtime support in the companion
on-chain Android build.
2 changes: 1 addition & 1 deletion lightning-invoice/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ serde = { version = "1.0", optional = true, default-features = false, features =
bitcoin = { version = "0.32.2", default-features = false, features = ["secp-recovery"] }

# RGB and related
rgb-lib = { git = "https://github.com/UTEXO-Protocol/rgb-lib.git", tag = "v0.3.0-beta.50-bfa", default-features = false }
rgb-lib = { git = "https://github.com/UTEXO-Protocol/rgb-lib-bfa.git", rev = "3f571ac58909400046d69143ebb535f4da1f4d42", default-features = false }

[dev-dependencies]
serde_json = { version = "1"}
Expand Down
3 changes: 2 additions & 1 deletion lightning/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ amplify = "4.8"
bincode = "1.3"
rgb-strict-encoding = "1.0.1"
futures = "0.3"
rgb-lib = { git = "https://github.com/UTEXO-Protocol/rgb-lib.git", tag = "v0.3.0-beta.50-bfa", default-features = false }
rgb-lib = { git = "https://github.com/UTEXO-Protocol/rgb-lib-bfa.git", rev = "3f571ac58909400046d69143ebb535f4da1f4d42", default-features = false }
serde = { version = "^1.0", features = [
"derive",
] }
serde_json = "1.0"
tokio = { version = "1.14.1", features = [
"macros",
"rt-multi-thread",
Expand Down
49 changes: 37 additions & 12 deletions lightning/src/rgb_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use rgb_lib::{
keys::WitnessVersion,
wallet::{
rust_only::{AssetColoringInfo, ColoringInfo},
DatabaseType, OnlineOptions, RgbWalletOpsOffline, SinglesigKeys, Wallet, WalletData,
DatabaseType, IndexerConfig, OnlineOptions, RgbWalletOpsOffline, SinglesigKeys, Wallet,
WalletData,
},
AssetSchema, Assignment, BitcoinNetwork, ConsignmentExt, ContractId, Error as RgbLibError,
Fascia, FileContent, RgbTransfer, WitnessOrd,
Expand All @@ -55,6 +56,8 @@ pub const INDEXER_URL_FNAME: &str = "indexer_url";
/// KVStore configuration key for the Ethereum RPC used to validate BFA funding consignments.
/// Missing or empty values disable BFA support.
pub const ETH_RPC_URL_FNAME: &str = "eth_rpc_url";
/// EVM RPC endpoints by chain ID, serialized as JSON for the current unlock.
pub const EVM_RPC_URLS_FNAME: &str = "evm_rpc_urls";
/// Name of the file containing the account-level xPub of the vanilla-side of the wallet
pub const WALLET_ACCOUNT_XPUB_VANILLA_FNAME: &str = "wallet_account_xpub_vanilla";
/// Name of the file containing the account-level xPub of the colored-side of the wallet
Expand Down Expand Up @@ -195,6 +198,34 @@ fn _get_eth_rpc_url(kv_store: &dyn KVStoreSync) -> Option<String> {
}
}

fn _get_evm_rpc_urls(kv_store: &dyn KVStoreSync) -> HashMap<u64, String> {
match kv_store.read_config(EVM_RPC_URLS_FNAME) {
Ok(value) => serde_json::from_str(&value).expect("invalid EVM RPC map in KVStore"),
Err(e) if e.kind() == io::ErrorKind::NotFound => HashMap::new(),
Err(e) => panic!("cannot read EVM RPC configuration: {e}"),
}
}

/// Construct explicit indexer and EVM options for the protocol-1.0 BFA library.
pub fn rgb_online_options(
indexer_url: String, evm_rpc_urls: HashMap<u64, String>, skip_consistency_check: bool,
) -> OnlineOptions {
let indexer_config =
if indexer_url.starts_with("https://") || indexer_url.starts_with("http://") {
IndexerConfig::Esplora { url: indexer_url }
} else {
IndexerConfig::Electrum { url: indexer_url }
};
OnlineOptions {
indexer_config,
skip_consistency_check,
vanilla_sync_lookback: VANILLA_SYNC_LOOKBACK,
failed_witness_receive_grace_secs: 86400,
proxy_auth_keys: HashMap::new(),
evm_rpc_urls,
}
}

#[cfg(test)]
mod bfa_config_tests {
use super::*;
Expand Down Expand Up @@ -238,7 +269,7 @@ pub fn supported_asset_schemas(bitcoin_network: BitcoinNetwork, bfa: bool) -> Ve

fn _new_rgb_wallet(
data_dir: String, bitcoin_network: BitcoinNetwork, account_xpub_vanilla: String,
account_xpub_colored: String, master_fingerprint: String, reuse_addresses: bool, bfa: bool,
account_xpub_colored: String, master_fingerprint: String, _reuse_addresses: bool, bfa: bool,
) -> Wallet {
let keys = SinglesigKeys {
account_xpub_vanilla,
Expand All @@ -255,7 +286,6 @@ fn _new_rgb_wallet(
database_type: DatabaseType::Sqlite,
max_allocations_per_utxo: 1,
supported_schemas: supported_asset_schemas(bitcoin_network, bfa),
reuse_addresses,
},
keys,
)
Expand All @@ -282,7 +312,7 @@ fn _get_wallet_data(
}

async fn _get_rgb_wallet(ldk_data_dir: &Path, kv_store: &dyn KVStoreSync) -> Wallet {
let bfa = _get_eth_rpc_url(kv_store).is_some();
let bfa = !_get_evm_rpc_urls(kv_store).is_empty();
let (
data_dir,
bitcoin_network,
Expand Down Expand Up @@ -328,7 +358,7 @@ async fn _accept_transfer(
reuse_addresses,
) = _get_wallet_data(ldk_data_dir, kv_store);
let indexer_url = _get_indexer_url(kv_store);
let eth_rpc_url = _get_eth_rpc_url(kv_store);
let evm_rpc_urls = _get_evm_rpc_urls(kv_store);
// the consignment is received from the channel counterparty over the p2p link and written to disk
let consignment_path = ldk_data_dir.join(format!("consignment_{funding_txid}"));
tokio::task::spawn_blocking(move || {
Expand All @@ -339,14 +369,9 @@ async fn _accept_transfer(
account_xpub_colored,
master_fingerprint,
reuse_addresses,
eth_rpc_url.is_some(),
!evm_rpc_urls.is_empty(),
);
let online = wallet.go_online(OnlineOptions {
indexer_url,
skip_consistency_check: true,
vanilla_sync_lookback: VANILLA_SYNC_LOOKBACK,
eth_rpc_url,
})?;
let online = wallet.go_online(rgb_online_options(indexer_url, evm_rpc_urls, true))?;
let (consignment, assignments, media_digests) = wallet.accept_transfer_consignment(
online,
consignment_path,
Expand Down
Loading