@pushchain/ui-kit
Version:
## Overview
229 lines • 12 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PhantomProvider = void 0;
const tslib_1 = require("tslib");
const ethers_1 = require("ethers");
const BaseWalletProvider_1 = require("../BaseWalletProvider");
const wallet_types_1 = require("../../../types/wallet.types");
const web3_js_1 = require("@solana/web3.js");
const viem_1 = require("viem");
const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
const chains_1 = require("viem/chains");
class PhantomProvider extends BaseWalletProvider_1.BaseWalletProvider {
constructor() {
super('Phantom', 'https://www.phantom.app/img/logo.png', [
wallet_types_1.ChainType.ETHEREUM,
wallet_types_1.ChainType.SOLANA,
]);
this.connectedChainType = null;
this.isInstalled = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
return (typeof window !== 'undefined' && typeof window.phantom !== 'undefined');
});
this.connectEthereum = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b;
if (!((_a = window.phantom) === null || _a === void 0 ? void 0 : _a.ethereum)) {
throw new Error('Phantom not installed for Ethereum');
}
const provider = (_b = window.phantom) === null || _b === void 0 ? void 0 : _b.ethereum;
const accounts = yield provider.request({ method: 'eth_requestAccounts' });
const rawAddress = accounts[0];
const checksumAddress = (0, ethers_1.getAddress)(rawAddress);
const chainId = yield this.getChainId(wallet_types_1.ChainType.ETHEREUM);
this.connectedChainType = wallet_types_1.ChainType.ETHEREUM;
const caipAddress = this.formatAddress(checksumAddress, wallet_types_1.ChainType.ETHEREUM, chainId);
return caipAddress;
});
this.connectSolana = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b;
if (!((_a = window.phantom) === null || _a === void 0 ? void 0 : _a.solana)) {
throw new Error('Phantom not installed for Solana');
}
const provider = (_b = window.phantom) === null || _b === void 0 ? void 0 : _b.solana;
const accounts = yield provider.connect();
const chainId = yield this.getChainId(wallet_types_1.ChainType.SOLANA);
this.connectedChainType = wallet_types_1.ChainType.SOLANA;
const caipAddress = this.formatAddress(accounts.publicKey.toString(), wallet_types_1.ChainType.SOLANA, chainId);
return caipAddress;
});
this.connect = (chainType) => tslib_1.__awaiter(this, void 0, void 0, function* () {
let account;
if (!chainType || chainType === wallet_types_1.ChainType.SOLANA) {
account = this.connectSolana();
}
else if (chainType === wallet_types_1.ChainType.ETHEREUM) {
account = this.connectEthereum();
}
if (!account) {
throw new Error('Error in connecting to phantom');
}
return account;
});
this.getChainId = (chainType) => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b;
if (chainType === wallet_types_1.ChainType.ETHEREUM) {
const provider = (_a = window.phantom) === null || _a === void 0 ? void 0 : _a.ethereum;
if (!provider)
throw new Error('No Phantom Ethereum wallet connected');
const chainId = yield provider.request({ method: 'eth_chainId' });
return parseInt(chainId, 16);
}
else if (chainType === wallet_types_1.ChainType.SOLANA) {
const provider = (_b = window.phantom) === null || _b === void 0 ? void 0 : _b.solana;
if (!provider)
throw new Error('No Phantom Solana wallet connected');
return provider.chainId || 1;
}
throw new Error('No Phantom wallet connected');
});
this.signMessage = (message) => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const isInstalled = this.isInstalled();
if (!isInstalled) {
throw new Error('No Phantom wallet installed');
}
if (this.connectedChainType === wallet_types_1.ChainType.SOLANA && ((_a = window.phantom) === null || _a === void 0 ? void 0 : _a.solana)) {
try {
const provider = (_b = window.phantom) === null || _b === void 0 ? void 0 : _b.solana;
const signedMessage = yield provider.signMessage(message, 'utf8');
return signedMessage.signature;
}
catch (error) {
console.error('Phantom Solana signing error:', error);
throw error;
}
}
else if (this.connectedChainType === wallet_types_1.ChainType.ETHEREUM && ((_c = window.phantom) === null || _c === void 0 ? void 0 : _c.ethereum)) {
try {
const provider = (_d = window.phantom) === null || _d === void 0 ? void 0 : _d.ethereum;
const accounts = yield provider.request({
method: 'eth_accounts',
});
if (!accounts || accounts.length === 0) {
throw new Error('No connected account');
}
const hexMessage = (0, viem_1.bytesToHex)(message);
const signature = yield provider.request({
method: 'personal_sign',
params: [hexMessage, accounts[0]],
});
return (0, viem_1.hexToBytes)(signature);
}
catch (error) {
console.error('Phantom Ethereum signing error:', error);
throw error;
}
}
else {
throw new Error('No Phantom wallet connected');
}
});
this.signAndSendTransaction = (txn) => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const isInstalled = this.isInstalled();
if (!isInstalled) {
throw new Error('No Phantom wallet installed');
}
if (this.connectedChainType === wallet_types_1.ChainType.SOLANA && ((_a = window.phantom) === null || _a === void 0 ? void 0 : _a.solana)) {
try {
const provider = (_b = window.phantom) === null || _b === void 0 ? void 0 : _b.solana;
const transaction = web3_js_1.Transaction.from(txn);
const signedTransaction = yield provider.signAndSendTransaction(transaction);
return bytes_1.bs58.decode(signedTransaction.signature);
}
catch (error) {
console.error('Phantom Solana signing error:', error);
throw error;
}
}
else if (this.connectedChainType === wallet_types_1.ChainType.ETHEREUM && ((_c = window.phantom) === null || _c === void 0 ? void 0 : _c.ethereum)) {
try {
const provider = (_d = window.phantom) === null || _d === void 0 ? void 0 : _d.ethereum;
const accounts = yield provider.request({
method: 'eth_accounts',
});
if (!accounts || accounts.length === 0) {
throw new Error('No connected account');
}
const hex = (0, viem_1.bytesToHex)(txn);
const parsed = (0, viem_1.parseTransaction)(hex);
const txParams = {
from: accounts[0],
to: parsed.to,
value: parsed.value ? '0x' + parsed.value.toString(16) : undefined,
data: parsed.data,
gas: parsed.gas ? '0x' + parsed.gas.toString(16) : undefined,
maxPriorityFeePerGas: parsed.maxPriorityFeePerGas
? '0x' + parsed.maxPriorityFeePerGas.toString(16)
: undefined,
maxFeePerGas: parsed.maxFeePerGas
? '0x' + parsed.maxFeePerGas.toString(16)
: undefined,
};
const signature = yield provider.request({
method: 'eth_sendTransaction',
params: [txParams],
});
return (0, viem_1.hexToBytes)(signature);
}
catch (error) {
console.error('Phantom Ethereum signing error:', error);
throw error;
}
}
else {
throw new Error('No Phantom wallet connected');
}
});
this.signTypedData = (typedData) => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b;
const isInstalled = this.isInstalled();
if (!isInstalled) {
throw new Error('No Phantom wallet installed');
}
if (this.connectedChainType === wallet_types_1.ChainType.SOLANA && ((_a = window.phantom) === null || _a === void 0 ? void 0 : _a.solana)) {
throw new Error('signTypedData is not implemented for this provider');
}
else if (this.connectedChainType === wallet_types_1.ChainType.ETHEREUM && ((_b = window.phantom) === null || _b === void 0 ? void 0 : _b.ethereum)) {
try {
const walletClient = (0, viem_1.createWalletClient)({
chain: chains_1.sepolia,
transport: (0, viem_1.custom)(window.ethereum),
});
const accounts = yield walletClient.request({
method: 'eth_accounts',
});
if (!accounts || accounts.length === 0) {
throw new Error('No connected account');
}
const signature = yield walletClient.signTypedData(Object.assign({ account: accounts[0] }, typedData));
return (0, viem_1.hexToBytes)(signature);
}
catch (error) {
console.error('Phantom Ethereum signing error:', error);
throw error;
}
}
else {
throw new Error('No Phantom wallet connected');
}
});
this.disconnect = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
const isInstalled = this.isInstalled();
if (!isInstalled)
return;
if (this.connectedChainType === wallet_types_1.ChainType.SOLANA && ((_a = window.phantom) === null || _a === void 0 ? void 0 : _a.solana)) {
const provider = (_b = window.phantom) === null || _b === void 0 ? void 0 : _b.solana;
this.connectedChainType = null;
yield provider.disconnect();
}
if (this.connectedChainType === wallet_types_1.ChainType.ETHEREUM && ((_c = window.phantom) === null || _c === void 0 ? void 0 : _c.ethereum)) {
this.connectedChainType = null;
//TOOD: find how to disconnect ethereum
}
return Promise.resolve();
});
}
}
exports.PhantomProvider = PhantomProvider;
//# sourceMappingURL=phantom.js.map