Skip to content

Commit 9f5c784

Browse files
authored
feat: integrate ApeChain and Curtis networks (#1277)
* feat: integrate ApeChain and Curtis networks * chore: rename apechain to ape * chore: add changeset * chore: use Apechain logo for Curtis * feat: add support for Curtis and Apechain treasuries * fix: add placeholder for missing token metadata
1 parent 028de1a commit 9f5c784

14 files changed

Lines changed: 105 additions & 10 deletions

File tree

.changeset/odd-trains-clean.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@snapshot-labs/sx": patch
3+
---
4+
5+
add Apechain and Curtis networks

apps/api/src/evm/config.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,16 @@ import ProxyFactory from './abis/ProxyFactory.json';
77
import SimpleQuorumTimelockExecutionStrategy from './abis/SimpleQuorumTimelockExecutionStrategy.json';
88
import Space from './abis/Space.json';
99

10-
type NetworkID = 'eth' | 'sep' | 'oeth' | 'matic' | 'arb1' | 'base' | 'mnt';
10+
type NetworkID =
11+
| 'eth'
12+
| 'sep'
13+
| 'oeth'
14+
| 'matic'
15+
| 'arb1'
16+
| 'base'
17+
| 'mnt'
18+
| 'ape'
19+
| 'curtis';
1120

1221
const START_BLOCKS: Record<NetworkID, number> = {
1322
eth: 18962278,
@@ -16,7 +25,9 @@ const START_BLOCKS: Record<NetworkID, number> = {
1625
matic: 50858232,
1726
arb1: 157825417,
1827
base: 23524251,
19-
mnt: 75662182
28+
mnt: 75662182,
29+
ape: 12100384,
30+
curtis: 16682282
2031
};
2132

2233
export type FullConfig = {

apps/api/src/evm/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const maticConfig = createConfig('matic');
1010
const arb1Config = createConfig('arb1');
1111
const baseConfig = createConfig('base');
1212
const mntConfig = createConfig('mnt');
13+
const apeConfig = createConfig('ape');
14+
const curtisConfig = createConfig('curtis');
1315

1416
const ethIndexer = new evm.EvmIndexer(createWriters(ethConfig));
1517
const sepIndexer = new evm.EvmIndexer(createWriters(sepConfig));
@@ -18,6 +20,8 @@ const maticIndexer = new evm.EvmIndexer(createWriters(maticConfig));
1820
const arb1Indexer = new evm.EvmIndexer(createWriters(arb1Config));
1921
const baseIndexer = new evm.EvmIndexer(createWriters(baseConfig));
2022
const mntIndexer = new evm.EvmIndexer(createWriters(mntConfig));
23+
const apeIndexer = new evm.EvmIndexer(createWriters(apeConfig));
24+
const curtisIndexer = new evm.EvmIndexer(createWriters(curtisConfig));
2125

2226
export function addEvmIndexers(checkpoint: Checkpoint) {
2327
registerIndexer(checkpoint, ethConfig.indexerName, ethConfig, ethIndexer);
@@ -32,4 +36,11 @@ export function addEvmIndexers(checkpoint: Checkpoint) {
3236
registerIndexer(checkpoint, arb1Config.indexerName, arb1Config, arb1Indexer);
3337
registerIndexer(checkpoint, baseConfig.indexerName, baseConfig, baseIndexer);
3438
registerIndexer(checkpoint, mntConfig.indexerName, mntConfig, mntIndexer);
39+
registerIndexer(checkpoint, apeConfig.indexerName, apeConfig, apeIndexer);
40+
registerIndexer(
41+
checkpoint,
42+
curtisConfig.indexerName,
43+
curtisConfig,
44+
curtisIndexer
45+
);
3546
}

apps/mana/src/eth/rpc.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
22
clients,
3+
evmApe,
34
evmArbitrum,
45
evmBase,
6+
evmCurtis,
57
evmMainnet,
68
evmMantle,
79
EvmNetworkConfig,
@@ -21,6 +23,8 @@ export const NETWORKS = new Map<number, EvmNetworkConfig>([
2123
[5000, evmMantle],
2224
[42161, evmArbitrum],
2325
[1, evmMainnet],
26+
[33139, evmApe],
27+
[33111, evmCurtis],
2428
[11155111, evmSepolia]
2529
]);
2630

apps/ui/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ VITE_MANA_URL=https://mana.box
44
VITE_HIGHLIGHT_URL=https://testnet.highlight.red
55
VITE_IPFS_GATEWAY=ipfs.snapshot.box
66
VITE_INFURA_API_KEY=46a5dd9727bf48d4a132672d3f376146
7-
VITE_ALCHEMY_API_KEY=ombBQyf580z-jx2EVQgJu4eTjePU-a2z
7+
VITE_ALCHEMY_API_KEY=Dg0ixifhoQIaQrgsbK76LcX13Seu92U2
88
VITE_OPENSEA_API_KEY=dad1ec57d9024a1d9cb72e6d82c2d015
99
VITE_GA_MEASUREMENT_ID=G-8MQS50MVZX
1010
VITE_TENDERLY_ACCESS_KEY=8-1V1FGLxFqhs75T7bUs4lK1BaPOnfcT

apps/ui/src/helpers/alchemy/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ export const SUPPORTED_CHAIN_IDS = [
1515
137, // Polygon,
1616
324, // ZkSync Era
1717
8453, // Base
18+
33111, // Curtis
19+
33139, // Apechain
1820
42161, // Arbitrum
1921
42170, // Arbitrum Nova
2022
11155111 // Sepolia
@@ -26,11 +28,20 @@ const NETWORKS: Record<(typeof SUPPORTED_CHAIN_IDS)[number], string> = {
2628
137: 'polygon-mainnet',
2729
324: 'zksync-mainnet',
2830
8453: 'base-mainnet',
31+
33111: 'apechain-curtis',
32+
33139: 'apechain-mainnet',
2933
42161: 'arb-mainnet',
3034
42170: 'arbnova-mainnet',
3135
11155111: 'eth-sepolia'
3236
};
3337

38+
const DEFAULT_METADATA: GetTokensMetadataResponse[number] = {
39+
name: 'This token is not recognized',
40+
symbol: '?',
41+
decimals: 18,
42+
logo: ''
43+
};
44+
3445
function getApiUrl(chainId: ChainId) {
3546
const network = NETWORKS[chainId];
3647
if (!network) throw new Error('Unsupported chain for Alchemy API');
@@ -131,13 +142,15 @@ export async function getTokensMetadata(
131142
addresses: string[],
132143
chainId: ChainId
133144
): Promise<GetTokensMetadataResponse> {
134-
return batchRequest(
145+
const response = await batchRequest(
135146
addresses.map(address => ({
136147
method: 'alchemy_getTokenMetadata',
137148
params: [address]
138149
})),
139150
chainId
140151
);
152+
153+
return response.map(metadata => metadata || DEFAULT_METADATA);
141154
}
142155

143156
/**

apps/ui/src/helpers/constants.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export const CHAIN_IDS: Record<Exclude<NetworkID, 's' | 's-tn'>, ChainId> = {
3131
base: 8453,
3232
arb1: 42161,
3333
mnt: 5000,
34+
ape: 33139,
35+
curtis: 33111,
3436
sep: 11155111,
3537
// Starknet
3638
sn: '0x534e5f4d41494e',
@@ -42,15 +44,19 @@ export const COINGECKO_ASSET_PLATFORMS = {
4244
10: 'optimistic-ethereum',
4345
137: 'polygon-pos',
4446
8453: 'base',
45-
42161: 'arbitrum-one'
47+
42161: 'arbitrum-one',
48+
33139: 'ethereum',
49+
33111: 'apechain'
4650
};
4751

4852
export const COINGECKO_BASE_ASSETS = {
4953
1: 'ethereum',
5054
10: 'ethereum',
5155
137: 'matic-network',
5256
8453: 'ethereum',
53-
42161: 'ethereum'
57+
42161: 'ethereum',
58+
33139: 'apecoin',
59+
33111: 'apecoin'
5460
};
5561

5662
export const MAX_SYMBOL_LENGTH = 12;

apps/ui/src/helpers/opensea.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export const SUPPORTED_CHAIN_IDS = [
2626
1329, // Sei
2727
8217, // Klaytn
2828
8453, // Base
29+
33111, // Curtis
30+
33139, // Apechain
2931
42161, // Arbitrum
3032
42170, // Arbitrum Nova
3133
43114, // Avalanche
@@ -40,6 +42,8 @@ const NETWORKS: Record<(typeof SUPPORTED_CHAIN_IDS)[number], ChainItem> = {
4042
1329: { name: 'sei', isTestnet: false },
4143
8217: { name: 'klaytn', isTestnet: false },
4244
8453: { name: 'base', isTestnet: false },
45+
33111: { name: 'ape_curtis', isTestnet: true },
46+
33139: { name: 'ape_chain', isTestnet: false },
4347
42161: { name: 'arbitrum', isTestnet: false },
4448
42170: { name: 'arbitrum_nova', isTestnet: false },
4549
43114: { name: 'avalanche', isTestnet: false },

apps/ui/src/networks/evm/actions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import { Provider, Web3Provider } from '@ethersproject/providers';
44
import { formatBytes32String } from '@ethersproject/strings';
55
import {
66
clients,
7+
evmApe,
78
evmArbitrum,
89
evmBase,
10+
evmCurtis,
911
evmMainnet,
1012
evmMantle,
1113
EvmNetworkConfig,
@@ -60,6 +62,8 @@ const CONFIGS: Record<number, EvmNetworkConfig> = {
6062
8453: evmBase,
6163
42161: evmArbitrum,
6264
1: evmMainnet,
65+
33139: evmApe,
66+
33111: evmCurtis,
6367
11155111: evmSepolia
6468
};
6569

apps/ui/src/networks/evm/index.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ export const METADATA: Record<string, Metadata> = {
7272
'ipfs://bafkreid7ndxh6y2ljw2jhbisodiyrhcy2udvnwqgon5wgells3kh4si5z4',
7373
blockTime: ETH_MAINNET_BLOCK_TIME
7474
},
75+
ape: {
76+
name: 'ApeChain',
77+
ticker: 'APE',
78+
chainId: 33139,
79+
currentChainId: 1,
80+
apiUrl: UNIFIED_API_URL,
81+
avatar:
82+
'ipfs://bafkreielbgcox2jsw3g6pqulqb7pyjgx7czjt6ahnibihaij6lozoy53w4',
83+
blockTime: ETH_MAINNET_BLOCK_TIME
84+
},
85+
curtis: {
86+
name: 'Curtis',
87+
ticker: 'APE',
88+
chainId: 33111,
89+
currentChainId: 11155111,
90+
apiUrl: UNIFIED_API_TESTNET_URL,
91+
avatar:
92+
'ipfs://bafkreielbgcox2jsw3g6pqulqb7pyjgx7czjt6ahnibihaij6lozoy53w4',
93+
blockTime: ETH_MAINNET_BLOCK_TIME
94+
},
7595
sep: {
7696
name: 'Ethereum Sepolia',
7797
chainId: 11155111,
@@ -143,7 +163,9 @@ export function createEvmNetwork(networkId: NetworkID): Network {
143163
'matic',
144164
'base',
145165
'mnt',
146-
'arb1'
166+
'arb1',
167+
'ape',
168+
'curtis'
147169
].includes(networkId),
148170
managerConnectors: EVM_CONNECTORS,
149171
actions: createActions(provider, helpers, chainId),

0 commit comments

Comments
 (0)