-
Notifications
You must be signed in to change notification settings - Fork 1
/
server-adapter.ts
101 lines (78 loc) · 3.01 KB
/
server-adapter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/// @author clowes.eth
/// Basic server adapter for resolving from Layer 2
import { createServerAdapter } from "@whatwg-node/server";
import { Contract, AbiCoder, Provider } from "ethers";
const ABI_CODER = new AbiCoder();
const registryABI = [
"function addr(bytes32 node) public view returns (address)",
"function addr(bytes32 node, uint256 coinType) external view returns (bytes)",
"function text(bytes32 node, string key) view returns (string text)",
"function contenthash(bytes32 node) external view returns (bytes memory)",
];
export default (provider: Provider, registryAddress: string) => {
return createServerAdapter(async (request: Request) => {
const registryContract = new Contract(registryAddress, registryABI, provider);
console.log("Received request:", request);
if (!["POST", "OPTIONS"].includes(request.method)) {
console.log("Rejecting non-POST request");
return errorResponse("Only POST requests are allowed", 405);
}
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
},
});
}
try {
const requestBody = await request.text();
const requestData = JSON.parse(requestBody);
const { sender, data: wCalldata } = requestData;
if (!wCalldata) {
return errorResponse("Missing calldata");
}
const [labelhash, calldata] = ABI_CODER.decode(["bytes32", "bytes"], wCalldata);
const functionSelector = calldata.slice(0, 10);
const fn = registryContract.interface.getFunction(functionSelector);
const fullFunctionName = fn?.format("minimal");
if (!fn) {
return errorResponse(`Unsupported function selector ${functionSelector}`);
}
const decodedFunctionData = registryContract.interface.decodeFunctionData(fn, calldata)!;
const modifiedFunctionData = [labelhash, ...decodedFunctionData.slice(1)];
const result = await registryContract[functionSelector](
...modifiedFunctionData
);
const encodedResult = registryContract.interface.encodeFunctionResult(
fn,
[result]
);
return successResponse(encodedResult);
} catch (error) {
return errorResponse("Failed to process request", 500);
}
});
}
const successResponse = (data: string, status: number = 200) => {
console.log("Sending success response:", data);
return new Response(JSON.stringify({ data }), {
status: status,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
});
};
const errorResponse = (message: string, status: number = 400) => {
console.log("Sending error response:", message, status);
return new Response(JSON.stringify({ message }), {
status: status,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*"
},
});
};