mirror of
https://github.com/Brotocol-xyz/bro-sdk.git
synced 2026-01-12 06:44:18 +08:00
feat: add ETH token support
This commit is contained in:
178
docs/add-evm-token-support.md
Normal file
178
docs/add-evm-token-support.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# How to Add Support for a new EVM Token
|
||||
|
||||
This document explains the process for adding support for a new EVM token in the XLink SDK.
|
||||
|
||||
## Overview
|
||||
|
||||
Adding support for a new EVM token requires modifying the following files:
|
||||
|
||||
1. `src/utils/types/knownIds.ts` - Add the new Token ID
|
||||
2. `src/evmUtils/xlinkContractHelpers.ts` - Add the token to the contract configuration
|
||||
3. `src/stacksUtils/stxContractAddresses.ts` - Add contract addresses for the corresponding token on the Stacks chain
|
||||
|
||||
## Important Notice for Developers and AI Assistants
|
||||
|
||||
**CRITICAL**: The following values MUST be obtained from contract deployers or development team and should NEVER be generated by developers or AI tools:
|
||||
|
||||
1. The exact `ONCHAIN_CONFIG_KEY` value for the token (e.g., `TOKEN_NEW_TOKEN`)
|
||||
2. The contract addresses in `stxTokenContractAddresses_legacy`
|
||||
3. The token name/identifier (the actual token name like "ETH", "BTC", etc.)
|
||||
|
||||
These values are determined by the contract deployers and must match the deployed contract configurations.
|
||||
|
||||
**NAMING CONVENTIONS**:
|
||||
- `KnownTokenId.EVM.TOKEN_NAME` and `KnownTokenId.Stacks.TOKEN_NAME` typically use the same name (e.g., both would be "ETH" for ETH)
|
||||
- However, `ONCHAIN_CONFIG_KEY.TOKEN_NAME` is NOT directly related to these names and is determined by how it's defined in the smart contract (e.g., "TOKEN_ETH" for ETH)
|
||||
- Always confirm the exact naming for `ONCHAIN_CONFIG_KEY` with the contract deployers, as it must match what's in the contract
|
||||
|
||||
## Detailed Steps
|
||||
|
||||
### 1. Add the Token ID in knownIds.ts
|
||||
|
||||
In the `src/utils/types/knownIds.ts` file, add the new Token ID to the appropriate sections in the `KnownTokenId` namespace:
|
||||
|
||||
```typescript
|
||||
export namespace KnownTokenId {
|
||||
export namespace EVM {
|
||||
// Add the new EVM Token ID here - use the exact token name provided by the team
|
||||
// For example, ETH for Ethereum
|
||||
export const TOKEN_NAME = tokenId("evm-tokenname")
|
||||
}
|
||||
|
||||
// If Stacks support is needed, also add it to the Stacks namespace
|
||||
// Use the same token name as above
|
||||
export namespace Stacks {
|
||||
export const TOKEN_NAME = tokenId("stx-tokenname")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Update Contract Configuration in xlinkContractHelpers.ts
|
||||
|
||||
In the `src/evmUtils/xlinkContractHelpers.ts` file, you need to update the following sections:
|
||||
|
||||
1. Add a new token key to the `ONCHAIN_CONFIG_KEY` enum:
|
||||
|
||||
```typescript
|
||||
enum ONCHAIN_CONFIG_KEY {
|
||||
// Other token keys...
|
||||
// IMPORTANT: Use the exact key provided by the contract deployers
|
||||
// This key format is usually different from the token name itself
|
||||
// For example, TOKEN_ETH for Ethereum
|
||||
TOKEN_KEY = "TOKEN_KEY", // This must match what's configured in the smart contract
|
||||
}
|
||||
```
|
||||
|
||||
2. Add the new token key to the `getConfigs` call in the `_getOnChainConfigsImpl` function:
|
||||
|
||||
```typescript
|
||||
const configs = await readContract(client, {
|
||||
abi: BridgeConfigAbi,
|
||||
address: configContractAddress,
|
||||
functionName: "getConfigs",
|
||||
args: [
|
||||
[
|
||||
// Other token keys...
|
||||
ONCHAIN_CONFIG_KEY.TOKEN_KEY, // Use the key added in the enum above
|
||||
],
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
3. Add the token mapping to the return object in the same function:
|
||||
|
||||
```typescript
|
||||
return {
|
||||
// Other mappings...
|
||||
// Note: EVMToken.TOKEN_NAME uses the same name as in KnownTokenId.EVM
|
||||
// while ONCHAIN_CONFIG_KEY.TOKEN_KEY uses the contract-specific key
|
||||
[EVMToken.TOKEN_NAME]: maybeAddress(configs[INDEX_POSITION]),
|
||||
}
|
||||
```
|
||||
|
||||
> Important: The `INDEX_POSITION` should match the position of your token key in the `getConfigs` args array. For example, if your token is the 21st item in the array, use `configs[20]` (zero-indexed).
|
||||
|
||||
### 3. Add Stacks Contract Addresses in stxContractAddresses.ts
|
||||
|
||||
Add the corresponding contract addresses in the `src/stacksUtils/stxContractAddresses.ts` file:
|
||||
|
||||
```typescript
|
||||
export const stxTokenContractAddresses_legacy: Record<
|
||||
// ...
|
||||
> = {
|
||||
// Other tokens...
|
||||
// Use the same token name as in KnownTokenId.Stacks
|
||||
[KnownTokenId.Stacks.TOKEN_NAME]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
// IMPORTANT: Use the exact addresses provided by the contract deployers
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-name", // This contract name must be obtained from the team
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
// IMPORTANT: Use the exact addresses provided by the contract deployers
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: "token-name", // This contract name must be obtained from the team
|
||||
}),
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Example: Adding ETH Token Support
|
||||
|
||||
Here's a real example of adding support for the ETH token:
|
||||
|
||||
1. Adding to `knownIds.ts`:
|
||||
```typescript
|
||||
export const ETH = tokenId("evm-eth") // In EVM namespace
|
||||
export const ETH = tokenId("stx-eth") // In Stacks namespace - same name as EVM
|
||||
```
|
||||
|
||||
2. Updating `xlinkContractHelpers.ts`:
|
||||
```typescript
|
||||
// Add to enum - this key was provided by the contract deployers
|
||||
// Note that this is TOKEN_ETH, not just ETH
|
||||
enum ONCHAIN_CONFIG_KEY {
|
||||
// ...other tokens
|
||||
TOKEN_ETH = "TOKEN_ETH",
|
||||
}
|
||||
|
||||
// Add to getConfigs call
|
||||
ONCHAIN_CONFIG_KEY.TOKEN_ETH,
|
||||
|
||||
// Add to return object mapping
|
||||
// Here we use EVMToken.ETH (the token name), not TOKEN_ETH
|
||||
[EVMToken.ETH]: maybeAddress(configs[20]),
|
||||
```
|
||||
|
||||
3. Adding to `stxContractAddresses.ts`:
|
||||
```typescript
|
||||
[KnownTokenId.Stacks.ETH]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-eth", // This name was provided by the team
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: "token-eth", // This name was provided by the team
|
||||
}),
|
||||
},
|
||||
```
|
||||
|
||||
## Important Considerations
|
||||
|
||||
1. After adding a new token, ensure that all related cross-chain routing and validation logic works correctly
|
||||
2. Maintain consistency with array indices - ensure the index position in the `configs` array matches the position of your token in the `getConfigs` args array
|
||||
3. If the contract address is read from on-chain configuration, make sure the on-chain contract has the correct token address configured
|
||||
4. After adding a new token, perform comprehensive testing to ensure all functionality works as expected
|
||||
|
||||
## For Automated Tools (AI Assistants)
|
||||
|
||||
When adding a new token, follow these exact steps:
|
||||
|
||||
1. **DO NOT generate any values on your own** - always ask for the official token name, ONCHAIN_CONFIG_KEY, and contract addresses
|
||||
2. Identify the next available index position for the token in the `getConfigs` call
|
||||
3. Add the token ID with the appropriate prefix pattern (e.g., "evm-tokenname" and "stx-tokenname")
|
||||
4. Add the token to all three files mentioned above
|
||||
5. Ensure the index position in the return mapping matches the position in the args array
|
||||
6. Follow the existing naming conventions for contract names as specified by the contract deployers
|
||||
7. Remember that KnownTokenId names typically match in EVM and Stacks namespaces, but ONCHAIN_CONFIG_KEY uses a different format defined by the contract
|
||||
@@ -223,6 +223,7 @@ const _getOnChainConfigsImpl = async (
|
||||
ONCHAIN_CONFIG_KEY.TOKEN_STX,
|
||||
ONCHAIN_CONFIG_KEY.TOKEN_TRUMP,
|
||||
ONCHAIN_CONFIG_KEY.TOKEN_GHIBLICZ,
|
||||
ONCHAIN_CONFIG_KEY.TOKEN_ETH,
|
||||
],
|
||||
],
|
||||
}).catch(err => {
|
||||
@@ -270,6 +271,7 @@ const _getOnChainConfigsImpl = async (
|
||||
[EVMToken.STX]: maybeAddress(configs[17]),
|
||||
[EVMToken.TRUMP]: maybeAddress(configs[18]),
|
||||
[EVMToken.GHIBLICZ]: maybeAddress(configs[19]),
|
||||
[EVMToken.ETH]: maybeAddress(configs[20]),
|
||||
}
|
||||
}
|
||||
function maybeAddress(value: string | null): Address | undefined {
|
||||
@@ -319,4 +321,7 @@ enum ONCHAIN_CONFIG_KEY {
|
||||
|
||||
// https://t.me/c/1599543687/73009
|
||||
TOKEN_GHIBLICZ = "TOKEN_GHIBLICZ",
|
||||
|
||||
// https://t.me/c/1599543687/73347
|
||||
TOKEN_ETH = "TOKEN_ETH",
|
||||
}
|
||||
|
||||
@@ -350,4 +350,14 @@ export const stxTokenContractAddresses_legacy: Record<
|
||||
contractName: "bsc-ghiblicz",
|
||||
}),
|
||||
},
|
||||
[KnownTokenId.Stacks.ETH]: {
|
||||
[KnownChainId.Stacks.Mainnet]: wrapContractAddress("mainnet", {
|
||||
deployerAddress: xlinkContractsMultisigMainnet,
|
||||
contractName: "token-eth",
|
||||
}),
|
||||
[KnownChainId.Stacks.Testnet]: wrapContractAddress("testnet", {
|
||||
deployerAddress: xlinkContractsMultisigTestnet,
|
||||
contractName: "token-eth",
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ export namespace KnownTokenId {
|
||||
export const STX = tokenId("evm-stx")
|
||||
export const TRUMP = tokenId("evm-trump")
|
||||
export const GHIBLICZ = tokenId("evm-ghiblicz")
|
||||
export const ETH = tokenId("evm-eth")
|
||||
}
|
||||
/** This type includes all known tokens on EVM-compatible blockchains. */
|
||||
export type EVMToken = (typeof _allKnownEVMTokens)[number]
|
||||
@@ -116,6 +117,7 @@ export namespace KnownTokenId {
|
||||
export const STX = tokenId("stx-stx")
|
||||
export const TRUMP = tokenId("stx-trump")
|
||||
export const GHIBLICZ = tokenId("stx-ghiblicz")
|
||||
export const ETH = tokenId("stx-eth")
|
||||
}
|
||||
const _allKnownStacksTokens = [
|
||||
Stacks.sUSDT,
|
||||
|
||||
Reference in New Issue
Block a user