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

hicommonwealth / commonwealth / 22331928937

24 Feb 2026 01:00AM UTC coverage: 38.204% (+0.03%) from 38.173%
22331928937

Pull #13194

github

web-flow
Merge 37238f8f5 into 6658c85df
Pull Request #13194: AI Completion Fixes

2110 of 6026 branches covered (35.01%)

Branch coverage included in aggregate %.

9 of 81 new or added lines in 4 files covered. (11.11%)

30 existing lines in 14 files now uncovered.

3752 of 9318 relevant lines covered (40.27%)

52.52 hits per line

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

0.0
/libs/model/src/aggregates/bot/LaunchTokenBot.command.ts
1
import { LaunchpadAbi } from '@commonxyz/common-protocol-abis';
2
import {
3
  AppError,
4
  command,
5
  InvalidState,
6
  logger,
7
  ServerError,
8
  type Command,
9
} from '@hicommonwealth/core';
10
import {
11
  createPrivateEvmClient,
12
  getErc20TokenInfo,
13
  getFactoryContract,
14
  getLaunchpadTokenCreatedTransaction,
15
  getTargetMarketCap,
16
  isValidChain,
17
  launchToken,
18
} from '@hicommonwealth/evm-protocols';
19
import * as schemas from '@hicommonwealth/schemas';
20
import { ChainBase, ChainType } from '@hicommonwealth/shared';
21
import _ from 'lodash';
22
import { z } from 'zod';
23
import { config } from '../../config';
24
import { models } from '../../database';
25
import { mustExist } from '../../middleware/guards';
26
import { CreateCommunity } from '../community';
27

UNCOV
28
const log = logger(import.meta);
×
29

30
export function LaunchTokenBot(): Command<typeof schemas.LaunchToken> {
31
  return {
×
32
    ...schemas.LaunchToken,
33
    auth: [],
34
    body: async ({ payload, actor }) => {
35
      const { name, symbol, totalSupply, eth_chain_id, icon_url, description } =
36
        payload;
×
37

38
      if (!isValidChain(eth_chain_id)) {
×
39
        throw new AppError('eth_chain_id is not supported');
×
40
      }
41

42
      if (!config.WEB3.LAUNCHPAD_PRIVATE_KEY)
×
43
        throw new ServerError('Launchpad private key not set!');
×
44

45
      const communityId = _.kebabCase(name.toLowerCase());
×
46
      const existingCommunity = await models.Community.findOne({
×
47
        where: { id: communityId },
48
      });
49

50
      if (existingCommunity) {
×
51
        throw new AppError('Token already exists, choose another name');
×
52
      }
53

54
      const chainNode = await models.ChainNode.scope('withPrivateData').findOne(
×
55
        {
56
          where: { eth_chain_id },
57
          attributes: ['id', 'eth_chain_id', 'url', 'private_url'],
58
        },
59
      );
60

61
      mustExist('Chain Node', chainNode);
×
62

63
      const web3 = createPrivateEvmClient({
×
64
        rpc: chainNode.private_url!,
65
        privateKey: config.WEB3.LAUNCHPAD_PRIVATE_KEY,
66
      });
67
      const launchpadContract = new web3.eth.Contract(
×
68
        LaunchpadAbi,
69
        getFactoryContract(eth_chain_id).Launchpad,
70
      );
71
      const receipt = await launchToken(
×
72
        launchpadContract,
73
        name,
74
        symbol,
75
        [],
76
        [],
77
        web3.utils.toWei(totalSupply.toString(), 'ether') as string,
78
        web3.eth.defaultAccount as string,
79
        830000,
80
        getFactoryContract(eth_chain_id).TokenCommunityManager,
81
      );
82

83
      const tokenData = await getLaunchpadTokenCreatedTransaction({
×
84
        rpc: chainNode.private_url! || chainNode.url!,
×
85
        transactionHash: receipt.transactionHash,
86
      });
87

88
      if (!tokenData) {
×
89
        throw new InvalidState('Transaction not found');
×
90
      }
91

92
      let tokenInfo: { name: string; symbol: string; totalSupply: bigint };
93
      try {
×
94
        tokenInfo = await getErc20TokenInfo({
×
95
          rpc: chainNode.private_url || chainNode.url,
×
96
          tokenAddress: tokenData.parsedArgs.tokenAddress,
97
        });
98
      } catch (e) {
99
        log.error(
×
100
          `Failed to get erc20 token properties for token ${tokenData.parsedArgs.tokenAddress}`,
101
          e instanceof Error ? e : undefined,
×
102
          {
103
            e,
104
          },
105
        );
106
        throw new Error(
×
107
          `Failed to get erc20 token properties for token ${tokenData.parsedArgs.tokenAddress}`,
108
        );
109
      }
110

111
      const [token] = await models.LaunchpadToken.findOrCreate({
×
112
        where: {
113
          token_address: tokenData.parsedArgs.tokenAddress.toLowerCase(),
114
          namespace: tokenData.parsedArgs.namespace,
115
        },
116
        defaults: {
117
          token_address: tokenData.parsedArgs.tokenAddress.toLowerCase(),
118
          namespace: tokenData.parsedArgs.namespace,
119
          name: tokenInfo.name,
120
          symbol: tokenInfo.symbol,
121
          initial_supply: Number(tokenInfo.totalSupply / BigInt(1e18)),
122
          liquidity_transferred: false,
123
          launchpad_liquidity: tokenData.parsedArgs.launchpadLiquidity,
124
          eth_market_cap_target: getTargetMarketCap(),
125
          description: description ?? null,
×
126
          icon_url: icon_url ?? null,
×
127
        },
128
      });
129

130
      // Create corresponding community for token
131
      await command(CreateCommunity(), {
×
132
        actor,
133
        payload: {
134
          id: communityId,
135
          name,
136
          default_symbol: symbol,
137
          icon_url,
138
          description,
139
          base: ChainBase.Ethereum,
140
          token_name: name,
141
          chain_node_id: chainNode!.id!,
142
          type: ChainType.Offchain,
143
          social_links: [],
144
          directory_page_enabled: false,
145
          tags: [],
146
        },
147
      });
148

149
      await models.Community.update(
×
150
        { namespace: name },
151
        { where: { id: communityId } },
152
      );
153

154
      const response = {
×
155
        community_url: `${config.SERVER_URL}/${communityId}`,
156
        ...token!.toJSON(),
157
      };
158
      return response as unknown as z.infer<typeof schemas.TokenView> & {
×
159
        community_url: string;
160
      };
161
    },
162
  };
163
}
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