Skip to content

Commit ea6de2e

Browse files
authored
Add support for executeMetaTransaction (#309)
* Add support for executeMetaTransaction * Relayer working
1 parent f7887da commit ea6de2e

File tree

4 files changed

+91
-13
lines changed

4 files changed

+91
-13
lines changed

src/constants/relayer.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,19 @@ export const ERC20PermitAbi = [
134134
type: "function",
135135
},
136136
];
137+
138+
export const NativeMetaTransaction = [
139+
{
140+
inputs: [
141+
{ internalType: "address", name: "userAddress", type: "address" },
142+
{ internalType: "bytes", name: "functionSignature", type: "bytes" },
143+
{ internalType: "bytes32", name: "sigR", type: "bytes32" },
144+
{ internalType: "bytes32", name: "sigS", type: "bytes32" },
145+
{ internalType: "uint8", name: "sigV", type: "uint8" },
146+
],
147+
name: "executeMetaTransaction",
148+
outputs: [{ internalType: "bytes", name: "", type: "bytes" }],
149+
stateMutability: "payable",
150+
type: "function",
151+
},
152+
];

src/schema/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ export type ContractExtension =
1111
| "deploy-published"
1212
| "account-factory"
1313
| "account"
14-
| "forwarder";
14+
| "relayer";

src/server/routes/relayer/create.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ export async function createRelayer(fastify: FastifyInstance) {
4545
allowedForwarders,
4646
} = req.body;
4747

48+
const chainId = (await getChainIdFromChain(chain)).toString();
4849
const relayer = await prisma.relayers.create({
4950
data: {
50-
chainId: getChainIdFromChain(chain).toString(),
51+
chainId,
5152
backendWalletAddress,
5253
allowedContracts: allowedContracts
5354
? JSON.stringify(

src/server/routes/relayer/index.ts

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Static, Type } from "@sinclair/typebox";
2-
import { ethers } from "ethers";
2+
import { ethers, utils } from "ethers";
33
import { FastifyInstance } from "fastify";
44
import { StatusCodes } from "http-status-codes";
55
import {
66
ERC20PermitAbi,
77
ERC2771ContextAbi,
88
ForwarderAbi,
9+
NativeMetaTransaction,
910
} from "../../../constants/relayer";
1011
import { getRelayerById } from "../../../db/relayer/getRelayerById";
1112
import { queueTx } from "../../../db/transactions/queueTx";
@@ -42,10 +43,17 @@ const BodySchema = Type.Union([
4243
value: Type.String(),
4344
nonce: Type.String(),
4445
deadline: Type.String(),
45-
r: Type.String(),
46-
s: Type.String(),
47-
v: Type.String(),
4846
}),
47+
signature: Type.String(),
48+
}),
49+
Type.Object({
50+
type: Type.Literal("execute-meta-transaction"),
51+
request: Type.Object({
52+
from: Type.String(),
53+
to: Type.String(),
54+
data: Type.String(),
55+
}),
56+
signature: Type.String(),
4957
}),
5058
]);
5159

@@ -105,9 +113,62 @@ export async function relayTransaction(fastify: FastifyInstance) {
105113
walletAddress: relayer.backendWalletAddress,
106114
});
107115

108-
if (req.body.type === "permit") {
116+
if (req.body.type === "execute-meta-transaction") {
117+
// Polygon Execute Meta Transaction
118+
const { request, signature } = req.body;
119+
const { v, r, s } = utils.splitSignature(signature);
120+
121+
if (
122+
relayer.allowedContracts &&
123+
!relayer.allowedContracts.includes(request.to.toLowerCase())
124+
) {
125+
return res.status(400).send({
126+
error: {
127+
message: `Requesting to relay transaction to unauthorized contract ${request.to}.`,
128+
},
129+
});
130+
}
131+
132+
const target = await sdk.getContractFromAbi(
133+
request.to.toLowerCase(),
134+
NativeMetaTransaction,
135+
);
136+
137+
const tx = await target.prepare("executeMetaTransaction", [
138+
request.from,
139+
request.data,
140+
r,
141+
s,
142+
v,
143+
]);
144+
145+
const queueId = await queueTx({
146+
tx,
147+
chainId: relayer.chainId,
148+
extension: "relayer",
149+
});
150+
151+
res.status(200).send({
152+
result: {
153+
queueId,
154+
},
155+
});
156+
return;
157+
} else if (req.body.type === "permit") {
109158
// EIP-2612
110-
const { request } = req.body;
159+
const { request, signature } = req.body;
160+
const { v, r, s } = utils.splitSignature(signature);
161+
162+
if (
163+
relayer.allowedContracts &&
164+
!relayer.allowedContracts.includes(request.to.toLowerCase())
165+
) {
166+
return res.status(400).send({
167+
error: {
168+
message: `Requesting to relay transaction to unauthorized contract ${request.to}.`,
169+
},
170+
});
171+
}
111172

112173
const target = await sdk.getContractFromAbi(
113174
request.to.toLowerCase(),
@@ -119,15 +180,15 @@ export async function relayTransaction(fastify: FastifyInstance) {
119180
request.spender,
120181
request.value,
121182
request.deadline,
122-
request.v,
123-
request.r,
124-
request.s,
183+
v,
184+
r,
185+
s,
125186
]);
126187

127188
const queueId = await queueTx({
128189
tx,
129190
chainId: relayer.chainId,
130-
extension: "forwarder",
191+
extension: "relayer",
131192
});
132193

133194
res.status(200).send({
@@ -212,7 +273,7 @@ export async function relayTransaction(fastify: FastifyInstance) {
212273
const queueId = await queueTx({
213274
tx,
214275
chainId: relayer.chainId,
215-
extension: "forwarder",
276+
extension: "relayer",
216277
});
217278

218279
res.status(200).send({

0 commit comments

Comments
 (0)