Skip to content
Merged
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
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[workspace]

resolver = "2"
members = [ "client", "protocol", "veritas", "testutil", "wallet"]
members = [ "client", "protocol", "veritas", "testutil", "wallet", "ptr"]
95 changes: 95 additions & 0 deletions SUBSPACES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Guide to Subspaces

## Operating a Space

### 1. Initialize the Space

Initialize your space for operation:

```bash
$ space-cli operate @bitcoin
```

### 2. Issue Subspaces

Use [subs](https://github.com/spacesprotocol/subs) to issue subspaces off-chain and create commitments.


An **end-user** can generate a key pair like this:

```
$ subs request alice@bitcoin
✔ Created handle request
→ alice@bitcoin.req.json
→ Private key saved: alice@bitcoin.priv
```

An **operator** such as @bitcoin, can accept requests into their tree:

```
$ subs add alice@bitcoin.req.json
```


For this example, we will commit just one handle, but it's more efficient to add a large batch of handles before making a commitment.

```
$ subs commit
✔ Committed batch
→ Tree root: 79d39952ac5a8d6daedd48e59c0a58d12d10644c09f2fa3c70e9fe76e72f866a
```


### 3. Submit Commitments

After your tree is updated, commit it's root hash. Each commitment is cryptographically bound to all previous commitments you made on-chain.

**Example:** To submit a commitment for `@bitcoin` with root hash `79d39952ac5a8d6daedd48e59c0a58d12d10644c09f2fa3c70e9fe76e72f866a`:

```bash
$ space-cli commit @bitcoin 79d39952ac5a8d6daedd48e59c0a58d12d10644c09f2fa3c70e9fe76e72f866a
```

**Retrieve commitments** for a space:

```bash
$ space-cli getcommitment @bitcoin
```


### Delegating Operational Control

You can authorize another party to make commitments on your behalf:

```bash
$ space-cli delegate @bitcoin --to <operator-address>
```

## Binding Handles On-Chain

Handles like `alice@bitcoin` are bound to unique script pubkeys off-chain and are designed to remain off-chain by default. However, when on-chain interactivity is required, handles can be bound to UTXOs with minimal on-chain footprint.

### Creating a Space Pointer

Given a handle with its associated script pubkey:

```json
{
"handle": "alice@bitcoin",
"script_pubkey": "5120d3c3196cb3ed7fa79c882ed62f8e5942e546130d5ae5983da67dbb6c9bdd2e79"
}
```

You can create an on-chain identifier that only the controller of the script pubkey can use, without requiring additional metadata on-chain:

```bash
$ space-cli createptr 5120d3c3196cb3ed7fa79c882ed62f8e5942e546130d5ae5983da67dbb6c9bdd2e79
```

This command creates a UTXO with the same script pubkey and "mints" a space pointer (sptr) derived from it:

```
sptr13thcluavwywaktvv466wr6hykf7x5avg49hgdh7w8hh8chsqvwcskmtxpd
```

The space pointer serves as a permanent, transferable on-chain reference for the handle that can be sold and transferred like any other space UTXO.
1 change: 1 addition & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ path = "src/lib.rs"
[dependencies]
spaces_wallet = { path = "../wallet" }
spaces_protocol = { path = "../protocol", version = "*", features = ["std"]}
spaces_ptr = { path = "../ptr" , features = ["std"]}
spacedb = { git = "https://github.com/spacesprotocol/spacedb", version = "0.0.7" }

tokio = { version = "1.37.0", features = ["signal"] }
Expand Down
14 changes: 6 additions & 8 deletions client/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::config::Args;
use crate::rpc::{AsyncChainState, RpcServerImpl, WalletLoadRequest, WalletManager};
use crate::source::{BitcoinBlockSource, BitcoinRpc};
use crate::spaces::Spaced;
use crate::store::LiveSnapshot;
use crate::store::chain::{Chain};
use crate::wallets::RpcWallet;

pub struct App {
Expand All @@ -27,7 +27,7 @@ impl App {
let wallet_service = RpcWallet::service(
spaced.network,
spaced.rpc.clone(),
spaced.chain.state.clone(),
spaced.chain.clone(),
rx,
self.shutdown.clone(),
spaced.num_workers,
Expand All @@ -52,11 +52,11 @@ impl App {
wallets: Arc::new(Default::default()),
};

let chain_state = spaced.chain.clone();
let (async_chain_state, async_chain_state_handle) = create_async_store(
spaced.rpc.clone(),
spaced.anchors_path.clone(),
spaced.chain.state.clone(),
spaced.block_index.as_ref().map(|index| index.state.clone()),
chain_state,
self.shutdown.subscribe(),
)
.await;
Expand Down Expand Up @@ -116,8 +116,7 @@ impl App {
async fn create_async_store(
rpc: BitcoinRpc,
anchors: Option<PathBuf>,
chain_state: LiveSnapshot,
block_index: Option<LiveSnapshot>,
state: Chain,
shutdown: broadcast::Receiver<()>,
) -> (AsyncChainState, JoinHandle<()>) {
let (tx, rx) = mpsc::channel(32);
Expand All @@ -128,8 +127,7 @@ async fn create_async_store(
&client,
rpc,
anchors,
chain_state,
block_index,
state,
rx,
shutdown,
)
Expand Down
Loading
Loading