Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle wallet birthday height for non-mainnet chain ids #216

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion apps/extension/src/routes/page/onboarding/set-grpc-endpoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@ import { FadeTransition } from '@repo/ui/components/ui/fade-transition';
import { usePageNav } from '../../../utils/navigate';
import { PagePath } from '../paths';
import { GrpcEndpointForm } from '../../../shared/components/grpc-endpoint-form';
import { createPromiseClient } from '@connectrpc/connect';
import { createGrpcWebTransport } from '@connectrpc/connect-web';
import { AppService, TendermintProxyService } from '@penumbra-zone/protobuf';
import { localExtStorage } from '../../../storage/local';

// Because the new seed phrase generation step queries a mainnet rpc,
// when using a non-mainnet chain id, there is a chance that generated wallet birthday is wrong.
// This logic fixes this issue after they select their rpc.
export const correctBirthdayHeightIfNeeded = async (grpcEndpoint: string) => {
const transport = createGrpcWebTransport({ baseUrl: grpcEndpoint });
const { appParameters } = await createPromiseClient(AppService, transport).appParameters({});

if (!appParameters?.chainId.includes('penumbra-1')) {
const setWalletBirthday = await localExtStorage.get('walletCreationBlockHeight');
if (setWalletBirthday) {
const tendermintClient = createPromiseClient(TendermintProxyService, transport);
const { syncInfo } = await tendermintClient.getStatus({});

// If the user's birthday is longer than the chain height, that means their mainnet birthday
// is too long and needs to be shortened to the current block height of the non-mainnet chain
if (syncInfo?.latestBlockHeight && Number(syncInfo.latestBlockHeight) < setWalletBirthday) {
await localExtStorage.set('walletCreationBlockHeight', Number(syncInfo.latestBlockHeight));
}
}
}
};

export const SetGrpcEndpoint = () => {
const navigate = usePageNav();
Expand All @@ -24,7 +50,12 @@ export const SetGrpcEndpoint = () => {
</CardHeader>

<div className='mt-6'>
<GrpcEndpointForm submitButtonLabel='Next' isOnboarding={true} onSuccess={onSuccess} />
<GrpcEndpointForm
submitButtonLabel='Next'
isOnboarding={true}
onSuccess={onSuccess}
beforeSubmit={correctBirthdayHeightIfNeeded}
/>
</div>
</Card>
</FadeTransition>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ export const GrpcEndpointForm = ({
submitButtonLabel,
isOnboarding,
onSuccess,
beforeSubmit,
}: {
submitButtonLabel: string;
isOnboarding: boolean;
onSuccess: () => void | Promise<void>;
beforeSubmit?: (proposedEndpoint: string) => void | Promise<void>;
}) => {
const {
chainId,
Expand All @@ -39,7 +41,7 @@ export const GrpcEndpointForm = ({
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (isSubmitButtonEnabled) {
void onSubmit(onSuccess);
void onSubmit({ beforeSubmit, onSuccess });
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,21 @@ export const useGrpcEndpointForm = (isOnboarding: boolean) => {

const chainIdChanged = !!originalChainId && !!chainId && originalChainId !== chainId;

const onSubmit = async (
const onSubmit = async ({
beforeSubmit,
onSuccess,
}: {
/** Callback to run prior to saving action */
beforeSubmit?: (proposedEndpoint: string) => void | Promise<void>;
/** Callback to run when the RPC endpoint successfully saves */
onSuccess: () => void | Promise<void>,
) => {
onSuccess: () => void | Promise<void>;
}) => {
setIsSubmitButtonEnabled(false);

if (beforeSubmit) {
await beforeSubmit(grpcEndpointInput);
}

// If the chain id has changed, our cache is invalid
if (!isOnboarding && chainIdChanged) {
const promiseWithResolvers = Promise.withResolvers<void>();
Expand Down
5 changes: 2 additions & 3 deletions apps/extension/src/wallet-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ export const startWalletServices = async () => {
const wallet = await onboardWallet();
const grpcEndpoint = await onboardGrpcEndpoint();
const numeraires = await localExtStorage.get('numeraires');

// Retrieve the wallet creation height flag from storage
const chainId = await getChainId(grpcEndpoint);
const walletCreationBlockHeight = await localExtStorage.get('walletCreationBlockHeight');

const services = new Services({
grpcEndpoint,
chainId: await getChainId(grpcEndpoint),
chainId,
walletId: WalletId.fromJsonString(wallet.id),
fullViewingKey: FullViewingKey.fromJsonString(wallet.fullViewingKey),
numeraires: numeraires.map(n => AssetId.fromJsonString(n)),
Expand Down