Skip to content

Commit 84c6dd8

Browse files
authored
Refactor transport part 1 (#715)
* Copilot instructions * Refactor message payload to borsh * Move and rename module * Refactor imports * Cleanup todos * Review fixes, serialization improvements, cleanup * All protocol serialization with borsh and base58.
1 parent b8f47ed commit 84c6dd8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+665
-250
lines changed

.github/copilot-instructions.md

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
# Copilot Instructions for E-Bills Project
2+
3+
## Project Overview
4+
5+
**E-Bills** is a Rust-based project for the Bitcredit E-Bills system, primarily targeting **WebAssembly (WASM)** as the main execution environment. The project provides a core API for managing electronic bills with Bitcoin integration, Nostr-based transport, and SurrealDB persistence.
6+
7+
## Project Structure
8+
9+
This is a Rust workspace with the following crates:
10+
11+
- **`bcr-ebill-core`** - Core data models, validation logic, and traits for bills, contacts, companies, and blockchain operations
12+
- **`bcr-ebill-persistence`** - Persistence traits and SurrealDB implementation (uses IndexedDB in WASM)
13+
- **`bcr-ebill-transport`** - Network transport API traits with Nostr protocol implementation
14+
- **`bcr-ebill-api`** - Main business logic and service layer integrating all components
15+
- **`bcr-ebill-wasm`** - **Primary entrypoint** - WASM bindings and JavaScript/TypeScript API surface
16+
17+
### Key Dependencies
18+
19+
- Bitcoin operations: `bitcoin`, `bip39`, `miniscript`, `secp256k1`
20+
- WASM integration: `wasm-bindgen`, `tsify`, `serde-wasm-bindgen`
21+
- Transport: `nostr`, `nostr-sdk` (for decentralized communication)
22+
- Database: `surrealdb` (IndexedDB for WASM, other backends for native)
23+
- Async runtime: `tokio` and `tokio_with_wasm` for cross-platform async support
24+
- Internal dependencies: `bcr-common`, `bcr-wallet-lib` (from BitcreditProtocol organization)
25+
26+
## Architecture Principles
27+
28+
### WASM-First Design
29+
30+
1. **Target Environment**: The primary execution environment is WebAssembly running in browsers
31+
2. **Database**: Uses IndexedDB via SurrealDB in WASM builds (`indxdb://default` connection string)
32+
3. **Platform Abstraction**: Code must work in both single-threaded (WASM) and multi-threaded environments
33+
- Use `ServiceTraitBounds` trait for platform-specific trait bounds
34+
- `Send + Sync` on native, no bounds on `wasm32`
35+
4. **Async Runtime**: Use `tokio_with_wasm` for WASM compatibility, `tokio` for native
36+
37+
### Core Architecture Layers
38+
39+
```
40+
┌─────────────────────────────────────┐
41+
│ bcr-ebill-wasm (WASM API) │ ← TypeScript bindings, JS interface
42+
├─────────────────────────────────────┤
43+
│ bcr-ebill-api (Business Logic) │ ← Services, orchestration
44+
├─────────────────────────────────────┤
45+
│ bcr-ebill-transport (Nostr) │ ← Network communication
46+
│ bcr-ebill-persistence (DB) │ ← Data storage
47+
├─────────────────────────────────────┤
48+
│ bcr-ebill-core (Domain Models) │ ← Core types, validation
49+
└─────────────────────────────────────┘
50+
```
51+
52+
## Key Concepts
53+
54+
### Bill Lifecycle
55+
56+
E-Bills follow a complex state machine with multiple roles:
57+
- **Drawer**: Bill issuer
58+
- **Payer**: Bill drawee (who pays)
59+
- **Holder**: Current bill holder (payee or endorsee)
60+
- **Contingent**: Guarantee chain participant
61+
- **Recoursee**: Participant being recoursed against
62+
- **Buyer**: User to sell bill to
63+
64+
### Bill States
65+
66+
Bills have multi-dimensional states:
67+
1. **Acceptance State**: requested → accepted/rejected/expired
68+
2. **Payment State**: requested → paid/rejected/expired
69+
3. **Recourse States**: List of recourse transactions (latest first)
70+
4. **Sell States**: List of sale transactions (latest first)
71+
5. **Mint State**: Whether bill was minted
72+
73+
See `docs/concepts.md` for detailed state machine documentation.
74+
75+
### Blockchain Structure
76+
77+
Bills use a blockchain-like structure with blocks representing actions. Each action creates a new block in the bill's chain.
78+
79+
## Development Guidelines
80+
81+
### Code Style
82+
83+
1. **Formatting**: Use `cargo fmt` (configuration in `rustfmt.toml`)
84+
2. **Linting**: Use `cargo clippy` (configuration in `clippy.toml`)
85+
- `too-many-arguments-threshold=200` is configured
86+
3. **Validation**: Implement `Validate` trait for all domain types
87+
4. **Error Handling**: Use `thiserror` for error types, `anyhow` for contexts
88+
89+
### Testing Strategy
90+
91+
- **Core**: Thorough unit tests for validation and blockchain logic
92+
- **Persistence**: Unit tests for database operations
93+
- **Transport**: Unit tests for Nostr communication
94+
- **API**: Integration tests combining components
95+
- **WASM**: Basic wiring tests
96+
97+
Run tests with:
98+
```bash
99+
cargo test # Without logs
100+
RUST_LOG=info cargo test -- --nocapture # With logs
101+
```
102+
103+
### WASM Development
104+
105+
#### Building WASM
106+
107+
```bash
108+
# Development build
109+
wasm-pack build --dev --target web --out-name index ./crates/bcr-ebill-wasm
110+
111+
# Release build (optimized)
112+
wasm-pack build --target web ./crates/bcr-ebill-wasm
113+
```
114+
115+
Or use the justfile:
116+
```bash
117+
just wasm # Development build
118+
```
119+
120+
#### TypeScript Bindings
121+
122+
Use `tsify` for automatic TypeScript generation from Rust types:
123+
124+
**For structs/types:**
125+
```rust
126+
use tsify::Tsify;
127+
128+
#[derive(Tsify, Serialize, Deserialize)]
129+
#[tsify(into_wasm_abi, from_wasm_abi)]
130+
pub struct MyType {
131+
field: String,
132+
}
133+
```
134+
135+
**For API functions:**
136+
```rust
137+
use wasm_bindgen::prelude::*;
138+
139+
#[wasm_bindgen]
140+
impl MyApi {
141+
#[wasm_bindgen(unchecked_return_type = "MyReturnType")]
142+
pub async fn my_function(
143+
&self,
144+
#[wasm_bindgen(unchecked_param_type = "MyParamType")] payload: JsValue,
145+
) -> Result<JsValue> {
146+
let param: MyParamType = serde_wasm_bindgen::from_value(payload)?;
147+
// ... logic
148+
let result = serde_wasm_bindgen::to_value(&response)?;
149+
Ok(result)
150+
}
151+
}
152+
```
153+
154+
**For numeric enums:**
155+
```rust
156+
#[wasm_bindgen]
157+
#[repr(u8)]
158+
#[derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)]
159+
pub enum MyEnum {
160+
Variant1 = 0,
161+
Variant2 = 1,
162+
}
163+
```
164+
165+
**For string-based enums:**
166+
```rust
167+
#[derive(Tsify, Serialize, Deserialize)]
168+
#[tsify(into_wasm_abi, from_wasm_abi)]
169+
pub enum MyEnum {
170+
Variant1,
171+
Variant2,
172+
}
173+
```
174+
175+
#### Testing WASM Locally
176+
177+
```bash
178+
# Build and serve
179+
just wasm
180+
just serve
181+
182+
# Or manually
183+
wasm-pack build --dev --target web ./crates/bcr-ebill-wasm
184+
http-server -g -c-1 -p 8081 ./crates/bcr-ebill-wasm/
185+
```
186+
187+
Access at http://localhost:8081/ and use browser DevTools (Storage tab) to inspect IndexedDB.
188+
189+
### Configuration
190+
191+
WASM apps require initialization with config:
192+
193+
```javascript
194+
let config = {
195+
bitcoin_network: "testnet", // mainnet, testnet, testnet4, regtest
196+
esplora_base_url: "https://esplora.minibill.tech",
197+
nostr_relays: ["wss://bcr-relay-dev.minibill.tech"],
198+
surreal_db_connection: "indxdb://default", // IndexedDB for WASM
199+
data_dir: ".",
200+
job_runner_initial_delay_seconds: 1,
201+
job_runner_check_interval_seconds: 600,
202+
};
203+
204+
await wasm.default();
205+
await wasm.initialize_api(config);
206+
```
207+
208+
## Common Tasks
209+
210+
### Adding a New Feature
211+
212+
1. **Domain Model** (`bcr-ebill-core`): Add types with `Validate` trait
213+
2. **Persistence** (`bcr-ebill-persistence`): Add repository traits and implementations
214+
3. **Transport** (`bcr-ebill-transport`): Add network operations if needed
215+
4. **Business Logic** (`bcr-ebill-api`): Add service methods
216+
5. **WASM API** (`bcr-ebill-wasm`): Expose via WASM bindings with TypeScript types
217+
6. **Tests**: Add unit tests at each layer, integration tests in API
218+
7. **Documentation**: Update relevant docs in `docs/`
219+
220+
### Working with Bills
221+
222+
Bills are central to this system. Key files:
223+
- `crates/bcr-ebill-core/src/bill/` - Bill types and validation
224+
- `crates/bcr-ebill-core/src/blockchain/bill/` - Bill blockchain structure
225+
- `crates/bcr-ebill-api/src/service/` - Bill business logic
226+
227+
### Bitcoin Integration
228+
229+
The project uses Bitcoin for payments. Key considerations:
230+
- Support for multiple networks (mainnet, testnet, testnet4, regtest)
231+
- Esplora integration for blockchain queries
232+
- Miniscript for complex spending conditions
233+
- Payment tracking via mempool and confirmations
234+
235+
### Nostr Transport
236+
237+
Communication uses the Nostr protocol:
238+
- Decentralized relay-based messaging
239+
- NIP-04 and NIP-59 support
240+
- Configured via relay URLs in config
241+
242+
## Build and CI
243+
244+
### Quality Checks
245+
246+
Use the `check` recipe in justfile:
247+
```bash
248+
just check
249+
```
250+
251+
This runs:
252+
1. WASM build
253+
2. Format check (`cargo fmt -- --check`)
254+
3. Compilation check (`cargo check`)
255+
4. All tests (`cargo test --all`)
256+
5. Clippy lints (`cargo clippy --all-targets --all-features -- -D warnings`)
257+
6. Dependency audit (`cargo deny check`)
258+
259+
### CI Pipeline
260+
261+
GitHub Actions workflow (`.github/workflows/`) runs on all branches:
262+
- Format, build, test, lint checks
263+
- Uses GitHub App token for private repo access (bcr-common, bcr-wallet-lib)
264+
- Disk space optimization for limited runners
265+
266+
## Important Patterns
267+
268+
### Platform-Specific Code
269+
270+
```rust
271+
#[cfg(not(target_arch = "wasm32"))]
272+
pub trait ServiceTraitBounds: Send + Sync {}
273+
274+
#[cfg(target_arch = "wasm32")]
275+
pub trait ServiceTraitBounds {}
276+
```
277+
278+
### Validation Pattern
279+
280+
```rust
281+
impl Validate for MyType {
282+
fn validate(&self) -> Result<(), ValidationError> {
283+
// Validation logic
284+
Ok(())
285+
}
286+
}
287+
```
288+
289+
### Error Handling in WASM
290+
291+
```rust
292+
#[derive(Tsify, Serialize)]
293+
#[tsify(into_wasm_abi)]
294+
struct JsErrorData {
295+
error: &'static str,
296+
message: String,
297+
code: u16,
298+
}
299+
```
300+
301+
JavaScript side uses try/catch:
302+
```javascript
303+
try {
304+
let result = await api.someMethod(params);
305+
} catch (error) {
306+
// error has: { error, message, code }
307+
}
308+
```
309+
310+
## Documentation
311+
312+
- `README.md` - Project overview
313+
- `CONTRIBUTING.md` - Links to contribution guidelines
314+
- `docs/index.md` - Documentation index
315+
- `docs/wasm.md` - WASM build and usage guide
316+
- `docs/wasm_configuration.md` - Configuration reference
317+
- `docs/concepts.md` - Bill lifecycle and state machine
318+
- `docs/testing.md` - Testing strategy
319+
- `docs/versioning.md` - Versioning guide
320+
- `docs/wasm_releasing.md` - Release process
321+
322+
## External Resources
323+
324+
- NPM Package: `@bitcredit/bcr-ebill-wasm`
325+
- GitHub Organization: BitcreditProtocol
326+
- Contributing Guidelines: [Google Doc](https://docs.google.com/document/d/18468Jb_PT4Sn1YoiwsEIZmWXUb2opxEQzFyGGnwH5VQ)
327+
328+
## Notes for AI Assistants
329+
330+
1. **WASM is Primary**: Always consider WASM compatibility. Check for `wasm32` target when suggesting async or platform-specific code
331+
2. **Type Safety**: Leverage Rust's type system and `Validate` trait for correctness
332+
3. **TypeScript Bindings**: When modifying WASM API, ensure proper TypeScript type generation using `tsify` or `wasm_bindgen` annotations
333+
4. **Testing**: Add tests at the appropriate layer (unit tests in core/persistence/transport, integration in API)
334+
5. **Documentation**: Bill lifecycle is complex - refer to `docs/concepts.md` for state machine details
335+
6. **Dependencies**: Some deps are from BitcreditProtocol private repos requiring GitHub App authentication
336+
7. **Serialization**: Use `borsh` for internal serialization, `serde_json` for WASM boundaries
337+
8. **Edition**: Project uses Rust 2024 edition

crates/bcr-ebill-api/src/service/bill_service/blocks.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,11 @@ use bcr_ebill_core::{
2020
company::CompanyKeys,
2121
contact::{BillParticipant, ContactType},
2222
identity::IdentityWithAll,
23+
protocol::{CompanyChainEvent, IdentityChainEvent},
2324
util::BcrKeys,
2425
};
2526

26-
use crate::{
27-
data::validate_node_id_network,
28-
service::notification_service::event::{CompanyChainEvent, IdentityChainEvent},
29-
};
27+
use crate::data::validate_node_id_network;
3028

3129
use super::{BillAction, Result, error::Error, service::BillService};
3230

crates/bcr-ebill-api/src/service/bill_service/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ pub enum Error {
3535
#[error("Notification error: {0}")]
3636
Notification(#[from] notification_service::Error),
3737

38+
#[error("Protocol error: {0}")]
39+
Protocol(#[from] bcr_ebill_core::protocol::ProtocolError),
40+
3841
#[error("io error {0}")]
3942
Io(#[from] std::io::Error),
4043

crates/bcr-ebill-api/src/service/bill_service/issue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::{
33
constants::MAX_BILL_ATTACHMENTS,
44
data::validate_node_id_network,
55
get_config,
6-
service::notification_service::event::BillChainEvent,
76
util::{self, file::UploadFileType},
87
};
98
use bcr_ebill_core::{
@@ -17,6 +16,7 @@ use bcr_ebill_core::{
1716
},
1817
contact::{BillAnonParticipant, BillIdentParticipant, BillParticipant},
1918
hash::Sha256Hash,
19+
protocol::BillChainEvent,
2020
util::BcrKeys,
2121
};
2222
use log::{debug, error, info};

crates/bcr-ebill-api/src/service/bill_service/payment.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use super::Result;
22
use super::service::BillService;
3-
use crate::service::{
4-
bill_service::{BillAction, BillServiceApi},
5-
notification_service::event::BillChainEvent,
6-
};
3+
use crate::service::bill_service::{BillAction, BillServiceApi};
74
use bcr_ebill_core::{
85
NodeId,
96
bill::{BillId, BillKeys, BitcreditBill, PaymentState, RecourseReason},
@@ -17,6 +14,7 @@ use bcr_ebill_core::{
1714
company::{Company, CompanyKeys},
1815
contact::{BillAnonParticipant, BillIdentParticipant, BillParticipant},
1916
identity::{Identity, IdentityType, IdentityWithAll},
17+
protocol::BillChainEvent,
2018
util::BcrKeys,
2119
};
2220
use log::{debug, info};

0 commit comments

Comments
 (0)