Skip to content

Commit db654fa

Browse files
feat: add Tron smart contracts and deployment infrastructure (#1687)
## Add Tron blockchain support with smart contract deployment and testing This PR adds comprehensive support for the Tron blockchain to the Request Network protocol, including: - Implementation of TRC20 token support in the currency package - Deployment of the ERC20FeeProxy contract on Tron mainnet and Nile testnet - Comprehensive test suite for Tron smart contracts - Deployment scripts and verification utilities - GitHub Actions workflow for CI/CD automation The implementation moves Tron from a declarative chain to a fully supported VM chain with smart contract capabilities, enabling payment requests with TRC20 tokens like USDT and USDC. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Tron support: deploy, verify and interact with contracts on Nile testnet and mainnet; TRC20 test tokens and ERC20FeeProxy integrated; Tron added to currency/chains/types surface. * **Documentation** * Comprehensive Tron deployment and testing guide added. * **Chores** * CI workflow for Tron pipelines added; CLI scripts and automation for compile/migrate/deploy/verify/wallet/setup/test-token flows; TronWeb tooling included. * **Tests** * End-to-end Tron test suite validating proxy and various token behaviors. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- Closes RequestNetwork/private-issues#222 Closes RequestNetwork/private-issues#230 Closes RequestNetwork/private-issues#231 Closes RequestNetwork/private-issues#232
1 parent a5d6a48 commit db654fa

29 files changed

Lines changed: 2541 additions & 13 deletions

File tree

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
name: Tron Smart Contracts Tests
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- master
7+
paths:
8+
- 'packages/smart-contracts/tron/**'
9+
- 'packages/smart-contracts/deployments/tron/**'
10+
- 'packages/smart-contracts/migrations/tron/**'
11+
- 'packages/smart-contracts/scripts/tron/**'
12+
- 'packages/smart-contracts/test/tron/**'
13+
- 'packages/smart-contracts/tronbox-config.js'
14+
- 'packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/**'
15+
- 'packages/payment-processor/src/payment/*tron*'
16+
- 'packages/payment-processor/test/payment/*tron*'
17+
- 'packages/currency/src/chains/tron/**'
18+
- '.github/workflows/tron-smart-contracts.yml'
19+
push:
20+
branches:
21+
- master
22+
paths:
23+
- 'packages/smart-contracts/tron/**'
24+
- 'packages/smart-contracts/deployments/tron/**'
25+
- 'packages/smart-contracts/migrations/tron/**'
26+
- 'packages/smart-contracts/scripts/tron/**'
27+
- 'packages/smart-contracts/test/tron/**'
28+
- 'packages/smart-contracts/tronbox-config.js'
29+
- 'packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/**'
30+
- 'packages/payment-processor/src/payment/*tron*'
31+
- 'packages/payment-processor/test/payment/*tron*'
32+
- 'packages/currency/src/chains/tron/**'
33+
workflow_dispatch:
34+
35+
jobs:
36+
tron-compile-check:
37+
name: Tron Contract Compilation Check
38+
runs-on: ubuntu-latest
39+
40+
steps:
41+
- name: Checkout repository
42+
uses: actions/checkout@v4
43+
44+
- name: Setup Node.js
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: '22'
48+
cache: 'yarn'
49+
50+
- name: Install TronBox globally
51+
run: npm install -g tronbox
52+
53+
- name: Install dependencies
54+
run: yarn install --frozen-lockfile
55+
56+
- name: Compile Tron contracts
57+
working-directory: packages/smart-contracts
58+
run: yarn tron:compile
59+
60+
- name: Verify build artifacts exist
61+
working-directory: packages/smart-contracts
62+
run: |
63+
echo "Checking build artifacts..."
64+
ls -la build/tron/
65+
66+
# Verify key contracts were compiled
67+
for contract in ERC20FeeProxy TestTRC20 BadTRC20 TRC20True TRC20NoReturn TRC20False TRC20Revert; do
68+
if [ ! -f "build/tron/${contract}.json" ]; then
69+
echo "ERROR: ${contract}.json not found!"
70+
exit 1
71+
fi
72+
echo "✓ ${contract}.json exists"
73+
done
74+
75+
echo "✅ All required artifacts present"
76+
77+
- name: Verify contract ABI structure
78+
working-directory: packages/smart-contracts
79+
run: |
80+
echo "Verifying ERC20FeeProxy ABI..."
81+
82+
# Check that the compiled contract has the expected functions
83+
for func in transferFromWithReferenceAndFee; do
84+
if ! grep -q "$func" build/tron/ERC20FeeProxy.json; then
85+
echo "ERROR: ERC20FeeProxy missing $func function!"
86+
exit 1
87+
fi
88+
echo "✓ ERC20FeeProxy has $func"
89+
done
90+
91+
# Verify TestTRC20 has standard ERC20 functions
92+
for func in transfer approve transferFrom balanceOf allowance; do
93+
if ! grep -q "$func" build/tron/TestTRC20.json; then
94+
echo "ERROR: TestTRC20 missing $func function!"
95+
exit 1
96+
fi
97+
echo "✓ TestTRC20 has $func"
98+
done
99+
100+
echo "✅ Contract ABI structure verified"
101+
102+
- name: Verify deployment files are valid JSON
103+
working-directory: packages/smart-contracts
104+
run: |
105+
echo "Validating deployment files..."
106+
107+
for network in nile mainnet; do
108+
file="deployments/tron/${network}.json"
109+
if [ -f "$file" ]; then
110+
if ! python3 -m json.tool "$file" > /dev/null 2>&1; then
111+
echo "ERROR: $file is not valid JSON!"
112+
exit 1
113+
fi
114+
115+
# Verify required fields
116+
if ! grep -q '"ERC20FeeProxy"' "$file"; then
117+
echo "ERROR: $file missing ERC20FeeProxy entry!"
118+
exit 1
119+
fi
120+
121+
if ! grep -q '"address"' "$file"; then
122+
echo "ERROR: $file missing address field!"
123+
exit 1
124+
fi
125+
126+
echo "✓ $file is valid"
127+
fi
128+
done
129+
130+
echo "✅ Deployment files validated"
131+
132+
tron-payment-processor-tests:
133+
name: Tron Payment Processor Unit Tests
134+
runs-on: ubuntu-latest
135+
136+
steps:
137+
- name: Checkout repository
138+
uses: actions/checkout@v4
139+
140+
- name: Setup Node.js
141+
uses: actions/setup-node@v4
142+
with:
143+
node-version: '22'
144+
cache: 'yarn'
145+
146+
- name: Install dependencies
147+
run: yarn install --frozen-lockfile
148+
149+
- name: Build dependencies
150+
run: |
151+
yarn workspace @requestnetwork/types build
152+
yarn workspace @requestnetwork/utils build
153+
yarn workspace @requestnetwork/currency build
154+
yarn workspace @requestnetwork/smart-contracts build
155+
yarn workspace @requestnetwork/payment-detection build
156+
157+
- name: Run Tron payment processor tests
158+
working-directory: packages/payment-processor
159+
run: yarn test -- --testPathPattern="tron" --passWithNoTests
160+
161+
tron-artifact-registry-check:
162+
name: Tron Artifact Registry Check
163+
runs-on: ubuntu-latest
164+
165+
steps:
166+
- name: Checkout repository
167+
uses: actions/checkout@v4
168+
169+
- name: Setup Node.js
170+
uses: actions/setup-node@v4
171+
with:
172+
node-version: '22'
173+
cache: 'yarn'
174+
175+
- name: Install dependencies
176+
run: yarn install --frozen-lockfile
177+
178+
- name: Build smart-contracts package
179+
run: |
180+
yarn workspace @requestnetwork/types build
181+
yarn workspace @requestnetwork/utils build
182+
yarn workspace @requestnetwork/currency build
183+
yarn workspace @requestnetwork/smart-contracts build
184+
185+
- name: Verify Tron addresses in artifact registry
186+
run: |
187+
echo "Checking Tron addresses in artifact registry..."
188+
189+
# Check that nile address is registered
190+
if ! grep -q "THK5rNmrvCujhmrXa5DB1dASepwXTr9cJs" packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/index.ts; then
191+
echo "ERROR: Nile testnet address not found in artifact registry!"
192+
exit 1
193+
fi
194+
echo "✓ Nile address registered"
195+
196+
# Check that mainnet address is registered
197+
if ! grep -q "TCUDPYnS9dH3WvFEaE7wN7vnDa51J4R4fd" packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/index.ts; then
198+
echo "ERROR: Mainnet address not found in artifact registry!"
199+
exit 1
200+
fi
201+
echo "✓ Mainnet address registered"
202+
203+
echo "✅ Tron addresses verified in artifact registry"
204+
205+
# Note: Full integration tests require a Tron node and are skipped in CI.
206+
# Run integration tests locally with:
207+
# docker run -d --name tron-tre -p 9090:9090 tronbox/tre # On ARM64 machine
208+
# yarn tron:test
209+
# Or run against Nile testnet:
210+
# TRON_PRIVATE_KEY=your_key yarn tron:test:nile

packages/currency/src/chains/declarative/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { CurrencyTypes } from '@requestnetwork/types';
22

3-
import * as TronDefinition from './data/tron';
43
import * as SolanaDefinition from './data/solana';
54
import * as StarknetDefinition from './data/starknet';
65
import * as TonDefinition from './data/ton';
@@ -10,7 +9,6 @@ import * as SuiDefinition from './data/sui';
109
export type DeclarativeChain = CurrencyTypes.Chain;
1110

1211
export const chains: Record<CurrencyTypes.DeclarativeChainName, DeclarativeChain> = {
13-
tron: TronDefinition,
1412
solana: SolanaDefinition,
1513
starknet: StarknetDefinition,
1614
ton: TonDefinition,
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import BtcChains from './btc/BtcChains';
22
import EvmChains from './evm/EvmChains';
33
import NearChains from './near/NearChains';
4+
import TronChains from './tron/TronChains';
45
import DeclarativeChains from './declarative/DeclarativeChains';
56
import { isSameChain } from './utils';
67

7-
export { BtcChains, EvmChains, NearChains, DeclarativeChains, isSameChain };
8+
export { BtcChains, EvmChains, NearChains, TronChains, DeclarativeChains, isSameChain };
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { ChainsAbstract } from '../ChainsAbstract';
2+
import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types';
3+
import { TronChain, chains } from './index';
4+
5+
class TronChains extends ChainsAbstract<CurrencyTypes.TronChainName, TronChain, string> {}
6+
export default new TronChains(chains, RequestLogicTypes.CURRENCY.ETH);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export const chainId = 'nile';
2+
3+
// Nile is Tron's test network
4+
export const testnet = true;
5+
6+
// Test tokens on Nile testnet
7+
// Note: These are testnet token addresses, not mainnet
8+
export const currencies = {
9+
// Add testnet token addresses as needed
10+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export const chainId = 'tron';
2+
3+
// Tron mainnet configuration
4+
export const testnet = false;
5+
6+
// Common TRC20 tokens on Tron
7+
export const currencies = {
8+
// USDT-TRC20 - the most widely used stablecoin on Tron
9+
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t: {
10+
name: 'Tether USD',
11+
symbol: 'USDT',
12+
decimals: 6,
13+
},
14+
// USDC on Tron
15+
TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8: {
16+
name: 'USD Coin',
17+
symbol: 'USDC',
18+
decimals: 6,
19+
},
20+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { CurrencyTypes } from '@requestnetwork/types';
2+
3+
import * as TronDefinition from './data/tron';
4+
import * as NileDefinition from './data/nile';
5+
6+
export type TronChain = CurrencyTypes.Chain;
7+
8+
export const chains: Record<CurrencyTypes.TronChainName, TronChain> = {
9+
tron: TronDefinition,
10+
nile: NileDefinition,
11+
};

packages/currency/src/native.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types';
22

33
type NativeEthCurrency = CurrencyTypes.NamedNativeCurrency & {
4-
network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName;
4+
network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName | CurrencyTypes.TronChainName;
55
};
66
type NativeBtcCurrency = CurrencyTypes.NamedNativeCurrency & {
77
network: CurrencyTypes.BtcChainName;
@@ -178,6 +178,18 @@ export const nativeCurrencies: Record<RequestLogicTypes.CURRENCY.ETH, NativeEthC
178178
name: '$S',
179179
network: 'sonic',
180180
},
181+
{
182+
symbol: 'TRX',
183+
decimals: 6,
184+
name: 'Tron',
185+
network: 'tron',
186+
},
187+
{
188+
symbol: 'TRX-nile',
189+
decimals: 6,
190+
name: 'Nile Tron',
191+
network: 'nile',
192+
},
181193
],
182194
[RequestLogicTypes.CURRENCY.BTC]: [
183195
{

packages/request-client.js/test/index.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ describe('request-client.js', () => {
946946

947947
expect(requestData.meta).not.toBeNull();
948948
expect(requestData.meta!.transactionManagerMeta.encryptionMethod).toBe('ecies-aes256-gcm');
949-
});
949+
}, 60000); // Increased from default – encrypted request creation + storage can be slow in CI
950950

951951
it('creates an encrypted request and accept it', async () => {
952952
const requestNetwork = new RequestNetwork({
@@ -1348,7 +1348,7 @@ describe('request-client.js', () => {
13481348
expect(dataAfterRefresh.balance?.events[0].parameters!.txHash).toBe(
13491349
'0x06d95c3889dcd974106e82fa27358549d9392d6fee6ea14fe1acedadc1013114',
13501350
);
1351-
});
1351+
}, 120000); // Increased from default – mock storage + payment detection can be slow in CI
13521352

13531353
it('can disable and enable the get the balance of a request', async () => {
13541354
const etherscanMock = new EtherscanProviderMock();
@@ -1506,7 +1506,7 @@ describe('request-client.js', () => {
15061506
expect(dataAfterRefresh.balance?.events[0].parameters!.txHash).toBe(
15071507
'0x06d95c3889dcd974106e82fa27358549d9392d6fee6ea14fe1acedadc1013114',
15081508
);
1509-
}, 180000);
1509+
}, 180000); // Increased from 60s – skipped-detection refresh path is slower; prevents flaky CI failures
15101510
});
15111511

15121512
describe('ERC20 address based requests', () => {

0 commit comments

Comments
 (0)