Skip to content

Commit

Permalink
Merge branch 'develop' into feat/encryptus-flow
Browse files Browse the repository at this point in the history
  • Loading branch information
vsubhuman authored Jun 10, 2024
2 parents 646beb0 + a0fd658 commit 6733d0b
Show file tree
Hide file tree
Showing 66 changed files with 8,166 additions and 9,324 deletions.
5 changes: 1 addition & 4 deletions packages/e2e-tests/helpers/mock-dApp-webpage/dAppTxHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,8 @@ export function getTtl() {
},
];
const defaultTtlOffset = 7200;
const timeToSlot = genTimeToSlot(fullConfig);
const absSlotNumber = new BigNumber(
timeToSlot({
time: new Date(1649261533360),
}).slot
TimeUtils.timeToAbsoluteSlot(fullConfig, new Date(1649261533360))
);

return absSlotNumber.plus(defaultTtlOffset).toNumber();
Expand Down
87 changes: 78 additions & 9 deletions packages/yoroi-extension/app/api/ada/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ import { CoreAddressTypes, TxStatusCodes, } from './lib/storage/database/primiti
import type { NetworkRow, TokenRow, } from './lib/storage/database/primitives/tables';
import { TransactionType } from './lib/storage/database/primitives/tables';
import { PublicDeriver, } from './lib/storage/models/PublicDeriver/index';
import { asDisplayCutoff, asGetAllUtxos, asHasLevels, } from './lib/storage/models/PublicDeriver/traits';
import {
asDisplayCutoff,
asGetAllUtxos,
asHasLevels,
asHasUtxoChains,
} from './lib/storage/models/PublicDeriver/traits';
import { ConceptualWallet } from './lib/storage/models/ConceptualWallet/index';
import type { IHasLevels } from './lib/storage/models/ConceptualWallet/interfaces';
import type {
Expand Down Expand Up @@ -101,7 +106,8 @@ import { WrongPassphraseError } from './lib/cardanoCrypto/cryptoErrors';
import type {
AccountStateFunc,
AddressUtxoFunc,
BestBlockFunc, FilterFunc,
BestBlockFunc,
FilterFunc,
GetRecentTransactionHashesFunc,
GetTransactionsByHashesFunc,
HistoryFunc,
Expand All @@ -114,9 +120,14 @@ import type {
TokenInfoFunc,
} from './lib/state-fetch/types';
import { getChainAddressesForDisplay, } from './lib/storage/models/utils';
import { getAllAddressesForDisplay, rawGetAddressRowsForWallet, } from './lib/storage/bridge/traitUtils';
import {
asAddressedUtxo, cardanoMinAdaRequiredFromAssets_coinsPerWord,
getAllUsedAddresses,
getAllAddressesForDisplay,
rawGetAddressRowsForWallet,
} from './lib/storage/bridge/traitUtils';
import {
asAddressedUtxo,
cardanoMinAdaRequiredFromAssets_coinsPerWord,
convertAdaTransactionsToExportRows,
multiTokenFromCardanoValue,
multiTokenFromRemote,
Expand Down Expand Up @@ -147,7 +158,7 @@ import type { PersistedSubmittedTransaction } from '../localStorage';
import type { ForeignUtxoFetcher } from '../../connector/stores/ConnectorStore';
import type WalletTransaction from '../../domain/WalletTransaction';
import { derivePrivateByAddressing, derivePublicByAddressing } from './lib/cardanoCrypto/deriveByAddressing';
import { genTimeToSlot } from './lib/storage/bridge/timeUtils';
import TimeUtils from './lib/storage/bridge/timeUtils';

// ADA specific Request / Response params

Expand Down Expand Up @@ -498,6 +509,7 @@ export type GetTransactionRowsToExportFunc = (
) => Promise<GetTransactionRowsToExportResponse>;

export const FETCH_TXS_BATCH_SIZE = 20;
const MIN_REORG_OUTPUT_AMOUNT = '1000000';

export default class AdaApi {

Expand Down Expand Up @@ -1614,10 +1626,7 @@ export default class AdaApi {
if (changeAddr == null) {
throw new Error(`${nameof(this.createSimpleTx)} no internal addresses left. Should never happen`);
}
const timeToSlot = await genTimeToSlot(fullConfig);
const absSlotNumber = new BigNumber(
timeToSlot({ time: new Date()}).slot
);
const absSlotNumber = new BigNumber(TimeUtils.timeToAbsoluteSlot(fullConfig, new Date()));

const unsignedTx = await shelleyNewAdaUnsignedTx(
request.entries,
Expand Down Expand Up @@ -2313,6 +2322,66 @@ export default class AdaApi {
}
return utxos;
}

async createReorgTx(
publicDeriver: PublicDeriver<>,
usedUtxoIds: Array<string>,
reorgTargetAmount: string,
utxos: Array<CardanoAddressedUtxo>,
submittedTxs: Array<PersistedSubmittedTransaction>,
reorgTargetAddress?: string,
): Promise<{|
unsignedTx: HaskellShelleyTxSignRequest,
collateralOutputAddressSet: Set<string>,
|}> {
const network = publicDeriver.getParent().getNetworkInfo();

const withUtxos = asGetAllUtxos(publicDeriver);
if (withUtxos == null) {
throw new Error(`missing utxo functionality`);
}

const withHasUtxoChains = asHasUtxoChains(withUtxos);
if (withHasUtxoChains == null) {
throw new Error(`missing chains functionality`);
}

const fullConfig = getCardanoHaskellBaseConfig(network);
const absSlotNumber = new BigNumber(TimeUtils.timeToAbsoluteSlot(fullConfig, new Date()));
const targetAddress = reorgTargetAddress ?? (await getAllUsedAddresses(publicDeriver))[0];
if (targetAddress == null) {
throw new Error('unexpected: no target address or used addresses available');
}
const reorgOutputValue = BigNumber
.max(reorgTargetAmount, MIN_REORG_OUTPUT_AMOUNT)
.toString();
const includeTargets = [{
address: targetAddress,
isForeign: false,
value: reorgOutputValue,
}];
const collateralOutputAddressSet = new Set<string>([targetAddress]);
const dontUseUtxoIds = new Set(usedUtxoIds);
const unsignedTx = await this.createUnsignedTxForConnector(
{
publicDeriver: withHasUtxoChains,
absSlotNumber,
cardanoTxRequest: {
includeTargets,
},
utxos: (await this.addressedUtxosWithSubmittedTxs(
utxos,
publicDeriver,
submittedTxs,
)).filter(utxo => !dontUseUtxoIds.has(utxo.utxo_id)),
// we already factored in submitted transactions above, no need to handle it
// any more, so just use an empty array here
submittedTxs: [],
},
null,
);
return { unsignedTx, collateralOutputAddressSet };
}
}
// ========== End of class AdaApi =========

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ import type {
MultiAssetSupplyResponse,
FilterUsedRequest,
FilterUsedResponse,
GetSwapFeeTiersFunc,
GetSwapFeeTiersFunc, GetTransactionSlotsByHashesResponse, SignedBatchRequest,
} from './types';

export interface IFetcher {
getUTXOsForAddresses(body: AddressUtxoRequest): Promise<AddressUtxoResponse>;
getTransactionsHistoryForAddresses(body: HistoryRequest): Promise<HistoryResponse>;
getRewardHistory(body: RewardHistoryRequest): Promise<RewardHistoryResponse>;
getBestBlock(body: BestBlockRequest): Promise<BestBlockResponse>;
sendTx(body: SignedRequest): Promise<SignedResponse>;
sendTx(body: SignedRequest | SignedBatchRequest): Promise<SignedResponse>;
getAccountState(body: AccountStateRequest): Promise<AccountStateResponse>;
getPoolInfo(body: PoolInfoRequest): Promise<PoolInfoResponse>;
getCatalystRoundInfo(body: CatalystRoundInfoRequest): Promise<CatalystRoundInfoResponse>;
Expand All @@ -56,6 +56,8 @@ export interface IFetcher {
: GetRecentTransactionHashesRequest => Promise<GetRecentTransactionHashesResponse>;
getTransactionsByHashes
: GetTransactionsByHashesRequest => Promise<GetTransactionsByHashesResponse>;
getTransactionSlotsByHashes
: GetTransactionsByHashesRequest => Promise<GetTransactionSlotsByHashesResponse>;
getSwapFeeTiers
: GetSwapFeeTiersFunc;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import type {
FilterUsedRequest,
FilterUsedResponse,
FilterFunc,
GetSwapFeeTiersFunc,
GetSwapFeeTiersFunc, GetTransactionSlotsByHashesResponse, GetTransactionSlotsByHashesFunc, SignedBatchRequest,
} from './types';
import LocalizableError from '../../../../i18n/LocalizableError';

Expand Down Expand Up @@ -111,6 +111,14 @@ export class BatchedFetcher implements IFetcher {
)(body)
);

getTransactionSlotsByHashes
: GetTransactionsByHashesRequest => Promise<GetTransactionSlotsByHashesResponse>
= (body) => (
batchGetTransactionSlotsByHashes(
this.baseFetcher.getTransactionSlotsByHashes
)(body)
);

getRewardHistory: RewardHistoryRequest => Promise<RewardHistoryResponse> = (body) => (
batchGetRewardHistory(
this.baseFetcher.getRewardHistory
Expand All @@ -122,9 +130,8 @@ export class BatchedFetcher implements IFetcher {
this.baseFetcher.getBestBlock(body)
)

sendTx: SignedRequest => Promise<SignedResponse> = (body) => (
sendTx: (SignedRequest | SignedBatchRequest) => Promise<SignedResponse> = (body) => (
// We don't batch transaction sending (it's just a single request)
// TODO: Should we support batching a list of transactions?
this.baseFetcher.sendTx(body)
)

Expand Down Expand Up @@ -298,15 +305,31 @@ function batchGetTransactionsByHashes(
return async function(
body: GetTransactionsByHashesRequest
): Promise<GetTransactionsByHashesResponse> {
let txs = [];
for (const txHashes of chunk(body.txHashes, 100)) {
const batchResult = await getTransactionsByHashes({
const promises = chunk(body.txHashes, 100).map(txHashes => {
return getTransactionsByHashes({
txHashes,
network: body.network,
});
txs = [ ...txs, ...batchResult ];
}
return txs;
});
const resultChunks = await Promise.all(promises);
return resultChunks.reduce((res, entry) => ([ ...res, ...entry ]), ([]: GetTransactionsByHashesResponse));
};
}

function batchGetTransactionSlotsByHashes(
getTransactionSlotsByHashes: GetTransactionSlotsByHashesFunc,
): GetTransactionSlotsByHashesFunc {
return async function(
body: GetTransactionsByHashesRequest
): Promise<GetTransactionSlotsByHashesResponse> {
const promises = chunk(body.txHashes, 100).map(txHashes => {
return getTransactionSlotsByHashes({
txHashes,
network: body.network,
});
});
const resultChunks = await Promise.all(promises);
return resultChunks.reduce((res, entry) => ({ ...res, ...entry }), ({}: GetTransactionSlotsByHashesResponse));
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,52 @@

import BigNumber from 'bignumber.js';
import type {
HistoryRequest,
HistoryResponse,
HistoryFunc,
BestBlockRequest,
BestBlockResponse,
BestBlockFunc,
AddressUtxoRequest,
AddressUtxoResponse,
AddressUtxoFunc,
RewardHistoryFunc,
AccountStateFunc,
AccountStateRequest,
AccountStateResponse,
AccountStateFunc,
AddressUtxoFunc,
AddressUtxoRequest,
AddressUtxoResponse,
BestBlockFunc,
BestBlockRequest,
BestBlockResponse,
FilterFunc,
FilterUsedRequest,
FilterUsedResponse,
GetRecentTransactionHashesFunc,
GetRecentTransactionHashesRequest,
GetRecentTransactionHashesResponse,
GetTransactionsByHashesFunc,
GetTransactionsByHashesRequest,
GetTransactionsByHashesResponse,
HistoryFunc,
HistoryRequest,
HistoryResponse,
MultiAssetMintMetadataFunc,
MultiAssetSupplyFunc,
PoolInfoFunc,
PoolInfoRequest,
PoolInfoResponse,
PoolInfoFunc,
RemoteTransaction,
RemoteTransactionInput,
RemoteUnspentOutput,
RewardHistoryFunc,
SignedRequestInternal,
RemoteTransactionInput,
TokenInfoFunc,
MultiAssetMintMetadataFunc,
GetTransactionsByHashesRequest,
GetTransactionsByHashesResponse,
GetTransactionsByHashesFunc,
GetRecentTransactionHashesRequest,
GetRecentTransactionHashesResponse,
GetRecentTransactionHashesFunc,
MultiAssetSupplyFunc, FilterUsedRequest, FilterUsedResponse, FilterFunc,
} from './types';
import { ShelleyCertificateTypes } from './types';
import { RollbackApiError, } from '../../../common/errors';
import { toEnterprise, addressToKind, toHexOrBase58 } from '../storage/bridge/utils';
import { CoreAddressTypes } from '../storage/database/primitives/enums';
import { addressToKind, toEnterprise, toHexOrBase58 } from '../storage/bridge/utils';
import type { CoreAddressT } from '../storage/database/primitives/enums';
import {
mnemonicToEntropy
} from 'bip39';
import {
WalletTypePurpose,
} from '../../../../config/numbersConfig';
import { CoreAddressTypes } from '../storage/database/primitives/enums';
import { mnemonicToEntropy } from 'bip39';
import { WalletTypePurpose, } from '../../../../config/numbersConfig';
import type { NetworkRow } from '../storage/database/primitives/tables';

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

import { generateLedgerWalletRootKey } from '../cardanoCrypto/cryptoWallet';
import { networks, getCardanoHaskellBaseConfig } from '../storage/database/prepackaged/networks';
import { getCardanoHaskellBaseConfig, networks } from '../storage/database/prepackaged/networks';
import { bech32 } from 'bech32';
import { Bech32Prefix } from '../../../../config/stringConfig';
import { parseTokenList } from '../../transactions/utils';
Expand All @@ -62,7 +62,7 @@ import type {
UtxoDiffSincePointRequest
} from '@emurgo/yoroi-lib/dist/utxo/models';
import { UtxoApiResult, } from '@emurgo/yoroi-lib/dist/utxo/models';
import { ShelleyCertificateTypes } from './types';
import { forceNonNull, last } from '../../../../coreUtils';

function byronAddressToHex(byronAddrOrHex: string): string {
if (RustModule.WalletV4.ByronAddress.is_valid(byronAddrOrHex)) {
Expand Down Expand Up @@ -551,8 +551,8 @@ export function toRemoteByronTx(
blockchain: Array<RemoteTransaction>,
request: SignedRequestInternal,
): RemoteTransaction {
const signedTx = RustModule.WalletV4.Transaction
.from_bytes(Buffer.from(request.signedTx, 'base64'));
const tx = Array.isArray(request.signedTx) ? forceNonNull(last(request.signedTx)) : request.signedTx;
const signedTx = RustModule.WalletV4.Transaction.from_bytes(Buffer.from(tx, 'base64'));
const body = signedTx.body();
const hash = Buffer.from(RustModule.WalletV4.hash_transaction(body).to_bytes()).toString('hex');
Expand Down
Loading

0 comments on commit 6733d0b

Please sign in to comment.