Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: commerceblockx
username: mercurylayer
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
-
name: Set up Docker Buildx
Expand All @@ -35,28 +35,28 @@ jobs:
context: .
file: ./server/Dockerfile
push: true
tags: commerceblockx/mercury-server:${{ env.COMMIT_HASH }}
tags: mercurylayer/mercury-server:${{ env.COMMIT_HASH }}
-
name: Build and push for token-server
uses: docker/build-push-action@v5
with:
context: .
file: ./token-server/Dockerfile
push: true
tags: commerceblockx/token-server:${{ env.COMMIT_HASH }}
tags: mercurylayer/token-server:${{ env.COMMIT_HASH }}
-
name: Build and push for mercury-explorer
uses: docker/build-push-action@v5
with:
context: .
file: ./explorer/Dockerfile
push: true
tags: commerceblockx/mercury-explorer:${{ env.COMMIT_HASH }}
tags: mercurylayer/mercury-explorer:${{ env.COMMIT_HASH }}
-
name: Build and push for keylist-cronjob
uses: docker/build-push-action@v5
with:
context: .
file: ./keylistCron/Dockerfile
push: true
tags: commerceblockx/keylist-cronjob:${{ env.COMMIT_HASH }}
tags: mercurylayer/keylist-cronjob:${{ env.COMMIT_HASH }}
34 changes: 33 additions & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[workspace]
members = ["clients/apps/rust", "clients/libs/rust", "server", "wasm", "lib", "token-server", "clients/tests/rust"]
members = ["clients/apps/rust", "clients/libs/rust", "server", "wasm", "lib", "token-server", "clients/tests/rust", "token-server-v2"]
exclude = ["clients/apps/kotlin", "clients/apps/nodejs", "clients/apps/react-app", "clients/libs/nodejs", "docs", "enclave", "explorer", "keylistCron"]
resolver = "2"
72 changes: 72 additions & 0 deletions Test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Running Rust tests

1. `$ docker compose -f docker-compose-token-servers.yml up --build` to run the Mercury and token servers. This also starts a Esplora node.

2. Run the commands below to start the Bitcoin network.

```bash
$ container_id=$(docker ps -qf "name=esplora-container")
$ wallet_name="esplora_wallet"
$ docker exec $container_id cli createwallet $wallet_name
$ address=$(docker exec $container_id cli getnewaddress $wallet_name)
$ docker exec $container_id cli generatetoaddress 101 "$address"
```

3. `cd clients/tests/rust/`

4. `cargo run`

# Running Web tests

1. `$ docker compose -f docker-compose-token-servers.yml up --build` to run the Mercury and token servers. This also starts a Esplora node.

2. `$ docker compose -f docker-compose-token-lnd-nodes.yml up --build` to start LND nodes to test lightning latch functions.

3. Run the commands below to start the Bitcoin network.

```bash
$ container_id=$(docker ps -qf "name=esplora-container")
$ wallet_name="esplora_wallet"
$ docker exec $container_id cli createwallet $wallet_name
$ address=$(docker exec $container_id cli getnewaddress $wallet_name)
$ docker exec $container_id cli generatetoaddress 101 "$address"
```

4. Run the commands below to start and set up the LND nodes.

```bash
$ container_id=$(docker ps -qf "name=mercurylayer-bitcoind-1")
$ wallet_name="new_wallet"
$ docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet $wallet_name
$ address=$(docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass getnewaddress $wallet_name)
$ docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass generatetoaddress 101 "$address"
$ container_id_alice=$(docker ps -qf "name=mercurylayer-alice-1")
$ container_id_bob=$(docker ps -qf "name=mercurylayer-bob-1")
$ identity_pubkey_bob=$(docker exec $container_id_bob lncli -n regtest getinfo | jq -r '.identity_pubkey')
$ docker exec $container_id_alice lncli -n regtest connect $identity_pubkey_bob@bob:9735
$ address=$(docker exec $container_id_bob lncli -n regtest newaddress p2wkh | jq -r '.address')
$ container_id_bitcoind=$(docker ps -qf "name=mercurylayer-bitcoind-1")
$ docker exec $container_id_bitcoind bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass sendtoaddress $address 0.5
$ docker exec $(docker ps -qf "name=mercurylayer-bitcoind-1") bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass -generate 6
$ identity_pubkey_alice=$(docker exec $container_id_alice lncli -n regtest getinfo | jq -r '.identity_pubkey')
$ docker exec $container_id_bob lncli -n regtest openchannel $identity_pubkey_alice 100000
$ docker exec $(docker ps -qf "name=mercurylayer-bitcoind-1") bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass -generate 5
```


5. Install the nodejs components and run the tests:

```bash
$ cd clients/libs/web
$ npm i
$ cd ../../tests/web
$ npm i
$ npm install chai
$ node server-regtest.cjs # start the test server
$ npx vitest --browser.name=chromium --browser.headless --reporter=basic --disable-console-intercept
```

# Other Environments

The `docker compose -f docker-compose-token-servers.yml` file can be used to build a Mercury Layer infrastructure in test or production environments as it has all the necessary servers including Lockbox, Electrs/Esplora, Token, and Mercury.
The default values ​​of this file however must be changed.
6 changes: 2 additions & 4 deletions clients/apps/nodejs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ async function main() {

program.command('new-token')
.description('Get new token.')
.argument('<wallet_name>', 'name of the wallet')
.action(async (wallet_name) => {

const token = await mercurynodejslib.newToken(clientConfig, wallet_name);
.action(async () => {
const token = await mercurynodejslib.newToken(clientConfig);
console.log(JSON.stringify(token, null, 2));

});
Expand Down
4 changes: 2 additions & 2 deletions clients/apps/rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ async fn main() -> Result<()> {
println!("Wallet created: {:?}", wallet);
},
Commands::NewToken { } => {
let token_id = mercuryrustlib::deposit::get_token(&client_config).await?;
let token_response = mercuryrustlib::deposit::get_token(&client_config).await?;

let obj = json!({"token": token_id});
let obj = json!(token_response);

println!("{}", serde_json::to_string_pretty(&obj).unwrap());
},
Expand Down
6 changes: 3 additions & 3 deletions clients/libs/rust/src/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ pub async fn init(client_config: &ClientConfig, wallet: &Wallet, token_id: uuid:
Ok(wallet)
}

pub async fn get_token(client_config: &ClientConfig) -> Result<String> {
pub async fn get_token(client_config: &ClientConfig) -> Result<mercurylib::deposit::TokenResponse> {

let endpoint = client_config.statechain_entity.clone();
let path = "deposit/get_token";
Expand All @@ -138,7 +138,7 @@ pub async fn get_token(client_config: &ClientConfig) -> Result<String> {

let value = response.text().await?;

let token: mercurylib::deposit::TokenID = serde_json::from_str(value.as_str())?;
let token: mercurylib::deposit::TokenResponse = serde_json::from_str(value.as_str())?;

return Ok(token.token_id);
return Ok(token);
}
1 change: 1 addition & 0 deletions clients/libs/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub use mercurylib::transfer::sender::{TransferSenderRequestPayload, TransferSen
pub use mercurylib::transaction::{SignFirstRequestPayload, SignFirstResponsePayload, create_and_commit_nonces};
pub use mercurylib::utils::get_blockheight;
pub use mercurylib::{validate_address, decode_transfer_address};
pub use mercurylib::deposit::TokenResponse;

pub fn add(left: usize, right: usize) -> usize {
left + right
Expand Down
78 changes: 26 additions & 52 deletions clients/libs/web/deposit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,8 @@ import wasmUrl from 'mercury-wasm/mercury_wasm_bg.wasm?url'
import * as mercury_wasm from 'mercury-wasm';
import storageManager from './storage_manager.js';
import transaction from './transaction.js';
import CoinStatus from './coin_enum.js';
import utils from './utils.js';

/* const getTokenFromServer = async (clientConfig) => {

const statechain_entity_url = clientConfig.statechainEntity;
const path = "tokens/token_init";
const url = statechain_entity_url + '/' + path;

const response = await axios.get(url);

if (response.status != 200) {
throw new Error(`Token error: ${response.data}`);
}

let token = response.data;

return token;
} */

const getTokenFromServer = async (clientConfig) => {

const statechain_entity_url = clientConfig.statechainEntity;
Expand All @@ -42,26 +24,8 @@ const getTokenFromServer = async (clientConfig) => {
return token;
}

const getToken = async (clientConfig, walletName) => {

let wallet = storageManager.getWallet(walletName);

let token = await getTokenFromServer(clientConfig);

// for dev purposes
token.confirmed = true;
token.spent = false
token.btc_payment_address = "b1qdgjdmmsdp5hkrhwl6cxd3uvt6hvjvlmmzucdca";
token.fee = "0.0001";
token.lightning_invoice = "lnbc10u1pj3knpdsp5k9f25s2wpzewkf9c78pftkgnkuuz82erkcjml7zkgsp7znyhs5yspp5rxz3tkc7ydgln3u7ez6duhp0g6jpzgtnn7ph5xrjy6muh9xm07wqdp2f9h8vmmfvdjjqen0wgsy6ctfdeehgcteyp6x76m9dcxqyjw5qcqpj9qyysgq6z9whs8am75r6mzcgt76vlwgk5g9yq5g8xefdxx6few6d5why7fs7h5g2dx9hk7s60ywtnkyc0f3p0cha4a9kmgkq5jvu5e7hvsaawqpjtf8p4";
token.processor_id = "1";
token.expiry = "2024-12-26T17:29:50.013Z";

wallet.tokens.push(token);

storageManager.updateWallet(wallet);

return token;
const getToken = async (clientConfig) => {
return await getTokenFromServer(clientConfig);
}

const init = async (clientConfig, wallet, token_id) => {
Expand All @@ -78,11 +42,29 @@ const init = async (clientConfig, wallet, token_id) => {
const path = "deposit/init/pod";
const url = statechain_entity_url + '/' + path;

const response = await axios.post(url, depositMsg1);
let response = null;
try {
response = await axios.post(url, depositMsg1);
} catch (error) {
// Get error message from response body
let err_msg = "";
if (error.response) {
// Server responded with error
console.log('Error body:', error.response.data);
err_msg = error.response.data;
} else if (error.request) {
// Request made but no response received
console.log('No response received:', error.request);
err_msg = error.request;
} else {
// Error setting up request
console.log('Error:', error.message);
err_msg = error.message;
}

throw new Error(`Deposit error: ${err_msg}`);
}

if (response.status != 200) {
throw new Error(`Deposit error: ${response.data}`);
}

let depositMsg1Response = response.data;

Expand All @@ -95,19 +77,13 @@ const init = async (clientConfig, wallet, token_id) => {
storageManager.updateWallet(wallet);
}

const getDepositBitcoinAddress = async (clientConfig, walletName, amount) => {
const getDepositBitcoinAddress = async (clientConfig, walletName, token_id, amount) => {

await initWasm(wasmUrl);

let wallet = storageManager.getWallet(walletName);

let foundToken = wallet.tokens.find(token => token.confirmed === true && token.spent === false);

if (!foundToken) {
throw new Error(`There is no token available`);
}

await init(clientConfig, wallet, foundToken.token_id);
await init(clientConfig, wallet, token_id);

let coin = wallet.coins[wallet.coins.length - 1];

Expand All @@ -117,8 +93,6 @@ const getDepositBitcoinAddress = async (clientConfig, walletName, amount) => {
coin.aggregated_address = aggregatedPublicKey.aggregate_address;
coin.aggregated_pubkey = aggregatedPublicKey.aggregate_pubkey;

foundToken.spent = true;

storageManager.updateWallet(wallet);

return { "deposit_address": coin.aggregated_address, "statechain_id": coin.statechain_id };
Expand Down
10 changes: 4 additions & 6 deletions clients/libs/web/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import transfer_receive from './transfer_receive.js';
import lightningLatch from './lightning-latch.js';
import { v4 as uuidv4 } from 'uuid';
import { decodeInvoice } from '../../tests/web/test-utils.js';
import { util } from 'chai';
import utils from './utils.js';

const greet = async () => {
Expand All @@ -33,13 +32,12 @@ const createWallet = async (clientConfig, name) => {
return wallet;
}

const newToken = async (clientConfig, walletName) => {
const token = await deposit.getToken(clientConfig, walletName);
return token;
const newToken = async (clientConfig) => {
return await deposit.getToken(clientConfig);
}

const getDepositBitcoinAddress = async (clientConfig, walletName, amount) => {
const address_info = await deposit.getDepositBitcoinAddress(clientConfig, walletName, amount);
const getDepositBitcoinAddress = async (clientConfig, walletName, token_id, amount) => {
const address_info = await deposit.getDepositBitcoinAddress(clientConfig, walletName, token_id, amount);
return address_info;
}

Expand Down
Loading
Loading