@tmawallet/sdk
Version:
TMA Wallet SDK
127 lines • 4.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TMAWalletClient = void 0;
const eventemitter3_1 = require("eventemitter3");
const sdk_1 = require("@twa-dev/sdk");
const hmacSha256_1 = require("./utils/hmacSha256");
const hexToUint8Array_1 = require("./utils/hexToUint8Array");
const uint8ArrayToHex_1 = require("./utils/uint8ArrayToHex");
const ClientBundleController_1 = require("./client/ClientBundleController");
const TelegramCloudStorage_1 = require("./storage/TelegramCloudStorage");
const MAIN_ENDPOINT = 'https://api.tmawallet.com';
class TMAWalletClient extends eventemitter3_1.EventEmitter {
projectPublicToken;
_bundle = null;
telegramInitData;
storage;
endpoint;
clientBundleController;
constructor(projectPublicToken, options = {}) {
super();
this.projectPublicToken = projectPublicToken;
this.endpoint = options.endpoint ?? MAIN_ENDPOINT;
this.telegramInitData = options.telegramInitData || sdk_1.default.initData;
this.storage = options.storage ?? new TelegramCloudStorage_1.TelegramCloudStorage();
this.clientBundleController = new ClientBundleController_1.ClientBundleController(this.storage);
}
get isBundleExists() {
return !!this._bundle;
}
get bundle() {
return this._bundle;
}
async _init() {
this._bundle = await this.clientBundleController.getClientBundle();
}
async _authenticate() {
await this._init();
if (!this._bundle) {
await this._createBundle();
}
}
async _createBundle() {
if (this._bundle) {
throw new Error('Client bundle already exists');
}
this._bundle = await this.clientBundleController.createNewBundle();
}
async _storeWalletAddress(type, walletAddress) {
await fetch(`${this.endpoint}/wallet/address`, {
method: 'POST',
body: JSON.stringify({
type,
projectPublicToken: this.projectPublicToken,
telegramInitData: this.telegramInitData,
walletAddress,
}),
headers: {
'Content-Type': 'application/json',
},
});
}
async destroyBundleAndLoseWalletAccessForever() {
await this.clientBundleController.clearClientBundle();
this._bundle = null;
}
async getIntermediaryKeyAttempt(telegramInitData, clientPublicKey) {
const response = await fetch(`${this.endpoint}/wallet/access`, {
method: 'POST',
body: JSON.stringify({
projectPublicToken: this.projectPublicToken,
telegramInitData,
clientPublicKey: (0, uint8ArrayToHex_1.uint8ArrayToHex)(clientPublicKey),
}),
headers: {
'Content-Type': 'application/json',
},
});
const responseData = (await response.json());
if (responseData.result) {
const intermediaryKey = (0, hexToUint8Array_1.hexToUint8Array)(responseData.data.intermediaryKey);
return intermediaryKey;
}
else {
throw new Error(responseData.error);
}
}
async getIntermediaryKey(telegramInitData, clientPublicKey) {
const maxAttempts = 5;
let attempts = 0;
while (attempts < maxAttempts) {
try {
return await this.getIntermediaryKeyAttempt(telegramInitData, clientPublicKey);
}
catch (error) {
attempts++;
if (attempts >= maxAttempts) {
throw error;
}
await new Promise((resolve) => setTimeout(resolve, 600));
}
}
throw new Error('Failed to get intermediary key');
}
async restorePrivateKey(initData) {
if (!this._bundle) {
throw new Error('Client bundle does not exist');
}
const intermediaryKey = await this.getIntermediaryKey(initData, this._bundle.clientPublicKey);
const privateKey = await (0, hmacSha256_1.hmacSha256)(intermediaryKey, this._bundle.clientSecretKey);
return privateKey;
}
async accessPrivateKey() {
if (!this._bundle) {
throw new Error('Client bundle does not exist');
}
const privateKey = await this.restorePrivateKey(this.telegramInitData);
return privateKey;
}
async createBundle() {
if (this._bundle) {
throw new Error('Client bundle already exists');
}
this._bundle = await this.clientBundleController.createNewBundle();
}
}
exports.TMAWalletClient = TMAWalletClient;
//# sourceMappingURL=TMAWallet.Client.js.map