UNPKG

@river-build/web3

Version:

Dapps for our Space and Registry contracts

112 lines 3.77 kB
import { keccak256, parseEther } from 'viem/utils'; import { foundry } from 'viem/chains'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; import { createTestClient, http, publicActions, walletActions } from 'viem'; import { dlogger } from '@river-build/dlog'; const logger = dlogger('csb:TestGatingUtils'); export class Mutex { queue; locked; constructor() { this.queue = []; this.locked = false; } lock() { if (!this.locked) { this.locked = true; return Promise.resolve(); } let unlockNext; const promise = new Promise((resolve) => { unlockNext = resolve; }); this.queue.push(unlockNext); return promise; } unlock() { if (this.queue.length > 0) { const unlockNext = this.queue.shift(); unlockNext?.(); } else { this.locked = false; } } } export function toEIP55Address(address) { const addressHash = keccak256(address.substring(2).toLowerCase()); let checksumAddress = '0x'; for (let i = 2; i < address.length; i++) { if (parseInt(addressHash[i], 16) >= 8) { checksumAddress += address[i].toUpperCase(); } else { checksumAddress += address[i].toLowerCase(); } } return checksumAddress; } export function isEIP55Address(address) { return address === toEIP55Address(address); } export function isHexString(value) { // Check if the value is undefined first if (value === undefined) { return false; } return typeof value === 'string' && /^0x[0-9a-fA-F]+$/.test(value); } export async function deployContract(contractName, abi, bytecode, // bytecode is a hex string constructorArgs = []) { let retryCount = 0; let lastError; while (retryCount++ < 5) { try { const privateKey = generatePrivateKey(); const throwawayAccount = privateKeyToAccount(privateKey); const client = createTestClient({ chain: foundry, mode: 'anvil', transport: http(), account: throwawayAccount, }) .extend(publicActions) .extend(walletActions); await client.setBalance({ address: throwawayAccount.address, value: parseEther('1'), }); const hash = await client.deployContract({ abi, account: throwawayAccount, args: constructorArgs, bytecode, }); const receipt = await client.waitForTransactionReceipt({ hash }); if (receipt.contractAddress) { logger.info('deployed', receipt.contractAddress, isEIP55Address(receipt.contractAddress)); return toEIP55Address(receipt.contractAddress); } else { throw new Error(`Failed to deploy contract ${contractName}`); } } catch (e) { lastError = e; if (typeof e === 'object' && e !== null && 'message' in e && typeof e.message === 'string' && (e.message.includes('nonce too low') || e.message.includes('NonceTooLowError') || e.message.includes('Nonce provided for the transaction is lower than the current nonce'))) { logger.log('retrying because nonce too low', e, retryCount, contractName); } else { throw e; } } } throw lastError; } //# sourceMappingURL=TestGatingUtils.js.map