Add Tron Chain to the Dapp example and wallet (#86)
This commit is contained in:
parent
5817d5e536
commit
a6ca910a6f
@ -38,6 +38,7 @@
|
|||||||
"react-scripts": "^4.0.3",
|
"react-scripts": "^4.0.3",
|
||||||
"solana-wallet": "^1.0.1",
|
"solana-wallet": "^1.0.1",
|
||||||
"styled-components": "^5.2.0",
|
"styled-components": "^5.2.0",
|
||||||
|
"tronweb": "^4.4.0",
|
||||||
"web-vitals": "^0.2.4"
|
"web-vitals": "^0.2.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -6,6 +6,7 @@ import * as polkadot from "./polkadot";
|
|||||||
import * as solana from "./solana";
|
import * as solana from "./solana";
|
||||||
import * as near from "./near";
|
import * as near from "./near";
|
||||||
import * as elrond from "./elrond";
|
import * as elrond from "./elrond";
|
||||||
|
import * as tron from './tron';
|
||||||
|
|
||||||
import { ChainMetadata, ChainRequestRender } from "../helpers";
|
import { ChainMetadata, ChainRequestRender } from "../helpers";
|
||||||
|
|
||||||
@ -24,6 +25,8 @@ export function getChainMetadata(chainId: string): ChainMetadata {
|
|||||||
return near.getChainMetadata(chainId);
|
return near.getChainMetadata(chainId);
|
||||||
case "elrond":
|
case "elrond":
|
||||||
return elrond.getChainMetadata(chainId);
|
return elrond.getChainMetadata(chainId);
|
||||||
|
case 'tron':
|
||||||
|
return tron.getChainMetadata(chainId);
|
||||||
default:
|
default:
|
||||||
throw new Error(`No metadata handler for namespace ${namespace}`);
|
throw new Error(`No metadata handler for namespace ${namespace}`);
|
||||||
}
|
}
|
||||||
|
42
dapps/react-dapp-v2/src/chains/tron.ts
Normal file
42
dapps/react-dapp-v2/src/chains/tron.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { ChainsMap } from 'caip-api';
|
||||||
|
import { NamespaceMetadata, ChainMetadata } from '../helpers';
|
||||||
|
|
||||||
|
// TODO: add `tron` namespace to `caip-api` package to avoid manual specification here.
|
||||||
|
export const TronChainData: ChainsMap = {
|
||||||
|
'0x2b6653dc': {
|
||||||
|
id: 'tron:0x2b6653dc',
|
||||||
|
name: 'Tron Mainnet',
|
||||||
|
rpc: [],
|
||||||
|
slip44: 195,
|
||||||
|
testnet: false
|
||||||
|
},
|
||||||
|
'0xcd8690dc': {
|
||||||
|
id: 'tron:0xcd8690dc',
|
||||||
|
name: 'Tron Testnet',
|
||||||
|
rpc: [],
|
||||||
|
slip44: 195,
|
||||||
|
testnet: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TronMetadata: NamespaceMetadata = {
|
||||||
|
// Tron Mainnet
|
||||||
|
'0x2b6653dc': {
|
||||||
|
logo: 'https://tronscan.io/static/media/TRON.4a760cebd163969b2ee874abf2415e9a.svg',
|
||||||
|
rgb: '183, 62, 49',
|
||||||
|
},
|
||||||
|
// Tron TestNet
|
||||||
|
'0xcd8690dc': {
|
||||||
|
logo: 'https://tronscan.io/static/media/TRON.4a760cebd163969b2ee874abf2415e9a.svg',
|
||||||
|
rgb: '183, 62, 49',
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getChainMetadata(chainId: string): ChainMetadata {
|
||||||
|
const reference = chainId.split(':')[1];
|
||||||
|
const metadata = TronMetadata[reference];
|
||||||
|
if (typeof metadata === 'undefined') {
|
||||||
|
throw new Error(`No chain metadata found for chainId: ${chainId}`);
|
||||||
|
}
|
||||||
|
return metadata;
|
||||||
|
}
|
@ -13,6 +13,7 @@ export const DEFAULT_MAIN_CHAINS = [
|
|||||||
"solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ",
|
"solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ",
|
||||||
"polkadot:91b171bb158e2d3848fa23a9f1c25182",
|
"polkadot:91b171bb158e2d3848fa23a9f1c25182",
|
||||||
"elrond:1",
|
"elrond:1",
|
||||||
|
'tron:0x2b6653dc',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DEFAULT_TEST_CHAINS = [
|
export const DEFAULT_TEST_CHAINS = [
|
||||||
@ -26,6 +27,7 @@ export const DEFAULT_TEST_CHAINS = [
|
|||||||
"polkadot:e143f23803ac50e8f6f8e62695d1ce9e",
|
"polkadot:e143f23803ac50e8f6f8e62695d1ce9e",
|
||||||
"near:testnet",
|
"near:testnet",
|
||||||
"elrond:D",
|
"elrond:D",
|
||||||
|
'tron:0xcd8690dc',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
|
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
|
||||||
@ -113,6 +115,16 @@ export enum DEFAULT_ELROND_METHODS {
|
|||||||
|
|
||||||
export enum DEFAULT_ELROND_EVENTS {}
|
export enum DEFAULT_ELROND_EVENTS {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TRON
|
||||||
|
*/
|
||||||
|
export enum DEFAULT_TRON_METHODS {
|
||||||
|
TRON_SIGN_TRANSACTION = 'tron_signTransaction',
|
||||||
|
TRON_SIGN_MESSAGE = 'tron_signMessage'
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum DEFAULT_TRON_EVENTS {}
|
||||||
|
|
||||||
export const DEFAULT_GITHUB_REPO_URL =
|
export const DEFAULT_GITHUB_REPO_URL =
|
||||||
"https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2";
|
"https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2";
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
import { SolanaChainData } from "../chains/solana";
|
import { SolanaChainData } from "../chains/solana";
|
||||||
import { PolkadotChainData } from "../chains/polkadot";
|
import { PolkadotChainData } from "../chains/polkadot";
|
||||||
import { ElrondChainData } from "../chains/elrond";
|
import { ElrondChainData } from "../chains/elrond";
|
||||||
|
import { TronChainData } from '../chains/tron';
|
||||||
|
|
||||||
import { ChainNamespaces, getAllChainNamespaces } from "../helpers";
|
import { ChainNamespaces, getAllChainNamespaces } from "../helpers";
|
||||||
import { NearChainData } from "../chains/near";
|
import { NearChainData } from "../chains/near";
|
||||||
@ -50,6 +51,8 @@ export function ChainDataContextProvider({
|
|||||||
chains = NearChainData;
|
chains = NearChainData;
|
||||||
} else if (namespace === "elrond") {
|
} else if (namespace === "elrond") {
|
||||||
chains = ElrondChainData;
|
chains = ElrondChainData;
|
||||||
|
} else if (namespace === 'tron') {
|
||||||
|
chains = TronChainData;
|
||||||
} else {
|
} else {
|
||||||
chains = await apiGetChainNamespace(namespace);
|
chains = await apiGetChainNamespace(namespace);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ import {
|
|||||||
SystemProgram,
|
SystemProgram,
|
||||||
Transaction as SolanaTransaction,
|
Transaction as SolanaTransaction,
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
|
// @ts-expect-error
|
||||||
|
import TronWeb from 'tronweb';
|
||||||
import {
|
import {
|
||||||
eip712,
|
eip712,
|
||||||
formatTestTransaction,
|
formatTestTransaction,
|
||||||
@ -32,6 +34,7 @@ import {
|
|||||||
DEFAULT_POLKADOT_METHODS,
|
DEFAULT_POLKADOT_METHODS,
|
||||||
DEFAULT_NEAR_METHODS,
|
DEFAULT_NEAR_METHODS,
|
||||||
DEFAULT_ELROND_METHODS,
|
DEFAULT_ELROND_METHODS,
|
||||||
|
DEFAULT_TRON_METHODS,
|
||||||
} from "../constants";
|
} from "../constants";
|
||||||
import { useChainData } from "./ChainDataContext";
|
import { useChainData } from "./ChainDataContext";
|
||||||
import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto";
|
import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto";
|
||||||
@ -90,6 +93,10 @@ interface IContext {
|
|||||||
testSignTransaction: TRpcRequestCallback;
|
testSignTransaction: TRpcRequestCallback;
|
||||||
testSignTransactions: TRpcRequestCallback;
|
testSignTransactions: TRpcRequestCallback;
|
||||||
};
|
};
|
||||||
|
tronRpc: {
|
||||||
|
testSignMessage: TRpcRequestCallback;
|
||||||
|
testSignTransaction: TRpcRequestCallback;
|
||||||
|
};
|
||||||
rpcResult?: IFormattedRpcResponse | null;
|
rpcResult?: IFormattedRpcResponse | null;
|
||||||
isRpcRequestPending: boolean;
|
isRpcRequestPending: boolean;
|
||||||
isTestnet: boolean;
|
isTestnet: boolean;
|
||||||
@ -1049,6 +1056,94 @@ export function JsonRpcContextProvider({
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------- TRON RPC METHODS --------
|
||||||
|
|
||||||
|
const tronRpc = {
|
||||||
|
testSignTransaction: _createJsonRpcRequestHandler(
|
||||||
|
async (chainId: string, address: string): Promise<IFormattedRpcResponse> => {
|
||||||
|
// Nile TestNet, if you want to use in MainNet, change the fullHost to 'https://api.trongrid.io'
|
||||||
|
const fullHost = isTestnet ? "https://nile.trongrid.io/" : "https://api.trongrid.io/";
|
||||||
|
|
||||||
|
const tronWeb = new TronWeb({
|
||||||
|
fullHost,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Take USDT as an example:
|
||||||
|
// Nile TestNet: https://nile.tronscan.org/#/token20/TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf
|
||||||
|
// MainNet: https://tronscan.org/#/token20/TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
|
||||||
|
|
||||||
|
|
||||||
|
const testContract = isTestnet ? "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf" : "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
|
||||||
|
const testTransaction = await tronWeb.transactionBuilder.triggerSmartContract(
|
||||||
|
testContract,
|
||||||
|
'approve(address,uint256)',
|
||||||
|
{ feeLimit: 200000000 },
|
||||||
|
[
|
||||||
|
{ type: 'address', value: address },
|
||||||
|
{ type: 'uint256', value: 0 }
|
||||||
|
],
|
||||||
|
address
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { result } = await client!.request<{ result: any }>({
|
||||||
|
chainId,
|
||||||
|
topic: session!.topic,
|
||||||
|
request: {
|
||||||
|
method: DEFAULT_TRON_METHODS.TRON_SIGN_TRANSACTION,
|
||||||
|
params: {
|
||||||
|
address,
|
||||||
|
transaction:{
|
||||||
|
...testTransaction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
method: DEFAULT_TRON_METHODS.TRON_SIGN_TRANSACTION,
|
||||||
|
address,
|
||||||
|
valid: true,
|
||||||
|
result: result.signature
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
testSignMessage: _createJsonRpcRequestHandler(
|
||||||
|
async (chainId: string, address: string): Promise<IFormattedRpcResponse> => {
|
||||||
|
|
||||||
|
const message = 'This is a message to be signed for Tron';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await client!.request<{ signature: string }>({
|
||||||
|
chainId,
|
||||||
|
topic: session!.topic,
|
||||||
|
request: {
|
||||||
|
method: DEFAULT_TRON_METHODS.TRON_SIGN_MESSAGE,
|
||||||
|
params: {
|
||||||
|
address,
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
method: DEFAULT_TRON_METHODS.TRON_SIGN_MESSAGE,
|
||||||
|
address,
|
||||||
|
valid: true,
|
||||||
|
result: result.signature
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<JsonRpcContext.Provider
|
<JsonRpcContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@ -1059,6 +1154,7 @@ export function JsonRpcContextProvider({
|
|||||||
polkadotRpc,
|
polkadotRpc,
|
||||||
nearRpc,
|
nearRpc,
|
||||||
elrondRpc,
|
elrondRpc,
|
||||||
|
tronRpc,
|
||||||
rpcResult: result,
|
rpcResult: result,
|
||||||
isRpcRequestPending: pending,
|
isRpcRequestPending: pending,
|
||||||
isTestnet,
|
isTestnet,
|
||||||
|
@ -12,6 +12,8 @@ import {
|
|||||||
DEFAULT_NEAR_EVENTS,
|
DEFAULT_NEAR_EVENTS,
|
||||||
DEFAULT_ELROND_EVENTS,
|
DEFAULT_ELROND_EVENTS,
|
||||||
DEFAULT_ELROND_METHODS,
|
DEFAULT_ELROND_METHODS,
|
||||||
|
DEFAULT_TRON_METHODS,
|
||||||
|
DEFAULT_TRON_EVENTS,
|
||||||
} from "../constants";
|
} from "../constants";
|
||||||
|
|
||||||
export const getNamespacesFromChains = (chains: string[]) => {
|
export const getNamespacesFromChains = (chains: string[]) => {
|
||||||
@ -40,6 +42,8 @@ export const getSupportedMethodsByNamespace = (namespace: string) => {
|
|||||||
return Object.values(DEFAULT_NEAR_METHODS);
|
return Object.values(DEFAULT_NEAR_METHODS);
|
||||||
case "elrond":
|
case "elrond":
|
||||||
return Object.values(DEFAULT_ELROND_METHODS);
|
return Object.values(DEFAULT_ELROND_METHODS);
|
||||||
|
case 'tron':
|
||||||
|
return Object.values(DEFAULT_TRON_METHODS);
|
||||||
default:
|
default:
|
||||||
throw new Error(`No default methods for namespace: ${namespace}`);
|
throw new Error(`No default methods for namespace: ${namespace}`);
|
||||||
}
|
}
|
||||||
@ -59,6 +63,8 @@ export const getSupportedEventsByNamespace = (namespace: string) => {
|
|||||||
return Object.values(DEFAULT_NEAR_EVENTS);
|
return Object.values(DEFAULT_NEAR_EVENTS);
|
||||||
case "elrond":
|
case "elrond":
|
||||||
return Object.values(DEFAULT_ELROND_EVENTS);
|
return Object.values(DEFAULT_ELROND_EVENTS);
|
||||||
|
case "tron":
|
||||||
|
return Object.values(DEFAULT_TRON_EVENTS);
|
||||||
default:
|
default:
|
||||||
throw new Error(`No default events for namespace: ${namespace}`);
|
throw new Error(`No default events for namespace: ${namespace}`);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
DEFAULT_ELROND_METHODS,
|
DEFAULT_ELROND_METHODS,
|
||||||
DEFAULT_TEST_CHAINS,
|
DEFAULT_TEST_CHAINS,
|
||||||
DEFAULT_NEAR_METHODS,
|
DEFAULT_NEAR_METHODS,
|
||||||
|
DEFAULT_TRON_METHODS,
|
||||||
} from "../constants";
|
} from "../constants";
|
||||||
import { AccountAction, setLocaleStorageTestnetFlag } from "../helpers";
|
import { AccountAction, setLocaleStorageTestnetFlag } from "../helpers";
|
||||||
import Toggle from "../components/Toggle";
|
import Toggle from "../components/Toggle";
|
||||||
@ -73,6 +74,7 @@ const Home: NextPage = () => {
|
|||||||
polkadotRpc,
|
polkadotRpc,
|
||||||
nearRpc,
|
nearRpc,
|
||||||
elrondRpc,
|
elrondRpc,
|
||||||
|
tronRpc,
|
||||||
isRpcRequestPending,
|
isRpcRequestPending,
|
||||||
rpcResult,
|
rpcResult,
|
||||||
isTestnet,
|
isTestnet,
|
||||||
@ -271,6 +273,27 @@ const Home: NextPage = () => {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTronActions = (): AccountAction[] => {
|
||||||
|
const onSignTransaction = async (chainId: string, address: string) => {
|
||||||
|
openRequestModal();
|
||||||
|
await tronRpc.testSignTransaction(chainId, address);
|
||||||
|
};
|
||||||
|
const onSignMessage = async (chainId: string, address: string) => {
|
||||||
|
openRequestModal();
|
||||||
|
await tronRpc.testSignMessage(chainId, address);
|
||||||
|
};
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
method: DEFAULT_TRON_METHODS.TRON_SIGN_TRANSACTION,
|
||||||
|
callback: onSignTransaction
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: DEFAULT_TRON_METHODS.TRON_SIGN_MESSAGE,
|
||||||
|
callback: onSignMessage
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
const getBlockchainActions = (chainId: string) => {
|
const getBlockchainActions = (chainId: string) => {
|
||||||
const [namespace] = chainId.split(":");
|
const [namespace] = chainId.split(":");
|
||||||
switch (namespace) {
|
switch (namespace) {
|
||||||
@ -286,6 +309,8 @@ const Home: NextPage = () => {
|
|||||||
return getNearActions();
|
return getNearActions();
|
||||||
case "elrond":
|
case "elrond":
|
||||||
return getElrondActions();
|
return getElrondActions();
|
||||||
|
case "tron":
|
||||||
|
return getTronActions();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"react-qr-reader-es6": "2.2.1-2",
|
"react-qr-reader-es6": "2.2.1-2",
|
||||||
"solana-wallet": "^1.0.2",
|
"solana-wallet": "^1.0.2",
|
||||||
|
"tronweb": "^4.4.0",
|
||||||
"valtio": "1.6.0"
|
"valtio": "1.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -4,6 +4,7 @@ import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
|||||||
import { nearAddresses } from '@/utils/NearWalletUtil'
|
import { nearAddresses } from '@/utils/NearWalletUtil'
|
||||||
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||||
import { elrondAddresses } from '@/utils/ElrondWalletUtil'
|
import { elrondAddresses } from '@/utils/ElrondWalletUtil'
|
||||||
|
import { tronAddresses } from '@/utils/TronWalletUtil'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
|
|
||||||
export default function AccountPicker() {
|
export default function AccountPicker() {
|
||||||
@ -17,6 +18,7 @@ export default function AccountPicker() {
|
|||||||
SettingsStore.setSolanaAddress(solanaAddresses[account])
|
SettingsStore.setSolanaAddress(solanaAddresses[account])
|
||||||
SettingsStore.setNearAddress(nearAddresses[account])
|
SettingsStore.setNearAddress(nearAddresses[account])
|
||||||
SettingsStore.setElrondAddress(elrondAddresses[account])
|
SettingsStore.setElrondAddress(elrondAddresses[account])
|
||||||
|
SettingsStore.setTronAddress(tronAddresses[account])
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -7,6 +7,7 @@ import SessionSignNearModal from '@/views/SessionSignNearModal'
|
|||||||
import SessionSignPolkadotModal from '@/views/SessionSignPolkadotModal'
|
import SessionSignPolkadotModal from '@/views/SessionSignPolkadotModal'
|
||||||
import SessionSignSolanaModal from '@/views/SessionSignSolanaModal'
|
import SessionSignSolanaModal from '@/views/SessionSignSolanaModal'
|
||||||
import SessionSignElrondModal from '@/views/SessionSignElrondModal'
|
import SessionSignElrondModal from '@/views/SessionSignElrondModal'
|
||||||
|
import SessionSignTronModal from '@/views/SessionSignTronModal'
|
||||||
import SessionSignTypedDataModal from '@/views/SessionSignTypedDataModal'
|
import SessionSignTypedDataModal from '@/views/SessionSignTypedDataModal'
|
||||||
import SessionUnsuportedMethodModal from '@/views/SessionUnsuportedMethodModal'
|
import SessionUnsuportedMethodModal from '@/views/SessionUnsuportedMethodModal'
|
||||||
import LegacySessionProposalModal from '@/views/LegacySessionProposalModal'
|
import LegacySessionProposalModal from '@/views/LegacySessionProposalModal'
|
||||||
@ -31,6 +32,7 @@ export default function Modal() {
|
|||||||
{view === 'SessionSignPolkadotModal' && <SessionSignPolkadotModal />}
|
{view === 'SessionSignPolkadotModal' && <SessionSignPolkadotModal />}
|
||||||
{view === 'SessionSignNearModal' && <SessionSignNearModal />}
|
{view === 'SessionSignNearModal' && <SessionSignNearModal />}
|
||||||
{view === 'SessionSignElrondModal' && <SessionSignElrondModal />}
|
{view === 'SessionSignElrondModal' && <SessionSignElrondModal />}
|
||||||
|
{view === 'SessionSignTronModal' && <SessionSignTronModal />}
|
||||||
{view === 'LegacySessionProposalModal' && <LegacySessionProposalModal />}
|
{view === 'LegacySessionProposalModal' && <LegacySessionProposalModal />}
|
||||||
{view === 'LegacySessionSignModal' && <LegacySessionSignModal />}
|
{view === 'LegacySessionSignModal' && <LegacySessionSignModal />}
|
||||||
{view === 'LegacySessionSignTypedDataModal' && <LegacySessionSignTypedDataModal />}
|
{view === 'LegacySessionSignTypedDataModal' && <LegacySessionSignTypedDataModal />}
|
||||||
|
@ -3,6 +3,7 @@ import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
|||||||
import { NEAR_TEST_CHAINS, TNearChain } from '@/data/NEARData'
|
import { NEAR_TEST_CHAINS, TNearChain } from '@/data/NEARData'
|
||||||
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||||
import { ELROND_CHAINS, TElrondChain } from '@/data/ElrondData'
|
import { ELROND_CHAINS, TElrondChain } from '@/data/ElrondData'
|
||||||
|
import { TRON_CHAINS, TTronChain } from '@/data/TronData'
|
||||||
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ export default function RequesDetailsCard({ chains, protocol }: IProps) {
|
|||||||
SOLANA_CHAINS[chain as TSolanaChain]?.name ??
|
SOLANA_CHAINS[chain as TSolanaChain]?.name ??
|
||||||
NEAR_TEST_CHAINS[chain as TNearChain]?.name ??
|
NEAR_TEST_CHAINS[chain as TNearChain]?.name ??
|
||||||
ELROND_CHAINS[chain as TElrondChain]?.name ??
|
ELROND_CHAINS[chain as TElrondChain]?.name ??
|
||||||
|
TRON_CHAINS[chain as TTronChain]?.name ??
|
||||||
chain
|
chain
|
||||||
)
|
)
|
||||||
.join(', ')}
|
.join(', ')}
|
||||||
|
@ -4,6 +4,7 @@ import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
|||||||
import { NEAR_TEST_CHAINS } from '@/data/NEARData'
|
import { NEAR_TEST_CHAINS } from '@/data/NEARData'
|
||||||
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
||||||
import { ELROND_MAINNET_CHAINS, ELROND_TEST_CHAINS } from '@/data/ElrondData'
|
import { ELROND_MAINNET_CHAINS, ELROND_TEST_CHAINS } from '@/data/ElrondData'
|
||||||
|
import { TRON_MAINNET_CHAINS, TRON_TEST_CHAINS } from '@/data/TronData'
|
||||||
import { formatChainName } from '@/utils/HelperUtil'
|
import { formatChainName } from '@/utils/HelperUtil'
|
||||||
import { Col, Row, Text } from '@nextui-org/react'
|
import { Col, Row, Text } from '@nextui-org/react'
|
||||||
import { SessionTypes } from '@walletconnect/types'
|
import { SessionTypes } from '@walletconnect/types'
|
||||||
@ -16,11 +17,13 @@ const CHAIN_METADATA = {
|
|||||||
...COSMOS_MAINNET_CHAINS,
|
...COSMOS_MAINNET_CHAINS,
|
||||||
...SOLANA_MAINNET_CHAINS,
|
...SOLANA_MAINNET_CHAINS,
|
||||||
...ELROND_MAINNET_CHAINS,
|
...ELROND_MAINNET_CHAINS,
|
||||||
|
...TRON_MAINNET_CHAINS,
|
||||||
...EIP155_MAINNET_CHAINS,
|
...EIP155_MAINNET_CHAINS,
|
||||||
...EIP155_TEST_CHAINS,
|
...EIP155_TEST_CHAINS,
|
||||||
...SOLANA_TEST_CHAINS,
|
...SOLANA_TEST_CHAINS,
|
||||||
...NEAR_TEST_CHAINS,
|
...NEAR_TEST_CHAINS,
|
||||||
...ELROND_TEST_CHAINS
|
...ELROND_TEST_CHAINS,
|
||||||
|
...TRON_TEST_CHAINS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,7 @@ import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
|||||||
import { NEAR_TEST_CHAINS } from '@/data/NEARData'
|
import { NEAR_TEST_CHAINS } from '@/data/NEARData'
|
||||||
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
||||||
import { ELROND_MAINNET_CHAINS, ELROND_TEST_CHAINS } from '@/data/ElrondData'
|
import { ELROND_MAINNET_CHAINS, ELROND_TEST_CHAINS } from '@/data/ElrondData'
|
||||||
|
import { TRON_MAINNET_CHAINS, TRON_TEST_CHAINS } from '@/data/TronData'
|
||||||
import { formatChainName } from '@/utils/HelperUtil'
|
import { formatChainName } from '@/utils/HelperUtil'
|
||||||
import { Col, Row, Text } from '@nextui-org/react'
|
import { Col, Row, Text } from '@nextui-org/react'
|
||||||
import { ProposalTypes } from '@walletconnect/types'
|
import { ProposalTypes } from '@walletconnect/types'
|
||||||
@ -16,11 +17,13 @@ const CHAIN_METADATA = {
|
|||||||
...COSMOS_MAINNET_CHAINS,
|
...COSMOS_MAINNET_CHAINS,
|
||||||
...SOLANA_MAINNET_CHAINS,
|
...SOLANA_MAINNET_CHAINS,
|
||||||
...ELROND_MAINNET_CHAINS,
|
...ELROND_MAINNET_CHAINS,
|
||||||
|
...TRON_MAINNET_CHAINS,
|
||||||
...EIP155_MAINNET_CHAINS,
|
...EIP155_MAINNET_CHAINS,
|
||||||
...EIP155_TEST_CHAINS,
|
...EIP155_TEST_CHAINS,
|
||||||
...SOLANA_TEST_CHAINS,
|
...SOLANA_TEST_CHAINS,
|
||||||
...NEAR_TEST_CHAINS,
|
...NEAR_TEST_CHAINS,
|
||||||
...ELROND_TEST_CHAINS
|
...ELROND_TEST_CHAINS,
|
||||||
|
...TRON_TEST_CHAINS
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
49
wallets/react-wallet-v2/src/data/TronData.ts
Normal file
49
wallets/react-wallet-v2/src/data/TronData.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
export type TTronChain = keyof typeof TRON_MAINNET_CHAINS
|
||||||
|
|
||||||
|
interface TRONChains {
|
||||||
|
[key: string]: ChainMetadata
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChainMetadata = {
|
||||||
|
chainId: string
|
||||||
|
name: string
|
||||||
|
logo: string
|
||||||
|
rgb: string
|
||||||
|
fullNode: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chains
|
||||||
|
*/
|
||||||
|
export const TRON_MAINNET_CHAINS: TRONChains = {
|
||||||
|
'tron:0x2b6653dc': {
|
||||||
|
chainId: '0x2b6653dc',
|
||||||
|
name: 'Tron',
|
||||||
|
logo: 'https://tronscan.io/static/media/TRON.4a760cebd163969b2ee874abf2415e9a.svg',
|
||||||
|
rgb: '183, 62, 49',
|
||||||
|
fullNode: 'https://api.trongrid.io'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TRON_TEST_CHAINS: TRONChains = {
|
||||||
|
'tron:0xcd8690dc': {
|
||||||
|
chainId: '0xcd8690dc',
|
||||||
|
name: 'Tron Testnet',
|
||||||
|
logo: 'https://tronscan.io/static/media/TRON.4a760cebd163969b2ee874abf2415e9a.svg',
|
||||||
|
rgb: '183, 62, 49',
|
||||||
|
fullNode: 'https://nile.trongrid.io/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TRON_CHAINS = { ...TRON_MAINNET_CHAINS, ...TRON_TEST_CHAINS }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods
|
||||||
|
*/
|
||||||
|
export const TRON_SIGNING_METHODS = {
|
||||||
|
TRON_SIGN_TRANSACTION: 'tron_signTransaction',
|
||||||
|
TRON_SIGN_MESSAGE: 'tron_signMessage'
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { createOrRestoreEIP155Wallet } from '@/utils/EIP155WalletUtil'
|
|||||||
import { createOrRestoreSolanaWallet } from '@/utils/SolanaWalletUtil'
|
import { createOrRestoreSolanaWallet } from '@/utils/SolanaWalletUtil'
|
||||||
import { createOrRestorePolkadotWallet } from '@/utils/PolkadotWalletUtil'
|
import { createOrRestorePolkadotWallet } from '@/utils/PolkadotWalletUtil'
|
||||||
import { createOrRestoreElrondWallet } from '@/utils/ElrondWalletUtil'
|
import { createOrRestoreElrondWallet } from '@/utils/ElrondWalletUtil'
|
||||||
|
import { createOrRestoreTronWallet } from '@/utils/TronWalletUtil'
|
||||||
import { createSignClient } from '@/utils/WalletConnectUtil'
|
import { createSignClient } from '@/utils/WalletConnectUtil'
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
@ -23,6 +24,7 @@ export default function useInitialization() {
|
|||||||
const { polkadotAddresses } = await createOrRestorePolkadotWallet()
|
const { polkadotAddresses } = await createOrRestorePolkadotWallet()
|
||||||
const { nearAddresses } = await createOrRestoreNearWallet()
|
const { nearAddresses } = await createOrRestoreNearWallet()
|
||||||
const { elrondAddresses } = await createOrRestoreElrondWallet()
|
const { elrondAddresses } = await createOrRestoreElrondWallet()
|
||||||
|
const { tronAddresses } = await createOrRestoreTronWallet()
|
||||||
|
|
||||||
SettingsStore.setEIP155Address(eip155Addresses[0])
|
SettingsStore.setEIP155Address(eip155Addresses[0])
|
||||||
SettingsStore.setCosmosAddress(cosmosAddresses[0])
|
SettingsStore.setCosmosAddress(cosmosAddresses[0])
|
||||||
@ -30,7 +32,7 @@ export default function useInitialization() {
|
|||||||
SettingsStore.setPolkadotAddress(polkadotAddresses[0])
|
SettingsStore.setPolkadotAddress(polkadotAddresses[0])
|
||||||
SettingsStore.setNearAddress(nearAddresses[0])
|
SettingsStore.setNearAddress(nearAddresses[0])
|
||||||
SettingsStore.setElrondAddress(elrondAddresses[0])
|
SettingsStore.setElrondAddress(elrondAddresses[0])
|
||||||
|
SettingsStore.setTronAddress(tronAddresses[0])
|
||||||
await createSignClient(relayerRegionURL)
|
await createSignClient(relayerRegionURL)
|
||||||
prevRelayerURLValue.current = relayerRegionURL
|
prevRelayerURLValue.current = relayerRegionURL
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import { EIP155_SIGNING_METHODS } from '@/data/EIP155Data'
|
|||||||
import { SOLANA_SIGNING_METHODS } from '@/data/SolanaData'
|
import { SOLANA_SIGNING_METHODS } from '@/data/SolanaData'
|
||||||
import { POLKADOT_SIGNING_METHODS } from '@/data/PolkadotData'
|
import { POLKADOT_SIGNING_METHODS } from '@/data/PolkadotData'
|
||||||
import { ELROND_SIGNING_METHODS } from '@/data/ElrondData'
|
import { ELROND_SIGNING_METHODS } from '@/data/ElrondData'
|
||||||
|
import { TRON_SIGNING_METHODS } from '@/data/TronData'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import { signClient } from '@/utils/WalletConnectUtil'
|
import { signClient } from '@/utils/WalletConnectUtil'
|
||||||
import { SignClientTypes } from '@walletconnect/types'
|
import { SignClientTypes } from '@walletconnect/types'
|
||||||
@ -77,6 +78,9 @@ export default function useWalletConnectEventsManager(initialized: boolean) {
|
|||||||
topic,
|
topic,
|
||||||
response: await approveNearRequest(requestEvent)
|
response: await approveNearRequest(requestEvent)
|
||||||
})
|
})
|
||||||
|
case TRON_SIGNING_METHODS.TRON_SIGN_MESSAGE:
|
||||||
|
case TRON_SIGNING_METHODS.TRON_SIGN_TRANSACTION:
|
||||||
|
return ModalStore.open('SessionSignTronModal', { requestEvent, requestSession })
|
||||||
default:
|
default:
|
||||||
return ModalStore.open('SessionUnsuportedMethodModal', { requestEvent, requestSession })
|
return ModalStore.open('SessionUnsuportedMethodModal', { requestEvent, requestSession })
|
||||||
}
|
}
|
||||||
|
58
wallets/react-wallet-v2/src/lib/TronLib.ts
Normal file
58
wallets/react-wallet-v2/src/lib/TronLib.ts
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
import TronWeb from 'tronweb'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
interface IInitArguments {
|
||||||
|
privateKey: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Library
|
||||||
|
*/
|
||||||
|
export default class TronLib {
|
||||||
|
privateKey: string
|
||||||
|
tronWeb: any
|
||||||
|
|
||||||
|
constructor(privateKey: string) {
|
||||||
|
this.privateKey = privateKey
|
||||||
|
this.tronWeb = new TronWeb({
|
||||||
|
// Nile TestNet, if you want to use in MainNet, change the fullHost to 'https://api.trongrid.io', or use tronWeb.setFullNode
|
||||||
|
fullHost: 'https://nile.trongrid.io/',
|
||||||
|
privateKey: privateKey
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static async init({ privateKey }: IInitArguments) {
|
||||||
|
if(!privateKey){
|
||||||
|
const account = TronWeb.utils.accounts.generateAccount();
|
||||||
|
return new TronLib(account.privateKey)
|
||||||
|
} else {
|
||||||
|
return new TronLib(privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAddress() {
|
||||||
|
return this.tronWeb.defaultAddress.base58
|
||||||
|
}
|
||||||
|
|
||||||
|
public createAccount() {
|
||||||
|
return this.tronWeb.createAccount()
|
||||||
|
}
|
||||||
|
|
||||||
|
public setFullNode(node: string) {
|
||||||
|
return this.tronWeb.setFullNode(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
public async signMessage(message: string) {
|
||||||
|
const signedtxn = await this.tronWeb.trx.signMessageV2(message)
|
||||||
|
return signedtxn
|
||||||
|
}
|
||||||
|
|
||||||
|
public async signTransaction(transaction: any) {
|
||||||
|
const signedtxn = await this.tronWeb.trx.sign(transaction.transaction)
|
||||||
|
return signedtxn
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
|||||||
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
||||||
import { POLKADOT_MAINNET_CHAINS, POLKADOT_TEST_CHAINS } from '@/data/PolkadotData'
|
import { POLKADOT_MAINNET_CHAINS, POLKADOT_TEST_CHAINS } from '@/data/PolkadotData'
|
||||||
import { ELROND_MAINNET_CHAINS, ELROND_TEST_CHAINS } from '@/data/ElrondData'
|
import { ELROND_MAINNET_CHAINS, ELROND_TEST_CHAINS } from '@/data/ElrondData'
|
||||||
|
import { TRON_MAINNET_CHAINS, TRON_TEST_CHAINS } from '@/data/TronData'
|
||||||
import SettingsStore from '@/store/SettingsStore'
|
import SettingsStore from '@/store/SettingsStore'
|
||||||
import { Text } from '@nextui-org/react'
|
import { Text } from '@nextui-org/react'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
@ -20,7 +21,8 @@ export default function HomePage() {
|
|||||||
solanaAddress,
|
solanaAddress,
|
||||||
polkadotAddress,
|
polkadotAddress,
|
||||||
nearAddress,
|
nearAddress,
|
||||||
elrondAddress
|
elrondAddress,
|
||||||
|
tronAddress
|
||||||
} = useSnapshot(SettingsStore.state)
|
} = useSnapshot(SettingsStore.state)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -46,6 +48,9 @@ export default function HomePage() {
|
|||||||
{Object.values(ELROND_MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
{Object.values(ELROND_MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={elrondAddress} />
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={elrondAddress} />
|
||||||
))}
|
))}
|
||||||
|
{Object.values(TRON_MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={tronAddress} />
|
||||||
|
))}
|
||||||
|
|
||||||
{testNets ? (
|
{testNets ? (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@ -67,6 +72,9 @@ export default function HomePage() {
|
|||||||
{Object.values(ELROND_TEST_CHAINS).map(({ name, logo, rgb }) => (
|
{Object.values(ELROND_TEST_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={elrondAddress} />
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={elrondAddress} />
|
||||||
))}
|
))}
|
||||||
|
{Object.values(TRON_TEST_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={tronAddress} />
|
||||||
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) : null}
|
) : null}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -5,13 +5,14 @@ import { cosmosWallets } from '@/utils/CosmosWalletUtil'
|
|||||||
import { eip155Wallets } from '@/utils/EIP155WalletUtil'
|
import { eip155Wallets } from '@/utils/EIP155WalletUtil'
|
||||||
import { solanaWallets } from '@/utils/SolanaWalletUtil'
|
import { solanaWallets } from '@/utils/SolanaWalletUtil'
|
||||||
import { elrondWallets } from '@/utils/ElrondWalletUtil'
|
import { elrondWallets } from '@/utils/ElrondWalletUtil'
|
||||||
|
import { tronWallets } from '@/utils/TronWalletUtil'
|
||||||
import { Card, Divider, Row, Switch, Text } from '@nextui-org/react'
|
import { Card, Divider, Row, Switch, Text } from '@nextui-org/react'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
import packageJSON from '../../package.json'
|
import packageJSON from '../../package.json'
|
||||||
|
|
||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
const { testNets, eip155Address, cosmosAddress, solanaAddress, elrondAddress } = useSnapshot(
|
const { testNets, eip155Address, cosmosAddress, solanaAddress, elrondAddress, tronAddress } = useSnapshot(
|
||||||
SettingsStore.state
|
SettingsStore.state
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -88,6 +89,13 @@ export default function SettingsPage() {
|
|||||||
<Card bordered borderWeight="light" css={{ minHeight: '215px', wordWrap: 'break-word' }}>
|
<Card bordered borderWeight="light" css={{ minHeight: '215px', wordWrap: 'break-word' }}>
|
||||||
<Text css={{ fontFamily: '$mono' }}>{elrondWallets[elrondAddress].getMnemonic()}</Text>
|
<Text css={{ fontFamily: '$mono' }}>{elrondWallets[elrondAddress].getMnemonic()}</Text>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<Text h4 css={{ marginTop: '$10', marginBottom: '$5' }}>
|
||||||
|
Tron Private Key
|
||||||
|
</Text>
|
||||||
|
<Card bordered borderWeight="light" css={{ minHeight: '100px', wordWrap: 'break-word' }}>
|
||||||
|
<Text css={{ fontFamily: '$mono' }}>{tronWallets[tronAddress].privateKey}</Text>
|
||||||
|
</Card>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ interface State {
|
|||||||
| 'SessionSignPolkadotModal'
|
| 'SessionSignPolkadotModal'
|
||||||
| 'SessionSignNearModal'
|
| 'SessionSignNearModal'
|
||||||
| 'SessionSignElrondModal'
|
| 'SessionSignElrondModal'
|
||||||
|
| 'SessionSignTronModal'
|
||||||
| 'LegacySessionProposalModal'
|
| 'LegacySessionProposalModal'
|
||||||
| 'LegacySessionSignModal'
|
| 'LegacySessionSignModal'
|
||||||
| 'LegacySessionSignTypedDataModal'
|
| 'LegacySessionSignTypedDataModal'
|
||||||
|
@ -12,6 +12,7 @@ interface State {
|
|||||||
polkadotAddress: string
|
polkadotAddress: string
|
||||||
nearAddress: string
|
nearAddress: string
|
||||||
elrondAddress: string
|
elrondAddress: string
|
||||||
|
tronAddress: string
|
||||||
relayerRegionURL: string
|
relayerRegionURL: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ const state = proxy<State>({
|
|||||||
polkadotAddress: '',
|
polkadotAddress: '',
|
||||||
nearAddress: '',
|
nearAddress: '',
|
||||||
elrondAddress: '',
|
elrondAddress: '',
|
||||||
|
tronAddress: '',
|
||||||
relayerRegionURL: ''
|
relayerRegionURL: ''
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -66,6 +68,10 @@ const SettingsStore = {
|
|||||||
state.elrondAddress = elrondAddress
|
state.elrondAddress = elrondAddress
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setTronAddress(tronAddress: string) {
|
||||||
|
state.tronAddress = tronAddress
|
||||||
|
},
|
||||||
|
|
||||||
toggleTestNets() {
|
toggleTestNets() {
|
||||||
state.testNets = !state.testNets
|
state.testNets = !state.testNets
|
||||||
if (state.testNets) {
|
if (state.testNets) {
|
||||||
|
@ -3,6 +3,7 @@ import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
|||||||
import { NEAR_TEST_CHAINS, TNearChain } from '@/data/NEARData'
|
import { NEAR_TEST_CHAINS, TNearChain } from '@/data/NEARData'
|
||||||
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||||
import { ELROND_CHAINS, TElrondChain } from '@/data/ElrondData'
|
import { ELROND_CHAINS, TElrondChain } from '@/data/ElrondData'
|
||||||
|
import { TRON_CHAINS, TTronChain } from '@/data/TronData'
|
||||||
import { utils } from 'ethers'
|
import { utils } from 'ethers'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,6 +118,13 @@ export function isElrondChain(chain: string) {
|
|||||||
return chain.includes('elrond')
|
return chain.includes('elrond')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if chain is part of TRON standard
|
||||||
|
*/
|
||||||
|
export function isTronChain(chain: string) {
|
||||||
|
return chain.includes('tron')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats chainId to its name
|
* Formats chainId to its name
|
||||||
*/
|
*/
|
||||||
@ -127,6 +135,7 @@ export function formatChainName(chainId: string) {
|
|||||||
SOLANA_CHAINS[chainId as TSolanaChain]?.name ??
|
SOLANA_CHAINS[chainId as TSolanaChain]?.name ??
|
||||||
NEAR_TEST_CHAINS[chainId as TNearChain]?.name ??
|
NEAR_TEST_CHAINS[chainId as TNearChain]?.name ??
|
||||||
ELROND_CHAINS[chainId as TElrondChain]?.name ??
|
ELROND_CHAINS[chainId as TElrondChain]?.name ??
|
||||||
|
TRON_CHAINS[chainId as TTronChain]?.name ??
|
||||||
chainId
|
chainId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
49
wallets/react-wallet-v2/src/utils/TronRequestHandlerUtil.ts
Normal file
49
wallets/react-wallet-v2/src/utils/TronRequestHandlerUtil.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import {TRON_MAINNET_CHAINS, TRON_TEST_CHAINS, TRON_SIGNING_METHODS} from '@/data/TronData'
|
||||||
|
import { getWalletAddressFromParams } from '@/utils/HelperUtil'
|
||||||
|
import { tronAddresses, tronWallets } from '@/utils/TronWalletUtil'
|
||||||
|
import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils'
|
||||||
|
import { SignClientTypes } from '@walletconnect/types'
|
||||||
|
import { getSdkError } from '@walletconnect/utils'
|
||||||
|
|
||||||
|
export async function approveTronRequest(
|
||||||
|
requestEvent: SignClientTypes.EventArguments['session_request']
|
||||||
|
) {
|
||||||
|
const { params, id } = requestEvent
|
||||||
|
const { request } = params
|
||||||
|
|
||||||
|
const wallet = tronWallets[getWalletAddressFromParams(tronAddresses, params)]
|
||||||
|
|
||||||
|
if(TRON_MAINNET_CHAINS[params.chainId]){
|
||||||
|
wallet.setFullNode(TRON_MAINNET_CHAINS[params.chainId].fullNode)
|
||||||
|
} else if(TRON_TEST_CHAINS[params.chainId]){
|
||||||
|
wallet.setFullNode(TRON_TEST_CHAINS[params.chainId].fullNode)
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid chain id')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch (request.method) {
|
||||||
|
case TRON_SIGNING_METHODS.TRON_SIGN_MESSAGE:
|
||||||
|
const signedMessage = await wallet.signMessage(request.params.message)
|
||||||
|
const res = {
|
||||||
|
signature: signedMessage
|
||||||
|
}
|
||||||
|
return formatJsonRpcResult(id, res)
|
||||||
|
|
||||||
|
case TRON_SIGNING_METHODS.TRON_SIGN_TRANSACTION:
|
||||||
|
const signedTransaction = await wallet.signTransaction(request.params.transaction)
|
||||||
|
const resData = {
|
||||||
|
result: signedTransaction
|
||||||
|
}
|
||||||
|
return formatJsonRpcResult(id, resData)
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(getSdkError('INVALID_METHOD').message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rejectTronRequest(request: SignClientTypes.EventArguments['session_request']) {
|
||||||
|
const { id } = request
|
||||||
|
|
||||||
|
return formatJsonRpcError(id, getSdkError('USER_REJECTED_METHODS').message)
|
||||||
|
}
|
44
wallets/react-wallet-v2/src/utils/TronWalletUtil.ts
Normal file
44
wallets/react-wallet-v2/src/utils/TronWalletUtil.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import TronLib from '@/lib/TronLib'
|
||||||
|
|
||||||
|
export let tronWeb1: TronLib
|
||||||
|
export let tronWeb2: TronLib
|
||||||
|
export let tronWallets: Record<string, TronLib>
|
||||||
|
export let tronAddresses: string[]
|
||||||
|
|
||||||
|
let address1: string
|
||||||
|
let address2: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities
|
||||||
|
*/
|
||||||
|
export async function createOrRestoreTronWallet() {
|
||||||
|
const privateKey1 = localStorage.getItem('TRON_PrivateKey_1')
|
||||||
|
const privateKey2 = localStorage.getItem('TRON_PrivateKey_2')
|
||||||
|
|
||||||
|
if (privateKey1 && privateKey2) {
|
||||||
|
tronWeb1 = await TronLib.init({ privateKey: privateKey1 })
|
||||||
|
tronWeb2 = await TronLib.init({ privateKey: privateKey2 })
|
||||||
|
} else {
|
||||||
|
tronWeb1 = await TronLib.init({ privateKey: '' })
|
||||||
|
tronWeb2 = await TronLib.init({ privateKey: '' })
|
||||||
|
|
||||||
|
// Don't store privateKey in local storage in a production project!
|
||||||
|
localStorage.setItem('TRON_PrivateKey_1', tronWeb1.privateKey)
|
||||||
|
localStorage.setItem('TRON_PrivateKey_2', tronWeb2.privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
address1 = tronWeb1.getAddress()
|
||||||
|
address2 = tronWeb2.getAddress()
|
||||||
|
|
||||||
|
tronWallets = {
|
||||||
|
[address1]: tronWeb1,
|
||||||
|
[address2]: tronWeb2
|
||||||
|
}
|
||||||
|
|
||||||
|
tronAddresses = Object.keys(tronWallets)
|
||||||
|
|
||||||
|
return {
|
||||||
|
tronWallets,
|
||||||
|
tronAddresses
|
||||||
|
}
|
||||||
|
}
|
@ -7,13 +7,15 @@ import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
|||||||
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
||||||
import { polkadotAddresses } from '@/utils/PolkadotWalletUtil'
|
import { polkadotAddresses } from '@/utils/PolkadotWalletUtil'
|
||||||
import { elrondAddresses } from '@/utils/ElrondWalletUtil'
|
import { elrondAddresses } from '@/utils/ElrondWalletUtil'
|
||||||
|
import { tronAddresses } from '@/utils/TronWalletUtil'
|
||||||
import {
|
import {
|
||||||
isCosmosChain,
|
isCosmosChain,
|
||||||
isEIP155Chain,
|
isEIP155Chain,
|
||||||
isSolanaChain,
|
isSolanaChain,
|
||||||
isPolkadotChain,
|
isPolkadotChain,
|
||||||
isNearChain,
|
isNearChain,
|
||||||
isElrondChain
|
isElrondChain,
|
||||||
|
isTronChain
|
||||||
} from '@/utils/HelperUtil'
|
} from '@/utils/HelperUtil'
|
||||||
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||||
import { signClient } from '@/utils/WalletConnectUtil'
|
import { signClient } from '@/utils/WalletConnectUtil'
|
||||||
@ -149,6 +151,15 @@ export default function SessionProposalModal() {
|
|||||||
chain={chain}
|
chain={chain}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
} else if (isTronChain(chain)) {
|
||||||
|
return (
|
||||||
|
<ProposalSelectSection
|
||||||
|
addresses={tronAddresses}
|
||||||
|
selectedAddresses={selectedAccounts[chain]}
|
||||||
|
onSelect={onSelectAccount}
|
||||||
|
chain={chain}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
72
wallets/react-wallet-v2/src/views/SessionSignTronModal.tsx
Normal file
72
wallets/react-wallet-v2/src/views/SessionSignTronModal.tsx
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
||||||
|
import RequestDataCard from '@/components/RequestDataCard'
|
||||||
|
import RequesDetailsCard from '@/components/RequestDetalilsCard'
|
||||||
|
import RequestMethodCard from '@/components/RequestMethodCard'
|
||||||
|
import RequestModalContainer from '@/components/RequestModalContainer'
|
||||||
|
import ModalStore from '@/store/ModalStore'
|
||||||
|
import { approveTronRequest, rejectTronRequest } from '@/utils/TronRequestHandlerUtil'
|
||||||
|
import { signClient } from '@/utils/WalletConnectUtil'
|
||||||
|
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||||
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
|
export default function SessionSignTronModal() {
|
||||||
|
// Get request and wallet data from store
|
||||||
|
const requestEvent = ModalStore.state.data?.requestEvent
|
||||||
|
const requestSession = ModalStore.state.data?.requestSession
|
||||||
|
|
||||||
|
// Ensure request and wallet are defined
|
||||||
|
if (!requestEvent || !requestSession) {
|
||||||
|
return <Text>Missing request data</Text>
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get required request data
|
||||||
|
const { topic, params } = requestEvent
|
||||||
|
const { request, chainId } = params
|
||||||
|
|
||||||
|
// Handle approve action (logic varies based on request method)
|
||||||
|
async function onApprove() {
|
||||||
|
if (requestEvent) {
|
||||||
|
const response = await approveTronRequest(requestEvent)
|
||||||
|
await signClient.respond({
|
||||||
|
topic,
|
||||||
|
response
|
||||||
|
})
|
||||||
|
ModalStore.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle reject action
|
||||||
|
async function onReject() {
|
||||||
|
if (requestEvent) {
|
||||||
|
const response = rejectTronRequest(requestEvent)
|
||||||
|
await signClient.respond({
|
||||||
|
topic,
|
||||||
|
response
|
||||||
|
})
|
||||||
|
ModalStore.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<RequestModalContainer title="Sign Message">
|
||||||
|
<ProjectInfoCard metadata={requestSession.peer.metadata} />
|
||||||
|
<Divider y={2} />
|
||||||
|
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||||
|
<Divider y={2} />
|
||||||
|
<RequestDataCard data={params} />
|
||||||
|
<Divider y={2} />
|
||||||
|
<RequestMethodCard methods={[request.method]} />
|
||||||
|
</RequestModalContainer>
|
||||||
|
|
||||||
|
<Modal.Footer>
|
||||||
|
<Button auto flat color="error" onClick={onReject}>
|
||||||
|
Reject
|
||||||
|
</Button>
|
||||||
|
<Button auto flat color="success" onClick={onApprove}>
|
||||||
|
Approve
|
||||||
|
</Button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user