Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/v1.7.8 #10399

Merged
merged 60 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
98531ce
added the new option for skale
KaleemNeslit Dec 5, 2024
d3a3cd7
added the SKALE in ValidChains
KaleemNeslit Dec 5, 2024
574e78e
fixed the failed build
KaleemNeslit Dec 5, 2024
c43118b
fixed build error
KaleemNeslit Dec 5, 2024
5e7eb78
Merge branch 'master' of https://github.com/hicommonwealth/commonweal…
KaleemNeslit Dec 6, 2024
844873e
Merge branch 'master' of https://github.com/hicommonwealth/commonweal…
KaleemNeslit Dec 6, 2024
62a51f8
pr reviews address
KaleemNeslit Dec 6, 2024
f74717d
dissconnect-all-addresses
salman-neslit Dec 6, 2024
d06af37
es-lint
salman-neslit Dec 9, 2024
2457a9f
feat: add about button to header
devin-ai-integration[bot] Dec 11, 2024
f59de3e
refactor: change About button from icon to text
devin-ai-integration[bot] Dec 11, 2024
c5a8a08
refactor: remove redundant tooltip from About button
devin-ai-integration[bot] Dec 11, 2024
0dc7f61
fix: standardize tooltip positioning and restore About Common tooltip
devin-ai-integration[bot] Dec 12, 2024
cd3803a
change the SKALE_ID from 1564830818 to 974399131
KaleemNeslit Dec 12, 2024
71790ec
Merge branch 'master' of https://github.com/hicommonwealth/commonweal…
KaleemNeslit Dec 12, 2024
796e1d2
enable local runs of sitemap-runner.ts
timolegros Dec 12, 2024
abcdd0b
Merge branch 'master' of https://github.com/hicommonwealth/commonweal…
salman-neslit Dec 13, 2024
c9747d0
feat: hide About button on small and medium screens
devin-ai-integration[bot] Dec 13, 2024
bca991d
fix: add missing width parameter to isWindowSmallInclusive
devin-ai-integration[bot] Dec 13, 2024
0cf20b8
Simplified token launch flow to match quick launch
mzparacha Dec 16, 2024
8e1b895
Removed "Community" text from generated community names
mzparacha Dec 16, 2024
e2d640c
Removed dall-e-3 as image model for token idea generation
mzparacha Dec 16, 2024
defd15b
Fix idea counter alignment
mzparacha Dec 16, 2024
db7da25
feat: Enhance referral link functionality and sharing options
masvelio Dec 16, 2024
f35ed74
Make user profile page available for not logged in user
masvelio Dec 16, 2024
bdd4677
CI
masvelio Dec 16, 2024
c72eb5f
CR
masvelio Dec 16, 2024
cd39b75
farcaster action validation
rbennettcw Dec 17, 2024
987c12b
remove log
rbennettcw Dec 17, 2024
718e5bc
lint
rbennettcw Dec 17, 2024
4cb8ea9
err message
rbennettcw Dec 17, 2024
7ac8618
lint
rbennettcw Dec 17, 2024
7c3b773
CR
masvelio Dec 17, 2024
0418a8b
add farcaster contest bot
rbennettcw Dec 17, 2024
06c42c4
Uncomment code
masvelio Dec 17, 2024
227ce8d
merge master
rbennettcw Dec 17, 2024
9e12b25
Merge pull request #10332 from hicommonwealth/ryan/farcaster-action-v…
rbennettcw Dec 17, 2024
3479236
Merge branch 'master' into ryan/farcaster-contest-bot
rbennettcw Dec 17, 2024
27d7aee
add FC bot error replies
rbennettcw Dec 17, 2024
0308d94
fix get threads pagination query
rbennettcw Dec 18, 2024
c7f8fa1
typo
rbennettcw Dec 18, 2024
7fa590b
restore cancel filter
rbennettcw Dec 18, 2024
13b4f2a
Merge branch 'master' into kaleemNelit.9911.skale_added
timolegros Dec 18, 2024
1cf2f41
Merge pull request #10363 from hicommonwealth/ryan/get-threads-fix2
ilijabojanovic Dec 18, 2024
c407e24
Merge branch 'master' into tim/sitemap-local
timolegros Dec 18, 2024
9f5d439
Merge pull request #10336 from hicommonwealth/marcin/fix-switching-ad…
masvelio Dec 18, 2024
1412ae8
Merge pull request #10269 from hicommonwealth/tim/sitemap-local
timolegros Dec 18, 2024
5eda85c
refine envs + better typing
rbennettcw Dec 18, 2024
252bd51
pr-comments
salman-neslit Dec 18, 2024
af668f3
Merge branch 'master' of https://github.com/hicommonwealth/commonweal…
salman-neslit Dec 18, 2024
75683cf
Merge pull request #10177 from hicommonwealth/salman/Issue#8711/dissc…
salman-neslit Dec 18, 2024
8fe4424
Merge branch 'master' into malik.10243.remove-extra-token-creation-steps
mzparacha Dec 19, 2024
756f7cb
Merge pull request #10312 from hicommonwealth/marcin/7777/sharing-as-…
masvelio Dec 19, 2024
9609019
Merge pull request #10309 from hicommonwealth/malik.10243.remove-extr…
mzparacha Dec 19, 2024
9acb7a3
Merge pull request #10335 from hicommonwealth/ryan/farcaster-contest-bot
rbennettcw Dec 19, 2024
de26d16
feat: add About Common icon to sidebar
devin-ai-integration[bot] Dec 19, 2024
0da852b
Merge pull request #10132 from hicommonwealth/kaleemNelit.9911.skale_…
dillchen Dec 19, 2024
79f8008
Merge branch 'devin/1734631044-add-about-icon-sidebar' into devin/173…
devin-ai-integration[bot] Dec 19, 2024
b1cb8f8
refactor: move About icon to quick switcher and show on small screens…
devin-ai-integration[bot] Dec 19, 2024
6da9d1d
Merge pull request #10228 from hicommonwealth/devin/1733936319-add-ab…
Israellund Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions libs/model/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {
ALCHEMY_PUBLIC_APP_KEY,
MEMBERSHIP_REFRESH_BATCH_SIZE,
MEMBERSHIP_REFRESH_TTL_SECONDS,
NEYNAR_BOT_UUID,
NEYNAR_API_KEY,
NEYNAR_CAST_CREATED_WEBHOOK_SECRET,
NEYNAR_REPLY_WEBHOOK_URL,
Expand Down Expand Up @@ -91,6 +92,7 @@ export const config = configure(
: 5,
FLAG_FARCASTER_CONTEST: FLAG_FARCASTER_CONTEST === 'true',
NEYNAR_API_KEY: NEYNAR_API_KEY,
NEYNAR_BOT_UUID: NEYNAR_BOT_UUID,
NEYNAR_CAST_CREATED_WEBHOOK_SECRET: NEYNAR_CAST_CREATED_WEBHOOK_SECRET,
NEYNAR_REPLY_WEBHOOK_URL: NEYNAR_REPLY_WEBHOOK_URL,
FARCASTER_ACTION_URL: FARCASTER_ACTION_URL,
Expand Down Expand Up @@ -195,10 +197,41 @@ export const config = configure(
MIN_USER_ETH: z.number(),
MAX_USER_POSTS_PER_CONTEST: z.number().int(),
FLAG_FARCASTER_CONTEST: z.boolean().nullish(),
NEYNAR_API_KEY: z.string().nullish(),
NEYNAR_CAST_CREATED_WEBHOOK_SECRET: z.string().nullish(),
NEYNAR_REPLY_WEBHOOK_URL: z.string().nullish(),
FARCASTER_ACTION_URL: z.string().nullish(),
NEYNAR_BOT_UUID: z
.string()
.optional()
.refine(
(data) => !(target.APP_ENV === 'production' && !data),
'NEYNAR_BOT_UUID must be set to a non-default value in production.',
),
NEYNAR_API_KEY: z
.string()
.optional()
.refine(
(data) => !(target.APP_ENV === 'production' && !data),
'NEYNAR_API_KEY must be set to a non-default value in production.',
),
NEYNAR_CAST_CREATED_WEBHOOK_SECRET: z
.string()
.optional()
.refine(
(data) => !(target.APP_ENV === 'production' && !data),
'NEYNAR_CAST_CREATED_WEBHOOK_SECRET must be set to a non-default value in production.',
),
NEYNAR_REPLY_WEBHOOK_URL: z
.string()
.optional()
.refine(
(data) => !(target.APP_ENV === 'production' && !data),
'NEYNAR_REPLY_WEBHOOK_URL must be set to a non-default value in production.',
),
FARCASTER_ACTION_URL: z
.string()
.optional()
.refine(
(data) => !(target.APP_ENV === 'production' && !data),
'FARCASTER_ACTION_URL must be set to a non-default value in production.',
),
}),
AUTH: z
.object({
Expand Down
28 changes: 27 additions & 1 deletion libs/model/src/contest/Contests.projection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
EvmEventSignatures,
commonProtocol as cp,
} from '@hicommonwealth/evm-protocols';
import { config } from '@hicommonwealth/model';
import { ContestScore, events } from '@hicommonwealth/schemas';
import { buildContestLeaderboardUrl, getBaseUrl } from '@hicommonwealth/shared';
import { QueryTypes } from 'sequelize';
import { z } from 'zod';
import { models } from '../database';
Expand All @@ -17,6 +19,8 @@ import {
decodeThreadContentUrl,
getChainNodeUrl,
getDefaultContestImage,
parseFarcasterContentUrl,
publishCast,
} from '../utils';

const log = logger(import.meta);
Expand Down Expand Up @@ -295,7 +299,9 @@ export function Contests(): Projection<typeof inputs> {
},

ContestContentAdded: async ({ payload }) => {
const { threadId } = decodeThreadContentUrl(payload.content_url);
const { threadId, isFarcaster } = decodeThreadContentUrl(
payload.content_url,
);
await models.ContestAction.create({
...payload,
contest_id: payload.contest_id || 0,
Expand All @@ -306,6 +312,26 @@ export function Contests(): Projection<typeof inputs> {
voting_power: '0',
created_at: new Date(),
});

// post confirmation via FC bot
if (isFarcaster) {
const contestManager = await models.ContestManager.findByPk(
payload.contest_address,
);
const leaderboardUrl = buildContestLeaderboardUrl(
getBaseUrl(config.APP_ENV),
contestManager!.community_id,
contestManager!.contest_address,
);
const { replyCastHash } = parseFarcasterContentUrl(
payload.content_url,
);
await publishCast(
replyCastHash,
({ username }) =>
`Hey @${username}, your entry has been submitted to the contest: ${leaderboardUrl}`,
);
}
},

ContestContentUpvoted: async ({ payload }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { NeynarAPIClient } from '@neynar/nodejs-sdk';
import { config } from '../config';
import { models } from '../database';
import { mustExist } from '../middleware/guards';
import { emitEvent } from '../utils';
import { emitEvent, publishCast } from '../utils';

const log = logger(import.meta);

Expand All @@ -21,13 +21,19 @@ export function FarcasterReplyCastCreatedWebhook(): Command<
mustExist('Farcaster Cast Author FID', payload.data.author?.fid);

const client = new NeynarAPIClient(config.CONTESTS.NEYNAR_API_KEY!);

// get user verified address
const { users } = await client.fetchBulkUsers([payload.data.author.fid]);
const verified_address = users[0].verified_addresses.eth_addresses.at(0);
if (!verified_address) {
log.warn(
'Farcaster verified address not found for reply cast created event- content will be ignored.',
);
await publishCast(
payload.data.hash,
({ username }) =>
`Hey @${username}, you need a verified address to participate in the contest.`,
);
return;
}

Expand Down
17 changes: 4 additions & 13 deletions libs/model/src/contest/FarcasterUpvoteAction.command.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { logger, type Command } from '@hicommonwealth/core';
import * as schemas from '@hicommonwealth/schemas';
import { NeynarAPIClient } from '@neynar/nodejs-sdk';
import { config } from '../config';
import { models } from '../database';
import { mustExist } from '../middleware/guards';
import { buildFarcasterContentUrl, emitEvent } from '../utils';
Expand All @@ -16,23 +14,16 @@ export function FarcasterUpvoteAction(): Command<
...schemas.FarcasterUpvoteAction,
auth: [],
body: async ({ payload }) => {
const client = new NeynarAPIClient(config.CONTESTS.NEYNAR_API_KEY!);
// get user verified address
const { users } = await client.fetchBulkUsers([
payload.untrustedData.fid,
]);
const verified_address = users[0].verified_addresses.eth_addresses.at(0);
const verified_address =
payload.interactor.verified_addresses?.eth_addresses.at(0);

if (!verified_address) {
log.warn(
'Farcaster verified address not found for upvote action- upvote will be ignored.',
);
return;
}

const castsResponse = await client.fetchBulkCasts([
payload.untrustedData.castId.hash,
]);
const { parent_hash, hash } = castsResponse.result.casts.at(0)!;
const { parent_hash, hash } = payload.cast;
const content_url = buildFarcasterContentUrl(parent_hash!, hash);

// find content from farcaster hash
Expand Down
6 changes: 1 addition & 5 deletions libs/model/src/policies/FarcasterWorker.policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,7 @@ export function FarcasterWorker(): Policy<typeof inputs> {
});
},
FarcasterVoteCreated: async ({ payload }) => {
const client = new NeynarAPIClient(config.CONTESTS.NEYNAR_API_KEY!);
const castsResponse = await client.fetchBulkCasts([
payload.untrustedData.castId.hash,
]);
const { parent_hash, hash } = castsResponse.result.casts.at(0)!;
const { parent_hash, hash } = payload.cast;
const content_url = buildFarcasterContentUrl(parent_hash!, hash);

const contestManager = await models.ContestManager.findOne({
Expand Down
3 changes: 1 addition & 2 deletions libs/model/src/services/openai/generateTokenIdea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,8 @@ const generateTokenIdea = async function* ({

// generate image url and send the generated url to the client (to save time on s3 upload)
const imageResponse = await openai.images.generate({
model: 'dall-e-3',
prompt: TOKEN_AI_PROMPTS_CONFIG.image(tokenIdea.name, tokenIdea.symbol),
size: '512x512',
size: '256x256',
n: 1,
response_format: 'url',
});
Expand Down
41 changes: 13 additions & 28 deletions libs/model/src/thread/GetThreads.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,6 @@ export function GetThreads(): Query<typeof schemas.GetThreads> {
pastWinners: ' AND CON.end_time <= NOW()',
all: '',
};
const baseWhereClause = `
community_id = :community_id AND
deleted_at IS NULL AND
archived_at IS ${archived ? 'NOT' : ''} NULL
${topic_id ? ' AND topic_id = :topic_id' : ''}
${stage ? ' AND stage = :stage' : ''}
${from_date ? ' AND T.created_at > :from_date' : ''}
${to_date ? ' AND T.created_at < :to_date' : ''}
${contestAddress ? ' AND id IN (SELECT * FROM "contest_ids")' : ''}
`;
const responseThreadsQuery = models.sequelize.query<
z.infer<typeof schemas.ThreadView>
>(
Expand All @@ -96,10 +86,18 @@ export function GetThreads(): Query<typeof schemas.GetThreads> {
pinned, community_id, T.created_at, updated_at, locked_at as thread_locked, links,
has_poll, last_commented_on, comment_count as "numberOfComments",
marked_as_spam_at, archived_at, topic_id, reaction_weights_sum, canvas_signed_data,
canvas_msg_id, last_edited, address_id, reaction_count
canvas_msg_id, last_edited, address_id, reaction_count,
(COUNT(id) OVER())::INTEGER AS total_num_thread_results
FROM "Threads" T
WHERE ${baseWhereClause}

WHERE
community_id = :community_id AND
deleted_at IS NULL AND
archived_at IS ${archived ? 'NOT' : ''} NULL
${topic_id ? ' AND topic_id = :topic_id' : ''}
${stage ? ' AND stage = :stage' : ''}
${from_date ? ' AND T.created_at > :from_date' : ''}
${to_date ? ' AND T.created_at < :to_date' : ''}
${contestAddress ? ' AND id IN (SELECT * FROM "contest_ids")' : ''}
ORDER BY pinned DESC, ${orderByQueries[order_by ?? 'newest']}
LIMIT :limit OFFSET :offset
), thread_metadata AS (
Expand Down Expand Up @@ -252,37 +250,24 @@ export function GetThreads(): Query<typeof schemas.GetThreads> {
},
);

const countThreadsQuery = models.sequelize.query<{ count: number }>(
`
SELECT COUNT(*) AS count
FROM "Threads" T
WHERE ${baseWhereClause}
`,
{
replacements,
type: QueryTypes.SELECT,
},
);

const numVotingThreadsQuery = models.Thread.count({
where: {
community_id,
stage: 'voting',
},
});

const [threads, numVotingThreads, countResult] = await Promise.all([
const [threads, numVotingThreads] = await Promise.all([
responseThreadsQuery,
numVotingThreadsQuery,
countThreadsQuery,
]);

return {
limit: replacements.limit,
page: replacements.page,
threads,
numVotingThreads,
threadCount: Number(countResult[0]?.count) || 0,
threadCount: threads.at(0)?.total_num_thread_results || 0,
};
},
};
Expand Down
9 changes: 6 additions & 3 deletions libs/model/src/user/GetUserProfile.query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@ import * as schemas from '@hicommonwealth/schemas';
import { Op } from 'sequelize';
import { z } from 'zod';
import { models } from '../database';
import { mustExist } from '../middleware/guards';

export function GetUserProfile(): Query<typeof schemas.GetUserProfile> {
return {
...schemas.GetUserProfile,
auth: [],
secure: true,
secure: false,
body: async ({ actor, payload }) => {
const user_id = payload.userId ?? actor.user.id;
const user_id = payload.userId ?? actor.user?.id;

const user = await models.User.findOne({
where: { id: user_id },
attributes: ['profile', 'xp_points', 'referral_link'],
});

mustExist('User', user);

const addresses = await models.Address.findAll({
where: { user_id },
include: [
Expand Down Expand Up @@ -98,7 +101,7 @@ export function GetUserProfile(): Query<typeof schemas.GetUserProfile> {
commentThreads: commentThreads.map(
(c) => c.toJSON() as z.infer<typeof schemas.ThreadView>,
),
isOwner: actor.user.id === user_id,
isOwner: actor.user?.id === user_id,
// ensure Tag is present in typed response
tags: profileTags.map((t) => ({ id: t.Tag!.id!, name: t.Tag!.name })),
xp_points: user!.xp_points ?? 0,
Expand Down
6 changes: 0 additions & 6 deletions libs/model/src/utils/buildFarcasterContentUrl.ts

This file was deleted.

14 changes: 14 additions & 0 deletions libs/model/src/utils/farcasterUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export function buildFarcasterContentUrl(
parentCastHash: string,
replyCashHash: string,
) {
return `/farcaster/${parentCastHash}/${replyCashHash}`;
}

export function parseFarcasterContentUrl(url: string) {
const [, , parentCastHash, replyCastHash] = url.split('/');
return {
parentCastHash,
replyCastHash,
};
}
2 changes: 1 addition & 1 deletion libs/model/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export * from './buildFarcasterContentUrl';
export * from './buildFarcasterWebhookName';
export * from './decodeContent';
export * from './defaultAvatar';
export * from './denormalizedCountUtils';
export * from './farcasterUtils';
export * from './getDefaultContestImage';
export * from './getDelta';
export * from './makeGetBalancesOptions';
Expand Down
Loading
Loading