-
-
Notifications
You must be signed in to change notification settings - Fork 274
fix(wallet): Fix builds and most lint issues #8420
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
Changes from all commits
9d908c5
c4b0728
8626c7c
b36ee54
36691cc
e91bbe2
a652933
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,4 +37,9 @@ scripts/coverage | |
| packages/*/*.tsbuildinfo | ||
|
|
||
| # AI | ||
| .sisyphus/ | ||
| .sisyphus/ | ||
|
|
||
| # Wallet | ||
| .claude/ | ||
| .env | ||
| !.env.example | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| INFURA_PROJECT_KEY= | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,9 @@ | ||
| import { | ||
| ClientConfigApiService, | ||
| ClientType, | ||
| DistributionType, | ||
| EnvironmentType, | ||
| } from '@metamask/remote-feature-flag-controller'; | ||
| import { enableNetConnect } from 'nock'; | ||
|
|
||
| import { importSecretRecoveryPhrase, sendTransaction } from './utilities'; | ||
|
|
@@ -7,12 +13,27 @@ const TEST_PHRASE = | |
| 'test test test test test test test test test test test ball'; | ||
| const TEST_PASSWORD = 'testpass'; | ||
|
|
||
| async function setupWallet() { | ||
| async function setupWallet(): Promise<Wallet> { | ||
| if (!process.env.INFURA_PROJECT_KEY) { | ||
| throw new Error( | ||
| 'INFURA_PROJECT_KEY is not set. Copy .env.example to .env and fill in your key.', | ||
| ); | ||
| } | ||
|
|
||
| const wallet = new Wallet({ | ||
| options: { | ||
| infuraProjectId: 'infura-project-id', | ||
| infuraProjectId: process.env.INFURA_PROJECT_KEY, | ||
| clientVersion: '1.0.0', | ||
| showApprovalRequest: () => undefined, | ||
| showApprovalRequest: (): undefined => undefined, | ||
| clientConfigApiService: new ClientConfigApiService({ | ||
| fetch: globalThis.fetch, | ||
| config: { | ||
| client: ClientType.Extension, | ||
| distribution: DistributionType.Main, | ||
| environment: EnvironmentType.Production, | ||
| }, | ||
| }), | ||
| getMetaMetricsId: (): string => 'fake-metrics-id', | ||
| }, | ||
| }); | ||
|
|
||
|
|
@@ -22,8 +43,21 @@ async function setupWallet() { | |
| } | ||
|
|
||
| describe('Wallet', () => { | ||
| let wallet: Wallet; | ||
|
|
||
| beforeEach(() => { | ||
| jest.useFakeTimers({ doNotFake: ['nextTick', 'queueMicrotask'] }); | ||
| }); | ||
|
|
||
| afterEach(async () => { | ||
| await wallet?.destroy(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Any concern with just doing
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As opposed to in
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I generally find that more readable but it also provides flexibility in the way that we can pass different arguments to
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer keeping cleanup in the hooks because customizing it between different test cases has a tendency to cause pernicious bugs in the test suite, IME. |
||
| enableNetConnect(); | ||
| jest.useRealTimers(); | ||
| }); | ||
|
|
||
| it('can unlock and populate accounts', async () => { | ||
| const { messenger } = await setupWallet(); | ||
| wallet = await setupWallet(); | ||
| const { messenger } = wallet; | ||
|
|
||
| expect( | ||
| messenger | ||
|
|
@@ -35,7 +69,7 @@ describe('Wallet', () => { | |
| it('signs transactions', async () => { | ||
| enableNetConnect(); | ||
|
|
||
| const wallet = await setupWallet(); | ||
| wallet = await setupWallet(); | ||
|
|
||
| const addresses = wallet.messenger | ||
| .call('AccountsController:listAccounts') | ||
|
|
@@ -47,7 +81,8 @@ describe('Wallet', () => { | |
| { networkClientId: 'sepolia' }, | ||
| ); | ||
|
|
||
| const hash = await result; | ||
| // Advance timers by an arbitrary value to trigger downstream timer logic. | ||
| const hash = await jest.advanceTimersByTimeAsync(60_000).then(() => result); | ||
FrederikBolding marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| expect(hash).toStrictEqual(expect.any(String)); | ||
| expect(transactionMeta).toStrictEqual( | ||
|
|
@@ -61,10 +96,11 @@ describe('Wallet', () => { | |
| }), | ||
| }), | ||
| ); | ||
| }); | ||
| }, 10_000); | ||
|
|
||
| it('exposes state', async () => { | ||
| const { state } = await setupWallet(); | ||
| wallet = await setupWallet(); | ||
| const { state } = wallet; | ||
|
|
||
| expect(state.KeyringController).toStrictEqual({ | ||
| isUnlocked: true, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| import type { | ||
| ActionConstraint, | ||
| EventConstraint, | ||
| Messenger, | ||
| MessengerActions, | ||
| MessengerEvents, | ||
| } from '@metamask/messenger'; | ||
|
|
||
| import * as defaultConfigurations from './instances'; | ||
| import type { InitializationConfiguration, InstanceState } from './types'; | ||
|
|
||
| export { defaultConfigurations }; | ||
|
|
||
| type ExtractInstance<Config> = | ||
| Config extends InitializationConfiguration<infer Instance, infer _> | ||
| ? Instance | ||
| : never; | ||
|
|
||
| type ExtractInstanceMessenger<Config> = | ||
| Config extends InitializationConfiguration<infer _, infer InferredMessenger> | ||
| ? InferredMessenger | ||
| : never; | ||
|
|
||
| type ExtractName<Config> = | ||
| ExtractInstance<Config> extends { name: infer Name extends string } | ||
| ? Name | ||
| : never; | ||
|
|
||
| type Configs = typeof defaultConfigurations; | ||
|
|
||
| type AllMessengers = ExtractInstanceMessenger<Configs[keyof Configs]>; | ||
|
|
||
| export type DefaultInstances = { | ||
| [Key in keyof Configs as ExtractName<Configs[Key]>]: ExtractInstance< | ||
| Configs[Key] | ||
| >; | ||
| }; | ||
|
|
||
| export type DefaultActions = MessengerActions<AllMessengers>; | ||
|
|
||
| export type DefaultEvents = MessengerEvents<AllMessengers>; | ||
|
|
||
| export type RootMessenger< | ||
| AllowedActions extends ActionConstraint = ActionConstraint, | ||
| AllowedEvents extends EventConstraint = EventConstraint, | ||
| > = Messenger<'Root', AllowedActions, AllowedEvents>; | ||
|
|
||
| export type DefaultState = { | ||
| [Key in keyof DefaultInstances]: InstanceState<DefaultInstances[Key]>; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,8 @@ | ||
| export type { | ||
| DefaultActions, | ||
| DefaultEvents, | ||
| DefaultInstances, | ||
| DefaultState, | ||
| RootMessenger, | ||
| } from './defaults'; | ||
| export { initialize } from './initialization'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we need to pass this entire thing in? Maybe just add
client,distribution,environmenttoWalletOptionsand we can constructClientConfigApiServicebased on that?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think merging the constructor params of
ClientConfigApiServiceinto theWalletconstructor params would be more trouble than it's worth. If we ultimately decide that we don't care about all of the options of the former, we can always fold it in later.