Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
5b633d4
feat: add Tron smart contracts and deployment infrastructure
rodrigopavezi Jan 26, 2026
6c4a209
fix: correct deployment output paths in Tron scripts
rodrigopavezi Jan 27, 2026
fe9ebd2
refactor: consolidate Tron files into standard folder structure
rodrigopavezi Jan 27, 2026
9c65732
refactor: move tron-build to build/tron for consistency
rodrigopavezi Jan 27, 2026
7b9597e
refactor: remove TronBox build artifacts from version control
rodrigopavezi Jan 27, 2026
c3bcd0c
fix: update paths in CI workflow, scripts, and docs for new folder st…
rodrigopavezi Jan 27, 2026
2ffeb39
refactor: use symlink for ERC20FeeProxy.sol in tron contracts
rodrigopavezi Jan 27, 2026
c127e2c
docs: add comment explaining intentional open mint in test contract
rodrigopavezi Jan 27, 2026
235fb87
fix: add TronChainName type to support Tron network deployments
rodrigopavezi Jan 27, 2026
6e7768d
fix: add TronChainName to ERC20Currency network type
rodrigopavezi Jan 27, 2026
72c27dd
fix: move tron contracts outside Hardhat sources to avoid conflicts
rodrigopavezi Jan 27, 2026
e0fe735
fix: increase timeouts for flaky request-client.js tests
rodrigopavezi Jan 27, 2026
b677718
fix: increase ETH balance test timeout to 120s
rodrigopavezi Jan 27, 2026
e70c9f7
fix: correct paths in Tron deployment scripts
rodrigopavezi Jan 27, 2026
51ca4ad
fix: ensure deployments directory exists before writing
rodrigopavezi Jan 27, 2026
892d5de
fix: increase timeouts for encrypted request tests to prevent CI fail…
rodrigopavezi Feb 11, 2026
fb04b23
fix: update native currency types and add Tron network support
rodrigopavezi Feb 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 210 additions & 0 deletions .github/workflows/tron-smart-contracts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
name: Tron Smart Contracts Tests

on:
pull_request:
branches:
- master
paths:
- 'packages/smart-contracts/tron/**'
- 'packages/smart-contracts/deployments/tron/**'
- 'packages/smart-contracts/migrations/tron/**'
- 'packages/smart-contracts/scripts/tron/**'
- 'packages/smart-contracts/test/tron/**'
- 'packages/smart-contracts/tronbox-config.js'
- 'packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/**'
- 'packages/payment-processor/src/payment/*tron*'
- 'packages/payment-processor/test/payment/*tron*'
- 'packages/currency/src/chains/tron/**'
- '.github/workflows/tron-smart-contracts.yml'
push:
branches:
- master
paths:
- 'packages/smart-contracts/tron/**'
- 'packages/smart-contracts/deployments/tron/**'
- 'packages/smart-contracts/migrations/tron/**'
- 'packages/smart-contracts/scripts/tron/**'
- 'packages/smart-contracts/test/tron/**'
- 'packages/smart-contracts/tronbox-config.js'
- 'packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/**'
- 'packages/payment-processor/src/payment/*tron*'
- 'packages/payment-processor/test/payment/*tron*'
- 'packages/currency/src/chains/tron/**'
workflow_dispatch:

jobs:
tron-compile-check:
name: Tron Contract Compilation Check
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'yarn'

- name: Install TronBox globally
run: npm install -g tronbox

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Compile Tron contracts
working-directory: packages/smart-contracts
run: yarn tron:compile

- name: Verify build artifacts exist
working-directory: packages/smart-contracts
run: |
echo "Checking build artifacts..."
ls -la build/tron/

# Verify key contracts were compiled
for contract in ERC20FeeProxy TestTRC20 BadTRC20 TRC20True TRC20NoReturn TRC20False TRC20Revert; do
if [ ! -f "build/tron/${contract}.json" ]; then
echo "ERROR: ${contract}.json not found!"
exit 1
fi
echo "✓ ${contract}.json exists"
done

echo "✅ All required artifacts present"

- name: Verify contract ABI structure
working-directory: packages/smart-contracts
run: |
echo "Verifying ERC20FeeProxy ABI..."

# Check that the compiled contract has the expected functions
for func in transferFromWithReferenceAndFee; do
if ! grep -q "$func" build/tron/ERC20FeeProxy.json; then
echo "ERROR: ERC20FeeProxy missing $func function!"
exit 1
fi
echo "✓ ERC20FeeProxy has $func"
done

# Verify TestTRC20 has standard ERC20 functions
for func in transfer approve transferFrom balanceOf allowance; do
if ! grep -q "$func" build/tron/TestTRC20.json; then
echo "ERROR: TestTRC20 missing $func function!"
exit 1
fi
echo "✓ TestTRC20 has $func"
done

echo "✅ Contract ABI structure verified"

- name: Verify deployment files are valid JSON
working-directory: packages/smart-contracts
run: |
echo "Validating deployment files..."

for network in nile mainnet; do
file="deployments/tron/${network}.json"
if [ -f "$file" ]; then
if ! python3 -m json.tool "$file" > /dev/null 2>&1; then
echo "ERROR: $file is not valid JSON!"
exit 1
fi

# Verify required fields
if ! grep -q '"ERC20FeeProxy"' "$file"; then
echo "ERROR: $file missing ERC20FeeProxy entry!"
exit 1
fi

if ! grep -q '"address"' "$file"; then
echo "ERROR: $file missing address field!"
exit 1
fi

echo "✓ $file is valid"
fi
done

echo "✅ Deployment files validated"

tron-payment-processor-tests:
name: Tron Payment Processor Unit Tests
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build dependencies
run: |
yarn workspace @requestnetwork/types build
yarn workspace @requestnetwork/utils build
yarn workspace @requestnetwork/currency build
yarn workspace @requestnetwork/smart-contracts build
yarn workspace @requestnetwork/payment-detection build

- name: Run Tron payment processor tests
working-directory: packages/payment-processor
run: yarn test -- --testPathPattern="tron" --passWithNoTests

tron-artifact-registry-check:
name: Tron Artifact Registry Check
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build smart-contracts package
run: |
yarn workspace @requestnetwork/types build
yarn workspace @requestnetwork/utils build
yarn workspace @requestnetwork/currency build
yarn workspace @requestnetwork/smart-contracts build

- name: Verify Tron addresses in artifact registry
run: |
echo "Checking Tron addresses in artifact registry..."

# Check that nile address is registered
if ! grep -q "THK5rNmrvCujhmrXa5DB1dASepwXTr9cJs" packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/index.ts; then
echo "ERROR: Nile testnet address not found in artifact registry!"
exit 1
fi
echo "✓ Nile address registered"

# Check that mainnet address is registered
if ! grep -q "TCUDPYnS9dH3WvFEaE7wN7vnDa51J4R4fd" packages/smart-contracts/src/lib/artifacts/ERC20FeeProxy/index.ts; then
echo "ERROR: Mainnet address not found in artifact registry!"
exit 1
fi
echo "✓ Mainnet address registered"

echo "✅ Tron addresses verified in artifact registry"

# Note: Full integration tests require a Tron node and are skipped in CI.
# Run integration tests locally with:
# docker run -d --name tron-tre -p 9090:9090 tronbox/tre # On ARM64 machine
# yarn tron:test
# Or run against Nile testnet:
# TRON_PRIVATE_KEY=your_key yarn tron:test:nile
2 changes: 0 additions & 2 deletions packages/currency/src/chains/declarative/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { CurrencyTypes } from '@requestnetwork/types';

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

export const chains: Record<CurrencyTypes.DeclarativeChainName, DeclarativeChain> = {
tron: TronDefinition,
solana: SolanaDefinition,
starknet: StarknetDefinition,
ton: TonDefinition,
Expand Down
3 changes: 2 additions & 1 deletion packages/currency/src/chains/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import BtcChains from './btc/BtcChains';
import EvmChains from './evm/EvmChains';
import NearChains from './near/NearChains';
import TronChains from './tron/TronChains';
import DeclarativeChains from './declarative/DeclarativeChains';
import { isSameChain } from './utils';

export { BtcChains, EvmChains, NearChains, DeclarativeChains, isSameChain };
export { BtcChains, EvmChains, NearChains, TronChains, DeclarativeChains, isSameChain };
6 changes: 6 additions & 0 deletions packages/currency/src/chains/tron/TronChains.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ChainsAbstract } from '../ChainsAbstract';
import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types';
import { TronChain, chains } from './index';

class TronChains extends ChainsAbstract<CurrencyTypes.TronChainName, TronChain, string> {}
export default new TronChains(chains, RequestLogicTypes.CURRENCY.ETH);
10 changes: 10 additions & 0 deletions packages/currency/src/chains/tron/data/nile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const chainId = 'nile';

// Nile is Tron's test network
export const testnet = true;

// Test tokens on Nile testnet
// Note: These are testnet token addresses, not mainnet
export const currencies = {
// Add testnet token addresses as needed
};
20 changes: 20 additions & 0 deletions packages/currency/src/chains/tron/data/tron.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const chainId = 'tron';

// Tron mainnet configuration
export const testnet = false;

// Common TRC20 tokens on Tron
export const currencies = {
// USDT-TRC20 - the most widely used stablecoin on Tron
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t: {
name: 'Tether USD',
symbol: 'USDT',
decimals: 6,
},
// USDC on Tron
TEkxiTehnzSmSe2XqrBj4w32RUN966rdz8: {
name: 'USD Coin',
symbol: 'USDC',
decimals: 6,
},
};
11 changes: 11 additions & 0 deletions packages/currency/src/chains/tron/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { CurrencyTypes } from '@requestnetwork/types';

import * as TronDefinition from './data/tron';
import * as NileDefinition from './data/nile';

export type TronChain = CurrencyTypes.Chain;

export const chains: Record<CurrencyTypes.TronChainName, TronChain> = {
tron: TronDefinition,
nile: NileDefinition,
};
14 changes: 13 additions & 1 deletion packages/currency/src/native.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CurrencyTypes, RequestLogicTypes } from '@requestnetwork/types';

type NativeEthCurrency = CurrencyTypes.NamedNativeCurrency & {
network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName;
network: CurrencyTypes.EvmChainName | CurrencyTypes.NearChainName | CurrencyTypes.TronChainName;
};
type NativeBtcCurrency = CurrencyTypes.NamedNativeCurrency & {
network: CurrencyTypes.BtcChainName;
Expand Down Expand Up @@ -178,6 +178,18 @@ export const nativeCurrencies: Record<RequestLogicTypes.CURRENCY.ETH, NativeEthC
name: '$S',
network: 'sonic',
},
{
symbol: 'TRX',
decimals: 6,
name: 'Tron',
network: 'tron',
},
{
symbol: 'TRX-nile',
decimals: 6,
name: 'Nile Tron',
network: 'nile',
},
],
[RequestLogicTypes.CURRENCY.BTC]: [
{
Expand Down
6 changes: 3 additions & 3 deletions packages/request-client.js/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,7 @@ describe('request-client.js', () => {

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

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

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

describe('ERC20 address based requests', () => {
Expand Down
Loading