Skip to content

Commit 1c17897

Browse files
enesozturkclaude
andauthored
fix(tron): respect wallet tron_method_version for tron_signTransaction payload (#5694)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 32af290 commit 1c17897

3 files changed

Lines changed: 80 additions & 4 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
'@reown/appkit-utils': patch
3+
'@reown/appkit': patch
4+
'@reown/appkit-cdn': patch
5+
'@reown/appkit-cli': patch
6+
'@reown/appkit-codemod': patch
7+
'@reown/appkit-common': patch
8+
'@reown/appkit-core': patch
9+
'@reown/appkit-experimental': patch
10+
'@reown/appkit-pay': patch
11+
'@reown/appkit-polyfills': patch
12+
'@reown/appkit-scaffold-ui': patch
13+
'@reown/appkit-siwe': patch
14+
'@reown/appkit-siwx': patch
15+
'@reown/appkit-testing': patch
16+
'@reown/appkit-ui': patch
17+
'@reown/appkit-universal-connector': patch
18+
'@reown/appkit-wallet-button': patch
19+
'@reown/appkit-wallet': patch
20+
'@reown/appkit-controllers': patch
21+
'@reown/appkit-adapter-bitcoin': patch
22+
'@reown/appkit-adapter-ethers': patch
23+
'@reown/appkit-adapter-ethers5': patch
24+
'@reown/appkit-adapter-solana': patch
25+
'@reown/appkit-adapter-ton': patch
26+
'@reown/appkit-adapter-tron': patch
27+
'@reown/appkit-adapter-wagmi': patch
28+
---
29+
30+
Fixed TRON `tron_signTransaction` payload shape to respect the wallet's `tron_method_version` session property. The connector now sends the spec-mandated legacy nested `transaction.transaction` shape by default, and the simplified flat shape only when the wallet advertises `tron_method_version: "v1"` in `sessionProperties`.

packages/adapters/tron/src/connectors/TronWalletConnectConnector.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,17 @@ export class TronWalletConnectConnector
110110
throw new Error(unsignedTx?.Error || 'Failed to create transaction')
111111
}
112112

113-
// Step 2: Send full transaction to wallet for signing via WalletConnect
113+
// Step 2: Send full transaction to wallet for signing via WalletConnect.
114+
// Wallets opt into the simplified (v1) payload shape by advertising
115+
// `tron_method_version: "v1"` in sessionProperties during the handshake.
116+
// Otherwise the spec mandates the legacy nested `transaction.transaction` shape.
117+
// See https://docs.reown.com/advanced/multichain/rpc-reference/tron-rpc
118+
const usesV1Format = this.provider.session?.sessionProperties?.['tron_method_version'] === 'v1'
114119
const signRequest = {
115120
method: 'tron_signTransaction',
116121
params: {
117122
address: params.from,
118-
transaction: unsignedTx
123+
transaction: usesV1Format ? unsignedTx : { transaction: unsignedTx }
119124
}
120125
}
121126
const signedTx:

packages/adapters/tron/src/tests/TronWalletConnectConnector.test.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,14 @@ describe('TronWalletConnectConnector', () => {
146146
expect(createBody.method).toBe('tron_createTransaction')
147147
expect(createBody.params).toEqual([MOCK_OWNER_ADDRESS, MOCK_TO_ADDRESS, 1000000, true])
148148

149-
// Verify WC sign call with full transaction object
149+
// Verify WC sign call uses the legacy nested shape by default (wallet did not
150+
// advertise tron_method_version: "v1" in sessionProperties)
150151
expect(mockProviderRequest).toHaveBeenCalledWith(
151152
{
152153
method: 'tron_signTransaction',
153154
params: {
154155
address: MOCK_OWNER_ADDRESS,
155-
transaction: MOCK_UNSIGNED_TX
156+
transaction: { transaction: MOCK_UNSIGNED_TX }
156157
}
157158
},
158159
MOCK_CHAIN_ID
@@ -167,6 +168,46 @@ describe('TronWalletConnectConnector', () => {
167168
expect(broadcastBody.params[4]).toEqual(MOCK_SIGNED_TX.signature)
168169
})
169170

171+
it('should send the flat (v1) transaction shape when wallet advertises tron_method_version v1', async () => {
172+
const v1Provider = {
173+
...mockProvider,
174+
session: {
175+
...mockProvider.session,
176+
sessionProperties: { tron_method_version: 'v1' }
177+
}
178+
}
179+
const v1Connector = new TronWalletConnectConnector({
180+
provider: v1Provider as any,
181+
chains: [MOCK_CAIP_NETWORK as any]
182+
})
183+
184+
mockFetch.mockResolvedValueOnce({
185+
json: () => Promise.resolve({ result: MOCK_UNSIGNED_TX })
186+
})
187+
mockProviderRequest.mockResolvedValueOnce(MOCK_SIGNED_TX)
188+
mockFetch.mockResolvedValueOnce({
189+
json: () => Promise.resolve({ result: { result: true } })
190+
})
191+
192+
await v1Connector.sendTransaction({
193+
from: MOCK_OWNER_ADDRESS,
194+
to: MOCK_TO_ADDRESS,
195+
value: '1000000'
196+
})
197+
198+
// v1 wallets receive the flat transaction object (no nested wrapper)
199+
expect(mockProviderRequest).toHaveBeenCalledWith(
200+
{
201+
method: 'tron_signTransaction',
202+
params: {
203+
address: MOCK_OWNER_ADDRESS,
204+
transaction: MOCK_UNSIGNED_TX
205+
}
206+
},
207+
MOCK_CHAIN_ID
208+
)
209+
})
210+
170211
it('should throw when createTransaction fails', async () => {
171212
mockFetch.mockResolvedValueOnce({
172213
json: () =>

0 commit comments

Comments
 (0)