Skip to content

Commit

Permalink
Add multiple deposit feature in web lib
Browse files Browse the repository at this point in the history
  • Loading branch information
ssantos21 committed Nov 4, 2024
1 parent ee556c1 commit da76505
Show file tree
Hide file tree
Showing 32 changed files with 1,852 additions and 260 deletions.
2 changes: 2 additions & 0 deletions clients/libs/nodejs/coin_enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const CoinStatus = {
TRANSFERRED: "TRANSFERRED", // the coin was transferred
WITHDRAWN: "WITHDRAWN", // the coin was withdrawn
DUPLICATED: "DUPLICATED", // the coin was withdrawn
DUPLICATED: "DUPLICATED", // the coin was withdrawn
INVALIDATED: "INVALIDATED", // the coin was invalidated
};

module.exports = { CoinStatus };
6 changes: 3 additions & 3 deletions clients/libs/web/broadcast_backup_tx.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ const execute = async (clientConfig, walletName, statechainId, toAddress, feeRat

await initWasm(wasmUrl);

let wallet = storageManager.getItem(walletName);
let wallet = storageManager.getWallet(walletName);

let backupTxs = storageManager.getItem(statechainId);
let backupTxs = storageManager.getBackupTransactions(walletName, statechainId);

if (!feeRate) {
const response = await axios.get(`${clientConfig.esploraServer}/api/fee-estimates`);
Expand Down Expand Up @@ -69,7 +69,7 @@ const execute = async (clientConfig, walletName, statechainId, toAddress, feeRat
coin.withdrawal_address = toAddress;
coin.status = CoinStatus.WITHDRAWING;

storageManager.setItem(walletName, wallet, true);
storageManager.updateWallet(wallet);

utils.completeWithdraw(clientConfig, coin.statechain_id, coin.signed_statechain_id);

Expand Down
1 change: 1 addition & 0 deletions clients/libs/web/coin_enum.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const CoinStatus = {
TRANSFERRED: "TRANSFERRED", // the coin was transferred
WITHDRAWN: "WITHDRAWN", // the coin was withdrawn
DUPLICATED: "DUPLICATED", // the coin was duplicated
INVALIDATED: "INVALIDATED", // the coin was invalidated
};

export default CoinStatus;
33 changes: 29 additions & 4 deletions clients/libs/web/coin_status.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,16 @@ const checkDeposit = async (clientConfig, coin, walletNetwork) => {
const utxo_txid = utxo.txid;
const utxo_vout = utxo.vout;

const backup_tx = await deposit.createTx1(clientConfig, coin, walletNetwork, utxo_txid, utxo_vout);
if (coin.status !== CoinStatus.INITIALISED) {
throw new Error(`The coin with the aggregated address ${aggregated_address} is not in the INITIALISED state`);
}


coin.utxo_txid = utxo_txid;
coin.utxo_vout = utxo_vout;
coin.status = CoinStatus.IN_MEMPOOL;

const backup_tx = await deposit.createTx1(clientConfig, coin, walletNetwork, 1);

const activity_utxo = `${utxo_txid}:${utxo_vout}`;

Expand Down Expand Up @@ -221,7 +230,7 @@ const updateCoins = async (clientConfig, walletName) => {

await initWasm(wasmUrl);

let wallet = storageManager.getItem(walletName);
let wallet = storageManager.getWallet(walletName);

const network = wallet.network;

Expand All @@ -234,7 +243,7 @@ const updateCoins = async (clientConfig, walletName) => {

if (depositResult) {
wallet.activities.push(depositResult.activity);
storageManager.setItem(coin.statechain_id, [depositResult.backup_tx], false);
storageManager.createBackupTransactions(wallet.name, coin.statechain_id, [depositResult.backup_tx])
}
} else if (coin.status === CoinStatus.IN_TRANSFER) {
let is_transferred = await checkTransfer(clientConfig, coin);
Expand All @@ -254,7 +263,23 @@ const updateCoins = async (clientConfig, walletName) => {
const duplicatedCoins = await checkForDuplicated(clientConfig, wallet.coins);
wallet.coins = [...wallet.coins, ...duplicatedCoins];

storageManager.setItem(wallet.name, wallet, true);
// invalidate duplicated coins that were not transferred
for (let i = 0; i < wallet.coins.length; i++) {
if (wallet.coins[i].status === CoinStatus.DUPLICATED) {
const is_transferred = wallet.coins.some((coin, j) =>
i !== j && // Skip comparing with self
coin.statechain_id === wallet.coins[i].statechain_id &&
coin.locktime === wallet.coins[i].locktime &&
coin.status === CoinStatus.TRANSFERRED
);

if (is_transferred) {
wallet.coins[i].status = CoinStatus.INVALIDATED;
}
}
}

storageManager.updateWallet(wallet);
}

export default { updateCoins }
28 changes: 8 additions & 20 deletions clients/libs/web/deposit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const getTokenFromServer = async (clientConfig) => {

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

let wallet = storageManager.getItem(walletName);
let wallet = storageManager.getWallet(walletName);

let token = await getTokenFromServer(clientConfig);

Expand All @@ -36,7 +36,7 @@ const getToken = async (clientConfig, walletName) => {

wallet.tokens.push(token);

storageManager.setItem(walletName, wallet, true);
storageManager.updateWallet(wallet);

return token;
}
Expand All @@ -47,7 +47,7 @@ const init = async (clientConfig, wallet, token_id) => {

wallet.coins.push(coin);

storageManager.setItem(wallet.name, wallet, true);
storageManager.updateWallet(wallet);

let depositMsg1 = mercury_wasm.createDepositMsg1(coin, token_id);

Expand All @@ -69,14 +69,14 @@ const init = async (clientConfig, wallet, token_id) => {
coin.signed_statechain_id = depositInitResult.signed_statechain_id;
coin.server_pubkey = depositInitResult.server_pubkey;

storageManager.setItem(wallet.name, wallet, true);
storageManager.updateWallet(wallet);
}

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

await initWasm(wasmUrl);

let wallet = storageManager.getItem(walletName);
let wallet = storageManager.getWallet(walletName);

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

Expand All @@ -96,24 +96,12 @@ const getDepositBitcoinAddress = async (clientConfig, walletName, amount) => {

foundToken.spent = true;

storageManager.setItem(wallet.name, wallet, true);
storageManager.updateWallet(wallet);

return { "deposit_address": coin.aggregated_address, "statechain_id": coin.statechain_id };
}

const createTx1 = async (clientConfig, coin, walletNetwork, tx0Hash, tx0Vout) => {

if (coin.status !== CoinStatus.INITIALISED) {
throw new Error(`The coin with the aggregated address ${aggregated_address} is not in the INITIALISED state`);
}

if ('utxo_txid' in coin && 'input_vout' in coin) {
throw new Error(`The coin with the aggregated address ${aggregated_address} has already been deposited`);
}

coin.utxo_txid = tx0Hash;
coin.utxo_vout = tx0Vout;
coin.status = CoinStatus.IN_MEMPOOL;
const createTx1 = async (clientConfig, coin, walletNetwork, txN) => {

const toAddress = mercury_wasm.getUserBackupAddress(coin, walletNetwork);
const isWithdrawal = false;
Expand All @@ -137,7 +125,7 @@ const createTx1 = async (clientConfig, coin, walletNetwork, tx0Hash, tx0Vout) =>
);

let backupTx = {
tx_n: 1,
tx_n: txN,
tx: signedTx,
client_public_nonce: coin.public_nonce,
server_public_nonce: coin.server_public_nonce,
Expand Down
6 changes: 3 additions & 3 deletions clients/libs/web/lightning-latch.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const createPreImage = async (clientConfig, walletName, statechainId) => {

const batchId = uuidv4();

const wallet = storageManager.getItem(walletName);
const wallet = storageManager.getWallet(walletName);

const coinsWithStatechainId = wallet.coins.filter(c => {
return c.statechain_id === statechainId
Expand Down Expand Up @@ -55,7 +55,7 @@ const sendPaymentHash = async (clientConfig, paymentHashPayload) => {

const confirmPendingInvoice = async (clientConfig, walletName, statechainId) => {

const wallet = storageManager.getItem(walletName);
const wallet = storageManager.getWallet(walletName);

const coinsWithStatechainId = wallet.coins.filter(c => {
return c.statechain_id === statechainId
Expand Down Expand Up @@ -84,7 +84,7 @@ const confirmPendingInvoice = async (clientConfig, walletName, statechainId) =>

const retrievePreImage = async (clientConfig, walletName, statechainId, batchId) => {

const wallet = storageManager.getItem(walletName);
const wallet = storageManager.getWallet(walletName);

const coinsWithStatechainId = wallet.coins.filter(c => {
return c.statechain_id === statechainId
Expand Down
23 changes: 16 additions & 7 deletions clients/libs/web/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ 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 @@ -26,7 +28,7 @@ const createWallet = async (clientConfig, name) => {

const wallet = await walletManager.createWallet(clientConfig, name);

storageManager.setItem(name, wallet, false);
storageManager.createWallet(wallet);

return wallet;
}
Expand All @@ -45,13 +47,16 @@ const listStatecoins = async (clientConfig, walletName) => {

await coin_status.updateCoins(clientConfig, walletName);

let wallet = storageManager.getItem(walletName);
let wallet = storageManager.getWallet(walletName);

let coins = wallet.coins.map(coin => ({
statechain_id: coin.statechain_id,
utxo_txid: coin.utxo_txid,
utxo_vout: coin.utxo_vout,
amount: coin.amount,
status: coin.status,
adress: coin.address,
address: coin.address,
aggregated_address: coin.aggregated_address,
locktime: coin.locktime,
duplicate_index: coin.duplicate_index
}));
Expand Down Expand Up @@ -88,11 +93,11 @@ const newTransferAddress = async (walletName, generateBatchId) => {
return res;
}

const transferSend = async (clientConfig, walletName, statechainId, toAddress, forceSend, batchId) => {
const transferSend = async (clientConfig, walletName, statechainId, toAddress, forceSend, batchId, duplicatedIndexes) => {

await coin_status.updateCoins(clientConfig, walletName);

return await transfer_send.execute(clientConfig, walletName, statechainId, toAddress, forceSend, batchId);
return await transfer_send.execute(clientConfig, walletName, statechainId, toAddress, forceSend, batchId, duplicatedIndexes);
}

const transferReceive = async (clientConfig, walletName) => {
Expand Down Expand Up @@ -153,5 +158,9 @@ export default {
confirmPendingInvoice,
retrievePreImage,
getPaymentHash,
verifyInvoice
}
verifyInvoice,
getPreviousOutpoint: utils.getPreviousOutpoint,
getBlockheight: utils.getBlockheight,
splitBackupTransactions: transfer_receive.splitBackupTransactions,
infoConfig: utils.infoConfig,
};
29 changes: 28 additions & 1 deletion clients/libs/web/storage_manager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
const namespace = 'mercury-layer'

const createWallet = (wallet) => {
setItem(wallet.name, wallet);
}

const updateWallet = (wallet) => {
setItem(wallet.name, wallet, true);
}

const getWallet = (walletName) => {
return getItem(walletName);
}

const createBackupTransactions = (walletName, statechainId, backupTransactions) => {
const key = `${walletName}-${statechainId}`;
setItem(key, backupTransactions);
}

const updateBackupTransactions = (walletName, statechainId, backupTransactions) => {
const key = `${walletName}-${statechainId}`;
setItem(key, backupTransactions, true);
}

const getBackupTransactions = (walletName, statechainId) => {
const key = `${walletName}-${statechainId}`;
return getItem(key);
}

const setItem = (key, jsonData, isUpdate = false) => {
const namespacedKey = `${namespace}:${key}`;

Expand All @@ -21,4 +48,4 @@ const getItem = (key) => {
return JSON.parse(jsonData);
}

export default { setItem, getItem }
export default { createWallet, updateWallet, getWallet, createBackupTransactions, updateBackupTransactions, getBackupTransactions };
Loading

0 comments on commit da76505

Please sign in to comment.