Remote Connector
Connecting to Tonhub wallet from your dApp or bot
TonhubConnector
allows you to connect to a wallet app from a web browser, bot or backend.
Creating a connector
Before connecting to an app you need to create a connector:
import { TonhubConnector} from "ton-x";
const connector = new TonhubConnector({network: "mainnet"}); //Set network "sandbox" for testnet
Starting a new session
Before requesting a connection to a wallet you need to create session and persist it's data somewhere in your app.
You can generate session anywhere
It could be web app, bot, console app. ton-x doesn't depend on specific environment.
Do not forget to persist session
At this step you need to persist and reuse this session values even in the case of app restart until session was revoked (see later)
let session: TonhubCreatedSession = await connector.createNewSession({
name: 'Your app name',
url: 'Your app url'
});
// Session ID, Seed and Auth Link
const sessionId = session.id;
const sessionSeed = session.seed;
const sessionLink = session.link;
Present a session link to the user
After session was created and persisted you can present user a link to connect to your app. On desktop you need to show a QR Code and on mobile you need to show it as a normal link that user will need to press.
Do not try to navigate your user automatically
This is almost never works on mobile
Await session confirmation
After presenting a link the user you can await session confirmation or rejection.
Revoked session couldn't be restarted
If user rejected connection or backend revoked a token you can't use it again and have to create a new one.
const session: TonhubSessionAwaited = await connector.awaitSessionReady(sessionId, 5 * 60 * 1000); // 5 min timeout
if (session.state === 'revoked' || session.state === 'expired') {
// Handle revoked or expired session
} else if (session.state === 'ready') {
// Handle session
const walletConfig: TonhubWalletConfig = session.walletConfig;
// You need to persist this values to work with this connection:
// * sessionId
// * sessionSeed
// * walletConfig
// You can check signed wallet config on backend using TonhubConnector.verifyWalletConfig.
// walletConfig is cryptographically signed for specific session and other parameters
// you can safely use it as authentication proof without the need to sign something.
const correctConfig: boolean = TonhubConnector.verifyWalletConfig(sessionId, walletConfig);
// ...
} else {
throw new Error('Impossible');
}
Requesting Transaction
To request a transaction you can call requestTransaction
in connector after successful session.
// Request body
const request: TonhubTransactionRequest = {
seed: sessionSeed, // Session Seed
appPublicKey: walletConfig.appPublicKey, // Wallet's app public key
to: 'EQCkR1cGmnsE45N4K0otPl5EnxnRakmGqeJUNua5fkWhales', // Destination
value: '10000000000', // Amount in nano-tons
timeout: 5 * 60 * 1000, // 5 minut timeout
stateInit: '....', // Optional serialized to base64 string state_init cell
text: 'Hello world', // Optional comment. If no payload specified - sends actual content, if payload is provided this text is used as UI-only hint
payload: '....' // Optional serialized to base64 string payload cell
};
const response: TonhubTransactionResponse = await connector.requestTransaction(request);
if (response.type === 'rejected') {
// Handle rejection
} else if (response.type === 'expired') {
// Handle expiration
} else if (response.type === 'invalid_session') {
// Handle expired or invalid session
} else if (response.type === 'success') {
// Handle successful transaction
const externalMessage = response.response; // Signed body of external message that was sent to the network
} else {
throw new Error('Impossible');
}
Requesting Signature
To request a transaction you can call requestTransaction
in connector after successful session.
const payloadToSign = Buffer.concat([Buffer.from([0, 0, 0, 0]), Buffer.from('Some random string')]);
const payload = beginCell()
.storeBuffer(payloadToSign)
.endCell()
.toBoc({idx:false})
.toString('base64');
const text = 'Please, sign our terms or service and privacy policy';
// Request body
const request: TonhubSignRequest = {
seed: sessionSeed, // Session Seed
appPublicKey: walletConfig.appPublicKey, // Wallet's app public key
timeout: 5 * 60 * 1000, // 5 minut timeout
text: 'Hello world', // Text to sign, presented to the user.
payload: payload // Optional serialized to base64 string payload cell
};
const response: TonhubSignResponse = await connector.requestSign(request);
if (response.type === 'rejected') {
// Handle rejection
} else if (response.type === 'expired') {
// Handle expiration
} else if (response.type === 'invalid_session') {
// Handle expired or invalid session
} else if (response.type === 'success') {
// Handle successful transaction
const signature = response.signature;
// You can check signature on the backend with TonhubConnector.verifySignatureResponse
let correctSignature = TonhubConnector.verifySignatureResponse({ signature: signature, config: walletConfig });
} else {
throw new Error('Impossible');
}
Check session state
If you need to check from time to time that your session is a valid you can call getSessionState
method.
While it is possible to track session state we are NOT recommending to do so since you can always re-authenticate user if transaction or signature request requested and session became expired.
const session: TonhubSessionState = await connector.getSessionState(sessionId);
Updated about 2 years ago