Skip to content

Commit 5852474

Browse files
author
iGroza
committed
feat: add tron support for SSS and HOT providers
1 parent 01c7803 commit 5852474

File tree

10 files changed

+263
-36
lines changed

10 files changed

+263
-36
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@haqq/rn-wallet-providers",
3-
"version": "0.0.8",
3+
"version": "0.0.9",
44
"description": "React Native providers for Haqq wallet",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ import * as constants from './constants';
22
import * as providers from './providers';
33
import * as utils from './utils';
44

5-
export {providers, utils, constants};
5+
export {constants, providers, utils};
66

77
export * from './providers';

src/providers/hot/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './evm-provider';
2+
export * from './tron-provider';
23
export * from './provider';
34
export * from './types';

src/providers/hot/tron-provider.ts

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import {accountInfo} from '@haqq/provider-web3-utils';
2+
import tron from 'tronweb';
3+
4+
import {ProviderHotBase} from './provider';
5+
import {ProviderHotTronOptions} from './types';
6+
7+
import {compressPublicKey} from '../../utils';
8+
import {getPrivateKey} from '../../utils/hot/get-private-key';
9+
import {
10+
BytesLike,
11+
ProviderInterface,
12+
TransactionRequest,
13+
TypedData,
14+
} from '../types';
15+
16+
export class ProviderHotTron
17+
extends ProviderHotBase
18+
implements ProviderInterface
19+
{
20+
private _tronWebHostUrl: string;
21+
constructor(options: ProviderHotTronOptions) {
22+
super(options);
23+
this._tronWebHostUrl = options.tronWebHostUrl;
24+
}
25+
26+
/* hd path ignore for hot wallet */
27+
async getAccountInfo(_hdPath: string) {
28+
const {share: privateKey} = await getPrivateKey(
29+
this._options.account,
30+
this._options.getPassword,
31+
);
32+
33+
if (!privateKey) {
34+
throw new Error('private_key_not_found');
35+
}
36+
37+
const account = await accountInfo(privateKey);
38+
39+
return {
40+
publicKey: compressPublicKey(account.publicKey),
41+
address: tron.utils.address.fromHex(account.address),
42+
};
43+
}
44+
45+
async signTransaction(
46+
_hdPath: string,
47+
transaction: TransactionRequest,
48+
): Promise<string> {
49+
let resp = '';
50+
try {
51+
const {share: privateKey} = await getPrivateKey(
52+
this._options.account,
53+
this._options.getPassword,
54+
);
55+
56+
if (!privateKey) {
57+
throw new Error('private_key_not_found');
58+
}
59+
60+
const tronWeb = new tron.TronWeb({
61+
fullHost: this._tronWebHostUrl,
62+
privateKey,
63+
});
64+
65+
// Convert Ethereum-style transaction to Tron transaction
66+
const tronTransaction = {
67+
to_address: tron.utils.address.isAddress(transaction.to)
68+
? transaction.to
69+
: tron.utils.address.fromHex(transaction.to),
70+
owner_address: tron.utils.crypto.pkToAddress(privateKey),
71+
amount: tron.TronWeb.toSun(
72+
Number(transaction.value),
73+
) as unknown as number,
74+
};
75+
76+
// Get the signature
77+
const tx = await tronWeb.transactionBuilder.sendTrx(
78+
tronTransaction.to_address,
79+
tronTransaction.amount,
80+
tronTransaction.owner_address,
81+
);
82+
83+
const signedTx = await tronWeb.trx.signTransaction(tx);
84+
resp = signedTx.signature[0];
85+
86+
this.emit('signTransaction', true);
87+
} catch (e) {
88+
if (e instanceof Error) {
89+
this.catchError(e, 'signTransaction');
90+
}
91+
}
92+
93+
return resp;
94+
}
95+
96+
async signPersonalMessage(
97+
_hdPath: string,
98+
_message: BytesLike | string,
99+
): Promise<string> {
100+
throw new Error(' signPersonalMessage not implemented');
101+
}
102+
103+
async signTypedData(_hdPath: string, _typedData: TypedData): Promise<string> {
104+
try {
105+
throw new Error(
106+
"Tron blockchain doesn't support signTypedData medthods.",
107+
);
108+
} catch (e) {
109+
this.catchError(e, 'signTypedData');
110+
} finally {
111+
return '';
112+
}
113+
}
114+
}

src/providers/hot/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ export type ProviderHotBaseOptions = {
22
account: string;
33
getPassword: () => Promise<string>;
44
};
5+
6+
export type ProviderHotTronOptions = ProviderHotBaseOptions & {
7+
tronWebHostUrl: string;
8+
};

src/providers/mnemonic/tron-provider.ts

+1-24
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
/* eslint-disable no-console */
21
import {accountInfo, derive} from '@haqq/provider-web3-utils';
32
import tron from 'tronweb';
43

54
import {ProviderMnemonicBase} from './provider';
65
import {ProviderMnemonicTronOptions} from './types';
76

7+
import {compressPublicKey} from '../../utils';
88
import {getMnemonic} from '../../utils/mnemonic/get-mnemonic';
99
import {
1010
BytesLike,
1111
ProviderInterface,
1212
TransactionRequest,
1313
TypedData,
1414
} from '../types';
15-
import { compressPublicKey } from '../../utils';
1615

1716
export class ProviderMnemonicTron
1817
extends ProviderMnemonicBase
@@ -24,24 +23,6 @@ export class ProviderMnemonicTron
2423
this._tronWebHostUrl = options.tronWebHostUrl;
2524
}
2625

27-
static async initialize(
28-
mnemonic: string | null,
29-
getPassword: () => Promise<string>,
30-
options: Omit<ProviderMnemonicTronOptions, 'getPassword'>,
31-
): Promise<ProviderMnemonicTron> {
32-
const base = await ProviderMnemonicBase.initialize(
33-
mnemonic,
34-
getPassword,
35-
options,
36-
);
37-
38-
return new ProviderMnemonicTron({
39-
...options,
40-
getPassword,
41-
account: base._options.account,
42-
});
43-
}
44-
4526
async getAccountInfo(hdPath: string) {
4627
const share = await getMnemonic(
4728
this._options.account,
@@ -60,10 +41,6 @@ export class ProviderMnemonicTron
6041
}
6142

6243
const account = await accountInfo(ethPrivateKey);
63-
console.log('ethPrivateKey', ethPrivateKey);
64-
console.log('account', account);
65-
66-
6744
return {
6845
publicKey: compressPublicKey(account.publicKey),
6946
address: tron.utils.address.fromHex(account.address),

src/providers/sss/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './evm-provider';
2+
export * from './tron-provider';
23
export * from './provider';
34
export * from './types';

src/providers/sss/provider.ts

+2-10
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,14 @@ import EncryptedStorage from 'react-native-encrypted-storage';
1414
import {ProviderSSSBaseOptions, StorageInterface} from './types';
1515

1616
import {ITEM_KEYS, WalletType} from '../../constants';
17-
import {Multichain} from '../../services/multichain';
1817
import {
1918
Polynomial,
2019
compressPublicKey,
21-
convertHdPath,
2220
getSeed,
2321
lagrangeInterpolation,
2422
} from '../../utils';
2523
import {ProviderBase} from '../base-provider';
26-
import {NETWORK_TYPE, ProviderBaseOptions, ProviderInterface} from '../types';
24+
import {ProviderBaseOptions, ProviderInterface} from '../types';
2725

2826
export class ProviderSSSBase
2927
extends ProviderBase<ProviderSSSBaseOptions>
@@ -246,7 +244,7 @@ export class ProviderSSSBase
246244
}
247245

248246
async getAccountInfo(hdPath: string) {
249-
let resp = {publicKey: '', address: '', tronAddress: ''};
247+
let resp = {publicKey: '', address: ''};
250248
try {
251249
const {seed} = await getSeed(
252250
this._options.account,
@@ -265,16 +263,10 @@ export class ProviderSSSBase
265263
}
266264

267265
const account = await accountInfo(privateKey);
268-
const tronAddress = await Multichain.generateAddress(
269-
NETWORK_TYPE.TRON,
270-
convertHdPath(hdPath, NETWORK_TYPE.TRON),
271-
await this.getMnemonicPhrase(),
272-
);
273266

274267
resp = {
275268
publicKey: compressPublicKey(account.publicKey),
276269
address: account.address,
277-
tronAddress,
278270
};
279271
this.emit('getPublicKeyForHDPath', true);
280272
} catch (e) {

src/providers/sss/tron-provider.ts

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import {accountInfo, derive} from '@haqq/provider-web3-utils';
2+
import tron from 'tronweb';
3+
4+
import {ProviderSSSBase} from './provider';
5+
import {ProviderSSSTronOptions} from './types';
6+
7+
import {compressPublicKey, getSeed} from '../../utils';
8+
import {
9+
BytesLike,
10+
ProviderInterface,
11+
TransactionRequest,
12+
TypedData,
13+
} from '../types';
14+
15+
export class ProviderSSSTron
16+
extends ProviderSSSBase
17+
implements ProviderInterface
18+
{
19+
private _tronWebHostUrl: string;
20+
constructor(options: ProviderSSSTronOptions) {
21+
super(options);
22+
this._tronWebHostUrl = options.tronWebHostUrl;
23+
}
24+
25+
async getAccountInfo(hdPath: string) {
26+
let resp = {publicKey: '', address: ''};
27+
try {
28+
const {seed} = await getSeed(
29+
this._options.account,
30+
this._options.storage,
31+
this._options.getPassword,
32+
);
33+
34+
if (!seed) {
35+
throw new Error('seed_not_found');
36+
}
37+
38+
const privateKey = await derive(seed, hdPath);
39+
40+
if (!privateKey) {
41+
throw new Error('private_key_not_found');
42+
}
43+
44+
const account = await accountInfo(privateKey);
45+
46+
resp = {
47+
publicKey: compressPublicKey(account.publicKey),
48+
address: tron.utils.address.fromHex(account.address),
49+
};
50+
this.emit('getPublicKeyForHDPath', true);
51+
} catch (e) {
52+
if (e instanceof Error) {
53+
this.catchError(e, 'getPublicKeyForHDPath');
54+
}
55+
}
56+
return resp;
57+
}
58+
59+
async signTransaction(
60+
hdPath: string,
61+
transaction: TransactionRequest,
62+
): Promise<string> {
63+
let resp = '';
64+
try {
65+
const {seed} = await getSeed(
66+
this._options.account,
67+
this._options.storage,
68+
this._options.getPassword,
69+
);
70+
71+
if (!seed) {
72+
throw new Error('seed_not_found');
73+
}
74+
75+
const privateKey = (await derive(seed, hdPath)).replace(/^0x/, '');
76+
77+
if (!privateKey) {
78+
throw new Error('private_key_not_found');
79+
}
80+
81+
const tronWeb = new tron.TronWeb({
82+
fullHost: this._tronWebHostUrl,
83+
privateKey,
84+
});
85+
86+
// Convert Ethereum-style transaction to Tron transaction
87+
const tronTransaction = {
88+
to_address: tron.utils.address.isAddress(transaction.to)
89+
? transaction.to
90+
: tron.utils.address.fromHex(transaction.to),
91+
owner_address: tron.utils.crypto.pkToAddress(privateKey),
92+
amount: tron.TronWeb.toSun(
93+
Number(transaction.value),
94+
) as unknown as number,
95+
};
96+
97+
// Get the signature
98+
const tx = await tronWeb.transactionBuilder.sendTrx(
99+
tronTransaction.to_address,
100+
tronTransaction.amount,
101+
tronTransaction.owner_address,
102+
);
103+
104+
const signedTx = await tronWeb.trx.signTransaction(tx);
105+
resp = signedTx.signature[0];
106+
107+
this.emit('signTransaction', true);
108+
} catch (e) {
109+
if (e instanceof Error) {
110+
this.catchError(e, 'signTransaction');
111+
}
112+
}
113+
return resp;
114+
}
115+
116+
async signPersonalMessage(
117+
_hdPath: string,
118+
_message: BytesLike | string,
119+
): Promise<string> {
120+
throw new Error(' signPersonalMessage not implemented');
121+
}
122+
123+
async signTypedData(_hdPath: string, _typedData: TypedData): Promise<string> {
124+
try {
125+
throw new Error(
126+
"Tron blockchain doesn't support signTypedData medthods.",
127+
);
128+
} catch (e) {
129+
this.catchError(e, 'signTypedData');
130+
} finally {
131+
return '';
132+
}
133+
}
134+
}

src/providers/sss/types.ts

+4
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ export type ShareEncrypted = {
2828
polynomialID: string;
2929
publicShare: string;
3030
};
31+
32+
export type ProviderSSSTronOptions = ProviderSSSBaseOptions & {
33+
tronWebHostUrl: string;
34+
};

0 commit comments

Comments
 (0)