Skip to content

Emmet-Finance/emmet.sdk.v3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emmet Cross-Chain Bridge Client Library

All the Emmet.Bridge related data is stored on-chain!. Use async / await to fetch it.

NB: To avoid repetition, every variable is set once in the document. If you forgot how to set the variable search for the other occurances in the document above its usage.

Library installation

Go to https://github.com/Emmet-Finance/emmet.sdk.v3/tree/dist and check the hash of the last commit.

For example: https://github.com/Emmet-Finance/emmet.sdk.v3/commit/011d4f7783f6c3771f36ec0aa4ecc3cbfe4f2344

Install or update the library in your environment to the last commit:

yarn add "git+https://github.com/Emmet-Finance/emmet.sdk.v3#011d4f7783f6c3771f36ec0aa4ecc3cbfe4f2344"

or

npm install "git+https://github.com/Emmet-Finance/emmet.sdk.v3#011d4f7783f6c3771f36ec0aa4ecc3cbfe4f2344"

Import

Importing the chain Factories:

import { ChainFactoryBuilder, ChainFactoryConfigs } from "emmet.js/dist";
import { ChainFactory } from "emmet.js/dist/factory/types";

export const chainFactoryTestnet: ChainFactory = await ChainFactoryBuilder(
  // Switch between Mainnet & testnet
  ChainFactoryConfigs.TestNet(),
);

Usage

Getting the current chain handler

import { Web3Helper } from "emmet.js/dist/chains/web3";
import { TonHelper } from "emmet.js/dist/chains/ton";
import {Chain} from "emmet.js/dist/factory/types";
import { chainFactoryTestnet } from "./your-path-to/chainFactory";

// Same for Mainnets & Testnets

(async () => {
    ...
    const berachain: Web3Helper  = await chainFactoryTestnet.inner(Chain.BERACHAIN) as Web3Helper;
    const ethereum:  Web3Helper  = await chainFactoryTestnet.inner(Chain.ETHEREUM)  as Web3Helper;
    const onlylayer: Web3Helper  = await chainFactoryTestnet.inner(Chain.ONLYLAYER) as Web3Helper;
    const polygon:   Web3Helper  = await chainFactoryTestnet.inner(Chain.POLYGON)   as Web3Helper;
    const ton:       TonHelper   = await chainFactoryTestnet.inner(Chain.TON)       as TonHelper;
    ...
})()

Getting token data

Getting the token data:

type TTokenName = 
    'CAVI' 
    | 'DAI'
    | 'GrabClub'
    | 'TON'
    | 'TRT'
    | 'USDC'
    ;

type TToken {
    address:     string,    // the token contract address
    swap?:       string,    // will be deprecated soon
    decimals:    bigint,    // token decimals, ex. 6 or 18
    symbol:      string,    // The short name, ex. USDC
    fee:         bigint,    // the token fee if liquidity pool is involved
    feedecimals: bigint,    // the fee decimals, usually 6
}

(async () => {
    ...
    const tokenSymbol: string = "USDC";
    const token: TToken = await handler.token(tokenSymbol);
    console.log(token);
    const tokenAddress:     string = token.address;
    const tokenDecimals:    bigint = token.decimals;
    ...
})()

Getting Token allowance

If token allowance is less than the amount intended to be bridged, the transfer will fail.

(async () => {

    const bridgeAddress: string = await handler.bridge();

    const allowance: bigint = await handler.getApprovedAmount(
        token.address,
        bridge.senderAddress,
        bridgeAddress
    );

    console.log(allowance);

})()

Getting an EVM Signer

To trigger user signature generate a signer object

import { BrowserProvider, JsonRpcSigner } from "ethers";
import { useMemo } from "react";
import type { Account, Chain, Client, Transport } from "viem";
import { type Config, useConnectorClient } from "wagmi";

export function clientToSigner(client: Client<Transport, Chain, Account>) {
  const { account, chain, transport } = client;
  const network = {
    chainId: chain.id,
    name: chain.name,
    ensAddress: chain.contracts?.ensRegistry?.address,
  };
  const provider = new BrowserProvider(transport, network);
  const signer = new JsonRpcSigner(provider, account.address);
  return signer;
}

/** Hook to convert a viem Wallet Client to an ethers.js Signer. */
export function useEthersSigner({ chainId }: { chainId?: number } = {}) {
  const { data: client } = useConnectorClient<Config>({ chainId });
  return useMemo(() => (client ? clientToSigner(client) : undefined), [client]);
}

Approving (only relevant for EVM chains)

To avoid transfer failure, the amount must be approved

import { useEthersSigner } from "./useEthersSigner";

(async () => {
    ...
    const bridgeAddress: string = await handler.bridge();

    const signer = useEthersSigner();

    const amountToApprove: bigint = 10; // update to your amount

    const formattedAmount: bigint = amountToApprove * 10n ** tokenDecimals;

    // Some non-Evm chains don't have approval, ut have pre-transfer
    // The SDK function is called so for compatibility with them all
    await chainFactoryTestnet.preTransfer(
          handler,
          signer,
          tokenAddress,
          bridgeAddress,
          BigInt(Math.ceil(formattedAmount)),
          {},
        );

    ...

})()

Getting a TON signer

import { useTonAddress, useTonConnectUI } from "@tonconnect/ui-react";
import { Address, Sender, SenderArguments } from "@ton/core";

export function useTonConnect(): {
  sender: Sender;
  connected: boolean;
  hash: string;
} {
  const [tonConnectUI] = useTonConnectUI();
  const address = useTonAddress();

  return {
    sender: {
      // @ts-ignore
      send: async (args: SenderArguments) => {
        await tonConnectUI.sendTransaction({
          messages: [
            {
              address: args.to.toString(),
              amount: args.value.toString(),
              payload: args.body?.toBoc().toString("base64"),
            },
          ],
          validUntil: Date.now() + 5 * 60 * 1000, // 5 minutes for user to approve
        });
        return 0;
      },
      address: address ? Address.parse(address) : undefined,
    },
    connected: tonConnectUI.connected,
  };
}

Transferring tokens

export const SUPPORTED_CHAINS = { ...MAINNETS, ...TESTNETS };
export type TChainName = keyof typeof SUPPORTED_CHAINS;
export const ChainToDestinationDomain: { [key in TChainName]: number } = {
    // CCTP unsupported chains
  ethereum: 0,
  sepolia: 0,
  avalanche: 1,
  avalancheFuji: 1,
  optimism: 2,
  optimismSepolia: 2,
  arbitrum: 3,
  arbitrumSepolia: 3,
  bsc: 4,
  bscTestnet: 4,
  base: 6,
  baseSepolia: 6,
  polygon: 7,
  polygonAmoy: 7,
  // Other chains
  ton: 65534,
  tonTestnet: 65535,
  berachainBartio: 80084,
  onlylayerTestnet: 728696,
  solana: 102, // TODO: subject to change
};

(async (
    fromChain: TChainName,
    toChain: TChainName, 
    fromToken: TTokenName, 
    toToken: TTokenName,
    amount: bigint,
    mintRecipient: string // the address of the destination beneficiary
) => {
    ...
    const { sender: tonSender } = useTonConnect();
    // See: https://github.com/Emmet-Finance/websitev2/blob/feat/TON/src/hooks/useBridgeFee.ts
    const { fee } = useBridgeFee();
    const signer = useEthersSigner();

    const fromChainID = ChainToDestinationDomain[toChain];
    const formattedAmount: bigint = amount * 10n ** tokenDecimals;
    const destinationDomain = ChainToDestinationDomain[toChain];

     // TON example:
    if(fromChainID === Chain.TON){
        const handler = await chainFactoryTestnet.inner(fromChainID);
        const { hash } = await chainFactoryTestnet.sendInstallment(
            handler,
            tonSender,
            BigInt(Math.ceil(formattedAmount)),
            destinationDomain,
            fromToken,
            toToken,
            mintRecipient,
        );
        console.log(hash);
    // EVM chains example:
    } else if ( 
          fromChainID === Chain.POLYGON ||
          fromChainID === Chain.ETHEREUM ||
          fromChainID === Chain.BSC ||
          fromChainID === Chain.BERACHAIN ||
          fromChainID === Chain.ONLYLAYER
    ) {
        const handler: Web3Helper = await chainFactoryTestnet.inner(fromChainID) as Web3Helper;

        const { hash } = await chainFactoryTestnet.sendInstallment(
            handler,
            signer!,
            BigInt(Math.ceil(formattedAmount)),
            destinationDomain,
            fromToken,
            toToken,
            mintRecipient,
            {
              value: fee,
            },
          );
          console.log(hash);

    }

})(
    'tonTestnet'
    'sepolia',
    'USDC',
    'USDC',
    10n,
    'your-evm-address'
)   

About

Web3 <> Web2 interaction logic

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •