diff --git a/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md b/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md
index 48ef052..fb61641 100644
--- a/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md
+++ b/atomic-swaps/configuring-atomic-swaps-in-desktop-wallet.md
@@ -8,117 +8,8 @@ https://www.youtube.com/watch?v=_SOgPybgi8Y&t=504s
Configure your Beam wallet to enable Atomic Swaps by connecting to the node and wallet of the currency you wish to swap. Each currency can link with your Beam wallet via RPC full node or an Electrum wallet.
-## **Connecting to Full Node via Litecoin**
+For detailed instructions on connecting via RPC full node, refer to [RPC Full Node Atomic Swaps Configuration](rpc-full-node-atomic-swaps.md).
-To connect Litecoin with your Beam wallet via full node, follow the steps below:
+For detailed instructions on connecting with an Electrum wallet, refer to [Electrum Atomic Swaps Configuration](electrum-atomic-swaps.md).
-### **Edit Litecoin Configuration File**
-
-Using a text editor, open the `Litecoin.conf` file and enter the following parameters to configure Litecoin to run with JSON RPC:
-
-```
-# server=1 tells Litecoin-QT to accept JSON-RPC commands.
-server=1
-
-rpcport=9432
-
-# You must set rpcuser and rpcpassword to secure the JSON-RPC api
-rpcuser=liteuser
-rpcpassword=123
-```
-
-Save your changes to `Litecoin.conf`.
-
-### Synch Litecoin Node with Beam Wallet
-
-Go to **Settings**.
-
-
-
-### Enter Litecoin Node Address
-
-Under the Litecoin tab, **enter the node ip:port address along with the RPC username and password**. The fee paid on the respective chain per Kb of transaction size can be left at the default value.
-
-**Click Apply > Connect.**
-
-A green light will appear next to **Litecoin Node,** indicating the connection was a success!
-
-
-
-## Connect with Electrum Wallet
-
-If you have an Electrum wallet, connecting to a remote node follows a similar yet more straightforward process:
-
-### Edit Electrum Wallet Settings
-
-1. **Settings****> toggle "Node" to "Electrum."**
-2. Enter your Electrum address.
-3. Enter an existing seed phrase or generate a new one (you can change wallets at any time).
-
-Once connected, you should be able to see the list of all wallet addresses in your Electrum wallet by clicking "Show wallet addresses."\
-
-
-
-
-Once you have optimized and synchronized your nodes in the settings tabs, you will now be able to accept Atomic Swap offers.
-
-
-
-## Connecting to Ethereum
-
-To link your Ethereum and Beam wallets together, you must have an Infura account as well as an Ethereum Metamask.
-
-[Infura](https://infura.io/) is the API service that broadcasts information from the Ethereum blockchain, and [Metamask](https://metamask.io/) is a browser-based Ethereum wallet.
-
-Note: [infura.io](https://www.infura.io) requires specific parameters from your Beam wallet as well as valid email address verification.
-
-
-Before attempting to create an Ethereum <> Beam Atomic Swap make sure your wallet balance has enough Ethereum to cover mining fees.
-
-
-## To connect to Ethereum
-
-1. **Launch** [infura.io.](http://www.infura.io)
-2. Go to **Settings > "keys" > Copy Project ID.**
-3. **Launch** your Beam wallet.
-4. Go to **Settings****> "Connectivity" > "Ethereum" > Paste Project ID.**
-5. **Click "Generate Seed Phrase"** to generate the seed phrase you will import to your Metamask. You can also use an existing seed phrase.
-6. **Copy seed phrase > "apply changes" > "Connect to node."**
-7. **Launch** **Metamask > click "import using account seed phrase."**
-8. Enter your seed phrase and create a strong wallet password.
-
-If you have successfully linked your accounts, a green light will appear next to the Ethereum node indicating the connection was a success!
-
-## **How it looks in your wallet**
-
-### Infura.io
-
-Copy this project ID string.
-
-
-
-### Beam wallet settings
-
-Paste your Infura Preject ID under "Ethereum."
-
-
-
-### Generate a new seed phrase
-
-Click "apply changes" after you have copied your seed phrase.
-
-
-
-### Connect to Ethereum
-
-
-
-### Import Ethereum seed phrase
-
-The next step is to import the Ethereum seed phrase into a Metamask wallet. At the bottom of your Metamask browser extension, click "Import using account seed phrase." Enter your seed phrase and create a password.
-
-
-
-### Atomic Swaps screen
-
-
+For detailed instructions on connecting to Ethereum, refer to [Ethereum Atomic Swaps Configuration](ethereum-atomic-swaps.md).
diff --git a/atomic-swaps/electrum-atomic-swaps.md b/atomic-swaps/electrum-atomic-swaps.md
new file mode 100644
index 0000000..cd0db40
--- /dev/null
+++ b/atomic-swaps/electrum-atomic-swaps.md
@@ -0,0 +1,19 @@
+# Electrum Atomic Swaps Configuration
+
+## Connect with Electrum Wallet
+
+If you have an Electrum wallet, connecting to a remote node follows a similar yet more straightforward process:
+
+### Edit Electrum Wallet Settings
+
+1. **Settings****> toggle "Node" to "Electrum."**
+2. Enter your Electrum address.
+3. Enter an existing seed phrase or generate a new one (you can change wallets at any time).
+
+Once connected, you should be able to see the list of all wallet addresses in your Electrum wallet by clicking "Show wallet addresses."
+
+
+
+Once you have optimized and synchronized your nodes in the settings tabs, you will now be able to accept Atomic Swap offers.
+
+
diff --git a/atomic-swaps/ethereum-atomic-swaps.md b/atomic-swaps/ethereum-atomic-swaps.md
new file mode 100644
index 0000000..705c32a
--- /dev/null
+++ b/atomic-swaps/ethereum-atomic-swaps.md
@@ -0,0 +1,58 @@
+# Ethereum Atomic Swaps Configuration
+
+## Connecting to Ethereum
+
+To link your Ethereum and Beam wallets together, you must have an Infura account as well as an Ethereum Metamask.
+
+[Infura](https://infura.io/) is the API service that broadcasts information from the Ethereum blockchain, and [Metamask](https://metamask.io/) is a browser-based Ethereum wallet.
+
+Note: [infura.io](https://www.infura.io) requires specific parameters from your Beam wallet as well as valid email address verification.
+
+Before attempting to create an Ethereum <> Beam Atomic Swap make sure your wallet balance has enough Ethereum to cover mining fees.
+
+## To connect to Ethereum
+
+1. **Launch** [infura.io.](http://www.infura.io)
+2. Go to **Settings > "keys" > Copy Project ID.**
+3. **Launch** your Beam wallet.
+4. Go to **Settings****> "Connectivity" > "Ethereum" > Paste Project ID.**
+5. **Click "Generate Seed Phrase"** to generate the seed phrase you will import to your Metamask. You can also use an existing seed phrase.
+6. **Copy seed phrase > "apply changes" > "Connect to node."**
+7. **Launch** **Metamask > click "import using account seed phrase."**
+8. Enter your seed phrase and create a strong wallet password.
+
+If you have successfully linked your accounts, a green light will appear next to the Ethereum node indicating the connection was a success!
+
+## How it looks in your wallet
+
+### Infura.io
+
+Copy this project ID string.
+
+
+
+### Beam wallet settings
+
+Paste your Infura Project ID under "Ethereum."
+
+
+
+### Generate a new seed phrase
+
+Click "apply changes" after you have copied your seed phrase.
+
+
+
+### Connect to Ethereum
+
+
+
+### Import Ethereum seed phrase
+
+The next step is to import the Ethereum seed phrase into a Metamask wallet. At the bottom of your Metamask browser extension, click "Import using account seed phrase." Enter your seed phrase and create a password.
+
+
+
+### Atomic Swaps screen
+
+
diff --git a/atomic-swaps/rpc-full-node-atomic-swaps.md b/atomic-swaps/rpc-full-node-atomic-swaps.md
new file mode 100644
index 0000000..1d6417e
--- /dev/null
+++ b/atomic-swaps/rpc-full-node-atomic-swaps.md
@@ -0,0 +1,38 @@
+# RPC Full Node Atomic Swaps Configuration
+
+## Connecting to Full Node via Litecoin
+
+To connect Litecoin with your Beam wallet via full node, follow the steps below:
+
+### Edit Litecoin Configuration File
+
+Using a text editor, open the `Litecoin.conf` file and enter the following parameters to configure Litecoin to run with JSON RPC:
+
+```
+# server=1 tells Litecoin-QT to accept JSON-RPC commands.
+server=1
+
+rpcport=9432
+
+# You must set rpcuser and rpcpassword to secure the JSON-RPC api
+rpcuser=liteuser
+rpcpassword=123
+```
+
+Save your changes to `Litecoin.conf`.
+
+### Synch Litecoin Node with Beam Wallet
+
+Go to **Settings**.
+
+
+
+### Enter Litecoin Node Address
+
+Under the Litecoin tab, **enter the node ip:port address along with the RPC username and password**. The fee paid on the respective chain per Kb of transaction size can be left at the default value.
+
+**Click Apply > Connect.**
+
+A green light will appear next to **Litecoin Node,** indicating the connection was a success!
+
+
diff --git a/core-tech/.gitbook/assets/SimpleTransactionFlow.png b/core-tech/.gitbook/assets/SimpleTransactionFlow.png
deleted file mode 100644
index aa9555f..0000000
Binary files a/core-tech/.gitbook/assets/SimpleTransactionFlow.png and /dev/null differ
diff --git a/core-tech/.gitbook/assets/dmmr1.png b/core-tech/.gitbook/assets/dmmr1.png
deleted file mode 100644
index 8ef38c0..0000000
Binary files a/core-tech/.gitbook/assets/dmmr1.png and /dev/null differ
diff --git a/core-tech/.gitignore b/core-tech/.gitignore
index e69de29..b13ebc3 100644
--- a/core-tech/.gitignore
+++ b/core-tech/.gitignore
@@ -0,0 +1 @@
+.claude/
\ No newline at end of file
diff --git a/core-tech/AVX.md b/core-tech/AVX.md
deleted file mode 100644
index c8e5d52..0000000
--- a/core-tech/AVX.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Advanced Vector Extensions (AVX, also known as Sandy Bridge New Extensions) are extensions to the x86 instruction set architecture for microprocessors from Intel and AMD proposed by Intel in March 2008 and first supported by Intel with the Sandy Bridge processor shipping in Q1 2011 and later on by AMD with the Bulldozer processor shipping in Q3 2011. AVX provides new features, new instructions and a new coding scheme.
-
-For now we separate our builds in two categories:
-* with AVX instructions set
-* without AVX instructions set
-
-If you are not sure is the AVX support at your PC please check description of your processor.
-[Example](https://prntscr.com/llj7mj)
\ No newline at end of file
diff --git a/core-tech/Adding-support-for-Beam-Confidential-Asset.md b/core-tech/Adding-support-for-Beam-Confidential-Asset.md
deleted file mode 100644
index 7ed82f4..0000000
--- a/core-tech/Adding-support-for-Beam-Confidential-Asset.md
+++ /dev/null
@@ -1,294 +0,0 @@
-# Adding support for Beam Confidential Asset
-
-## TLDR;
-
-1. In version 6.0 Beam supports Confidential Assets
-1. Each asset has an `asset_id`, 0 is for Beam and 1,2,3... for new Assets.
-1. A complete list of existing assets is [here](https://explorer.beam.mw/assets)
-1. To enable assets add the following line to the `wallet-api` config file
-
- ```
- enable_assets=true
- ```
-1. The following API calls have been updated to support assets:
- * `wallet_status`
- * `tx_send`
- * `tx_split`
-1. New API methods have been added
- * `tx_asset_issue`
- * `tx_asset_consume`
- * `tx_asset_info`
- * `get_asset_info`
- * `calc_change`
-
-## Confidential Assets
-
-Confidential Assets (CA) are tokens mint on the Beam blockchain. Beam supports Confidential Assets since hard fork 2, but this feature had limited ability to be used in real life applications. Starting from the version 6.0 Beam Wallet adds ability to create smart contracts which make CA more usable and very important feature in Beam infrastructure. We already have [API](https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API#assets-support) to work with CA, but it was disabled by default. If you wish to accept and create transactions with CA you should enable this feature in the wallet API and update your codebase to handle CA correctly.
-
-### Enable CA support
-
-* run new binary with `--enable_assets`. With this flag your wallet starts to accept transactions with Confidential Assets
-
- ```
- ./wallet-api --enable_assets -n
- ```
- or specify it in config file
- ```
- enable_assets=true
- ```
-* to retrieve info about assets use `wallet_status` method, it will return an array of the info about assets in the wallet, including BEAM
-
- `-->`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 6,
- "method":"wallet_status"
- }
- ```
-
- `<--`
- ```json
- {
- "id": 1236,
- "jsonrpc": "2.0",
- "result": {
- "current_height": 112,
- "current_state_hash": "b9e8b868de60f28e553a1499a569f481991e4cff9fe2191d09d71a03c7708296",
- "difficulty": 378.36236572265625,
- "prev_state_hash": "3f84da0b0390deaca908603b6061867def987575a1af9311248ffb01503a0f02",
- "available": 303000000000,
- "receiving": 123,
- "sending": 0,
- "maturing": 8000000000,
- "locked": 30,
- "totals": [
- {
- "asset_id": 0,
- "available": 303000000000,
- "available_str": "303000000000",
- "maturing": 8000000000,
- "maturing_str": "8000000000",
- "receiving": 123,
- "receiving_str": "123",
- "sending": 0,
- "sending_str": "0"
- },
- {
- "asset_id": 1, // <--------------- this could be used to send/split CA or to retrieve extended info
- "available": 2000000000,
- "available_str": "2000000000",
- "maturing": 0,
- "maturing_str": "0",
- "receiving": 0,
- "receiving_str": "0",
- "sending": 0,
- "sending_str": "0"
- }
- ]
- }
- }
- ```
-
-* if you want to send or split CA you should specify `"asset_id"` in parameters
-
- `-->`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 2,
- "method":"tx_send",
- "params":
- {
- "value": 12342342,
- "fee": 2,
- "from": "472e17b0419055ffee3b3813b98ae671579b0ac0dcd6f1a23b11a75ab148cc67",
- "address": "472e17b0419055ffee3b3813b98ae671579b0ac0dcd6f1a23b11a75ab148cc67",
- "comment": "thank you!",
- "asset_id": 1 <------------------ NEW
- }
- }
- ```
-
-* if you want to get info about CA use
-
- `-->`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 2,
- "method": "tx_asset_info",
- "params":
- {
- "asset_id": 1
- }
- }
- ```
- `<--`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 2,
- "result":
- {
- "txId" : "10c4b760c842433cb58339a0fafef3db"
- }
- }
- ```
-* after this transaction become completed, you can read CA info from the local database
-
- `-->`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 6,
- "method": "get_asset_info",
- "params" :
- {
- "asset_id": 1
- }
- }
- ```
-
- * `asset_id` asset id to retrieve info about. Can be used for any asset even if you don't own it.
-
- `<--`
- ```json
- {
- "id": 1236,
- "jsonrpc": "2.0",
- "result":
- {
- "asset_id": 1,
- "emission": 2000000000,
- "emission_str": "2000000000",
- "isOwned": 1,
- "lockHeight": 39,
- "metadata": "STD:N=NAME;SN=SNM;UN=UNIT;NTHUN=NTHUNIT",
- "ownerId": "0ae08a49e018e98177774294107dc033790b87538e54a20e99c6b98f1dbd39ce",
- "refreshHeight": 927
- }
- }
- ```
- Returns full asset info or [error code](#Errors).
-
- * `asset_id` asset id
- * `metadata` asset metadata
- * `emission` & `emission_str` total asset emission. Maximum asset emission is 2128-1. To ensure compatibility with JavaScript raw number returned only if it is less than or equal to `Number.MAX_SAFE_INTEGER` (253-1). If asset emission is greater than `Number.MAX_SAFE_INTEGER` only corresponding string representation is returned.
- * `isOwned` is 1 if you own this asset
- * `lockHeight` last block when asset emission turned to/from 0.
- * `refreshHeight` block at which asset information has been received. Please note, that all returned fields are valid only for this and previous blocks. In next blocks emission might change, asset become unregistered &c. Use [tx_asset_info](#tx_asset_info) to retrieve the most recent info.
-
-* For minting new asset coins use `tx_asset_issue`. You must own the asset and info about the asset should be in a local database. `tx_asset_info` to retrieve the latest asset info if necessary. Asset minting is free. You need to pay only regular transaction fee.
-
- `-->`
- ```json
- {
- "jsonrpc": "2.0",
- "id": 2,
- "method": "tx_asset_issue",
- "params":
- {
- "value": 6,
- "asset_id": 1
- }
- }
- ```
-
- * `value` how much asset to mint, in asset groth.
- * `fee` transaction fee in BEAM groth. Omit to use default fee.
- * `asset_id` asset id of the asset to mint.
- * `txId` optional, provide your own transaction ID.
-
- `<--`
- ```json
- {
- "jsonrpc": "2.0",
- "id": 2,
- "result":
- {
- "txId" : "10c4b760c842433cb58339a0fafef3db"
- }
- }
- ```
- Returns transaction id or [error code](#Errors).
-
-* to burn existing asset coins use `tx_asset_consume`. You must own the asset itself as well as asset coins to burn them. You cannot burn asset coins that belong to another wallet. Info about the asset should be in a local database.
-
- `-->`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 2,
- "method":"tx_asset_consume",
- "params":
- {
- "value": 6,
- "asset_id": 1
- }
- }
- ```
-
- * `value` how much asset to burn, in asset groth.
- * `fee` transaction fee in BEAM groth, omit for a default fee.
- * `asset_id` id of the asset to consume.
- * `txId` optional, provide your own transaction ID
-
-
- `<--`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 2,
- "result":
- {
- "txId" : "10c4b760c842433cb58339a0fafef3db"
- }
- }
- ```
- Returns transaction id or [error code](#Errors).
-
-* if yoiu want to calculate the change amount for transaction use `calc_change`, it calculates the change value for given `amount` in for given `asset_id`
-
- `-->`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 4,
- "method":"calc_change",
- "params":
- {
- "amount" : 1234,
- "asset_id": 2,
- "fee": 10000,
- "is_push_transaction": true
- }
- }
- ```
-
- `<--`
- ```json
- {
- "jsonrpc":"2.0",
- "id": 4,
- "result":
- {
- "asset_change": 12,
- "asset_change_str": "12",
- "change": 12,
- "change_str": "12",
- "explicit_fee": 1100000,
- "explicit_fee_str": "1100000"
- }
- }
- ```
-
- where
-
- * `amount` is a requested amount we are going to send
- * `asset_id` asset id of the requested amount
- * `fee` explicit fee in GROTHs chosen by the user
- * `asset_change` change amount for requested `asset_id`
- * `change` change in for BEAM. `asset_change` and `change` are equal if `asset_id == 0`, i.e. BEAM
- * `explicit_fee` the fee which should be used
- * `is_push_transaction` `true` if we are going to push transaction output into the shielded pool.
\ No newline at end of file
diff --git a/core-tech/Addresses-in-Beam.md b/core-tech/Addresses-in-Beam.md
deleted file mode 100644
index dad7b04..0000000
--- a/core-tech/Addresses-in-Beam.md
+++ /dev/null
@@ -1,259 +0,0 @@
-
-
-
-
-There're (too) many different kinds of addresses in Beam:
-* Regular (a.k.a. new-style)
-* Legacy (BBS-only, a.k.a. old-style)
-* Offline
-* Max-privacy
-
-In addition to those kinds of addresses, there's more terminology:
-* Payment _Tokens_, that consist of an address with the requested payment amount
-* _Vouchers_
-* _Endpoints_ (alternatively called as _Signature_, or _Identity_)
-* _Payment proof_
-
-Some of the above things are permanent, some expire, and some are intended for single usage.
-In addition to that, when the wallet is restored, the addresses are not preserved (new wallet instance generates new addresses).
-All this is very confusing. Here we'll explain in details how things work, why historically so many kinds of addresses were implemented, and what is relevant today.
-
-# What are Beam addresses?
-
-First and foremost:
-### there are no addresses on the Beam blockchain per se.
-***
-
-Beam is based on UTXO model (set of coins, in simple words). There're 2 types of UTXOs:
-* MW (MimbleWimble) UTXOs.
-* Shielded TXOs. Those are created and spent using in Lelantus-MW txs.
-
-Both kinds of UTXOs are opaque, and look like random data. No addresses that expose who owns them, and the value is concealed.
-
-Each UTXO has its secret key, which is needed to build a valid tx that spends it. Means whoever knows that secret key - actually owns the coin.
-
-## How the wallet manages its coins
-
-Each wallet has the _Master Key_ (initialized from the secret seed phrase). It is used to derive all the coin keys. When the coins are generated by the wallet, they're encoded such that they can re recognized by the corresponding _Owner Key_ (also derived from the Master Key).
-
-This means the following:
-* All the coins belong to the wallet that generated it. They can be recognized by its _Owner Key_, and then spent in the future txs using its _Master Key_.
-* Coins do **NOT** belong to addresses.
-* Addresses are only used between the wallets to communicate and build txs (more about this later). After the tx is included in a block - addresses don't matter.
-
-# MW txs and old-style addresses
-
-Beam is based on MW, where transactions are built interactively. Means users must communicate to build a transaction.
-
-For this we developed an SBBS system, that allows wallets to exchange encrypted messages anonymously. Wallets can generate public/private key pairs, where the public key is used to encrypt messages, and private key can decrypt them.
-
-That's how **addresses** were born on Beam. Address in fact meant SBBS address, a public key to encode messages, that can only be decoded by the appropriate private key.
-
-Here're some notes regarding the SBBS encryption:
-* All encrypted messages are opaque (look like random data), the sender/receiver of the message is also opaque, and the message is protected against tampering (using HMAC scheme).
-* Using the SBBS address one can only encrypt messages, not decrypt.
-* There's no feasible way to realize that a specific SBBS message was encoded by a given SBBS address.
- * Means you can share your SBBS address to different users, they won't be able to see when you communicate with others.
-* Users can generate as many SBBS addresses as they want.
-* In order to receive the SBBS message, one tries to decrypt all the incoming SBBS traffic. Only the intended messages would be successfully decrypted and pass HMAC verification.
-* If you listen to several active SBBS addresses - the wallet will try to decrypt each message by each address private key.
- * The more active SBBS addresses - the harder the wallet works to receive the messages.
-
-## Address generation and expiration
-
-As we said, a wallet may generate multiple SBBS addreses. It may also _deactivate_ a specific address, which means it'd stop trying to decrypt incoming SBBS messages by its private key.
-
-Theoretically there was no good reason to have more than 1 SBBS address. User could just live fine with only a single SBBS address, and share it freely. As we've said, all the messages are completely opaque, and the communication is anonymous.
-
-There's only limited scenarios where a user may need more than 1 address. If the user wishes to provide several addresses that look like of different users (for example, have several accounts at an exchange, with different SBBS addresses for funds withdrawal).
-
-However, due to user habits and some misconceptions, users insisted on changing addresses regularly. That's why we implemented automatic SBBS address generation and expiration
-
-# Payment proof
-
-Unlike other blockchain designs, in Beam there're no addresses on the blockchain per se.
-As a result, if Alice sends funds to Bob, there's no way to prove it later from the blockchain data (Bob has plausible deniability).
-
-To address this, we implemented a _Payment Proof_. It's a signature, signed by the recipient of the funds, that it indeed accepts the specific amount from the specific sender. It is signed by the receiver and verified by the sender during the transaction negotiation stage (all this happens off-chain).
-
-The _Payment Proof_ signature signed the following:
-* Identity (pubkey) of the sender
-* Identity (pubkey) of the receiver (the signature is signed by the corresponding private key).
-* Amount and asset type being-received
-* Transaction Kernel ID. If the tx was negotiated but not broadcasted and accepted in a block - the _Payment Proof_ is considered invalid (i.e. there was an intention of the tx, but it didn't take place actually).
-
-_Identities_ of both sender/receiver were in fact their SBBS addresses. That is, **the same key was used both for SBBS messages encryption, and to identify the owner of the funds**.
-
-# Hardware Wallet, and new-style addresses (a.k.a. Regular addresses)
-
-With the hardware wallet the things work differently. The _Master Key_ and all the coin keys are managed entirely in the HW wallet. The software wallet gets the _Owner Key_ that can recognize coins (but not spend them), and handles all the communication and blockchain state change logic.
-
-The SBBS address must be managed by the software wallet, it's too complex for the HW wallet to decrypt all the SBBS traffic. On the other hand, when the _Payment Proof_ is signed/verified - it must be done with the key that is managed by the HW wallet.
-
-This is where we decided to split the SBBS address and the user identity. The SBBS address is the address you're communicating with, and the _Identity_ is the public key of the final receiver/sender of the funds. For standard wallets both are managed by the wallet, but with the HW wallet they're managed in different places.
-
-To support this, we defined a new-style address (now called a Regular address).
-
-First, the address format was changed. The older SBBS address was just a hex-encoded pubkey. We decided to change it into an encoded collection of arbitrary number of parameters (to support possible future parameters for various address/token types).
-
-The Regular address consists of the following fields:
-* SBBS address
-* User Identity
-
-## Endpoint
-
-Historically we had several names for the above user identity: _Identity_, _HW Identity_, _Signature_, and etc. All that lead to confuses, so we decided to give a distinctive name to this: the _Endpoint_.
-
-The rationale behind this name is the following. Suppose Alice sends funds to Bob, both use HW wallet. Conceptually you may treat this situation as this: Alice's HW wallet is the ultimate sender of the funds, Bob's HW wallet is the ultimate receiver. And they negotiate the transaction with each other.
-The software wallets of Alice and Bob are just intermediate entities, they're not part of the transaction negotiation.
-
-In other words, the _Endpoint_ is the final source/destination of the funds.
-
-# Lelantus-MW
-
-To address the inherent MW linkability problem, we extended Beam with the Lelantus-MW protocol. It's our proprietary modification of the Lelantus protocol, adjusted to fit and complement the MW.
-
-With it we added 2 new transaction elements:
-* Shielded Output - add an opaque coin into the shielded pool
-* Shielded Input - spend _some_ coin from the shielded pool.
-
-In MW transactions are interactive, when Bob receives funds from Alice, he creates his UTXO to accept the funds in advance (during negotiation stage) . And since Bob himself created his UTXO, he can recognize it using his _Owner Key_, and spend using his _Master Key_.
-
-In contrast to MW txs, Lelantus-MW txs are non-interactive. Means Alice creates the _Shielded Output_ tx element, without Bob being-involved. Yet she creates it in such a way that Bob will be able to recognize and spend it later.
-
-This means that Bob should give Alice an additional data, to allow her to send funds to Bob using Lelantus-MW.
-
-Technically each _Shielded Output_ comes with a _Ticket_. It's an opaque data object, but encoded such that it can be recognized by the funds recipient (Bob). Moreover, _Tickets_ must be unique, it's impossible to use the same ticket twice (this is related to double-spend prevention).
-
-So, basically there're 2 options here:
-1. Bob gives Alice a source data, using which Alice may generate arbitrary number of Bob's tickets.
-2. Bob generates arbitrary number of tickets, and gives them to Alice.
-
-Both methods have their pros and cons. And both are supported in terms of different address types.
-
-## Offline address
-
-This corresponds to the 1st method. The _Offline address_ in essence is a ticket generator. It also comes with the Bob's _Endpoint_, and is also signed by _Endpoint_'s signature (if Alice needs to prove that she sent funds to Bob - she can show that the corresponding ticket was generated by the generator signed by Bob).
-
-Once Alice has it, she can send arbitrary number of Lelantus-MW txs to Bob, which is a good thing.
-
-There's however a drawback. Alice knows the internal parameters of the ticket (since she actually generated it). One of them later will be used by Bob, when he'll spend this shielded coin.
-
-Means that the **sender will notice when the receiver will spend the shielded coin**. For the 3rd-party observers the shielded transactions are anonymous, but this specific kind is not anonymous w.r.t. the sender. Hence we call it _Offline_, but not truly private.
-
-**Note:** despite the above drawback, the above is perfectly fine if you receive shielded funds from a trusted sender. For instance, you may have several wallets (with different seed phrases). You may use _Offline_ address to transfer funds in a private way. As we've said, 3rd-party observers will see no link between the Shielded Output and the corresponding Shielded Input.
-
-## Max Privacy address
-
-This corresponds to the 2nd option. The _Max Privacy_ address consists of the following:
-* Receiver _Endpoint_
-* Arbitrary number of _Vouchers_.
- * Each _Voucher_ is actually a ticket, signed by Bob _Endpoint_ signature (to prove later that Bob is the receiver of the funds).
-* Optional SBBS address to ask for more vouchers.
-
-This method doesn't have the drawback of the _Offline_ address. Alice may send funds to Bob, Bob later may spend those funds anonymously w.r.t. Alice.
-
-The obvious drawback is that there's a limited number of Vouchers/Tickets. Once they're all consumed - there's no way to send more txs.
-This is where the SBBS address can be used. Once Alice runs out of Bob's vouchers (or getting low on them) - her wallet may request for more Bob's vouchers via SBBS. If/when Bob will be online - his wallet will respond, and provide Alice with more vouchers automatically.
-
-# Tokens
-
-As we've said, all the address types, except the "old-style", are represented as a collection of parameters. In addition to the address itself (whatever kind it is), it's possible to include more fields.
-
-Using this we've introduced a so-called payment _Tokens_, which are a way to request a specific payment. They consist of the address (any kind), and the requested Amount and asset type.
-
-
-***
-
-# Ideas for improvements
-
-So we've described what Beam addresses are, why it's not a big deal to loose them (i.e. coins don't belong to addresses, you don't loose coins).
-We also explained why there're different kinds of addresses, and why they are necessary. The old-style address is actually obsolete, and even incompatible with the HW wallet (i.e. you can't even generate it with the HW wallet). But, unfortunately, we can't get rid of it completely, because some existing exchanges won't accept different addresses (they do a sort of a regular-expression check on the address). So they're still here.
-
-However, many things can and should be improved, mostly regarding user experience and the UX.
-
-The most important change can be expressed as this:
-
-***
-### It's all about Endpoints
-***
-
-In simple words, each address consists of two things:
-* Who does it belong to, i.e. who is the supposed receiver of the funds. This is the _Endpoint_.
-* What kind of tx would that be, and how to negotiate and build it.
-
-_Endpoint_, i.e. the identity of the sender/receiver - is the most important thing. It should be visible wherever applicable, and play a crucial role in the address book.
-_Who_ am I paying, and _who_ payed me. This is arguably more important than _how_ is the payment done.
-
-## Address format
-
-Currently all address types (except legacy) are displayed as a Base58-encoded strings of a pairs, where key is an 1-byte identifier of the parameter.
-As a result, the user has no way to see either the embedded arguments, or even the address type. A better option would be encoding the arguments in a human-readable way.
-
-For example, a Regular (online) address could be displayed as:
-
-`beam_Bk1azc8VtaYU1f6t7jiRGkxJDiAVui6Y5WvohjoU1yFA_bbs274b78587e1c9643e7472e221be1634b8efe06f747175d3d8c98ce1ef665b056d4a`
-
-It begins with `beam` (a common practice in some networks), then followed by a human-readable _Endpoint_, and then followed by the bbs address.
-
-### What if users tamper/modify address manually?
-
-The good news is that Beam addresses are generally resistant to tampering. If one modifies the address (either intentionally or not) - there is no risk of loss of funds.
-
-If one modifies the SBBS address, the communication with the receiver will fail. And if the _Endpoint_ is modified, the negotiation with the receiver will fail.
-
-Same applies to Max Privacy and Offline addresses. They contain pre-signed receiver signatures (that would be a part of the future payment proof). If one modifies some address fields - the address would become invalid.
-
-And, again, this all boils down to the _Endpoint_ of the address, i.e. **who** is the supposed recipient of the funds. If the sender verifies it and is confident that it's the intended one - there's no risk of funds loss, or the payment going into wrong hands.
-
-## Address book refactor
-
-Address book consists of several tabs. (My active addresses, My expired addresses, Contacts).
-For the "Contacts" tab there is a list of all known addresses of other users.
-
-A more sane address book should look like this
-
-* There should be a list of known _Endpoints_, not addresses/tokens. Those are actually different contacts. Each can be annotated by a name.
-* For each _Endpoint_ we can show the following information:
- * Its SBBS address (if known)
- * Do we have its Offline address (yes/no)?
- * How many vouchers are left for Max Privacy txs?
- * Optionally - a button to request more vouchers manually
-
-* For owned (my) _Endpoints_ the following information should be presented
- * Internal number. That is, all the keys are generated using _Master Key_, from the provided key number. Normally they're picked at random, and not shown to the user. But we can show them. By such users will be able to re-generate the same addresses after the wallet is restored.
- * Option to generate an address/token of any kind for this specific _Endpoint_.
- * HW wallets: option to verify the _Endpoint_ on the HW wallet
-
-## Send screen - To
-
-Currently in the "To" field the user puts an address. The wallet parses the address, recognizes its type, and acts accordingly. For some addresses the wallet gives an option to modify the transaction type (Online, Offline, Max Privacy) if that token has enough information.
-
-Instead the wallet should recognize the _Endpoint_ from the given address, check if it's already in the address book, and realize all the possible ways of sending from what it already knows about it. Not only from the parameters of the provided address.
-
-Moreover, it should be possible to specify "To" the _Endpoint_ only. Or just the name that the user annotated to it in the address book.
-The wallet should automatically find it in the address book, and allow tx types according to what is known about it.
-
-## Send screen - From
-
-Currently this doesn't exist at all. When funds are sent - the sending wallet always identifies itself as a random user with an ephemeral _Endpoint_.
-
-There should be an option to specify an **existing** _Endpoint_. By such the sender may make the receiver know who sent the funds.
-
-In the "From" field there should be a choice of the currently existing _Endpoints_ (i.e. active addresses), as well as previously used (perhaps no more active), or an "Anonymous", which means what it is today - a random _Endpoint_.
-
-## Transaction details
-
-The transaction details are loaded with lots of technical parameters (SBBS address of sender/receiver, signatures, etc.). They are mostly meaningless to the user.
-
-There should be the following parameters:
-* For funds transfer transactions:
- * _Endpoint_ of the sender/receiver. If they exist in the address book - this should be mentioned.
- * Type of tx (Online, Offline, Max Privacy)
- * Amount transferred and asset type
- * Payment proof
-* For other txs (coinswap, contract calls)
- * _Endpoints_ and Payment proof are irrelevant. Don't show them.
- * List of sent/received asset types and amounts
-
-
diff --git a/core-tech/Asset-Descriptor-v1.0.md b/core-tech/Asset-Descriptor-v1.0.md
index 8bb73be..3b61f33 100644
--- a/core-tech/Asset-Descriptor-v1.0.md
+++ b/core-tech/Asset-Descriptor-v1.0.md
@@ -1,5 +1,5 @@
# Abstract
-The assets are described [here](https://github.com/BeamMW/beam/wiki/Confidential-assets)
+The assets are described [here](transactions/Transactions-Confidential-Assets.md)
This document's purpose is to specify the asset metadata, to enable 3rd party tools to consume and display the subset of asset-related information in a simple and well-standardized manner.
diff --git a/core-tech/Atomic-swap-token.md b/core-tech/Atomic-swap-token.md
deleted file mode 100644
index e816bb4..0000000
--- a/core-tech/Atomic-swap-token.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Atomic swap token
-## Overview
-Swap token is intended to allow users to exchange info about transactions(swap) via any side channels.
-In general, token is serialized list of transaction parameters, presented as a base58 encoded byte buffer.
-
-## Description
-Token has the following fields:
-
-`- flags // 1 byte`
-
-`- optional TxID // 1 or 17 bytes`
-
-`- list of parameters // not less than 34 byte since transaction should have at least one address parameter`
-
-
-### flags
-Flags is a 1-byte field where only the highest bit is defined the others are reserved.
-0x80 means that this is a token.
-
-
-### tx ID
-This is an optional transaction ID. All swap transaction should have this value. It is optional for the cases if we will use the token structure for other types of transaction.
-There are two possible values:
-
-`|0x01| 16 byte UUID|`
-
-or
-
-`|0x00| `
-
-### Transaction parameters
-Transaction parameter is a pair of the parameter key and value.
-The key is 1 byte value and its meaning is defined by `TxParameterID `enum from [wallet/common.h](https://github.com/BeamMW/beam/blob/master/wallet/common.h)
-The values are arrays of bytes and contain serialized values.
-The value type and size is defined by the key meaning. All integer types are big-endian.
-
-
-
-
-
-
diff --git a/core-tech/Atomic-swap.md b/core-tech/Atomic-swap.md
deleted file mode 100644
index 5ac7eaf..0000000
--- a/core-tech/Atomic-swap.md
+++ /dev/null
@@ -1,149 +0,0 @@
-Atomic swap is performed between Beam and other cryptocurrency. Denote it BTC, but actually it can denote other network that supports the needed functionality.
-
-The swap is performed in a single transaction, which effectively transfers the ownership of the Beam UTXO in exchange for some secret, which is needed to claim the being-exchanged coin on the BTC network.
-
-# High-level design
-
-There are two parties:
-* **A**lice. Owns the Beam, interested to trade it for the BTC
-* **B**ob. Owns the BTC, interested to trade it for the Beam.
-
-There are 3 major phases of the atomic swap
-1. Prerequesites
- * The being-exchanged UTXOs are locked on both networks for a specific time period (in terms of blocks).
- * Parties monitor both networks to ensure the source UTXOs are indeed locked.
-2. Exchange
- * Parties collaborate to create a transaction that transfers the locked Beam to **B** in exchange for the secret.
- * **B** substitutes the secret to the transaction and finally broadcasts it to the network.
- * Once transaction is visible - **A** learns the secret.
- * **A** creates a BTC transaction to claim the BTC UTXO, and broadcasts it to the BTC network.
-3. Rollback. In case the swap didn't take place (for whatever reason)
- * Locked UTXOs on both network should remain intact until their lock timeout expires.
- * After the timeout expiration parties broadcast transactions that transfers the locked UTXOs back to them.
-
-Note that **A** actually claims the BTC UTXO after sending the Beam UTXO. This means that the lock timeout of the BTC UTXO must be significantly bigger than that of the Beam UTXO, because **B** may broadcast the Beam transaction just before the timeout expires, the **A** should still have enough time to build and broadcast the BTC transaction.
-
-# Technical design
-
-The _unlock secret_ is the SHA-256 hash preimage (i.e. a 256-bit value which, after hashing, should be equal to a known 256-bit value). Supported on Beam, BTC, and, probably, many other networks.
-
-**Note**: The drawback of this scheme is a considerable privacy compromise. As we'll see, it's possible for the attacker to detect such an atomic swap, by looking for the matching hash preimages in both networks.
-
-There is a better option, where the _unlock secret_ is an EC scalar, i.e. private key. It's based on the so-called aggregate signatures. It's less generic, since it assumes both networks use the same EC equation and the Generator.
-
-So we'll review the scheme with the Hash-lock, but keep in mind that it can easily be modified to the one with the aggregate signature, and the rest of the argument, and the general flow are exactly the same.
-
-There are no scripts in Beam blockchain. However the following is supported in the transaction kernel:
-* Timelock - minimum blockchain height for the kernel to be valid
-* HashPreimage
-
-## UTXO lock on BTC network
-
-**B** broadcasts a BTC transaction, which creates an UTXO which can be spent under the following conditions:
-1. Timeout + secret key chosen by **B**
-1. Hash preimage chosen by **B** + secret key chosen by **A**
-
-## UTXO lock on Beam network
-
-This part is somewhat more complex, since there are no scripts in Beam. **A** and **B** collaborate to create a _shared_ UTXO, whose blinding factor is shared between them.
-
-1. **A** and **B** randomly choose their parts of the blinding factor for the shared UTXO
-1. **A** and **B** first create the "rollback" transaction, which would transfer the shared UTXO back to **A** if the exchange didn't take place.
- * This transaction kernel is Time-locked, i.e. transaction can only be broadcasted starting from specific blockchain height.
- * **A** saves this transaction, but doesn't broadcast yet.
-1. **A** and **B** create the transaction that spends **A**'s UTXO and creates the shared one.
- * The tricky part is creating the Bulletproof for the shared UTXO. Takes 3 iterations.
-1. They broadcast this transaction to the Beam network, to create the shared UTXO.
-
-## Exchange transaction
-
-At this point both Beam and BTC UTXOs are locked, both parties get confirmations for this. In addition **A** knows the _Image_ of the locked BTC UTXO. Now they collaborate to build a Beam transaction that transfers the shared (locked) Beam UTXO to **B** in exchange for revealing the _Hash Preimage_, which, after hashing, equals to the known _Image_.
-
-* **B** randomly chooses the blinding factor for the new UTXO
-* **A** creates the Transaction Kernel, which is supposed to contain the _Hash Preimage_ (but doesn't contain yet), which corresponds to the knwo _Image_.
-* **A** puts her part of the kernel multisig, which assumes the correct _Image_.
-* Incomplete transaction is passed to **B**.
-* **B** puts his part of the kernel multisig, which assumes the correct _Image_ (same as Alice).
-* **B** substitutes the correct _Hash Preimage_ to make the transaction kernel valid.
- * This is where the atomic swap actually occurs!
-* **B** broadcasts the transaction to the Beam network.
-
-**A** monitors the Beam network. Once the exchange transaction kernel is visible:
-* **A** realized that the exchange occurred.
-* **A** learns the _Hash Preimage_.
-* **A** creates and broadcasts the BTC transaction to claim her BTC UTXO.
-
-# In-depth flow diagram
-
-## Bob
-
-* Collaborate to lock the BTC UTXO
- * Get `Pka` from **A** - her generated pubkey for some secret key `ska`.
- * Generate the `hpi` - the _Hash Preimage_.
- * `hi = Hash(hpi)` - the _Hash Image_.
- * Generate and broadcast the transaction that creates a locked BTC UTXO.
- * The created UTXO can be spent iff both `hpi` and `ska` are known.
- * `hi` and `Pka` are revealed.
- * Send **A** this transaction (so she'll be able to identify it in the BTC network).
-* Collaborate to lock the Beam UTXO
- * Generate `sfb` - the part of the blinding factor of the shared UTXO.
- * Get `Pfa` - **A**'s part of the public blinding factor (of the shared UTXO).
- * Collaborate to sign the kernel for the transaction that transfers the shared (non-existing yet) UTXO back to **A**
- * The kernel must be time-locked
- * **B**'s part of the signature accounts for the `sfb`.
- * Collaborate to create the Bulletproof of the shared UTXO.
- * requires 3 iteration cycles with **A**
- * Collaborate to sign the kernel for the transaction that creates the shared UTXO
- * **B**'s part of the signature accounts for the `sfb`.
-* Wait until the mutual UTXO becomes visible
-* Collaborate to build the exchange transaction
- * Transaction kernel is supposed to (but doesn't yet) contain the `hpi`.
- * Means - its signature signs the kernel contents, including `Hash(hpi) == hi`, whereas `hi` is known to both parties.
- * Generate the new UTXO
- * Pass it to **A** so that she creates such a kernel, and substitutes her part of the signature.
- * Get the half-signed kernel from **A**, and verify it.
- * **Important:** Ensure there is enough time left until the timelock of the shared UTXO expires!
- * Finish the kernel signature.
- * Substitute the `hpi` as the _Hash Preimage_.
- * Complete the signature.
- * Broadcast the transaction to the Beam network.
-* Wait until the exchange transaction becomes visible, or until the BTC UTXO timelock expires.
- * If the transaction is visible (and enough new blocks are generated above) - Congratulations! It's done.
- * If the BTC UTXO timelock expired and it's still unspent - take it back (create and broadcast another BTC transaction).
-
-## Alice
-
-* Collaborate to lock the BTC UTXO
- * Generate `ska` - private key on the BTC network.
- * Send `Pka = G * ska` to **B**.
- * Receive the BTC transaction details from **B**, and verify it
- * Correct amount is locked.
- * Can be spent using `ska`, and a _Preimage_ of `hi` (the preimage is not known yet).
-* Collaborate to lock the Beam UTXO
- * Select input(s) to build the transaction that creates the shared UTXO
- * Generate `sfa` - the part of the blinding factor of the shared UTXO.
- * Get `Pfb` - **B**'s part of the public blinding factor (of the shared UTXO).
- * Collaborate with **B** to build:
- * A time-locked rollback transaction that transfers the shared (non-existing yet) UTXO back to **A**.
- * It must be created before the shared UTXO is actually created.
- * Bulletproof for the shared UTXO
- * Transaction that spends the selected inputs and creates the shared UTXO
- * Send the transaction to create the shared UTXO to the network
-* Wait until the locked BTC UTXO becomes visible in the BTC network
-* Ensure the BTC timelock is significantly bigger than the Beam timelock
-* Collaborate to build the exchange transaction
- * Transaction kernel is supposed to (but doesn't yet) contain the `hpi`.
- * **A** creates such a kernel, puts her part of the signature, which
- * Corresponds to her part of the shared UTXO (compensates for `ska`).
- * Would become valid only when the correct _Hash Preimage_ (`hpi`) will be substituted.
- * Half-signed transaction is passed to **B**
-* Wait until the exchange transaction becomes visible, or until the Beam UTXO timelock expires.
- * Once the transaction is visible:
- * **A** learns the `hpi` from the visible transaction kernel
- * **A** Creates and broadcasts the BTC transaction to claim the BTC UTXO
- * If the Beam UTXO timelock expired and it's still unspent
- * Broadcast the rollback transaction to the network
- * Wait until the transaction (either post-exchange or the rollback) becomes visible.
-
-## Swap diagram
-
\ No newline at end of file
diff --git a/core-tech/Authorization-control-and-signatures-in-contracts.md b/core-tech/Authorization-control-and-signatures-in-contracts.md
deleted file mode 100644
index 4258141..0000000
--- a/core-tech/Authorization-control-and-signatures-in-contracts.md
+++ /dev/null
@@ -1,131 +0,0 @@
-In the most common cases the contract method calls `Env::AddSig()` for each needed public key, and the app shader includes the key material for each key within the `SigRequest` structure, when it calls `Env::GenerateKernel()`.
-
-This is a preferred method to design a contract and its application, as it has the following advantages:
-
-* Performance: native signature is both compact and fast.
-* Security: apps have no access to secret keys, they can only derive public keys.
-* Simplicity.
-
-However there are more complex situations, where either several users are required to authorize a method call, or a custom signature scheme is required (such as m-out-of-n signature).
-
-Those may include:
-
-1. Explicit multisignatures. Several keys are verified (mutliple calls to `Env::AddSig()`), belonging to different users.
-2. Seemless multisignatures. There is a single key, but it is a sum (or any linear combination) of several keys, belonging to different users.
-3. Non-standard signature is needed (ring signatures and etc.).
-4. Any combination of the above
-
-On the contract side those are supported. In addition to `Env::AddSig()` (which can be invoked arbitrary number of times) the contract has access to **Secp** primitives, using which it can implement custom cryptographic scheme verification.
-
-For apps, however, the default functionality is not enough. Creating a multisigned transaction that is supposed to invoke such a contract assumes that different wallets should cooperate and communicate on behalf of the apps.
-
-So we extended the BVM functionality to support all the variety of possible signature schemes. Though apps still don't get direct access to secret keys with the added functions, the risk is somewhat greater (more about this later), hence to use those extra functions the app needs an elevated privilege level (OFF by default).
-
-Technically those functions are:
-* Nonce Slots management functions
-* getting an image of a key or a slot, with either standard (**G**) or any custom generator
-* getting a blinded key
-* Communication support (via SBBS system)
-* `Env::GenerateKernelAdvanced()` - with more specific signature control
-
-## Nonce slots and blinded keys
-
-(the idea of nonce slots is the same as in our HW wallet design)
-
-Generally our supported signatures follow this ritual: first a unique nonce is generated and its image is exposed (in some manner). Then, during the signing, a pseudo-random challenge is derived, and the prover should reveal a linear combination of the secret key and the nonce, a.k.a. blinded key.
-
-This scheme is applicable to Schnorr's signature, Ring signature, Groth's 1-out-of-many, and probably many others.
-It's **critically** important to make sure the nonce is unique, i.e. not reused for the same secret key in different signatures.
-
-So we decided to add appropriate support functions for the apps: generate unique nonces, get their images, and get blinded keys:
-* Generate unique nonce.
- * BVM generates a nonce using system random and state mutation.
- * optionally app can specify extra seed data to strengthen the nonce (i.e. less dependency on system random).
-* Get nonce image (arbitrary number of times, with arbitrary generators).
-* Get blinded key.
- * The app supplies the needed key material (a.k.a. `KeyID`, `SigRequest`), arbitrary challenge (scalar) and the nonce slot number.
- * Once the nonce is used - it's immediately wiped.
-
-By such apps are given opportunity to build complex signature schemes, without either direct access to the secret keys, or the feasible opportunity to extract them.
-
-# Building a custom signature scheme
-
-As we mentioned, an app can create a custom signature (such as Ring signature), include it in the contract method invocation arguments, then the contract shader may verify it by implementing the needed verification scheme (in terms of **Secp** primitives).
-
-Apps can generate such signatures by the provided functionality: obtaining nonce images, and getting blinded keys for the needed challenges.
-
-### Risk of signature _hijacking_
-
-When using native signature (`SigRequest`/`AddSig()`), it's included in the kernel multi-signature, which also includes its blinding factor. Other users can't take it as-is and use in their transactions (it's not feasible to build a transaction with unknown blinding factor).
-
-In contrast, the custom signature is not automatically bound to the kernel blinding factor. Hence any other user that monitors transactions can build its own transaction that invokes the same method with exactly the same arguments.
-
-To mitigate this threat we recommend the following scheme:
-
-Normally challenges for signatures are derived using _Random Oracle Model_, which is initialized with the message being-signed, this binds the signature for this specific message.
-
-So we recommend deriving an arbitrary ephemeral (unique) key. Its image (pubKey) should be included in the method arguments, and initialize the _Oracle_ (challenges derivation), **AND** it also should be included in the native kernel signature (i.e. `Env::AddSig()`).
-
-So we recommend using a hybrid of a custom and native signatures. Instead of binding the signature to a message, we recommend binding it to an ephemeral key, whose signature in turn is bound to the kernel blidning factor. By such it's no more feasible to hijack the signature.
-
-# Building a mutli-signed transaction using native signature
-
-In simple scenario the app calls `Env::GenerateKernel()`, and supplies the info about how it should be signed (gives array of `SigRequest`), the signing itself is deferred until a later stage. Hence some kernel parameters may still vary: min/max height, fee.
-
-For multi-signed transactions this is different. All the kernel parameters must be decided in advance, so that all the challenges can be derived.
-Those include:
-
-* Standard parameters: **contractID**, method number, args
-* min/max heights
-* kernel fee
-* Funds balance
-* Kernel blinding factor image
- * together with Funds balance is used to derive kernel `Commitment`
-* Total nonce image, which includes
- * internal BVM nonce for the kernel blinding factor
- * all the nonces the app uses for the keys used in the signature
- * all the nonces the apps running in different wallets use for their keys
-
-From all this the challenges are derived.
-
-Then it's the apps's task to calculate the signature: the sum of all the needed blinded keys (its own, as well as of other users).
-
-Technically the flow goes like this:
-* Decide auxiliary kernel parameters (heights, fee)
-* get nonce images
-* get the image of additional nonce, which would be used by the BVM to blind the kernel blinding factor
-* for all the co-signers:
- * co-signers send their (cumulative) nonces for their keys
-* sum all the nonces
-* Call Env::GenerateKernelAdvanced() for the 1st time to derive the challenges
-* Extract the blinded keys, using the appropriate nonces and derived challenges
-* for all the co-signers:
- * Signer sends them the total nonce and the kernel blidning factor, so that they cal also derive the challenges
- * co-Signers reply with the sum of their blinded keys
-* sum those blinded keys to get a multi-signature
-* Invoke Env::GenerateKernelAdvanced() for the 2nd time, to finally build the transaction.
-
-Some examples of this flow:
-* **vault** app: example of a seamless multisignature, where a vault `PubKey` is actually a sum of the keys of 2 users. The contract code is unmodified (i.e. doesn't care if this is a multi-owned account).
-* **upgradable2** contract and app: example of an explicit multisignature, where the contract demands authorization by multiple keys.
-* more examples to come, to demonstrate custom signature schemes
-
-# Security considerations
-
-When app is invoked in the wallet, it's possible to define its _privilege level_, which may restrict its access to potentially dangerous functionality.
-
-* Level 0: apps have no access to any user-specific info, and no permission to create transactions. They can only interpret and display the blockchain status information. This is considered safe (though of course the info that app displays may be misleading).
-
-* Level 1 (default): Apps have an access to user's public keys (only those related to contracts), and can ask to create transactions. For the transactions the user sees the resulting balance (funds in/out), and they need user approval. There are 2 risks to consider:
- * There is no reliable way to know it the funds are spent as supposed. A malicious app can steal those funds by sending them such that they won't be accessible by the user in the future.
- * App may try to deanonymize the user. It may derive multiple public keys, which are normally intended for different contracts, and expose them in some transaction in a seamless way (a disguised parameter to some contract, recognized by the attacker).
-* Level 2: Apps have access to blinded keys.
- * A malicious app can sign **arbitrary** transaction to steal the user funds.
- * Although such a risk already exists at privilege level 1, here it's somewhat greater, because the leaked signature may be used later, not necessarily during the app invocation.
-* Level 3: Apps have access to inter-wallet communication.
- * This somewhat increases the risk of disguised signature leakage: Rather than hiding the leaked signature for the attacker on-chain in the explicit tx, a malicious app can now communicate it directly to the attacker.
-
-## Conclusion
-At any privilege level above 0 there is a risk of deanonymization and funds theft. So we strongly suggest using only trusted apps: either reviewed and built by the user, or signed by trusted 3rd-party developers.
-
-Anyway the deanonymization and theft risks are bounded by the contracts. Apps have no access to other wallet keys (UTXOs, shielded outputs, onwer key, and etc.
diff --git a/core-tech/BEAM-IPFS-Support.md b/core-tech/BEAM-IPFS-Support.md
index b78960e..97de726 100644
--- a/core-tech/BEAM-IPFS-Support.md
+++ b/core-tech/BEAM-IPFS-Support.md
@@ -1,121 +1,182 @@
-**THIS DOCUMENT DESCRIBES UPCOMING AND NOT YET RELEASED v6.3 IPFS SUPPORT. Subject to change without prior notice.**
+# BEAM IPFS Support
-As of v6.3 BEAM adds IPFS support and IPFS can be accessed via API. Refer [version 6.3 API](https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API-v6.3) docs for details on supported IPFS calls.
+Beam embeds a full [IPFS](https://ipfs.tech/) (InterPlanetary File System) node into the wallet process, enabling decentralized content-addressed storage for DApp user interfaces and other on-chain assets.
-* in Desktop UI client IPFS is enabled by default. IPFS node is started when user launches any DApp granting full IPFS support to DApps. After IPFS node is started it continues to run until desktop client is closed.
+## Why IPFS Is Embedded
-* in wallet-api IPFS support is disabled by default, `--enable_ipfs=true` option should be specified to start IPFS node granting full IPFS support
+Beam DApps are implemented as [shader pairs](bvm/BVM-Shader-Development.md): a contract shader running inside the BVM and an app shader that runs in the wallet and builds the UI. The UI assets — HTML, JavaScript, images — must be delivered to the wallet client without relying on a centralized server. IPFS provides content-addressed immutable storage, so a CID embedded in the shader's metadata permanently identifies the exact UI bundle. When a user opens a DApp the wallet fetches the bundle by CID from the IPFS network.
-* in Mobile clients & WASM client limited IPFS support is enabled. No local IPFS node is started, write-only methods like ipfs_add/ipfs_pin would fail. Read-only methods like ipfs_get are enabled via HTTP calls to BEAM managed IPFS nodes.
+Secondary use cases include NFT metadata storage and application-level content pinning from DApp shaders via the wallet API.
-## BEAM IPFS Config
+## Client Modes
-BEAM IPFS repository is located in the `[wallet data folder]/ipfs-repo` until `--ipfs_repo=[path]` option is specified for API CLI or `[ipfsnode] ipfs_repo=[path]` in Desktop `settings.ini` file. When there is no initialized IPFS repository in the given path it would be automatically initialized with the default 'server' IPFS profile for API CLI and with the default (client) profile for Desktop Client except the following custom BEAM settings:
+| Client type | IPFS node | Write operations | Read operations |
+|---|---|---|---|
+| Desktop wallet | Full local node (optional, starts on DApp launch by default) | `ipfs_add`, `ipfs_pin`, `ipfs_unpin`, `ipfs_gc` | `ipfs_get`, `ipfs_hash` |
+| `wallet-api` CLI | Full local node (opt-in: `--enable_ipfs=true`) | All methods | All methods |
+| Mobile / WASM clients | No local node | Not available (fail) | Via HTTP to BEAM-managed IPFS nodes |
-* `Swarm.ConnMgr.LowWater` - is set to `100`. Can be changed using `--ipfs_low_water` option in API CLI and using `[ipfsnode] ipfs_low_water=` in Desktop client 'settings.ini' file.
+The compile-time guard `BEAM_IPFS_SUPPORT` controls whether any of this code is included; builds without it expose none of the IPFS symbols.
-* `Swarm.ConnMgr.HighWater` - `200` / `--ipfs_high_water`, `settings.ini -> [ipfsnode] ipfs_high_water=`
+## Architecture
-* Swarm.ConnMgr.GracePeriod - `20s` / `--ipfs_grace_period`, `settings.ini -> [ipfsnode] ipfs_grace_period=` as uint32 seconds
+### Threading Model
-* Bootstrap - default BEAM bootstrap node(s) / `--ipfs_bootstrap` (space separated [multiaddr](https://github.com/multiformats/multiaddr) list), `settings.ini -> [ipfsnode] ipfs_bootstrap=`
+`IPFSService` (`wallet/ipfs/ipfs.h`) is the public interface. The underlying `asio_ipfs::node` runs on a dedicated **service thread** with its own `boost::asio::io_context`. All IPFS operations are non-blocking from the caller's perspective.
-* Addresses.Swarm - custom `10100` listening port / `--ipfs_swarm_port`, `settings.ini -> [ipfsnode] ipfs_swarm_port=`
+```cpp
+struct IPFSService {
+ struct Handler {
+ // Called from the IPFS service thread — must dispatch back to the
+ // wallet's reactor thread, not execute work inline.
+ virtual void AnyThread_pushToClient(std::function&&) = 0;
+ virtual void AnyThread_onStatus(const std::string& error, uint32_t peercnt) = 0;
+ };
-* Addresses.API - custom `/ip4/127.0.0.1/tcp/6100` listening address for API / empty (API disabled) on Desktop / `--ipfs_api_addr`, `settings.ini -> [ipfsnode] ipfs_api_addr=`
+ static Ptr AnyThread_create(HandlerPtr);
-* Addresses.Gateway - custom `/ip4/127.0.0.1/tcp/6200` listening address in API / empty (Gateway disabled) on Desktop / `--ipfs_gateway_addr`, `settings.ini -> [ipfsnode] ipfs_gateway_addr=`
+ // Calling thread becomes the service thread for this call
+ virtual void ServiceThread_start(asio_ipfs::config) = 0;
+ virtual void ServiceThread_stop() = 0;
-* Swarm.EnableAutoRelay - false in API / `true` on Desktop / `--ipfs_auto_relay`, `settings.ini -> [ipfsnode] ipfs_auto_relay=`
+ virtual bool AnyThread_running() const = 0;
+ virtual std::string AnyThread_id() const = 0;
-* Swarm.EnableRelayHop - `false` / `--ipfs_relay_hop`, `settings.ini -> [ipfsnode] ipfs_relay_hop=`
+ virtual void AnyThread_add (data, bool pin, timeout, res_cb, err_cb) = 0;
+ virtual void AnyThread_hash (data, timeout, res_cb, err_cb) = 0;
+ virtual void AnyThread_get (hash, timeout, res_cb, err_cb) = 0;
+ virtual void AnyThread_pin (hash, timeout, res_cb, err_cb) = 0;
+ virtual void AnyThread_unpin (hash, res_cb, err_cb) = 0;
+ virtual void AnyThread_gc (timeout, res_cb, err_cb) = 0;
+};
+```
-* Swarm.Transports.Network.Relay - forced to `true` everywhere. Not adjustable at the moment.
+Every method name prefixed `AnyThread_` is safe to call from any thread. Callbacks always arrive in the wallet's reactor thread via `Handler::AnyThread_pushToClient`, which posts through `PostToReactorThread` — an `io::AsyncEvent`-based cross-thread queue (`wallet/ipfs/ipfs_async.h`).
-* AutoNAT.ServiceMode - `enabled` / `--ipfs_autonat`, `settings.ini -> [ipfsnode] ipfs_autonat=` as bool
+### Startup Sequence
-* AutoNAT.Throttle.GlobalLimit - `30` / `--ipfs_autonat_limit`, `settings.ini -> [ipfsnode] ipfs_autonat_limit=`
+`ServiceThread_start` runs the `asio_ipfs::node::build` coroutine **synchronously** in the calling thread until the node is fully initialized (bootstrap connection established, swarm key accepted, peer ID derived). Only then does the dedicated service thread begin its event loop. This simplifies the startup flow at the cost of a potentially multi-second blocking call on first launch.
-* AutoNAT.Throttle.PeerLimit - `3` / `--ipfs_autonat_peer_limit`, `settings.ini -> [ipfsnode] ipfs_autonat_peer_limit=`
+## Configuration (`asio_ipfs::config`)
-* Datastore.StorageMax - `20GB` in API CLI / `2GB` in Desktop client / `--ipfs_storage_max`, `settings.ini -> [ipfsnode] ipfs_storage_max=`
+| Field | Desktop default | Server (`wallet-api`) default | CLI flag | `settings.ini` key |
+|---|---|---|---|---|
+| `repo_root` | `/ipfs-repo` | same | `--ipfs_repo` | `[ipfsnode] ipfs_repo` |
+| `storage_max` | `2GB` | `20GB` | `--ipfs_storage_max` | `[ipfsnode] ipfs_storage_max` |
+| `low_water` | `100` | `100` | `--ipfs_low_water` | `[ipfsnode] ipfs_low_water` |
+| `high_water` | `200` | `200` | `--ipfs_high_water` | `[ipfsnode] ipfs_high_water` |
+| `grace_period` | `20s` | `20s` | `--ipfs_grace_period` | `[ipfsnode] ipfs_grace_period` |
+| `swarm_port` | `10100` | `10100` | `--ipfs_swarm_port` | `[ipfsnode] ipfs_swarm_port` |
+| `api_address` | *(disabled)* | `/ip4/127.0.0.1/tcp/6100` | `--ipfs_api_addr` | `[ipfsnode] ipfs_api_addr` |
+| `gateway_address` | *(disabled)* | `/ip4/127.0.0.1/tcp/6200` | `--ipfs_gateway_addr` | `[ipfsnode] ipfs_gateway_addr` |
+| `routing_type` | `dht` | `dhtserver` | `--ipfs_routing_type` | `[ipfsnode] ipfs_routing_type` |
+| `auto_relay` | `true` | `false` | `--ipfs_auto_relay` | `[ipfsnode] ipfs_auto_relay` |
+| `relay_hop` | `false` | `false` | `--ipfs_relay_hop` | `[ipfsnode] ipfs_relay_hop` |
+| `autonat` | `true` | `true` | `--ipfs_autonat` | `[ipfsnode] ipfs_autonat` |
+| `autonat_limit` | `30` | `30` | `--ipfs_autonat_limit` | `[ipfsnode] ipfs_autonat_limit` |
+| `autonat_peer_limit` | `3` | `3` | `--ipfs_autonat_peer_limit` | `[ipfsnode] ipfs_autonat_peer_limit` |
+| `run_gc` | `true` | `false` | `--ipfs_run_gc` | `[ipfsnode] ipfs_run_gc` |
+| `bootstrap` | network defaults | network defaults | `--ipfs_bootstrap` (space-separated multiaddr list) | `[ipfsnode] ipfs_bootstrap` |
+| `peering` | network defaults | network defaults | — | — |
+| `swarm_key` | network default | network default | `--ipfs_swarm_key` | `[ipfsnode] ipfs_swarm_key` |
-* Routing.Type - `dhtserver` in API CLI / `dht` in Desktop client / `--ipfs_routing_type`, `settings.ini -> [ipfsnode] ipfs_routing_type=`
+### Network-Specific Bootstrap and Swarm Keys
-* swarm.key file is created to ensure connection to the BEAM private IPFS network / `--ipfs_swarm_key`, `settings.ini -> [ipfsnode] ipfs_swarm_key=` as string
+Beam operates a **private IPFS swarm** — nodes with a wrong or missing swarm key cannot join. Bootstrap nodes and swarm keys are injected automatically based on `Rules::get().m_Network`:
-* IPFS periodic GC is disabled in API CLI / launched in Desktop Client / `--ipfs_run_gc`, `settings.ini -> [ipfsnode] ipfs_run_gc=` as bool
+| Network | Bootstrap peers | Swarm key prefix |
+|---|---|---|
+| `mainnet` | `eu-node01..04.mainnet.beam.mw:38041` | `1fabcf9e…` |
+| `testnet` | `eu-node01..03.testnet.beam.mw:38041` | `1191aea7…` |
+| `masternet` | `3.19.32.148:38041` | `18502580…` |
+| `dappnet` | `3.16.160.95:38041` | `bf2f2063…` |
-* sockets-based activation for "io.ipfs.api" and "io.ipfs.gateway" is disabled at the moment and is not planned in the future. Contact us if you need this feature.
+All swarm keys use the PSK v1 format: `/key/swarm/psk/1.0.0/\n/base16/\n`.
-* WebUI is not supported and disabled, will be supported in the future
+If a custom `swarm_key` or `bootstrap` list is provided in config, the network defaults are ignored entirely for that field.
-* fuse mounts for "/ipfs" and "/ipfs" are not supported and disabled, will be supported in the future
+### `config.lock` — Preventing Config Overwrite
-* remote pinning for MFS roots is not supported and disabled, will be supported in the future
+On every startup Beam forcibly overwrites the BEAM-specific settings in `/config`. To suppress this (e.g., to preserve manual edits), create the file `/config.lock`. When this file is present, all BEAM-side config knobs — CLI flags, `wallet_api.cfg`, desktop settings — are ignored and the existing `config` file is used as-is.
-There are no changes in default IPFS repo layout, all default config and data files are and you are able to manage the IPFS repo via default IPFS cli tool paired with the `IPFS_PATH` environment variable. Ensure that BEAM client that uses the repo is not launched when accessing it using IPFS cli. In case of Desktop client's IPFS repo `ipfs_node_api_port`/`Addresses.API` setting should be specified before running daemon or it would crash. go-ipfs is unable to launch without API support.
+## Async API
-### ipfs-repo/config.lock file
+All six service methods follow the same pattern: submit a coroutine to the IPFS `io_context`, optionally attach a `boost::asio::steady_timer` for timeout enforcement, then marshal the result back to the wallet's reactor thread via `Handler::AnyThread_pushToClient`.
-This section describes BEAM extension to IPFS repo & config handling.
+| Method | Direction | Notes |
+|---|---|---|
+| `AnyThread_add(data, pin, timeout, res, err)` | local → IPFS network | Stores bytes; returns CID string. `pin=true` prevents GC from evicting the block. |
+| `AnyThread_hash(data, timeout, res, err)` | local only | Computes CID without storing (`calc_cid` internally). No network I/O. |
+| `AnyThread_get(hash, timeout, res, err)` | IPFS network → local | Fetches content by CID; returns raw bytes. |
+| `AnyThread_pin(hash, timeout, res, err)` | local bookkeeping | Marks a CID as pinned so GC will not remove it. |
+| `AnyThread_unpin(hash, res, err)` | local bookkeeping | Removes pin; timeout not applicable (local). |
+| `AnyThread_gc(timeout, res, err)` | local | Removes all un-pinned blocks from the local store. |
-On every start BEAM would force and overwrite the aforementioned BEAM custom settings in the `ipfs-repo/config` file. If you want to cancel this behavior, edit the `ipfs-repo/config` file manually or via cli and preserve your custom changes `ipfs-repo/config.lock` file should be created.
+Timeout is in milliseconds; pass `0` to disable timeout enforcement (unpin always uses `0`).
-If `ipfs-repo/config.lock` is present BEAM would not make any changes to the `ipfs-repo/config` file. All BEAM ways to change IPFS settings are immediately blocked and ignored including `--ipfs-xxx` CLI options, any IPFS options set in `wallet_api.cfg` file, any IPFS options set via desktop UI and any IPFS options set in desktop UI `settings.ini` file.
+### Wallet API Methods
-## Useful stuff
+These operations are also exposed as JSON-RPC methods in the wallet API (since v6.3), all tagged `APPS_ALLOWED` so DApp shaders can call them:
-### Access BEAM IPFS node using standard IPFS cli tool
+| JSON-RPC method | Access level | Async |
+|---|---|---|
+| `ipfs_add` | write | yes |
+| `ipfs_hash` | read | yes |
+| `ipfs_get` | write | yes |
+| `ipfs_pin` | write | yes |
+| `ipfs_unpin` | write | yes |
+| `ipfs_gc` | write | yes |
-1. Start wallet api
-2. Install go-ipfs
-3. Create beam-ipfs bash script (do not forget to change your paths)
+See the [Wallet API v7.0](api/Beam-wallet-protocol-API-v7.0.md) documentation for parameter schemas.
-```bash
-#/bin/bash
-export IPFS_PATH=/home/ubuntu/beam-api/ipfs-repo/
-# uncomment the following line if you're using private IPFS network
-# export LIBP2P_FORCE_PNET=1
-/home/ubuntu/go-ipfs-node/ipfs "$@"
-```
+## Interaction with Shader Invocation
-In desktop client IPFS node API is disabled by default. `ipfs_node_api_port` should be set in `settings.ini` or `Addresses.API` in `ipfs-repo/config` to access IPFS node API.
+When a DApp is opened in the desktop wallet, the wallet:
-4. Make it executable
+1. Reads the shader's embedded metadata to find the app shader's IPFS CID.
+2. Calls `AnyThread_get(cid, ...)` to fetch the UI bundle from IPFS.
+3. Starts a local IPFS node on demand (if not already running) via `IWThread_startIPFSNode`.
+4. Launches a sandboxed WebView pointing at the fetched bundle.
-```bash
-chmod +x ./beam_ipfs
-```
+The app shader running inside the WebView can call `ipfs_add`, `ipfs_get`, etc., through the DApp API (`wallet/client/apps_api/apps_api.h`). The DApp API checks whether an IPFS node is available (`hasIPFSNode`) at DApp launch time and logs a warning if it is not; read operations from mobile/WASM clients fall back to HTTP calls to BEAM-managed gateway nodes.
+
+## Repository Layout
-5. Execute usual ipfs commands via the script
+The IPFS repo lives at `/ipfs-repo` by default and is a standard go-ipfs repository. The standard IPFS CLI can inspect it:
```bash
-./beam-ipfs swarm peers
+export IPFS_PATH=/path/to/beam/ipfs-repo
+export LIBP2P_FORCE_PNET=1 # required for private swarm
+ipfs swarm peers
+ipfs pin ls
```
-### SystemD IPFS unit file
+Ensure the Beam wallet is not running when using the IPFS CLI against the same repo — both processes cannot hold the repo lock simultaneously.
-Example below if given for a standard go-ipfs binary. You can also use the same settings for running wallet API
+**Desktop note:** The IPFS API (`Addresses.API`) is disabled in the desktop client's default repo config. Set `ipfs_node_api_port` in `settings.ini` or add `Addresses.API` manually to `ipfs-repo/config` before starting, otherwise `ipfs daemon` will abort.
-```
-/etc/systemd/system/ipfs.service
-```
+### SystemD Unit (wallet-api)
-```
+```ini
[Unit]
-Description=GO IPFS Node
+Description=Beam Wallet API with IPFS
After=network.target
[Service]
Type=exec
Restart=on-failure
-Environment="IPFS_PATH=/home/ubuntu/go-ipfs-node/repo"
-# uncomment if private IPFS network
-# Environment="LIBP2P_FORCE_PNET=1"
-WorkingDirectory=/home/ubuntu/go-ipfs-node
-ExecStart=/home/ubuntu/go-ipfs-node/ipfs daemon
+WorkingDirectory=/home/beam/wallet-api
+ExecStart=/home/beam/wallet-api/wallet-api --enable_ipfs=true ...
[Install]
WantedBy=multi-user.target
```
+
+## Current Limitations
+
+- **WebUI** is disabled and not planned.
+- **FUSE mounts** (`/ipfs`, `/ipns`) are disabled and not planned.
+- **Remote MFS-root pinning** is not supported.
+- **Sockets-based activation** for `io.ipfs.api` / `io.ipfs.gateway` is not supported.
+- The IPFS startup is **synchronous** (blocks the calling thread until the node is connected); async startup is a noted TODO in the implementation.
+- Connect timeout lowering is also listed as a TODO; the initial peer connection may take several seconds on a cold start.
diff --git a/core-tech/BEAM-Mining.md b/core-tech/BEAM-Mining.md
index ded7049..53f01a4 100644
--- a/core-tech/BEAM-Mining.md
+++ b/core-tech/BEAM-Mining.md
@@ -17,7 +17,7 @@ At Mainnet launch, we will use the following Equihash parameters: **n=150**, **k
Note: in Testnet 3 we are still using **n=144**, **k=5**
-The minimal memory requirement for the GPU will be 4 GB. The most up-to-date list of supported GPUs will be available [here](https://github.com/BeamMW/beam/wiki/Supported-GPU-cards-for-mining-(NVIDIA)).
+The minimal memory requirement for the GPU will be 4 GB. The most up-to-date list of supported GPUs is available at [Supported nVidia Cards (OpenCL)](historical/Supported-nVidia-cards-for-mining-using-OpenCL-miner.md).
# Block Size and Time
A Beam block will be generated approximately every minute and contain about 1000 transactions. Block size will be roughly 1MB.
@@ -51,7 +51,7 @@ The external miner software is available for download [here](https://www.beam.mw
# How can you help?
* Want to help developing Beam mining infrastructure? Have GPU development skills or experience with mining pools? Write to us at mining@beam.mw. Fair compensation will be offered to qualified developers.
-* Own a mining farm and want to mine Beam at launch? Join Beam Mining community on Telegram or contact us at mining@beam.mw.
+* Own a mining farm and want to mine Beam? Join Beam Mining community on [Telegram](https://t.me/BeamMiners) or contact us at mining@beam.mw.
diff --git a/core-tech/Beam-Cpp-Style-And-Conventions.md b/core-tech/Beam-Cpp-Style-And-Conventions.md
new file mode 100644
index 0000000..9fdfff7
--- /dev/null
+++ b/core-tech/Beam-Cpp-Style-And-Conventions.md
@@ -0,0 +1,389 @@
+# Beam C++ Style and Conventions
+
+This page documents the C++ idioms, patterns, and conventions used throughout the Beam codebase. Its audience is contributors adding new code to `core/`, `node/`, `wallet/`, `bvm/`, or `utility/`.
+
+---
+
+## C++ Standard and Compiler Support
+
+The baseline standard is **C++17** (`CMAKE_CXX_STANDARD 17`), enforced as required. An optional C++20 mode exists via the CMake flag `-DBEAM_CPP_20_STANDARD=ON`, but the vast majority of the codebase targets C++17. Avoid C++20-only features in new code unless explicitly building under that flag.
+
+Supported compilers: GCC, Clang, and MSVC. Platform guards use `#ifdef WIN32`, `#if defined(__clang__)`, `#if defined(__GNUC__)`.
+
+---
+
+## Naming Conventions
+
+### Types and Classes
+
+All types use **PascalCase**: `NodeProcessor`, `TxKernel`, `WalletDB`, `HeightRange`, `Serializer`.
+
+Nested types follow the same rule: `NodeProcessor::Mapped::Utxo`, `Reactor::Object`, `Exc::Checkpoint`.
+
+### Data Members
+
+All data members carry an `m_` prefix:
+
+```cpp
+Height m_Height = 0;
+uint32_t m_Pos = 0;
+ECC::Hash::Value m_Hash;
+```
+
+Pointer members additionally use a `p` suffix on the prefix: `m_pData`, `m_pExternal`, `m_pNext`. This signals non-owning raw pointer semantics.
+
+Static data members use `s_`: `s_pInstance`, `s_pTop`.
+
+### Free Functions and Methods
+
+Both free functions and member functions use **PascalCase**: `HeightAdd`, `ZeroObject`, `GetTime_ms`, `ExportNnz`, `FromPubKey`. Utility helpers outside the `beam` namespace (in `utility/helpers.h`) may use `lower_snake_case` (`format_timestamp`, `local_timestamp_msec`).
+
+### Macros
+
+All macros use `UPPER_SNAKE_CASE` with the `BEAM_` prefix for public-API macros: `BEAM_LOG_ERROR`, `BEAM_VERIFY`, `BEAM_LOG_INFO`. Internal codegen macros omit the prefix but still use upper snake case: `COMPARISON_VIA_CMP`, `IMPLEMENT_GET_PARENT_OBJ`, `SERIALIZE`, `BIND_THIS_MEMFN`.
+
+---
+
+## Memory Ownership
+
+### The `Ptr` typedef
+
+Every class that participates in shared lifetime declares a `Ptr` member type alias:
+
+```cpp
+// Shared ownership — services, long-lived objects
+using Ptr = std::shared_ptr; // wallet/core/wallet.h
+using Ptr = std::shared_ptr; // wallet/core/wallet_db.h
+using Ptr = std::shared_ptr; // utility/io/reactor.h
+
+// Exclusive ownership — data objects with clear single owner
+typedef std::unique_ptr Ptr; // core/block_crypt.h
+typedef std::unique_ptr Ptr;
+using Ptr = std::unique_ptr; // utility/io/timer.h
+```
+
+Callers use `ClassName::Ptr` rather than spelling out the smart pointer type, so ownership semantics are expressed once at the declaration site.
+
+### Guidelines
+
+| Scenario | Type |
+|---|---|
+| Object with a single, clear owner (kernel, input, output) | `std::unique_ptr` |
+| Object shared between subsystems (wallet, reactor, DB) | `std::shared_ptr` |
+| Non-owning reference / observer | raw pointer (`T*`) or raw reference (`T&`) |
+| Optional pointer, not owned | raw pointer initialized to `nullptr` |
+
+`beam::Ptr<>` does not appear as a standalone alias in the codebase; ownership is expressed through the per-class `Ptr` typedef described above.
+
+---
+
+## Error Handling
+
+### `beam::Exc` — Recoverable Exceptions
+
+The primary exception type is `beam::Exc`, derived from `std::runtime_error`:
+
+```cpp
+struct Exc : public std::runtime_error {
+ uint32_t m_Type;
+
+ static void Fail(); // throws with empty message
+ static void Fail(const char*); // throws with message
+ static void Test(bool b) { if (!b) Fail(); }
+};
+```
+
+`Exc::Test(cond)` is the preferred assertion-to-exception idiom: it reads like a guard clause and avoids `if (!cond) throw`.
+
+### `Exc::Checkpoint` — Contextual Breadcrumbs
+
+`Exc::Checkpoint` is a thread-local linked list of context objects that are dumped when an exception is thrown. Concrete implementations provide a `Dump(std::ostream&)` override. `CheckpointTxt` is the lightweight string variant:
+
+```cpp
+Exc::CheckpointTxt cp("verifying kernel");
+// ... code that may throw ...
+// On exception, "verifying kernel" appears in the error output
+```
+
+The logger integrates with checkpoints via `BEAM_LOG_MESSAGE << FlushAllCheckpoints{}`.
+
+### `beam::CorruptionException` — Non-Recoverable Errors
+
+`CorruptionException` is intentionally not derived from `std::exception`. It signals database or block corruption that cannot be recovered in-process and should not be caught at intermediate call sites. It propagates to the top-level handler, which shuts down the node cleanly.
+
+### Network Errors: `proto::NodeConnection::OnDisconnect`
+
+Network layer errors do not throw; they invoke the virtual callback:
+
+```cpp
+virtual void OnDisconnect(const DisconnectReason&) {}
+```
+
+Subclasses override `OnDisconnect` to clean up connection state. The `DisconnectReason` carries an error code and a human-readable description. This pattern avoids exception propagation across async boundaries.
+
+---
+
+## Serialization
+
+### YAS Binary Archive
+
+Beam uses the **YAS** (Yet Another Serialization) library for binary serialization, configured as:
+
+```cpp
+constexpr int SERIALIZE_OPTIONS =
+ yas::binary | yas::no_header | yas::elittle | yas::compacted;
+```
+
+- `binary` — raw binary format, not JSON or text
+- `no_header` — no version header in the byte stream
+- `elittle` — explicit little-endian for all integers
+- `compacted` — variable-length encoding for integers
+
+### The `SERIALIZE(...)` Macro
+
+Structs declare serialization inline using the `SERIALIZE` macro from `utility/serialize_fwd.h`:
+
+```cpp
+struct HeightPos {
+ Height m_Height = 0;
+ uint32_t m_Pos = 0;
+
+ template void serialize(Archive& ar) const {
+ ar & m_Height & m_Pos;
+ }
+ template void serialize(Archive& ar) {
+ ar & m_Height & m_Pos;
+ }
+};
+// Equivalent — generated by:
+SERIALIZE(m_Height, m_Pos)
+```
+
+The macro generates both const and non-const overloads. Use the macro for new structs; spell it out only when custom logic is needed inside `serialize`.
+
+### `Serializer` and `Deserializer`
+
+```cpp
+// Write
+beam::Serializer ser;
+ser & myObject;
+auto [ptr, size] = ser.buffer();
+
+// Read
+beam::Deserializer deser;
+deser.reset(ptr, size);
+deser & myObject;
+```
+
+For fixed-size on-stack buffers use `StaticBufferSerializer` (default 100 KB). For size estimation without storing data, use `SerializerSizeCounter`.
+
+---
+
+## IO and Reactor Model
+
+### `io::Reactor`
+
+All async I/O runs through `io::Reactor`, a thin wrapper around **libuv**. A single reactor per thread owns the event loop:
+
+```cpp
+auto reactor = io::Reactor::create(); // returns Reactor::Ptr
+{
+ io::Reactor::Scope scope(*reactor); // registers as thread-local current reactor
+ reactor->run(); // blocks until reactor->stop() is called
+}
+```
+
+`Reactor::Scope` is an RAII guard that sets the thread-local current reactor. `Reactor::get_Current()` retrieves it from anywhere on that thread.
+
+### Timers
+
+```cpp
+io::Timer::Ptr timer = io::Timer::create(*reactor);
+timer->start(intervalMs, /*isPeriodic=*/true, [&]() {
+ // callback fires every intervalMs
+});
+```
+
+`Timer::Ptr` is `std::unique_ptr`. Destroying the `Ptr` cancels the timer. The callback is stored as `std::function`.
+
+### TCP Connections
+
+TCP connect/accept use `std::function` callbacks passed at connection time:
+
+```cpp
+reactor->tcp_connect(address, tag,
+ [](uint64_t tag, std::unique_ptr&& stream, io::ErrorCode ec) {
+ if (ec != 0) { /* handle error */ return; }
+ // stream is ready
+ },
+ timeoutMs
+);
+```
+
+All network objects (`TcpStream`, `TcpServer`, `SslStream`) inherit from `Reactor::Object`, which owns a `uv_handle_t*` and a `Reactor::Ptr` back-reference.
+
+### `GracefulIntHandler`
+
+`Reactor::GracefulIntHandler` catches `SIGINT`/`SIGTERM` (or `Ctrl+C` on Windows) and calls `reactor->stop()`. Instantiate one per process to get clean shutdown behaviour:
+
+```cpp
+io::Reactor::GracefulIntHandler intHandler(*reactor);
+reactor->run();
+```
+
+---
+
+## RAII Scope Guards
+
+The `Scope` pattern recurs throughout Beam to set thread-local or global context for the lifetime of a block:
+
+| Class | What it sets |
+|---|---|
+| `io::Reactor::Scope` | Current reactor on this thread |
+| `Executor::Scope` | Current parallel executor on this thread |
+| `Rules::Scope` | Consensus parameters (used in tests to override fork heights) |
+| `NodeDB::Transaction` | Database transaction |
+
+All follow the same pattern: constructor records the previous value, destructor restores it.
+
+---
+
+## Common Macros
+
+### `IMPLEMENT_GET_PARENT_OBJ`
+
+Used when an inner struct needs access to its enclosing object without storing an explicit back-pointer. It computes the parent pointer arithmetically from `this` using offsetof-style arithmetic:
+
+```cpp
+struct DB : public NodeDB {
+ void OnModified() override { get_ParentObj().OnModified(); }
+ IMPLEMENT_GET_PARENT_OBJ(NodeProcessor, m_DB)
+} m_DB;
+```
+
+The generated `get_ParentObj()` returns a reference to the enclosing `NodeProcessor`. An `assert` in the macro validates the pointer computation in debug builds.
+
+### `COMPARISON_VIA_CMP`
+
+Generates all six comparison operators from a single `int cmp(const T&) const` method:
+
+```cpp
+struct Blob {
+ int cmp(const Blob&) const;
+ COMPARISON_VIA_CMP
+};
+```
+
+### `BIND_THIS_MEMFN(M)`
+
+Wraps a member function pointer into a `std::function` lambda bound to `this`:
+
+```cpp
+reactor->tcp_connect(addr, tag, BIND_THIS_MEMFN(OnConnected), timeout);
+// equivalent to:
+// std::bind_memfn(this, &ClassName::OnConnected)
+```
+
+### `BEAM_VERIFY(x)`
+
+Like `assert`, but preserves the expression in release builds as a void cast (side-effect safe, no check). Use for expressions that must be evaluated in release but whose failure is non-fatal in production.
+
+---
+
+## X-Macro Pattern for Message Types
+
+The node-to-node protocol (`core/proto.h`) uses **X-macros** to declare all message types once and expand them into struct definitions, handler declarations, and dispatch tables:
+
+```cpp
+// Declaration: each message lists its fields
+#define BeamNodeMsg_NewTip(macro) \
+ macro(Block::SystemState::Full, Description)
+
+// Expansion: generates struct NewTip { Block::SystemState::Full Description; };
+// and virtual void OnMsg(NewTip&&) {} in NodeConnection
+```
+
+The same macro set is used to generate serialization code and the handler virtual methods. Adding a new message type requires only a new `BeamNodeMsg_Foo(macro)` definition and adding `Foo` to the `BeamNodeMsgsAll` list.
+
+---
+
+## Logging
+
+All logging goes through the `beam::Logger` singleton, accessed via macros:
+
+```cpp
+BEAM_LOG_INFO() << "processing block " << height;
+BEAM_LOG_WARNING() << "unexpected state: " << TRACE(value);
+BEAM_LOG_ERROR() << "failed to apply tx: " << errorCode;
+```
+
+The macros check `Logger::will_log(level)` before constructing the `LogMessage` object, so disabled log levels cost nothing. In release builds (`NDEBUG`), `BEAM_LOG_DEBUG()` and `BEAM_LOG_VERBOSE()` expand to a no-op `LogMessageStub` that is optimized away entirely.
+
+`TRACE(var)` is a shorthand that emits `" var="` for quick variable printing.
+
+Logger instances are created as `std::shared_ptr` RAII objects; when all references are released the logger is flushed and torn down.
+
+---
+
+## CMake Module Structure
+
+### Adding a New Library
+
+The standard pattern, illustrated by `core/CMakeLists.txt`:
+
+```cmake
+set(MY_LIB_SRC
+ file1.cpp
+ file2.cpp
+)
+add_library(mylib STATIC ${MY_LIB_SRC})
+target_link_libraries(mylib
+ PUBLIC
+ utility # exposed in headers
+ Boost::boost
+ PRIVATE
+ secp256k1 # implementation detail only
+)
+```
+
+- **`PUBLIC` dependencies** propagate to consumers of `mylib`.
+- **`PRIVATE` dependencies** are hidden; consumers do not need them.
+
+### Test Subdirectories
+
+Unit tests live in `unittest/` subdirectories and are guarded by a CMake option:
+
+```cmake
+if(BEAM_TESTS_ENABLED)
+ add_subdirectory(unittest)
+endif()
+```
+
+This keeps test binaries out of production builds. Test targets are plain executables registered with `add_test()` via the `AddTest` module included at the top level.
+
+### Beam Interface Target
+
+A top-level `INTERFACE` target named `beam` carries the global include path and feature requirements:
+
+```cmake
+add_library(beam INTERFACE IMPORTED GLOBAL)
+target_include_directories(beam INTERFACE
+ ${PROJECT_SOURCE_DIR}
+ ${PROJECT_SOURCE_DIR}/3rdparty)
+target_compile_features(beam INTERFACE cxx_std_17)
+```
+
+All library targets link against `beam` to pick up the include path and standard requirement.
+
+---
+
+## Unit Test Conventions
+
+Test files live in `unittest/` inside the relevant subsystem directory:
+
+- `core/unittest/ecc_test.cpp`, `core/unittest/storage_test.cpp`
+- `node/unittests/`
+
+There is no single test framework dependency. Tests are standalone executables that `assert()` or call a lightweight `BEAM_VERIFY` helper. Each test file includes directly from its parent subsystem using relative paths (`../ecc_native.h`).
+
+Tests that need to manipulate consensus parameters use `Rules::Scope` to override fork heights, then restore the original state on exit.
diff --git a/core-tech/Beam-Equihash-specification.md b/core-tech/Beam-Equihash-specification.md
deleted file mode 100644
index 08eccab..0000000
--- a/core-tech/Beam-Equihash-specification.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Beam Equihash specification
-
-## Chosen parameters
-`N = 150`
-`K = 5`
-
-## Hash generation convention
-Since 150 in not a multiple of 8 we pick 19 full bytes and clear lower 2 bits of 18th byte.
-We can get only 3 hashes from 512-bit **blake2** output.
-Expected blake2 hash output size is `3 * 19 = 57` bytes
-
-
-## Implementation for CPU
-Beam’s Equihash implementation for CPU is based on zcash’s version.
-[https://github.com/BeamMW/beam/blob/master/3rdparty/crypto/equihash_impl.cpp](https://github.com/BeamMW/beam/blob/master/3rdparty/crypto/equihash_impl.cpp)
\ No newline at end of file
diff --git a/core-tech/Beam-Node-Explorer-API.md b/core-tech/Beam-Node-Explorer-API.md
deleted file mode 100644
index 487327f..0000000
--- a/core-tech/Beam-Node-Explorer-API.md
+++ /dev/null
@@ -1,243 +0,0 @@
-
-
-# Beam Node Explorer API
-
-The Node Explorer provides information about current chain state and blocks.
-
-## How to use
-
-Find `explorer-node` binary in the `explorer` subdirectory and run with the following arguments:
-
-```
-Node explorer options:
- -h [ --help ] list of all options
- --peer arg (=172.104.249.212:8101) peer address
- --port arg (=10000) port to start the local node on
- --api_port arg (=8888) port to start the local api server on
-```
-
-`./explorer-node.exe --peer eu-node01.mainnet.beam.mw:8100 --api_port=8080` for example.
-It may take some time (a few hours) on the first start to load all the info from chain.
-
-## API
-
-### status
-
-`GET http://x.x.x.x:port/status`
-
-_Description_: Gets current blockchain status.
-
-_Response_:
-```json
-{
- "chainwork": "0x38594101d0a0",
- "hash": "7353b5e4ad29a2ffa5f7952749d1eb04acedd82215b1f4f01d75107165f4622b",
- "height": 20531,
- "low_horizon": 19090,
- "timestamp": 1550158283,
- "shielded_outputs_per_24h": 14,
- "shielded_outputs_total": 16919,
- "shielded_possible_ready_in_hours": 120
-}
-```
-***
-### block
-
-`GET http://x.x.x.x:port/block?height={height}`
-or
-`GET http://x.x.x.x:port/block?hash={hash}`
-or
-`GET http://x.x.x.x:port/block?kernel={kernel}`
-
-_Description_: Gets block info for specified `height`, `hash` or `kernel`.
-
-_Response_:
-```json
-{
- "chainwork": "0x384fdc718a20",
- "difficulty": 157.9972152709961,
- "found": true,
- "hash": "c2a7315b63b1de6106a185c1c79219001ef5e3a07c217db227b079bbb9dd9b64",
- "height": 20516,
- "inputs": [],
- "kernels": [
- {
- "excess": "0x60413b5a09858312403190721938463ca22d7d87981a024873ddfa204a399eec",
- "fee": 0,
- "id": "d72684dba6255b2fe8631be9df764ee3c984cb0c9f386a8cf71f566acebd197d",
- "maxHeight": 18446744073709552000,
- "minHeight": 20516
- }
- ],
- "outputs": [
- {
- "coinbase": true,
- "commitment": "0x75329071d041e7828a57cbf2f63fb8db21543f35c1c2291d5c26c20d9b11465a",
- "incubation": 0,
- "maturity": 20756
- }
- ],
- "prev": "4b9e35b467b416e0d307dd94bd2fdce6e720b6b3a029dca822ccab3ac57c6d22",
- "subsidy": 8000000000,
- "rate_btc": "0.00001551",
- "rate_usd": "0.231282",
- "timestamp": 1550157362
-}
-```
-***
-### blocks
-
-`GET http://x.x.x.x:port/blocks?height={start}&n={count}`
-
-_Description_: Gets blocks info for specified range, where `count` should be <= 1500.
-
-_Response_:
-```json
-[
- {
- "chainwork": "0x380b69b2d420",
- "difficulty": 161.94402313232422,
- "found": true,
- "hash": "2107b173f174972c8ec7543ab731bf1905d24d101f45b42d5f0cd64853e4c38e",
- "height": 20402,
- "inputs": [],
- "kernels": [
- {
- "excess": "0x3829270cf74d473af83015501a83747b5b8c75c0d13303569a352bfe53b4ef4b",
- "fee": 0,
- "id": "3d0bed1e452c911f830351c671696f51e4a6a9086aeb7a059fc027a0db9c84a0",
- "maxHeight": 18446744073709552000,
- "minHeight": 20402
- }
- ],
- "outputs": [
- {
- "coinbase": true,
- "commitment": "0xb4261a4a7fabe181f6dd7e766410cf1aba8892fd2f41d3a7ff9378a4811521ff",
- "incubation": 0,
- "maturity": 20642
- }
- ],
- "prev": "09cf95acda1e9c3e8b1a45873fd9ef1d744d6645d16bd6b8c5e9ae8dfe2d0b1a",
- "subsidy": 8000000000,
- "rate_btc": "0.00001551",
- "rate_usd": "0.231282",
- "timestamp": 1550150788
- },
- {
- "chainwork": "0x380ac7c128a0",
- "difficulty": 162.0944366455078,
- "found": true,
- "hash": "09cf95acda1e9c3e8b1a45873fd9ef1d744d6645d16bd6b8c5e9ae8dfe2d0b1a",
- "height": 20401,
- "inputs": [],
- "kernels": [
- {
- "excess": "0x554a6ef457d33abddcb98169fcd7fe68a7aa94bc2145a40f39d07ace7b43c0de",
- "fee": 0,
- "id": "c68cddd64a07974a1d5ea73eb4333a9b732a5b9ac705546217fa66d2ba5e8dd8",
- "maxHeight": 18446744073709552000,
- "minHeight": 20401
- }
- ],
- "outputs": [
- {
- "coinbase": true,
- "commitment": "0x6fd9e1124f91a744c7043f2873716094e1a6cc3a8ae9ca5278a1a421a7622301",
- "incubation": 0,
- "maturity": 20641
- }
- ],
- "prev": "9a8053f05ed7b6575770e002100025fa58452e307cf73d3594cbcd861fa5035a",
- "subsidy": 8000000000,
- "rate_btc": "0.00001551",
- "rate_usd": "0.231282",
- "timestamp": 1550150719
- },
- {
- "chainwork": "0x380a25a8fba0",
- "difficulty": 161.4037857055664,
- "found": true,
- "hash": "9a8053f05ed7b6575770e002100025fa58452e307cf73d3594cbcd861fa5035a",
- "height": 20400,
- "inputs": [],
- "kernels": [
- {
- "excess": "0x7eef6fa3449e87dde801fec11cd6cec8b448a87f7bd1231cff668904ee6045d5",
- "fee": 0,
- "id": "bee59b34ea59a95e9fb415d34de3cc34416debcc1e14fd993f749b2aaee9b14d",
- "maxHeight": 18446744073709552000,
- "minHeight": 20400
- }
- ],
- "outputs": [
- {
- "coinbase": true,
- "commitment": "0x3b8a5d665b08119b8b8ee98c831089e0f7b3219ee92b3cf9d749777349ffd285",
- "incubation": 0,
- "maturity": 20640
- }
- ],
- "prev": "34ce853ef5d9b6878bb694b5eec0620217d2b5f68f36cfdfc9c3bd4f1ae67107",
- "subsidy": 8000000000,
- "rate_btc": "0.00001551",
- "rate_usd": "0.231282",
- "timestamp": 1550150667
- }
-]
-```
-***
-### swap totals
-
-`GET http://x.x.x.x:port/swap_totals`
-
-_Description_: Return total amounts for all swap offers.
-
-_Response_:
-```json
-{
- "beams_offered": "15",
- "bicoin_cash_offered": "3",
- "bitcoin_offered": "0",
- "dash_offered": "0",
- "dogecoin_offered": "0",
- "litecoin_offered": "10",
- "qtum_offered": "0",
- "total_swaps_count": 2
-}
-```
-***
-### swap offers
-
-`GET http://x.x.x.x:port/swap_offers`
-
-_Description_: Return swap offers from offer board.
-
-_Response_:
-```json
-[
- {
- "beam_amount": "3",
- "height_expired": 253126,
- "min_height": 252406,
- "status": 0,
- "status_string": "pending",
- "swap_amount": "3",
- "swap_currency": "BCH",
- "time_created": "2020.11.06 18:31:54",
- "txId": "1b726d0adffe45c993b801c8bb46184e"
- },
- {
- "beam_amount": "12",
- "height_expired": 253126,
- "min_height": 252406,
- "status": 0,
- "status_string": "pending",
- "swap_amount": "10",
- "swap_currency": "LTC",
- "time_created": "2020.11.06 18:31:39",
- "txId": "1b837edae2904b658f95a7b5e84c7731"
- }
-]
-```
-***
\ No newline at end of file
diff --git a/core-tech/Beam-Technical-Specifications.md b/core-tech/Beam-Technical-Specifications.md
index 360f8a7..aa7a176 100644
--- a/core-tech/Beam-Technical-Specifications.md
+++ b/core-tech/Beam-Technical-Specifications.md
@@ -1,12 +1,10 @@
BEAM implements the MW protocol (with some extensions), which is based on elliptic curve cryptography (ECC).
-* [Cryptographic primitives](https://github.com/beam-mw/beam/wiki/Cryptographic-primitives)
-* [Merkle trees](https://github.com/beam-mw/beam/wiki/Merkle-trees)
- * [DMMR layout](https://github.com/beam-mw/beam/wiki/DMMR-internal-layout)
-* [Core transaction elements](https://github.com/beam-mw/beam/wiki/Core-transaction-elements)
-* [Blocks, headers, System States: concept, relevant structures and values](https://github.com/beam-mw/beam/wiki/System-state,-header,-block)
-* [System State in-depth](https://github.com/beam-mw/beam/wiki/System-state-in-depth)
-* Node
- * [Initial synchronization](https://github.com/beam-mw/beam/wiki/Node-initial-synchronization)
-* [Secure bulletin board system (SBBS)](https://github.com/BeamMW/beam/wiki/Secure-bulletin-board-system-(SBBS))
-* [Beam Equihash specification](https://github.com/BeamMW/beam/wiki/Beam-Equihash-specification)
\ No newline at end of file
+* [Cryptographic primitives](core/Core-Cryptographic-Primitives.md)
+* [Merkle trees](core/Core-Merkle-Structures.md)
+ * [DMMR layout](core/Core-Merkle-Structures.md)
+* [Core transaction elements](core/Core-transaction-elements.md)
+* [Blocks, headers, System States: concept, relevant structures and values](core/Core-Block-And-Chain-State.md)
+* [System State in-depth](core/Core-Block-And-Chain-State.md)
+* [Secure bulletin board system (SBBS)](wallet/Wallet-SBBS.md)
+* [Beam Equihash specification](consensus/Consensus-BeamHash.md)
diff --git a/core-tech/Beam-Wallet-Database.md b/core-tech/Beam-Wallet-Database.md
deleted file mode 100644
index 50d649e..0000000
--- a/core-tech/Beam-Wallet-Database.md
+++ /dev/null
@@ -1,100 +0,0 @@
-Since in Mimblewimble only UTXO related information is available on chain, most of the Wallet state should be maintained locally and store in the Wallet Database, which is described in this chapter.
-
-Beam Wallet stores and tracks information about four key entities:
-1. Coins
-2. Addresses
-3. Transactions
-4. Blockchain State
-
-The interface for the database is specified in the [wallet_db.h](https://github.com/BeamMW/beam/blob/56e9cdd7be211649a576fa15d3f0a97922ae2acd/wallet/wallet_db.h#L164) file
-
-Beam currently uses sqlite relational database in the implementation
-
-# Coins
-
-We will start with the [definition](https://github.com/BeamMW/beam/blob/56e9cdd7be211649a576fa15d3f0a97922ae2acd/wallet/wallet_db.h#L41) of a Coin structure, which represents a UTXO as it is seen by the wallet.
-
-```c++
-
- // Describes a UTXO in the context of the Wallet
- struct Coin
- {
- // Status is not stored in the database but can be
- // deduced from the current blockchain state
- enum Status
- {
- Unavailable, // initial status of a new UTXO
- Available, // UTXO is currently present in the chain and can be spent
- Maturing, // UTXO is present in the chain has maturity higher than current height (i.e coinbase or treasury)
- Outgoing, // Available and participates in outgoing transaction
- Incoming, // Outputs of incoming transaction, currently unavailable
- ChangeV0, // deprecated.
- Spent, // UTXO that was spent. Stored in wallet database until reset or restore
-
- count
- };
-
- Coin(Amount amount = 0, Key::Type keyType = Key::Type::Regular);
- bool operator==(const Coin&) const;
- bool operator!=(const Coin&) const;
- bool isReward() const;
- std::string toStringID() const;
- Amount getAmount() const;
-
- typedef Key::IDV ID; // unique identifier for the coin (including value), can be used to create blinding factor
- ID m_ID;
-
- Status m_status; // current status of the coin
- Height m_maturity; // coin can be spent only when chain is >= this value. Valid for confirmed coins (Available, Outgoing, Incoming, Change, Spent, Maturing).
-
- // The following fields are used to derive the status of the transaction
- Height m_confirmHeight; // height at which the coin was confirmed (appeared in the chain)
- Height m_spentHeight; // height at which the coin was spent
-
- boost::optional m_createTxId; // id of the transaction which created the UTXO
- boost::optional m_spentTxId; // id of the transaction which spernt the UTXO
-
- uint64_t m_sessionId; // Used in the API to lock coins for specific session (see https://github.com/BeamMW/beam/wiki/Beam-wallet-protocol-API#tx_split)
-
- bool IsMaturityValid() const; // is/was the UTXO confirmed?
- Height get_Maturity() const; // would return MaxHeight unless the UTXO was confirmed
-
- std::string getStatusString() const;
- static boost::optional FromString(const std::string& str);
- };
-```
-
- ## Deducing Coin Status
-
-By monitoring the state of the blockchain, the wallet can always deduce the current status of each coin by tracking the m_confirmHeight height and m_spentHeight. This is done in the `void DeduceStatus(const IWalletDB&, Coin&, Height hTop);` method which calls the `Coin::Status GetCoinStatus(const IWalletDB&, const Coin&, Height hTop);` method that in turn returns the current status of the coin.
-
-```c++
-
-Coin::Status GetCoinStatus(const IWalletDB& walletDB, const Coin& c, Height hTop)
-{
- if (c.m_spentHeight != MaxHeight)
- return Coin::Status::Spent;
-
- if (c.m_confirmHeight != MaxHeight)
- {
- if (c.m_maturity > hTop)
- return Coin::Status::Maturing;
-
- if (IsOngoingTx(walletDB, c.m_spentTxId))
- return Coin::Status::Outgoing;
-
- return Coin::Status::Available;
- }
-
- if (IsOngoingTx(walletDB, c.m_createTxId))
- return Coin::Status::Incoming;
-
- return Coin::Status::Unavailable;
-}
-```
-
-## Selecting coins for a specified amount
-
-Implemented in the `std::vector selectCoins(Amount amount) override;` method. The purpose of the function is to select Coins matching a specific amount (for example in sending scenario). Selection method should minimize number of Coins and the change outputs and hence use greedy strategy with some additional heuristics. Specific strategies for coin selection are implemented in the `struct CoinSelector3` in honor of three attempts to write an effective selector for large amount of coins.
-
-
\ No newline at end of file
diff --git a/core-tech/Beam-Web-Wallet-Starter-Kit.md b/core-tech/Beam-Web-Wallet-Starter-Kit.md
index 19fc46f..58fda1b 100644
--- a/core-tech/Beam-Web-Wallet-Starter-Kit.md
+++ b/core-tech/Beam-Web-Wallet-Starter-Kit.md
@@ -1,5 +1,3 @@
-
-
# Beam Web Wallet Starter Kit [working draft]
Web wallet starter allows you easily integrate Beam with your service, create a bunch of wallets and manage them... (TODO)
@@ -139,7 +137,7 @@ Here is an example: