Compare commits
30 Commits
8bb9f6b41e
...
435553bf05
Author | SHA1 | Date |
---|---|---|
Ladd Hoffman | 435553bf05 | |
Ladd Hoffman | 527c844ad0 | |
Ladd Hoffman | a204ec7f6f | |
Ladd Hoffman | e44f43350a | |
Ladd Hoffman | fe5fe522ab | |
Ladd Hoffman | 6a2b647b4b | |
Ladd Hoffman | e95d7ac91c | |
Ladd Hoffman | 2f6b3d4ed1 | |
Ladd Hoffman | 6f4b2855a8 | |
Ladd Hoffman | 9e5ccf6470 | |
Ladd Hoffman | ab103d3038 | |
Ladd Hoffman | 83d43b8312 | |
Ladd Hoffman | 4a38104d10 | |
Ladd Hoffman | 3593fafd91 | |
Ladd Hoffman | 039fc85fff | |
Ladd Hoffman | e4277a229b | |
Ladd Hoffman | 5b086aab9d | |
Ladd Hoffman | 9b44c5bf21 | |
Ladd Hoffman | b7a880322f | |
Ladd Hoffman | d09a46c292 | |
Ladd Hoffman | 9403e817b0 | |
Ladd Hoffman | 31fc599ce8 | |
Ladd Hoffman | 80cd3439d1 | |
Ladd Hoffman | eb54ff4805 | |
Ladd Hoffman | 1eacf3c9ab | |
Ladd Hoffman | bc4b9f6a5b | |
Ladd Hoffman | 8cc14bc7d5 | |
Ladd Hoffman | 27d0c853b2 | |
Ladd Hoffman | b713c77f10 | |
Ladd Hoffman | 466be6dacd |
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"localhost": {
|
||||
"DAO": "0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3",
|
||||
"Work1": "0xfe58B9EB03F75A603de1B286584f5E9532ab8fB5",
|
||||
"Onboarding": "0x1d63FDe5B461106729fE1e5e38A02fc68C518Af5",
|
||||
"Proposals": "0x050C420Cc4995B41217Eba1B54B82Fd5687e9139"
|
||||
"DAO": "0x57BDFFf79108E5198dec6268A6BFFD8B62ECfA38",
|
||||
"Work1": "0xB8f0cd092979F273b752FDa060F82BF2745f192e",
|
||||
"Onboarding": "0x8F00038542C87A5eAf18d5938B7723bF2A04A4e4",
|
||||
"Proposals": "0x6c18eb38b7450F8DaE5A5928A40fcA3952493Ee4"
|
||||
},
|
||||
"sepolia": {
|
||||
"DAO": "0x8e5bd58B2ca8910C5F9be8de847d6883B15c60d2",
|
||||
|
|
|
@ -4,9 +4,11 @@ const dataDir = process.env.LEVEL_DATA_DIR || 'data';
|
|||
|
||||
module.exports = {
|
||||
forum: new Level(`${dataDir}/forum`, { valueEncoding: 'json' }),
|
||||
authorAddresses: new Level(`${dataDir}/authorAddresses`, { valueEncoding: 'utf8' }),
|
||||
authorPrivKeys: new Level(`${dataDir}/authorPrivKeys`, { valueEncoding: 'utf8' }),
|
||||
authorAddresses: new Level(`${dataDir}/authorAddresses`),
|
||||
authorPrivKeys: new Level(`${dataDir}/authorPrivKeys`),
|
||||
appState: new Level(`${dataDir}/appState`, { valueEncoding: 'json' }),
|
||||
proposalEventIds: new Level(`${dataDir}/proposalEventIds`, { keyEncoding: 'json', valueEncoding: 'utf8' }),
|
||||
referendumEventIds: new Level(`${dataDir}/referendumEventIds`, { keyEncoding: 'json', valueEncoding: 'utf8' }),
|
||||
proposalEventIds: new Level(`${dataDir}/proposalEventIds`, { keyEncoding: 'json' }),
|
||||
referendumEventIds: new Level(`${dataDir}/referendumEventIds`, { keyEncoding: 'json' }),
|
||||
matrixUserToAuthorAddress: new Level(`${dataDir}/matrixUserToAuthorAddress`),
|
||||
authorAddressToMatrixUser: new Level(`${dataDir}/authorAddressToMatrixUser`),
|
||||
};
|
||||
|
|
|
@ -5,8 +5,14 @@ const {
|
|||
SimpleFsStorageProvider,
|
||||
} = require('matrix-bot-sdk');
|
||||
const fastq = require('fastq');
|
||||
const { recoverPersonalSignature } = require('@metamask/eth-sig-util');
|
||||
|
||||
const { appState, proposalEventIds } = require('./db');
|
||||
const {
|
||||
appState,
|
||||
proposalEventIds,
|
||||
matrixUserToAuthorAddress,
|
||||
authorAddressToMatrixUser,
|
||||
} = require('./db');
|
||||
|
||||
const {
|
||||
MATRIX_HOMESERVER_URL,
|
||||
|
@ -67,7 +73,7 @@ const start = async () => {
|
|||
// Leave targetRoomId uninitialized for now
|
||||
}
|
||||
|
||||
async function handleCommand(roomId, event) {
|
||||
const handleCommand = async (roomId, event) => {
|
||||
// Don't handle unhelpful events (ones that aren't text messages, are redacted, or sent by us)
|
||||
if (event.content?.msgtype !== 'm.text') return;
|
||||
if (event.sender === await client.getUserId()) return;
|
||||
|
@ -96,16 +102,52 @@ const start = async () => {
|
|||
try {
|
||||
const proposalEventId = await proposalEventIds.get(proposalIndex);
|
||||
const proposalEventUri = `https://matrix.to/#/${roomId}/${proposalEventId}`;
|
||||
await client.sendText(roomId, `Proposal ${proposalIndex}: ${proposalEventUri}`);
|
||||
const content = {
|
||||
body: `Proposal ${proposalIndex}: ${proposalEventUri}`,
|
||||
msgtype: 'm.text',
|
||||
};
|
||||
if (event.content['m.relates_to']?.rel_type === 'm.thread') {
|
||||
content['m.relates_to'] = event.content['m.relates_to'];
|
||||
}
|
||||
await client.sendEvent(roomId, 'm.room.message', content);
|
||||
} catch (e) {
|
||||
// Not found
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleRegisterIdentity = async (roomId, event) => {
|
||||
const { message, signature } = event.content;
|
||||
console.log('Received request to register identity');
|
||||
let account;
|
||||
try {
|
||||
account = recoverPersonalSignature({ data: message, signature });
|
||||
} catch (e) {
|
||||
console.log('error: failed to recover signature:', e.message);
|
||||
}
|
||||
if (account) {
|
||||
await matrixUserToAuthorAddress.put(event.sender, account);
|
||||
await authorAddressToMatrixUser.put(account, event.sender);
|
||||
}
|
||||
await client.sendNotice(roomId, `Registered matrix user ${event.sender} to author address ${account}`);
|
||||
};
|
||||
|
||||
// Before we start the bot, register our command handler
|
||||
client.on('room.message', handleCommand);
|
||||
|
||||
// Handler for custom events
|
||||
client.on('room.event', (roomId, event) => {
|
||||
// Note that state events can also be sent down this listener too
|
||||
if (event.state_key !== undefined) return; // state event
|
||||
|
||||
switch (event.type) {
|
||||
case 'io.dgov.identity.register':
|
||||
handleRegisterIdentity(roomId, event);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
|
||||
client.start().then(() => {
|
||||
console.log('Bot started!');
|
||||
outboundQueue.resume();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"localhost": {
|
||||
"DAO": "0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3",
|
||||
"Work1": "0xfe58B9EB03F75A603de1B286584f5E9532ab8fB5",
|
||||
"Onboarding": "0x1d63FDe5B461106729fE1e5e38A02fc68C518Af5",
|
||||
"Proposals": "0x050C420Cc4995B41217Eba1B54B82Fd5687e9139"
|
||||
"DAO": "0x57BDFFf79108E5198dec6268A6BFFD8B62ECfA38",
|
||||
"Work1": "0xB8f0cd092979F273b752FDa060F82BF2745f192e",
|
||||
"Onboarding": "0x8F00038542C87A5eAf18d5938B7723bF2A04A4e4",
|
||||
"Proposals": "0x6c18eb38b7450F8DaE5A5928A40fcA3952493Ee4"
|
||||
},
|
||||
"sepolia": {
|
||||
"DAO": "0x8e5bd58B2ca8910C5F9be8de847d6883B15c60d2",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"localhost": {
|
||||
"DAO": "0x8d914D38dD301FC4606f5aa9fEcF8A76389020d3",
|
||||
"Work1": "0xfe58B9EB03F75A603de1B286584f5E9532ab8fB5",
|
||||
"Onboarding": "0x1d63FDe5B461106729fE1e5e38A02fc68C518Af5",
|
||||
"Proposals": "0x050C420Cc4995B41217Eba1B54B82Fd5687e9139"
|
||||
"DAO": "0x57BDFFf79108E5198dec6268A6BFFD8B62ECfA38",
|
||||
"Work1": "0xB8f0cd092979F273b752FDa060F82BF2745f192e",
|
||||
"Onboarding": "0x8F00038542C87A5eAf18d5938B7723bF2A04A4e4",
|
||||
"Proposals": "0x6c18eb38b7450F8DaE5A5928A40fcA3952493Ee4"
|
||||
},
|
||||
"sepolia": {
|
||||
"DAO": "0x8e5bd58B2ca8910C5F9be8de847d6883B15c60d2",
|
||||
|
|
|
@ -5,19 +5,9 @@
|
|||
<link rel="icon" type="image/svg+xml" href="/dgf.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>DGF Prototype</title>
|
||||
<script blocking="render">
|
||||
console.log('adding window message event listener');
|
||||
window.addEventListener(
|
||||
'message',
|
||||
(event) => {
|
||||
if (event.data?.target?.startsWith('metamask')) return;
|
||||
console.log('window message', event);
|
||||
},
|
||||
);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script async type="module" src="/src/main.jsx"></script>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -229,7 +229,7 @@ function WebApp() {
|
|||
Work1Contract.events.AvailabilityStaked().off();
|
||||
OnboardingContract.events.AvailabilityStaked().off();
|
||||
};
|
||||
}, [provider, account, chainId, balance, dispatchValidationPool, dispatchPost, reputation,
|
||||
}, [provider, account, chainId, balance, dispatchValidationPool, dispatchPost,
|
||||
DAORef, workRef, onboardingRef,
|
||||
fetchPost, fetchPosts, fetchReputation, fetchValidationPool, fetchValidationPools, fetchMembers,
|
||||
]);
|
||||
|
|
|
@ -10,7 +10,9 @@ import Container from 'react-bootstrap/Container';
|
|||
import Row from 'react-bootstrap/Row';
|
||||
import Col from 'react-bootstrap/Col';
|
||||
import Stack from 'react-bootstrap/Stack';
|
||||
import { EventDirection, WidgetEventCapability } from 'matrix-widget-api';
|
||||
import {
|
||||
WidgetApi, EventDirection, WidgetEventCapability, /* MatrixCapabilities, */
|
||||
} from 'matrix-widget-api';
|
||||
// import { MuiCapabilitiesGuard } from '@matrix-widget-toolkit/mui';
|
||||
// import { useWidgetApi } from '@matrix-widget-toolkit/react';
|
||||
|
||||
|
@ -233,7 +235,7 @@ function Widget() {
|
|||
Work1Contract.events.AvailabilityStaked().off();
|
||||
OnboardingContract.events.AvailabilityStaked().off();
|
||||
};
|
||||
}, [provider, account, chainId, balance, dispatchValidationPool, dispatchPost, reputation,
|
||||
}, [provider, account, chainId, balance, dispatchValidationPool, dispatchPost,
|
||||
DAORef, workRef, onboardingRef,
|
||||
fetchPost, fetchPosts, fetchReputation, fetchValidationPool, fetchValidationPools, fetchMembers,
|
||||
]);
|
||||
|
@ -252,11 +254,41 @@ function Widget() {
|
|||
|
||||
useEffect(() => {
|
||||
console.log('window.location', window.location);
|
||||
const { searchParams } = new URL(window.location.href);
|
||||
const widgetId = searchParams.get('widgetId');
|
||||
|
||||
window.widgetApiPromise.then((api) => {
|
||||
console.log('widgetApi promise resolved', api);
|
||||
widgetApi.current = api;
|
||||
widgetApi.current = widgetApi.current ?? new WidgetApi(widgetId, 'https://chat.dgov.io');
|
||||
|
||||
console.log('widget api', widgetApi.current);
|
||||
|
||||
// widgetApi.current.requestCapability(MatrixCapabilities.AlwaysOnScreen);
|
||||
|
||||
// widgetApi.current.requestCapabilities([
|
||||
// WidgetEventCapability.forRoomEvent(
|
||||
// EventDirection.Send,
|
||||
// 'm.message',
|
||||
// ),
|
||||
// ]);
|
||||
|
||||
// widgetApi.current.updateRequestedCapabilities();
|
||||
|
||||
widgetApi.current.on('ready', (e) => {
|
||||
console.log('WIDGET READY', e);
|
||||
|
||||
const sendMessageCapability = WidgetEventCapability.forRoomEvent(
|
||||
EventDirection.Send,
|
||||
'm.room.message',
|
||||
);
|
||||
const sendRegisterIdentityCapability = WidgetEventCapability.forRoomEvent(
|
||||
EventDirection.Send,
|
||||
'io.dgov.identity.register',
|
||||
);
|
||||
widgetApi.current.requestCapability(sendMessageCapability.raw);
|
||||
widgetApi.current.requestCapability(sendRegisterIdentityCapability.raw);
|
||||
widgetApi.current.updateRequestedCapabilities();
|
||||
});
|
||||
|
||||
widgetApi.current.start();
|
||||
}, []);
|
||||
|
||||
/* -------------------------------------------------------------------------------- */
|
||||
|
@ -341,16 +373,20 @@ function Widget() {
|
|||
setShowViewPost(true);
|
||||
}, [setViewPost, setShowViewPost]);
|
||||
|
||||
// TODO: Sign and send a message to the forum-api bot / to a room in matrix
|
||||
const registerMatrixIdentity = async () => {
|
||||
await widgetApi.current.requestCapabilities([
|
||||
WidgetEventCapability.forRoomEvent(
|
||||
EventDirection.Send,
|
||||
'm.message',
|
||||
),
|
||||
]);
|
||||
widgetApi.current.sendRoomEvent('m.message', 'test message');
|
||||
};
|
||||
// Sign and send a message
|
||||
const registerMatrixIdentity = useCallback(async () => {
|
||||
const message = new Date().toISOString();
|
||||
|
||||
const signature = await provider.request({
|
||||
method: 'personal_sign',
|
||||
params: [message, account],
|
||||
});
|
||||
|
||||
await widgetApi.current.sendRoomEvent('io.dgov.identity.register', {
|
||||
message,
|
||||
signature,
|
||||
});
|
||||
}, [provider, account]);
|
||||
|
||||
/* -------------------------------------------------------------------------------- */
|
||||
/* --------------------------- END UI ACTIONS ------------------------------------- */
|
||||
|
|
|
@ -7,12 +7,12 @@ import {
|
|||
createBrowserRouter,
|
||||
RouterProvider,
|
||||
} from 'react-router-dom';
|
||||
import { WidgetApiImpl } from '@matrix-widget-toolkit/api';
|
||||
// import { WidgetApiImpl } from '@matrix-widget-toolkit/api';
|
||||
|
||||
import WebApp from './WebApp';
|
||||
import Widget from './Widget';
|
||||
|
||||
window.widgetApiPromise = WidgetApiImpl.create({});
|
||||
// window.widgetApiPromise = WidgetApiImpl.create({});
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue