diff --git a/.eslintrc.json b/.eslintrc.json index b38041af9e..52e4b2c6cb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -21,8 +21,8 @@ "parserOptions": { "ecmaVersion": "latest", "sourceType": "module", - // "project": ["tsconfig.base.json"] - "project": true + "project": ["tsconfig.base.json"] + // "project": true }, "rules": { "no-extra-boolean-cast": "off", diff --git a/global-wallets-env.d.ts b/global-wallets-env.d.ts index ddff86ffc1..2d1fe4a1fb 100644 --- a/global-wallets-env.d.ts +++ b/global-wallets-env.d.ts @@ -31,5 +31,6 @@ declare global { tally: any; bitkeep: any; mytonwallet: any; + TronLinkEVM: any; } } diff --git a/wallets/provider-tron-link/src/helpers.ts b/wallets/provider-tron-link/src/helpers.ts index 19d5a2583a..a857a34cf9 100644 --- a/wallets/provider-tron-link/src/helpers.ts +++ b/wallets/provider-tron-link/src/helpers.ts @@ -1,5 +1,24 @@ -export function tronLink() { - const { tronLink } = window; - if (!!tronLink) return tronLink; - return null; +import type { Network } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; + +type Provider = Map; + +export function tronLinkInstances(): Provider | null { + const { tronLink, TronLinkEVM } = window; + + if (!tronLink) { + return tronLink; + } + + const instances: Provider = new Map(); + + if (TronLinkEVM && TronLinkEVM.isTronLink) { + instances.set(Networks.ETHEREUM, TronLinkEVM); + } + + if (tronLink) { + instances.set(Networks.TRON, tronLink); + } + return instances; } diff --git a/wallets/provider-tron-link/src/index.ts b/wallets/provider-tron-link/src/index.ts index bca2d4a960..f443d6d444 100644 --- a/wallets/provider-tron-link/src/index.ts +++ b/wallets/provider-tron-link/src/index.ts @@ -1,15 +1,22 @@ import type { CanSwitchNetwork, Connect, + ProviderConnectResult, Subscribe, WalletInfo, } from '@rango-dev/wallets-shared'; import type { BlockchainMeta, SignerFactory } from 'rango-types'; -import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; -import { tronBlockchain } from 'rango-types'; +import { + canSwitchNetworkToEvm, + chooseInstance, + getEvmAccounts, + Networks, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains, isEvmBlockchain, tronBlockchain } from 'rango-types'; -import { tronLink as tronLink_instance } from './helpers'; +import { tronLinkInstances } from './helpers'; import signer from './signer'; /* @@ -23,27 +30,63 @@ export const config = { defaultNetwork: Networks.TRON, }; -export const getInstance = tronLink_instance; +export const getInstance = tronLinkInstances; + +export const connect: Connect = async ({ instance, meta }) => { + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + const tronInstance = chooseInstance(instance, meta, Networks.TRON); -export const connect: Connect = async ({ instance }) => { - let r = undefined; - if (!!instance && !instance.ready) { - r = await instance.request({ method: 'tron_requestAccounts' }); - if (!r) { + const results: ProviderConnectResult[] = []; + + if (ethInstance) { + const evmResult = await getEvmAccounts(ethInstance); + results.push(evmResult); + } + + if (tronInstance && !tronInstance.ready) { + const res = await tronInstance.request({ method: 'tron_requestAccounts' }); + if (!res) { throw new Error('Please unlock your TronLink extension first.'); } - if (!!r?.code && !!r.message) { - throw new Error(r.message); + if (!!res?.code && !!res.message) { + throw new Error(res.message); } + + // TODO check connected network + const address = tronInstance.tronWeb.address.fromHex( + (await instance.tronWeb.trx.getAccount()).address.toString() + ); + results.push({ + accounts: address ? [address] : [], + chainId: Networks.TRON, + }); } - const address = instance.tronWeb.address.fromHex( - (await instance.tronWeb.trx.getAccount()).address.toString() - ); - // TODO check connected network - return { accounts: address ? [address] : [], chainId: Networks.TRON }; + + return results; }; -export const subscribe: Subscribe = ({ updateAccounts, disconnect }) => { +export const subscribe: Subscribe = ({ + instance, + state, + updateChainId, + updateAccounts, + meta, + disconnect, +}) => { + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + + ethInstance?.on('accountsChanged', (addresses: string[]) => { + const eth_chainId = meta + .filter(isEvmBlockchain) + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; + if (state.connected) { + if (state.network != Networks.ETHEREUM && eth_chainId) { + updateChainId(eth_chainId); + } + updateAccounts(addresses); + } + }); + window.addEventListener('message', (e) => { if ( e.data.isTronLink && @@ -59,14 +102,14 @@ export const subscribe: Subscribe = ({ updateAccounts, disconnect }) => { } }); }; - -export const canSwitchNetworkTo: CanSwitchNetwork = () => false; +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; export const getSigners: (provider: any) => SignerFactory = signer; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains ) => { + const evms = evmBlockchains(allBlockChains); const tron = tronBlockchain(allBlockChains); return { name: 'TronLink', @@ -79,6 +122,6 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( DEFAULT: 'https://www.tronlink.org', }, color: '#96e7ed', - supportedChains: tron, + supportedChains: [...evms, ...tron], }; }; diff --git a/wallets/provider-tron-link/src/signer.ts b/wallets/provider-tron-link/src/signer.ts index b0dc9a9ca0..b558f2941b 100644 --- a/wallets/provider-tron-link/src/signer.ts +++ b/wallets/provider-tron-link/src/signer.ts @@ -1,12 +1,15 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultEvmSigner } from '@rango-dev/signer-evm'; import { DefaultTronSigner } from '@rango-dev/signer-tron'; -import { - DefaultSignerFactory, - SignerFactory, - TransactionType as TxType, -} from 'rango-types'; +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; export default function getSigners(provider: any): SignerFactory { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const tronProvider = getNetworkInstance(provider, Networks.TRON); const signers = new DefaultSignerFactory(); - signers.registerSigner(TxType.TRON, new DefaultTronSigner(provider)); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); + signers.registerSigner(TxType.TRON, new DefaultTronSigner(tronProvider)); return signers; }