UNPKG

@hashgraph/hedera-wallet-connect

Version:

A library to facilitate integrating Hedera with WalletConnect

125 lines (124 loc) 5.57 kB
import { JsonRpcProvider, Wallet, Transaction, } from 'ethers'; import { formatJsonRpcError, formatJsonRpcResult, } from '@walletconnect/jsonrpc-utils'; import { getSdkError } from '@walletconnect/utils'; import { Eip155JsonRpcMethod, HederaChainDefinition, getSignParamsMessage, getSignTypedDataParamsData, } from '..'; /** * Library */ export class EIP155Wallet { constructor(wallet) { this.wallet = wallet; } connect(provider) { return this.wallet.connect(provider); } personal_sign(message) { return this.eth_sign(message); } eth_sign(message) { return this.wallet.signMessage(message); } eth_signTypedData(domain, types, data) { return this.wallet.signTypedData(domain, types, data); } eth_signTypedData_v3(domain, types, data) { return this.eth_signTypedData(domain, types, data); } eth_signTypedData_v4(domain, types, data) { return this.eth_signTypedData(domain, types, data); } async eth_signTransaction(transaction, provider) { // Populate transaction const preparedTransaction = await this.connect(provider).populateTransaction(transaction); delete preparedTransaction.from; const txObj = Transaction.from(preparedTransaction); return this.wallet.signTransaction(txObj); } eth_sendTransaction(transaction, provider) { return this.connect(provider).sendTransaction(transaction); } eth_sendRawTransaction(rawTransaction, provider) { return provider.broadcastTransaction(rawTransaction); } static init({ privateKey }) { const wallet = privateKey ? new Wallet(privateKey) : Wallet.createRandom(); return new EIP155Wallet(wallet); } getPrivateKey() { return this.wallet.privateKey; } getEvmAddress() { return this.wallet.address; } async approveSessionRequest(requestEvent) { const { params, id } = requestEvent; const { chainId, request } = params; const networks = Object.values(HederaChainDefinition.EVM); const caipNetwork = networks.find((network) => network.caipNetworkId == chainId); if (!caipNetwork) { return formatJsonRpcError(id, 'Unsupported network'); } switch (request.method) { case Eip155JsonRpcMethod.PersonalSign: case Eip155JsonRpcMethod.Sign: try { const message = getSignParamsMessage(request.params); const signedMessage = await this.eth_sign(message); return formatJsonRpcResult(id, signedMessage); } catch (error) { if (!(error instanceof Error)) { return formatJsonRpcError(id, 'Failed to sign message'); } return formatJsonRpcError(id, error.message); } case Eip155JsonRpcMethod.SignTypedData: case Eip155JsonRpcMethod.SignTypedDataV3: case Eip155JsonRpcMethod.SignTypedDataV4: try { const { domain, types, message: data } = getSignTypedDataParamsData(request.params); // https://github.com/ethers-io/ethers.js/issues/687#issuecomment-714069471 delete types.EIP712Domain; const signedData = await this.eth_signTypedData(domain, types, data); return formatJsonRpcResult(id, signedData); } catch (error) { if (!(error instanceof Error)) { return formatJsonRpcError(id, 'Failed to sign typed data'); } return formatJsonRpcError(id, error.message); } case Eip155JsonRpcMethod.SendRawTransaction: case Eip155JsonRpcMethod.SendTransaction: try { const provider = new JsonRpcProvider(caipNetwork.rpcUrls.default.http[0]); const sendTransaction = request.params[0]; const txResponse = await this[request.method](sendTransaction, provider); const txHash = typeof txResponse === 'string' ? txResponse : txResponse === null || txResponse === void 0 ? void 0 : txResponse.hash; return formatJsonRpcResult(id, txHash); } catch (error) { return formatJsonRpcError(id, error instanceof Error ? error.message : 'Failed to send transaction'); } case Eip155JsonRpcMethod.SignTransaction: try { const provider = new JsonRpcProvider(caipNetwork.rpcUrls.default.http[0]); const signTransaction = request.params[0]; const signature = await this.eth_signTransaction(signTransaction, provider); return formatJsonRpcResult(id, signature); } catch (error) { if (!(error instanceof Error)) { return formatJsonRpcError(id, 'Failed to sign transaction'); } return formatJsonRpcError(id, error.message); } default: throw new Error(getSdkError('INVALID_METHOD').message); } } rejectSessionRequest(requestEvent) { const { id } = requestEvent; return formatJsonRpcError(id, getSdkError('USER_REJECTED').message); } }