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

842 use bufbuild type to storetransmit fvk instead of bech32 string #846

Merged
Show file tree
Hide file tree
Changes from 18 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
2 changes: 1 addition & 1 deletion apps/extension/src/message/popup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
} from '@penumbra-zone/types/src/internal-msg/shared';
import type { UserChoice } from '@penumbra-zone/types/src/user-choice';
import type { Jsonified } from '@penumbra-zone/types/src/jsonified';
import { OriginRecord } from '@penumbra-zone/storage/src/chrome/local';
import { OriginRecord } from '@penumbra-zone/storage/src/chrome/types';

export enum PopupType {
TxApproval = 'TxApproval',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { FadeTransition } from '@penumbra-zone/ui/components/ui/fade-transition'
import { Input } from '@penumbra-zone/ui/components/ui/input';
import { LinkGradientIcon } from '../../../icons/link-gradient';
import { SettingsHeader } from '../../../shared/components/settings-header';
import { OriginRecord } from '@penumbra-zone/storage/src/chrome/local';
import { OriginRecord } from '@penumbra-zone/storage/src/chrome/types';
import { DisplayOriginURL } from '../../../shared/components/display-origin-url';
import { useStore } from '../../../state';
import { connectedSitesSelector } from '../../../state/connected-sites';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ import { useStore } from '../../../state';
import { passwordSelector } from '../../../state/password';
import { KeyGradientIcon } from '../../../icons/key-gradient';
import { walletsSelector } from '../../../state/wallets';
import { bech32FullViewingKey } from '@penumbra-zone/bech32/src/full-viewing-key';

export const SettingsFullViewingKey = () => {
const { isPassword } = useStore(passwordSelector);
const { getFullViewingKey } = useStore(walletsSelector);

const [password, setPassword] = useState('');
const [enteredIncorrect, setEnteredIncorrect] = useState(false);
const [fullViewingKey, setFullViewingKey] = useState('');
const [fullViewingKey, setFullViewingKey] = useState<string>();

const submit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

void (async function () {
if (await isPassword(password)) {
setFullViewingKey(await getFullViewingKey());
setFullViewingKey(bech32FullViewingKey(await getFullViewingKey()));
Valentine1898 marked this conversation as resolved.
Show resolved Hide resolved
} else {
setEnteredIncorrect(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ import { useStore } from '../../../state';
import { passwordSelector } from '../../../state/password';
import { AccountKeyGradientIcon } from '../../../icons/account-key-gradient';
import { walletsSelector } from '../../../state/wallets';
import { bech32SpendKey } from '@penumbra-zone/bech32/src/spend-key';

export const SettingsSpendKey = () => {
const { isPassword } = useStore(passwordSelector);
const { getSpendKey } = useStore(walletsSelector);

const [password, setPassword] = useState('');
const [enteredIncorrect, setEnteredIncorrect] = useState(false);
const [spendKey, setSpendKey] = useState('');
const [spendKey, setSpendKey] = useState<string>();

const submit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();

void (async function () {
if (await isPassword(password)) {
setSpendKey(await getSpendKey());
setSpendKey(bech32SpendKey(await getSpendKey()));
} else {
setEnteredIncorrect(true);
}
Expand Down
8 changes: 6 additions & 2 deletions apps/extension/src/service-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ import { approveTransaction } from './approve-transaction';
// all rpc implementations, local and proxy
import { rpcImpls } from './impls';
import { backOff } from 'exponential-backoff';
import {
FullViewingKey,
WalletId,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';

const startServices = async () => {
const grpcEndpoint = await localExtStorage.get('grpcEndpoint');
Expand All @@ -44,8 +48,8 @@ const startServices = async () => {
const services = new Services({
idbVersion: IDB_VERSION,
grpcEndpoint,
walletId: wallet0.id,
fullViewingKey: wallet0.fullViewingKey,
walletId: WalletId.fromJsonString(wallet0.id),
fullViewingKey: FullViewingKey.fromJsonString(wallet0.fullViewingKey),
numeraireAssetId: USDC_ASSET_ID,
});
await services.initialize();
Expand Down
7 changes: 2 additions & 5 deletions apps/extension/src/state/connected-sites.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { beforeEach, describe, expect, test } from 'vitest';
import { create, StoreApi, UseBoundStore } from 'zustand';
import { AllSlices, initializeStore } from '.';
import {
localDefaults,
LocalStorageState,
OriginRecord,
} from '@penumbra-zone/storage/src/chrome/local';
import { localDefaults } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState, OriginRecord } from '@penumbra-zone/storage/src/chrome/types';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import {
mockLocalExtStorage,
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/state/connected-sites.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import { LocalStorageState, OriginRecord } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState, OriginRecord } from '@penumbra-zone/storage/src/chrome/types';
import { AllSlices, SliceCreator } from '.';

import Map from '@penumbra-zone/polyfills/src/Map.groupBy';
Expand Down
3 changes: 2 additions & 1 deletion apps/extension/src/state/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { customPersist } from './persist';
import { createPasswordSlice, PasswordSlice } from './password';
import { createSeedPhraseSlice, SeedPhraseSlice } from './seed-phrase';
import { createNetworkSlice, NetworkSlice } from './network';
import { localExtStorage, LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { localExtStorage } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import { sessionExtStorage, SessionStorageState } from '@penumbra-zone/storage/src/chrome/session';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import { createTxApprovalSlice, TxApprovalSlice } from './tx-approval';
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/state/network.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, test } from 'vitest';
import { create, StoreApi, UseBoundStore } from 'zustand';
import { AllSlices, initializeStore } from '.';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import {
mockLocalExtStorage,
mockSessionExtStorage,
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/state/network.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import { AllSlices, SliceCreator } from '.';

Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/state/password.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AllSlices, initializeStore } from '.';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import { Key, KeyPrint } from '@penumbra-zone/crypto-web/src/encryption';
import { webcrypto } from 'crypto';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import {
mockLocalExtStorage,
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/state/password.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AllSlices, SliceCreator } from '.';
import { Key, KeyJson, KeyPrint } from '@penumbra-zone/crypto-web/src/encryption';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import { SessionStorageState } from '@penumbra-zone/storage/src/chrome/session';

// Documentation in /docs/custody.md
Expand Down
3 changes: 2 additions & 1 deletion apps/extension/src/state/persist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { StateCreator, StoreMutatorIdentifier } from 'zustand';
import { AllSlices } from '.';
import { produce } from 'immer';

import { localExtStorage, LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { localExtStorage } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import { sessionExtStorage, SessionStorageState } from '@penumbra-zone/storage/src/chrome/session';
import { StorageItem } from '@penumbra-zone/storage/src/chrome/base';
import { walletsFromJson } from '@penumbra-zone/types/src/wallet';
Expand Down
8 changes: 5 additions & 3 deletions apps/extension/src/state/tx-approval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
Metadata,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb';
import { viewTransactionPlan } from '@penumbra-zone/perspective/plan/index';
import { FullViewingKey } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';

export interface TxApprovalSlice {
/**
Expand Down Expand Up @@ -72,12 +73,13 @@ export const createTxApprovalSlice = (): SliceCreator<TxApprovalSlice> => (set,
};

const wallets = await localExtStorage.get('wallets');
const activeWalletFvk = wallets[0]?.fullViewingKey ?? '';

if (!wallets[0]) {
throw new Error('No found wallet');
}
const transactionView = await viewTransactionPlan(
authorizeRequest.plan ?? new TransactionPlan(),
getMetadata,
activeWalletFvk,
FullViewingKey.fromJsonString(wallets[0].fullViewingKey),
);

// pregenerate views from various perspectives.
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/state/wallets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AllSlices, initializeStore } from '.';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import { webcrypto } from 'crypto';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import {
mockLocalExtStorage,
mockSessionExtStorage,
Expand Down
24 changes: 17 additions & 7 deletions apps/extension/src/state/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import {
} from '@penumbra-zone/wasm/src/keys';
import { Key } from '@penumbra-zone/crypto-web/src/encryption';
import { ExtensionStorage } from '@penumbra-zone/storage/src/chrome/base';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/local';
import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';
import { LocalStorageState } from '@penumbra-zone/storage/src/chrome/types';
import {
Address,
FullViewingKey,
SpendKey,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';
import { Wallet, WalletCreate } from '@penumbra-zone/types/src/wallet';

export interface WalletsSlice {
all: Wallet[];
addWallet: (toAdd: WalletCreate) => Promise<Wallet>;
getSeedPhrase: () => Promise<string[]>;
getSpendKey: () => Promise<string>;
getFullViewingKey: () => Promise<string>;
getSpendKey: () => Promise<SpendKey>;
getFullViewingKey: () => Promise<FullViewingKey>;
Valentine1898 marked this conversation as resolved.
Show resolved Hide resolved
}

export const createWalletsSlice =
Expand All @@ -36,7 +40,12 @@ export const createWalletsSlice =
const key = await Key.fromJson(passwordKey);
const encryptedSeedPhrase = await key.seal(seedPhraseStr);
const walletId = getWalletId(fullViewingKey);
const newWallet = new Wallet(label, walletId, fullViewingKey, { encryptedSeedPhrase });
const newWallet = new Wallet(
label,
walletId.toJsonString(),
fullViewingKey.toJsonString(),
{ encryptedSeedPhrase },
);

set(state => {
state.wallets.all.unshift(newWallet);
Expand Down Expand Up @@ -82,7 +91,8 @@ export const addrByIndexSelector =
const active = getActiveWallet(state);
if (!active) throw new Error('No active wallet');

const fullViewingKey = FullViewingKey.fromJsonString(active.fullViewingKey);
return ephemeral
? getEphemeralByIndex(active.fullViewingKey, index)
: getAddressByIndex(active.fullViewingKey, index);
? getEphemeralByIndex(fullViewingKey, index)
: getAddressByIndex(fullViewingKey, index);
};
3 changes: 2 additions & 1 deletion apps/extension/src/wasm-build-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1/transaction_pb';
import type { JsonValue } from '@bufbuild/protobuf';
import type { ActionBuildRequest } from '@penumbra-zone/types/src/internal-msg/offscreen';
import { FullViewingKey } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';

// necessary to propagate errors that occur in promises
// see: https://stackoverflow.com/questions/39992417/how-to-bubble-a-web-worker-error-in-a-promise-via-worker-onerror
Expand Down Expand Up @@ -40,7 +41,7 @@ self.addEventListener('message', workerListener, { once: true });
async function executeWorker(
transactionPlan: TransactionPlan,
witness: WitnessData,
fullViewingKey: string,
fullViewingKey: FullViewingKey,
actionPlanIndex: number,
): Promise<JsonValue> {
// Dynamically load wasm module
Expand Down
11 changes: 11 additions & 0 deletions packages/bech32/src/full-viewing-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { bech32m } from 'bech32';
import { PENUMBRA_BECH32_FVK_LENGTH, PENUMBRA_BECH32_FVK_PREFIX } from './penumbra-bech32';
import { FullViewingKey } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';

export const bech32FullViewingKey = (fvk: FullViewingKey): string =>
bech32m.encode(PENUMBRA_BECH32_FVK_PREFIX, bech32m.toWords(fvk.inner));

export const bech32ToFullViewingKey = (fvk: string): FullViewingKey => {
const decodeAddress = bech32m.decode(fvk, PENUMBRA_BECH32_FVK_LENGTH);
return new FullViewingKey({ inner: new Uint8Array(bech32m.fromWords(decodeAddress.words)) });
};
6 changes: 6 additions & 0 deletions packages/bech32/src/penumbra-bech32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@ export const PENUMBRA_BECH32_ASSET_LENGTH = 160;
export const PENUMBRA_BECH32_ASSET_PREFIX = 'passet';
export const PENUMBRA_BECH32_IDENTITY_LENGTH = PENUMBRA_BECH32_ADDRESS_LENGTH;
export const PENUMBRA_BECH32_IDENTITY_PREFIX = 'penumbravalid';
export const PENUMBRA_BECH32_FVK_PREFIX = 'penumbrafullviewingkey';
export const PENUMBRA_BECH32_FVK_LENGTH = 132;
export const PENUMBRA_BECH32_WALLET_ID_LENGTH = 75;
export const PENUMBRA_BECH32_WALLET_ID_PREFIX = 'penumbrawalletid';
export const PENUMBRA_BECH32_SPEND_KEY_LENGTH = 75;
export const PENUMBRA_BECH32_SPEND_KEY_PREFIX = 'penumbraspendkey';
13 changes: 13 additions & 0 deletions packages/bech32/src/spend-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { bech32m } from 'bech32';
import {
PENUMBRA_BECH32_SPEND_KEY_LENGTH,
PENUMBRA_BECH32_SPEND_KEY_PREFIX,
} from './penumbra-bech32';

export const bech32SpendKey = (fvk: { inner: Uint8Array }): string =>
bech32m.encode(PENUMBRA_BECH32_SPEND_KEY_PREFIX, bech32m.toWords(fvk.inner));

export const bech32ToSpendKey = (fvk: string) => {
const decodeAddress = bech32m.decode(fvk, PENUMBRA_BECH32_SPEND_KEY_LENGTH);
return new Uint8Array(bech32m.fromWords(decodeAddress.words));
};
14 changes: 14 additions & 0 deletions packages/bech32/src/wallet-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { bech32m } from 'bech32';
import {
PENUMBRA_BECH32_WALLET_ID_LENGTH,
PENUMBRA_BECH32_WALLET_ID_PREFIX,
} from './penumbra-bech32';
import { WalletId } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';

export const bech32WalletId = (walletId: WalletId): string =>
bech32m.encode(PENUMBRA_BECH32_WALLET_ID_PREFIX, bech32m.toWords(walletId.inner));

export const bech32ToWalletId = (walletId: string): WalletId => {
const decodeAddress = bech32m.decode(walletId, PENUMBRA_BECH32_WALLET_ID_LENGTH);
return new WalletId({ inner: new Uint8Array(bech32m.fromWords(decodeAddress.words)) });
};
1 change: 0 additions & 1 deletion packages/crypto/src/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ const decrypt = async (
* ==== External ====
*/

// Public, stored representation of KeyPrint
export interface KeyPrintJson {
hash: Base64Str;
salt: Base64Str;
Expand Down
5 changes: 3 additions & 2 deletions packages/perspective/plan/get-address-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Address,
AddressIndex,
AddressView,
FullViewingKey,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';
import { bech32ToAddress } from '@penumbra-zone/bech32/src/address';

Expand Down Expand Up @@ -40,7 +41,7 @@ describe('getAddressView()', () => {
},
});

expect(getAddressView(address, 'fvk').equals(expected)).toBe(true);
expect(getAddressView(address, new FullViewingKey()).equals(expected)).toBe(true);
});
});

Expand All @@ -59,7 +60,7 @@ describe('getAddressView()', () => {
},
});

expect(getAddressView(address, 'fvk').equals(expected)).toBe(true);
expect(getAddressView(address, new FullViewingKey()).equals(expected)).toBe(true);
});
});
});
3 changes: 2 additions & 1 deletion packages/perspective/plan/get-address-view.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
Address,
AddressView,
FullViewingKey,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';
import { getAddressIndexByAddress } from '@penumbra-zone/wasm/src/address';

export const getAddressView = (address: Address, fullViewingKey: string): AddressView => {
export const getAddressView = (address: Address, fullViewingKey: FullViewingKey): AddressView => {
const index = getAddressIndexByAddress(fullViewingKey, address);

if (index) {
Expand Down
6 changes: 4 additions & 2 deletions packages/perspective/plan/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1/transaction_pb';
import { bech32ToAddress } from '@penumbra-zone/bech32/src/address';
import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb';
import { bech32ToFullViewingKey } from '@penumbra-zone/bech32/src/full-viewing-key';

describe('viewTransactionPlan()', () => {
const returnAddressAsBech32 =
Expand All @@ -15,8 +16,9 @@ describe('viewTransactionPlan()', () => {
const chainId = 'testnet';
const expiryHeight = 100n;
const metadataByAssetId = vi.fn(() => Promise.resolve(new Metadata()));
const mockFvk =
'penumbrafullviewingkey1vzfytwlvq067g2kz095vn7sgcft47hga40atrg5zu2crskm6tyyjysm28qg5nth2fqmdf5n0q530jreumjlsrcxjwtfv6zdmfpe5kqsa5lg09';
const mockFvk = bech32ToFullViewingKey(
'penumbrafullviewingkey1vzfytwlvq067g2kz095vn7sgcft47hga40atrg5zu2crskm6tyyjysm28qg5nth2fqmdf5n0q530jreumjlsrcxjwtfv6zdmfpe5kqsa5lg09',
);

const validTxnPlan = new TransactionPlan({
memo: {
Expand Down
3 changes: 2 additions & 1 deletion packages/perspective/plan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TransactionView,
} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/transaction/v1/transaction_pb';
import { viewActionPlan } from './view-action-plan';
import { FullViewingKey } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';

/**
* Given a `TransactionPlan`, returns a `TransactionView` that can be passed to
Expand All @@ -22,7 +23,7 @@ import { viewActionPlan } from './view-action-plan';
export const viewTransactionPlan = async (
txPlan: TransactionPlan,
metadataByAssetId: (id: AssetId) => Promise<Metadata>,
fullViewingKey: string,
fullViewingKey: FullViewingKey,
): Promise<TransactionView> => {
const returnAddress = txPlan.memo?.plaintext?.returnAddress;
const transactionParameters = txPlan.transactionParameters;
Expand Down
Loading
Loading