Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build code from docs #407

Merged
merged 7 commits into from
May 17, 2024
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
31 changes: 28 additions & 3 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ lto = "thin"

[workspace]
resolver = "2"
members = [
members = [
"examples/rust/getting-started",
"libs/gl-client",
"libs/gl-client-py",
"libs/gl-plugin",
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ gen: ${GENALL}
build-self: ensure-docker
cargo build --all
cd libs/gl-client-py; maturin develop
mypy examples/python

check-all: check-self check-self-gl-client check-py

Expand Down Expand Up @@ -150,6 +151,8 @@ cln-versions/lightningd-%.tar.bz2:
cln: ${CLN_TARGETS}

docs:
mypy examples/python
cargo build --manifest-path=./examples/rust/getting-started/Cargo.toml
mkdir -p ${REPO_ROOT}/site/
(cd docs; mkdocs build --strict --clean --site-dir=${REPO_ROOT}/site/ --verbose)
pdoc -o site/py glclient
Expand Down
2 changes: 2 additions & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ markdown_extensions:
- pymdownx.striphtml:
strip_comments: true
strip_js_on_attributes: false
- pymdownx.snippets:
base_path: ["../examples/rust/getting-started/src", "../examples/python/getting-started/"]
theme:
name: material
logo: assets/logo.png
Expand Down
37 changes: 2 additions & 35 deletions docs/src/getting-started/recover.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,12 @@ In order to recover access all you need to do is recover the `seed` from the BIP

=== "Rust"
```rust
use gl_client::{signer::Signer, tls::TlsConfig, scheduler::Scheduler, bitcoin::Network};

let cert = ...; // Your developer certificate (client.crt)
let key = ...; // Your developer key (client-key.pem)
let seed = ...; // Load seed from file

let tls = TlsConfig::new()
.unwrap()
.identity(cert, key);

let signer =
Signer::new(seed, Network::Bitcoin, tls).unwrap();

let scheduler = Scheduler::new(
signer.node_id(),
Network::Bitcoin
)
.await
.unwrap();

let res = scheduler.recover(&signer).await.unwrap();
--8<-- "main.rs:recover_node"
```

=== "Python"
```python
from glclient import Scheduler, Signer, TlsConfig

cert = ... // Your developer certificate
key = ... // Your developer key
seed = ... // Load seed from file

tls = TlsConfig().identity(cert, key);
signer = Signer(seed, network="bitcoin", tls=tls)
scheduler = Scheduler(
node_id=signer.node_id(),
network="bitcoin",
tls=tls,
)
res = scheduler.recover(signer)
--8<-- "main.py:recover_node"
```

Notice that we are using a `TlsConfig` that is not configured with a
nepet marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
96 changes: 15 additions & 81 deletions docs/src/getting-started/register.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ creative way of storing it they can think of.

!!! note
The following code-snippets build on each other. By copying each snippet
after the other you should get a working example.
after the other you should get a working example. See the getting started project in [examples](https://github.com/Blockstream/greenlight/tree/main/examples/rust) to view the code in one file.

=== "Rust"

Expand All @@ -50,35 +50,13 @@ phrase and then convert it into a seed secret we can use:

=== "Rust"
```rust
use bip39::{Mnemonic, Language};

let mut rng = rand::thread_rng();
let m = Mnemonic::generate_in_with(&mut rng, Language::English, 24).unwrap();
let phrase = m.word_iter().fold("".to_string(), |c, n| c + " " + n);

// Prompt user to safely store the phrase

let seed = &m.to_seed("")[0..32]; // Only need the first 32 bytes

let secret = seed[0..32].to_vec();

// Store the seed on the filesystem, or secure configuration system
--8<-- "main.rs:create_seed"
```

=== "Python"

```python
import bip39
import secrets # Make sure to use cryptographically sound randomness

rand = secrets.randbits(256).to_bytes(32, 'big') # 32 bytes of randomness
phrase = bip39.encode_bytes(rand)

# Prompt user to safely store the phrase

seed = bip39.phrase_to_seed(phrase)[:32] # Only need 32 bytes

# Store the seed on the filesystem, or secure configuration system
--8<-- "main.py:create_seed"
```

!!! important
Expand All @@ -87,31 +65,21 @@ phrase and then convert it into a seed secret we can use:
funds on the node will be lost forever! We mean it when we say _you're
the only one with access to the seed_!

## Registering the node
## Initializing the signer

We'll configure mTLS using our developer identity. Any connection using the
`TlsConfig`-object specified below will allow you to register new Greenlight
To initialize a signer we'll first need to configure `Nobody` credentials so we can talk to the scheduler using mTLS. Nobody credentials require data from the files downloaded from the Greenlight Developer Console, so the files must be accessible from wherever the node registration program is run. Any connection using the
nepet marked this conversation as resolved.
Show resolved Hide resolved
`developer_creds` object will allow you to register new Greenlight
nodes.

=== "Rust"
```rust
use gl_client::tls::TlsConfig;

// Creating a new `TlsConfig` object using your developer certificate
// cert: contains the content of `client.crt`
// key: contains the content of `client-key.pem`
let tls = TlsConfig::new().unwrap().identity(cert, key);
--8<-- "main.rs:dev_creds"
```

=== "Python"

```python
from glclient import TlsConfig

# Creating a new `TlsConfig` object using your developer certificate
# - cert: contains the content of `client.crt`
# - key: contains the content of `client-key.pem`
tls = TlsConfig().identity(cert, key)
--8<-- "main.py:dev_creds"
```


Expand All @@ -127,16 +95,12 @@ We'll pick `bitcoin`, because ... reckless 😉

=== "Rust"
```rust
use gl_client::signer::Signer;
use gl_client::bitcoin::Network;
let signer = Signer::new(secret, Network::Bitcoin, tls).unwrap();
--8<-- "main.rs:init_signer"
```

=== "Python"
```python
from glclient import Signer

signer = Signer(seed, network="bitcoin", tls=tls)
--8<-- "main.py:init_signer"
```

[bip39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
Expand All @@ -154,30 +118,12 @@ node's private key. Since the private key is managed exclusively by the

=== "Rust"
```rust
use gl_client::scheduler::Scheduler;
use gl_client::bitcoin::Network;

let scheduler = Scheduler::new(signer.node_id(), Network::Bitcoin).await.unwrap();

// Passing in the signer is required because the client needs to prove
// ownership of the `node_id`
scheduler.register(&signer, None).await.unwrap();

--8<-- "main.rs:register_node"
```

=== "Python"
```python
from glclient import Scheduler

scheduler = Scheduler(
node_id=signer.node_id(),
network="bitcoin",
tls=tls,
)

# Passing in the signer is required because the client needs to prove
# ownership of the `node_id`
res = scheduler.register(signer)
--8<-- "main.py:register_node"
```

The result of `register` contains the credentials that can be used
Expand All @@ -188,25 +134,13 @@ going forward to talk to the scheduler and the node itself.
these credentials can access your node.

=== "Rust"
```
let tls = TlsConfig::new().unwrap().identity(res.device_cert, res.device_key);

// Use the configured `tls` instance when creating `Scheduler` and `Signer`
// instance going forward
let signer = Signer::new(seed.to_vec(), Network::Bitcoin, tls.clone()).unwrap();
let scheduler = Scheduler::with(signer.node_id(), Network::Bitcoin, "uri".to_string(), &tls).await.unwrap();
let mut node: ClnClient = scheduler.schedule(tls.clone()).await.unwrap();
```rust
--8<-- "main.rs:get_node"
```

=== "Python"
```python
tls = TlsConfig().identity(res.device_cert, res.device_key)

# Use the configured `tls` instance when creating `Scheduler` and `Signer`
# instance going forward
signer = Signer(seed, network="bitcoin", tls=tls)
scheduler = Scheduler(node_id=signer.node_id(), network="bitcoin", tls=tls)
node = scheduler.node()
--8<-- "main.py:get_node"
```

If you get an error about a certificate verification failure when
Expand Down
Loading
Loading