mirror of
https://github.com/0xbow-io/privacy-pools-core.git
synced 2026-01-09 17:37:58 -05:00
feat: adding relayer fee commitment with signed message
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
import { NextFunction, Request, Response } from "express";
|
||||
import { getAddress } from "viem";
|
||||
import { getAssetConfig } from "../../config/index.js";
|
||||
import { getAssetConfig, getFeeReceiverAddress } from "../../config/index.js";
|
||||
import { QuoterError } from "../../exceptions/base.exception.js";
|
||||
import { quoteProvider, web3Provider } from "../../providers/index.js";
|
||||
import { QuoteMarshall } from "../../types.js";
|
||||
import { encodeWithdrawalData } from "../../utils.js";
|
||||
|
||||
const TIME_20_SECS = 20 * 1000;
|
||||
|
||||
export async function relayQuoteHandler(
|
||||
req: Request,
|
||||
@@ -25,11 +28,28 @@ export async function relayQuoteHandler(
|
||||
const quote = await quoteProvider.quoteNativeTokenInERC20(chainId, tokenAddress, amountIn);
|
||||
const feeBPS = await quoteProvider.quoteFeeBPSNative(config.fee_bps, amountIn, quote, gasPrice, value);
|
||||
|
||||
const recipient = req.body.recipient ? getAddress(req.body.recipient.toString()) : undefined
|
||||
|
||||
const quoteResponse = new QuoteMarshall({
|
||||
baseFeeBPS: config.fee_bps,
|
||||
feeBPS,
|
||||
});
|
||||
|
||||
if (recipient) {
|
||||
const feeReceiverAddress = getFeeReceiverAddress(chainId);
|
||||
const withdrawalData = encodeWithdrawalData({
|
||||
feeRecipient: getAddress(feeReceiverAddress),
|
||||
recipient,
|
||||
relayFeeBPS: feeBPS
|
||||
})
|
||||
const expiration = Number(new Date()) + TIME_20_SECS
|
||||
const relayerCommitment = { withdrawalData, expiration };
|
||||
const signedRelayerCommitment = await web3Provider.signRelayerCommitment(chainId, relayerCommitment);
|
||||
quoteResponse.addFeeCommitment({ expiration, withdrawalData, signedRelayerCommitment })
|
||||
}
|
||||
|
||||
res
|
||||
.status(200)
|
||||
.json(res.locals.marshalResponse(new QuoteMarshall({
|
||||
baseFeeBPS: config.fee_bps,
|
||||
feeBPS,
|
||||
})));
|
||||
.json(res.locals.marshalResponse(quoteResponse));
|
||||
|
||||
}
|
||||
|
||||
@@ -8,10 +8,15 @@ export interface QuotetBody {
|
||||
/** Asset address */
|
||||
asset: string;
|
||||
/** Asset address */
|
||||
address?: string;
|
||||
recipient?: string;
|
||||
}
|
||||
|
||||
export interface QuoteResponse {
|
||||
baseFeeBPS: bigint,
|
||||
feeBPS: bigint,
|
||||
feeCommitment?: {
|
||||
expiration: number,
|
||||
withdrawalData: string
|
||||
signedRelayerCommitment: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
import { Chain, createPublicClient, http, PublicClient } from "viem";
|
||||
import { Chain, createPublicClient, Hex, http, PublicClient } from "viem";
|
||||
import {
|
||||
CONFIG
|
||||
CONFIG,
|
||||
getSignerPrivateKey
|
||||
} from "../config/index.js";
|
||||
import { createChainObject } from "../utils.js";
|
||||
import { privateKeyToAccount } from "viem/accounts";
|
||||
|
||||
interface IWeb3Provider {
|
||||
client(chainId: number): PublicClient;
|
||||
getGasPrice(chainId: number): Promise<bigint>;
|
||||
}
|
||||
|
||||
const domain = (chainId: number) => ({
|
||||
name: "Privacy Pools Relayer",
|
||||
version: "1",
|
||||
chainId,
|
||||
} as const)
|
||||
|
||||
const RelayerCommitmentTypes = {
|
||||
RelayerCommitment: [
|
||||
{ name: "withdrawalData", type: "bytes" },
|
||||
{ name: "expiration", type: "uint256" },
|
||||
]
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Class representing the provider for interacting with several chains
|
||||
*/
|
||||
@@ -42,4 +57,19 @@ export class Web3Provider implements IWeb3Provider {
|
||||
return await this.client(chainId).getGasPrice()
|
||||
}
|
||||
|
||||
async signRelayerCommitment(chainId: number, commitment: { withdrawalData: `0x${string}`, expiration: number }) {
|
||||
const pk = getSignerPrivateKey(chainId) as Hex;
|
||||
const signer = privateKeyToAccount(pk);
|
||||
const {withdrawalData, expiration} = commitment;
|
||||
return signer.signTypedData({
|
||||
domain: domain(chainId),
|
||||
types: RelayerCommitmentTypes,
|
||||
primaryType: 'RelayerCommitment',
|
||||
message: {
|
||||
withdrawalData,
|
||||
expiration: BigInt(expiration)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ const quoteSchema: JSONSchemaType<QuotetBody> = {
|
||||
chainId: { type: ["string", "number"] },
|
||||
amount: { type: ["string"] },
|
||||
asset: { type: ["string"] },
|
||||
address: { type: ["string"], nullable: true },
|
||||
recipient: { type: ["string"], nullable: true },
|
||||
},
|
||||
required: ["chainId", "amount", "asset"],
|
||||
} as const;
|
||||
|
||||
@@ -41,10 +41,20 @@ export class QuoteMarshall extends RelayerMarshall {
|
||||
constructor(readonly response: QuoteResponse) {
|
||||
super();
|
||||
}
|
||||
|
||||
addFeeCommitment(feeCommitment: {
|
||||
expiration: number
|
||||
withdrawalData: string,
|
||||
signedRelayerCommitment: string
|
||||
}) {
|
||||
this.response.feeCommitment = feeCommitment;
|
||||
}
|
||||
|
||||
override toJSON(): object {
|
||||
return {
|
||||
baseFeeBPS: this.response.baseFeeBPS.toString(),
|
||||
feeBPS: this.response.feeBPS.toString(),
|
||||
feeCommitment: this.response.feeCommitment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user