Skip to content

Commit

Permalink
Auto deshield transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Duddino committed May 20, 2024
1 parent e54fbb5 commit 8a80159
Show file tree
Hide file tree
Showing 21 changed files with 208 additions and 22 deletions.
1 change: 1 addition & 0 deletions locale/cnr/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Interna greška, molimo pokušajte ponovo kasnije" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/de/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Interner Fehler, bitte versuche es später erneut" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/en/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "Save Wallet File" # Save Wallet File
proposalOverBudget = "Over Budget" # Over Budget
badSaplingRoot = "There was an error while syncing. Resyncing from scratch (Bad sapling root)" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "Creating SHIELD transaction..." # Creating SHIELD transaction...
autoShieldTransaction = "Auto shield transaction" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Internal error, please try again later" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/es-mx/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Error interno, vuelve a intentarlo más tarde" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/fr/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Erreur interne, veuillez réessayer plus tard" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/it/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Errore interno, rirova più tardi" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/nl/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Interne fout, probeer het later opnieuw" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/ph/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Internal error, Pakiusap uliting muli" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/pl/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Błąd wewnętrzny, spróbuj ponownie później" # Internal error, please try again later
Expand Down
1 change: 1 addition & 0 deletions locale/pt-br/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
STAKE_ADDR_SET = "<b>Endereço de Cold Staking definido!</b><br>Ao fazer Stake no futuro este endereço irá ser usado." # <b>Cold Address set!</b><br>Future stakes will use this address.
Expand Down
1 change: 1 addition & 0 deletions locale/pt-pt/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ saveWalletFile = "" # Save Wallet File
proposalOverBudget = "" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
STAKE_ADDR_SET = "<b>Endereço de Cold Staking definido!</b><br>Ao fazer Stake no futuro irá ser usado este endereço." # <b>Cold Address set!</b><br>Future stakes will use this address.
Expand Down
1 change: 1 addition & 0 deletions locale/template/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ shieldAddress = "Shield address"
cantShieldToExc = "This address does not support shield transfers"
badSaplingRoot = "There was an error while syncing. Resyncing from scratch (Bad sapling root)"
creatingShieldTransaction = "Creating SHIELD transaction..."
autoShieldTransaction = "Auto shield transaction"

[ALERTS]
INTERNAL_ERROR = "Internal error, please try again later"
Expand Down
1 change: 1 addition & 0 deletions locale/uwu/translation.toml
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ saveWalletFile = "Save Wawwet File" # Save Wallet File
proposalOverBudget = "Over Budgey" # Over Budget
badSaplingRoot = "" # There was an error while syncing. Resyncing from scratch (Bad sapling root)
creatingShieldTransaction = "" # Creating SHIELD transaction...
autoShieldTransaction = "" # Auto shield transaction

[ALERTS]
INTERNAL_ERROR = "Internal error, pwease try again later" # Internal error, please try again later
Expand Down
26 changes: 19 additions & 7 deletions scripts/composables/use_wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ export const useWallet = defineStore('wallet', () => {
getEventEmitter().on('shield-loaded-from-disk', () => {
hasShield.value = wallet.hasShield();
});
const sendTransaction = async (network, tx) => {
const res = await network.sendTransaction(tx.serialize());
if (res) {
await wallet.addTransaction(tx);
} else {
wallet.discardTransaction(tx);
}
return res;
};
const createAndSendTransaction = lockableFunction(
async (network, address, value, opts) => {
const tx = wallet.createTransaction(address, value, opts);
Expand All @@ -81,15 +90,17 @@ export const useWallet = defineStore('wallet', () => {
} else {
await wallet.sign(tx);
}
const res = await network.sendTransaction(tx.serialize());
if (res) {
await wallet.addTransaction(tx);
} else {
wallet.discardTransaction(tx);
}
return res;
return await sendTransaction(network, tx);
}
);
const createAuthoshieldTransactions = async (network, address, value) => {
const txs = await wallet.createAutoshieldTransactions(address, value);
let res = true;
for (const tx of txs) {
res = res && (await sendTransaction(network, tx));
}
return res;
};
const isCreatingTransaction = () => createAndSendTransaction.isLocked();

getEventEmitter().on('toggle-network', async () => {
Expand Down Expand Up @@ -136,5 +147,6 @@ export const useWallet = defineStore('wallet', () => {
createAndSendTransaction,
loadFromDisk,
coldBalance,
createAuthoshieldTransactions,
};
});
22 changes: 18 additions & 4 deletions scripts/dashboard/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,9 @@ function lockWallet() {
* Sends a transaction
* @param {string} address - Address or contact to send to
* @param {number} amount - Amount of PIVs to send
* @param {boolean} isAutoShield - Whether or not this is an autoshield transaction
*/
async function send(address, amount, useShieldInputs) {
async function send(address, amount, useShieldInputs, isAutoShield) {
// Ensure a wallet is unlocked
if (wallet.isViewOnly && !wallet.isHardwareWallet) {
if (
Expand Down Expand Up @@ -325,9 +326,22 @@ async function send(address, amount, useShieldInputs) {
// Create and send the TX
try {
await wallet.createAndSendTransaction(getNetwork(), address, nValue, {
useShieldInputs,
});
if (isAutoShield) {
await wallet.createAuthoshieldTransactions(
getNetwork(),
address,
nValue
);
} else {
await wallet.createAndSendTransaction(
getNetwork(),
address,
nValue,
{
useShieldInputs,
}
);
}
} catch (e) {
console.error(e);
createAlert('warning', e);
Expand Down
25 changes: 24 additions & 1 deletion scripts/dashboard/TransferMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ const emit = defineEmits([
// Amount of PIVs to send in the selected currency (e.g. USD)
const amountCurrency = ref('');
const useShieldInputs = ref(false);
const autoShieldTransaction = ref(false);
const color = ref('');
watch(useShieldInputs, (useShieldInputs) => {
if (!useShieldInputs) autoShieldTransaction.value = false;
});
const props = defineProps({
show: Boolean,
price: Number,
Expand Down Expand Up @@ -55,7 +60,8 @@ function send() {
'send',
sanitizeHTML(address.value),
amount.value,
useShieldInputs.value
useShieldInputs.value,
autoShieldTransaction.value
);
}
Expand Down Expand Up @@ -254,6 +260,23 @@ async function selectContact() {
}}</label>
</div>
<br />
<div v-show="useShieldInputs">
<div class="custom-control custom-switch">
<input
type="checkbox"
class="custom-control-input"
data-testid="useShieldInputs"
id="autoShieldTransaction"
v-model="autoShieldTransaction"
/>
<label
class="custom-control-label"
for="autoShieldTransaction"
>{{ translation.autoShieldTransaction }}</label
>
</div>
<br />
</div>
</div>

<div class="text-right pb-2">
Expand Down
28 changes: 22 additions & 6 deletions scripts/transaction_builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ export class TransactionBuilder {

// Part of the tx fee that has been already handled
#handledFee = 0;
MIN_FEE_PER_BYTE = 10;
static MIN_FEE_PER_BYTE = 10;
// This number is larger or equal than the max size of the script sig for a P2CS and P2PKH transaction
SCRIPT_SIG_MAX_SIZE = 108;
static SCRIPT_SIG_MAX_SIZE = 108;

get valueIn() {
return this.#valueIn;
Expand All @@ -35,7 +35,9 @@ export class TransactionBuilder {
*/
isDust({ out, value }) {
// Dust is a transaction such that its creation costs more than its value
return value < out.serialize().length * this.MIN_FEE_PER_BYTE;
return (
value < out.serialize().length * TransactionBuilder.MIN_FEE_PER_BYTE
);
}

constructor() {
Expand All @@ -52,18 +54,31 @@ export class TransactionBuilder {
return new TransactionBuilder();
}

/**
* @returns {number} Amount of fee in sats of a standard transaction based on the
* number of inputs and outputs
*/
static getStandardTxFee(nInputs, nOutputs) {
return (
(nInputs * 138 + nOutputs * 34 + 21) *
TransactionBuilder.MIN_FEE_PER_BYTE
);
}

getFee() {
//TODO: find a cleaner way to add the dummy signature
let scriptSig = [];
for (let vin of this.#transaction.vin) {
scriptSig.push(vin.scriptSig);
// Insert a dummy signature just to compute fees
vin.scriptSig = bytesToHex(Array(this.SCRIPT_SIG_MAX_SIZE).fill(0));
vin.scriptSig = bytesToHex(
Array(TransactionBuilder.SCRIPT_SIG_MAX_SIZE).fill(0)
);
}

const fee =
Math.ceil(this.#transaction.serialize().length / 2) *
this.MIN_FEE_PER_BYTE -
TransactionBuilder.MIN_FEE_PER_BYTE -
this.#handledFee;
// Re-insert whatever was inside before
for (let i = 0; i < scriptSig.length; i++) {
Expand Down Expand Up @@ -174,7 +189,8 @@ export class TransactionBuilder {
if (this.isDust({ out, value }) && subtractFeeFromAmt) {
return;
}
const fee = out.serialize().length * this.MIN_FEE_PER_BYTE;
const fee =
out.serialize().length * TransactionBuilder.MIN_FEE_PER_BYTE;
// We have subtracted fees from the value, mark this fee as handled (don't pay them again)
if (subtractFeeFromAmt) {
out.value -= fee;
Expand Down
38 changes: 37 additions & 1 deletion scripts/wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { beforeUnloadListener, blockCount } from './global.js';
import { getNetwork } from './network.js';
import { MAX_ACCOUNT_GAP, SHIELD_BATCH_SYNC_SIZE } from './chain_params.js';
import { HistoricalTx, HistoricalTxType } from './historical_tx.js';
import { COutpoint, Transaction } from './transaction.js';
import { COutpoint, Transaction, UTXO } from './transaction.js';
import { confirmPopup, createAlert, isShieldAddress } from './misc.js';
import { cChainParams } from './chain_params.js';
import { COIN } from './chain_params.js';
Expand Down Expand Up @@ -1072,6 +1072,7 @@ export class Wallet {
const value =
transaction.shieldOutput[0]?.value || transaction.vout[0].value;
try {
//await this.#shield.loadSaplingProver();
const { hex } = await this.#shield.createTransaction({
address:
transaction.shieldOutput[0]?.address ||
Expand All @@ -1098,6 +1099,41 @@ export class Wallet {
}
}

/**
*
*/
async createAutoshieldTransactions(address, value) {
const [intermediaryAddress] = this.getNewAddress(1);
const firstTx = await this.sign(
this.createTransaction(
intermediaryAddress,
value + TransactionBuilder.getStandardTxFee(1, 1),
{
useShieldInputs: true,
}
)
);
const txBuilder = new TransactionBuilder()
.addUTXO(
new UTXO({
outpoint: new COutpoint({
txid: firstTx.txid,
n: 0,
}),
value: firstTx.vout[0].value,
script: firstTx.vout[0].script,
})
)
.addOutput({
address,
value: firstTx.vout[0].value,
});
txBuilder.equallySubtractAmt(txBuilder.getFee());
const tx = txBuilder.build();
await this.sign(tx);
return [firstTx, tx];
}

/**
* @param {import('./transaction.js').Transaction} transaction - transaction to sign
* @throws {Error} if the wallet is view only
Expand Down
4 changes: 2 additions & 2 deletions tests/components/TransferMenu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ it('Sends transaction correctly', async () => {
expect(wrapper.emitted('send')).toBeUndefined();
await wrapper.find('[data-testid=sendButton]').trigger('click');
expect(wrapper.emitted('send')).toStrictEqual([
['DLabsktzGMnsK5K9uRTMCF6NoYNY6ET4Bc', '60', false],
['DLabsktzGMnsK5K9uRTMCF6NoYNY6ET4Bc', '60', false, false],
]);
});

Expand All @@ -74,6 +74,6 @@ it('Sends transaction with shield inputs', async () => {
await wrapper.find('[data-testid=sendButton]').trigger('click');

expect(wrapper.emitted('send')).toStrictEqual([
['DLabsktzGMnsK5K9uRTMCF6NoYNY6ET4Bc', '60', true],
['DLabsktzGMnsK5K9uRTMCF6NoYNY6ET4Bc', '60', true, false],
]);
});
Loading

0 comments on commit 8a80159

Please sign in to comment.