@unicitylabs/bridge-plugin 0.2.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEMO.md +255 -0
- package/README.md +89 -0
- package/lib/BridgeLockJustification.d.ts +31 -0
- package/lib/BridgeLockJustification.js +41 -0
- package/lib/BridgeMintJustificationVerifier.d.ts +12 -0
- package/lib/BridgeMintJustificationVerifier.js +35 -0
- package/lib/LockMintJustificationVerifier.d.ts +42 -0
- package/lib/LockMintJustificationVerifier.js +108 -0
- package/lib/address.d.ts +13 -0
- package/lib/address.js +71 -0
- package/lib/bridge-back/abi.d.ts +30 -0
- package/lib/bridge-back/abi.js +89 -0
- package/lib/bridge-back/burn.d.ts +79 -0
- package/lib/bridge-back/burn.js +78 -0
- package/lib/bridge-back/burned-blob.d.ts +6 -0
- package/lib/bridge-back/burned-blob.js +16 -0
- package/lib/bridge-back/cbor.d.ts +32 -0
- package/lib/bridge-back/cbor.js +146 -0
- package/lib/bridge-back/derivations.d.ts +112 -0
- package/lib/bridge-back/derivations.js +201 -0
- package/lib/bridge-back/index.d.ts +11 -0
- package/lib/bridge-back/index.js +11 -0
- package/lib/cli/main.d.ts +2 -0
- package/lib/cli/main.js +149 -0
- package/lib/cli/scenario.d.ts +36 -0
- package/lib/cli/scenario.js +94 -0
- package/lib/config.d.ts +25 -0
- package/lib/config.js +1 -0
- package/lib/contract-call.d.ts +13 -0
- package/lib/contract-call.js +19 -0
- package/lib/evm/EvmRpcClient.d.ts +25 -0
- package/lib/evm/EvmRpcClient.js +54 -0
- package/lib/evm/config.d.ts +6 -0
- package/lib/evm/config.js +6 -0
- package/lib/evm/family.d.ts +3 -0
- package/lib/evm/family.js +21 -0
- package/lib/evm/index.d.ts +6 -0
- package/lib/evm/index.js +6 -0
- package/lib/evm/presentation.d.ts +4 -0
- package/lib/evm/presentation.js +21 -0
- package/lib/evm/providers.d.ts +3 -0
- package/lib/evm/providers.js +9 -0
- package/lib/evm/signer.d.ts +43 -0
- package/lib/evm/signer.js +91 -0
- package/lib/families.d.ts +4 -0
- package/lib/families.js +11 -0
- package/lib/family.d.ts +16 -0
- package/lib/family.js +1 -0
- package/lib/hex.d.ts +4 -0
- package/lib/hex.js +33 -0
- package/lib/identifiers.d.ts +14 -0
- package/lib/identifiers.js +22 -0
- package/lib/index.d.ts +48 -0
- package/lib/index.js +55 -0
- package/lib/lock-event.d.ts +28 -0
- package/lib/lock-event.js +48 -0
- package/lib/source-chain.d.ts +29 -0
- package/lib/source-chain.js +1 -0
- package/lib/tron/TronRpcClient.d.ts +39 -0
- package/lib/tron/TronRpcClient.js +100 -0
- package/lib/tron/config.d.ts +11 -0
- package/lib/tron/config.js +31 -0
- package/lib/tron/family.d.ts +4 -0
- package/lib/tron/family.js +18 -0
- package/lib/tron/presentation.d.ts +10 -0
- package/lib/tron/presentation.js +18 -0
- package/lib/tron/providers.d.ts +46 -0
- package/lib/tron/providers.js +32 -0
- package/lib/tron/signer.d.ts +166 -0
- package/lib/tron/signer.js +238 -0
- package/lib/value.d.ts +23 -0
- package/lib/value.js +58 -0
- package/lib/wallet/allowance.d.ts +20 -0
- package/lib/wallet/allowance.js +27 -0
- package/lib/wallet/backing.d.ts +2 -0
- package/lib/wallet/backing.js +15 -0
- package/lib/wallet/facade.d.ts +97 -0
- package/lib/wallet/facade.js +100 -0
- package/lib/wallet/finality.d.ts +8 -0
- package/lib/wallet/finality.js +28 -0
- package/lib/wallet/index.d.ts +25 -0
- package/lib/wallet/index.js +25 -0
- package/lib/wallet/manifest.d.ts +69 -0
- package/lib/wallet/manifest.js +81 -0
- package/lib/wallet/manifests.d.ts +31 -0
- package/lib/wallet/manifests.js +70 -0
- package/lib/wallet/payout.d.ts +5 -0
- package/lib/wallet/payout.js +14 -0
- package/lib/wallet/registry.d.ts +40 -0
- package/lib/wallet/registry.js +34 -0
- package/lib/wallet/return-client.d.ts +91 -0
- package/lib/wallet/return-client.js +100 -0
- package/lib/wallet/self-mint-verifier.d.ts +10 -0
- package/lib/wallet/self-mint-verifier.js +5 -0
- package/lib/wallet/signer.d.ts +18 -0
- package/lib/wallet/signer.js +1 -0
- package/lib/wallet/source-adapter.d.ts +33 -0
- package/lib/wallet/source-adapter.js +99 -0
- package/lib/wallet/token-plugin.d.ts +4 -0
- package/lib/wallet/token-plugin.js +20 -0
- package/manifests/bridges.nile.json +23 -0
- package/package.json +71 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
function strip0x(h) {
|
|
2
|
+
return h.startsWith('0x') || h.startsWith('0X') ? h.slice(2) : h;
|
|
3
|
+
}
|
|
4
|
+
export class TronHttpRpcClient {
|
|
5
|
+
baseUrl;
|
|
6
|
+
apiKey;
|
|
7
|
+
fetchFn;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
10
|
+
this.apiKey = options.apiKey;
|
|
11
|
+
// Bind to globalThis: native `fetch` is spec'd to require `this` to be the
|
|
12
|
+
// real global (window/self) — assigning the bare reference and later
|
|
13
|
+
// calling it as `this.fetchFn(...)` rebinds `this` to the client instance,
|
|
14
|
+
// which throws "Illegal invocation".
|
|
15
|
+
const f = options.fetchFn ?? globalThis.fetch?.bind(globalThis);
|
|
16
|
+
if (!f) {
|
|
17
|
+
throw new Error('No fetch available; pass fetchFn in TronHttpRpcClientOptions.');
|
|
18
|
+
}
|
|
19
|
+
this.fetchFn = f;
|
|
20
|
+
}
|
|
21
|
+
async post(path, body) {
|
|
22
|
+
const headers = { 'content-type': 'application/json' };
|
|
23
|
+
if (this.apiKey) {
|
|
24
|
+
headers['TRON-PRO-API-KEY'] = this.apiKey;
|
|
25
|
+
}
|
|
26
|
+
const res = await this.fetchFn(`${this.baseUrl}${path}`, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers,
|
|
29
|
+
body: JSON.stringify(body),
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok) {
|
|
32
|
+
throw new Error(`Tron RPC ${path} failed: HTTP ${res.status}`);
|
|
33
|
+
}
|
|
34
|
+
return (await res.json());
|
|
35
|
+
}
|
|
36
|
+
async getTransactionInfo(txidHex) {
|
|
37
|
+
const info = await this.post('/wallet/gettransactioninfobyid', { value: strip0x(txidHex) });
|
|
38
|
+
if (!info || Object.keys(info).length === 0 || info.id == null) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const receipt = (info.receipt ?? {});
|
|
42
|
+
const rawLogs = Array.isArray(info.log) ? info.log : [];
|
|
43
|
+
const logs = rawLogs.map((l) => ({
|
|
44
|
+
address: String(l.address ?? '').toLowerCase(),
|
|
45
|
+
topics: Array.isArray(l.topics) ? l.topics.map((t) => String(t).toLowerCase()) : [],
|
|
46
|
+
data: String(l.data ?? '').toLowerCase(),
|
|
47
|
+
}));
|
|
48
|
+
return {
|
|
49
|
+
blockNumber: BigInt(info.blockNumber ?? 0),
|
|
50
|
+
success: String(receipt.result ?? '') === 'SUCCESS',
|
|
51
|
+
logs,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async getNowBlockNumber() {
|
|
55
|
+
const block = await this.post('/wallet/getnowblock', {});
|
|
56
|
+
const header = (block.block_header ?? {});
|
|
57
|
+
const raw = (header.raw_data ?? {});
|
|
58
|
+
return BigInt(raw.number ?? 0);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read-only (constant) contract call — used for `allowance(owner, spender)` so
|
|
62
|
+
* bridge-in can skip a redundant `approve`. Addresses go over the wire in the
|
|
63
|
+
* hex `41…` form (visible:false). Throws if the node reports the call reverted
|
|
64
|
+
* or returns no result word.
|
|
65
|
+
*/
|
|
66
|
+
async constantCall(input) {
|
|
67
|
+
const res = await this.post('/wallet/triggerconstantcontract', {
|
|
68
|
+
owner_address: '41' + strip0x(input.ownerHex).toLowerCase(),
|
|
69
|
+
contract_address: '41' + strip0x(input.contractHex).toLowerCase(),
|
|
70
|
+
function_selector: input.functionSignature,
|
|
71
|
+
parameter: strip0x(input.parameterHex ?? ''),
|
|
72
|
+
visible: false,
|
|
73
|
+
});
|
|
74
|
+
const result = (res.result ?? {});
|
|
75
|
+
// `result.result === true` on success; a revert sets a code/message instead.
|
|
76
|
+
if (result.result !== true && (result.code != null || result.message != null)) {
|
|
77
|
+
const msg = typeof result.message === 'string' ? hexMessage(result.message) : String(result.code);
|
|
78
|
+
throw new Error(`triggerconstantcontract ${input.functionSignature} reverted: ${msg}`);
|
|
79
|
+
}
|
|
80
|
+
const cr = res.constant_result;
|
|
81
|
+
if (!Array.isArray(cr) || cr.length === 0 || typeof cr[0] !== 'string') {
|
|
82
|
+
throw new Error(`triggerconstantcontract ${input.functionSignature} returned no result`);
|
|
83
|
+
}
|
|
84
|
+
return strip0x(cr[0]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Decode a possibly-hex Tron revert message into readable text (best effort). */
|
|
88
|
+
function hexMessage(m) {
|
|
89
|
+
if (!/^[0-9a-fA-F]*$/.test(m) || m.length % 2 !== 0)
|
|
90
|
+
return m;
|
|
91
|
+
try {
|
|
92
|
+
const bytes = new Uint8Array(m.length / 2);
|
|
93
|
+
for (let i = 0; i < bytes.length; i++)
|
|
94
|
+
bytes[i] = parseInt(m.slice(i * 2, i * 2 + 2), 16);
|
|
95
|
+
return new TextDecoder().decode(bytes).replace(/\0+/g, '').trim() || m;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return m;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type BridgeAssetConfig } from '../config.js';
|
|
2
|
+
/** Tron network ids (TronWeb genesis-derived chain ids). */
|
|
3
|
+
export declare const TRON_MAINNET_CHAIN_ID = 728126428;
|
|
4
|
+
export declare const TRON_NILE_CHAIN_ID = 3448148188;
|
|
5
|
+
/** Canonical USDT (TRC20) contract on Tron mainnet. */
|
|
6
|
+
export declare const TRON_MAINNET_USDT = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
|
|
7
|
+
/** Canonical USDT (TRC20) contract on the Tron Nile testnet. */
|
|
8
|
+
export declare const TRON_NILE_USDT = "TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf";
|
|
9
|
+
export declare const TRON_DEFAULT_CONFIRMATIONS = 20;
|
|
10
|
+
export declare function tronMainnetUsdtConfig(lockContract: string, rpcUrl?: string): BridgeAssetConfig;
|
|
11
|
+
export declare function tronNileUsdtConfig(lockContract: string, rpcUrl?: string): BridgeAssetConfig;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DEFAULT_DECIMALS } from '../config.js';
|
|
2
|
+
/** Tron network ids (TronWeb genesis-derived chain ids). */
|
|
3
|
+
export const TRON_MAINNET_CHAIN_ID = 728126428; // 0x2b6653dc
|
|
4
|
+
export const TRON_NILE_CHAIN_ID = 3448148188; // 0xcd8690dc
|
|
5
|
+
/** Canonical USDT (TRC20) contract on Tron mainnet. */
|
|
6
|
+
export const TRON_MAINNET_USDT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t';
|
|
7
|
+
/** Canonical USDT (TRC20) contract on the Tron Nile testnet. */
|
|
8
|
+
export const TRON_NILE_USDT = 'TXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf';
|
|
9
|
+
export const TRON_DEFAULT_CONFIRMATIONS = 20;
|
|
10
|
+
export function tronMainnetUsdtConfig(lockContract, rpcUrl = 'https://api.trongrid.io') {
|
|
11
|
+
return {
|
|
12
|
+
family: 'tron',
|
|
13
|
+
chainId: TRON_MAINNET_CHAIN_ID,
|
|
14
|
+
lockContract,
|
|
15
|
+
assetContract: TRON_MAINNET_USDT,
|
|
16
|
+
confirmations: TRON_DEFAULT_CONFIRMATIONS,
|
|
17
|
+
decimals: DEFAULT_DECIMALS,
|
|
18
|
+
rpcUrl,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function tronNileUsdtConfig(lockContract, rpcUrl = 'https://nile.trongrid.io') {
|
|
22
|
+
return {
|
|
23
|
+
family: 'tron',
|
|
24
|
+
chainId: TRON_NILE_CHAIN_ID,
|
|
25
|
+
lockContract,
|
|
26
|
+
assetContract: TRON_NILE_USDT,
|
|
27
|
+
confirmations: TRON_DEFAULT_CONFIRMATIONS,
|
|
28
|
+
decimals: DEFAULT_DECIMALS,
|
|
29
|
+
rpcUrl,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { toEvmAddressHex } from '../address.js';
|
|
2
|
+
import { TRON_DEFAULT_CONFIRMATIONS } from './config.js';
|
|
3
|
+
import { tronPresentation } from './presentation.js';
|
|
4
|
+
import { TronHttpRpcClient } from './TronRpcClient.js';
|
|
5
|
+
/** The CAIP-2-style chain reference for a Tron numeric chainId (`tron:0x<hex>`). */
|
|
6
|
+
export function tronChainRef(chainId) {
|
|
7
|
+
return `tron:0x${chainId.toString(16)}`;
|
|
8
|
+
}
|
|
9
|
+
export const tronFamily = {
|
|
10
|
+
family: 'tron',
|
|
11
|
+
chainName: 'Tron',
|
|
12
|
+
defaultConfirmations: TRON_DEFAULT_CONFIRMATIONS,
|
|
13
|
+
blockSeconds: 3,
|
|
14
|
+
chainRef: tronChainRef,
|
|
15
|
+
normalizeAddress: toEvmAddressHex,
|
|
16
|
+
createRpc: ({ rpcUrl, apiKey }) => new TronHttpRpcClient({ baseUrl: rpcUrl ?? 'https://api.trongrid.io', apiKey }),
|
|
17
|
+
presentation: tronPresentation,
|
|
18
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the wallet UI shows for a Tron chain without knowing Tron: the
|
|
3
|
+
* Tronscan link for a transaction and the shape of a valid destination.
|
|
4
|
+
*/
|
|
5
|
+
import type { BridgePresentation } from '@unicitylabs/bridge-core';
|
|
6
|
+
/** Tronscan transaction URL for a Tron chainId (Nile testnet vs mainnet). */
|
|
7
|
+
export declare function explorerTxUrl(chainId: number, txid: string): string;
|
|
8
|
+
/** Structural validity of a Tron base58 (`T…`) address (a bridge-out destination). */
|
|
9
|
+
export declare function isValidTronAddress(addr: string): boolean;
|
|
10
|
+
export declare function tronPresentation(chainId: number): BridgePresentation;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TRON_NILE_CHAIN_ID } from './config.js';
|
|
2
|
+
/** Tronscan transaction URL for a Tron chainId (Nile testnet vs mainnet). */
|
|
3
|
+
export function explorerTxUrl(chainId, txid) {
|
|
4
|
+
const base = chainId === TRON_NILE_CHAIN_ID
|
|
5
|
+
? 'https://nile.tronscan.org/#/transaction/'
|
|
6
|
+
: 'https://tronscan.org/#/transaction/';
|
|
7
|
+
return base + txid;
|
|
8
|
+
}
|
|
9
|
+
/** Structural validity of a Tron base58 (`T…`) address (a bridge-out destination). */
|
|
10
|
+
export function isValidTronAddress(addr) {
|
|
11
|
+
return /^T[1-9A-HJ-NP-Za-km-z]{33}$/.test(addr.trim());
|
|
12
|
+
}
|
|
13
|
+
export function tronPresentation(chainId) {
|
|
14
|
+
return {
|
|
15
|
+
explorerTxUrl: (txid) => explorerTxUrl(chainId, txid),
|
|
16
|
+
validateAddress: (addr) => isValidTronAddress(addr),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tron wallet providers (08 Phase 3 — wallet picker, adapter/WalletConnect seam).
|
|
3
|
+
*
|
|
4
|
+
* The bridge-in flow needs a {SourceSigner}; *which* wallet supplies it (injected
|
|
5
|
+
* TronLink, WalletConnect, a managed key) is a user choice. This is the small
|
|
6
|
+
* registry the picker renders: each {SourceWalletProvider} knows its id/name, whether
|
|
7
|
+
* it's usable here, and how to `create` a (not-yet-connected) `SourceSigner` for a
|
|
8
|
+
* given source chain. `runBridgeIn` then drives that signer uniformly — `connect()`
|
|
9
|
+
* prompts (TronLink authorize, or the WalletConnect QR), the rest is identical.
|
|
10
|
+
*
|
|
11
|
+
* TronLink (priority 1) needs no extra dependency and is implemented here.
|
|
12
|
+
* WalletConnect is wired by **injecting a signer factory** ({TronWalletConfig})
|
|
13
|
+
* from the app once `@tronweb3/walletconnect-tron` is installed and a `projectId`
|
|
14
|
+
* is configured — so this module (and everything that typechecks against it) has
|
|
15
|
+
* **no** dependency on the WalletConnect package. Until the factory is supplied,
|
|
16
|
+
* only TronLink is offered.
|
|
17
|
+
*/
|
|
18
|
+
import type { SourceSigner, SourceWalletProvider } from '../wallet/signer.js';
|
|
19
|
+
import { type TronLinkWindow } from './signer.js';
|
|
20
|
+
/** Stable ids for the wallets the picker can offer. */
|
|
21
|
+
export type TronWalletId = 'tronlink' | 'walletconnect';
|
|
22
|
+
/**
|
|
23
|
+
* Factory the app injects once `@tronweb3/walletconnect-tron` v4 is installed and a
|
|
24
|
+
* WalletConnect `projectId` is configured. Returns a `SourceSigner` that wraps the
|
|
25
|
+
* adapter (its `connect()` opens the WC modal). Keeping this a callback is what lets
|
|
26
|
+
* the plugin stay free of any WalletConnect dependency.
|
|
27
|
+
*/
|
|
28
|
+
export type WalletConnectSignerFactory = (chainId: number) => SourceSigner;
|
|
29
|
+
/** App-supplied wallet configuration (which optional wallets to offer + how to build them). */
|
|
30
|
+
export interface TronWalletConfig {
|
|
31
|
+
/** Present only when WalletConnect is configured (projectId set + factory wired). */
|
|
32
|
+
readonly walletConnect?: {
|
|
33
|
+
readonly signerFactory: WalletConnectSignerFactory;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Injected-TronLink provider (browser extension) — priority 1, no extra deps. */
|
|
37
|
+
export declare function tronLinkProvider(win?: TronLinkWindow): SourceWalletProvider;
|
|
38
|
+
/** WalletConnect provider built from the app-injected signer factory. */
|
|
39
|
+
export declare function walletConnectProvider(factory: WalletConnectSignerFactory): SourceWalletProvider;
|
|
40
|
+
/**
|
|
41
|
+
* The wallets to offer in the picker: TronLink always, plus WalletConnect when the
|
|
42
|
+
* app has configured it. Availability (extension present?) is left to the UI via
|
|
43
|
+
* `isAvailable()` — the list is not pre-filtered, so a missing TronLink can still be
|
|
44
|
+
* shown with an "install it" hint rather than silently vanishing.
|
|
45
|
+
*/
|
|
46
|
+
export declare function availableTronWallets(config?: TronWalletConfig): SourceWalletProvider[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { TronLinkSigner } from './signer.js';
|
|
2
|
+
/** Injected-TronLink provider (browser extension) — priority 1, no extra deps. */
|
|
3
|
+
export function tronLinkProvider(win = globalThis) {
|
|
4
|
+
return {
|
|
5
|
+
id: 'tronlink',
|
|
6
|
+
name: 'TronLink',
|
|
7
|
+
isAvailable: () => Boolean(win.tronWeb),
|
|
8
|
+
create: (chainId) => new TronLinkSigner(win, chainId),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** WalletConnect provider built from the app-injected signer factory. */
|
|
12
|
+
export function walletConnectProvider(factory) {
|
|
13
|
+
return {
|
|
14
|
+
id: 'walletconnect',
|
|
15
|
+
name: 'WalletConnect',
|
|
16
|
+
isAvailable: () => true, // usable on any device once configured (that's the point of WC)
|
|
17
|
+
create: (chainId) => factory(chainId),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The wallets to offer in the picker: TronLink always, plus WalletConnect when the
|
|
22
|
+
* app has configured it. Availability (extension present?) is left to the UI via
|
|
23
|
+
* `isAvailable()` — the list is not pre-filtered, so a missing TronLink can still be
|
|
24
|
+
* shown with an "install it" hint rather than silently vanishing.
|
|
25
|
+
*/
|
|
26
|
+
export function availableTronWallets(config = {}) {
|
|
27
|
+
const providers = [tronLinkProvider()];
|
|
28
|
+
if (config.walletConnect) {
|
|
29
|
+
providers.push(walletConnectProvider(config.walletConnect.signerFactory));
|
|
30
|
+
}
|
|
31
|
+
return providers;
|
|
32
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tron signers behind the family-neutral {SourceSigner} (06 §A1.3, §W2; 08
|
|
3
|
+
* §1.2/§1.3): TronLink first, WalletConnect and a managed key behind the same
|
|
4
|
+
* surface. `connect()` prompts once; `getNetwork()` derives the wallet node's
|
|
5
|
+
* real chainId from its genesis block, so the caller can refuse to sign
|
|
6
|
+
* against the wrong chain.
|
|
7
|
+
*/
|
|
8
|
+
import type { ContractCall } from '../contract-call.js';
|
|
9
|
+
import type { SourceSigner, WalletChange } from '../wallet/signer.js';
|
|
10
|
+
export interface TronSendOptions {
|
|
11
|
+
/** Energy/bandwidth fee cap in SUN (1 TRX = 1e6 SUN). Default 150 TRX. */
|
|
12
|
+
readonly feeLimitSun?: number;
|
|
13
|
+
/** TRX (in SUN) to send with the call. Default 0. */
|
|
14
|
+
readonly callValueSun?: number;
|
|
15
|
+
}
|
|
16
|
+
/** Minimal shape of the TronWeb instance TronLink injects on `window`. */
|
|
17
|
+
export interface InjectedTronWeb {
|
|
18
|
+
defaultAddress: {
|
|
19
|
+
base58: string | false;
|
|
20
|
+
};
|
|
21
|
+
fullNode?: {
|
|
22
|
+
host: string;
|
|
23
|
+
};
|
|
24
|
+
transactionBuilder: {
|
|
25
|
+
triggerSmartContract(contractAddress: string, functionSelector: string, options: Record<string, unknown>, parameters: readonly {
|
|
26
|
+
type: string;
|
|
27
|
+
value: string;
|
|
28
|
+
}[], issuerAddress: string): Promise<{
|
|
29
|
+
transaction: unknown;
|
|
30
|
+
result?: {
|
|
31
|
+
result?: boolean;
|
|
32
|
+
};
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
trx: {
|
|
36
|
+
sign(transaction: unknown): Promise<unknown>;
|
|
37
|
+
sendRawTransaction(signed: unknown): Promise<{
|
|
38
|
+
result?: boolean;
|
|
39
|
+
txid?: string;
|
|
40
|
+
transaction?: {
|
|
41
|
+
txID?: string;
|
|
42
|
+
};
|
|
43
|
+
}>;
|
|
44
|
+
getChainParameters?(): Promise<unknown>;
|
|
45
|
+
/** Genesis-block fetch — the source of the wallet's real chainId (08 §1.3). */
|
|
46
|
+
getBlockByNumber?(n: number): Promise<{
|
|
47
|
+
blockID?: string;
|
|
48
|
+
} | null>;
|
|
49
|
+
};
|
|
50
|
+
address: {
|
|
51
|
+
toHex(addr: string): string;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** The browser injections TronLink exposes. */
|
|
55
|
+
export interface TronLinkWindow {
|
|
56
|
+
tronLink?: {
|
|
57
|
+
request(args: {
|
|
58
|
+
method: string;
|
|
59
|
+
}): Promise<unknown>;
|
|
60
|
+
};
|
|
61
|
+
tronWeb?: InjectedTronWeb & {
|
|
62
|
+
ready?: boolean;
|
|
63
|
+
};
|
|
64
|
+
addEventListener?(type: string, listener: (e: unknown) => void): void;
|
|
65
|
+
removeEventListener?(type: string, listener: (e: unknown) => void): void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Tron's chainId (as used by the bridge config, e.g. Nile `3448148188`) is the
|
|
69
|
+
* low 4 bytes of the genesis block's `blockID`. Deriving it from the wallet's
|
|
70
|
+
* connected node is a real network identity — not the manifest echoing itself.
|
|
71
|
+
*/
|
|
72
|
+
export declare function chainIdFromGenesisBlockId(blockId: string): number;
|
|
73
|
+
/**
|
|
74
|
+
* TronLink-backed signer (priority 1). Uses the injected `window.tronWeb` for
|
|
75
|
+
* building + broadcasting; `tron_requestAccounts` prompts the connection once.
|
|
76
|
+
*/
|
|
77
|
+
export declare class TronLinkSigner implements SourceSigner {
|
|
78
|
+
/** The injected window (defaults to the global one in a browser). */
|
|
79
|
+
private readonly win;
|
|
80
|
+
/** Expected Tron chainId (from the manifest) — for the caller's wrong-network message. */
|
|
81
|
+
private readonly expectedChainId?;
|
|
82
|
+
/** True once `connect()` has prompted; `getAddress()` then reads live silently. */
|
|
83
|
+
private connected;
|
|
84
|
+
constructor(
|
|
85
|
+
/** The injected window (defaults to the global one in a browser). */
|
|
86
|
+
win?: TronLinkWindow,
|
|
87
|
+
/** Expected Tron chainId (from the manifest) — for the caller's wrong-network message. */
|
|
88
|
+
expectedChainId?: number | undefined);
|
|
89
|
+
private tronWeb;
|
|
90
|
+
connect(): Promise<string>;
|
|
91
|
+
getAddress(): Promise<string>;
|
|
92
|
+
getNetwork(): Promise<number>;
|
|
93
|
+
onChange(cb: (e: WalletChange) => void): () => void;
|
|
94
|
+
/** The manifest's expected chainId, for building a clear wrong-network message. */
|
|
95
|
+
get expected(): number | undefined;
|
|
96
|
+
sendCall(call: ContractCall, opts?: TronSendOptions): Promise<string>;
|
|
97
|
+
}
|
|
98
|
+
/** Sign an unsigned Tron transaction, resolving to the signed form. */
|
|
99
|
+
export type TronTxSign = (unsignedTx: unknown) => Promise<unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* Build → **sign (via `sign`)** → broadcast a call over any {InjectedTronWeb} (the
|
|
102
|
+
* dApp-broadcast model). The build + broadcast use `tw`; only the signature is the
|
|
103
|
+
* wallet's concern — so this serves both the injected path (`tw.trx.sign`) and
|
|
104
|
+
* adapter/WalletConnect (the adapter's `signTransaction`).
|
|
105
|
+
*/
|
|
106
|
+
export declare function sendCallSigned(tw: InjectedTronWeb, issuerBase58: string, call: ContractCall, sign: TronTxSign, opts?: TronSendOptions): Promise<string>;
|
|
107
|
+
/**
|
|
108
|
+
* Shared build → sign → broadcast over any {InjectedTronWeb} (the dApp-broadcast
|
|
109
|
+
* model). TronLink prompts on `trx.sign`; a key-bearing TronWeb signs silently.
|
|
110
|
+
*/
|
|
111
|
+
export declare function sendCallVia(tw: InjectedTronWeb, issuerBase58: string, call: ContractCall, opts?: TronSendOptions): Promise<string>;
|
|
112
|
+
/**
|
|
113
|
+
* A wallet that connects + signs but does **not** build/broadcast (WalletConnect,
|
|
114
|
+
* or any `@tronweb3/tronwallet-adapters` adapter). The app adapts the concrete
|
|
115
|
+
* adapter to this shape; {AdapterTronSigner} pairs it with a node TronWeb for the
|
|
116
|
+
* build/broadcast, so the plugin needs no WalletConnect/tronweb dependency.
|
|
117
|
+
*/
|
|
118
|
+
export interface AdapterWallet {
|
|
119
|
+
/** Connect (e.g. open the WalletConnect modal); resolve to the base58 address. */
|
|
120
|
+
connect(): Promise<string>;
|
|
121
|
+
/** Sign a built Tron transaction; resolve to the signed transaction. */
|
|
122
|
+
signTransaction(unsignedTx: unknown): Promise<unknown>;
|
|
123
|
+
/** Optional: subscribe to account/disconnect changes. */
|
|
124
|
+
onChange?(cb: (e: WalletChange) => void): () => void;
|
|
125
|
+
/** Optional: tear down the session. */
|
|
126
|
+
disconnect?(): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A {SourceSigner} backed by an {AdapterWallet} (WalletConnect / adapter) for signing,
|
|
130
|
+
* plus a lazily-provided node TronWeb for build + broadcast. The node builds the tx
|
|
131
|
+
* against the bridge's chain, so the tx is bound to that chain regardless of what the
|
|
132
|
+
* remote wallet reports — hence `getNetwork()` returns the configured chainId (as
|
|
133
|
+
* {ManagedTronSigner} does), and the wrong-network guard is satisfied by construction.
|
|
134
|
+
*/
|
|
135
|
+
export declare class AdapterTronSigner implements SourceSigner {
|
|
136
|
+
private readonly wallet;
|
|
137
|
+
/** Lazily builds the node TronWeb (keeps the heavy `tronweb` import off the hot path). */
|
|
138
|
+
private readonly tronWebProvider;
|
|
139
|
+
private readonly chainId;
|
|
140
|
+
private address;
|
|
141
|
+
private tw;
|
|
142
|
+
constructor(wallet: AdapterWallet,
|
|
143
|
+
/** Lazily builds the node TronWeb (keeps the heavy `tronweb` import off the hot path). */
|
|
144
|
+
tronWebProvider: () => Promise<InjectedTronWeb>, chainId: number);
|
|
145
|
+
connect(): Promise<string>;
|
|
146
|
+
getAddress(): Promise<string>;
|
|
147
|
+
getNetwork(): Promise<number>;
|
|
148
|
+
sendCall(call: ContractCall, opts?: TronSendOptions): Promise<string>;
|
|
149
|
+
onChange(cb: (e: WalletChange) => void): () => void;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Managed-key / WalletConnect signer (06 §W4): wraps a pre-built `TronWeb`-shaped
|
|
153
|
+
* object that already holds a key (managed: `new TronWeb({ privateKey })`; the
|
|
154
|
+
* proven `demo/tron.ts` path) or a WalletConnect-provided signer. No extension,
|
|
155
|
+
* no flow change — same `SourceSigner` surface, signs silently. Its network is
|
|
156
|
+
* known from construction (the node it was built against), so it's trusted.
|
|
157
|
+
*/
|
|
158
|
+
export declare class ManagedTronSigner implements SourceSigner {
|
|
159
|
+
private readonly tw;
|
|
160
|
+
private readonly chainId;
|
|
161
|
+
constructor(tw: InjectedTronWeb, chainId: number);
|
|
162
|
+
connect(): Promise<string>;
|
|
163
|
+
getAddress(): Promise<string>;
|
|
164
|
+
getNetwork(): Promise<number>;
|
|
165
|
+
sendCall(call: ContractCall, opts?: TronSendOptions): Promise<string>;
|
|
166
|
+
}
|