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

hicommonwealth / commonwealth / 13183913818

06 Feb 2025 04:58PM UTC coverage: 46.438% (-0.07%) from 46.505%
13183913818

Pull #10877

github

web-flow
Merge f8bcf155a into 21e4c81d5
Pull Request #10877: Added logic to gate premium APIs. Gated launchToken

1364 of 3277 branches covered (41.62%)

Branch coverage included in aggregate %.

1 of 13 new or added lines in 2 files covered. (7.69%)

2612 of 5285 relevant lines covered (49.42%)

36.72 hits per line

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

0.0
/libs/model/src/bot/LaunchTokenBot.command.ts
1
import {
2
  AppError,
3
  InvalidState,
4
  ServerError,
5
  command,
6
  type Command,
7
} from '@hicommonwealth/core';
8
import {
9
  commonProtocol as cp,
10
  getErc20TokenInfo,
11
  getLaunchpadTokenCreatedTransaction,
12
  launchpadFactoryAbi,
13
} from '@hicommonwealth/evm-protocols';
14
import { config } from '@hicommonwealth/model';
15
import * as schemas from '@hicommonwealth/schemas';
16
import { TokenView } from '@hicommonwealth/schemas';
17
import { ChainBase, ChainType } from '@hicommonwealth/shared';
18
import { z } from 'zod';
19
import { CreateCommunity } from '../community';
20
import { models } from '../database';
21
import { mustExist } from '../middleware/guards';
22

23
export function LaunchTokenBot(): Command<typeof schemas.LaunchToken> {
24
  return {
×
25
    ...schemas.LaunchToken,
26
    auth: [],
27
    body: async ({ payload, actor }) => {
28
      const { name, symbol, totalSupply, eth_chain_id, icon_url, description } =
29
        payload;
×
30

NEW
31
      if (!cp.isValidChain(eth_chain_id)) {
×
NEW
32
        throw new AppError('eth_chain_id is not supported');
×
33
      }
34

NEW
35
      if (!config.WEB3.CONTEST_BOT_PRIVATE_KEY)
×
NEW
36
        throw new ServerError('Contest bot private key not set!');
×
37

NEW
38
      const communityId = name.toLowerCase().replace(/\s+/g, '-');
×
NEW
39
      const existingCommunity = await models.Community.findOne({
×
40
        where: { id: communityId },
41
      });
42

NEW
43
      if (existingCommunity) {
×
NEW
44
        throw new AppError('Token already exists, choose another name');
×
45
      }
46

47
      const chainNode = await models.ChainNode.findOne({
×
48
        where: { eth_chain_id },
49
        attributes: ['id', 'eth_chain_id', 'url', 'private_url'],
50
      });
51

52
      mustExist('Chain Node', chainNode);
×
53

54
      // Create corresponding community for token
NEW
55
      await command(CreateCommunity(), {
×
56
        actor,
57
        payload: {
58
          id: communityId,
59
          name,
60
          default_symbol: symbol,
61
          icon_url,
62
          description,
63
          base: ChainBase.Ethereum,
64
          token_name: name,
65
          chain_node_id: chainNode!.id!,
66
          type: ChainType.Offchain,
67
          social_links: [],
68
          directory_page_enabled: false,
69
          tags: [],
70
        },
71
      });
72

NEW
73
      await models.Community.update(
×
74
        { namespace: name },
75
        { where: { id: communityId } },
76
      );
77

78
      const web3 = cp.createPrivateEvmClient({
×
79
        rpc: chainNode.private_url!,
80
        privateKey: config.WEB3.CONTEST_BOT_PRIVATE_KEY,
81
      });
82
      const launchpadContract = new web3.eth.Contract(
×
83
        launchpadFactoryAbi,
84
        cp.factoryContracts[
85
          eth_chain_id as cp.ValidChains.SepoliaBase
86
        ].launchpad,
87
      );
88
      const receipt = await cp.launchToken(
×
89
        launchpadContract,
90
        name,
91
        symbol,
92
        [],
93
        [],
94
        web3.utils.toWei(totalSupply.toString(), 'ether') as string,
95
        web3.eth.defaultAccount as string,
96
        830000,
97
        cp.factoryContracts[eth_chain_id as cp.ValidChains.SepoliaBase]
98
          .tokenCommunityManager,
99
      );
100

101
      const tokenData = await getLaunchpadTokenCreatedTransaction({
×
102
        rpc: chainNode.private_url! || chainNode.url!,
×
103
        transactionHash: receipt.transactionHash,
104
      });
105

106
      if (!tokenData) {
×
107
        throw new InvalidState('Transaction not found');
×
108
      }
109

110
      let tokenInfo: { name: string; symbol: string; totalSupply: bigint };
111
      try {
×
112
        tokenInfo = await getErc20TokenInfo({
×
113
          rpc: chainNode.private_url || chainNode.url,
×
114
          tokenAddress: tokenData.parsedArgs.tokenAddress,
115
        });
116
      } catch (e) {
117
        throw new Error(
×
118
          `Failed to get erc20 token properties for token ${tokenData.parsedArgs.tokenAddress}`,
119
        );
120
      }
121

122
      const [token] = await models.LaunchpadToken.findOrCreate({
×
123
        where: {
124
          token_address: tokenData.parsedArgs.tokenAddress.toLowerCase(),
125
          namespace: tokenData.parsedArgs.namespace,
126
        },
127
        defaults: {
128
          token_address: tokenData.parsedArgs.tokenAddress.toLowerCase(),
129
          namespace: tokenData.parsedArgs.namespace,
130
          name: tokenInfo.name,
131
          symbol: tokenInfo.symbol,
132
          initial_supply: Number(tokenInfo.totalSupply / BigInt(1e18)),
133
          liquidity_transferred: false,
134
          launchpad_liquidity: tokenData.parsedArgs.launchpadLiquidity,
135
          eth_market_cap_target: cp.getTargetMarketCap(),
136
          description: description ?? null,
×
137
          icon_url: icon_url ?? null,
×
138
        },
139
      });
140

NEW
141
      const response = {
×
142
        community_url: `https://common.xyz/${communityId}`,
143
        ...token!.toJSON(),
144
      };
NEW
145
      return response as unknown as z.infer<typeof TokenView> & {
×
146
        community_url: string;
147
      };
148
    },
149
  };
150
}
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