Skip to content

Commit

Permalink
feat: migrate Coinbase to use Hub
Browse files Browse the repository at this point in the history
  • Loading branch information
mikasackermn committed Jan 1, 2025
1 parent 9d9fced commit 48bdf1a
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 55 deletions.
4 changes: 2 additions & 2 deletions wallets/provider-all/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as braavos from '@rango-dev/provider-braavos';
import * as brave from '@rango-dev/provider-brave';
import * as clover from '@rango-dev/provider-clover';
import * as coin98 from '@rango-dev/provider-coin98';
import * as coinbase from '@rango-dev/provider-coinbase';
import { versions as coinbase } from '@rango-dev/provider-coinbase';
import * as cosmostation from '@rango-dev/provider-cosmostation';
import * as defaultInjected from '@rango-dev/provider-default';
import * as enkrypt from '@rango-dev/provider-enkrypt';
Expand Down Expand Up @@ -123,7 +123,7 @@ export const allProviders = (options?: Options): VersionedProviders[] => {
legacyProviderImportsToVersionsInterface(safepal),
legacyProviderImportsToVersionsInterface(brave),
legacyProviderImportsToVersionsInterface(coin98),
legacyProviderImportsToVersionsInterface(coinbase),
coinbase,
legacyProviderImportsToVersionsInterface(cosmostation),
legacyProviderImportsToVersionsInterface(exodus),
legacyProviderImportsToVersionsInterface(mathwallet),
Expand Down
12 changes: 6 additions & 6 deletions wallets/provider-coinbase/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
"version": "0.40.1-next.5",
"license": "MIT",
"type": "module",
"source": "./src/index.ts",
"main": "./dist/index.js",
"source": "./src/mod.ts",
"main": "./dist/mod.js",
"exports": {
".": "./dist/index.js"
".": "./dist/mod.js"
},
"typings": "dist/index.d.ts",
"typings": "dist/mod.d.ts",
"files": [
"dist",
"src"
],
"scripts": {
"build": "node ../../scripts/build/command.mjs --path wallets/provider-coinbase",
"build": "node ../../scripts/build/command.mjs --path wallets/provider-coinbase --inputs src/mod.ts",
"ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json",
"clean": "rimraf dist",
"format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
Expand All @@ -30,4 +30,4 @@
"publishConfig": {
"access": "public"
}
}
}
22 changes: 22 additions & 0 deletions wallets/provider-coinbase/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type ProviderInfo } from '@rango-dev/wallets-core';

export const WALLET_ID = 'coinbase';

export const info: ProviderInfo = {
name: 'Coinbase',
icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg',
extensions: {
chrome:
'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad',
brave:
'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad',
homepage: 'https://www.coinbase.com/wallet',
},
properties: [
{
name: 'detached',
// if you are adding a new namespace, don't forget to also update `getWalletInfo`
value: ['evm', 'solana'],
},
],
};
41 changes: 0 additions & 41 deletions wallets/provider-coinbase/src/helpers.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ import type {
} from '@rango-dev/wallets-shared';
import type { BlockchainMeta, SignerFactory } from 'rango-types';

import {
type LegacyProviderInterface,
LegacyNetworks as Networks,
} from '@rango-dev/wallets-core/legacy';
import {
canEagerlyConnectToEvm,
canSwitchNetworkToEvm,
chooseInstance,
getEvmAccounts,
Networks,
switchNetworkForEvm,
WalletTypes,
} from '@rango-dev/wallets-shared';
Expand All @@ -25,7 +28,12 @@ import {
solanaBlockchain,
} from 'rango-types';

import { coinbase as coinbase_instance, getSolanaAccounts } from './helpers.js';
import {
coinbase as coinbase_instance,
getSolanaAccounts,
solanaCoinbase,
} from '../utils.js';

import signer from './signer.js';

const WALLET = WalletTypes.COINBASE;
Expand All @@ -44,15 +52,19 @@ export const connect: Connect = async ({ instance, meta }) => {
* whenever we are requesting accounts.
*/
const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM);
let results: ProviderConnectResult[] = [];
const results: ProviderConnectResult[] = [];

if (evm_instance) {
const evm = await getEvmAccounts(evm_instance);
results.push(evm);
}

const solanaResults = await getSolanaAccounts(instance);
results = [...results, ...solanaResults];
const solanaInstance = solanaCoinbase();
if (solanaInstance) {
const solanaResults = await getSolanaAccounts(solanaInstance);
results.push(solanaResults);
}

return results;
};

Expand Down Expand Up @@ -133,5 +145,34 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
},
color: '#2a62f5',
supportedChains: [...evms, ...solana],
needsNamespace: {
selection: 'multiple',
data: [
{
label: 'EVM',
value: 'EVM',
id: 'ETH',
},
{
label: 'Solana',
value: 'Solana',
id: 'SOLANA',
},
],
},
};
};

const legacyProvider: LegacyProviderInterface = {
config,
getInstance,
connect,
subscribe,
switchNetwork,
canSwitchNetworkTo,
getSigners,
getWalletInfo,
canEagerConnect,
};

export { legacyProvider };
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { SignerFactory } from 'rango-types';

import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared';
import { LegacyNetworks as Networks } from '@rango-dev/wallets-core/legacy';
import { getNetworkInstance } from '@rango-dev/wallets-shared';
import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types';

import { CustomSolanaSigner } from './solana-signer.js';
Expand Down
11 changes: 11 additions & 0 deletions wallets/provider-coinbase/src/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineVersions } from '@rango-dev/wallets-core/utils';

import { legacyProvider } from './legacy/index.js';
import { provider } from './provider.js';

const versions = defineVersions()
.version('0.0.0', legacyProvider)
.version('1.0.0', provider)
.build();

export { versions };
30 changes: 30 additions & 0 deletions wallets/provider-coinbase/src/namespaces/evm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm';

import { NamespaceBuilder } from '@rango-dev/wallets-core';
import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common';
import { actions, builders } from '@rango-dev/wallets-core/namespaces/evm';

import { WALLET_ID } from '../constants.js';
import { evmCoinbase } from '../utils.js';

const [changeAccountSubscriber, changeAccountCleanup] =
actions.changeAccountSubscriber(evmCoinbase);

const connect = builders
.connect()
.action(actions.connect(evmCoinbase))
.before(changeAccountSubscriber)
.or(changeAccountCleanup)
.build();

const disconnect = commonBuilders
.disconnect<EvmActions>()
.after(changeAccountCleanup)
.build();

const evm = new NamespaceBuilder<EvmActions>('EVM', WALLET_ID)
.action(connect)
.action(disconnect)
.build();

export { evm };
53 changes: 53 additions & 0 deletions wallets/provider-coinbase/src/namespaces/solana.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { CaipAccount } from '@rango-dev/wallets-core/namespaces/common';
import type { SolanaActions } from '@rango-dev/wallets-core/namespaces/solana';

import { NamespaceBuilder } from '@rango-dev/wallets-core';
import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common';
import {
actions,
builders,
CAIP_NAMESPACE,
CAIP_SOLANA_CHAIN_ID,
} from '@rango-dev/wallets-core/namespaces/solana';
import { CAIP } from '@rango-dev/wallets-core/utils';

import { WALLET_ID } from '../constants.js';
import { getSolanaAccounts, solanaCoinbase } from '../utils.js';

const [changeAccountSubscriber, changeAccountCleanup] =
actions.changeAccountSubscriber(solanaCoinbase);

const connect = builders
.connect()
.action(async function () {
const solanaInstance = solanaCoinbase();
const result = await getSolanaAccounts(solanaInstance);

const formatAccounts = result.accounts.map(
(account) =>
CAIP.AccountId.format({
address: account,
chainId: {
namespace: CAIP_NAMESPACE,
reference: CAIP_SOLANA_CHAIN_ID,
},
}) as CaipAccount
);

return formatAccounts;
})
.before(changeAccountSubscriber)
.or(changeAccountCleanup)
.build();

const disconnect = commonBuilders
.disconnect<SolanaActions>()
.after(changeAccountCleanup)
.build();

const solana = new NamespaceBuilder<SolanaActions>('Solana', WALLET_ID)
.action(connect)
.action(disconnect)
.build();

export { solana };
22 changes: 22 additions & 0 deletions wallets/provider-coinbase/src/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ProviderBuilder } from '@rango-dev/wallets-core';

import { info, WALLET_ID } from './constants.js';
import { evm } from './namespaces/evm.js';
import { solana } from './namespaces/solana.js';
import { coinbase as coinbaseInstance } from './utils.js';

const provider = new ProviderBuilder(WALLET_ID)
.init(function (context) {
const [, setState] = context.state();

if (coinbaseInstance()) {
setState('installed', true);
console.debug('[coinbase] instance detected.', context);
}
})
.config('info', info)
.add('solana', solana)
.add('evm', evm)
.build();

export { provider };
66 changes: 66 additions & 0 deletions wallets/provider-coinbase/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type { ProviderAPI as EvmProviderApi } from '@rango-dev/wallets-core/namespaces/evm';
import type { ProviderAPI as SolanaProviderApi } from '@rango-dev/wallets-core/namespaces/solana';
import type { ProviderConnectResult } from '@rango-dev/wallets-shared';

import { LegacyNetworks } from '@rango-dev/wallets-core/legacy';

type Provider = Map<string, unknown>;

export function coinbase(): Provider | null {
const { coinbaseWalletExtension, coinbaseSolana } = window;

if (!coinbaseSolana && !coinbaseWalletExtension) {
return null;
}

const instances = new Map();

if (coinbaseWalletExtension) {
instances.set(LegacyNetworks.ETHEREUM, coinbaseWalletExtension);
}

if (coinbaseSolana) {
instances.set(LegacyNetworks.SOLANA, coinbaseSolana);
}

return instances;
}

export function evmCoinbase(): EvmProviderApi {
const instances = coinbase();

const evmInstance = instances?.get(LegacyNetworks.ETHEREUM);

if (!evmInstance) {
throw new Error(
'Coinbase not injected or EVM not enabled. Please check your wallet.'
);
}

return evmInstance as EvmProviderApi;
}

export function solanaCoinbase(): SolanaProviderApi {
const instance = coinbase();
const solanaInstance = instance?.get(LegacyNetworks.SOLANA);

if (!solanaInstance) {
throw new Error(
'Coinbase not injected or Solana not enabled. Please check your wallet.'
);
}

return solanaInstance;
}

export async function getSolanaAccounts(
instance: any
): Promise<ProviderConnectResult> {
await instance.connect();
const account = instance.publicKey.toString();

return {
accounts: [account],
chainId: LegacyNetworks.SOLANA,
};
}

0 comments on commit 48bdf1a

Please sign in to comment.