wip: working on new connector
parent
cf0e7baf88
commit
f105b2cbc4
|
@ -1,4 +1,3 @@
|
|||
import axios, { AxiosRequestConfig } from "axios";
|
||||
import { getSecureRandomBytes, keyPairFromSeed } from "ton-crypto";
|
||||
import { backoff } from "../utils/backoff";
|
||||
import { toUrlSafe } from "../utils/toURLsafe";
|
||||
|
@ -8,7 +7,6 @@ import { Cell, Address, beginCell, CommentMessage, safeSign, contractAddress, sa
|
|||
import BN from 'bn.js';
|
||||
import { WalletV4Source } from 'ton-contracts';
|
||||
import { TonhubHttpTransport } from '../transport/TonhubHttpTransport';
|
||||
import { TonhubEmbeddedTransport } from '../transport/TonhubEmbeddedTransport';
|
||||
|
||||
const sessionStateCodec = t.union([
|
||||
t.type({
|
||||
|
@ -168,15 +166,6 @@ function textToCell(src: string) {
|
|||
return res;
|
||||
}
|
||||
|
||||
export function autodiscoverTransport() {
|
||||
if (TonhubEmbeddedTransport.isAvailable()) {
|
||||
return new TonhubEmbeddedTransport();
|
||||
}
|
||||
return new TonhubHttpTransport({
|
||||
endpoint: 'https://connect.tonhubapi.com'
|
||||
});
|
||||
}
|
||||
|
||||
export class TonhubConnector {
|
||||
|
||||
static extractPublicKey(config: {
|
||||
|
@ -277,7 +266,7 @@ export class TonhubConnector {
|
|||
|
||||
readonly network: 'mainnet' | 'sandbox';
|
||||
readonly transport: Transport;
|
||||
|
||||
|
||||
|
||||
constructor(args?: { network?: 'mainnet' | 'sandbox', transport?: Transport }) {
|
||||
let network: 'mainnet' | 'sandbox' = 'mainnet';
|
||||
|
@ -288,7 +277,7 @@ export class TonhubConnector {
|
|||
}
|
||||
|
||||
this.network = network;
|
||||
this.transport = args?.transport || autodiscoverTransport();
|
||||
this.transport = args?.transport || new TonhubHttpTransport();
|
||||
}
|
||||
|
||||
createNewSession = async (args: { name: string, url: string }): Promise<TonhubCreatedSession> => {
|
||||
|
@ -306,8 +295,8 @@ export class TonhubConnector {
|
|||
name: args.name,
|
||||
url: args.url,
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
if (!session.ok) {
|
||||
throw Error('Unable to create state');
|
||||
}
|
||||
|
@ -589,7 +578,7 @@ export class TonhubConnector {
|
|||
return { type: 'expired' };
|
||||
}
|
||||
if (res.job !== boc) {
|
||||
return { type: 'rejected' };
|
||||
return { type: 'rejected' };
|
||||
}
|
||||
if (res.state === 'expired') {
|
||||
return { type: 'expired' };
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
import * as t from 'io-ts';
|
||||
|
||||
const configCodec = t.type({
|
||||
version: t.literal(1),
|
||||
platform: t.union([t.literal('iOS'), t.literal('Android')]),
|
||||
platformVersion: t.union([t.string, t.number]),
|
||||
network: t.union([t.literal('sandbox'), t.literal('mainnet')]),
|
||||
address: t.string,
|
||||
publicKey: t.string,
|
||||
walletConfig: t.string,
|
||||
walletType: t.string,
|
||||
signature: t.string,
|
||||
time: t.number,
|
||||
subkey: t.type({
|
||||
domain: t.string,
|
||||
publicKey: t.string,
|
||||
time: t.number,
|
||||
signature: t.string
|
||||
})
|
||||
});
|
||||
|
||||
export type TonhubLocalConfig = {
|
||||
version: number,
|
||||
network: 'sandbox' | 'mainnet',
|
||||
address: string,
|
||||
publicKey: string,
|
||||
walletConfig: string,
|
||||
walletType: string,
|
||||
signature: string,
|
||||
time: number,
|
||||
subkey: {
|
||||
domain: string,
|
||||
publicKey: string,
|
||||
time: number,
|
||||
signature: string
|
||||
}
|
||||
};
|
||||
|
||||
export type TonhubLocalTransactionRequest = {
|
||||
to: string,
|
||||
value: string,
|
||||
stateInit?: string | null | undefined,
|
||||
text?: string | null | undefined,
|
||||
payload?: string | null | undefined
|
||||
};
|
||||
|
||||
export type TonhubLocalTransactionResponse = {
|
||||
type: 'success',
|
||||
response: string
|
||||
} | {
|
||||
type: 'rejected'
|
||||
};
|
||||
|
||||
export class TonhubLocalConnector {
|
||||
|
||||
static isAvailable() {
|
||||
if (typeof window === 'undefined') {
|
||||
return false;
|
||||
}
|
||||
if (!((window as any)['ton-x'])) {
|
||||
return false;
|
||||
}
|
||||
let tx = ((window as any)['ton-x']);
|
||||
if (tx.__IS_TON_X !== true) {
|
||||
return false;
|
||||
}
|
||||
if (!configCodec.is(tx)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
readonly network: 'mainnet' | 'sandbox';
|
||||
readonly config: TonhubLocalConfig;
|
||||
|
||||
#provider: (name: string, args: any) => Promise<any>
|
||||
|
||||
constructor(network: 'mainnet' | 'sandbox') {
|
||||
if (typeof window === 'undefined') {
|
||||
throw Error('Not running in browser');
|
||||
}
|
||||
if (!((window as any)['ton-x'])) {
|
||||
throw Error('Not running in dApp browser');
|
||||
}
|
||||
let tx = ((window as any)['ton-x']);
|
||||
if (tx.__IS_TON_X !== true) {
|
||||
throw Error('Not running in dApp browser');
|
||||
}
|
||||
let cfg = tx.config;
|
||||
if (!configCodec.is(cfg)) {
|
||||
throw Error('Not running in dApp browser');
|
||||
}
|
||||
if (cfg.network !== network) {
|
||||
throw Error('Invalid network');
|
||||
}
|
||||
this.network = network;
|
||||
this.config = {
|
||||
version: cfg.version,
|
||||
network: cfg.network,
|
||||
address: cfg.address,
|
||||
publicKey: cfg.publicKey,
|
||||
walletConfig: cfg.walletConfig,
|
||||
walletType: cfg.walletType,
|
||||
signature: cfg.signature,
|
||||
time: cfg.time,
|
||||
subkey: {
|
||||
domain: cfg.subkey.domain,
|
||||
publicKey: cfg.subkey.publicKey,
|
||||
time: cfg.subkey.time,
|
||||
signature: cfg.subkey.signature
|
||||
}
|
||||
};
|
||||
this.#provider = tx.call;
|
||||
Object.freeze(this.config.subkey);
|
||||
Object.freeze(this.config);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
async requestTransaction(request: TonhubLocalTransactionRequest): Promise<TonhubLocalTransactionResponse> {
|
||||
let res = await this.#provider('tx', {
|
||||
network: this.network,
|
||||
to: request.to,
|
||||
value: request.value,
|
||||
stateInit: request.stateInit ? request.stateInit : null,
|
||||
text: request.text ? request.text : null,
|
||||
payload: request.payload ? request.payload : null,
|
||||
});
|
||||
if (res.type === 'ok') {
|
||||
let d = res.data;
|
||||
if (d.state === 'rejected') {
|
||||
return { type: 'rejected' };
|
||||
}
|
||||
if (d.state === 'sent') {
|
||||
return { type: 'success', response: d.result };
|
||||
}
|
||||
throw Error('Unknown reponse');
|
||||
}
|
||||
throw Error(res.message);
|
||||
}
|
||||
}
|
|
@ -12,4 +12,11 @@ export {
|
|||
TonhubSignRequest,
|
||||
TonhubSignResponse,
|
||||
TonhubWalletConfig
|
||||
} from './connector/TonhubConnector';
|
||||
} from './connector/TonhubConnector';
|
||||
|
||||
export {
|
||||
TonhubLocalConnector,
|
||||
TonhubLocalConfig,
|
||||
TonhubLocalTransactionRequest,
|
||||
TonhubLocalTransactionResponse
|
||||
} from './connector/TonhubLocalConnector';
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
export class TonhubEmbeddedTransport implements Transport {
|
||||
call<TResult, TArgs>(method: string, args: TArgs): Promise<TResult> {
|
||||
let tonX = TonhubEmbeddedTransport.get();
|
||||
if (!tonX) {
|
||||
throw new Error('ton-x not found');
|
||||
}
|
||||
|
||||
return tonX.call(method, args);
|
||||
}
|
||||
|
||||
private static get() {
|
||||
if (typeof window === 'undefined' || !(window as any)?.tonX) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return window && (window as any).tonX as {
|
||||
call: <TResult, TPayload>(type: string, payload: TPayload) => Promise<TResult>
|
||||
};
|
||||
}
|
||||
|
||||
static isAvailable() {
|
||||
return this.get() !== null;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import axios from 'axios';
|
||||
import { string } from 'fp-ts';
|
||||
|
||||
export class TonhubHttpTransport implements Transport {
|
||||
private readonly _endpoint: string;
|
||||
|
|
Loading…
Reference in New Issue