diff --git a/src/index.ts b/src/index.ts index d581250..0e787c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,19 +20,19 @@ app.get("/", async (req: Request, res: Response) => { }); app.post("/", async (req: Request, res: Response) => { - try { - const tokenId = (await req.body).tokenId; - const publicKey = await m3ter.publicKey(tokenId); - const latestNonce = await rollup.nonce(tokenId); - saveMeter({ - publicKey, - tokenId, - latestNonce: Number(latestNonce), - devEui: (await req.body).devEui ?? null, - }); - } catch (err) { - console.error(err); - } + // try { + // const tokenId = (await req.body).tokenId; + // const publicKey = await m3ter.publicKey(tokenId); + // const latestNonce = await rollup.nonce(tokenId); + // saveMeter({ + // publicKey, + // tokenId, + // latestNonce: Number(latestNonce), + // devEui: (await req.body).devEui ?? null, + // }); + // } catch (err) { + // console.error(err); + // } res.redirect("/"); console.log("[server]: Server handled POST request at `/`"); }); diff --git a/src/logic/context.ts b/src/logic/context.ts index 9b01fa0..ec3664a 100644 --- a/src/logic/context.ts +++ b/src/logic/context.ts @@ -32,7 +32,7 @@ app.listen(port, () => { const provider = new JsonRpcProvider(process.env.MAINNET_RPC); export const m3ter = new Contract( - "0x7c6FEF064603B91bE9d739fE981c28Fd82a6D62b", // "0x40a36C0eF29A49D1B1c1fA45fab63762f8FC423F" + process.env.M3TER_CONTRACT_ADDRESS || "0x9C547B649475f1bE81323AefdbcF209C17961D5E", [ "function publicKey(uint256) view returns (bytes32)", "function tokenID(bytes32) view returns (uint256)", @@ -41,7 +41,7 @@ export const m3ter = new Contract( ); export const rollup = new Contract( - "0x6E31632D6A7Af8d30766AA9E216c49F5AAb846c2", // TODO: Replace with actual rollup contract address + process.env.ROLLUP_CONTRACT_ADDRESS || "0xf8f2d4315DB5db38f3e5c45D0bCd59959c603d9b", ["function nonce(uint256 tokenId) external view returns (bytes6)"], provider ); diff --git a/src/logic/mqtt.ts b/src/logic/mqtt.ts index 7f1ff98..7d22e33 100644 --- a/src/logic/mqtt.ts +++ b/src/logic/mqtt.ts @@ -90,12 +90,14 @@ export async function handleMessage(blob: Buffer) { if (!existingMeter) { const tokenId = Number(await m3terContract.tokenID(`0x${publicKey}`)); - if (tokenId === 0) { - throw new Error("Token ID not found for public key: " + publicKey); - } + // if (tokenId === 0) { + // throw new Error("Token ID not found for public key: " + publicKey); + // } const latestNonce = Number(await rollupContract.nonce(tokenId)); + console.log("[info] Fetched tokenId and latestNonce from chain:", tokenId, latestNonce); + // save new meter with devEui const newMeter = { publicKey: `0x${publicKey}`, @@ -105,10 +107,17 @@ export async function handleMessage(blob: Buffer) { }; saveMeter(newMeter); console.log("[info] Saved new meter:", newMeter); - } else if (existingMeter && !existingMeter.devEui) { + } else { // update existing meter with devEui if not already set + console.log("[info] Updating meter with DevEui:", message["deviceInfo"]["devEui"]); updateMeterDevEui(`0x${publicKey}`, message["deviceInfo"]["devEui"]); - console.log("[info] Updated meter with DevEui:", existingMeter.tokenId); + + // fetch and update latest nonce from chain + const latestNonce = Number(await rollupContract.nonce(existingMeter.tokenId)); + + console.log("[info] Fetched latestNonce from chain:", latestNonce); + + updateMeterNonce(`0x${publicKey}`, latestNonce); } } @@ -131,17 +140,24 @@ export async function handleMessage(blob: Buffer) { } } + const expectedNonce = m3ter.latestNonce + 1; + console.log( "[info] Received blob for meter", m3ter?.tokenId, "expected nonce:", - m3ter?.latestNonce + 1, + expectedNonce, "got:", decoded.nonce ); + if (decoded.nonce !== expectedNonce && decoded.nonce !== 0) { + throw new Error( + `Invalid nonce. Expected ${expectedNonce}, got ${decoded.nonce}. Public key: ${publicKey}` + ); + } + // if device nonce is correct - const expectedNonce = m3ter.latestNonce + 1; if (decoded.nonce === expectedNonce) { console.log("[info] Nonce is valid:", decoded.nonce); @@ -176,18 +192,21 @@ export async function handleMessage(blob: Buffer) { const proverURL = await getProverURL(); console.log("[info] Sending pending transactions to prover:", proverURL); - await sendPendingTransactionsToProver(proverURL!); + const response = await sendPendingTransactionsToProver(proverURL!); console.log("[info] done sending to prover"); + try { + console.log("[info] Prover response:", await response?.json()); + } catch (jsonError) { + console.log("[info] Prover response (text):", await response?.text()); + } } catch (error) { console.error("Error sending pending transactions to prover:", error); } } const state = - decoded.nonce === m3ter.latestNonce + 1 || (decoded.nonce === 0 && m3ter.latestNonce === 0) - ? { is_on: true } - : { nonce: m3ter.latestNonce, is_on: true }; + decoded.nonce === expectedNonce ? { is_on: true } : { nonce: m3ter.latestNonce - 1, is_on: true }; // TODO: remove the following block after testing // if transaction nonce is 0 and the latest nonce is 0 diff --git a/src/logic/verify.ts b/src/logic/verify.ts index 713c0bc..62bbcc1 100644 --- a/src/logic/verify.ts +++ b/src/logic/verify.ts @@ -78,8 +78,6 @@ export async function sendTransactionsToProver( if (!response.ok) { throw new Error(`Prover responded with status: ${response.status}`); } - const json = await response.json(); - console.log("[info] Transactions sent to prover:", json); return response; } catch (err: any) { console.error("Failed to send transactions to prover:", err.message); @@ -137,9 +135,14 @@ export async function sendPendingTransactionsToProver(proverURL: string) { return; } + if (pendingTransactions.length > 0) { + console.log("[info] Pending transactions:", pendingTransactions); + } + + console.log("[info] Sending", pendingTransactions.length, "transactions to prover at", proverURL); + const requestPayload = buildBatchPayload(pendingTransactions); - console.log("[info] Sending", requestPayload.length, "transactions to prover at", proverURL); console.log("[info] Request payload:", requestPayload); return await sendTransactionsToProver(proverURL, requestPayload); diff --git a/src/store/sqlite.ts b/src/store/sqlite.ts index 1451667..652dbc3 100644 --- a/src/store/sqlite.ts +++ b/src/store/sqlite.ts @@ -125,8 +125,6 @@ function prepareQueries() { // Meter management functions export function saveMeter(meterData: MeterRecord): void { try { - console.log("saving m3ter data", meterData); - insertMeterQuery.run({ publicKey: meterData.publicKey, tokenId: meterData.tokenId, diff --git a/src/utils.ts b/src/utils.ts index 0d95e3a..dff5122 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -15,7 +15,7 @@ export function verifyPayloadSignature(transaction: Buffer, rawPubKey: Buffer): // Wrap raw key in SPKI DER const spkiPrefix = Buffer.from("302a300506032b6570032100", "hex"); - const derKey = Buffer.concat([spkiPrefix, rawPubKey]); + const derKey = Buffer.concat([new Uint8Array(spkiPrefix), new Uint8Array(rawPubKey)]); const publicKey = createPublicKey({ key: derKey, @@ -24,8 +24,8 @@ export function verifyPayloadSignature(transaction: Buffer, rawPubKey: Buffer): }); // Verify - const ok = verify(null, message, publicKey, signature); - + const ok = verify(null, new Uint8Array(message), publicKey, new Uint8Array(signature)); + return ok; } catch (error) { console.error("Error verifying signature:", error);