@river-build/web3
Version:
Dapps for our Space and Registry contracts
112 lines • 3.77 kB
JavaScript
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