fix: zero-amount invoices, identity.verify DID extraction, tor service permissions
- Allow zero-amount Lightning invoices (BOLT11 "any amount") by changing validation from amount_sats < 1 to amount_sats < 0 - identity.verify now extracts pubkey directly from did:key format instead of requiring the DID to belong to a local identity - tor.create-service writes config to data_dir/tor-config/ instead of /var/lib/archipelago/tor/ (owned by debian-tor, not archipelago user) - Add E2E test script (scripts/run-e2e-tests.sh) covering 47 RPC endpoints - Add testing plan with results (loop/testing.md) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
e3aa95a103
commit
0cf71c4115
@@ -212,17 +212,10 @@ impl IdentityManager {
|
||||
}
|
||||
|
||||
/// Verify a signature against a DID's public key.
|
||||
/// The DID must belong to an identity managed by this node.
|
||||
/// Works for any valid did:key (not just local identities).
|
||||
pub async fn verify(&self, did: &str, data: &[u8], sig_hex: &str) -> Result<bool> {
|
||||
// Find identity by DID
|
||||
let (identities, _) = self.list().await?;
|
||||
let identity = identities
|
||||
.iter()
|
||||
.find(|i| i.did == did)
|
||||
.ok_or_else(|| anyhow::anyhow!("No identity found for DID: {}", did))?;
|
||||
|
||||
let pubkey_bytes = hex::decode(&identity.pubkey_hex)
|
||||
.context("Invalid pubkey hex")?;
|
||||
// Extract pubkey from did:key directly — no local lookup needed
|
||||
let pubkey_bytes = pubkey_bytes_from_did_key(did)?;
|
||||
let verifying_key = VerifyingKey::from_bytes(
|
||||
pubkey_bytes
|
||||
.as_slice()
|
||||
@@ -294,6 +287,25 @@ impl IdentityManager {
|
||||
|
||||
// --- internal helpers ---
|
||||
|
||||
}
|
||||
|
||||
/// Extract Ed25519 pubkey bytes from a did:key string.
|
||||
/// Format: did:key:z<base58btc(0xed01 + 32-byte-pubkey)>
|
||||
fn pubkey_bytes_from_did_key(did: &str) -> Result<Vec<u8>> {
|
||||
let z_part = did
|
||||
.strip_prefix("did:key:z")
|
||||
.ok_or_else(|| anyhow::anyhow!("Invalid did:key format: {}", did))?;
|
||||
let decoded = bs58::decode(z_part)
|
||||
.into_vec()
|
||||
.context("Invalid base58 in did:key")?;
|
||||
if decoded.len() != 34 || decoded[0] != 0xed || decoded[1] != 0x01 {
|
||||
return Err(anyhow::anyhow!("Invalid Ed25519 did:key multicodec prefix"));
|
||||
}
|
||||
Ok(decoded[2..].to_vec())
|
||||
}
|
||||
|
||||
impl IdentityManager {
|
||||
|
||||
async fn get_default_id(&self) -> Option<String> {
|
||||
let marker = self.identities_dir.join(DEFAULT_MARKER);
|
||||
fs::read_to_string(&marker).await.ok().map(|s| s.trim().to_string())
|
||||
|
||||
Reference in New Issue
Block a user