• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hicommonwealth / commonwealth / 16150741569

08 Jul 2025 05:57PM UTC coverage: 40.016% (+0.008%) from 40.008%
16150741569

push

github

web-flow
Merge pull request #12599 from hicommonwealth/Rotorsoft-patch-1

Update CODEOWNERS

1857 of 5027 branches covered (36.94%)

Branch coverage included in aggregate %.

3293 of 7843 relevant lines covered (41.99%)

36.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.52
/libs/model/src/aggregates/contest/UpdateContestManagerFrameHashes.command.ts
1
import { Command, logger } from '@hicommonwealth/core';
2
import { config, models } from '@hicommonwealth/model';
3
import * as schemas from '@hicommonwealth/schemas';
4
import { NeynarAPIClient } from '@neynar/nodejs-sdk';
5
import { Mutex } from 'async-mutex';
6
import _ from 'lodash';
7
import { Op } from 'sequelize';
8
import { mustExist } from '../../middleware/guards';
9

10
const log = logger(import.meta);
11

31✔
12
const Errors = {
13
  ContestEnded: 'Contest has ended',
31✔
14
};
15

16
const neynarMutex = new Mutex();
17

31✔
18
export function UpdateContestManagerFrameHashes(): Command<
19
  typeof schemas.UpdateContestManagerFrameHashes
20
> {
21
  return {
22
    ...schemas.UpdateContestManagerFrameHashes,
×
23
    auth: [],
24
    body: async ({ payload }) => {
25
      await neynarMutex.runExclusive(async () => {
26
        const contestManager = await models.ContestManager.findOne({
×
27
          where: {
×
28
            contest_address: payload.contest_address,
29
            cancelled: {
30
              [Op.not]: true,
31
            },
32
            ended: {
33
              [Op.not]: true,
34
            },
35
          },
36
          include: [
37
            {
38
              model: models.Contest,
39
              as: 'contests',
40
              required: true,
41
            },
42
          ],
43
        });
44
        mustExist('Contest Manager', contestManager);
45
        if (new Date() > contestManager.contests![0]!.end_time) {
×
46
          log.warn(`${Errors.ContestEnded}: ${contestManager.contest_address}`);
×
47
          return {};
×
48
        }
×
49

50
        // find webhook by ID
51
        const client = new NeynarAPIClient(config.CONTESTS.NEYNAR_API_KEY!);
52
        const { webhook: existingCastWebhook } = await client.lookupWebhook(
×
53
          config.CONTESTS.NEYNAR_CAST_WEBHOOK_ID!,
×
54
        );
55
        mustExist('Neynar Webhook', existingCastWebhook);
56

×
57
        // remove and add hashes to subscription
58
        const allParentHashes = _.uniq([
59
          ...(existingCastWebhook?.subscription?.filters['cast.created']
×
60
            ?.parent_hashes || []),
×
61
          ...(existingCastWebhook?.subscription?.filters['cast.deleted']
62
            ?.parent_hashes || []),
×
63
        ])
64
          .filter((hash) => {
65
            return !(payload.frames_to_remove || []).includes(hash);
66
          })
×
67
          .concat(payload.frames_to_add || []);
68

×
69
        const subscription = {
70
          ...(existingCastWebhook.subscription?.filters || {}),
×
71
          // reply cast created on parent
×
72
          'cast.created': {
73
            ...(existingCastWebhook.subscription?.filters['cast.created'] ||
74
              {}),
×
75
            parent_hashes: allParentHashes,
76
          },
77
          // reply cast deleted on parent
78
          'cast.deleted': {
79
            ...(existingCastWebhook.subscription?.filters['cast.deleted'] ||
80
              {}),
×
81
            parent_hashes: allParentHashes,
82
          },
83
        };
84

85
        await client.updateWebhook(
86
          existingCastWebhook.webhook_id,
×
87
          existingCastWebhook.title,
88
          existingCastWebhook.target_url,
89
          {
90
            subscription,
91
          },
92
        );
93

94
        if (!payload.webhooks_only) {
95
          // update contest manager frame hashes
×
96
          contestManager.farcaster_frame_hashes = (
97
            contestManager.farcaster_frame_hashes || []
×
98
          )
×
99
            .filter((hash) => {
100
              return !(payload.frames_to_remove || []).includes(hash);
101
            })
×
102
            .concat(payload.frames_to_add || []);
103
          await contestManager.save();
×
104
        }
×
105
      });
106

107
      return {};
108
    },
×
109
  };
110
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc