lapsecoin 0.8.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lapsecoin-0.8.3/LICENSE +21 -0
- lapsecoin-0.8.3/PKG-INFO +203 -0
- lapsecoin-0.8.3/README.md +174 -0
- lapsecoin-0.8.3/VERSION +1 -0
- lapsecoin-0.8.3/conftest.py +16 -0
- lapsecoin-0.8.3/docs/whitepaper.md +97 -0
- lapsecoin-0.8.3/hook_oqs.py +31 -0
- lapsecoin-0.8.3/lapsecoin.egg-info/PKG-INFO +203 -0
- lapsecoin-0.8.3/lapsecoin.egg-info/SOURCES.txt +164 -0
- lapsecoin-0.8.3/lapsecoin.egg-info/dependency_links.txt +1 -0
- lapsecoin-0.8.3/lapsecoin.egg-info/entry_points.txt +2 -0
- lapsecoin-0.8.3/lapsecoin.egg-info/requires.txt +17 -0
- lapsecoin-0.8.3/lapsecoin.egg-info/top_level.txt +1 -0
- lapsecoin-0.8.3/lapsecoin.svg +3 -0
- lapsecoin-0.8.3/lapsecoin_launcher.py +28 -0
- lapsecoin-0.8.3/main.py +783 -0
- lapsecoin-0.8.3/pyproject.toml +58 -0
- lapsecoin-0.8.3/setup.cfg +4 -0
- lapsecoin-0.8.3/src/api.py +1909 -0
- lapsecoin-0.8.3/src/bip39_english.txt +2048 -0
- lapsecoin-0.8.3/src/block.py +675 -0
- lapsecoin-0.8.3/src/chainstate.py +300 -0
- lapsecoin-0.8.3/src/crypto.py +243 -0
- lapsecoin-0.8.3/src/discovery.py +469 -0
- lapsecoin-0.8.3/src/discovery_dht.py +237 -0
- lapsecoin-0.8.3/src/gossip.py +264 -0
- lapsecoin-0.8.3/src/gui.py +514 -0
- lapsecoin-0.8.3/src/hardware_info.py +31 -0
- lapsecoin-0.8.3/src/http_probe.py +66 -0
- lapsecoin-0.8.3/src/info_probe.py +100 -0
- lapsecoin-0.8.3/src/market.py +1782 -0
- lapsecoin-0.8.3/src/market_routes.py +1079 -0
- lapsecoin-0.8.3/src/mempool.py +216 -0
- lapsecoin-0.8.3/src/node.py +2338 -0
- lapsecoin-0.8.3/src/params.py +169 -0
- lapsecoin-0.8.3/src/peer_udp.py +2089 -0
- lapsecoin-0.8.3/src/peerpool.py +378 -0
- lapsecoin-0.8.3/src/settings.py +320 -0
- lapsecoin-0.8.3/src/singleton_lock.py +113 -0
- lapsecoin-0.8.3/src/state.py +205 -0
- lapsecoin-0.8.3/src/storage.py +416 -0
- lapsecoin-0.8.3/src/swap.py +490 -0
- lapsecoin-0.8.3/src/swap_engine.py +1819 -0
- lapsecoin-0.8.3/src/swap_worker.py +422 -0
- lapsecoin-0.8.3/src/syncer.py +754 -0
- lapsecoin-0.8.3/src/trade_storage.py +437 -0
- lapsecoin-0.8.3/src/trust.py +690 -0
- lapsecoin-0.8.3/src/tx.py +322 -0
- lapsecoin-0.8.3/src/update_check.py +114 -0
- lapsecoin-0.8.3/src/updater.py +389 -0
- lapsecoin-0.8.3/src/upnp.py +78 -0
- lapsecoin-0.8.3/src/vdf.py +172 -0
- lapsecoin-0.8.3/src/version.py +21 -0
- lapsecoin-0.8.3/src/xlm.py +561 -0
- lapsecoin-0.8.3/templates_html/address.html +102 -0
- lapsecoin-0.8.3/templates_html/base.html +468 -0
- lapsecoin-0.8.3/templates_html/block_detail.html +48 -0
- lapsecoin-0.8.3/templates_html/board.html +229 -0
- lapsecoin-0.8.3/templates_html/dashboard.html +209 -0
- lapsecoin-0.8.3/templates_html/distribution.html +37 -0
- lapsecoin-0.8.3/templates_html/error.html +4 -0
- lapsecoin-0.8.3/templates_html/explorer.html +36 -0
- lapsecoin-0.8.3/templates_html/market.html +470 -0
- lapsecoin-0.8.3/templates_html/market_book.html +110 -0
- lapsecoin-0.8.3/templates_html/market_take.html +231 -0
- lapsecoin-0.8.3/templates_html/network.html +592 -0
- lapsecoin-0.8.3/templates_html/odds.html +441 -0
- lapsecoin-0.8.3/templates_html/send.html +215 -0
- lapsecoin-0.8.3/templates_html/settings.html +133 -0
- lapsecoin-0.8.3/templates_html/trades.html +300 -0
- lapsecoin-0.8.3/templates_html/tx_detail.html +27 -0
- lapsecoin-0.8.3/templates_html/whitepaper.html +4 -0
- lapsecoin-0.8.3/tests/test_api.py +933 -0
- lapsecoin-0.8.3/tests/test_block.py +1086 -0
- lapsecoin-0.8.3/tests/test_chainstate.py +416 -0
- lapsecoin-0.8.3/tests/test_crypto.py +333 -0
- lapsecoin-0.8.3/tests/test_discovery.py +67 -0
- lapsecoin-0.8.3/tests/test_discovery_dht.py +67 -0
- lapsecoin-0.8.3/tests/test_e2e_flows.py +232 -0
- lapsecoin-0.8.3/tests/test_gossip.py +639 -0
- lapsecoin-0.8.3/tests/test_hardware_info.py +41 -0
- lapsecoin-0.8.3/tests/test_info_probe.py +106 -0
- lapsecoin-0.8.3/tests/test_integration_block_tx_state.py +192 -0
- lapsecoin-0.8.3/tests/test_main_smoke.py +159 -0
- lapsecoin-0.8.3/tests/test_market.py +1855 -0
- lapsecoin-0.8.3/tests/test_market_routes.py +783 -0
- lapsecoin-0.8.3/tests/test_mempool.py +272 -0
- lapsecoin-0.8.3/tests/test_node.py +2451 -0
- lapsecoin-0.8.3/tests/test_peer_udp.py +1150 -0
- lapsecoin-0.8.3/tests/test_peerpool.py +420 -0
- lapsecoin-0.8.3/tests/test_state.py +363 -0
- lapsecoin-0.8.3/tests/test_storage.py +641 -0
- lapsecoin-0.8.3/tests/test_swap.py +396 -0
- lapsecoin-0.8.3/tests/test_swap_engine.py +2142 -0
- lapsecoin-0.8.3/tests/test_swap_worker.py +666 -0
- lapsecoin-0.8.3/tests/test_syncer.py +606 -0
- lapsecoin-0.8.3/tests/test_trust.py +767 -0
- lapsecoin-0.8.3/tests/test_tx.py +539 -0
- lapsecoin-0.8.3/tests/test_update_check.py +110 -0
- lapsecoin-0.8.3/tests/test_upnp.py +137 -0
- lapsecoin-0.8.3/tests/test_xlm.py +494 -0
- lapsecoin-0.8.3/vendor/README.md +9 -0
- lapsecoin-0.8.3/vendor/force-graph.min.js +5 -0
lapsecoin-0.8.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Victorio Nascimento
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
lapsecoin-0.8.3/PKG-INFO
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lapsecoin
|
|
3
|
+
Version: 0.8.3
|
|
4
|
+
Summary: LapseCoin full node: Falcon-512 post-quantum signatures, a VDF-based consensus clock, and a built-in wallet dashboard.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/Lapsecoin/core
|
|
7
|
+
Project-URL: Repository, https://github.com/Lapsecoin/core
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: argcomplete>=3.2
|
|
12
|
+
Requires-Dist: cachetools>=5.3
|
|
13
|
+
Requires-Dist: chiavdf>=1.1.14
|
|
14
|
+
Requires-Dist: flask>=3.0
|
|
15
|
+
Requires-Dist: flask-limiter>=3.5
|
|
16
|
+
Requires-Dist: liboqs-python>=0.14.0
|
|
17
|
+
Requires-Dist: libtorrent>=2.0.0
|
|
18
|
+
Requires-Dist: markdown>=3.5
|
|
19
|
+
Requires-Dist: msgpack>=1.0
|
|
20
|
+
Requires-Dist: orjson>=3.9
|
|
21
|
+
Requires-Dist: peewee>=3.17
|
|
22
|
+
Requires-Dist: Pillow>=10.0
|
|
23
|
+
Requires-Dist: PyNaCl>=1.5
|
|
24
|
+
Requires-Dist: pystray>=0.19
|
|
25
|
+
Requires-Dist: requests>=2.31
|
|
26
|
+
Requires-Dist: stellar-sdk>=13.0
|
|
27
|
+
Requires-Dist: waitress>=3.0
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
<div align="center">
|
|
31
|
+
<img src="lapsecoin.svg" width="120" alt="LapseCoin logo" />
|
|
32
|
+
|
|
33
|
+
# LapseCoin
|
|
34
|
+
|
|
35
|
+
Peer-to-peer electronic cash, secured by a Verifiable Delay Function instead of proof-of-work mining, with quantum-resistant signatures.
|
|
36
|
+
|
|
37
|
+
[](https://github.com/Lapsecoin/core/releases)
|
|
38
|
+
[](https://lapsenode.vicnas.me/)
|
|
39
|
+
[](docs/whitepaper.md)
|
|
40
|
+
[](#support)
|
|
41
|
+
[](https://discord.gg/FP2d8JmK6r)
|
|
42
|
+
[](https://reddit.com/r/Lapsecoin)
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
**Recommended: use a pre-built release.** Building from source requires native libraries (liboqs, chiavdf) that involve complex C/C++ compilation and can produce DLL or shared library errors depending on your platform. The release binaries on the [releases page](https://github.com/Lapsecoin/core/releases) are self-contained and require no dependencies.
|
|
46
|
+
|
|
47
|
+
Join the [Discord](https://discord.gg/FP2d8JmK6r) for discussions, news, and trades with other coins.
|
|
48
|
+
|
|
49
|
+
## Quick start
|
|
50
|
+
|
|
51
|
+
Grab a binary from the [releases page](https://github.com/Lapsecoin/core/releases), self-contained with no dependencies.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
# Linux # Windows
|
|
55
|
+
chmod +x lapsecoin lapsecoin.exe
|
|
56
|
+
./lapsecoin
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
You'll be prompted for a signing passphrase, then the wallet is at `http://localhost:8335` and the block explorer at `http://localhost:8333`.
|
|
60
|
+
|
|
61
|
+
For headless environments (Docker/systemd/CI, no GUI), set the passphrase non-interactively and pass `--no-gui`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
export LAPSECOIN_PASSPHRASE="your passphrase"
|
|
65
|
+
./lapsecoin --no-gui
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
<details>
|
|
69
|
+
<summary>How consensus works</summary>
|
|
70
|
+
|
|
71
|
+
Most cumulative proven work wins, Bitcoin-style. Two blocks at the same height carry equal work, so that tie goes to the lower VDF output, not to whichever arrived first. A height stays open to a better sibling for a few seconds (`LAPSECOIN_DRAW_WINDOW_SECONDS`) so the comparison can happen; work on the next height never stops meanwhile.
|
|
72
|
+
|
|
73
|
+
Block timing is enforced by a VDF anchored to real elapsed time, believed to have a much smaller hardware-advantage gap than proof-of-work. Transactions are ordinary and plaintext, with sender-bid fees, much like Bitcoin's own. Signatures are FALCON-512 (quantum-resistant). Full spec in [docs/whitepaper.md](docs/whitepaper.md).
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
<details>
|
|
77
|
+
<summary>Running from source</summary>
|
|
78
|
+
|
|
79
|
+
Requires Python 3.11+.
|
|
80
|
+
|
|
81
|
+
**Linux/macOS:**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
curl -fsSL https://raw.githubusercontent.com/Lapsecoin/core/main/scripts/install.sh | bash
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Windows (PowerShell):**
|
|
88
|
+
|
|
89
|
+
```powershell
|
|
90
|
+
irm https://raw.githubusercontent.com/Lapsecoin/core/main/scripts/install.ps1 | iex
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Then: `lapsecoin`. Installs build tools if missing, then the app; falls back to skipping `libtorrent` (with a starter peers list) only if that's what fails.
|
|
94
|
+
</details>
|
|
95
|
+
|
|
96
|
+
<details>
|
|
97
|
+
<summary>Building the binary yourself</summary>
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
pip install pyinstaller cairosvg Pillow miniupnpc
|
|
101
|
+
make linux # on Linux
|
|
102
|
+
make windows # on Windows
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Produces a self-contained binary in `dist/`. Requires cmake, ninja, and a C compiler (on Windows, also liboqs and MSVC redistributables).
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
<details>
|
|
109
|
+
<summary>Updating, and when it isn't optional</summary>
|
|
110
|
+
|
|
111
|
+
A node too old to speak the current wire format is refused at the handshake, so it sits alone mining a chain nobody sees. Old formats aren't carried forever, so some updates are mandatory. The version number says which:
|
|
112
|
+
|
|
113
|
+
| Change | Example | What it means |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| Third number | `0.6.0` to `0.6.1` | Fixes. Update when convenient |
|
|
116
|
+
| Second number | `0.5.1` to `0.6.0` | **Required.** Wire format changed, older nodes are dropped |
|
|
117
|
+
| First number | `0.x` to `1.x` | Consensus break. Required, expect a resync |
|
|
118
|
+
|
|
119
|
+
Alone with no peers after everyone else updated? Check your version first.
|
|
120
|
+
</details>
|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary>Ports and passphrase</summary>
|
|
124
|
+
|
|
125
|
+
| | Port | Interface | Purpose |
|
|
126
|
+
|---|---|---|---|
|
|
127
|
+
| Public | `8333` (`--port`) | `0.0.0.0` | Peer traffic (UDP) and the read-only node UI (TCP). Safe to expose. Send disabled. |
|
|
128
|
+
| Private | `port+2` (`--private-port`) | `127.0.0.1` | Wallet UI. **Never expose.** Full access, including Send. |
|
|
129
|
+
|
|
130
|
+
`port+3` is reserved for the DHT subsystem (libtorrent). Port `18334` is fixed and reserved across every node for same-network peer discovery (broadcast-based, finds other LapseCoin nodes on your LAN automatically regardless of their own port). Don't bind other services to either.
|
|
131
|
+
|
|
132
|
+
The passphrase is required to start the node. By default you're prompted via `getpass` (nothing touches shell history or `ps`). For Docker/systemd/CI, set it non-interactively instead:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
export LAPSECOIN_PASSPHRASE="your passphrase"
|
|
136
|
+
python main.py
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
There is no `--passphrase` flag, since it was removed because it leaked into `ps aux` and shell history.
|
|
140
|
+
|
|
141
|
+
The peer port can be set the same way, which is often easier than a flag in a container or unit file:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
export LAPSECOIN_PORT=8444
|
|
145
|
+
python main.py
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`--port` still wins if you pass it, so the variable sets the default rather than overriding what you typed. The private port follows from it as usual unless you set `--private-port`.
|
|
149
|
+
|
|
150
|
+
The log level can be set the same way:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
export LAPSECOIN_LOG_LEVEL=DEBUG
|
|
154
|
+
python main.py
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`--log-level` still wins if you pass it.
|
|
158
|
+
</details>
|
|
159
|
+
|
|
160
|
+
<details>
|
|
161
|
+
<summary>Settings and environment variables</summary>
|
|
162
|
+
|
|
163
|
+
Node-local settings live on the private wallet UI under **Settings**, and each can also be set by environment variable. The environment wins, so a container or unit file can force a value for one launch without overwriting what's saved; a value set that way shows on the page as forced rather than editable.
|
|
164
|
+
|
|
165
|
+
| Variable | Default | Meaning |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `LAPSECOIN_SWAP_CONFIRM_DEPTH` | `2` | How many blocks must bury a LapseCoin payment before a swap treats it as settled |
|
|
168
|
+
| `LAPSECOIN_SWAP_AUTO_ACCEPT_MIN_TRUST` | `0` | Minimum counterparty trust score for a fill request to auto-accept |
|
|
169
|
+
|
|
170
|
+
**Upgrading from 0.6.2 or earlier with the privacy setting on?** That version created a second key file, `lapsecoin_key.json.privacy`, and advertised its address for peers to pay. Nodes no longer advertise an address at all, so nothing creates or uses that file any more, but yours still exists and may hold what peers already sent it. **Keep it, and back it up.** It is an ordinary key file with its own salt, so the same passphrase opens it on its own whenever you want those funds.
|
|
171
|
+
</details>
|
|
172
|
+
|
|
173
|
+
<details>
|
|
174
|
+
<summary>All CLI options</summary>
|
|
175
|
+
|
|
176
|
+
| Option | Default | Description |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `--host` | `0.0.0.0` | Interface to bind for the public port |
|
|
179
|
+
| `--port` | `8333` | Public port for HTTP API and peer connections |
|
|
180
|
+
| `--private-port` | `port+2` | Private port for wallet UI, always bound to 127.0.0.1 |
|
|
181
|
+
| `--keyfile` | `lapsecoin_key.json` | Path to encrypted keypair |
|
|
182
|
+
| `--db` | `lapsecoin_chain.db` | Path to SQLite chain database |
|
|
183
|
+
| `--peer host:port` | - | Bootstrap peer (repeatable) |
|
|
184
|
+
| `--max-peers` | `125` | Hard cap on peer table size |
|
|
185
|
+
| `--log-level` | `INFO` (or `LAPSECOIN_LOG_LEVEL`) | Verbosity: DEBUG, INFO, WARNING, ERROR. DEBUG adds the HTTP access log |
|
|
186
|
+
| `--no-gui` | off | Headless. Implied when `LAPSECOIN_PASSPHRASE` is set |
|
|
187
|
+
| `--no-update-check` | off | Don't check for new releases |
|
|
188
|
+
| `--update-check-url` | *(project)* | Where to look for the current version |
|
|
189
|
+
| `--releases-url` | *(project)* | Where the update notice points people |
|
|
190
|
+
</details>
|
|
191
|
+
|
|
192
|
+
## Exchanges
|
|
193
|
+
|
|
194
|
+
No LAPSE exchange listings yet.
|
|
195
|
+
|
|
196
|
+
In the meantime, [Discord](https://discord.gg/FP2d8JmK6r) allows direct trades with XLM, as well as the in-app Market (beta). Default rate is 1 XLM for 1000 LAPSE.
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
<div align="center" id="support">
|
|
200
|
+
|
|
201
|
+
**Support the project:** BTC `bc1q8qxvr5zuws78650wz9rgzpqxfx7dqzl38rdtsw`
|
|
202
|
+
|
|
203
|
+
</div>
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="lapsecoin.svg" width="120" alt="LapseCoin logo" />
|
|
3
|
+
|
|
4
|
+
# LapseCoin
|
|
5
|
+
|
|
6
|
+
Peer-to-peer electronic cash, secured by a Verifiable Delay Function instead of proof-of-work mining, with quantum-resistant signatures.
|
|
7
|
+
|
|
8
|
+
[](https://github.com/Lapsecoin/core/releases)
|
|
9
|
+
[](https://lapsenode.vicnas.me/)
|
|
10
|
+
[](docs/whitepaper.md)
|
|
11
|
+
[](#support)
|
|
12
|
+
[](https://discord.gg/FP2d8JmK6r)
|
|
13
|
+
[](https://reddit.com/r/Lapsecoin)
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
**Recommended: use a pre-built release.** Building from source requires native libraries (liboqs, chiavdf) that involve complex C/C++ compilation and can produce DLL or shared library errors depending on your platform. The release binaries on the [releases page](https://github.com/Lapsecoin/core/releases) are self-contained and require no dependencies.
|
|
17
|
+
|
|
18
|
+
Join the [Discord](https://discord.gg/FP2d8JmK6r) for discussions, news, and trades with other coins.
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
Grab a binary from the [releases page](https://github.com/Lapsecoin/core/releases), self-contained with no dependencies.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
# Linux # Windows
|
|
26
|
+
chmod +x lapsecoin lapsecoin.exe
|
|
27
|
+
./lapsecoin
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
You'll be prompted for a signing passphrase, then the wallet is at `http://localhost:8335` and the block explorer at `http://localhost:8333`.
|
|
31
|
+
|
|
32
|
+
For headless environments (Docker/systemd/CI, no GUI), set the passphrase non-interactively and pass `--no-gui`:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
export LAPSECOIN_PASSPHRASE="your passphrase"
|
|
36
|
+
./lapsecoin --no-gui
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
<details>
|
|
40
|
+
<summary>How consensus works</summary>
|
|
41
|
+
|
|
42
|
+
Most cumulative proven work wins, Bitcoin-style. Two blocks at the same height carry equal work, so that tie goes to the lower VDF output, not to whichever arrived first. A height stays open to a better sibling for a few seconds (`LAPSECOIN_DRAW_WINDOW_SECONDS`) so the comparison can happen; work on the next height never stops meanwhile.
|
|
43
|
+
|
|
44
|
+
Block timing is enforced by a VDF anchored to real elapsed time, believed to have a much smaller hardware-advantage gap than proof-of-work. Transactions are ordinary and plaintext, with sender-bid fees, much like Bitcoin's own. Signatures are FALCON-512 (quantum-resistant). Full spec in [docs/whitepaper.md](docs/whitepaper.md).
|
|
45
|
+
</details>
|
|
46
|
+
|
|
47
|
+
<details>
|
|
48
|
+
<summary>Running from source</summary>
|
|
49
|
+
|
|
50
|
+
Requires Python 3.11+.
|
|
51
|
+
|
|
52
|
+
**Linux/macOS:**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
curl -fsSL https://raw.githubusercontent.com/Lapsecoin/core/main/scripts/install.sh | bash
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Windows (PowerShell):**
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
irm https://raw.githubusercontent.com/Lapsecoin/core/main/scripts/install.ps1 | iex
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Then: `lapsecoin`. Installs build tools if missing, then the app; falls back to skipping `libtorrent` (with a starter peers list) only if that's what fails.
|
|
65
|
+
</details>
|
|
66
|
+
|
|
67
|
+
<details>
|
|
68
|
+
<summary>Building the binary yourself</summary>
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
pip install pyinstaller cairosvg Pillow miniupnpc
|
|
72
|
+
make linux # on Linux
|
|
73
|
+
make windows # on Windows
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Produces a self-contained binary in `dist/`. Requires cmake, ninja, and a C compiler (on Windows, also liboqs and MSVC redistributables).
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
<summary>Updating, and when it isn't optional</summary>
|
|
81
|
+
|
|
82
|
+
A node too old to speak the current wire format is refused at the handshake, so it sits alone mining a chain nobody sees. Old formats aren't carried forever, so some updates are mandatory. The version number says which:
|
|
83
|
+
|
|
84
|
+
| Change | Example | What it means |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| Third number | `0.6.0` to `0.6.1` | Fixes. Update when convenient |
|
|
87
|
+
| Second number | `0.5.1` to `0.6.0` | **Required.** Wire format changed, older nodes are dropped |
|
|
88
|
+
| First number | `0.x` to `1.x` | Consensus break. Required, expect a resync |
|
|
89
|
+
|
|
90
|
+
Alone with no peers after everyone else updated? Check your version first.
|
|
91
|
+
</details>
|
|
92
|
+
|
|
93
|
+
<details>
|
|
94
|
+
<summary>Ports and passphrase</summary>
|
|
95
|
+
|
|
96
|
+
| | Port | Interface | Purpose |
|
|
97
|
+
|---|---|---|---|
|
|
98
|
+
| Public | `8333` (`--port`) | `0.0.0.0` | Peer traffic (UDP) and the read-only node UI (TCP). Safe to expose. Send disabled. |
|
|
99
|
+
| Private | `port+2` (`--private-port`) | `127.0.0.1` | Wallet UI. **Never expose.** Full access, including Send. |
|
|
100
|
+
|
|
101
|
+
`port+3` is reserved for the DHT subsystem (libtorrent). Port `18334` is fixed and reserved across every node for same-network peer discovery (broadcast-based, finds other LapseCoin nodes on your LAN automatically regardless of their own port). Don't bind other services to either.
|
|
102
|
+
|
|
103
|
+
The passphrase is required to start the node. By default you're prompted via `getpass` (nothing touches shell history or `ps`). For Docker/systemd/CI, set it non-interactively instead:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
export LAPSECOIN_PASSPHRASE="your passphrase"
|
|
107
|
+
python main.py
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
There is no `--passphrase` flag, since it was removed because it leaked into `ps aux` and shell history.
|
|
111
|
+
|
|
112
|
+
The peer port can be set the same way, which is often easier than a flag in a container or unit file:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
export LAPSECOIN_PORT=8444
|
|
116
|
+
python main.py
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`--port` still wins if you pass it, so the variable sets the default rather than overriding what you typed. The private port follows from it as usual unless you set `--private-port`.
|
|
120
|
+
|
|
121
|
+
The log level can be set the same way:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
export LAPSECOIN_LOG_LEVEL=DEBUG
|
|
125
|
+
python main.py
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`--log-level` still wins if you pass it.
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details>
|
|
132
|
+
<summary>Settings and environment variables</summary>
|
|
133
|
+
|
|
134
|
+
Node-local settings live on the private wallet UI under **Settings**, and each can also be set by environment variable. The environment wins, so a container or unit file can force a value for one launch without overwriting what's saved; a value set that way shows on the page as forced rather than editable.
|
|
135
|
+
|
|
136
|
+
| Variable | Default | Meaning |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| `LAPSECOIN_SWAP_CONFIRM_DEPTH` | `2` | How many blocks must bury a LapseCoin payment before a swap treats it as settled |
|
|
139
|
+
| `LAPSECOIN_SWAP_AUTO_ACCEPT_MIN_TRUST` | `0` | Minimum counterparty trust score for a fill request to auto-accept |
|
|
140
|
+
|
|
141
|
+
**Upgrading from 0.6.2 or earlier with the privacy setting on?** That version created a second key file, `lapsecoin_key.json.privacy`, and advertised its address for peers to pay. Nodes no longer advertise an address at all, so nothing creates or uses that file any more, but yours still exists and may hold what peers already sent it. **Keep it, and back it up.** It is an ordinary key file with its own salt, so the same passphrase opens it on its own whenever you want those funds.
|
|
142
|
+
</details>
|
|
143
|
+
|
|
144
|
+
<details>
|
|
145
|
+
<summary>All CLI options</summary>
|
|
146
|
+
|
|
147
|
+
| Option | Default | Description |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `--host` | `0.0.0.0` | Interface to bind for the public port |
|
|
150
|
+
| `--port` | `8333` | Public port for HTTP API and peer connections |
|
|
151
|
+
| `--private-port` | `port+2` | Private port for wallet UI, always bound to 127.0.0.1 |
|
|
152
|
+
| `--keyfile` | `lapsecoin_key.json` | Path to encrypted keypair |
|
|
153
|
+
| `--db` | `lapsecoin_chain.db` | Path to SQLite chain database |
|
|
154
|
+
| `--peer host:port` | - | Bootstrap peer (repeatable) |
|
|
155
|
+
| `--max-peers` | `125` | Hard cap on peer table size |
|
|
156
|
+
| `--log-level` | `INFO` (or `LAPSECOIN_LOG_LEVEL`) | Verbosity: DEBUG, INFO, WARNING, ERROR. DEBUG adds the HTTP access log |
|
|
157
|
+
| `--no-gui` | off | Headless. Implied when `LAPSECOIN_PASSPHRASE` is set |
|
|
158
|
+
| `--no-update-check` | off | Don't check for new releases |
|
|
159
|
+
| `--update-check-url` | *(project)* | Where to look for the current version |
|
|
160
|
+
| `--releases-url` | *(project)* | Where the update notice points people |
|
|
161
|
+
</details>
|
|
162
|
+
|
|
163
|
+
## Exchanges
|
|
164
|
+
|
|
165
|
+
No LAPSE exchange listings yet.
|
|
166
|
+
|
|
167
|
+
In the meantime, [Discord](https://discord.gg/FP2d8JmK6r) allows direct trades with XLM, as well as the in-app Market (beta). Default rate is 1 XLM for 1000 LAPSE.
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
<div align="center" id="support">
|
|
171
|
+
|
|
172
|
+
**Support the project:** BTC `bc1q8qxvr5zuws78650wz9rgzpqxfx7dqzl38rdtsw`
|
|
173
|
+
|
|
174
|
+
</div>
|
lapsecoin-0.8.3/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.8.3
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "tests"))
|
|
6
|
+
sys.path.insert(0, os.path.dirname(__file__))
|
|
7
|
+
|
|
8
|
+
# block.validate rejects timestamps more than 30s in the future using
|
|
9
|
+
# time.time(). On CI the system clock may be behind the genesis timestamp,
|
|
10
|
+
# causing spurious failures. Patch block._time.time to a fixed value well
|
|
11
|
+
# after genesis so tests are clock-independent.
|
|
12
|
+
import block as _block_mod
|
|
13
|
+
from params import GENESIS_TIMESTAMP
|
|
14
|
+
|
|
15
|
+
_TEST_NOW = GENESIS_TIMESTAMP + 365 * 24 * 3600 # one year after genesis
|
|
16
|
+
patch.object(_block_mod._time, "time", return_value=_TEST_NOW).start()
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# LapseCoin: A Peer-to-Peer Electronic Cash System
|
|
2
|
+
|
|
3
|
+
*Victorio Nascimento*
|
|
4
|
+
|
|
5
|
+
## Abstract
|
|
6
|
+
|
|
7
|
+
LapseCoin keeps Bitcoin's consensus model: the chain with the most proven work wins. Proof-of-work is replaced with a Verifiable Delay Function (VDF), tying block production to real elapsed time rather than a race for a lucky hash. Transactions are ordinary and plaintext, with sender-bid fees, much like Bitcoin's own. The VDF is believed to have a much smaller hardware advantage gap than proof-of-work, so it does not push the network toward the same resource-consumption spiral.
|
|
8
|
+
|
|
9
|
+
## 1. Consensus: Verifiable Delay Functions
|
|
10
|
+
|
|
11
|
+
Each block requires a VDF proof computed over the hash of the previous block and the builder's address. The VDF takes about 120 seconds of strictly sequential computation, and no amount of parallel hardware speeds it up. Binding the builder's address into the challenge stops anyone from copying a broadcast proof and claiming it under their own address: each builder evaluates a different VDF, so a stolen proof verifies against nobody else's challenge.
|
|
12
|
+
|
|
13
|
+
The transaction list is not part of the VDF challenge. A block rejected for a transaction problem can be fixed and rebroadcast without redoing the 120 seconds of work.
|
|
14
|
+
|
|
15
|
+
When two chains compete, the one with more cumulative proven VDF iterations wins, not the one with more blocks. An iteration count only counts if the proof verifies for that many, so it can't be inflated by lying.
|
|
16
|
+
|
|
17
|
+
Ties are routine rather than rare: two builders at the same height do the same protocol-set iteration count, so a plain fork ties exactly, and a tie can run many blocks deep if a competing chain matches the honest one's work all the way down. Ties break on VDF output, never on the block hash: the block hash covers the transaction list, which is not part of the VDF challenge, so a builder could swap transactions for free after the real work and grind hash variants at nearly zero cost, while VDF output can't be moved without redoing the 120 seconds, which keeps the tie-break's cost real. For a single contested height, that height stays open to a lower-output block for a short window after one is adopted, otherwise whatever arrived first wins as soon as anything is built on it and the tie-break decides nothing; work on the next height continues throughout. A tie spanning more than one height is settled the same way at every diverged height, not just the last one: whichever chain has the lower output at more of those heights wins. Deciding a multi-block tie from its final block alone, no matter how deep the tie ran, would have let matching a rival's work over many blocks be undone by out-grinding it at just the last one; requiring a majority of the diverged heights instead means undoing N blocks of tied work costs an advantage sustained over all N of them, the same assumption longest-chain systems already rest on.
|
|
18
|
+
|
|
19
|
+
Rewriting old history means redoing every VDF since that point, sequentially, in as much real time as the honest chain took to produce them. The honest chain keeps advancing the whole time, so the gap only grows.
|
|
20
|
+
|
|
21
|
+
## 2. Why a VDF instead of proof-of-work
|
|
22
|
+
|
|
23
|
+
**Proof-of-work has no ceiling; a VDF has a floor instead.** Hash rate buys share without limit, which is what took Bitcoin from CPUs to ASICs and a growing energy bill. A VDF challenge is one sequential computation, about 120 seconds here, that no amount of hardware shrinks below. Building a block is not about running more attempts in parallel but about how fast a single chain of steps evaluates, and the arithmetic sets a hard floor on that.
|
|
24
|
+
|
|
25
|
+
**The floor still leaves a hardware gap, just a bounded one.** Chia Network's 2019 competition on the same class-group VDF construction found specialized implementations beating commodity software by roughly 3 to 10 times. Unlike ASICs, which widened the lead every generation, that gap caps it. Below the top band a builder does not win a smaller proportional share the way lower hash rate does: it loses outright to any faster builder, having never finished in time to be compared.
|
|
26
|
+
|
|
27
|
+
**Inside the top band it is a lottery, by design.** Builders that finish close together tie, and the tie goes to the lowest VDF output, a value fixed by the previous hash and the builder's address but indistinguishable from random across addresses. Each address completing a full evaluation gets exactly one draw.
|
|
28
|
+
|
|
29
|
+
Nothing limits how many addresses an operator runs, and each needs its own real evaluation with no way to grind for a better one, so N addresses at the top tier win exactly N times the single-address share. Splitting one machine across several addresses does worse, since each fragment then runs too slow to compete. Both results were checked against a Monte Carlo model.
|
|
30
|
+
|
|
31
|
+
**That draw is where Sybil resistance is priced, not a coin fee.** An extra draw costs a full VDF of real machine-time, so participation and its energy scale linearly with spending, as Bitcoin's hash rate does, but without the arms race: a capped hardware gap means spending more mostly buys more whole machines. A coin-denominated registration fee was rejected because the economics track hardware and machine count, not balance, and a fee payable only from a balance would lock out the empty-handed new node this design means to admit.
|
|
32
|
+
|
|
33
|
+
**One Sybil surface sits outside this analysis: eclipse attacks on peer discovery**, where a node's view of the network is crowded out by attacker-controlled addresses. That is handled by capping how many peers from one address subnet a node admits, not by anything priced in coin.
|
|
34
|
+
|
|
35
|
+
## 3. Transactions
|
|
36
|
+
|
|
37
|
+
The base unit is the tick. One LAPSE equals 100,000,000 ticks.
|
|
38
|
+
|
|
39
|
+
A transaction is a plain, visible dict: a sender address, a public key, a list of outputs (recipient and amount), a sequential per-sender nonce, a fee, and a signature, plus an optional short plaintext memo. Nothing about it is encrypted or hidden, the memo included: it is a public note, not a private message.
|
|
40
|
+
|
|
41
|
+
Nonces are sequential per sender, starting from zero: a transaction's nonce must be exactly one more than the sender's last confirmed nonce. This is the standard replay-protection scheme, the same one Bitcoin-style account models use.
|
|
42
|
+
|
|
43
|
+
Fees are chosen by the sender, not fixed by the protocol, with one exception noted in §4. A transaction is valid as long as the sender's balance covers every output plus the fee. Builders are free to prioritize whichever pending transactions pay the most per byte, the same market-based mechanism Bitcoin uses to clear its mempool under load.
|
|
44
|
+
|
|
45
|
+
A block is capped at 2 MB. Bitcoin's own cap is sized for a ten-minute block; this chain's is a fifth of that, so the two carry the same bytes of chain growth per second, not a smaller one.
|
|
46
|
+
|
|
47
|
+
Blocks apply their listed transactions in order, checking each one against the state as it stands after the transactions before it in the same block. There is no required canonical ordering across transactions; a block's builder can list them however it likes, as long as each one is individually valid at the point it is applied.
|
|
48
|
+
|
|
49
|
+
## 4. Fees and block rewards
|
|
50
|
+
|
|
51
|
+
The builder receives the full block reward for every block, unconditionally, plus every transaction fee in that block. There is no split, and no separate party to pay out to.
|
|
52
|
+
|
|
53
|
+
One kind of transaction carries a protocol-enforced minimum on top of the usual sender-bid fee: a post to the public on-chain board, tagged by its memo, must clear a floor that rises in steps as more posts confirm, network-wide, over the board's lifetime, so it cannot be spammed indefinitely at a flat cost. The floor rises slowly enough, relative to how many posts a single block can carry, that it cannot invalidate a block's-worth of already-broadcast posts at once.
|
|
54
|
+
|
|
55
|
+
## 5. Supply
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
reward(block) = floor((21,000,000 LAPSE - total minted) * (1 - 0.5^(1/5,000,000)))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The halflife is about 5,000,000 blocks, roughly 20 years at 2 minutes per block. This smooth curve avoids the instability a hard halving schedule can cause.
|
|
62
|
+
|
|
63
|
+
## 6. Privacy and networking
|
|
64
|
+
|
|
65
|
+
Transactions and blocks both propagate through Dandelion routing, so no observer can reliably tell which peer first broadcast a given item. A block's builder address is public by construction, since that is who gets paid, but which machine produced it need not be. The originator re-sends anything that never comes back, so handing an item to one peer is not a gamble.
|
|
66
|
+
|
|
67
|
+
A node tells its peers nothing about which address it holds. It used to, so that peers could pay it, and that made every peer table a directory mapping an address to the machine that reported it. Where to pay a node now travels as a small note relayed on the same path as everything else, so the peer handing it over is almost never its author and no address is attributable to a machine.
|
|
68
|
+
|
|
69
|
+
Signatures use FALCON-512, a lattice-based scheme designed to resist quantum computers. Addresses are twelve-word phrases derived from the public key.
|
|
70
|
+
|
|
71
|
+
Peers find each other through the BitTorrent DHT. A node only connects to peers sharing its genesis block hash. The full chain is kept forever, so balances can always be recomputed from scratch.
|
|
72
|
+
|
|
73
|
+
## 7. Security and censorship: what this design does and does not solve
|
|
74
|
+
|
|
75
|
+
Consensus here is longest-chain, exactly like Bitcoin's, just measured in proven VDF iterations instead of hashes. That inherits Bitcoin's security model in full, including its limits.
|
|
76
|
+
|
|
77
|
+
Ordinary transaction censorship, a single non-majority actor refusing to include some transaction, is defeated the same way it always has been: any other willing participant can include it instead, and ordinary confirmation-depth economics protect against a brief refusal turning into a permanent one.
|
|
78
|
+
|
|
79
|
+
A sustained majority attacker is a different matter, and this design does not claim to beat Bitcoin there. Fork choice sees only cumulative proven work, and, on an exact tie, which side won more of the diverged heights; it never looks at what a chain contains, so a majority attacker can fork from before a transaction confirmed and build a history that never confirms it, at the cost of an ordinary reorg. No block-level or transaction-level rule stops that, because the attacker breaks no rule; it simply declines to extend the branch it dislikes. That is a property of longest-chain consensus generally, not a gap specific to this design.
|
|
80
|
+
|
|
81
|
+
Other inherited limitations:
|
|
82
|
+
|
|
83
|
+
- As with Bitcoin, a node syncing from scratch cannot cryptographically distinguish the honest chain from an attacker's alternative on its own; it has to trust the network it connects to at least once.
|
|
84
|
+
- Whether VDF-solving hardware availability keeps pace with the network's needs is a market question the protocol cannot guarantee, the same as mining hardware availability is for Bitcoin.
|
|
85
|
+
|
|
86
|
+
## 8. Conclusion
|
|
87
|
+
|
|
88
|
+
LapseCoin keeps Bitcoin's core guarantee: no trust required, everything verifiable, no authority can reverse a transaction. It replaces proof-of-work with a Verifiable Delay Function, which is believed to narrow the hardware-advantage gap that drove proof-of-work's runaway energy use, without needing a separate rule bolted on to achieve that. Transactions stay ordinary and plaintext, with sender-bid fees. Supply is capped at 21 million LAPSE with smooth decay and no halvings. Censorship resistance beyond ordinary confirmation-depth security is not claimed, because no rule at the block or transaction level can give it against a genuine majority attacker in a longest-chain system.
|
|
89
|
+
|
|
90
|
+
## References
|
|
91
|
+
|
|
92
|
+
1. S. Nakamoto, "Bitcoin: A Peer-to-Peer Electronic Cash System," 2008.
|
|
93
|
+
2. NIST, "FIPS 206 (Draft): FN-DSA (FALCON)," 2025.
|
|
94
|
+
3. G. Fanti et al., "Dandelion: Redesigning the Bitcoin Network for Anonymity," 2018.
|
|
95
|
+
4. A. Loewenstern et al., "BEP 44: Storing arbitrary data in the DHT," 2014.
|
|
96
|
+
5. D. Boneh et al., "Verifiable Delay Functions," 2018.
|
|
97
|
+
6. Chia Network, "Chia Network's Proof of Space and Time VDF Competition Results," 2019.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyInstaller runtime hook for oqs (liboqs-python).
|
|
3
|
+
|
|
4
|
+
Pre-loads liboqs via ctypes before oqs imports so it gets the cached
|
|
5
|
+
handle regardless of search path. Works on both Linux and Windows.
|
|
6
|
+
"""
|
|
7
|
+
import ctypes
|
|
8
|
+
import glob
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
if hasattr(sys, "_MEIPASS"):
|
|
13
|
+
meipass = sys._MEIPASS
|
|
14
|
+
|
|
15
|
+
if sys.platform == "win32":
|
|
16
|
+
patterns = ["oqs.dll", "liboqs.dll"]
|
|
17
|
+
else:
|
|
18
|
+
patterns = ["liboqs.so*"]
|
|
19
|
+
|
|
20
|
+
candidates = []
|
|
21
|
+
for pat in patterns:
|
|
22
|
+
candidates += sorted(glob.glob(os.path.join(meipass, pat)))
|
|
23
|
+
|
|
24
|
+
for lib in candidates:
|
|
25
|
+
if os.path.isfile(lib):
|
|
26
|
+
try:
|
|
27
|
+
ctypes.CDLL(lib)
|
|
28
|
+
os.environ["OQS_INSTALL_PATH"] = meipass
|
|
29
|
+
break
|
|
30
|
+
except OSError:
|
|
31
|
+
pass
|