View on GitHub
File Changes
      amount: '1100000'
    },
    {
-
      // eslint-disable-next-line max-len
-
      // '0465267961fefd53aefe4cf741dc0df9902d360bca0de4c0abe88ca89d0d08dd3dd993c5b8ca62c78801d3228a8de6b9e18217b001820c24d60c1bcd91c895d585'
      address: getAddressForType(
        TX_TEST_MNEMONIC_1,
        [
} from '../../../../types/TransferTypes';
import { RustModule } from '../../lib/cardanoCrypto/rustLoader';
import type { AddressKeyMap } from '../types';
-
import environment from '../../../../environment';
import { buildDaedalusTransferTx as shelleyFormatDaedalusTx } from '../shelley/daedalusTransfer';
import { buildDaedalusTransferTx as legacyFormatDaedalusTx } from '../byron/daedalusTransfer';

                      
  addressKeys: AddressKeyMap,
  outputAddr: string,
  getUTXOsForAddresses: AddressUtxoFunc,
+
  legacy: boolean,
|}): Promise<TransferTx> {
  const senderUtxos = await toSenderUtxos({
    outputAddr: payload.outputAddr,
    addressKeys: payload.addressKeys,
    senderUtxos,
  };
-
  return environment.isShelley()
-
    ? shelleyFormatDaedalusTx(txRequest)
-
    : legacyFormatDaedalusTx(txRequest);
+
  return payload.legacy
+
    ? legacyFormatDaedalusTx(txRequest)
+
    : shelleyFormatDaedalusTx(txRequest);
}
-
/* eslint-disable camelcase */
// @flow
+

                      
import '../../lib/test-config';
import { schema } from 'lovefield';
import {
  getCryptoDaedalusWalletFromMnemonics,
} from '../../lib/cardanoCrypto/cryptoWallet';
import {
  getAddressesKeys,
+
  buildDaedalusTransferTx,
} from './legacyDaedalus';
-
import { buildDaedalusTransferTx } from '../byron/daedalusTransfer';
import {
  GenerateTransferTxError,
} from '../../errors';
  silenceLogsForTesting();
});

                      
-
test('Daedalus transfer from single small UTXO', async () => {
-
  const words = 'note park thrive ignore spare latin common balance clap soup school tiny';
-
  const address = 'DdzFFzCqrhsmcx7z25PRkdbeUNqNNW4brhznpVxbm1EknAahjaCFEjYXg9KJRqkixjgGyz8D9GSX3CFDRoNrZyfJsi61N2FxCnq9yWBy';
-
  const txId = '915f2e6865fb31cc93410efb6c0e580ca74862374b3da461e20135c01f312e7c';
-
  const inputAmount = '1000000';
-
  const txIndex = 0;
-
  const outAddress = 'Ae2tdPwUPEZ4Gg5gmqwW2t7ottKBMjWunmPt7DwKkAGsxx9XNSfWqrE1Gbk';
-

                      
-
  const daedalusWallet = getCryptoDaedalusWalletFromMnemonics(words);
-
  const checker = RustModule.WalletV2.DaedalusAddressChecker.new(daedalusWallet);
-
  const addressMap = getAddressesKeys({
-
    checker,
-
    fullUtxo: [address]
-
  });
+
describe('Daedalus checker tests', () => {
+
  test('Daedalus transfer filters address not belonging to user', async () => {
+
    const words = 'note park thrive ignore spare latin common balance clap soup school tiny';
+
    const myAddress = 'DdzFFzCqrhsmcx7z25PRkdbeUNqNNW4brhznpVxbm1EknAahjaCFEjYXg9KJRqkixjgGyz8D9GSX3CFDRoNrZyfJsi61N2FxCnq9yWBy';
+
    const notMyAddress = 'DdzFFzCqrhsf69sXiAinAVVE9ZazKaoiKk9aSTRLJZSP4wMFGi4ogmcwjvSPMFuGD4a74HWemc3zfh3Eh4GdFRvmt3Jf88e77wCEUJgH';

                      
-
  const utxo = {
-
    utxo_id: 'ignore',
-
    tx_hash: txId,
-
    tx_index: txIndex,
-
    receiver: address,
-
    amount: inputAmount
-
  };
-

                      
-
  const transferInfo = await buildDaedalusTransferTx({
-
    addressKeys: addressMap,
-
    senderUtxos: [utxo],
-
    outputAddr: outAddress
-
  });
+
    const daedalusWallet = getCryptoDaedalusWalletFromMnemonics(words);
+
    const checker = RustModule.WalletV2.DaedalusAddressChecker.new(daedalusWallet);
+
    const addressMap = getAddressesKeys({
+
      checker,
+
      fullUtxo: [myAddress, notMyAddress]
+
    });

                      
-
  expect(transferInfo.fee.toString()).toBe('0.165841');
-
  expect(transferInfo.recoveredBalance.toString()).toBe('1');
-
  expect(transferInfo.senders).toEqual([address]);
-
  expect(transferInfo.receiver).toBe(outAddress);
-

                      
-
  // check tx itself
-
  const signedTx = RustModule.WalletV2.SignedTransaction.from_bytes(transferInfo.encodedTx);
-
  const txJson = signedTx.to_json();
-
  expect(txJson.tx.inputs).toHaveLength(1);
-
  expect(txJson.tx.inputs[0].id).toBe(txId);
-
  expect(txJson.tx.inputs[0].index).toBe(txIndex);
-

                      
-
  expect(txJson.tx.outputs).toHaveLength(1);
-
  expect(txJson.tx.outputs[0].address).toBe(outAddress);
-
  expect(txJson.tx.outputs[0].value).toBe(834159);
-

                      
-
  expect(txJson.witness).toHaveLength(1);
-
  expect(txJson.witness[0].PkWitness).toEqual([
-
    '1e74f51418f5835a063c1f4c69808134852b7ebdb85d0c08e867572c0a035e7b06b6bd7a7baa2a5dc191cd08f0ca81ada7298cfa20db44d7eda31e7777b4bbe0',
-
    '6e233a6365e9b371d3b8ce95b9f7f565a901109cbfd19e9bf32c4355f73a7466c6b57ec8867e8420d02ec9c2e42fa36e90ae080d6d184f2c9336bee079585c05',
-
  ]);
+
    expect(addressMap[myAddress]).not.toBe(undefined);
+
    expect(addressMap[notMyAddress]).toBe(undefined);
+
  });
});

                      
-
test('Daedalus transfer fails from too small UTXO', async () => {
-
  const words = 'note park thrive ignore spare latin common balance clap soup school tiny';
-
  const address = 'DdzFFzCqrhsmcx7z25PRkdbeUNqNNW4brhznpVxbm1EknAahjaCFEjYXg9KJRqkixjgGyz8D9GSX3CFDRoNrZyfJsi61N2FxCnq9yWBy';
-
  const txId = '915f2e6865fb31cc93410efb6c0e580ca74862374b3da461e20135c01f312e7c';
-
  const inputAmount = '1000';
-
  const txIndex = 0;
-
  const outAddress = 'Ae2tdPwUPEZ4Gg5gmqwW2t7ottKBMjWunmPt7DwKkAGsxx9XNSfWqrE1Gbk';
-

                      
-
  const daedalusWallet = getCryptoDaedalusWalletFromMnemonics(words);
-
  const checker = RustModule.WalletV2.DaedalusAddressChecker.new(daedalusWallet);
-
  const addressMap = getAddressesKeys({
-
    checker,
-
    fullUtxo: [address]
+
describe('Byron era tx format tests', () => {
+
  test('Daedalus transfer from single small UTXO', async () => {
+
    const words = 'note park thrive ignore spare latin common balance clap soup school tiny';
+
    const address = 'DdzFFzCqrhsmcx7z25PRkdbeUNqNNW4brhznpVxbm1EknAahjaCFEjYXg9KJRqkixjgGyz8D9GSX3CFDRoNrZyfJsi61N2FxCnq9yWBy';
+
    const txId = '915f2e6865fb31cc93410efb6c0e580ca74862374b3da461e20135c01f312e7c';
+
    const inputAmount = '1000000';
+
    const txIndex = 0;
+
    const outAddress = 'Ae2tdPwUPEZ4Gg5gmqwW2t7ottKBMjWunmPt7DwKkAGsxx9XNSfWqrE1Gbk';
+

                      
+
    const daedalusWallet = getCryptoDaedalusWalletFromMnemonics(words);
+
    const checker = RustModule.WalletV2.DaedalusAddressChecker.new(daedalusWallet);
+
    const addressMap = getAddressesKeys({
+
      checker,
+
      fullUtxo: [address]
+
    });
+

                      
+
    const utxo = {
+
      utxo_id: 'ignore',
+
      tx_hash: txId,
+
      tx_index: txIndex,
+
      receiver: address,
+
      amount: inputAmount
+
    };
+

                      
+
    const transferInfo = await buildDaedalusTransferTx({
+
      addressKeys: addressMap,
+
      getUTXOsForAddresses: (_addresses) => Promise.resolve([utxo]),
+
      outputAddr: outAddress,
+
      legacy: true
+
    });
+

                      
+
    expect(transferInfo.fee.toString()).toBe('0.165841');
+
    expect(transferInfo.recoveredBalance.toString()).toBe('1');
+
    expect(transferInfo.senders).toEqual([address]);
+
    expect(transferInfo.receiver).toBe(outAddress);
+

                      
+
    // check tx itself
+
    const signedTx = RustModule.WalletV2.SignedTransaction.from_bytes(transferInfo.encodedTx);
+
    const txJson = signedTx.to_json();
+
    expect(txJson.tx.inputs).toHaveLength(1);
+
    expect(txJson.tx.inputs[0].id).toBe(txId);
+
    expect(txJson.tx.inputs[0].index).toBe(txIndex);
+

                      
+
    expect(txJson.tx.outputs).toHaveLength(1);
+
    expect(txJson.tx.outputs[0].address).toBe(outAddress);
+
    expect(txJson.tx.outputs[0].value).toBe(834159);
+

                      
+
    expect(txJson.witness).toHaveLength(1);
+
    expect(txJson.witness[0].PkWitness).toEqual([
+
      '1e74f51418f5835a063c1f4c69808134852b7ebdb85d0c08e867572c0a035e7b06b6bd7a7baa2a5dc191cd08f0ca81ada7298cfa20db44d7eda31e7777b4bbe0',
+
      '6e233a6365e9b371d3b8ce95b9f7f565a901109cbfd19e9bf32c4355f73a7466c6b57ec8867e8420d02ec9c2e42fa36e90ae080d6d184f2c9336bee079585c05',
+
    ]);
  });

                      
-
  const utxo = {
-
    utxo_id: 'ignore',
-
    tx_hash: txId,
-
    tx_index: txIndex,
-
    receiver: address,
-
    amount: inputAmount
-
  };
-

                      
-
  expect(buildDaedalusTransferTx({
-
    addressKeys: addressMap,
-
    senderUtxos: [utxo],
-
    outputAddr: outAddress
-
  })).rejects.toThrow(GenerateTransferTxError);
-
});
+
  test('Daedalus transfer fails from too small UTXO', async () => {
+
    const words = 'note park thrive ignore spare latin common balance clap soup school tiny';
+
    const address = 'DdzFFzCqrhsmcx7z25PRkdbeUNqNNW4brhznpVxbm1EknAahjaCFEjYXg9KJRqkixjgGyz8D9GSX3CFDRoNrZyfJsi61N2FxCnq9yWBy';
+
    const txId = '915f2e6865fb31cc93410efb6c0e580ca74862374b3da461e20135c01f312e7c';
+
    const inputAmount = '1000';
+
    const txIndex = 0;
+
    const outAddress = 'Ae2tdPwUPEZ4Gg5gmqwW2t7ottKBMjWunmPt7DwKkAGsxx9XNSfWqrE1Gbk';
+

                      
+
    const daedalusWallet = getCryptoDaedalusWalletFromMnemonics(words);
+
    const checker = RustModule.WalletV2.DaedalusAddressChecker.new(daedalusWallet);
+
    const addressMap = getAddressesKeys({
+
      checker,
+
      fullUtxo: [address]
+
    });

                      
-
test('Daedalus transfer filters address not belonging to user', async () => {
-
  const words = 'note park thrive ignore spare latin common balance clap soup school tiny';
-
  const myAddress = 'DdzFFzCqrhsmcx7z25PRkdbeUNqNNW4brhznpVxbm1EknAahjaCFEjYXg9KJRqkixjgGyz8D9GSX3CFDRoNrZyfJsi61N2FxCnq9yWBy';
-
  const notMyAddress = 'DdzFFzCqrhsf69sXiAinAVVE9ZazKaoiKk9aSTRLJZSP4wMFGi4ogmcwjvSPMFuGD4a74HWemc3zfh3Eh4GdFRvmt3Jf88e77wCEUJgH';
+
    const utxo = {
+
      utxo_id: 'ignore',
+
      tx_hash: txId,
+
      tx_index: txIndex,
+
      receiver: address,
+
      amount: inputAmount
+
    };

                      
-
  const daedalusWallet = getCryptoDaedalusWalletFromMnemonics(words);
-
  const checker = RustModule.WalletV2.DaedalusAddressChecker.new(daedalusWallet);
-
  const addressMap = getAddressesKeys({
-
    checker,
-
    fullUtxo: [myAddress, notMyAddress]
  NoInputsError,
} from '../../errors';
import type { AddressedUtxo } from '../types';
-
import environment from '../../../../environment';
import type {
  AddressUtxoFunc,
} from '../../lib/state-fetch/types';
  keyLevel: number,
  signingKey: RustModule.WalletV3.Bip32PrivateKey,
  getUTXOsForAddresses: AddressUtxoFunc,
+
  legacy: boolean,
|}): Promise<TransferTx> {
-
  const senderUtxos = await toSenderUtxos(payload);
+
  const { legacy, ...rest } = payload;
+
  const senderUtxos = await toSenderUtxos(rest);

                      
  const txRequest = {
    outputAddr: payload.outputAddr,
    keyLevel: payload.keyLevel,
    signingKey: payload.signingKey,
    senderUtxos,
  };
-
  return environment.isShelley()
-
    ? shelleyFormatYoroiTx(txRequest)
-
    : legacyFormatYoroiTx(txRequest);
+
  return legacy
+
    ? legacyFormatYoroiTx(txRequest)
+
    : shelleyFormatYoroiTx(txRequest);
}
+
// @flow
+

                      
+
import '../../lib/test-config';
+
import { schema } from 'lovefield';
+
import {
+
  generateLegacyYoroiTransferTx,
+
} from './legacyYoroi';
+
import {
+
  silenceLogsForTesting,
+
} from '../../../../utils/logging';
+
import {
+
  Bip44DerivationLevels,
+
} from '../../lib/storage/database/walletTypes/bip44/api/utils';
+
import type {
+
  Address, Addressing
+
} from '../../lib/storage/models/PublicDeriver/interfaces';
+
import {
+
  ChainDerivations,
+
} from '../../../../config/numbersConfig';
+

                      
+
import {
+
  loadLovefieldDB,
+
} from '../../lib/storage/database/index';
+

                      
+
import type { ConfigType } from '../../../../../config/config-types';
+

                      
+
import { RustModule } from '../../lib/cardanoCrypto/rustLoader';
+

                      
+
declare var CONFIG: ConfigType;
+
const protocolMagic = CONFIG.network.protocolMagic;
+

                      
+
beforeAll(async () => {
+
  await RustModule.load();
+
  await loadLovefieldDB(schema.DataStoreType.MEMORY);
+
  silenceLogsForTesting();
+
});
+

                      
+
function getShelleyAddress(
+
  accountKey: RustModule.WalletV3.Bip32PrivateKey,
+
  derivationId: number
+
): {| ...Address, ...Addressing |} {
+
  const addr = RustModule.WalletV3.Address.single_from_public_key(
+
    accountKey
+
      .derive(ChainDerivations.EXTERNAL)
+
      .derive(0)
+
      .to_raw_key()
+
      .to_public(),
+
    RustModule.WalletV3.AddressDiscrimination.Production
+
  );
+
  return {
+
    address: addr.to_string('addr'),
+
    addressing: {
+
      path: [ChainDerivations.EXTERNAL, derivationId],
+
      startLevel: Bip44DerivationLevels.CHAIN.level,
+
    }
+
  };
+
}
+

                      
+
function getByronAddress(
+
  accountKey: RustModule.WalletV3.Bip32PrivateKey,
+
  derivationId: number
+
): {| ...Address, ...Addressing |} {
+
  const v3Key = accountKey
+
    .derive(ChainDerivations.EXTERNAL)
+
    .derive(0)
+
    .to_public();
+
  const v2Key = RustModule.WalletV2.PublicKey.from_hex(
+
    Buffer.from(v3Key.as_bytes()).toString('hex')
+
  );
+
  const addr = v2Key.bootstrap_era_address(
+
    RustModule.WalletV2.BlockchainSettings.from_json({
+
      protocol_magic: protocolMagic
+
    })
+
  );
+
  return {
+
    address: addr.to_base58(),
+
    addressing: {
+
      path: [ChainDerivations.EXTERNAL, derivationId],
+
      startLevel: Bip44DerivationLevels.CHAIN.level,
+
    }
+
  };
+
}
+

                      
+
describe('Byron era tx format tests', () => {
+
  test('Yoroi transfer from single small UTXO', async () => {
+
    const txId = '915f2e6865fb31cc93410efb6c0e580ca74862374b3da461e20135c01f312e7c';
+
    const inputAmount = '1000000';
+
    const txIndex = 0;
+
    const outAddress = 'Ae2tdPwUPEZKX8N2TjzBXLy5qrecnQUniTd2yxE8mWyrh2djNpUkbAtXtP4';
+

                      
+
    const accountPrivateKey = RustModule.WalletV3.Bip32PrivateKey.from_bytes(
+
      Buffer.from(
+
        '408a1cb637d615c49e8696c30dd54883302a20a7b9b8a9d1c307d2ed3cd50758c9402acd000461a8fc0f25728666e6d3b86d031b8eea8d2f69b21e8aa6ba2b153e3ec212cc8a36ed9860579dfe1e3ef4d6de778c5dbdd981623b48727cd96247',
+
        'hex',
+
      ),
+
    );
+

                      
+
    const addr1 = getByronAddress(accountPrivateKey, 0);
+
    const addr2 = getByronAddress(accountPrivateKey, 1);
+

                      
+
    const utxo = {
+
      utxo_id: 'ignore',
+
      tx_hash: txId,
+
      tx_index: txIndex,
+
      receiver: addr1.address,
+
      amount: inputAmount
+
    };
+

                      
+
    const transferInfo = await generateLegacyYoroiTransferTx({
+
      addresses: [addr1, addr2],
+
      getUTXOsForAddresses: (_addresses) => Promise.resolve([utxo]),
+
      keyLevel: Bip44DerivationLevels.ACCOUNT.level,
+
      signingKey: accountPrivateKey,
+
      outputAddr: outAddress,
+
      legacy: true
+
    });
+

                      
+
    expect(transferInfo.fee.toString()).toBe('0.165841');
+
    expect(transferInfo.recoveredBalance.toString()).toBe('1');
+
    expect(transferInfo.senders).toEqual([addr1.address]);
+
    expect(transferInfo.receiver).toBe(outAddress);
+

                      
+
    // check tx itself
+
    const signedTx = RustModule.WalletV2.SignedTransaction.from_bytes(transferInfo.encodedTx);
+
    const txJson = signedTx.to_json();
+
    expect(txJson.tx.inputs).toHaveLength(1);
+
    expect(txJson.tx.inputs[0].id).toBe(txId);
+
    expect(txJson.tx.inputs[0].index).toBe(txIndex);
+

                      
+
    expect(txJson.tx.outputs).toHaveLength(1);
+
    expect(txJson.tx.outputs[0].address).toBe(outAddress);
+
    expect(txJson.tx.outputs[0].value).toBe(834159);
+

                      
+
    expect(txJson.witness).toHaveLength(1);
+
    expect(txJson.witness[0].PkWitness).toEqual([
+
      '07cc5b01ab460562479f3e7fdf782b11636c4a1b721c19b9c1609bc7360b518ef3748736afd541361c4fb90b2963723fe9a10d237a024530d378181df4bf2c68',
+
      'c7beab6de0a38171bb4530c5f287239fba79fd8f2d89ba05a233c172bac4995d6933634521aba2ae43a175929ef0738ca531b22cf564071bd7149d8e80845500',
+
    ]);
+
  });
+
});
+

                      
+
describe('Shelley era tx format tests', () => {
+
  test('Yoroi transfer from single small UTXO', async () => {
+
    const txId = '915f2e6865fb31cc93410efb6c0e580ca74862374b3da461e20135c01f312e7c';
+
    const inputAmount = '1000000';
+
    const txIndex = 0;
+
    const outAddress = RustModule.WalletV3.Address.from_bytes(
+
      Buffer.from('038e2840fed90d2138761d8a14a4cbed08ed00cf908b07f94ec5fa9db6f4d7e74f', 'hex')
+
    ).to_string('addr');
+

                      
+
    const accountPrivateKey = RustModule.WalletV3.Bip32PrivateKey.from_bytes(
+
      Buffer.from(
+
        '408a1cb637d615c49e8696c30dd54883302a20a7b9b8a9d1c307d2ed3cd50758c9402acd000461a8fc0f25728666e6d3b86d031b8eea8d2f69b21e8aa6ba2b153e3ec212cc8a36ed9860579dfe1e3ef4d6de778c5dbdd981623b48727cd96247',
+
        'hex',
+
      ),
+
    );
+

                      
+
    const addr1 = getShelleyAddress(accountPrivateKey, 0);
+
    const addr2 = getShelleyAddress(accountPrivateKey, 1);
+

                      
+
    const utxo = {
+
      utxo_id: 'ignore',
+
      tx_hash: txId,
+
      tx_index: txIndex,
+
      receiver: addr1.address,
+
      amount: inputAmount
+
    };
+

                      
+
    const transferInfo = await generateLegacyYoroiTransferTx({
+
      addresses: [addr1, addr2],
+
      getUTXOsForAddresses: (_addresses) => Promise.resolve([utxo]),
+
      keyLevel: Bip44DerivationLevels.ACCOUNT.level,
+
      signingKey: accountPrivateKey,
+
      outputAddr: outAddress,
+
      legacy: false
+
    });
+

                      
+
    expect(transferInfo.fee.toString()).toBe('0.155383');
+
    expect(transferInfo.recoveredBalance.toString()).toBe('1');
+
    expect(transferInfo.senders).toEqual([addr1.address]);
+
    expect(transferInfo.receiver).toBe(outAddress);
+

                      
+
    // check tx itself
+
    const fragment = RustModule.WalletV3.Fragment.from_bytes(transferInfo.encodedTx);
+
    const signedTx = fragment.get_transaction();
+

                      
+
    const inputs = signedTx.inputs();
+
    expect(inputs.size()).toEqual(1);
+
    expect(inputs.get(0).value().to_str()).toEqual(inputAmount);
+
    const pointer = inputs.get(0).get_utxo_pointer();
+
    expect(Buffer.from(pointer.fragment_id().as_bytes()).toString('hex')).toEqual(txId);
+
    expect(pointer.output_index()).toEqual(txIndex);
+

                      
+
    const outputs = signedTx.outputs();
+
    expect(outputs.size()).toEqual(1);
+
    const output = outputs.get(0);
+
    expect(output.address().to_string('addr')).toEqual(outAddress);
+
    expect(output.value().to_str()).toEqual('844617');
+

                      
            outputAddr: nextInternalAddress,
            getUTXOsForAddresses:
              this.stores.substores.ada.stateFetchStore.fetcher.getUTXOsForAddresses,
+
            legacy: !environment.isShelley()
          });
          runInAction(() => {
            this.transferTx = transferTx;
      signingKey: accountKey,
      getUTXOsForAddresses:
        this.stores.substores.ada.stateFetchStore.fetcher.getUTXOsForAddresses,
+
      legacy: !environment.isShelley(),
    });
    // Possible exception: NotEnoughMoneyToSendError
    return transferTx;