diff --git a/scripts/test-oath-wallet.mjs b/scripts/test-oath-wallet.mjs new file mode 100644 index 000000000..95b00f0ea --- /dev/null +++ b/scripts/test-oath-wallet.mjs @@ -0,0 +1,61 @@ +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import { test } from 'node:test'; +import ts from 'typescript'; +import { CoreHelperUtil, OptionsController } from '@web3modal/core'; + +// Compile the production metadata with the repository's TypeScript compiler. +// The only substitution is CRA's SVG asset loader; Web3Modal is not mocked. +const require = createRequire(import.meta.url); +const source = readFileSync( + new URL('../src/connectors/oathWallet.ts', import.meta.url), + 'utf8', +); +const compiled = ts.transpileModule(source, { + compilerOptions: { module: ts.ModuleKind.CommonJS, esModuleInterop: true }, +}).outputText; +const exports = {}; +new Function('require', 'exports', compiled)((specifier) => { + if (specifier === 'assets/images/oath-wallet.svg') { + return '/static/media/oath-wallet.svg'; + } + return require(specifier); +}, exports); +const { oathWallet } = exports; + +test('the installed SDK retains Oath as a custom native wallet without changing provider options', () => { + const original = OptionsController.state.customWallets; + const projectId = OptionsController.state.projectId; + try { + OptionsController.setCustomWallets([oathWallet]); + assert.equal(OptionsController.state.customWallets[0].id, oathWallet.id); + assert.equal( + OptionsController.state.customWallets[0].mobile_link, + 'oathwallet://', + ); + assert.equal(OptionsController.state.projectId, projectId); + assert.equal(oathWallet.desktop_link, undefined); + assert.equal(oathWallet.webapp_link, undefined); + assert.equal(oathWallet.play_store, undefined); + } finally { + OptionsController.setCustomWallets(original); + } +}); + +test('the installed SDK hands the complete pairing URI to the Oath iOS wc route', () => { + // Synthetic pairing data only; never record a live pairing URI or key. + const pairing = `wc:${'a'.repeat( + 64, + )}@2?relay-protocol=irn&symKey=${'b'.repeat(64)}&expiryTimestamp=2000000000`; + const { redirect, href } = CoreHelperUtil.formatNativeUrl( + oathWallet.mobile_link, + pairing, + ); + const link = new URL(redirect); + assert.equal(link.protocol, 'oathwallet:'); + assert.equal(link.hostname, 'wc'); + assert.equal(link.searchParams.get('uri'), pairing); + assert.equal([...link.searchParams].length, 1); + assert.equal(href, 'oathwallet://'); +}); diff --git a/src/App.tsx b/src/App.tsx index b75865ce3..11588763f 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -75,6 +75,7 @@ import { ChainId } from '@uniswap/sdk'; import { SUPPORTED_CHAINIDS } from 'constants/index'; import { getConfig } from 'config/index'; import 'connectors/passport'; +import { oathWallet } from 'connectors/oathWallet'; import { createSoulZapApiClient, SoulZapApiClient, @@ -121,6 +122,7 @@ createWeb3Modal({ chains, chainImages, projectId, + customWallets: [oathWallet], enableAnalytics: true, allowUnsupportedChain: true, enableOnramp: true, diff --git a/src/assets/images/oath-wallet.svg b/src/assets/images/oath-wallet.svg new file mode 100644 index 000000000..8f8b9d7f5 --- /dev/null +++ b/src/assets/images/oath-wallet.svg @@ -0,0 +1 @@ +Oath — Signal Blue \ No newline at end of file diff --git a/src/connectors/oathWallet.ts b/src/connectors/oathWallet.ts new file mode 100644 index 000000000..4a10f1313 --- /dev/null +++ b/src/connectors/oathWallet.ts @@ -0,0 +1,15 @@ +import { Web3ModalOptions } from '@web3modal/ethers5/react'; +import oathLogo from 'assets/images/oath-wallet.svg'; + +// A native iOS wallet: Web3Modal uses its existing WalletConnect provider for +// desktop QR pairing and app handoff. Oath does not inject a browser provider. +export const oathWallet: NonNullable< + Web3ModalOptions['customWallets'] +>[number] = { + id: 'oath-wallet', + name: 'Oath Wallet', + homepage: 'https://oathwallet.org', + image_url: oathLogo, + mobile_link: 'oathwallet://', + app_store: 'https://apps.apple.com/app/id6780187283', +};