Skip to content

Commit 1201036

Browse files
committed
feat: migrate Coinbase to use Hub
1 parent 455bafc commit 1201036

File tree

12 files changed

+256
-52
lines changed

12 files changed

+256
-52
lines changed

wallets/provider-all/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as braavos from '@rango-dev/provider-braavos';
88
import * as brave from '@rango-dev/provider-brave';
99
import * as clover from '@rango-dev/provider-clover';
1010
import * as coin98 from '@rango-dev/provider-coin98';
11-
import * as coinbase from '@rango-dev/provider-coinbase';
11+
import { versions as coinbase } from '@rango-dev/provider-coinbase';
1212
import * as cosmostation from '@rango-dev/provider-cosmostation';
1313
import * as defaultInjected from '@rango-dev/provider-default';
1414
import * as enkrypt from '@rango-dev/provider-enkrypt';
@@ -96,7 +96,7 @@ export const allProviders = (options?: Options): VersionedProviders[] => {
9696
legacyProviderImportsToVersionsInterface(safepal),
9797
legacyProviderImportsToVersionsInterface(brave),
9898
legacyProviderImportsToVersionsInterface(coin98),
99-
legacyProviderImportsToVersionsInterface(coinbase),
99+
coinbase,
100100
legacyProviderImportsToVersionsInterface(cosmostation),
101101
legacyProviderImportsToVersionsInterface(exodus),
102102
legacyProviderImportsToVersionsInterface(mathwallet),

wallets/provider-coinbase/package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
"version": "0.39.0",
44
"license": "MIT",
55
"type": "module",
6-
"source": "./src/index.ts",
7-
"main": "./dist/index.js",
6+
"source": "./src/mod.ts",
7+
"main": "./dist/mod.js",
88
"exports": {
9-
".": "./dist/index.js"
9+
".": "./dist/mod.js"
1010
},
11-
"typings": "dist/index.d.ts",
11+
"typings": "dist/mod.d.ts",
1212
"files": [
1313
"dist",
1414
"src"
1515
],
1616
"scripts": {
17-
"build": "node ../../scripts/build/command.mjs --path wallets/provider-coinbase",
17+
"build": "node ../../scripts/build/command.mjs --path wallets/provider-coinbase --inputs src/mod.ts",
1818
"ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json",
1919
"clean": "rimraf dist",
2020
"format": "prettier --write '{.,src}/**/*.{ts,tsx}'",
@@ -30,4 +30,4 @@
3030
"publishConfig": {
3131
"access": "public"
3232
}
33-
}
33+
}
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { type ProviderInfo } from '@rango-dev/wallets-core';
2+
import { LegacyNetworks } from '@rango-dev/wallets-core/legacy';
3+
4+
export const EVM_SUPPORTED_CHAINS = [
5+
LegacyNetworks.ETHEREUM,
6+
LegacyNetworks.POLYGON,
7+
];
8+
9+
export const WALLET_ID = '';
10+
11+
export const info: ProviderInfo = {
12+
name: 'Coinbase',
13+
icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg',
14+
extensions: {
15+
chrome:
16+
'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad',
17+
brave:
18+
'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad',
19+
homepage: 'https://www.coinbase.com/wallet',
20+
},
21+
properties: [
22+
{
23+
name: 'detached',
24+
// if you are adding a new namespace, don't forget to also update `getWalletInfo`
25+
value: ['evm', 'solana'],
26+
},
27+
],
28+
};

wallets/provider-coinbase/src/helpers.ts

-41
This file was deleted.

wallets/provider-coinbase/src/index.ts wallets/provider-coinbase/src/legacy/index.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ import type {
99
} from '@rango-dev/wallets-shared';
1010
import type { BlockchainMeta, SignerFactory } from 'rango-types';
1111

12+
import {
13+
type LegacyProviderInterface,
14+
LegacyNetworks as Networks,
15+
} from '@rango-dev/wallets-core/legacy';
1216
import {
1317
canEagerlyConnectToEvm,
1418
canSwitchNetworkToEvm,
1519
chooseInstance,
1620
getEvmAccounts,
17-
Networks,
1821
switchNetworkForEvm,
1922
WalletTypes,
2023
} from '@rango-dev/wallets-shared';
@@ -25,7 +28,8 @@ import {
2528
solanaBlockchain,
2629
} from 'rango-types';
2730

28-
import { coinbase as coinbase_instance, getSolanaAccounts } from './helpers.js';
31+
import { coinbase as coinbase_instance, getSolanaAccounts } from '../utils.js';
32+
2933
import signer from './signer.js';
3034

3135
const WALLET = WalletTypes.COINBASE;
@@ -135,3 +139,17 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = (
135139
supportedChains: [...evms, ...solana],
136140
};
137141
};
142+
143+
const legacyProvider: LegacyProviderInterface = {
144+
config,
145+
getInstance,
146+
connect,
147+
subscribe,
148+
switchNetwork,
149+
canSwitchNetworkTo,
150+
getSigners,
151+
getWalletInfo,
152+
canEagerConnect,
153+
};
154+
155+
export { legacyProvider };

wallets/provider-coinbase/src/signer.ts wallets/provider-coinbase/src/legacy/signer.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { SignerFactory } from 'rango-types';
22

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

67
export default async function getSigners(

wallets/provider-coinbase/src/mod.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { defineVersions } from '@rango-dev/wallets-core/utils';
2+
3+
import { legacyProvider } from './legacy/index.js';
4+
import { provider } from './provider.js';
5+
6+
const versions = defineVersions()
7+
.version('0.0.0', legacyProvider)
8+
.version('1.0.0', provider)
9+
.build();
10+
11+
export { versions };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm';
2+
3+
import { NamespaceBuilder } from '@rango-dev/wallets-core';
4+
import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common';
5+
import { actions, builders } from '@rango-dev/wallets-core/namespaces/evm';
6+
7+
import { WALLET_ID } from '../constants.js';
8+
import { evmCoinbase } from '../utils.js';
9+
10+
const [changeAccountSubscriber, changeAccountCleanup] =
11+
actions.changeAccountSubscriber(evmCoinbase);
12+
13+
const connect = builders
14+
.connect()
15+
.action(actions.connect(evmCoinbase))
16+
.before(changeAccountSubscriber)
17+
.or(changeAccountCleanup)
18+
.build();
19+
20+
const disconnect = commonBuilders
21+
.disconnect<EvmActions>()
22+
.after(changeAccountCleanup)
23+
.build();
24+
25+
const evm = new NamespaceBuilder<EvmActions>('EVM', WALLET_ID)
26+
.action(connect)
27+
.action(disconnect)
28+
.build();
29+
30+
export { evm };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { CaipAccount } from '@rango-dev/wallets-core/namespaces/common';
2+
import type { SolanaActions } from '@rango-dev/wallets-core/namespaces/solana';
3+
4+
import { NamespaceBuilder } from '@rango-dev/wallets-core';
5+
import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common';
6+
import {
7+
actions,
8+
builders,
9+
CAIP_NAMESPACE,
10+
CAIP_SOLANA_CHAIN_ID,
11+
} from '@rango-dev/wallets-core/namespaces/solana';
12+
import { CAIP } from '@rango-dev/wallets-core/utils';
13+
import { getSolanaAccounts } from '@rango-dev/wallets-shared';
14+
15+
import { WALLET_ID } from '../constants.js';
16+
import { solanaCoinbase } from '../utils.js';
17+
18+
const [changeAccountSubscriber, changeAccountCleanup] =
19+
actions.changeAccountSubscriber(solanaCoinbase);
20+
21+
const connect = builders
22+
.connect()
23+
.action(async function () {
24+
const solanaInstance = solanaCoinbase();
25+
const result = await getSolanaAccounts({
26+
instance: solanaInstance,
27+
meta: [],
28+
});
29+
if (Array.isArray(result)) {
30+
throw new Error(
31+
'Expecting solana response to be a single value, not an array.'
32+
);
33+
}
34+
35+
const formatAccounts = result.accounts.map(
36+
(account) =>
37+
CAIP.AccountId.format({
38+
address: account,
39+
chainId: {
40+
namespace: CAIP_NAMESPACE,
41+
reference: CAIP_SOLANA_CHAIN_ID,
42+
},
43+
}) as CaipAccount
44+
);
45+
46+
return formatAccounts;
47+
})
48+
.before(changeAccountSubscriber)
49+
.or(changeAccountCleanup)
50+
.build();
51+
52+
const disconnect = commonBuilders
53+
.disconnect<SolanaActions>()
54+
.after(changeAccountCleanup)
55+
.build();
56+
57+
const solana = new NamespaceBuilder<SolanaActions>('Solana', WALLET_ID)
58+
.action(connect)
59+
.action(disconnect)
60+
.build();
61+
62+
export { solana };
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ProviderBuilder } from '@rango-dev/wallets-core';
2+
3+
import { info, WALLET_ID } from './constants.js';
4+
import { evm } from './namespaces/evm.js';
5+
import { solana } from './namespaces/solana.js';
6+
import { coinbase as coinbaseInstance } from './utils.js';
7+
8+
const provider = new ProviderBuilder(WALLET_ID)
9+
.init(function (context) {
10+
const [, setState] = context.state();
11+
12+
if (coinbaseInstance()) {
13+
setState('installed', true);
14+
console.debug('[coinbase] instance detected.', context);
15+
}
16+
})
17+
.config('info', info)
18+
.add('solana', solana)
19+
.add('evm', evm)
20+
.build();
21+
22+
export { provider };
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import type { ProviderAPI as EvmProviderApi } from '@rango-dev/wallets-core/namespaces/evm';
2+
import type { ProviderAPI as SolanaProviderApi } from '@rango-dev/wallets-core/namespaces/solana';
3+
import type { ProviderConnectResult } from '@rango-dev/wallets-shared';
4+
5+
import { LegacyNetworks } from '@rango-dev/wallets-core/legacy';
6+
7+
type Provider = Map<string, unknown>;
8+
9+
export function coinbase(): Provider | null {
10+
const { coinbaseWalletExtension, coinbaseSolana } = window;
11+
12+
if (!coinbaseSolana && !coinbaseWalletExtension) {
13+
return null;
14+
}
15+
16+
const instances = new Map();
17+
18+
if (coinbaseWalletExtension) {
19+
instances.set(LegacyNetworks.ETHEREUM, coinbaseWalletExtension);
20+
}
21+
22+
if (coinbaseSolana) {
23+
instances.set(LegacyNetworks.SOLANA, coinbaseSolana);
24+
}
25+
26+
return instances;
27+
}
28+
29+
export function evmCoinbase(): EvmProviderApi {
30+
const instances = coinbase();
31+
32+
const evmInstance = instances?.get(LegacyNetworks.ETHEREUM);
33+
34+
if (!evmInstance) {
35+
throw new Error(
36+
'Coinbase not injected or EVM not enabled. Please check your wallet.'
37+
);
38+
}
39+
40+
return evmInstance as EvmProviderApi;
41+
}
42+
43+
export function solanaCoinbase(): SolanaProviderApi {
44+
const instance = coinbase();
45+
const solanaInstance = instance?.get(LegacyNetworks.SOLANA);
46+
47+
if (!solanaInstance) {
48+
throw new Error(
49+
'Coinbase not injected or Solana not enabled. Please check your wallet.'
50+
);
51+
}
52+
53+
return solanaInstance;
54+
}
55+
56+
export async function getSolanaAccounts(
57+
instance: any
58+
): Promise<ProviderConnectResult[]> {
59+
const solanaInstance = await instance.get(LegacyNetworks.SOLANA);
60+
const results: ProviderConnectResult[] = [];
61+
62+
if (solanaInstance) {
63+
await solanaInstance.connect();
64+
const account = solanaInstance.publicKey.toString();
65+
66+
results.push({
67+
accounts: account ? [account] : [],
68+
chainId: LegacyNetworks.SOLANA,
69+
});
70+
}
71+
72+
return results;
73+
}

0 commit comments

Comments
 (0)