Skip to content

Commit

Permalink
chore: refactor handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
Keyrxng committed Aug 29, 2024
1 parent 11caa68 commit b3d85ab
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 67 deletions.
68 changes: 15 additions & 53 deletions src/handlers/faucet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,85 +2,47 @@ import { BigNumber, ethers } from "ethers";
import { Args, Context } from "../types";
import { logAndComment, throwError } from "../utils/logger";
import { NetworkId, RPCHandler } from "@ubiquity-dao/rpc-handler";
import { register } from "./register";

function isEthAddress(address: string) {
if (!address) return false;
return /^0x[a-fA-F0-9]{40}$/.test(address);
}

export async function faucet(context: Context, args: Args) {
const { config, storage } = context;
const { recipient, networkId, amount, token } = args;
const { config } = context;
const { recipient, networkId, amount } = args;

const userStorage = storage.getUserStorage(recipient);
if (!userStorage.wallet) {
return await register(context as Context<"issue_comment.created">, args);
if (!isEthAddress(recipient)) {
return throwError("Invalid recipient address", { recipient });
}

let value = amount || BigInt(0);
const isNative = token === "native";
const isWithoutTokenAndAmount = !(amount || token);
const isWithRecipientAndNetwork = recipient && networkId;
const isDefaultNative = isWithoutTokenAndAmount && isWithRecipientAndNetwork;

if (isNative || isDefaultNative) {
/**
* "/faucet <recipient> <networkId> <amount> <token>"
* OR
* "/faucet <recipient> <networkId>"
*/

if (value && value === BigInt(0) && config?.nativeGasToken) {
value = config.nativeGasToken;
}
} else if (isWithRecipientAndNetwork && token && isEthAddress(token)) {
/**
* "/faucet <recipient> <networkId> <amount> <token>"
*/
if (value && value === BigInt(0) && config.distributionTokens?.[token]) {
value = config.distributionTokens[token];
}
} else {
return throwError(`Incorrect arguments provided:`, { recipient, networkId, amount, token });
if (!networkId) {
return throwError("Network ID must be provided", { networkId });
}

if (!value || value <= BigInt(0)) {
return throwError("Invalid amount");
if (!amount) {
return throwError("Amount must be provided", { amount });
}

const wallet = await getWalletSigner(config.fundingWalletPrivateKey, networkId);
const transfer = await handleTransfer(context, wallet, userStorage.wallet, value, isNative, token);
const tx = await handleTransfer(context, wallet, recipient, amount);

if (transfer && transfer.transactionHash) {
userStorage.claimed++;
userStorage.lastClaim = new Date();
storage.setUserStorage(recipient, userStorage);
if (tx) {
context.logger.info(`Successfully sent ${amount} to ${recipient} on network ${networkId}`);
return tx;
}

return transfer;
return null;
}

export async function handleTransfer(context: Context, wallet: ethers.Wallet, recipient: string, value: bigint, isNative: boolean, token?: string) {
export async function handleTransfer(context: Context, wallet: ethers.Wallet, recipient: string, value: bigint) {
try {
let tx: ethers.providers.TransactionResponse | null = null;

if (isNative) {
tx = await wallet.sendTransaction({ to: recipient, value: BigNumber.from(value) });
} else if (token) {
const contract = new ethers.Contract(token, ["function transfer(address to, uint256 value)"], wallet.provider);
tx = await contract.transfer(recipient, value);
} else {
throwError("Token address must be provided for non-native transfers", { recipient, value, isNative, token });
}

const tx: ethers.providers.TransactionResponse = await wallet.sendTransaction({ to: recipient, value: BigNumber.from(value) });
return tx?.hash ? await wallet.provider?.waitForTransaction(tx.hash) : null;
} catch (err) {
throw await logAndComment(context, "error", "Failed to send transaction", {
err,
recipient,
isNative,
token,
success: false,
value: ethers.BigNumber.from(value).toString(),
});
Expand Down
24 changes: 10 additions & 14 deletions src/handlers/gas-subsidize.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { Context } from "../types";
import { register } from "./register";
import { logAndComment, throwError } from "../utils/logger";
import { throwError } from "../utils/logger";
import { faucet } from "./faucet";

export async function gasSubsidize(context: Context) {
const {
payload,
storage,
config: { howManyTimesUserCanClaim, networkIds, nativeGasToken },
config: { networkId, gasSubsidyAmount },
adapters: { supabase },
} = context;
const { issue } = payload;

Expand All @@ -21,28 +20,25 @@ export async function gasSubsidize(context: Context) {
users = issue.assignees;
} else if (issue.assignee) {
users = [issue.assignee];
} else {
users = [];
}

users.push(issue.user);

const txs = [];

for (const user of users) {
if (!user?.login) continue;
const { wallet, lastClaim, claimed } = storage.getUserStorage(user.login);
if (!wallet) {
await register(context as Context<"issue_comment.created">, { recipient: user.login, networkId: "1", amount: BigInt(0), token: "native" });
const userWallet = await supabase.user.getWalletByUserId(user.id, payload.issue.id);
if (!userWallet) {
continue;
}
if (lastClaim && claimed < howManyTimesUserCanClaim) {
await logAndComment(context, "info", `User ${user.login} has already claimed ${claimed} times`);

if (await supabase.user.hasClaimedBefore(user.id)) {
context.logger.info(`User ${user.login} has already claimed a gas subsidy`);
continue;
}

for (const networkId of networkIds) {
txs.push(await faucet(context, { recipient: user.login, networkId: String(networkId), amount: nativeGasToken, token: "native" }));
}
txs.push(await faucet(context, { recipient: userWallet, networkId, amount: gasSubsidyAmount }));
}

return txs;
Expand Down

0 comments on commit b3d85ab

Please sign in to comment.