Skip to content

Commit

Permalink
Merge f980550 into ceea841
Browse files Browse the repository at this point in the history
  • Loading branch information
lucas-barros committed Apr 5, 2024
2 parents ceea841 + f980550 commit 4fcfef8
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export const DappTransactionContainer = withAddressBookContext(
inMemoryWallet,
blockchainProvider: { assetProvider },
walletUI: { cardanoCoin },
walletState
walletState,
cardanoWallet
} = useWalletStore();

const ownAddresses = useObservable(inMemoryWallet.addresses$)?.map((a) => a.address);
Expand Down Expand Up @@ -180,7 +181,7 @@ export const DappTransactionContainer = withAddressBookContext(
errorMessage={errorMessage}
toAddress={toAddressTokens}
collateral={txCollateral}
ownAddresses={ownAddresses}
ownAddresses={cardanoWallet.source.wallet.metadata.addresses || ownAddresses}
addressToNameMap={addressToNameMap}
/>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ describe('Testing DappTransactionContainer component', () => {
inMemoryWallet,
blockchainProvider: { assetProvider },
walletInfo,
walletUI: { cardanoCoin }
walletUI: { cardanoCoin },
cardanoWallet: { source: { wallet: { metadata: {} } } }
}));
mockDappTransaction.mockReset();
mockDappTransaction.mockReturnValue(<span data-testid="DappTransaction" />);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/* eslint-disable no-magic-numbers */
/* eslint-disable unicorn/no-useless-undefined */
import { WalletManager, WalletRepository } from '@cardano-sdk/web-extension';
import { cacheWalletAddressSubscription } from '../cache-wallets-address';
import { Wallet } from '@lace/cardano';
import { BehaviorSubject, of } from 'rxjs';

describe('cacheWalletAddressSubscription', () => {
afterEach(() => {
jest.clearAllMocks();
});

it('should not trigger subscription for no active wallet', () => {
const mockWalletManager = {
activeWallet$: of(undefined),
activeWalletId$: of(undefined)
} as unknown as WalletManager<Wallet.WalletMetadata, Wallet.AccountMetadata>;

const mockWalletRepository = {
wallets$: of([]),
updateWalletMetadata: jest.fn()
} as unknown as WalletRepository<Wallet.WalletMetadata, Wallet.AccountMetadata>;

cacheWalletAddressSubscription(mockWalletManager, mockWalletRepository);

expect(mockWalletRepository.updateWalletMetadata).not.toHaveBeenCalled();
});

it('should subscribe and update metadata', () => {
const mockWalletManager = {
activeWallet$: of({ addresses$: of([{ address: 'address1' }]) }),
activeWalletId$: of({ walletId: 'walletId' })
} as unknown as WalletManager<Wallet.WalletMetadata, Wallet.AccountMetadata>;

const mockWalletRepository = {
wallets$: of([
{
walletId: 'walletId',
metadata: {}
}
]),
updateWalletMetadata: jest.fn()
} as unknown as WalletRepository<Wallet.WalletMetadata, Wallet.AccountMetadata>;

cacheWalletAddressSubscription(mockWalletManager, mockWalletRepository);

expect(mockWalletRepository.updateWalletMetadata).toHaveBeenCalledWith({
walletId: 'walletId',
metadata: {
addresses: ['address1']
}
});
});

it('should subscribe and update metadata when a new wallet is added and activated', () => {
const activeWallet$ = new BehaviorSubject({
addresses$: of([{ address: 'address1' }])
});
const activeWalletId$ = new BehaviorSubject({
walletId: 'walletId1'
});
const wallets$ = new BehaviorSubject<{ walletId: string; metadata: { addresses?: string[] } }[]>([
{
walletId: 'walletId1',
metadata: { addresses: ['address1'] }
}
]);
const mockWalletManager = {
activeWallet$,
activeWalletId$
} as unknown as WalletManager<Wallet.WalletMetadata, Wallet.AccountMetadata>;

const mockWalletRepository = {
wallets$,
updateWalletMetadata: jest.fn()
} as unknown as WalletRepository<Wallet.WalletMetadata, Wallet.AccountMetadata>;

cacheWalletAddressSubscription(mockWalletManager, mockWalletRepository);

wallets$.next([
{
walletId: 'walletId1',
metadata: { addresses: ['address1'] }
},
{
walletId: 'walletId2',
metadata: {}
}
]);
activeWalletId$.next({ walletId: 'walletId2' });
activeWallet$.next({ addresses$: of([{ address: 'address2' }, { address: 'address3' }]) });

expect(mockWalletRepository.updateWalletMetadata).toHaveBeenNthCalledWith(1, {
walletId: 'walletId1',
metadata: {
addresses: ['address1']
}
});

expect(mockWalletRepository.updateWalletMetadata).toHaveBeenNthCalledWith(2, {
walletId: 'walletId2',
metadata: {
addresses: ['address2', 'address3', 'address1']
}
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { WalletManager, WalletRepository } from '@cardano-sdk/web-extension';
import { Wallet } from '@lace/cardano';
import { filter, switchMap, withLatestFrom, zip } from 'rxjs';

export const cacheWalletAddressSubscription = (
walletManager: WalletManager<Wallet.WalletMetadata, Wallet.AccountMetadata>,
walletRepository: WalletRepository<Wallet.WalletMetadata, Wallet.AccountMetadata>
): void => {
zip([
walletManager.activeWalletId$.pipe(filter((activeWalletId) => Boolean(activeWalletId))),
walletManager.activeWallet$.pipe(
filter((wallet) => Boolean(wallet)),
switchMap((wallet) => wallet.addresses$)
)
])
.pipe(withLatestFrom(walletRepository.wallets$))
.subscribe(([[activeWallet, walletAddresses], wallets]) => {
const wallet = wallets.find(({ walletId }) => walletId === activeWallet.walletId);
const allCachedWalletAddresses = wallets.reduce(
(acc, { metadata: { addresses = [] } }) => [...acc, ...addresses],
[]
);

const addresses = new Set([...walletAddresses.map(({ address }) => address), ...allCachedWalletAddresses]);

walletRepository.updateWalletMetadata({
walletId: activeWallet.walletId,
metadata: {
...wallet.metadata,
addresses: [...addresses]
}
});
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { Wallet } from '@lace/cardano';
import { ADA_HANDLE_POLICY_ID, HANDLE_SERVER_URLS } from '@src/features/ada-handle/config';
import { Cardano, NotImplementedError } from '@cardano-sdk/core';
import { cacheWalletAddressSubscription } from './cache-wallets-address';

const logger = console;

Expand Down Expand Up @@ -198,4 +199,6 @@ walletManager
logger.error('Failed to initialize wallet manager', error);
});

cacheWalletAddressSubscription(walletManager, walletRepository);

export const wallet$ = walletManager.activeWallet$;
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ export const TransactionDetailsProxy = withAddressBookContext(
inMemoryWallet,
walletInfo,
environmentName,
walletUI: { cardanoCoin, appMode }
walletUI: { cardanoCoin, appMode },
cardanoWallet
} = useWalletStore();
const isPopupView = appMode === APP_MODE_POPUP;
const openExternalLink = useExternalLinkOpener();

// Prepare own addresses of active account
const walletAddresses = useObservable(inMemoryWallet.addresses$)?.map((a) => a.address);
const walletAddresses =
cardanoWallet.source.wallet.metadata.addresses || useObservable(inMemoryWallet.addresses$)?.map((a) => a.address);

// Prepare address book data as Map<address, name>
const { list: addressList } = useAddressBookContext();
Expand Down
1 change: 1 addition & 0 deletions packages/cardano/src/wallet/lib/cardano-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface WalletMetadata {
name: string;
lockValue?: HexBlob;
lastActiveAccountIndex?: number;
addresses?: Cardano.PaymentAddress[];
}

export interface AccountMetadata {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ const data: ComponentProps<typeof TransactionDetails> = {
openExternalLink: (url) => window.open(url, '_blank', 'noopener,noreferrer'),
handleOpenExternalHashLink: () => {
console.log('handle on hash click', '639a43144dc2c0ead16f2fb753360f4b4f536502dbdb8aa5e424b00abb7534ff');
}
},
ownAddresses: []
};

const stakeVoteDelegationCertificate = [
Expand Down

0 comments on commit 4fcfef8

Please sign in to comment.