148 lines
5.8 KiB
JavaScript
148 lines
5.8 KiB
JavaScript
import { ethers } from "ethers";
|
|
import * as ed from "@noble/ed25519";
|
|
const KIMAP_ABI = [
|
|
"function get(bytes32 namehash) external view returns (address tba, address owner, bytes memory data)",
|
|
"function leaf(bytes32 parenthash, bytes calldata label) external pure returns (bytes32 namehash)",
|
|
"function tbaOf(bytes32 entry) external view returns (address tba)",
|
|
];
|
|
const KIMAP_ADDRESS = "0x000000000044C6B8Cb4d8f0F889a3E47664EAeda";
|
|
// const KIMAP_ADDRESS = "0x969cAbCE3625224BA3d340ea4dC2f929301188Ad";
|
|
const RPC_URL = "https://base-mainnet.g.alchemy.com/v2/jWsKWKv217Jz-9Nnnu7uJpW6gqmBcNog";
|
|
class KimapClient {
|
|
apiKey;
|
|
contract;
|
|
constructor(apiKey) {
|
|
this.apiKey = apiKey;
|
|
const provider = ethers.getDefaultProvider(RPC_URL);
|
|
const contract = new ethers.Contract(KIMAP_ADDRESS, KIMAP_ABI, provider);
|
|
this.contract = contract;
|
|
}
|
|
async fetchAbi() {
|
|
const url = `https://api.basescan.org/api?module=contract&action=getabi&address=${KIMAP_ADDRESS}&apikey=${this.apiKey}`;
|
|
try {
|
|
const response = await fetch(url);
|
|
const data = await response.json();
|
|
if (data.status === "1") {
|
|
return data.result; // ABI as a JSON string
|
|
}
|
|
else {
|
|
throw new Error("Failed to fetch ABI: " + data.message);
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error("Error fetching ABI:", error);
|
|
throw error;
|
|
}
|
|
}
|
|
async getPublicKey(name) {
|
|
const hash = await this.namehash(name);
|
|
console.log({ name, hash, contract: KIMAP_ADDRESS });
|
|
// const res = await this.contract!.get(hash);
|
|
// console.log({ res });
|
|
const netKeyNoteNamehash = await this.contract.leaf(hash, ethers.toUtf8Bytes("~net-key"));
|
|
const stoof = await this.contract.get(hash);
|
|
console.log({ stoof });
|
|
const [tba, owner, data] = await this.contract.get(netKeyNoteNamehash);
|
|
if (!data || data === "0x") {
|
|
return { error: "no data" };
|
|
}
|
|
return { ok: data };
|
|
}
|
|
async namehash(name) {
|
|
let hash = ethers.ZeroHash;
|
|
const labels = name.split(".").reverse();
|
|
for (const part of labels) {
|
|
const newhash = await this.contract.leaf(hash, ethers.toUtf8Bytes(part));
|
|
hash = newhash;
|
|
}
|
|
return hash;
|
|
}
|
|
async verifySignature(node, messageArray, signatureArray) {
|
|
// This is not a Browser transaction signature, this doesn't work
|
|
try {
|
|
const publicKey = await this.getPublicKey(node);
|
|
console.log({ publicKey });
|
|
if ("error" in publicKey)
|
|
return { error: "no public key found for " + node };
|
|
const publicKeyBytes = ethers.getBytes(publicKey.ok);
|
|
let messageBytes = new Uint8Array(messageArray);
|
|
let signatureBytes = new Uint8Array(signatureArray);
|
|
const isValid = await ed.verifyAsync(signatureBytes, messageBytes, publicKeyBytes);
|
|
return { ok: isValid };
|
|
}
|
|
catch (e) {
|
|
return { error: `${e}` };
|
|
}
|
|
}
|
|
}
|
|
export default KimapClient;
|
|
// export function getClient() {
|
|
// const client = new KimapClient(KIMAP_ADDRESS, Bun.env.BASESCAN_API_KEY!);
|
|
// return client;
|
|
// }
|
|
// async setContract() {
|
|
// const abi = await this.fetchAbi();
|
|
// // console.log(JSON.parse(abi));
|
|
// const provider = ethers.getDefaultProvider(RPC_URL);
|
|
// const contract = new ethers.Contract(
|
|
// this.contractAddress,
|
|
// abi,
|
|
// provider,
|
|
// );
|
|
// this.contract = contract;
|
|
// }
|
|
// async verifySignature(
|
|
// node: string,
|
|
// messageBytes: BytesLike,
|
|
// signatureBytes: BytesLike,
|
|
// ): Promise<boolean> {
|
|
// // This is not a Browser transaction signature, this doesn't work
|
|
// const publicKey = await this.getPublicKey(node);
|
|
// console.log({ publicKey });
|
|
// if ("error" in publicKey) return false;
|
|
// // const messageBytes = ethers.toUtf8Bytes(message);
|
|
// const r = ethers.hexlify(signatureBytes.slice(0, 32));
|
|
// const s = ethers.hexlify(signatureBytes.slice(32, 64));
|
|
// const v = Number(ethers.hexlify(signatureBytes.slice(64, 65)));
|
|
// const signature = { r, s, v };
|
|
// const messageHash = ethers.hashMessage(messageBytes);
|
|
// const recovered = ethers.recoverAddress(messageHash, signature);
|
|
// // const lol: ethers.SignatureLike = "";
|
|
// console.log({ messageHash, recovered, publicKey });
|
|
// return false;
|
|
// }
|
|
// }
|
|
// const toCheck = {
|
|
// data: {
|
|
// body: {
|
|
// site: "f",
|
|
// time: 1741297185312,
|
|
// nonce: "ff",
|
|
// },
|
|
// message: [
|
|
// 115, 111, 114, 116, 117, 103, 100, 101, 118, 111, 46, 111, 115, 64, 108,
|
|
// 111, 103, 105, 110, 58, 108, 111, 103, 105, 110, 58, 115, 121, 115, 123,
|
|
// 34, 83, 105, 103, 110, 34, 58, 123, 34, 115, 105, 116, 101, 34, 58, 34,
|
|
// 102, 34, 44, 34, 116, 105, 109, 101, 34, 58, 49, 55, 52, 49, 50, 57, 55,
|
|
// 49, 56, 53, 51, 49, 50, 44, 34, 110, 111, 110, 99, 101, 34, 58, 34, 102,
|
|
// 102, 34, 125, 125,
|
|
// ],
|
|
// signature: [
|
|
// 41, 45, 105, 167, 143, 76, 68, 129, 157, 100, 71, 117, 117, 151, 89, 80,
|
|
// 40, 118, 14, 21, 235, 190, 98, 239, 156, 131, 225, 216, 167, 160, 96, 43,
|
|
// 132, 148, 254, 29, 49, 164, 131, 181, 205, 197, 136, 63, 175, 223, 57,
|
|
// 231, 253, 87, 130, 12, 118, 153, 72, 201, 246, 125, 200, 70, 4, 176, 98,
|
|
// 9,
|
|
// ],
|
|
// },
|
|
// };
|
|
// async function run() {
|
|
// const client = new KimapClient(KIMAP_ADDRESS, BASESCAN_API_KEY);
|
|
// // await client.setContract();
|
|
// // client.getPublicKey("sortugdevo.os");
|
|
// const messageBytes = new Uint8Array(toCheck.data.message);
|
|
// const signatureBytes = new Uint8Array(toCheck.data.signature);
|
|
// client.verifySignature("sortugdevo.os", messageBytes, signatureBytes);
|
|
// }
|
|
// run();
|