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

hicommonwealth / commonwealth / 13973489816

20 Mar 2025 03:44PM UTC coverage: 43.661% (+0.02%) from 43.641%
13973489816

push

github

web-flow
Merge pull request #11177 from hicommonwealth/tim/cp-viem

Contest Web3 -> Viem

1393 of 3542 branches covered (39.33%)

Branch coverage included in aggregate %.

5 of 23 new or added lines in 8 files covered. (21.74%)

2 existing lines in 1 file now uncovered.

2612 of 5631 relevant lines covered (46.39%)

37.73 hits per line

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

16.67
/libs/model/src/services/commonProtocol/newNamespaceValidator.ts
1
import { AppError, ServerError } from '@hicommonwealth/core';
2
import {
3
  EvmEventSignatures,
4
  decodeParameters,
5
  getNamespace,
6
  getTransactionReceipt,
7
  mustBeProtocolChainId,
8
} from '@hicommonwealth/evm-protocols';
9
import { models } from '@hicommonwealth/model';
10
import { BalanceSourceType } from '@hicommonwealth/shared';
11
import { CommunityAttributes } from '../../models';
12
import { equalEvmAddresses } from '../../utils';
13
import { getBalances } from '../tokenBalanceCache';
14

15
/**
16
 * Validate if an attested new namespace is valid on-chain Checks:
17
 * 1. Tx success
18
 * 2. sender validity
19
 * 3. correct contract address
20
 * 4. If user is the admin of namespace on-chain
21
 * @param model
22
 * @param namespace The namespace name
23
 * @param txHash transaction hash of creation tx
24
 * @param address user's address
25
 * @param community the community
26
 * @returns an AppError if any validations fail, else passses
27
 */
28
export const validateNamespace = async (
31✔
29
  namespace: string,
30
  txHash: string,
31
  address: string,
32
  community: CommunityAttributes,
33
): Promise<string> => {
34
  if (!community.chain_node_id) {
1!
35
    throw new AppError('Invalid community');
×
36
  }
37

38
  const chainNode = await models.ChainNode.scope('withPrivateData').findOne({
1✔
39
    where: {
40
      id: community.chain_node_id,
41
    },
42
  });
43

44
  if (!chainNode) {
1!
45
    throw new AppError('Invalid chain');
×
46
  }
47

48
  if (!chainNode.eth_chain_id) {
1!
49
    throw new AppError('Namespace not supported on selected chain');
1✔
50
  }
51

52
  if (!chainNode.private_url) {
×
53
    throw new ServerError(
×
54
      `Chain Node private url not found for chain node id ${chainNode.id}`,
55
    );
56
  }
57

58
  const chain_id = chainNode.eth_chain_id;
×
NEW
59
  mustBeProtocolChainId(chain_id);
×
60

61
  //tx data validation
62
  const { txReceipt } = await getTransactionReceipt({
×
63
    rpc: chainNode.private_url,
64
    txHash,
65
  });
66
  if (!txReceipt.status) {
×
67
    throw new AppError('tx failed');
×
68
  }
69
  if (txReceipt.from.toLowerCase() !== address.toLowerCase()) {
×
70
    throw new AppError('Attested sender did not tx sender');
×
71
  }
72

73
  //validate contract data
74
  const activeNamespace = await getNamespace(
×
75
    { rpc: chainNode.private_url, eth_chain_id: chain_id },
76
    namespace,
77
  );
78

79
  let namespaceAddress: string | undefined;
80

81
  // only emitted in token launch flows (launchpad)
82
  const communityNamespaceCreatedLog = txReceipt.logs.find((l) => {
×
83
    if (l.topics && l.topics.length > 0) {
×
84
      return (
×
85
        l.topics[0].toString() ===
86
        EvmEventSignatures.NamespaceFactory.CommunityNamespaceCreated
87
      );
88
    }
89
    return false;
×
90
  });
91
  if (communityNamespaceCreatedLog) {
×
92
    const { 0: _namespaceAddress } = decodeParameters({
×
93
      abiInput: ['address', 'address'],
94
      data: communityNamespaceCreatedLog.data!.toString(),
95
    });
96
    namespaceAddress = _namespaceAddress as string;
×
97
  } else {
98
    // default namespace deployment tx
99
    namespaceAddress = txReceipt.logs[0].address;
×
100
  }
101

102
  if (!equalEvmAddresses(activeNamespace, namespaceAddress)) {
×
103
    throw new AppError('Invalid tx hash for namespace creation');
×
104
  }
105

106
  // Validate User as admin
107
  const balance = await getBalances({
×
108
    balanceSourceType: BalanceSourceType.ERC1155,
109
    addresses: [address],
110
    sourceOptions: {
111
      contractAddress: activeNamespace,
112
      evmChainId: chainNode.eth_chain_id,
113
      tokenId: 0,
114
    },
115
    cacheRefresh: true,
116
  });
117
  if (balance[address] !== '1') {
×
118
    throw new AppError('User not admin of namespace');
×
119
  }
120

121
  return activeNamespace;
×
122
};
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