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

hicommonwealth / commonwealth / 15592247589

11 Jun 2025 06:03PM UTC coverage: 40.741% (-0.006%) from 40.747%
15592247589

push

github

web-flow
Merge pull request #12425 from hicommonwealth/rotorsoft/prepare-for-zod-v4

Prepares migration to zod/v4

1776 of 4725 branches covered (37.59%)

Branch coverage included in aggregate %.

7 of 19 new or added lines in 11 files covered. (36.84%)

3203 of 7496 relevant lines covered (42.73%)

37.51 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);
35✔
11

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

16
const neynarMutex = new Mutex();
35✔
17

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}`);
×
NEW
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

NEW
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