krusty-kms-client 0.3.0

Starknet RPC client for interacting with TONGO contracts
Documentation
# Starknet Client

Starknet RPC client for interacting with TONGO contracts on Starknet.

## ✅ Implemented Features

### Core Infrastructure
- **Starknet RPC provider creation** - JSON-RPC client setup
-**Account address derivation** - OpenZeppelin account address calculation
-**ElGamal decryption** - Decrypt cipher balances from chain
-**Proof generation** - Full parity with TypeScript for Fund, Transfer, Rollover, Withdraw
-**Integration test skeleton** - Complete flow documentation with TypeScript parity

### Key Management
- **BIP-44 key derivation** - TONGO coin type 5454 and Starknet coin type 9004
-**Public key derivation** - Elliptic curve scalar multiplication
-**Account address calculation** - Pedersen hash + Starknet Keccak

### Cryptographic Primitives
- **Proof of Exponentiation (PoE)** - Schnorr-like proofs for balances
-**Proof of Exponentiation 2 (PoE2)** - Okamoto's protocol for rollovers
-**ElGamal encryption** - Homomorphic encryption for transfers
-**Fiat-Shamir challenges** - Non-interactive proof generation

## 🚧 To Be Implemented

The following components require integration with the live Starknet network:

1. **RPC State Querying** - Fetch encrypted balances from TONGO contract
2. **Transaction Signing** - Sign and submit transactions using starknet-rust
3. **Calldata Serialization** - Convert Rust proofs to Cairo calldata format
4. **ERC20 Approve Flow** - Token approval before fund operations
5. **State Verification** - Query and decrypt state after transactions

## Account Derivation

The crate supports deriving Starknet account contract addresses using the standard contract address calculation formula:

```rust
use krusty_kms::{derive_keypair, derive_oz_account_address};
use starknet_types_core::felt::Felt;

// Derive a keypair from mnemonic
let keypair = derive_keypair(mnemonic, index, account_index, None)?;

// Get the public key x-coordinate
let affine = keypair.public_key.to_affine()?;
let public_key_x = affine.x();

// Calculate the account contract address
let class_hash = Felt::from_hex("0x05b4b537eaa2399e3aa99c4e2e0208ebd6c71bc1467938cd52c798c601e43564")?;
let account_address = derive_oz_account_address(&public_key_x, &class_hash, None)?;
```

## Testing

Run the account derivation tests:

```bash
cargo test -p krusty-kms-client --test account_derivation
```

## Next Steps

To complete the integration with Starknet:

### 1. Add TONGO Contract Interactions

Create a `TongoClient` struct that wraps the starknet provider and provides high-level methods:

```rust
pub struct TongoClient {
    provider: JsonRpcClient<HttpTransport>,
    contract_address: Felt,
}

impl TongoClient {
    pub async fn fund(&self, account: &TongoAccount, amount: u128) -> Result<TransactionHash>;
    pub async fn transfer(&self, account: &TongoAccount, to: &ProjectivePoint, amount: u128) -> Result<TransactionHash>;
    pub async fn rollover(&self, account: &TongoAccount) -> Result<TransactionHash>;
    pub async fn withdraw(&self, account: &TongoAccount, to: &Felt, amount: u128) -> Result<TransactionHash>;
    pub async fn get_state(&self, public_key: &ProjectivePoint) -> Result<TongoState>;
}
```

### 2. Implement Account Signer

Add utilities for signing transactions using derived keys:

```rust
use starknet_rust::accounts::{Account, SingleOwnerAccount};
use starknet_rust::signers::{LocalWallet, SigningKey};

pub fn create_signer(
    provider: JsonRpcClient<HttpTransport>,
    private_key: &Felt,
    address: &Felt,
    chain_id: Felt,
) -> SingleOwnerAccount<JsonRpcClient<HttpTransport>, LocalWallet> {
    let signer = LocalWallet::from(SigningKey::from_secret_scalar(private_key));
    SingleOwnerAccount::new(provider, signer, *address, chain_id)
}
```

### 3. Add Integration Tests

Create tests that replicate the TypeScript `tongo-sepolia.test.ts`:

```rust
#[tokio::test]
#[ignore] // Requires Sepolia testnet access
async fn test_fund_operation() {
    let provider = create_provider(SEPOLIA_RPC_URL);
    let tongo_client = TongoClient::new(provider, TONGO_CONTRACT_ADDRESS);

    // Derive TONGO keypair
    let keypair = derive_keypair(MNEMONIC, 0, 0, None)?;
    let account = TongoAccount::from_private_key(keypair.private_key, TONGO_CONTRACT_ADDRESS)?;

    // Check initial balance
    let state_before = tongo_client.get_state(&account.keypair.public_key).await?;

    // Fund operation
    let tx_hash = tongo_client.fund(&account, 1).await?;
    provider.wait_for_transaction(tx_hash).await?;

    // Verify balance increased
    let state_after = tongo_client.get_state(&account.keypair.public_key).await?;
    assert_eq!(state_after.balance, state_before.balance + 1);
}
```

## OpenZeppelin Account Class Hash

The tests use the OpenZeppelin account class hash deployed on Sepolia:

```
0x05b4b537eaa2399e3aa99c4e2e0208ebd6c71bc1467938cd52c798c601e43564
```

This is the same class hash used in the TypeScript reference implementation.

## TONGO Contract Address (Sepolia)

```
0x00b4cca30f0f641e01140c1c388f55641f1c3fe5515484e622b6cb91d8cee585
```

## Related Crates

- `krusty-kms`: Key derivation and account address calculation
- `krusty-kms-sdk`: TONGO operation proof generation
- `krusty-kms-crypto`: Cryptographic primitives (PoE, PoE2, ElGamal)