@magiceden/magiceden-sdk
Version:
A TypeScript SDK for interacting with Magic Eden's API across multiple chains.
170 lines (169 loc) • 5.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ViemWalletProvider = void 0;
const viem_1 = require("viem");
const evmWalletProvider_1 = require("./evmWalletProvider");
const accounts_1 = require("viem/accounts");
const chain_1 = require("../../helpers/evm/chain");
/**
* Implementation of EvmWalletProvider using Viem library
*/
class ViemWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
/**
* Creates a new Ethereum wallet adapter using Viem
*/
constructor(config) {
super();
this.wallet = (0, viem_1.createWalletClient)({
account: (0, accounts_1.privateKeyToAccount)(config.privateKey),
chain: (0, chain_1.getViemChainFromBlockchain)(config.blockchain),
transport: (0, viem_1.http)(),
});
this.rpcClient = (0, viem_1.createPublicClient)({
chain: (0, chain_1.getViemChainFromBlockchain)(config.blockchain),
transport: (0, viem_1.http)(),
});
// Set gas configuration with defaults
this.gasOptions = {
limitMultiplier: Math.max(config.options?.gas?.limitMultiplier ?? 1.2, 1),
feeMultiplier: Math.max(config.options?.gas?.feeMultiplier ?? 1, 1),
};
}
/**
* Gets the current wallet address
*/
getAddress() {
return this.wallet.account?.address ?? '';
}
/**
* Retrieves the wallet's native token balance
*/
async getBalance() {
const account = this.validateAccount();
return this.rpcClient.getBalance({ address: account.address });
}
/**
* Signs a message with the wallet's private key
*/
async signMessage(message) {
const account = this.validateAccount();
return this.wallet.signMessage({ account, message });
}
/**
* Signs EIP-712 typed data
*/
async signTypedData(data) {
const account = this.validateAccount();
return this.wallet.signTypedData({
account,
domain: data.domain,
types: data.types,
primaryType: data.primaryType,
message: data.message,
});
}
/**
* Signs a transaction without broadcasting it
*/
async signTransaction(tx) {
const account = this.validateAccount();
return this.wallet.signTransaction({
account,
to: tx.to,
value: tx.value,
data: tx.data,
chain: this.wallet.chain,
});
}
/**
* Signs and broadcasts a transaction
*/
async signAndSendTransaction(tx) {
const account = this.validateAccount();
const chain = this.validateChain();
// Calculate gas parameters with multipliers
const { gas, maxFeePerGas, maxPriorityFeePerGas } = await this.calculateGasParameters(tx, account);
return this.wallet.sendTransaction({
account,
chain,
to: tx.to,
value: tx.value,
data: tx.data,
gas,
maxFeePerGas,
maxPriorityFeePerGas,
});
}
/**
* Waits for transaction confirmation and returns receipt
*/
async waitForTransactionConfirmation(txHash) {
const receipt = await this.rpcClient.waitForTransactionReceipt({ hash: txHash });
return {
txId: txHash,
status: receipt.status === 'success' ? 'confirmed' : 'failed',
error: receipt.status === 'reverted' ? 'Transaction reverted' : undefined,
metadata: {
from: receipt.from,
to: receipt.to,
contractAddress: receipt.contractAddress,
status: receipt.status,
transactionHash: receipt.transactionHash,
blockHash: receipt.blockHash,
blockNumber: receipt.blockNumber,
transactionIndex: receipt.transactionIndex,
logs: receipt.logs,
logsBloom: receipt.logsBloom,
type: receipt.type,
gasUsed: receipt.gasUsed,
effectiveGasPrice: receipt.effectiveGasPrice,
cumulativeGasUsed: receipt.cumulativeGasUsed,
},
};
}
/**
* Calls a read-only contract method
*/
async readContract(params) {
return this.rpcClient.readContract(params);
}
/**
* Helper to ensure account is available
*/
validateAccount() {
const account = this.wallet.account;
if (!account) {
throw new Error('No account connected to wallet');
}
return account;
}
/**
* Helper to ensure chain is available
*/
validateChain() {
const chain = this.wallet.chain;
if (!chain) {
throw new Error('No chain configured for wallet');
}
return chain;
}
/**
* Calculate gas parameters with configured multipliers
*/
async calculateGasParameters(tx, account) {
// Estimate gas fees
const feeData = await this.rpcClient.estimateFeesPerGas();
const maxFeePerGas = BigInt(Math.round(Number(feeData?.maxFeePerGas) * this.gasOptions.feeMultiplier));
const maxPriorityFeePerGas = BigInt(Math.round(Number(feeData?.maxPriorityFeePerGas) * this.gasOptions.feeMultiplier));
// Estimate gas limit
const gasEstimate = await this.rpcClient.estimateGas({
account,
to: tx.to,
value: tx.value,
data: tx.data,
});
const gas = BigInt(Math.round(Number(gasEstimate) * this.gasOptions.limitMultiplier));
return { gas, maxFeePerGas, maxPriorityFeePerGas };
}
}
exports.ViemWalletProvider = ViemWalletProvider;