Add Tron Chain to the Dapp example and wallet (#86)
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
"react-scripts": "^4.0.3",
|
||||
"solana-wallet": "^1.0.1",
|
||||
"styled-components": "^5.2.0",
|
||||
"tronweb": "^4.4.0",
|
||||
"web-vitals": "^0.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -6,6 +6,7 @@ import * as polkadot from "./polkadot";
|
||||
import * as solana from "./solana";
|
||||
import * as near from "./near";
|
||||
import * as elrond from "./elrond";
|
||||
import * as tron from './tron';
|
||||
|
||||
import { ChainMetadata, ChainRequestRender } from "../helpers";
|
||||
|
||||
@@ -24,6 +25,8 @@ export function getChainMetadata(chainId: string): ChainMetadata {
|
||||
return near.getChainMetadata(chainId);
|
||||
case "elrond":
|
||||
return elrond.getChainMetadata(chainId);
|
||||
case 'tron':
|
||||
return tron.getChainMetadata(chainId);
|
||||
default:
|
||||
throw new Error(`No metadata handler for namespace ${namespace}`);
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
"polkadot:91b171bb158e2d3848fa23a9f1c25182",
|
||||
"elrond:1",
|
||||
'tron:0x2b6653dc',
|
||||
];
|
||||
|
||||
export const DEFAULT_TEST_CHAINS = [
|
||||
@@ -26,6 +27,7 @@ export const DEFAULT_TEST_CHAINS = [
|
||||
"polkadot:e143f23803ac50e8f6f8e62695d1ce9e",
|
||||
"near:testnet",
|
||||
"elrond:D",
|
||||
'tron:0xcd8690dc',
|
||||
];
|
||||
|
||||
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
|
||||
@@ -113,6 +115,16 @@ export enum DEFAULT_ELROND_METHODS {
|
||||
|
||||
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 =
|
||||
"https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2";
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import { SolanaChainData } from "../chains/solana";
|
||||
import { PolkadotChainData } from "../chains/polkadot";
|
||||
import { ElrondChainData } from "../chains/elrond";
|
||||
import { TronChainData } from '../chains/tron';
|
||||
|
||||
import { ChainNamespaces, getAllChainNamespaces } from "../helpers";
|
||||
import { NearChainData } from "../chains/near";
|
||||
@@ -50,6 +51,8 @@ export function ChainDataContextProvider({
|
||||
chains = NearChainData;
|
||||
} else if (namespace === "elrond") {
|
||||
chains = ElrondChainData;
|
||||
} else if (namespace === 'tron') {
|
||||
chains = TronChainData;
|
||||
} else {
|
||||
chains = await apiGetChainNamespace(namespace);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
SystemProgram,
|
||||
Transaction as SolanaTransaction,
|
||||
} from "@solana/web3.js";
|
||||
// @ts-expect-error
|
||||
import TronWeb from 'tronweb';
|
||||
import {
|
||||
eip712,
|
||||
formatTestTransaction,
|
||||
@@ -32,6 +34,7 @@ import {
|
||||
DEFAULT_POLKADOT_METHODS,
|
||||
DEFAULT_NEAR_METHODS,
|
||||
DEFAULT_ELROND_METHODS,
|
||||
DEFAULT_TRON_METHODS,
|
||||
} from "../constants";
|
||||
import { useChainData } from "./ChainDataContext";
|
||||
import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto";
|
||||
@@ -90,6 +93,10 @@ interface IContext {
|
||||
testSignTransaction: TRpcRequestCallback;
|
||||
testSignTransactions: TRpcRequestCallback;
|
||||
};
|
||||
tronRpc: {
|
||||
testSignMessage: TRpcRequestCallback;
|
||||
testSignTransaction: TRpcRequestCallback;
|
||||
};
|
||||
rpcResult?: IFormattedRpcResponse | null;
|
||||
isRpcRequestPending: 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 (
|
||||
<JsonRpcContext.Provider
|
||||
value={{
|
||||
@@ -1059,6 +1154,7 @@ export function JsonRpcContextProvider({
|
||||
polkadotRpc,
|
||||
nearRpc,
|
||||
elrondRpc,
|
||||
tronRpc,
|
||||
rpcResult: result,
|
||||
isRpcRequestPending: pending,
|
||||
isTestnet,
|
||||
|
||||
@@ -12,6 +12,8 @@ import {
|
||||
DEFAULT_NEAR_EVENTS,
|
||||
DEFAULT_ELROND_EVENTS,
|
||||
DEFAULT_ELROND_METHODS,
|
||||
DEFAULT_TRON_METHODS,
|
||||
DEFAULT_TRON_EVENTS,
|
||||
} from "../constants";
|
||||
|
||||
export const getNamespacesFromChains = (chains: string[]) => {
|
||||
@@ -40,6 +42,8 @@ export const getSupportedMethodsByNamespace = (namespace: string) => {
|
||||
return Object.values(DEFAULT_NEAR_METHODS);
|
||||
case "elrond":
|
||||
return Object.values(DEFAULT_ELROND_METHODS);
|
||||
case 'tron':
|
||||
return Object.values(DEFAULT_TRON_METHODS);
|
||||
default:
|
||||
throw new Error(`No default methods for namespace: ${namespace}`);
|
||||
}
|
||||
@@ -59,6 +63,8 @@ export const getSupportedEventsByNamespace = (namespace: string) => {
|
||||
return Object.values(DEFAULT_NEAR_EVENTS);
|
||||
case "elrond":
|
||||
return Object.values(DEFAULT_ELROND_EVENTS);
|
||||
case "tron":
|
||||
return Object.values(DEFAULT_TRON_EVENTS);
|
||||
default:
|
||||
throw new Error(`No default events for namespace: ${namespace}`);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
DEFAULT_ELROND_METHODS,
|
||||
DEFAULT_TEST_CHAINS,
|
||||
DEFAULT_NEAR_METHODS,
|
||||
DEFAULT_TRON_METHODS,
|
||||
} from "../constants";
|
||||
import { AccountAction, setLocaleStorageTestnetFlag } from "../helpers";
|
||||
import Toggle from "../components/Toggle";
|
||||
@@ -73,6 +74,7 @@ const Home: NextPage = () => {
|
||||
polkadotRpc,
|
||||
nearRpc,
|
||||
elrondRpc,
|
||||
tronRpc,
|
||||
isRpcRequestPending,
|
||||
rpcResult,
|
||||
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 [namespace] = chainId.split(":");
|
||||
switch (namespace) {
|
||||
@@ -286,6 +309,8 @@ const Home: NextPage = () => {
|
||||
return getNearActions();
|
||||
case "elrond":
|
||||
return getElrondActions();
|
||||
case "tron":
|
||||
return getTronActions();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user