From 39132ab162ed97e28b25cd2858dc12550913bdc1 Mon Sep 17 00:00:00 2001 From: Niccolo Lampa Date: Wed, 24 Jul 2024 19:15:02 +0800 Subject: [PATCH 1/6] add initial process of creating splitutxo --- dunes.js | 115 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 25 deletions(-) diff --git a/dunes.js b/dunes.js index 8f1ea6b..338ce02 100755 --- a/dunes.js +++ b/dunes.js @@ -427,6 +427,36 @@ function encodeToTuple(n) { return tupleRepresentation; } +const getDuneBalance = async (dune_name, address) => { + const utxos = await fetchAllUnspentOutputs(address); + let balance = 0n; + const utxoHashes = utxos.map((utxo) => `${utxo.txid}:${utxo.vout}`); + const chunkSize = 10; // Size of each chunk + + // Function to chunk the utxoHashes array + const chunkedUtxoHashes = []; + for (let i = 0; i < utxoHashes.length; i += chunkSize) { + chunkedUtxoHashes.push(utxoHashes.slice(i, i + chunkSize)); + } + + // Process each chunk + for (const chunk of chunkedUtxoHashes) { + const allDunes = await getDunesForUtxos(chunk); + + for (const dunesInfo of allDunes) { + for (const singleDunesInfo of dunesInfo.dunes) { + const [name, { amount }] = singleDunesInfo; + + if (name === dune_name) { + balance += BigInt(amount); + } + } + } + } + + return balance; +}; + program .command("printDunes") .description("Prints dunes of wallet") @@ -477,31 +507,7 @@ program .argument("
", "Wallet address") .description("Prints tick balance of wallet") .action(async (dune_name, address) => { - const utxos = await fetchAllUnspentOutputs(address); - let balance = 0n; - const utxoHashes = utxos.map((utxo) => `${utxo.txid}:${utxo.vout}`); - const chunkSize = 10; // Size of each chunk - - // Function to chunk the utxoHashes array - const chunkedUtxoHashes = []; - for (let i = 0; i < utxoHashes.length; i += chunkSize) { - chunkedUtxoHashes.push(utxoHashes.slice(i, i + chunkSize)); - } - - // Process each chunk - for (const chunk of chunkedUtxoHashes) { - const allDunes = await getDunesForUtxos(chunk); - - for (const dunesInfo of allDunes) { - for (const singleDunesInfo of dunesInfo.dunes) { - const [name, { amount }] = singleDunesInfo; - - if (name === dune_name) { - balance += BigInt(amount); - } - } - } - } + const balance = await getDuneBalance(dune_name, address); // Output the total balance console.log(`${balance.toString()} ${dune_name}`); @@ -1356,6 +1362,17 @@ walletCommand await walletSplit(splits); }); +// +walletCommand + .command("splitutxo") + .description("Split dune allocation from one utxo to multiple utxos") + .argument("", "UTXO to split") + .argument("", "number of utxos to split") + .argument("", "ticker of dune to split") + .action(async (utxotxid, split, ticker) => { + await utxoSplit(utxotxid, split, ticker); + }); + async function main() { program.parse(); } @@ -1481,6 +1498,54 @@ async function walletSplit(splits) { console.log(tx.hash); } +async function utxoSplit(utxotxid, split, ticker) { + if (split > 12) { + throw new Error("Can't split more than 12 "); + } + + const wallet = JSON.parse(fs.readFileSync(WALLET_PATH)); + + let selectedUtxo = wallet.utxos.find((utxo) => utxo.txid === utxotxid); + + if (!selectedUtxo) { + throw new Error("cant find utxo"); + } + + // will get the dune balance to split + const duneBalance = Number(await getDuneBalance(ticker, wallet.address)); + console.log(duneBalance); + let balanceSplit = Math.trunc(duneBalance / split); + + let selectedUtxoBal = selectedUtxo.satoshis; + + // update selected utxo balance + selectedUtxo.satoshis += duneBalance % split; + selectedUtxo.vout += 1; + + const splitUtxos = []; + + for (let i = 1; i <= split; i++) { + splitUtxos.push({ + txid: utxotxid, + vout: 1, + satoshis: balanceSplit, + ticker, + script: selectedUtxo.script, + }); + } + + const updatedUtxo = [...wallet.utxos, ...splitUtxos]; + + // add remainder to orignal utxo + // console.log(wallet); + // console.log("wallet utxos", wallet.utxos); + + // console.log("selected utxo updated", selectedUtxo); + // console.log("split utxo", splitUtxos); + + console.log("udpated utxo", updatedUtxo); +} + async function fund(wallet, tx, onlySafeUtxos = true) { // we get the utxos without dunes let utxosWithoutDunes; From c4164bd30a1896e3a51a6d7e4624a3d3e39cd15a Mon Sep 17 00:00:00 2001 From: Niccolo Lampa Date: Wed, 24 Jul 2024 20:02:50 +0800 Subject: [PATCH 2/6] add initial sending of split dunes amout to utxos --- dunes.js | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/dunes.js b/dunes.js index 338ce02..75301c4 100755 --- a/dunes.js +++ b/dunes.js @@ -1505,6 +1505,7 @@ async function utxoSplit(utxotxid, split, ticker) { const wallet = JSON.parse(fs.readFileSync(WALLET_PATH)); + // same txids for utxo? even when dune was split? let selectedUtxo = wallet.utxos.find((utxo) => utxo.txid === utxotxid); if (!selectedUtxo) { @@ -1516,34 +1517,51 @@ async function utxoSplit(utxotxid, split, ticker) { console.log(duneBalance); let balanceSplit = Math.trunc(duneBalance / split); - let selectedUtxoBal = selectedUtxo.satoshis; - - // update selected utxo balance - selectedUtxo.satoshis += duneBalance % split; - selectedUtxo.vout += 1; + // update selected utxo balance to be sent remainder of dune + selectedUtxo.satoshis = duneBalance % split; const splitUtxos = []; for (let i = 1; i <= split; i++) { splitUtxos.push({ txid: utxotxid, - vout: 1, + vout: 0, satoshis: balanceSplit, ticker, - script: selectedUtxo.script, }); } - const updatedUtxo = [...wallet.utxos, ...splitUtxos]; - - // add remainder to orignal utxo - // console.log(wallet); - // console.log("wallet utxos", wallet.utxos); + const updateDataUtxo = [selectedUtxo, ...splitUtxos]; - // console.log("selected utxo updated", selectedUtxo); - // console.log("split utxo", splitUtxos); + console.log( + "update reference utxo data. note: satoshis are the balance to be sent", + updateDataUtxo + ); - console.log("udpated utxo", updatedUtxo); + // next step just need to implement with dogecore syntax + // will send dunes to txid based on updateDataUtxo array + for (let i = 0; i <= updateDataUtxo.length; i++) { + // error "no dunes" ? + // utxo vout problem causing dune not found? + try { + await walletSendDunes( + selectedUtxo.txid, + // assumes that vout is updated every send + selectedUtxo.vout + i, + //dune + ticker, + //just followed the example in the documentation for decimals + 8, + // amountsAsArray just send the satoshis for entry in array + [updateDataUtxo[i].satoshis], + // addressesAsArray, + [wallet.address] + ); + } catch (error) { + console.error(error); + process.exit(1); + } + } } async function fund(wallet, tx, onlySafeUtxos = true) { From 13ce2d27ce28bebaa52ce28705030bb8ad9d990d Mon Sep 17 00:00:00 2001 From: Niccolo Lampa Date: Wed, 24 Jul 2024 20:33:09 +0800 Subject: [PATCH 3/6] update to send dunes remainder to first utxo --- dunes.js | 58 +++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/dunes.js b/dunes.js index 75301c4..bdea396 100755 --- a/dunes.js +++ b/dunes.js @@ -1514,54 +1514,52 @@ async function utxoSplit(utxotxid, split, ticker) { // will get the dune balance to split const duneBalance = Number(await getDuneBalance(ticker, wallet.address)); - console.log(duneBalance); + console.log("dune balance:", duneBalance); let balanceSplit = Math.trunc(duneBalance / split); - - // update selected utxo balance to be sent remainder of dune - selectedUtxo.satoshis = duneBalance % split; + let remainderSplit = duneBalance % split; const splitUtxos = []; for (let i = 1; i <= split; i++) { splitUtxos.push({ txid: utxotxid, - vout: 0, satoshis: balanceSplit, - ticker, }); } - const updateDataUtxo = [selectedUtxo, ...splitUtxos]; + // give the remainder to first utxo + if (remainderSplit) { + splitUtxos[0].satoshis += remainderSplit; + } console.log( "update reference utxo data. note: satoshis are the balance to be sent", - updateDataUtxo + splitUtxos ); // next step just need to implement with dogecore syntax - // will send dunes to txid based on updateDataUtxo array - for (let i = 0; i <= updateDataUtxo.length; i++) { - // error "no dunes" ? - // utxo vout problem causing dune not found? - try { - await walletSendDunes( - selectedUtxo.txid, - // assumes that vout is updated every send - selectedUtxo.vout + i, - //dune - ticker, - //just followed the example in the documentation for decimals - 8, - // amountsAsArray just send the satoshis for entry in array - [updateDataUtxo[i].satoshis], - // addressesAsArray, - [wallet.address] - ); - } catch (error) { - console.error(error); - process.exit(1); - } + // will send dunes to txid based on splitUtxos array + // error "no dunes" ? + // utxo vout problem causing dune not found? + try { + await walletSendDunes( + selectedUtxo.txid, + selectedUtxo.vout, + //dune + ticker, + //just followed the example in the documentation for decimals + 8, + // amountsAsArray just send the satoshis for entry in array + splitUtxos.map((update) => update.satoshis), + // addressesAsArray, + [wallet.address] + ); + } catch (error) { + console.error(error); + process.exit(1); } + + console.log("split success"); } async function fund(wallet, tx, onlySafeUtxos = true) { From 5d91969d06eea0e8502dda415e931e12d126218c Mon Sep 17 00:00:00 2001 From: Niccolo Lampa Date: Wed, 24 Jul 2024 20:50:54 +0800 Subject: [PATCH 4/6] update to create an address array for sending --- dunes.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dunes.js b/dunes.js index bdea396..cbb8e3a 100755 --- a/dunes.js +++ b/dunes.js @@ -1548,11 +1548,12 @@ async function utxoSplit(utxotxid, split, ticker) { //dune ticker, //just followed the example in the documentation for decimals + // also the decimals / divisibility of dune created 8, // amountsAsArray just send the satoshis for entry in array splitUtxos.map((update) => update.satoshis), // addressesAsArray, - [wallet.address] + Array.from({ length: splitUtxos.length }, () => wallet.address) ); } catch (error) { console.error(error); From 785ba007d313eaa84ebbcec68fb8630a11fb868f Mon Sep 17 00:00:00 2001 From: Niccolo Lampa Date: Wed, 24 Jul 2024 21:20:10 +0800 Subject: [PATCH 5/6] fix send dunes for splitutxo --- dunes.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dunes.js b/dunes.js index cbb8e3a..ac573ea 100755 --- a/dunes.js +++ b/dunes.js @@ -1506,7 +1506,11 @@ async function utxoSplit(utxotxid, split, ticker) { const wallet = JSON.parse(fs.readFileSync(WALLET_PATH)); // same txids for utxo? even when dune was split? - let selectedUtxo = wallet.utxos.find((utxo) => utxo.txid === utxotxid); + // find last entry matching utxos in array + const selectedUtxo = wallet.utxos + .slice() + .reverse() + .find((utxo) => utxo.txid === utxotxid); if (!selectedUtxo) { throw new Error("cant find utxo"); @@ -1537,6 +1541,8 @@ async function utxoSplit(utxotxid, split, ticker) { splitUtxos ); + // console.log(selectedUtxo.txid + ":1"); + // next step just need to implement with dogecore syntax // will send dunes to txid based on splitUtxos array // error "no dunes" ? From b77c2d54890b740765de220b8040959210720b3a Mon Sep 17 00:00:00 2001 From: Niccolo Lampa Date: Wed, 24 Jul 2024 22:47:12 +0800 Subject: [PATCH 6/6] update dunes.js comment --- dunes.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dunes.js b/dunes.js index ac573ea..7bc54fa 100755 --- a/dunes.js +++ b/dunes.js @@ -1541,12 +1541,11 @@ async function utxoSplit(utxotxid, split, ticker) { splitUtxos ); - // console.log(selectedUtxo.txid + ":1"); - // next step just need to implement with dogecore syntax // will send dunes to txid based on splitUtxos array // error "no dunes" ? // utxo vout problem causing dune not found? + // split amounts in updated wallet wrong altough total in split prmompt is correct? try { await walletSendDunes( selectedUtxo.txid,