// Import statements
import { DynamicTronWalletClient } from "@dynamic-labs-wallet/node-tron";
import { ThresholdSignatureScheme } from "@dynamic-labs-wallet/node";
import fs from "fs";
// Initialize TRON client
export const authenticatedTronClient = async () => {
const client = new DynamicTronWalletClient({
environmentId: process.env.DYNAMIC_ENVIRONMENT_ID!,
});
await client.authenticateApiToken(process.env.DYNAMIC_AUTH_TOKEN!);
return client;
};
// Example usage demonstrating all available functions
async function main() {
try {
console.log("Starting TRON Client Demo...\n");
// Initialize the TRON client
const tronClient = await authenticatedTronClient();
console.log("TRON client authenticated successfully\n");
// 1. Create a new TRON wallet
console.log("Creating new TRON wallet...");
const tronWallet = await tronClient.createWalletAccount({
thresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_TWO,
onError: (error: Error) => {
console.error("TRON wallet creation error:", error);
},
// Required when backing up to Dynamic — load from your secrets
// manager, never a hardcoded literal
password: process.env.TRON_WALLET_PASSWORD!,
backUpToDynamic: true,
});
const walletMetadata = tronWallet.walletMetadata;
console.log("TRON wallet created:", walletMetadata.accountAddress);
// Keep externalServerKeyShares out of logs — treat them like private key material.
console.log("rawPublicKey:", tronWallet.rawPublicKey);
// Save wallet metadata to file — keep externalServerKeyShares in a
// secrets vault rather than a plaintext file.
fs.writeFileSync("tronWallet.json", JSON.stringify(walletMetadata, null, 2));
console.log("Wallet saved to tronWallet.json\n");
// 2. Derive TRON address from public key (synchronous)
console.log("Deriving TRON address...");
try {
const { accountAddress } = tronClient.deriveAccountAddress({
rawPublicKey: tronWallet.rawPublicKey,
});
console.log("Derived address:", accountAddress);
} catch (error) {
console.log("Could not derive address:", error);
}
// 3. Get wallet information
console.log("\nGetting wallet details...");
try {
const walletDetails = await tronClient.getWalletByAddress(
walletMetadata.accountAddress
);
console.log("Wallet details retrieved:", walletDetails);
} catch (error) {
console.log("Could not retrieve wallet details:", error);
}
// 4. Get all TRON wallets
console.log("\nGetting all TRON wallets...");
try {
const allWallets = await tronClient.getTronWallets();
console.log("Found", allWallets.length, "TRON wallets");
} catch (error) {
console.log("Could not retrieve all wallets:", error);
}
// 5. Sign a message (TIP-191 / signMessageV2)
console.log("\nSigning a message...");
try {
const message = "Hello, TRON! This is a test message from Dynamic TRON wallet.";
const signedMessage = await tronClient.signMessage({
message,
walletMetadata,
password: process.env.TRON_WALLET_PASSWORD!,
});
console.log("Message signed successfully (hex)");
console.log("Signature:", signedMessage);
} catch (error) {
console.log("Message signing failed:", error instanceof Error ? error.message : String(error));
}
// 6. Sign a transaction (TRX transfer example)
console.log("\nPreparing TRON transaction...");
try {
// Build the unsigned transaction against a TRON full node
const unsignedResponse = await fetch(
"https://api.trongrid.io/wallet/createtransaction",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
owner_address: walletMetadata.accountAddress,
to_address: "RECIPIENT_TRON_ADDRESS",
amount: 1_000_000, // 1 TRX in SUN
visible: true,
}),
}
);
const unsignedTransaction = await unsignedResponse.json();
console.log("Transaction prepared, signing with TRON wallet...");
// Sign — returns the full transaction as broadcast-ready JSON
const signedTransaction = await tronClient.signTransaction({
walletMetadata,
password: process.env.TRON_WALLET_PASSWORD!,
transaction: unsignedTransaction,
});
console.log("Transaction signed successfully");
console.log("Signed transaction:", signedTransaction);
} catch (error) {
console.log("Transaction signing failed:", error instanceof Error ? error.message : String(error));
}
// 7. Import private key (if you have one)
console.log("\nTesting private key import...");
try {
const importedWallet = await tronClient.importPrivateKey({
privateKey: "your-private-key-here", // Replace with actual private key
thresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_TWO,
backUpToDynamic: true,
password: process.env.TRON_WALLET_PASSWORD!,
});
console.log("Private key imported:", importedWallet.walletMetadata.accountAddress);
} catch (error) {
console.log("Private key import skipped (no valid key provided)");
}
// 8. Export private key
console.log("\nExporting private key...");
try {
const privateKey = await tronClient.exportPrivateKey({
walletMetadata,
password: process.env.TRON_WALLET_PASSWORD!,
});
console.log("Private key exported (0x hex):", privateKey);
} catch (error) {
console.log("Key export not available or requires additional setup");
}
// 9. Offline export private key from key shares
console.log("\nOffline exporting private key...");
try {
if (tronWallet.externalServerKeyShares) {
const { derivedPrivateKey } = await tronClient.offlineExportPrivateKey({
keyShares: tronWallet.externalServerKeyShares,
});
console.log("Offline export successful:", derivedPrivateKey);
}
} catch (error) {
console.log("Offline export failed:", error instanceof Error ? error.message : String(error));
}
console.log("\nTRON Client Demo completed!");
} catch (error) {
console.error("Demo failed:", error instanceof Error ? error.message : String(error));
}
}
// Run the example
main().catch(console.error);