@coinbase/onchaintestkit
Version:
End-to-end testing toolkit for blockchain applications, powered by Playwright
197 lines (196 loc) • 6.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigBuilder = void 0;
exports.configure = configure;
const BaseWallet_1 = require("./wallets/BaseWallet");
const Coinbase_1 = require("./wallets/Coinbase");
const MetaMask_1 = require("./wallets/MetaMask");
/**
* Helper function to determine if a network is a testnet
* @param network - Network configuration
* @returns boolean indicating if the network is a testnet
*/
function isTestNetwork(network) {
return (network.name.toLowerCase().includes("test") ||
network.name.toLowerCase().includes("sepolia") ||
network.name.toLowerCase().includes("goerli"));
}
/**
* Base configuration builder that handles common wallet setup
*/
class BaseWalletBuilder {
constructor(config) {
this.config = config;
}
/**
* Helper method to chain multiple setup functions together.
* Ensures setup functions are executed in the order they were added.
*/
chainSetup(newSetup) {
const existingSetup = this.config.walletSetup;
this.config.walletSetup = async (wallet, context) => {
if (existingSetup) {
await existingSetup(wallet, context);
}
await newSetup(wallet, context);
};
}
/**
* Configure wallet with a seed phrase and optional password
* @param seedPhrase - The wallet's seed phrase
* @param password - Optional password for the wallet
*/
withSeedPhrase({ seedPhrase, password, }) {
this.config.password = password;
this.chainSetup(async (wallet) => {
await wallet.handleAction(BaseWallet_1.BaseActionType.IMPORT_WALLET_FROM_SEED, {
seedPhrase,
password,
});
});
return this;
}
/**
* Add custom setup steps to the wallet configuration
* @param setupFn - Custom function to perform additional wallet setup
*/
withCustomSetup(setupFn) {
this.chainSetup(setupFn);
return this;
}
setNodeConfig(config) {
this.nodeConfig = config;
}
/**
* Build the final wallet configuration
* @returns WalletFixtureOptions ready to be used with createOnchainTest
*/
build() {
if (!this.config.type) {
throw new Error("Wallet type must be specified");
}
const wallets = {
[this.config.type]: this.config,
};
return { wallets, nodeConfig: this.nodeConfig };
}
}
/**
* MetaMask-specific configuration builder
* Extends base builder with MetaMask-specific functionality
*/
class MetaMaskConfigBuilder extends BaseWalletBuilder {
// Add MetaMask-specific methods here
// add network and switch to it
withNetwork(network) {
this.chainSetup(async (wallet, context) => {
if (context?.localNodePort) {
// if the context has a localNodePort, use it to connect to the local node
network.rpcUrl = `http://localhost:${context.localNodePort}`;
}
console.log(`Adding network with RPC URL: ${network.rpcUrl}`);
// Add the network with the possibly modified URL
await wallet.handleAction(MetaMask_1.MetaMaskSpecificActionType.ADD_NETWORK, {
network,
isTestnet: isTestNetwork(network),
});
// Switch to the network
await wallet.handleAction(BaseWallet_1.BaseActionType.SWITCH_NETWORK, {
networkName: network.name,
isTestnet: isTestNetwork(network),
});
});
return this;
}
}
/**
* Coinbase-specific configuration builder
* Extends base builder with Coinbase-specific functionality
*/
class CoinbaseConfigBuilder extends BaseWalletBuilder {
// Add Coinbase-specific methods here
withNetwork(network) {
this.chainSetup(async (wallet, context) => {
if (context?.localNodePort) {
// if the context has a localNodePort, use it to connect to the local node
network.rpcUrl = `http://localhost:${context.localNodePort}`;
}
console.log(`Adding network with RPC URL: ${network.rpcUrl}`);
// Add the network with the possibly modified URL
await wallet.handleAction(Coinbase_1.CoinbaseSpecificActionType.ADD_NETWORK, {
network,
isTestnet: isTestNetwork(network),
});
// Switch to the network
await wallet.handleAction(BaseWallet_1.BaseActionType.SWITCH_NETWORK, {
networkName: network.name,
isTestnet: isTestNetwork(network),
});
});
return this;
}
}
/**
* Main configuration builder that initializes wallet-specific builders
*/
class ConfigBuilder {
constructor() {
this.config = {};
}
/**
* Initialize MetaMask configuration
* @returns MetaMask-specific builder
*/
withMetaMask() {
this.config = { type: "metamask" };
const builder = new MetaMaskConfigBuilder(this.config);
if (this.nodeConfig) {
builder.setNodeConfig(this.nodeConfig);
}
return builder;
}
/**
* Initialize Coinbase configuration
* @returns Coinbase-specific builder
*/
withCoinbase() {
this.config = { type: "coinbase" };
const builder = new CoinbaseConfigBuilder(this.config);
if (this.nodeConfig) {
builder.setNodeConfig(this.nodeConfig);
}
return builder;
}
/**
* Configure the local Anvil node
* @param config - Node configuration options
* @returns This builder for chaining
*/
withLocalNode(config = {}) {
this.nodeConfig = config;
return this;
}
/**
* Build the final configuration
* @returns Configuration object ready to be used with createOnchainTest
*/
build() {
if (!this.config.type) {
throw new Error("Wallet type must be specified");
}
const wallets = {
[this.config.type]: this.config,
};
return {
options: { wallets },
};
}
}
exports.ConfigBuilder = ConfigBuilder;
/**
* Creates a new configuration builder
* @returns ConfigBuilder instance
*/
function configure() {
return new ConfigBuilder();
}