Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ VITE_FEATURE_BOB=false
VITE_FEATURE_MODE=false
VITE_FEATURE_SONEIUM=false
VITE_FEATURE_SEI=false
VITE_FEATURE_CITREA=false
VITE_FEATURE_YIELD_MULTI_ACCOUNT=true
VITE_FEATURE_YIELD_XYZ=true
VITE_FEATURE_YIELDS_PAGE=true
Expand Down Expand Up @@ -235,6 +236,7 @@ VITE_TRON_NODE_URL=https://api.trongrid.io
VITE_UNICHAIN_NODE_URL=https://mainnet.unichain.org
VITE_WORLDCHAIN_NODE_URL=https://worldchain-mainnet.g.alchemy.com/public
VITE_ZKSYNC_ERA_NODE_URL=https://mainnet.era.zksync.io
VITE_CITREA_NODE_URL=https://rpc.mainnet.citrea.xyz

# midgard
VITE_THORCHAIN_MIDGARD_URL=https://api.thorchain.shapeshift.com/midgard/v2
Expand Down
2 changes: 2 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ VITE_FEATURE_YIELD_MULTI_ACCOUNT=true
VITE_FEATURE_AGENTIC_CHAT=true
VITE_FEATURE_MM_NATIVE_MULTICHAIN=true
VITE_FEATURE_NOTIFICATIONS_WEBSERVICES=true
VITE_FEATURE_CITREA=true

# mixpanel
VITE_MIXPANEL_TOKEN=a867ce40912a6b7d01d088cf62b0e1ff
Expand Down Expand Up @@ -92,6 +93,7 @@ VITE_BASE_NODE_URL=https://dev-api.base.shapeshift.com/api/v1/jsonrpc
VITE_THORCHAIN_NODE_URL=https://dev-api.thorchain.shapeshift.com/lcd
VITE_MAYACHAIN_NODE_URL=https://dev-api.mayachain.shapeshift.com/lcd
VITE_SOLANA_NODE_URL=https://dev-api.solana.shapeshift.com/api/v1/jsonrpc
VITE_CITREA_NODE_URL=https://rpc.mainnet.citrea.xyz

# midgard
VITE_THORCHAIN_MIDGARD_URL=https://dev-api.thorchain.shapeshift.com/midgard/v2
Expand Down
30 changes: 30 additions & 0 deletions chains/citrea.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"camelName": "citrea",
"pascalName": "Citrea",
"upperName": "CITREA",
"chainId": 4114,
"viemChainName": "citrea",
"nativeSymbol": "cBTC",
"nativeName": "Citrea Bitcoin",
"nativePrecision": 18,
"isNativeEth": false,
"color": "#F7931A",
"networkIconUrl": "https://assets.coingecko.com/asset_platforms/images/102132293/small/citrea.jpg",
"nativeIconUrl": "https://assets.coingecko.com/coins/images/102172844/large/cBTC.png",
"explorerUrl": "https://explorer.mainnet.citrea.xyz",
"explorerAddressLink": "https://explorer.mainnet.citrea.xyz/address/",
"explorerTxLink": "https://explorer.mainnet.citrea.xyz/tx/",
"rpcUrl": "https://rpc.mainnet.citrea.xyz",
"publicRpcUrls": ["https://rpc.mainnet.citrea.xyz"],
"coingeckoPlatform": "citrea",
"wrappedNativeAddress": "0x3100000000000000000000000000000000000006",
"relatedAssetKey": "eip155:4114/slip44:60",
"shortName": "citrea",
"swappers": {
"relay": { "supported": false },
"across": { "supported": false },
"portals": { "supported": false },
"zerion": { "supported": false },
"yieldxyz": { "supported": false }
}
}
11 changes: 11 additions & 0 deletions headers/csps/chains/citrea.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { loadEnv } from 'vite'

import { PUBLIC_RPC_URLS } from '../../../packages/contracts/src/publicRpcUrls'
import type { Csp } from '../../types'

const mode = process.env.MODE ?? process.env.NODE_ENV ?? 'development'
const env = loadEnv(mode, process.cwd(), '')

export const csp: Csp = {
'connect-src': [env.VITE_CITREA_NODE_URL, ...PUBLIC_RPC_URLS.citrea],
}
2 changes: 2 additions & 0 deletions headers/csps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { csp as blast } from './chains/blast'
import { csp as bnbsmartchain } from './chains/bnbsmartchain'
import { csp as bob } from './chains/bob'
import { csp as celo } from './chains/celo'
import { csp as citrea } from './chains/citrea'
import { csp as cosmos } from './chains/cosmos'
import { csp as cronos } from './chains/cronos'
import { csp as dogecoin } from './chains/dogecoin'
Expand Down Expand Up @@ -206,4 +207,5 @@ export const csps = [
railway,
discord,
yieldxyz,
citrea,
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"eip155:4114/slip44:60":"citrea","eip155:4114/erc20:0x547afd93b9c47d552059feb556909e017f8a9b25":"citrea","eip155:4114/erc20:0xe045e6c36cf77faa2cfb54466d71a3aef7bbe839":"citrea-bridged-usdc","eip155:4114/erc20:0x9f3096bac87e7f03dc09b0b416eb0df837304dc4":"citrea-bridged-usdt","eip155:4114/erc20:0xdf240dc08b0fdad1d93b74d5048871232f6bea3d":"citrea-bridged-wbtc-citrea","eip155:4114/erc20:0x8d82c4e3c936c7b5724a382a9c5a4e6eb7ab6d5d":"citrea-usd","eip155:4114/erc20:0xac8c1aeb584765db16ac3e08d4736cfce198589b":"generic-usd","eip155:4114/erc20:0x2a36f2b204b46fd82653cd06d00c7ff757c99ae4":"juice-protocol","eip155:4114/erc20:0x1b70ae756b1089cc5948e4f8a2ad498df30e897d":"savings-vault-jusd-citrea","eip155:4114/erc20:0x384157027b1cdeac4e26e3709667bb28735379bb":"symbiosis-btc-citrea","eip155:4114/erc20:0x3100000000000000000000000000000000000006":"wrapped-citrea-bitcoin"}
2 changes: 2 additions & 0 deletions packages/caip/src/adapters/coingecko/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import flowevm from "./eip155_747/adapter.json";
import celo from "./eip155_42220/adapter.json";
import sei from "./eip155_1329/adapter.json";
import abstract from "./eip155_2741/adapter.json";
import citrea from "./eip155_4114/adapter.json";
import cosmos from "./cosmos_cosmoshub-4/adapter.json";
import thorchain from "./cosmos_thorchain-1/adapter.json";
import mayachain from "./cosmos_mayachain-mainnet-v1/adapter.json";
Expand Down Expand Up @@ -86,6 +87,7 @@ export {
celo,
sei,
abstract,
citrea,
cosmos,
thorchain,
mayachain,
Expand Down
6 changes: 6 additions & 0 deletions packages/caip/src/adapters/coingecko/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
celoChainId,
CHAIN_NAMESPACE,
CHAIN_REFERENCE,
citreaChainId,
cosmosChainId,
cronosChainId,
ethChainId,
Expand Down Expand Up @@ -100,6 +101,7 @@ export enum CoingeckoAssetPlatform {
Ton = 'the-open-network',
Near = 'near-protocol',
Abstract = 'abstract',
Citrea = 'citrea',
}

type CoinGeckoId = string
Expand Down Expand Up @@ -198,6 +200,8 @@ export const chainIdToCoingeckoAssetPlatform = (chainId: ChainId): string => {
return CoingeckoAssetPlatform.Soneium
case CHAIN_REFERENCE.SeiMainnet:
return CoingeckoAssetPlatform.Sei
case CHAIN_REFERENCE.CitreaMainnet:
return CoingeckoAssetPlatform.Citrea
default:
throw new Error(
`chainNamespace ${chainNamespace}, chainReference ${chainReference} not supported.`,
Expand Down Expand Up @@ -367,6 +371,8 @@ export const coingeckoAssetPlatformToChainId = (
return tonChainId
case CoingeckoAssetPlatform.Near:
return nearChainId
case CoingeckoAssetPlatform.Citrea:
return citreaChainId
default:
return undefined
}
Expand Down
3 changes: 3 additions & 0 deletions packages/caip/src/adapters/coingecko/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ describe('adapters:coingecko:utils', () => {
'eip155:2741': {
'eip155:2741/slip44:60': 'ethereum',
},
'eip155:4114': {
'eip155:4114/slip44:60': 'citrea-bridged-bitcoin',
},
'near:mainnet': {
'near:mainnet/slip44:397': 'near',
},
Expand Down
17 changes: 17 additions & 0 deletions packages/caip/src/adapters/coingecko/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
celoChainId,
CHAIN_NAMESPACE,
CHAIN_REFERENCE,
citreaAssetId,
citreaChainId,
cosmosChainId,
cronosAssetId,
cronosChainId,
Expand Down Expand Up @@ -665,6 +667,20 @@ export const parseData = (coins: CoingeckoCoin[]): AssetMap => {
}
}

if (Object.keys(platforms).includes(CoingeckoAssetPlatform.Citrea)) {
try {
const assetId = toAssetId({
chainNamespace: CHAIN_NAMESPACE.Evm,
chainReference: CHAIN_REFERENCE.CitreaMainnet,
assetNamespace: 'erc20',
assetReference: platforms[CoingeckoAssetPlatform.Citrea],
})
prev[citreaChainId][assetId] = id
} catch {
// unable to create assetId, skip token
}
}

return prev
},
{
Expand Down Expand Up @@ -707,6 +723,7 @@ export const parseData = (coins: CoingeckoCoin[]): AssetMap => {
[suiChainId]: { [suiAssetId]: 'sui' },
[nearChainId]: { [nearAssetId]: 'near' },
[tonChainId]: { [tonAssetId]: 'the-open-network' },
[citreaChainId]: { [citreaAssetId]: 'citrea-bridged-bitcoin' },
},
)

Expand Down
6 changes: 6 additions & 0 deletions packages/caip/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const suiAssetId: AssetId = 'sui:35834a8a/slip44:784'
export const nearAssetId: AssetId = 'near:mainnet/slip44:397'
export const starknetAssetId: AssetId = 'starknet:SN_MAIN/slip44:9004'
export const tonAssetId: AssetId = 'ton:mainnet/slip44:607'
export const citreaAssetId: AssetId = 'eip155:4114/slip44:60'
export const uniV2EthFoxArbitrumAssetId: AssetId =
'eip155:42161/erc20:0x5f6ce0ca13b87bd738519545d3e018e70e339c24'

Expand Down Expand Up @@ -142,6 +143,7 @@ export const suiChainId: ChainId = 'sui:35834a8a'
export const nearChainId: ChainId = 'near:mainnet'
export const starknetChainId: ChainId = 'starknet:SN_MAIN'
export const tonChainId: ChainId = 'ton:mainnet'
export const citreaChainId: ChainId = 'eip155:4114'

export const CHAIN_NAMESPACE = {
Evm: 'eip155',
Expand Down Expand Up @@ -210,6 +212,7 @@ export const CHAIN_REFERENCE = {
StarknetMainnet: 'SN_MAIN', // https://namespaces.chainagnostic.org/starknet/caip2
TonMainnet: 'mainnet', // TON Mainnet
AbstractMainnet: '2741', // https://abscan.org
CitreaMainnet: '4114', // https://explorer.mainnet.citrea.xyz
} as const

export const ASSET_NAMESPACE = {
Expand Down Expand Up @@ -277,6 +280,7 @@ export const ASSET_REFERENCE = {
Starknet: '9004',
Ton: '607',
Abstract: '60', // evm chain which uses ethereum derivation path as common practice
Citrea: '60', // evm chain which uses ethereum derivation path as common practice
} as const

export const VALID_CHAIN_IDS: ValidChainMap = Object.freeze({
Expand Down Expand Up @@ -323,6 +327,7 @@ export const VALID_CHAIN_IDS: ValidChainMap = Object.freeze({
CHAIN_REFERENCE.SeiMainnet,
CHAIN_REFERENCE.CeloMainnet,
CHAIN_REFERENCE.AbstractMainnet,
CHAIN_REFERENCE.CitreaMainnet,
],
[CHAIN_NAMESPACE.CosmosSdk]: [
CHAIN_REFERENCE.CosmosHubMainnet,
Expand Down Expand Up @@ -407,4 +412,5 @@ export const FEE_ASSET_IDS = [
katanaAssetId,
etherealAssetId,
flowEvmAssetId,
citreaAssetId,
]
9 changes: 9 additions & 0 deletions packages/chain-adapters/src/evm/EvmBaseAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
supportsBob,
supportsBSC,
supportsCelo,
supportsCitrea,
supportsCronos,
supportsETH,
supportsEthereal,
Expand Down Expand Up @@ -135,6 +136,7 @@ export const evmChainIds = [
KnownChainIds.SoneiumMainnet,
KnownChainIds.SeiMainnet,
KnownChainIds.AbstractMainnet,
KnownChainIds.CitreaMainnet,
] as const

export type EvmChainAdapter = EvmBaseAdapter<EvmChainId>
Expand Down Expand Up @@ -283,6 +285,8 @@ export abstract class EvmBaseAdapter<T extends EvmChainId> implements IChainAdap
return supportsSoneium(wallet)
case Number(fromChainId(KnownChainIds.SeiMainnet).chainReference):
return supportsSei(wallet)
case Number(fromChainId(KnownChainIds.CitreaMainnet).chainReference):
return supportsCitrea(wallet)
default:
return false
}
Expand Down Expand Up @@ -490,6 +494,11 @@ export abstract class EvmBaseAdapter<T extends EvmChainId> implements IChainAdap
symbol: 'ETH',
explorer: 'https://abscan.org',
},
[KnownChainIds.CitreaMainnet]: {
name: 'Citrea Bitcoin',
symbol: 'cBTC',
explorer: 'https://explorer.mainnet.citrea.xyz',
},
}[this.chainId]

try {
Expand Down
2 changes: 2 additions & 0 deletions packages/chain-adapters/src/evm/SecondClassEvmAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
blastChainId,
bobChainId,
celoChainId,
citreaChainId,
cronosChainId,
flowEvmChainId,
hemiChainId,
Expand Down Expand Up @@ -75,6 +76,7 @@ const WRAPPED_NATIVE_CONTRACT_BY_CHAIN_ID: Partial<Record<ChainId, string>> = {
[storyChainId]: '0x1514000000000000000000000000000000000000',
[plumeChainId]: '0xea237441c92cae6fc17caaf9a7acb3f953be4bd1',
[seiChainId]: '0xE30feDd158A2e3b13e9badaeABaFc5516e95e8C7',
[citreaChainId]: '0x3100000000000000000000000000000000000006',
}
const BATCH_SIZE = 500

Expand Down
57 changes: 57 additions & 0 deletions packages/chain-adapters/src/evm/citrea/CitreaChainAdapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { AssetId } from '@shapeshiftoss/caip'
import { ASSET_REFERENCE, citreaAssetId } from '@shapeshiftoss/caip'
import type { RootBip44Params } from '@shapeshiftoss/types'
import { KnownChainIds } from '@shapeshiftoss/types'

import { ChainAdapterDisplayName } from '../../types'
import type { TokenInfo } from '../SecondClassEvmAdapter'
import { SecondClassEvmAdapter } from '../SecondClassEvmAdapter'

const SUPPORTED_CHAIN_IDS = [KnownChainIds.CitreaMainnet]
const DEFAULT_CHAIN_ID = KnownChainIds.CitreaMainnet

export type ChainAdapterArgs = {
rpcUrl: string
getKnownTokens: () => TokenInfo[]
}

export const isCitreaChainAdapter = (adapter: unknown): adapter is ChainAdapter => {
return (adapter as ChainAdapter).getType() === KnownChainIds.CitreaMainnet
}

export class ChainAdapter extends SecondClassEvmAdapter<KnownChainIds.CitreaMainnet> {
public static readonly rootBip44Params: RootBip44Params = {
purpose: 44,
coinType: Number(ASSET_REFERENCE.Citrea),
accountNumber: 0,
}

constructor(args: ChainAdapterArgs) {
super({
assetId: citreaAssetId,
chainId: DEFAULT_CHAIN_ID,
rootBip44Params: ChainAdapter.rootBip44Params,
supportedChainIds: SUPPORTED_CHAIN_IDS,
rpcUrl: args.rpcUrl,
getKnownTokens: args.getKnownTokens,
})
}

getDisplayName() {
return ChainAdapterDisplayName.Citrea
}

getName() {
return 'Citrea'
}

getType(): KnownChainIds.CitreaMainnet {
return KnownChainIds.CitreaMainnet
}

getFeeAssetId(): AssetId {
return this.assetId
}
}

export type { TokenInfo }
1 change: 1 addition & 0 deletions packages/chain-adapters/src/evm/citrea/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './CitreaChainAdapter'
1 change: 1 addition & 0 deletions packages/chain-adapters/src/evm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { isSecondClassEvmAdapter, SecondClassEvmAdapter } from './SecondClassEvm
export type { SecondClassEvmAdapterArgs, TokenInfo } from './SecondClassEvmAdapter'

export * as evm from './evm'
export * as citrea from './citrea'
export * as abstract from './abstract'

export * as ethereum from './ethereum'
Expand Down
Loading