Skip to content

Commit

Permalink
feat: bsc chain with bnb, ethb and btcb tokens (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
palace22 authored Oct 15, 2024
1 parent d7d8e4d commit 467a5ba
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-rings-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@folks-finance/xchain-sdk": patch
---

Added BSC chain and BNB, ETHB and BTCB tokens
4 changes: 4 additions & 0 deletions src/chains/evm/common/constants/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
avalancheFuji,
base,
baseSepolia,
bsc,
bscTestnet,
mainnet,
sepolia,
Expand Down Expand Up @@ -45,6 +46,7 @@ export const MAINNET_EVM_FOLKS_CHAIN_ID = {
AVALANCHE: 100,
ETHEREUM: 101,
BASE: 102,
BSC: 103,
} as const;

export const TESTNET_EVM_FOLKS_CHAIN_ID = {
Expand All @@ -64,6 +66,7 @@ export const MAINNET_CHAIN_VIEM = {
[EVM_FOLKS_CHAIN_ID.AVALANCHE]: avalanche,
[EVM_FOLKS_CHAIN_ID.ETHEREUM]: mainnet,
[EVM_FOLKS_CHAIN_ID.BASE]: base,
[EVM_FOLKS_CHAIN_ID.BSC]: bsc,
} as const;
export const TESTNET_CHAIN_VIEM = {
[EVM_FOLKS_CHAIN_ID.AVALANCHE_FUJI]: avalancheFuji,
Expand All @@ -81,6 +84,7 @@ export const MAINNET_CHAIN_NODE = {
[EVM_FOLKS_CHAIN_ID.AVALANCHE]: [...avalanche.rpcUrls.default.http],
[EVM_FOLKS_CHAIN_ID.ETHEREUM]: [...mainnet.rpcUrls.default.http],
[EVM_FOLKS_CHAIN_ID.BASE]: [...base.rpcUrls.default.http],
[EVM_FOLKS_CHAIN_ID.BSC]: [...bsc.rpcUrls.default.http],
};
export const TESTNET_CHAIN_NODE = {
[EVM_FOLKS_CHAIN_ID.AVALANCHE_FUJI]: [...avalancheFuji.rpcUrls.default.http],
Expand Down
12 changes: 12 additions & 0 deletions src/chains/evm/common/constants/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ export const CONTRACT_SLOT: Partial<
allowance: 10n,
},
[MAINNET_FOLKS_TOKEN_ID.cbBTC_base]: {
balanceOf: 1n,
allowance: 2n,
},
},
},
[EVM_FOLKS_CHAIN_ID.BSC]: {
erc20: {
[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc]: {
balanceOf: 1n,
allowance: 2n,
},
[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc]: {
balanceOf: 9n,
allowance: 10n,
},
Expand Down
30 changes: 30 additions & 0 deletions src/chains/evm/hub/constants/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,36 @@ export const HUB_CHAIN: Record<NetworkType, HubChain> = {
poolAddress: convertToGenericAddress("0x9eD81F0b5b0E9b6dE00F374fFc7f270902576EF7" as EvmAddress, ChainType.EVM),
supportedLoanTypes: new Set([LoanTypeId.DEPOSIT, LoanTypeId.GENERAL]),
},
[MAINNET_FOLKS_TOKEN_ID.BNB]: {
token: {
type: TokenType.NATIVE,
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.BNB,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.BNB],
poolAddress: convertToGenericAddress("0x89970d3662614a5A4C9857Fcc9D9C3FA03824fe3" as EvmAddress, ChainType.EVM),
supportedLoanTypes: new Set([LoanTypeId.DEPOSIT, LoanTypeId.GENERAL]),
},
[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc]: {
token: {
type: TokenType.ERC20,
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.ETHB_bsc,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc],
poolAddress: convertToGenericAddress("0x18031B374a571F9e060de41De58Abb5957cD5258" as EvmAddress, ChainType.EVM),
supportedLoanTypes: new Set([LoanTypeId.DEPOSIT, LoanTypeId.GENERAL]),
},
[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc]: {
token: {
type: TokenType.ERC20,
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.BTCB_bsc,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc],
poolAddress: convertToGenericAddress("0xC2FD40D9Ec4Ae7e71068652209EB75258809e131" as EvmAddress, ChainType.EVM),
supportedLoanTypes: new Set([LoanTypeId.DEPOSIT, LoanTypeId.GENERAL]),
},
} satisfies Record<MainnetFolksTokenId, HubTokenData>,
},
[NetworkType.TESTNET]: {
Expand Down
86 changes: 81 additions & 5 deletions src/common/constants/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
avalancheFuji,
base,
baseSepolia,
bsc,
bscTestnet,
mainnet,
sepolia,
Expand All @@ -18,7 +19,14 @@ import { convertToGenericAddress } from "../utils/address.js";
import { MAINNET_POOLS, TESTNET_POOLS } from "./pool.js";

import type { EvmAddress } from "../types/address.js";
import type { FolksChainId, FolksChain, SpokeChain, FolksChainName } from "../types/chain.js";
import type {
FolksChainId,
FolksChain,
SpokeChain,
FolksChainName,
MainnetFolksChainId,
TestnetFolksChainId,
} from "../types/chain.js";

export const MAINNET_FOLKS_CHAIN_ID = {
...MAINNET_EVM_FOLKS_CHAIN_ID,
Expand Down Expand Up @@ -56,7 +64,14 @@ export const FOLKS_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Folks
chainId: base.id,
network: NetworkType.MAINNET,
},
},
[FOLKS_CHAIN_ID.BSC]: {
chainType: ChainType.EVM,
folksChainId: FOLKS_CHAIN_ID.BSC,
chainName: bsc.name,
chainId: bsc.id,
network: NetworkType.MAINNET,
},
} satisfies Record<MainnetFolksChainId, FolksChain>,
[NetworkType.TESTNET]: {
[FOLKS_CHAIN_ID.AVALANCHE_FUJI]: {
chainType: ChainType.EVM,
Expand Down Expand Up @@ -93,7 +108,7 @@ export const FOLKS_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Folks
chainId: arbitrumSepolia.id,
network: NetworkType.TESTNET,
},
},
} satisfies Record<TestnetFolksChainId, FolksChain>,
} as const;

export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, SpokeChain>>> = {
Expand Down Expand Up @@ -319,7 +334,68 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
},
},
},
},
[FOLKS_CHAIN_ID.BSC]: {
folksChainId: FOLKS_CHAIN_ID.BSC,
spokeCommonAddress: convertToGenericAddress(
"0xc7bc4A43384f84B8FC937Ab58173Edab23a4c3cD" as EvmAddress,
ChainType.EVM,
),
bridgeRouterAddress: convertToGenericAddress(
"0xCda75578328D0CB0e79dB7797289c44fa02a77ad" as EvmAddress,
ChainType.EVM,
),
adapters: {
[AdapterType.WORMHOLE_DATA]: convertToGenericAddress(
"0xeB48a1eE43B91959A1686b70B7Cd482c65DE69c9" as EvmAddress,
ChainType.EVM,
),
[AdapterType.CCIP_DATA]: convertToGenericAddress(
"0x5C60f12838b8E3EEB525F299cD7C454c989dd04e" as EvmAddress,
ChainType.EVM,
),
},
tokens: {
[MAINNET_FOLKS_TOKEN_ID.BNB]: {
token: {
type: TokenType.NATIVE,
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.BNB,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.BNB],
spokeAddress: convertToGenericAddress(
"0x5f2F4771B7dc7e2F7E9c1308B154E1e8957ecAB0" as EvmAddress,
ChainType.EVM,
),
},
[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc]: {
token: {
type: TokenType.ERC20,
address: convertToGenericAddress("0x2170Ed0880ac9A755fd29B2688956BD959F933F8" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.ETHB_bsc,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc],
spokeAddress: convertToGenericAddress(
"0x4Db12F554623E4B0b3F5bAcF1c8490D4493380A5" as EvmAddress,
ChainType.EVM,
),
},
[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc]: {
token: {
type: TokenType.ERC20,
address: convertToGenericAddress("0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c" as EvmAddress, ChainType.EVM),
decimals: 18,
},
folksTokenId: MAINNET_FOLKS_TOKEN_ID.BTCB_bsc,
poolId: MAINNET_POOLS[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc],
spokeAddress: convertToGenericAddress(
"0x12Db9758c4D9902334C523b94e436258EB54156f" as EvmAddress,
ChainType.EVM,
),
},
},
},
} satisfies Record<MainnetFolksChainId, SpokeChain>,
[NetworkType.TESTNET]: {
[FOLKS_CHAIN_ID.AVALANCHE_FUJI]: {
folksChainId: FOLKS_CHAIN_ID.AVALANCHE_FUJI,
Expand Down Expand Up @@ -581,5 +657,5 @@ export const SPOKE_CHAIN: Record<NetworkType, Partial<Record<FolksChainId, Spoke
},
},
},
},
} satisfies Record<TestnetFolksChainId, SpokeChain>,
};
12 changes: 10 additions & 2 deletions src/common/constants/gmp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { EvmAddress } from "../types/address.js";
import type { FolksChainId } from "../types/chain.js";
import type { CCIPData, WormholeData } from "../types/gmp.js";

export const WORMHOLE_DATA: Partial<Record<FolksChainId, WormholeData>> = {
export const WORMHOLE_DATA: Record<FolksChainId, WormholeData> = {
[FOLKS_CHAIN_ID.AVALANCHE]: {
wormholeChainId: 6,
wormholeRelayer: convertToGenericAddress("0x27428DD2d3DD32A4D7f7C497eAaa23130d894911" as EvmAddress, ChainType.EVM),
Expand All @@ -20,6 +20,10 @@ export const WORMHOLE_DATA: Partial<Record<FolksChainId, WormholeData>> = {
wormholeChainId: 30,
wormholeRelayer: convertToGenericAddress("0x706f82e9bb5b0813501714ab5974216704980e31" as EvmAddress, ChainType.EVM),
},
[FOLKS_CHAIN_ID.BSC]: {
wormholeChainId: 4,
wormholeRelayer: convertToGenericAddress("0x27428DD2d3DD32A4D7f7C497eAaa23130d894911" as EvmAddress, ChainType.EVM),
},
[FOLKS_CHAIN_ID.AVALANCHE_FUJI]: {
wormholeChainId: 6,
wormholeRelayer: convertToGenericAddress("0xA3cF45939bD6260bcFe3D66bc73d60f19e49a8BB" as EvmAddress, ChainType.EVM),
Expand All @@ -42,7 +46,7 @@ export const WORMHOLE_DATA: Partial<Record<FolksChainId, WormholeData>> = {
},
};

export const CCIP_DATA: Partial<Record<FolksChainId, CCIPData>> = {
export const CCIP_DATA: Record<FolksChainId, CCIPData> = {
[FOLKS_CHAIN_ID.AVALANCHE]: {
ccipChainId: BigInt("6433500567565415381"),
ccipRouter: convertToGenericAddress("0xF4c7E640EdA248ef95972845a62bdC74237805dB" as EvmAddress, ChainType.EVM),
Expand All @@ -55,6 +59,10 @@ export const CCIP_DATA: Partial<Record<FolksChainId, CCIPData>> = {
ccipChainId: BigInt("15971525489660198786"),
ccipRouter: convertToGenericAddress("0x881e3A65B4d4a04dD529061dd0071cf975F58bCD" as EvmAddress, ChainType.EVM),
},
[FOLKS_CHAIN_ID.BSC]: {
ccipChainId: BigInt("11344663589394136015"),
ccipRouter: convertToGenericAddress("0x34B03Cb9086d7D758AC55af71584F81A598759FE" as EvmAddress, ChainType.EVM),
},
[FOLKS_CHAIN_ID.AVALANCHE_FUJI]: {
ccipChainId: BigInt("14767482510784806043"),
ccipRouter: convertToGenericAddress("0xF694E193200268f9a4868e4Aa017A0118C9a8177" as EvmAddress, ChainType.EVM),
Expand Down
3 changes: 3 additions & 0 deletions src/common/constants/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const MAINNET_POOLS = {
[MAINNET_FOLKS_TOKEN_ID.wBTC_eth]: 7,
[MAINNET_FOLKS_TOKEN_ID.BTCb_ava]: 8,
[MAINNET_FOLKS_TOKEN_ID.cbBTC_base]: 9,
[MAINNET_FOLKS_TOKEN_ID.BNB]: 10,
[MAINNET_FOLKS_TOKEN_ID.ETHB_bsc]: 11,
[MAINNET_FOLKS_TOKEN_ID.BTCB_bsc]: 12,
} as const satisfies Record<MainnetFolksTokenId, number>;

export const TESTNET_POOLS = {
Expand Down
4 changes: 3 additions & 1 deletion src/common/types/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { GenericAddress } from "./address.js";
import type { AdapterType } from "./message.js";
import type { FolksTokenId, SpokeTokenData } from "./token.js";
import type { EvmChainName } from "../../chains/evm/common/types/chain.js";
import type { FOLKS_CHAIN_ID } from "../constants/chain.js";
import type { FOLKS_CHAIN_ID, MAINNET_FOLKS_CHAIN_ID, TESTNET_FOLKS_CHAIN_ID } from "../constants/chain.js";

export enum ChainType {
EVM = "EVM",
Expand All @@ -14,6 +14,8 @@ export enum NetworkType {
}

export type FolksChainName = EvmChainName;
export type MainnetFolksChainId = (typeof MAINNET_FOLKS_CHAIN_ID)[keyof typeof MAINNET_FOLKS_CHAIN_ID];
export type TestnetFolksChainId = (typeof TESTNET_FOLKS_CHAIN_ID)[keyof typeof TESTNET_FOLKS_CHAIN_ID];
export type FolksChainId = (typeof FOLKS_CHAIN_ID)[keyof typeof FOLKS_CHAIN_ID];

export type IFolksChain = {
Expand Down
3 changes: 3 additions & 0 deletions src/common/types/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export const MAINNET_FOLKS_TOKEN_ID = {
wBTC_eth: "wBTC_eth",
BTCb_ava: "BTCb_ava",
cbBTC_base: "cbBTC_base",
BNB: "BNB",
ETHB_bsc: "ETHB_bsc",
BTCB_bsc: "BTCB_bsc",
} as const;
export type MainnetFolksTokenId = (typeof MAINNET_FOLKS_TOKEN_ID)[keyof typeof MAINNET_FOLKS_TOKEN_ID];

Expand Down
8 changes: 2 additions & 6 deletions src/common/utils/gmp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ import type { FolksChainId } from "../types/chain.js";
import type { CCIPData, WormholeData } from "../types/gmp.js";

export function getWormholeData(folksChainId: FolksChainId): WormholeData {
const wormholeData = WORMHOLE_DATA[folksChainId];
if (wormholeData) return wormholeData;
throw new Error(`Wormhole data not found for folksChainId: ${folksChainId}`);
return WORMHOLE_DATA[folksChainId];
}

export function getCcipData(folksChainId: FolksChainId): CCIPData {
const ccipData = CCIP_DATA[folksChainId];
if (ccipData) return ccipData;
throw new Error(`CCIP data not found for folksChainId: ${folksChainId}`);
return CCIP_DATA[folksChainId];
}

0 comments on commit 467a5ba

Please sign in to comment.