ribbit-wallet-connect
Version:
Next-generation multi-chain wallet and payments app that makes crypto simple, secure, and usable in daily life.
180 lines (179 loc) • 9.47 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RibbitWalletClient = void 0;
const aptos = __importStar(require("@aptos-labs/ts-sdk"));
const supra_l1_sdk_core_1 = require("supra-l1-sdk-core");
const types_1 = require("../core/types");
const app_transport_1 = require("../transport/app-transport");
const extension_transport_1 = require("../transport/extension-transport");
const storage = __importStar(require("../utils/storage"));
const validation_1 = require("../utils/validation");
const constants_1 = require("../core/constants");
const buffer_1 = require("buffer");
const api_service_1 = require("../services/api-service");
const utils_1 = require("../utils/utils");
class RibbitWalletClient {
constructor() {
this.transport = null;
this.wallet = null;
}
initialize() {
var _a, _b, _c;
if (typeof window === 'undefined')
return;
if (((_a = window.ribbit) === null || _a === void 0 ? void 0 : _a.type) === 'app') {
this.transport = new app_transport_1.AppTransport();
}
else if (((_b = window.ribbit) === null || _b === void 0 ? void 0 : _b.type) === 'extension') {
this.transport = new extension_transport_1.ExtensionTransport();
}
else {
throw new Error(`Unknown ribbit type: ${(_c = window.ribbit) === null || _c === void 0 ? void 0 : _c.type}`);
}
this.transport.listen();
// Restore previous "connected" state for smoother UX
const stored = storage.getWallet();
if (stored) {
this.wallet = { walletAddress: stored, connected: true };
}
}
async connectToWallet(dapp) {
var _a, _b, _c;
if (!this.transport)
throw new Error('No transport available');
const { data } = await this.transport.sendMessage(types_1.TransportMessageType.CONNECT_REQUEST, { dapp });
if (!(data === null || data === void 0 ? void 0 : data.approved) || !((_a = data.accounts) === null || _a === void 0 ? void 0 : _a.length)) {
throw new Error(`Connection to wallet failed: ${data.error || 'Unknown error'}`);
}
const walletAddress = (_c = (_b = data.accounts) === null || _b === void 0 ? void 0 : _b.filter((addr) => addr.chain === constants_1.CHAIN_TYPE.SUPRA)[0]) === null || _c === void 0 ? void 0 : _c.walletAddress;
if (walletAddress === undefined) {
throw new Error('No wallet address found');
}
this.wallet = { walletAddress, connected: true };
storage.saveWallet(walletAddress);
return this.wallet;
}
async disconnect() {
this.wallet = null;
storage.clearWallet();
if (this.transport) {
return await this.transport.sendMessage(types_1.TransportMessageType.DISCONNECT_REQUEST, {});
}
}
async getWalletBalance(walletBalanceRequest) {
if (!this.transport)
throw new Error('No transport available');
if (!this.wallet)
throw new Error('Not connected');
const { chainId, resourceType, decimals } = walletBalanceRequest;
const formattedResourceType = resourceType.startsWith('<')
? resourceType
: `<${resourceType}>`;
const balance = await this.transport.sendMessage(types_1.TransportMessageType.GET_WALLET_BALANCE, {
chainId,
resourceType: formattedResourceType,
decimals,
});
return balance;
}
getWalletInfo() {
return this.wallet;
}
async createRawTransactionBuffer(rawTxnRequest, format = types_1.RawTxnFormat.supra) {
const { sender, moduleAddress, moduleName, functionName, typeArgs, args, chainId, } = rawTxnRequest;
try {
validation_1.ValidationUtils.validateRawTxnRequest(rawTxnRequest);
const expirationTimestampSecs = Math.floor(Date.now() / 1000) + 300;
const { network } = (0, utils_1.getNetworkAndChain)(chainId);
const sequenceNumber = await (0, api_service_1.getSequenceNumber)(sender, network);
const gasPrice = await (0, api_service_1.getGasPrice)(network);
if (format === types_1.RawTxnFormat.supra) {
const supraTypeTags = (typeArgs || []).map((t) => {
if (typeof t === 'string') {
return new supra_l1_sdk_core_1.TxnBuilderTypes.TypeTagParser(t).parseTypeTag();
}
else if (typeof t === 'object' && t !== null) {
return t;
}
else {
throw new Error(`Invalid type arg sent. Type arg should be a string or TxnBuilderTypes.TypeTag, ${t}`);
}
});
const entryFunction = supra_l1_sdk_core_1.TxnBuilderTypes.EntryFunction.natural(`${moduleAddress}::${moduleName}`, functionName, supraTypeTags, args);
const payload = new supra_l1_sdk_core_1.TxnBuilderTypes.TransactionPayloadEntryFunction(entryFunction);
const rawTxn = new supra_l1_sdk_core_1.TxnBuilderTypes.RawTransaction(supra_l1_sdk_core_1.TxnBuilderTypes.AccountAddress.fromHex(new supra_l1_sdk_core_1.HexString(sender)), BigInt(sequenceNumber), payload, BigInt(Math.floor(gasPrice.max_gas_price * 50)), BigInt(Math.floor(gasPrice.mean_gas_price)), BigInt(expirationTimestampSecs), new supra_l1_sdk_core_1.TxnBuilderTypes.ChainId(chainId));
const rawTxnBase64 = buffer_1.Buffer.from(supra_l1_sdk_core_1.BCS.bcsToBytes(rawTxn)).toString('base64');
return rawTxnBase64;
}
else if (format === types_1.RawTxnFormat.aptos) {
const aptosTypeTags = (typeArgs || []).map((t) => {
if (typeof t === 'string')
return aptos.parseTypeTag(t);
return t;
});
const entryFunc = new aptos.EntryFunction(new aptos.ModuleId(aptos.AccountAddress.fromString(moduleAddress), new aptos.Identifier(moduleName)), new aptos.Identifier(functionName), aptosTypeTags, args);
const payload = new aptos.TransactionPayloadEntryFunction(entryFunc);
const rawTxn = new aptos.RawTransaction(aptos.AccountAddress.fromString(sender), BigInt(sequenceNumber), payload, BigInt(gasPrice.max_gas_price * 50), BigInt(gasPrice.mean_gas_price), BigInt(expirationTimestampSecs), new aptos.ChainId(chainId));
const serializer = new aptos.Serializer();
rawTxn.serialize(serializer);
const rawTxnBase64 = buffer_1.Buffer.from(serializer.toUint8Array()).toString('base64');
return rawTxnBase64;
}
else {
throw new Error(`Unsupported format sent`);
}
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to create raw transaction buffer: ${errorMessage}`);
}
}
async signMessage(messageRequest) {
if (!this.transport)
throw new Error('No transport available');
if (!this.wallet)
throw new Error('Not connected');
return this.transport.sendMessage(types_1.TransportMessageType.SIGN_MESSAGE, Object.assign({}, messageRequest));
}
async signAndSendRawTransaction(tx) {
if (!this.transport)
throw new Error('No transport available');
if (!this.wallet)
throw new Error('Wallet not connected');
if (!validation_1.ValidationUtils.validateTransactionPayload(tx))
throw new Error('Invalid tx payload');
return this.transport.sendMessage(types_1.TransportMessageType.SEND_TRANSACTION, Object.assign({}, tx));
}
onChangeWallet(handler) {
var _a, _b;
(_b = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.on) === null || _b === void 0 ? void 0 : _b.call(_a, types_1.TransportMessageType.WALLET_CHANGED, handler);
}
onChangeNetwork(handler) {
var _a, _b;
(_b = (_a = this.transport) === null || _a === void 0 ? void 0 : _a.on) === null || _b === void 0 ? void 0 : _b.call(_a, types_1.TransportMessageType.NETWORK_CHANGED, handler);
}
}
exports.RibbitWalletClient = RibbitWalletClient;