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

✨ feat: Add keplr wallet support and shared utils package #1147

Closed
wants to merge 60 commits into from
Closed
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
c5087d0
initial keplr set up
0xSero Jun 12, 2024
5829861
move over keplr set up
0xSero Jun 12, 2024
4fd666f
more set up
0xSero Jun 12, 2024
60304a3
init
0xSero Jun 12, 2024
0ec44d3
keplr extension install
0xSero Jun 13, 2024
97091d6
selectors
0xSero Jun 13, 2024
101c9ad
playwright keplr set up
0xSero Jun 13, 2024
a5a6762
build set up
0xSero Jun 13, 2024
e8d0bd8
prepare test
0xSero Jun 13, 2024
e1179ad
prepare test
0xSero Jun 13, 2024
b39afcd
set up cache
0xSero Jun 13, 2024
acdf38c
more cache more setup with pages
0xSero Jun 13, 2024
68a6094
loading cache into browser for tests
0xSero Jun 14, 2024
769344d
build cache and unlock wallet from keplr (;
0xSero Jun 14, 2024
8d38cb2
clean up and port remaining functions
0xSero Jun 14, 2024
500669d
Merge branch 'new-dawn' into feat/keplr-wallet
0xSero Jun 17, 2024
c5cec19
make dynamic
0xSero Jun 17, 2024
fd48092
hashing
0xSero Jun 17, 2024
3cf42d9
s
0xSero Jun 17, 2024
5baf24d
h
0xSero Jun 17, 2024
d02d242
made a new /utils package to handle shared utility functions, as the …
0xSero Jun 17, 2024
76334cc
finish utils package
0xSero Jun 18, 2024
fb076ac
2
0xSero Jun 18, 2024
5ed5ca2
figured out the pesky cache
0xSero Jun 18, 2024
af0855e
improve keplr set up
0xSero Jun 18, 2024
d2c807c
debug cypress
0xSero Jun 19, 2024
8f6e1e4
add import test
0xSero Jun 19, 2024
834d458
unlock for fixture (: keplr
0xSero Jun 19, 2024
b18ed70
copy
0xSero Jun 19, 2024
b897897
clean up selector and fix an input i broke, also finish first test case
0xSero Jun 19, 2024
5671ba2
linting
0xSero Jun 19, 2024
093385b
new test
0xSero Jun 20, 2024
452498a
submitted keplr createWallet setup
0xSero Jun 21, 2024
2d38d89
bunch of tests
0xSero Jun 21, 2024
54b0b7c
hm
0xSero Jun 21, 2024
c962372
reject and accept access
0xSero Jun 21, 2024
386ae15
hm
0xSero Jun 21, 2024
f40fdf2
hm
0xSero Jun 21, 2024
138c7a1
Merge branch 'new-dawn' into feat/keplr-wallet
0xSero Jun 21, 2024
850b037
auto sorty
0xSero Jun 21, 2024
7991b42
v
0xSero Jun 24, 2024
988f112
fix
0xSero Jun 24, 2024
4a7f4e5
remove unnecessary test
0xSero Jun 24, 2024
e191940
clean up
0xSero Jun 24, 2024
d9b0332
Merge branch 'new-dawn' into feat/keplr-wallet
0xSero Jun 24, 2024
c10a1ff
clean up
0xSero Jun 24, 2024
4e5d50a
more clean up
0xSero Jun 24, 2024
c48386b
fix
0xSero Jun 24, 2024
cf89cc9
fix and clean
0xSero Jun 24, 2024
3d65aea
lint
0xSero Jun 24, 2024
630298b
done
0xSero Jun 24, 2024
1622f45
lint
0xSero Jun 24, 2024
25559c8
remove unused
0xSero Jun 24, 2024
a0da307
Merge branch 'new-dawn' into feat/keplr-wallet
drptbl Jul 1, 2024
7376f3e
update selectors, need to publish versions on NPM
0xSero Jul 1, 2024
97a91fc
remove
0xSero Jul 1, 2024
6f6c783
lint
0xSero Jul 1, 2024
e428447
test
0xSero Jul 1, 2024
78d6de9
Merge branch 'new-dawn' into feat/keplr-wallet
0xSero Jul 5, 2024
49257de
Merge branch 'new-dawn' into feat/keplr-wallet
0xSero Jul 5, 2024
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
5 changes: 3 additions & 2 deletions examples/new-dawn/test/playwright/wallet-setup/basic.setup.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { BrowserContext, Page } from '@playwright/test'
import { MetaMask } from '@synthetixio/synpress'
import { defineWalletSetup } from '@synthetixio/synpress'
import { MetaMask } from '@synthetixio/synpress/playwright'

const SEED_PHRASE = 'test test test test test test test test test test test junk'
const PASSWORD = 'SynpressIsAwesomeNow!!!'

export default defineWalletSetup(PASSWORD, async (context, walletPage) => {
export default defineWalletSetup(PASSWORD, async (context: BrowserContext, walletPage: Page) => {
const metamask = new MetaMask(context, walletPage, PASSWORD)

await metamask.importWallet(SEED_PHRASE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { BrowserContext, Page } from '@playwright/test'
import { MetaMask, getExtensionId } from '@synthetixio/synpress'
import { defineWalletSetup } from '@synthetixio/synpress'
import { MetaMask, getExtensionId } from '@synthetixio/synpress/playwright'
import 'dotenv/config'

const SEED_PHRASE = process.env.SEED_PHRASE
const PASSWORD = process.env.WALLET_PASSWORD

export default defineWalletSetup(PASSWORD, async (context, walletPage) => {
export default defineWalletSetup(PASSWORD, async (context: BrowserContext, walletPage: Page) => {
// This is a workaround for the fact that the MetaMask extension ID changes.
// This workaround won't be needed in the near future! 😁
const extensionId = await getExtensionId(context, 'MetaMask')
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"private": true,
"scripts": {
"build": "turbo build",
"build:cache": "turbo build:cache --filter=@synthetixio/synpress-metamask",
"build:cache": "turbo build:cache --filter=@synthetixio/synpress-metamask --filter=@synthetixio/synpress-keplr",
"docs:build": "turbo docs:build --filter=docs",
"format": "biome format . --write",
"format:check": "biome format . --error-on-warnings",
Expand All @@ -15,8 +15,8 @@
"sort-package-json": "sort-package-json 'package.json' '{packages,wallets,examples}/*/package.json'",
"sort-package-json:check": "sort-package-json 'package.json' '{packages,wallets,examples}/*/package.json' --check",
"test": "turbo test",
"test:e2e:headful": "turbo test:e2e:headful --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock",
"test:e2e:headless": "turbo test:e2e:headless --filter=@synthetixio/synpress-metamask --filter=@synthetixio/ethereum-wallet-mock",
"test:e2e:headful": "turbo test:e2e:headful --filter=@synthetixio/synpress-metamask --filter=@synthetixio/synpress-keplr --filter=@synthetixio/ethereum-wallet-mock",
"test:e2e:headless": "turbo test:e2e:headless --filter=@synthetixio/synpress-metamask --filter=@synthetixio/synpress-keplr --filter=@synthetixio/ethereum-wallet-mock",
"update:deps": "ncu -u -ws --root"
},
"lint-staged": {
Expand Down
32 changes: 24 additions & 8 deletions packages/cache/src/cli/cliEntrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { compileWalletSetupFunctions } from './compileWalletSetupFunctions'
import { footer } from './footer'

interface CliFlags {
keplr: boolean
metamask: boolean
headless: boolean
force: boolean
debug: boolean
Expand All @@ -30,24 +32,37 @@ export const cliEntrypoint = async () => {
)
.option('-f, --force', 'Force the creation of cache even if it already exists', false)
.option('-d, --debug', 'If this flag is present, the compilation files are not going to be deleted', false)
.option('-k, --keplr', 'Prepare the Keplr extension', false)
.option('-m, --metamask', 'Prepare the MetaMask extension', false)
.helpOption(undefined, 'Display help for command')
.addHelpText('afterAll', `\n${footer}\n`)
.parse(process.argv)

let walletSetupDir = program.args[0]
if (!walletSetupDir) {
walletSetupDir = path.join(process.cwd(), 'test', WALLET_SETUP_DIR_NAME)
}

const flags: CliFlags = program.opts()

if (flags.headless) {
process.env.HEADLESS = true
}

if (flags.debug) {
console.log('[DEBUG] Running with the following options:')
console.log({ cacheDir: walletSetupDir, ...flags, headless: Boolean(process.env.HEADLESS) ?? false }, '\n')
console.log({ cacheDir: walletSetupDir, ...flags, headless: flags.headless ?? false }, '\n')
}

const extensionsToSetup = () => {
const extensions = []
if (flags.keplr) {
extensions.push('Keplr')
}
if (flags.metamask) {
extensions.push('MetaMask')
}
return extensions
}
let extensionNames = extensionsToSetup()

if (!extensionNames.length) {
extensionNames = ['Keplr']
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use MetaMask as default?

}

if (os.platform() === 'win32') {
Expand All @@ -63,9 +78,10 @@ export const cliEntrypoint = async () => {
}

const compiledWalletSetupDirPath = await compileWalletSetupFunctions(walletSetupDir, flags.debug)

for (const extensionName of extensionNames) {
await createCache(compiledWalletSetupDirPath, () => prepareExtension(extensionName), flags.force) // Pass extensionName
}
// TODO: We should be using `prepareExtension` function from the wallet itself!
await createCache(compiledWalletSetupDirPath, prepareExtension, flags.force)

if (!flags.debug) {
await rimraf(compiledWalletSetupDirPath)
Expand Down
1 change: 1 addition & 0 deletions packages/cache/src/createCache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getUniqueWalletSetupFunctions } from './utils/getUniqueWalletSetupFunctions'
import { triggerCacheCreation } from './utils/triggerCacheCreation'

//@TODO: Make it so createCache can handle only one wallet setup function
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you elaborate?

Copy link
Contributor Author

@0xSero 0xSero Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason when we only have 1 setup file, the hash generated in prepareExtension creates what would have been the the hash from the second item in the wallet setup functions array.

If there's 2 or more setup functions this behaviour does not happen (this is true for MM as well even before adding Keplr)

This will be tackled in a separate issue

export async function createCache(walletSetupDirPath: string, downloadExtension: () => Promise<string>, force = false) {
const setupFunctions = await getUniqueWalletSetupFunctions(walletSetupDirPath)

Expand Down
2 changes: 1 addition & 1 deletion packages/cache/src/ensureCacheDirExists.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'node:path'
import fs from 'fs-extra'
import { CACHE_DIR_NAME } from './constants'
import { CACHE_DIR_NAME } from '../../cache/src/constants'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we do "./ensureCacheDirExists"?


export function ensureCacheDirExists() {
const cacheDirPath = path.join(process.cwd(), CACHE_DIR_NAME)
Expand Down
20 changes: 15 additions & 5 deletions packages/cache/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
export * from './constants'
export * from './createCache'
export * from './cli/cliEntrypoint'
export * from '../../cache/src/constants'
export * from './downloadFile'
export * from './unzipArchive'
export * from '../../cache/src/unzipArchive'
export * from './ensureCacheDirExists'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why isn't it in the same "cache" directory?

export * from './createCache'
export * from './defineWalletSetup'
export * from '../../cache/src/prepareExtension'
export * from './prepareExtension'
export * from './utils/bytesToMegabytes'
export * from './utils/createCacheForWalletSetupFunction'
export * from './utils/createTempContextDir'
export * from './utils/getUniqueWalletSetupFunctions'
export * from './utils/getWalletSetupFiles'
export * from './utils/getWalletSetupFuncHash'
export * from './utils/importWalletSetupFile'
export * from './utils/isDirEmpty'
export * from './utils/onDownloadProgress'
export * from './utils/triggerCacheCreation'
export * from './utils/removeTempContextDir'
export * from './prepareExtension'
export * from './cli/cliEntrypoint'
40 changes: 34 additions & 6 deletions packages/cache/src/prepareExtension.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
import { downloadFile, ensureCacheDirExists, unzipArchive } from '.'

export const DEFAULT_METAMASK_VERSION = '11.9.1'
export const EXTENSION_DOWNLOAD_URL = `https://github.com/MetaMask/metamask-extension/releases/download/v${DEFAULT_METAMASK_VERSION}/metamask-chrome-${DEFAULT_METAMASK_VERSION}.zip`
interface ExtensionConfig {
name: string
version: string
downloadUrl: string
}

export async function getExtensionConfig(name: string): Promise<ExtensionConfig> {
const config = {
extensions: [
{
name: 'MetaMask',
version: '11.9.1',
downloadUrl:
'https://github.com/MetaMask/metamask-extension/releases/download/v11.9.1/metamask-chrome-11.9.1.zip'
},
{
name: 'Keplr',
version: '0.12.102',
downloadUrl:
'https://github.com/chainapsis/keplr-wallet/releases/download/v0.12.102/keplr-extension-manifest-v2-v0.12.102.zip'
}
]
}

const extension = config.extensions.find((ext: { name: string }) => ext.name === name)
if (!extension) {
throw new Error(`Extension configuration not found for ${name}`)
}
return extension
}

// NOTE: This function is copied from `wallets/metamask/src/prepareExtension.ts` only TEMPORARILY!
export async function prepareExtension() {
export async function prepareExtension(extensionName: string) {
const cacheDirPath = ensureCacheDirExists()
const extensionConfig = await getExtensionConfig(extensionName) // Get config

const downloadResult = await downloadFile({
url: EXTENSION_DOWNLOAD_URL,
url: extensionConfig.downloadUrl,
outputDir: cacheDirPath,
fileName: `metamask-chrome-${DEFAULT_METAMASK_VERSION}.zip`
fileName: `${extensionConfig.name.toLowerCase()}-chrome-${extensionConfig.version}.zip`
})

const unzipResult = await unzipArchive({
Expand Down
7 changes: 5 additions & 2 deletions packages/cache/test/createCache.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { afterAll, afterEach, describe, expect, it, vi } from 'vitest'

import path from 'node:path'
import type { BrowserContext, Page } from 'playwright-core'
import { createCache } from '../src/createCache'
import type { WalletSetupFunction } from '../src/defineWalletSetup'
import * as GetUniqueWalletSetupFunctions from '../src/utils/getUniqueWalletSetupFunctions'
import * as TriggerCacheCreation from '../src/utils/triggerCacheCreation'

const ROOT_DIR = '/tmp'

const setupFunctions = new Map<string, { fileName: string; setupFunction: WalletSetupFunction }>()
const setupFunctions = new Map<
string,
{ fileName: string; setupFunction: (context: BrowserContext, walletPage: Page) => Promise<void> }
>()

setupFunctions.set('hash1', { fileName: path.join(ROOT_DIR, 'hash1'), setupFunction: vi.fn() })
setupFunctions.set('hash2', { fileName: path.join(ROOT_DIR, 'hash2'), setupFunction: vi.fn() })
Expand Down
2 changes: 1 addition & 1 deletion packages/cache/test/defineWalletSetup.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { defineWalletSetup } from '../src/defineWalletSetup'
import { defineWalletSetup } from '../src'

const PASSWORD = 'Quack Quack! 🦆'
const EXPECTED_HASH = 'f9c5ea5bb2c3aac96ff4'
Expand Down
2 changes: 1 addition & 1 deletion packages/cache/test/ensureCacheDirExists.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'node:path'
import fs from 'fs-extra'
import { afterAll, afterEach, describe, expect, it, vi } from 'vitest'
import { CACHE_DIR_NAME } from '../src/constants'
import { CACHE_DIR_NAME } from '../src'
import { ensureCacheDirExists } from '../src/ensureCacheDirExists'

vi.mock('fs-extra', async () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/cache/test/utils/bytesToMegabytes.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { bytesToMegabytes } from '../../src/utils/bytesToMegabytes'
import { bytesToMegabytes } from '../../src'

describe('bytesToMegabytes', () => {
it('converts bytes to megabytes and rounds the result', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { chromium } from 'playwright-core'
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest'
import { createCacheForWalletSetupFunction } from '../../src/utils/createCacheForWalletSetupFunction'
import { createCacheForWalletSetupFunction } from '../../src'
import * as WaitForExtensionOnLoadPage from '../../src/utils/waitForExtensionOnLoadPage'

const EXTENSION_PATH = '/tmp/extension'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { afterAll, describe, expect, it, vi } from 'vitest'
import { getUniqueWalletSetupFunctions } from '../../src/utils/getUniqueWalletSetupFunctions'
import { getUniqueWalletSetupFunctions } from '../../src'

vi.mock('../../src/utils/getWalletSetupFiles', async () => {
return {
Expand Down
2 changes: 1 addition & 1 deletion packages/cache/test/utils/getWalletSetupFuncHash.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { WALLET_SETUP_FUNC_HASH_LENGTH, getWalletSetupFuncHash } from '../../src/utils/getWalletSetupFuncHash'
import { WALLET_SETUP_FUNC_HASH_LENGTH, getWalletSetupFuncHash } from '../../src'

const EXPECTED_HASH = 'b940c886be3c1a041ddd'

Expand Down
2 changes: 1 addition & 1 deletion packages/cache/test/utils/importWalletSetupFile.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { afterAll, describe, expect, it, vi } from 'vitest'
import { importWalletSetupFile } from '../../src/utils/importWalletSetupFile'
import { importWalletSetupFile } from '../../src'

vi.mock('../../src/ensureCacheDirExists', async () => {
return {
Expand Down
2 changes: 1 addition & 1 deletion packages/cache/test/utils/removeTempContextDir.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { afterAll, describe, expect, it, vi } from 'vitest'
import { removeTempContextDir } from '../../src/utils/removeTempContextDir'
import { removeTempContextDir } from '../../src'

const PATH = 'Happy Quack Path'
const MAX_RETRIES = 10
Expand Down
Loading
Loading