-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcheck-video-nft.ts
162 lines (147 loc) · 4.08 KB
/
check-video-nft.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import "isomorphic-fetch";
import { ethers, BigNumber } from "ethers";
import * as standards from "./standards";
import fs from "fs";
const frontend = fs.readFileSync(__dirname + "/dist/index.html", "utf8");
const ERC721 = "erc721";
const ERC1155 = "erc1155";
const SIGN_STRING = "I have the NFT! Give me access.";
const chainList = require("./chains");
type Chains = {
[key: string]: any;
};
const chains: Chains = {};
for (const chain of chainList) {
const hex = `0x${chain.chainId.toString(16)}`;
for (let key of [chain.shortName, chain.chainId, hex]) {
key = `${key}`.toLowerCase();
if (chains[key]) {
console.error(
`duplicate for key ${key}: ${chains[key].name} and ${chain.name}`
);
} else {
chains[key] = chain;
}
}
}
type GateParams = {
contract?: string;
standard?: string;
network?: string;
message?: string;
proof?: string;
};
async function getResponse({
contract,
standard = ERC721,
network = "eth",
message = SIGN_STRING,
proof,
}: GateParams): Promise<BigNumber> {
if (!contract) {
throw new Error("missing contract");
}
if (!proof) {
throw new Error("Missing proof");
}
const chain = chains[network.toLowerCase()];
if (!chain) {
throw new Error(`network ${network} not found`);
}
let rpc;
for (const url of chain.rpc) {
if (!url.startsWith("https://")) {
continue;
}
// Skip URLs that require interpolation (API Keys)
if (url.includes("${")) {
continue;
}
rpc = url;
break;
}
if (!rpc) {
throw new Error(`RPC address not found for ${network}`);
}
let abi;
if (standard === ERC721) {
abi = standards[ERC721];
} else if (standard == ERC1155) {
abi = standards[ERC1155];
} else {
throw new Error(`uknown standard: ${standard}`);
}
// const provider = ethers.getDefaultProvider(ETH_URL);
const provider = new ethers.providers.StaticJsonRpcProvider(
{
url: rpc,
skipFetchSetup: true,
headers: {
"user-agent": "livepeer/gate",
},
},
chain.chainId
);
const contractObj = new ethers.Contract(contract, abi, provider);
const address = ethers.utils.verifyMessage(message, proof);
return await contractObj.balanceOf(address);
}
type WebhookPayload = {
requestUrl: string;
};
type Webhook = {
payload: WebhookPayload;
};
async function handleRequest(request: Request): Promise<Response> {
if (request.method === "GET") {
// Print out the frontend if present
return new Response(frontend, {
headers: { "content-type": "text/html; charset=UTF-8" },
});
}
const gateParams: GateParams = {};
// Extract parameters from query params
const { searchParams } = new URL(request.url);
for (const [key, value] of searchParams) {
gateParams[key] = value;
}
// Extract proof from webhook body
const data = (await request.json()) as Webhook;
const requestUrl: string = data?.payload?.requestUrl;
if (!requestUrl) {
return new Response("payload.url not found", { status: 413 });
}
const payloadUrl = new URL(requestUrl);
const proof = payloadUrl.searchParams.get("proof");
if (!proof) {
return new Response("`proof` query parameter missing from payload url");
}
gateParams.proof = proof;
try {
const balance = await getResponse(gateParams);
if (balance.gt(0)) {
return new Response("ok", { status: 200 });
} else {
return new Response(`Not enough NFTs.`, {
status: 403,
});
}
} catch (e: any) {
return new Response(e.message, { status: 500 });
}
}
if (typeof addEventListener === "function") {
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request as Request));
});
} else if (typeof module === "object" && !module.parent) {
getResponse({
standard: "erc721",
contract: "0x69c53e7b8c41bf436ef5a2d81db759dc8bd83b5f",
network: "matic",
proof:
"0xcf3708006566be50200fb4257f97e36f1fe3ad2c34a2c03d6395aa71b81ed8186af1432d1aa4e43284dfb2bf1e3b0f0b063ad461172f116685b8e842953cb2b71b",
})
.then((x) => console.log(x.toNumber()))
.catch((...x) => console.log(x));
}