import from matrix: sign as sender
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 36s Details

This commit is contained in:
Ladd Hoffman 2024-04-29 17:21:03 -05:00
parent 276677e1c8
commit 337c4824fd
6 changed files with 43 additions and 35 deletions

View File

@ -1,13 +1,17 @@
const { getClient } = require('../matrix-bot');
const ethers = require('ethers');
const { getClient } = require('../matrix-bot');
const { matrixUserToAuthorAddress } = require('../util/db');
const write = require('../util/forum/write');
const { dao } = require('../util/contracts');
const { dao, getProvider } = require('../util/contracts');
const {
ETH_NETWORK,
ETH_PRIVATE_KEY,
} = process.env;
const wallet = new ethers.Wallet(ETH_PRIVATE_KEY, getProvider());
const addPostWithRetry = async (authors, hash, citations, retryDelay = 5000) => {
try {
await dao.addPost(authors, hash, citations);
@ -58,8 +62,6 @@ module.exports = async (req, res) => {
}
// We want to add a post representing this matrix message.
// We can't sign it on behalf of the author.
// That means we need to support posts without signatures.
const authors = [{ authorAddress, weightPPM: 1000000 }];
// TODO: Take citations as input to this API call, referencing other posts or matrix events
const citations = [];
@ -68,9 +70,12 @@ module.exports = async (req, res) => {
roomId,
eventId,
};
// We can't sign it on behalf of the author, but we can sign it with our own key
const sender = wallet.getAddress();
const signature = await wallet.signMessage();
const { hash } = await write({
authors, citations, content, embeddedData,
sender, authors, citations, content, embeddedData, signature,
});
// Now we want to add a post on-chain

View File

@ -21,7 +21,7 @@ const start = async () => {
if (proposal.stage === BigInt(5)) {
// Proposal is accepted
enableStaking = false;
console.log(`STOP_PROPOSAL_ID ${STOP_PROPOSAL_ID} proposal accepted. Not starting.`);
console.log(`STOP_PROPOSAL_ID ${STOP_PROPOSAL_ID} proposal is accepted. Not starting.`);
} else if (proposal.stage === BigInt(4)) {
// Proposal is failed
console.log(`STOP_PROPOSAL_ID ${STOP_PROPOSAL_ID} proposal is failed. No effect.`);
@ -30,7 +30,7 @@ const start = async () => {
console.log(`STOP_PROPOSAL_ID ${STOP_PROPOSAL_ID} proposal is stage ${proposal.stage.toString()}. Registering listener.`);
const proposalAcceptedHandler = (event) => {
if (event.returnValues.proposalIndex === STOP_PROPOSAL_ID) {
console.log(`STOP_PROPOSAL_ID ${STOP_PROPOSAL_ID} proposal accepted. Stopping.`);
console.log(`STOP_PROPOSAL_ID ${STOP_PROPOSAL_ID} proposal is accepted. Stopping.`);
enableStaking = false;
proposals.off('ProposalAccepted', proposalAcceptedHandler);
}
@ -53,7 +53,7 @@ const start = async () => {
console.log(`START_PROPOSAL_ID ${START_PROPOSAL_ID} proposal is stage ${proposal.stage.toString()}. Registering listener.`);
const proposalAcceptedHandler = (event) => {
if (event.returnValues.proposalIndex === START_PROPOSAL_ID) {
console.log(`START_PROPOSAL_ID ${START_PROPOSAL_ID} proposal accepted. Starting.`);
console.log(`START_PROPOSAL_ID ${START_PROPOSAL_ID} proposal is accepted. Starting.`);
enableStaking = true;
proposals.off('ProposalAccepted', proposalAcceptedHandler);
}

View File

@ -4,34 +4,39 @@ const { getContractAddressByNetworkName } = require('./contract-config');
const DAOArtifact = require('../../contractArtifacts/DAO.json');
const ProposalsArtifact = require('../../contractArtifacts/Proposals.json');
const network = process.env.ETH_NETWORK;
const {
ETH_NETWORK,
ETH_PRIVATE_KEY,
INFURA_API_KEY,
} = process.env;
console.log('network:', network);
console.log('network:', ETH_NETWORK);
const getProvider = () => {
switch (network) {
switch (ETH_NETWORK) {
case 'localhost':
return ethers.getDefaultProvider('http://localhost:8545');
case 'sepolia':
return new ethers.InfuraProvider(
network,
process.env.INFURA_API_KEY,
ETH_NETWORK,
INFURA_API_KEY,
);
default:
throw new Error('Unknown network');
}
};
const wallet = new ethers.Wallet(process.env.ETH_PRIVATE_KEY, getProvider());
const wallet = new ethers.Wallet(ETH_PRIVATE_KEY, getProvider());
module.exports = {
getProvider,
dao: new ethers.Contract(
getContractAddressByNetworkName(process.env.ETH_NETWORK, 'DAO'),
getContractAddressByNetworkName(ETH_NETWORK, 'DAO'),
DAOArtifact.abi,
wallet,
),
proposals: new ethers.Contract(
getContractAddressByNetworkName(process.env.ETH_NETWORK, 'Proposals'),
getContractAddressByNetworkName(ETH_NETWORK, 'Proposals'),
ProposalsArtifact.abi,
wallet,
),

View File

@ -10,12 +10,12 @@ const read = async (hash) => {
data.embeddedData = data.embeddedData || undefined;
const {
authors, content, signature, embeddedData, citations,
sender, authors, content, signature, embeddedData, citations,
} = data;
// Verify hash
const derivedHash = objectHash({
authors, content, signature, embeddedData,
sender, authors, content, signature, embeddedData,
});
if (derivedHash !== hash) {
throw new Error('hash mismatch');
@ -29,7 +29,7 @@ const read = async (hash) => {
}
return {
authors, content, signature, embeddedData, citations,
sender, authors, content, signature, embeddedData, citations,
};
};

View File

@ -4,26 +4,24 @@ const verifySignature = require('../verify-signature');
const { forum } = require('../db');
const write = async ({
authors, content, citations, embeddedData, signature,
sender, authors, content, citations, embeddedData, signature,
}) => {
if (signature) {
// Check author signature
if (!verifySignature({
authors, content, signature, embeddedData,
})) {
const err = new Error();
err.status = 403;
err.message = 'Signature verification failed';
throw err;
}
if (!verifySignature({
sender, authors, content, signature, embeddedData,
})) {
const err = new Error();
err.status = 403;
err.message = 'Signature verification failed';
throw err;
}
// Compute content hash
const data = {
authors, content, signature, embeddedData, citations,
sender, authors, content, signature, embeddedData, citations,
};
const hash = objectHash({
authors, content, signature, embeddedData,
sender, authors, content, signature, embeddedData,
});
// Store content

View File

@ -1,7 +1,7 @@
const { recoverPersonalSignature } = require('@metamask/eth-sig-util');
const verifySignature = ({
authors, content, signature, embeddedData,
sender, authors, content, signature, embeddedData,
}) => {
let contentToVerify = content;
if (embeddedData && Object.entries(embeddedData).length) {
@ -9,9 +9,9 @@ const verifySignature = ({
}
try {
const account = recoverPersonalSignature({ data: contentToVerify, signature });
const authorAddresses = authors.map((author) => author.authorAddress.toLowerCase());
if (!authorAddresses.includes(account.toLowerCase())) {
console.log('error: signer is not among the authors');
const addresses = authors.concat(sender).map((author) => author.authorAddress.toLowerCase());
if (!addresses.includes(account.toLowerCase())) {
console.log('error: signer is not among the authors or sender');
return false;
}
} catch (e) {