├── .gitattributes ├── .github ├── renovate.json └── workflows │ ├── publish_devel.yaml │ ├── publish_mainline.yaml │ └── tests.yaml ├── .gitignore ├── .mocharc.yml ├── .nvmrc ├── .yarnclean ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── .nojekyll ├── assets │ ├── highlight.css │ ├── main.js │ ├── search.js │ └── style.css ├── classes │ ├── AllowanceError.html │ ├── BaseToken.html │ ├── Bridge.SynapseBridge.html │ ├── Networks.Network.html │ ├── SwapPools.ETHSwapToken.html │ ├── SwapPools.SwapToken.html │ ├── TransactionError.html │ ├── UnsupportedSwapErrors.UnsupportedSwapError.html │ └── WrapperToken.html ├── enums │ └── UnsupportedSwapErrors.UnsupportedSwapErrorKind.html ├── functions │ ├── Bridge.bridgeSwapSupported.html │ ├── Bridge.checkBridgeTransactionComplete.html │ ├── Bridge.getRequiredConfirmationsForBridge.html │ ├── L1BridgeZapContractInstance.html │ ├── L2BridgeZapContractInstance.html │ ├── Networks.fromChainId.html │ ├── Networks.networkName.html │ ├── Networks.networkSupportsToken.html │ ├── Networks.supportedNetworks.html │ ├── Slippages._applySlippage.html │ ├── Slippages.addSlippage.html │ ├── Slippages.formatSlippageToString.html │ ├── Slippages.subtractSlippage.html │ ├── SwapPools.ethSwapPoolForNetwork.html │ ├── SwapPools.getAllSwappableTokensForNetwork.html │ ├── SwapPools.stableswapPoolForNetwork.html │ ├── SwapPools.swapGroupsForChain.html │ ├── SwapPools.swapPoolTokenForTypeForChain.html │ ├── SwapPools.swapPoolTokenFromLPTokenAddress.html │ ├── SwapPools.swapPoolTokenFromSwapAddress.html │ ├── SwapPools.swapPoolTokensForChainId.html │ ├── SwapPools.tokensForChainBySwapGroup.html │ ├── SynapseBridgeContractInstance.html │ ├── TokenSwap.addLiquidity.html │ ├── TokenSwap.bridgeSwapSupported.html │ ├── TokenSwap.buildAddLiquidityTransaction.html │ ├── TokenSwap.buildRemoveLiquidityOneTokenTransaction.html │ ├── TokenSwap.buildRemoveLiquidityTransaction.html │ ├── TokenSwap.buildSwapTokensTransaction.html │ ├── TokenSwap.calculateAddLiquidity.html │ ├── TokenSwap.calculateRemoveLiquidity.html │ ├── TokenSwap.calculateRemoveLiquidityOneToken.html │ ├── TokenSwap.calculateSwapRate.html │ ├── TokenSwap.detailedTokenSwapMap-1.html │ ├── TokenSwap.intermediateTokens.html │ ├── TokenSwap.removeLiquidity.html │ ├── TokenSwap.removeLiquidityOneToken.html │ ├── TokenSwap.swapContract.html │ ├── TokenSwap.swapSetup.html │ ├── TokenSwap.swapSupported.html │ ├── TokenSwap.swapTokens.html │ ├── Tokens.approveTokenSpend.html │ ├── Tokens.checkTokenAllowance.html │ ├── Tokens.gasTokenForChain.html │ ├── Tokens.gasTokenWrapper.html │ ├── Tokens.isMintBurnToken.html │ ├── Tokens.tokenFromSymbol.html │ ├── UnsupportedSwapErrors.nonMatchingSwapTypes.html │ ├── UnsupportedSwapErrors.tokenNotSupported.html │ ├── UnsupportedSwapErrors.tokenNotSupportedNetFrom.html │ ├── UnsupportedSwapErrors.tokenNotSupportedNetTo.html │ ├── UnsupportedSwapErrors.unsupportedMultiJEWELMigration.html │ ├── allNetworksSwapTokensMap.html │ ├── chainSupportsEIP1559.html │ ├── configureRPCEndpoints.html │ ├── fetchChainGasPrices.html │ ├── makeTransactionGasOverrides.html │ ├── networkSwapTokensMap.html │ ├── populateGasOptions.html │ ├── supportedChainIds.html │ ├── supportedNetworks.html │ ├── useAddLiquidity.html │ ├── useApproveBridgeSwap.html │ ├── useApproveLPToken.html │ ├── useApprovePoolToken.html │ ├── useBridgeAllowance.html │ ├── useBridgeSwapApproval.html │ ├── useCalculateAddLiquidity.html │ ├── useCalculateBridgeSwapOutput.html │ ├── useCalculateRemoveLiquidity.html │ ├── useCalculateRemoveLiquidityOneToken.html │ ├── useCalculateSwapRate.html │ ├── useChainETHSwapLPToken.html │ ├── useChainStableswapLPToken.html │ ├── useExecuteBridgeSwap.html │ ├── useHarmonyAVAXLPToken.html │ ├── useHarmonyJewelLPToken.html │ ├── useLPTokenAllowance.html │ ├── useLPTokenApproval.html │ ├── useLPTokenNeedsApproval.html │ ├── useNeedsBridgeSwapApproval.html │ ├── usePoolTokenAllowance.html │ ├── usePoolTokenApproval.html │ ├── usePoolTokenNeedsApproval.html │ ├── useRemoveLiquidity.html │ ├── useRemoveLiquidityOneToken.html │ └── useSwapTokens.html ├── index.html ├── interfaces │ ├── Bridge.BridgeParams.html │ ├── Bridge.BridgeTransactionCompleteParams.html │ ├── Bridge.BridgeTransactionParams.html │ ├── BridgeConfigV3Contract-1.html │ ├── GasOptions.html │ ├── L1BridgeZapContract.html │ ├── L2BridgeZapContract.html │ ├── RPCEndpointsConfig.html │ ├── SwapPools.LPToken.html │ ├── SwapPools.SwapPoolToken.html │ ├── SynapseBridgeContract.html │ ├── SynapseERC20Contract.html │ ├── Token.html │ ├── TokenSwap.AddLiquidityParams.html │ ├── TokenSwap.AddRemoveLiquidityParams.html │ ├── TokenSwap.BridgeSwapSupportedParams.html │ ├── TokenSwap.RemoveLiquidityOneParams.html │ ├── TokenSwap.RemoveLiquidityParams.html │ ├── TokenSwap.SwapParams.html │ ├── TokenSwap.SwapTokensParams.html │ ├── Tokens.ApproveTokenParams.html │ ├── Tokens.CheckTokenAllowanceParams.html │ └── UnsupportedSwapErrors.UnsupportedSwapErrorArgs.html ├── modules.html ├── modules │ ├── Bridge.html │ ├── BridgeConfigV3Contract.html │ ├── Networks.html │ ├── Slippages.html │ ├── SwapPools.html │ ├── TokenSwap.html │ ├── Tokens.html │ └── UnsupportedSwapErrors.html ├── types │ ├── Bridge.BridgeOutputEstimate.html │ ├── Bridge.CanBridgeResult.html │ ├── BridgeConfigV3Contract.PoolStruct.html │ ├── BridgeConfigV3Contract.PoolStructOutput.html │ ├── BridgeConfigV3Contract.TokenStruct.html │ ├── BridgeConfigV3Contract.TokenStructOutput.html │ ├── ChainGasPrices.html │ ├── ChainId.html │ ├── GenericZapBridgeContract.html │ ├── NetworkSwappableTokensMap.html │ ├── Slippages.Slippage.html │ ├── SwapPools.PoolTokensAmountsMap.html │ ├── SwapPools.SwapTypePoolTokens.html │ ├── TokenSwap.DetailedTokenSwapMap.html │ ├── TokenSwap.EstimatedSwapRate.html │ ├── TokenSwap.IntermediateSwapTokens.html │ └── TokenSwap.SwapSupportedResult.html └── variables │ ├── ChainId-1.html │ ├── EIP1559Chains.html │ ├── Networks.ARBITRUM.html │ ├── Networks.AURORA.html │ ├── Networks.AVALANCHE.html │ ├── Networks.BOBA.html │ ├── Networks.BSC.html │ ├── Networks.CRONOS.html │ ├── Networks.DFK.html │ ├── Networks.ETH.html │ ├── Networks.FANTOM.html │ ├── Networks.HARMONY.html │ ├── Networks.KLAYTN.html │ ├── Networks.METIS.html │ ├── Networks.MOONBEAM.html │ ├── Networks.MOONRIVER.html │ ├── Networks.OPTIMISM.html │ ├── Networks.POLYGON.html │ ├── Slippages.One.html │ ├── Slippages.OneTenth.html │ ├── Slippages.Quarter.html │ ├── Slippages.TwoTenth.html │ ├── SwapPools.ARBITRUM_ETH_SWAP_TOKEN.html │ ├── SwapPools.ARBITRUM_POOL_SWAP_TOKEN.html │ ├── SwapPools.AURORA_POOL_SWAP_TOKEN.html │ ├── SwapPools.AVALANCHE_ETH_SWAP_TOKEN.html │ ├── SwapPools.AVALANCHE_POOL_SWAP_TOKEN.html │ ├── SwapPools.AllSwapPoolTokens.html │ ├── SwapPools.BOBA_ETH_SWAP_TOKEN.html │ ├── SwapPools.BOBA_POOL_SWAP_TOKEN.html │ ├── SwapPools.BSC_POOL_SWAP_TOKEN.html │ ├── SwapPools.CRONOS_POOL_SWAP_TOKEN.html │ ├── SwapPools.ETH_POOL_SWAP_TOKEN.html │ ├── SwapPools.FANTOM_ETH_SWAP_TOKEN.html │ ├── SwapPools.FANTOM_POOL_SWAP_TOKEN.html │ ├── SwapPools.HARMONY_AVAX_SWAP_TOKEN.html │ ├── SwapPools.HARMONY_JEWEL_SWAP_TOKEN.html │ ├── SwapPools.HARMONY_ONEETH_TOKEN.html │ ├── SwapPools.HARMONY_POOL_SWAP_TOKEN.html │ ├── SwapPools.METIS_ETH_SWAP_TOKEN.html │ ├── SwapPools.METIS_POOL_SWAP_TOKEN.html │ ├── SwapPools.OPTIMISM_ETH_SWAP_TOKEN.html │ ├── SwapPools.OPTIMISM_POOL_SWAP_TOKEN.html │ ├── SwapPools.POLYGON_POOL_SWAP_TOKEN.html │ ├── SwapPools.bridgeSwappableMap.html │ ├── Tokens.AVAX.html │ ├── Tokens.AVWETH.html │ ├── Tokens.AllTokens.html │ ├── Tokens.BTCB.html │ ├── Tokens.BUSD.html │ ├── Tokens.ChainGasTokensMap.html │ ├── Tokens.DAI.html │ ├── Tokens.DFKTEARS.html │ ├── Tokens.DFK_ETH.html │ ├── Tokens.DFK_USDC.html │ ├── Tokens.DOG.html │ ├── Tokens.ETH.html │ ├── Tokens.FRAX.html │ ├── Tokens.FTM.html │ ├── Tokens.FTM_ETH.html │ ├── Tokens.GAS_JEWEL.html │ ├── Tokens.GMX.html │ ├── Tokens.GOHM.html │ ├── Tokens.H20.html │ ├── Tokens.HIGH.html │ ├── Tokens.JEWEL.html │ ├── Tokens.JUMP.html │ ├── Tokens.KLAY.html │ ├── Tokens.LINK.html │ ├── Tokens.LUNA.html │ ├── Tokens.MATIC.html │ ├── Tokens.METIS_ETH.html │ ├── Tokens.MOVR.html │ ├── Tokens.MULTIJEWEL.html │ ├── Tokens.MULTI_AVAX.html │ ├── Tokens.NETH.html │ ├── Tokens.NEWO.html │ ├── Tokens.NFD.html │ ├── Tokens.NUSD.html │ ├── Tokens.ONE_ETH.html │ ├── Tokens.SDT.html │ ├── Tokens.SFI.html │ ├── Tokens.SOLAR.html │ ├── Tokens.SYN.html │ ├── Tokens.SYN_AVAX.html │ ├── Tokens.SYN_FRAX.html │ ├── Tokens.SYN_JEWEL.html │ ├── Tokens.USDB.html │ ├── Tokens.USDC.html │ ├── Tokens.USDT.html │ ├── Tokens.UST.html │ ├── Tokens.VSTA.html │ ├── Tokens.WAVAX.html │ ├── Tokens.WBTC.html │ ├── Tokens.WETH.html │ ├── Tokens.WETHBEAM.html │ ├── Tokens.WETH_E.html │ ├── Tokens.WFTM.html │ ├── Tokens.WKLAY.html │ ├── Tokens.WMATIC.html │ ├── Tokens.WMOVR.html │ ├── Tokens.XJEWEL.html │ └── Tokens.mintBurnTokens.html ├── examples └── frontend │ ├── .gitignore │ ├── README.md │ ├── config-overrides.js │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt │ ├── src │ ├── App.css │ ├── App.test.tsx │ ├── App.tsx │ ├── components │ │ ├── Button.tsx │ │ ├── DarkRoundedItem.tsx │ │ ├── DropdownMenu.tsx │ │ └── Grid.tsx │ ├── index.css │ ├── index.tsx │ ├── logo.svg │ ├── pages │ │ └── bridge │ │ │ ├── components │ │ │ ├── AddLiquidity.tsx │ │ │ ├── BridgeSwap.tsx │ │ │ ├── RemoveLiquidity.tsx │ │ │ └── VariousComponents.tsx │ │ │ ├── hooks │ │ │ └── useActionButtonOnClick.tsx │ │ │ └── index.tsx │ ├── react-app-env.d.ts │ ├── reportWebVitals.ts │ ├── setupTests.ts │ └── utils │ │ ├── amounts.ts │ │ ├── index.ts │ │ ├── react_utils.ts │ │ ├── transactions.ts │ │ └── types.ts │ ├── tailwind.config.js │ ├── tsconfig.base.json │ ├── tsconfig.json │ └── yarn.lock ├── package.json ├── scripts ├── ERC20.json ├── fixup ├── gen_changelog ├── generate ├── make_release_branch ├── py_helpers.py ├── rebase ├── sdk-tests └── utils ├── src ├── bridge │ ├── bridge.ts │ ├── bridgeconfig.ts │ ├── bridgeutils.ts │ ├── erc20.ts │ ├── gasutils.ts │ └── slippages.ts ├── common │ ├── chainid.ts │ ├── gasoptions.ts │ ├── networks.ts │ ├── synapse_contracts.ts │ ├── types.ts │ └── utils.ts ├── contracts.ts ├── entities.ts ├── explorer │ ├── bridge_transactions │ │ └── query.ts │ ├── gqlutils.ts │ └── index.ts ├── gasprice.ts ├── hooks │ ├── bridge.ts │ ├── errors.ts │ ├── helpers.ts │ ├── index.ts │ ├── lptokens.ts │ ├── signer.ts │ ├── tokens.ts │ └── types.ts ├── index.ts ├── internal │ ├── gen │ │ ├── AvaxJewelMigration.ts │ │ ├── BridgeConfigV3.ts │ │ ├── ERC20.ts │ │ ├── L1BridgeZap.ts │ │ ├── L2BridgeZap.ts │ │ ├── SwapFlashLoan.ts │ │ ├── SynapseBridge.ts │ │ ├── SynapseERC20.ts │ │ ├── common.ts │ │ ├── factories │ │ │ ├── AvaxJewelMigration__factory.ts │ │ │ ├── BridgeConfigV3__factory.ts │ │ │ ├── ERC20__factory.ts │ │ │ ├── L1BridgeZap__factory.ts │ │ │ ├── L2BridgeZap__factory.ts │ │ │ ├── SwapFlashLoan__factory.ts │ │ │ ├── SynapseBridge__factory.ts │ │ │ ├── SynapseERC20__factory.ts │ │ │ └── index.ts │ │ └── index.ts │ ├── minirpc.ts │ ├── rpcconnector.ts │ ├── rpcproviders.ts │ ├── swaptype.ts │ ├── types.ts │ └── utils.ts ├── swappools.ts ├── token.ts ├── tokens.ts └── tokenswap.ts ├── test ├── basic │ ├── Basic-test.ts │ ├── Env-test.ts │ └── test_env.env ├── entities │ └── entities-test.ts ├── erc20 │ └── ERC20-test.ts ├── explorer │ └── explorer-test.ts ├── helpers │ └── index.ts ├── swappools │ └── SwapPools-test.ts ├── synapsebridge │ ├── ContractWrapperFunctions-test.ts │ ├── ProviderInteractions-test.ts │ ├── Slippages-test.ts │ ├── bridge_test_utils.ts │ ├── buildBridgeTokenTransaction-test.ts │ ├── checkSwapSupported-test.ts │ └── getEstimatedBridgeOutput-test.ts ├── test_setup.ts ├── token │ └── Token-test.ts ├── tokenswap │ ├── SwapRate-test.ts │ ├── TokenSwap-test.ts │ ├── checkTokenAllowance-test.ts │ └── liquidity-test.ts └── tsconfig.json ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | docs/ linguist-vendored -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "ignorePaths": [ 6 | "**/examples/**", 7 | "**/test/**", 8 | "**/scripts/**", 9 | "**/node_modules/**" 10 | ], 11 | "packageRules": [ 12 | { 13 | "matchDepTypes": ["peerDependencies"], 14 | "matchManagers": ["npm"], 15 | "enabled": false 16 | }, 17 | { 18 | "matchUpdateTypes": ["minor", "patch", "pin"], 19 | "matchDepTypes": ["devDependencies"], 20 | "groupName": "dev dependencies (minor/patch/pin)", 21 | "excludePackagePrefixes": ["dotenv", "react"], 22 | "matchManagers": ["npm"], 23 | "automerge": true 24 | }, 25 | { 26 | "matchUpdateTypes": ["minor", "patch", "pin"], 27 | "matchDepTypes": ["dependencies"], 28 | "groupName": "dependencies (minor/patch/pin)", 29 | "excludePackagePrefixes": [], 30 | "matchManagers": ["npm"], 31 | "automerge": true 32 | }, 33 | { 34 | "matchUpdateTypes": ["major"], 35 | "matchDepTypes": ["dependencies"], 36 | "matchManagers": ["npm"], 37 | "enabled": false 38 | }, 39 | { 40 | "matchUpdateTypes": ["major"], 41 | "matchDepTypes": ["devDependencies"], 42 | "groupName": "dev dependencies (major)", 43 | "excludePackagePrefixes": ["dotenv"], 44 | "matchManagers": ["npm"], 45 | "automerge": false 46 | } 47 | ], 48 | "prConcurrentLimit": 3, 49 | "prHourlyLimit": 5, 50 | "baseBranches": ["dev"], 51 | "enabledManagers": ["npm"], 52 | "rebaseWhen": "behind-base-branch", 53 | "automergeType": "branch", 54 | "lockFileMaintenance": { "enabled": true } 55 | } 56 | -------------------------------------------------------------------------------- /.github/workflows/publish_devel.yaml: -------------------------------------------------------------------------------- 1 | name: Publish (Dev/Beta) 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v[01].[0-9]+.[0-9]+-dev.[0-9]+" 7 | - "v[01].[0-9]+.[0-9]+-beta.[0-9]+" 8 | - "v[01].[0-9]+.[0-9]+-alpha.[0-9]+" 9 | 10 | jobs: 11 | tagged_release: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | with: 17 | fetch-depth: 0 18 | 19 | - name: Set git tag name in env 20 | id: git_tag 21 | run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} 22 | 23 | - name: Set NPM tag name in env 24 | id: npm_tag 25 | run: | 26 | REF_NAME=${GITHUB_REF#refs/*/} 27 | ALPHA='alpha' 28 | BETA='beta' 29 | DEV='dev' 30 | 31 | case $REF_NAME in 32 | *"$ALPHA"*) 33 | echo ::set-output name=tag::${ALPHA} 34 | ;; 35 | *"$BETA"*) 36 | echo ::set-output name=tag::${BETA} 37 | ;; 38 | *"$DEV"*) 39 | echo ::set-output name=tag::${DEV} 40 | ;; 41 | esac 42 | 43 | - name: Set tarball filename in env 44 | id: tarball_file 45 | run: | 46 | TARBALL=synapseprotocol-sdk-${{ steps.git_tag.outputs.tag }}.tar.gz 47 | echo ::set-output name=filename::${TARBALL} 48 | 49 | - name: Get node version from nvmrc 50 | id: nvm_version 51 | run: echo ::set-output name=version::$(cat .nvmrc) 52 | 53 | - name: Import GPG key 54 | id: import_gpg 55 | uses: crazy-max/ghaction-import-gpg@v4 56 | with: 57 | gpg_private_key: ${{ secrets.RELEASEBOT_GPG_PRIVATEKEY }} 58 | passphrase: ${{ secrets.RELEASEBOT_GPG_PASSPHRASE }} 59 | 60 | - uses: actions/setup-node@v3 61 | with: 62 | cache: "yarn" 63 | scope: "@synapseprotocol" 64 | registry-url: "https://registry.npmjs.org" 65 | node-version-file: '.nvmrc' 66 | 67 | - id: cache_dir 68 | run: echo ::set-output name=dir::$(yarn cache dir) 69 | 70 | - uses: actions/cache@v3 71 | id: yarn_cache 72 | with: 73 | path: ${{ steps.cache_dir.outputs.dir }} 74 | key: ${{ runner.os }}-${{ steps.nvm_version.outputs.version }}-yarn-${{ hashFiles('**/yarn.lock') }} 75 | restore-keys: | 76 | ${{ runner.os }}-${{ steps.nvm_version.outputs.version }}-yarn- 77 | 78 | - run: yarn install --frozen-lockfile 79 | if: steps.yarn_cache.outputs.cache-hit != 'true' 80 | 81 | - run: yarn run build 82 | 83 | - name: Build dist tarball 84 | run: yarn pack --filename ${{ steps.tarball_file.outputs.filename }} 85 | 86 | - name: GPG sign dist tarball 87 | run: gpg --armor --detach-sign ${{ steps.tarball_file.outputs.filename }} 88 | 89 | - name: Create and publish GitHub release 90 | uses: marvinpinto/action-automatic-releases@v1.2.1 91 | with: 92 | repo_token: ${{ secrets.GITHUB_TOKEN }} 93 | prerelease: true 94 | files: | 95 | ${{ steps.tarball_file.outputs.filename }} 96 | ${{ steps.tarball_file.outputs.filename }}.asc 97 | LICENSE 98 | README.md 99 | 100 | - name: Publish to NPM 101 | run: yarn publish --non-interactive --tag ${{ steps.npm_tag.outputs.tag }} 102 | env: 103 | NODE_AUTH_TOKEN: ${{ secrets.NPM_SERVICE_ACCOUNT_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/publish_mainline.yaml: -------------------------------------------------------------------------------- 1 | name: Publish (Mainline Release) 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v[01].[0-9]+.[0-9]+" 7 | - "!v*-dev*" 8 | - "!v*-beta*" 9 | - "!v*-alpha*" 10 | 11 | jobs: 12 | tagged_release: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | fetch-depth: 0 19 | 20 | - name: Set git tag name in env 21 | id: git_tag 22 | run: echo ::set-output name=tag::${GITHUB_REF#refs/*/} 23 | 24 | - name: Set tarball filename in env 25 | id: tarball_file 26 | run: | 27 | TARBALL=synapseprotocol-sdk-${{ steps.git_tag.outputs.tag }}.tar.gz 28 | echo ::set-output name=filename::${TARBALL} 29 | 30 | - name: Get node version from nvmrc 31 | id: nvm_version 32 | run: echo ::set-output name=version::$(cat .nvmrc) 33 | 34 | - name: Import GPG key 35 | id: import_gpg 36 | uses: crazy-max/ghaction-import-gpg@v4 37 | with: 38 | gpg_private_key: ${{ secrets.RELEASEBOT_GPG_PRIVATEKEY }} 39 | passphrase: ${{ secrets.RELEASEBOT_GPG_PASSPHRASE }} 40 | 41 | - uses: actions/setup-node@v3 42 | with: 43 | cache: "yarn" 44 | scope: "@synapseprotocol" 45 | registry-url: "https://registry.npmjs.org" 46 | node-version-file: '.nvmrc' 47 | 48 | - id: cache_dir 49 | run: echo ::set-output name=dir::$(yarn cache dir) 50 | 51 | - uses: actions/cache@v3 52 | id: yarn_cache 53 | with: 54 | path: ${{ steps.cache_dir.outputs.dir }} 55 | key: ${{ runner.os }}-${{ steps.nvm_version.outputs.version }}-yarn-${{ hashFiles('**/yarn.lock') }} 56 | restore-keys: | 57 | ${{ runner.os }}-${{ steps.nvm_version.outputs.version }}-yarn- 58 | 59 | - run: yarn install --frozen-lockfile 60 | if: steps.yarn_cache.outputs.cache-hit != 'true' 61 | 62 | - run: yarn run build 63 | 64 | - name: Build dist tarball 65 | run: yarn pack --filename ${{ steps.tarball_file.outputs.filename }} 66 | 67 | - name: GPG sign dist tarball 68 | run: gpg --armor --detach-sign ${{ steps.tarball_file.outputs.filename }} 69 | 70 | - name: Create and publish GitHub release 71 | uses: marvinpinto/action-automatic-releases@v1.2.1 72 | with: 73 | repo_token: ${{ secrets.GITHUB_TOKEN }} 74 | prerelease: false 75 | files: | 76 | ${{ steps.tarball_file.outputs.filename }} 77 | ${{ steps.tarball_file.outputs.filename }}.asc 78 | LICENSE 79 | README.md 80 | 81 | - name: Publish to NPM 82 | run: yarn publish --non-interactive --tag latest 83 | env: 84 | NODE_AUTH_TOKEN: ${{ secrets.NPM_SERVICE_ACCOUNT_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/tests.yaml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | branches: 9 | - master 10 | - dev 11 | paths-ignore: 12 | - '**.md' 13 | - 'LICENSE' 14 | - '.nvmrc' 15 | - '.gitignore' 16 | - '.yarnclean' 17 | - 'scripts/**' 18 | - 'examples/**' 19 | - 'tsconfig.build.json' 20 | push: 21 | branches: 22 | - master 23 | - dev 24 | - 'renovate/*' 25 | paths-ignore: 26 | - '**.md' 27 | - 'LICENSE' 28 | - '.nvmrc' 29 | - '.gitignore' 30 | - '.yarnclean' 31 | - 'scripts/**' 32 | - 'examples/**' 33 | - 'tsconfig.build.json' 34 | 35 | jobs: 36 | prebuild: 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v3 40 | with: 41 | fetch-depth: 2 42 | 43 | - if: github.event_name == 'push' 44 | id: push_commit_msg 45 | run: echo ::set-output name=push_msg::$(git log --format=%B -n 1 HEAD) 46 | 47 | - if: github.event_name == 'pull_request' 48 | id: pull_commit_msg 49 | run: echo ::set-output name=pull_msg::$(git log --format=%B -n 1 HEAD^2) 50 | 51 | outputs: 52 | commit_message: $( [ -z "${{ steps.pull_commit_msg.outputs.pull_msg }}" ] && echo "${{ steps.push_commit_msg.outputs.push_msg }}" || echo "${{ steps.pull_commit_msg.outputs.pull_msg }}" ) 53 | 54 | test: 55 | strategy: 56 | matrix: 57 | node-version: 58 | - lts/gallium # most recent release of Node v16, since it's LTS 59 | - 17.0.1 # Node version used in .nvmrc 60 | platform: 61 | - ubuntu-latest 62 | 63 | needs: 64 | - prebuild 65 | 66 | if: ${{ !contains(needs.prebuild.outputs.commit_message, '[ci notest]') }} 67 | 68 | env: 69 | COVERAGE_DIR: ${{ github.workspace }}/coverage 70 | 71 | runs-on: ${{ matrix.platform }} 72 | steps: 73 | - uses: actions/checkout@v3 74 | 75 | - name: Set coveralls run flag 76 | id: coveralls_flag 77 | run: | 78 | FLAGVAL=node-${{ matrix.node-version }} 79 | 80 | if [[ ${{ github.event_name }} == 'pull_request' ]]; then 81 | FLAGVAL="${FLAGVAL}.pr.${{ github.event.pull_request.number }}" 82 | else 83 | FLAGVAL="${FLAGVAL}.${{ github.ref_name }}" 84 | fi 85 | 86 | FLAGVAL="${FLAGVAL}.${{ github.run_id }}/${{ github.run_attempt }}" 87 | 88 | echo ::set-output name=coveralls_flag::${FLAGVAL} 89 | 90 | - uses: actions/setup-node@v3 91 | with: 92 | node-version: ${{ matrix.node-version }} 93 | cache: "yarn" 94 | 95 | - id: cache_dir 96 | run: echo ::set-output name=dir::$(yarn cache dir) 97 | 98 | - uses: actions/cache@v3 99 | id: yarn_cache 100 | with: 101 | path: ${{ steps.cache_dir.outputs.dir }} 102 | key: ${{ runner.os }}-${{ matrix.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }} 103 | restore-keys: | 104 | ${{ runner.os }}-${{ matrix.node-version }}-yarn- 105 | 106 | - run: yarn install 107 | if: steps.yarn_cache.outputs.cache-hit != 'true' 108 | 109 | - name: Run Tests (Node ${{ matrix.node-version }}) 110 | run: yarn -s run coverage:test 111 | env: 112 | REPORTS_DIR: ${{ env.COVERAGE_DIR }} 113 | ETH_RPC_URI: ${{ secrets.ETH_RPC_URI }} 114 | POLYGON_RPC_URI: ${{ secrets.POLYGON_RPC_URI }} 115 | FANTOM_RPC_URI: ${{ secrets.FANTOM_RPC_URI }} 116 | METIS_RPC_URI: ${{ secrets.METIS_RPC_URI }} 117 | ARBITRUM_RPC_URI: ${{ secrets.ARBITRUM_RPC_URI }} 118 | CRONOS_RPC_URI: "https://mmf-rpc.xstaking.sg/" 119 | HARMONY_RPC_URI: "https://harmony-0-rpc.gateway.pokt.network" 120 | INFINITE_APPROVALS_PRIVKEY: ${{ secrets.INFINITE_APPROVALS_PRIVKEY }} 121 | INFINITE_APPROVALS_PRIVKEY_ADDRESS: ${{ secrets.INFINITE_APPROVALS_PRIVKEY_ADDRESS }} 122 | BRIDGE_INTERACTIONS_PRIVKEY: ${{ secrets.BRIDGE_INTERACTIONS_PRIVKEY }} 123 | BRIDGE_INTERACTIONS_PRIVKEY_ADDRESS: ${{ secrets.BRIDGE_INTERACTIONS_PRIVKEY_ADDRESS }} 124 | 125 | - name: Generate Coverage report 126 | run: yarn -s run coverage:report 127 | env: 128 | REPORTS_DIR: ${{ env.COVERAGE_DIR }} 129 | 130 | - name: Coveralls - Process coverage 131 | uses: coverallsapp/github-action@master 132 | with: 133 | github-token: ${{ secrets.GITHUB_TOKEN }} 134 | path-to-lcov: ${{ env.COVERAGE_DIR }}/lcov.info 135 | flag-name: ${{ steps.coveralls_flag.outputs.coveralls_flag }} 136 | parallel: true 137 | 138 | send-coverage: 139 | needs: test 140 | runs-on: ubuntu-latest 141 | steps: 142 | - name: Coveralls - Process all coverage results 143 | uses: coverallsapp/github-action@master 144 | with: 145 | github-token: ${{ secrets.GITHUB_TOKEN }} 146 | parallel-finished: true 147 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .nvim/ 3 | node_modules/ 4 | 5 | abigen/ 6 | dist/ 7 | artifacts/ 8 | 9 | .env 10 | .coveralls.yml 11 | 12 | yarn-error.log 13 | 14 | keys/ 15 | 16 | coverage/ -------------------------------------------------------------------------------- /.mocharc.yml: -------------------------------------------------------------------------------- 1 | node-option: 2 | - 'es-module-specifier-resolution=node' 3 | - 'loader=ts-node/esm' 4 | 5 | extensions: 6 | - ts 7 | 8 | require: 9 | - './test/test_setup.ts' 10 | 11 | recursive: true 12 | parallel: true 13 | jobs: 6 14 | 15 | spec: 16 | # sync/non-network-based tests 17 | - 'test/entities/*-test.ts' 18 | - 'test/basic/*-test.ts' 19 | - 'test/swappools/*-test.ts' 20 | - 'test/token/*-test.ts' 21 | - 'test/tokenswap/TokenSwap-test.ts' 22 | - 'test/synapsebridge/buildBridgeTokenTransaction-test.ts' 23 | - 'test/synapsebridge/checkSwapSupported-test.ts' 24 | - 'test/synapsebridge/Slippages-test.ts' 25 | # async/network-based tests 26 | - 'test/synapsebridge/getEstimatedBridgeOutput-test.ts' 27 | - 'test/synapsebridge/ProviderInteractions-test.ts' 28 | - 'test/synapsebridge/ContractWrapperFunctions-test.ts' 29 | - 'test/tokenswap/checkTokenAllowance-test.ts' 30 | - 'test/tokenswap/SwapRate-test.ts' 31 | - 'test/tokenswap/liquidity-test.ts' 32 | - 'test/erc20/*-test.ts' 33 | - 'test/explorer/explorer-test.ts' 34 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v17.0.1 -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | # test directories 2 | __tests__ 3 | test 4 | tests 5 | powered-test 6 | 7 | # asset directories 8 | docs 9 | doc 10 | website 11 | images 12 | assets 13 | 14 | # examples 15 | example 16 | examples 17 | 18 | # code coverage directories 19 | coverage 20 | .nyc_output 21 | 22 | # build scripts 23 | Makefile 24 | Gulpfile.js 25 | Gruntfile.js 26 | 27 | # configs 28 | appveyor.yml 29 | circle.yml 30 | codeship-services.yml 31 | codeship-steps.yml 32 | wercker.yml 33 | .tern-project 34 | .gitattributes 35 | .editorconfig 36 | .*ignore 37 | .eslintrc 38 | .jshintrc 39 | .flowconfig 40 | .documentup.json 41 | .yarn-metadata.json 42 | .travis.yml 43 | 44 | # misc 45 | *.md 46 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to synapsecns/sdk 2 | 3 | We welcome issues and pull requests to this repo! If you have an idea which you think we should implement, 4 | just open up a new issue and make sure to tag it as a feature request. 5 | 6 | If you're opening a PR, please note that PRs against the [`master`](https://github.com/synapsecns/sdk/tree/master) branch 7 | will likely be ignored; instead, make your changes in a branch based off of [`dev`](https://github.com/synapsecns/sdk/tree/dev). 8 | This stipulation is due to how fast changes occur in the `dev` branch, and our PR workflow for merging `dev` into `master` 9 | by way of squash commits; that is to say, opening a PR against `master` will likely cause several merge conflicts 10 | when trying to merge it into `dev`. So please, just save all of us the pain of working out merge conflicts 11 | and make your changes against `dev`. 12 | 13 | ## PR formatting/etiquette 14 | 15 | When opening a pull request, please use a short but descriptive title. You can be as verbose and descriptive as necessary 16 | in the PR description, but try not to overthink it: if one sentence makes just as much sense as five, go with one. 17 | 18 | Please also make sure that, when your changes are ready for review, to rebase your branch against `dev` to ensure that 19 | your fork is up to date with any changes made to `dev` in the meantime. 20 | 21 | ## Tests 22 | 23 | PRs from external contributors will not be considered for merging unless all of the following criteria are met: 24 | 25 | 1. All existing tests pass 26 | 2. Test coverage of existing code is not decreased 27 | 3. New code -- especially significantly complex code -- has tests written for it, preferably a lot of them (both actual tests as well as test cases) 28 | 1. Minimum required test coverage percentage for new code is 95% 29 | 30 | If you need or want assistance from us in writing or improving tests, just let us know! We genuinely enjoy helping out contributors when we can. 31 | 32 | ## Development environment setup 33 | 34 | 1. Install [nvm](https://github.com/nvm-sh/nvm) (if not already installed on your system) 35 | 2. Use the correct NodeJS version: `nvm use` 36 | - If yarn is not already installed for the given NPM version: `npm install -g yarn` 37 | 3. Install dependencies: `yarn` 38 | 4. Checkout a new branch, and start developing! (`git checkout -b [insert branch name here]`) 39 | 40 | ### Tests 41 | 42 | `yarn test` 43 | 44 | ### Build 45 | 46 | `yarn build` 47 | 48 | Compiled and built files are output to `dist/`. 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2021 Synapse CNS/Synapse Protocol 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 14 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Repository Deprecated 2 | 3 | **Note:** This repository is no longer maintained and has been deprecated in favor of the new sdk. We recommend all users to transition to the new sdk for the latest updates, features, and support. 4 | 5 | ## New SDK 6 | 7 | You can find the npm package [here](https://www.npmjs.com/package/@synapsecns/sdk-router). 8 | 9 | ## Support 10 | 11 | For support with the new repository, please open an issue on the [SDK](https://github.com/synapsecns/sanguine/tree/master/packages/sdk-router). 12 | 13 | # synapseprotocol-sdk 14 | 15 | [![NPM](https://img.shields.io/npm/v/@synapseprotocol/sdk?color=blue)](https://www.npmjs.com/package/@synapseprotocol/sdk) 16 | 17 | [![Tests (master)](https://img.shields.io/github/workflow/status/synapsecns/sdk/Tests/master?event=push&label=tests%20%28master%29)](https://github.com/synapsecns/sdk/actions/workflows/tests.yaml) 18 | [![Coverage (master)](https://img.shields.io/coveralls/github/synapsecns/sdk/master?label=coverage%20%28master%29)](https://coveralls.io/github/synapsecns/sdk?branch=master) 19 | [![Tests (dev)](https://img.shields.io/github/workflow/status/synapsecns/sdk/Tests/dev?event=push&label=tests%20%28dev%29)](https://github.com/synapsecns/sdk/actions/workflows/tests.yaml) 20 | [![Coverage (dev)](https://img.shields.io/coveralls/github/synapsecns/sdk/dev?label=coverage%20%28dev%29)](https://coveralls.io/github/synapsecns/sdk?branch=dev) 21 | 22 | Typescript SDK for the Synapse Protocol. 23 | 24 | ## Usage instructions 25 | 26 | See the [Docs](https://github.com/synapsecns/sdk/wiki). 27 | 28 | ## Looking to help? 29 | 30 | Read our guidelines for [contributing](https://github.com/synapsecns/sdk/blob/master/CONTRIBUTING.md). 31 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-code-background: #FFFFFF; 3 | --dark-code-background: #1E1E1E; 4 | } 5 | 6 | @media (prefers-color-scheme: light) { :root { 7 | --code-background: var(--light-code-background); 8 | } } 9 | 10 | @media (prefers-color-scheme: dark) { :root { 11 | --code-background: var(--dark-code-background); 12 | } } 13 | 14 | :root[data-theme='light'] { 15 | --code-background: var(--light-code-background); 16 | } 17 | 18 | :root[data-theme='dark'] { 19 | --code-background: var(--dark-code-background); 20 | } 21 | 22 | pre, code { background: var(--code-background); } 23 | -------------------------------------------------------------------------------- /examples/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /examples/frontend/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `yarn start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `yarn test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `yarn build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `yarn eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /examples/frontend/config-overrides.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = function override(config) { 4 | config.resolve = { 5 | ...config.resolve, 6 | alias: { 7 | ...config.alias, 8 | "@utils": path.resolve(__dirname, 'src/utils'), 9 | "@hooks": path.resolve(__dirname, 'src/hooks'), 10 | "@components": path.resolve(__dirname, 'src/components'), 11 | "@pages": path.resolve(__dirname, 'src/pages'), 12 | }, 13 | }; 14 | 15 | return config; 16 | }; -------------------------------------------------------------------------------- /examples/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@headlessui/react": "^1.4.3", 7 | "@heroicons/react": "^1.0.5", 8 | "@synapseprotocol/sdk": "0.95.1-alpha.5", 9 | "@testing-library/jest-dom": "^5.14.1", 10 | "@testing-library/react": "^12.0.0", 11 | "@testing-library/user-event": "^13.2.1", 12 | "@types/jest": "^27.0.1", 13 | "@types/node": "^16.7.13", 14 | "@types/react": "^17.0.20", 15 | "@types/react-dom": "^17.0.9", 16 | "ethers": "^5.5.4", 17 | "lodash": "^4.17.21", 18 | "metamask-react": "^2.2.1", 19 | "react": "^18.0.0", 20 | "react-dom": "^18.0.0", 21 | "react-scripts": "5.0.0", 22 | "typescript": "^4.4.2", 23 | "web-vitals": "^2.1.0" 24 | }, 25 | "resolutions": { 26 | "@synapseprotocol/sdk/react": "^18.0.0" 27 | }, 28 | "scripts": { 29 | "start": "react-app-rewired start", 30 | "build": "react-app-rewired build", 31 | "test": "react-app-rewired test", 32 | "eject": "react-app-rewired eject" 33 | }, 34 | "eslintConfig": { 35 | "extends": [ 36 | "react-app", 37 | "react-app/jest" 38 | ] 39 | }, 40 | "browserslist": { 41 | "production": [ 42 | ">0.2%", 43 | "not dead", 44 | "not op_mini all" 45 | ], 46 | "development": [ 47 | "last 1 chrome version", 48 | "last 1 firefox version", 49 | "last 1 safari version" 50 | ] 51 | }, 52 | "devDependencies": { 53 | "autoprefixer": "^10.4.2", 54 | "postcss": "^8.4.6", 55 | "react-app-rewired": "^2.2.1", 56 | "tailwindcss": "^3.0.23" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /examples/frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsecns/sdk/b7f0d8826a5556edce05cd2168dd043030882df5/examples/frontend/public/favicon.ico -------------------------------------------------------------------------------- /examples/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /examples/frontend/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsecns/sdk/b7f0d8826a5556edce05cd2168dd043030882df5/examples/frontend/public/logo192.png -------------------------------------------------------------------------------- /examples/frontend/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synapsecns/sdk/b7f0d8826a5556edce05cd2168dd043030882df5/examples/frontend/public/logo512.png -------------------------------------------------------------------------------- /examples/frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/frontend/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/frontend/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /examples/frontend/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './App.css'; 3 | 4 | import BridgePage from "@pages/bridge"; 5 | 6 | function App() { 7 | return ( 8 |
9 |
10 | 11 |
12 |
13 | ); 14 | } 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /examples/frontend/src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import type {OnClickFunction} from "@utils"; 2 | 3 | export interface ButtonProps { 4 | text: string, 5 | onClick?: OnClickFunction, 6 | disabled?: boolean, 7 | } 8 | 9 | export const emptyOnClick: OnClickFunction = () => {} 10 | 11 | export default function Button({text, onClick, disabled=false}: ButtonProps) { 12 | return ( 13 |
14 | 21 |
22 | ) 23 | } -------------------------------------------------------------------------------- /examples/frontend/src/components/DarkRoundedItem.tsx: -------------------------------------------------------------------------------- 1 | import {classNames} from "@utils"; 2 | 3 | const CLASS_NAME: string = classNames( 4 | "rounded-md border", 5 | "shadow-md", 6 | "dark:bg-gray-800 dark:border-gray-600", 7 | "h-28" 8 | ) 9 | 10 | export default function DarkRoundedItem({children}) { 11 | return ( 12 |
13 | {children} 14 |
15 | ) 16 | } -------------------------------------------------------------------------------- /examples/frontend/src/components/DropdownMenu.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Listbox, 3 | Transition, 4 | } from "@headlessui/react"; 5 | 6 | import { SelectorIcon } from '@heroicons/react/solid'; 7 | 8 | import {classNames} from "@utils"; 9 | 10 | export interface DropdownItem { 11 | label: string, 12 | key: string, 13 | className?: string, 14 | link?: string, 15 | disabled: boolean, 16 | } 17 | 18 | interface DropdownMenuProps { 19 | selectedItem: any, 20 | setSelectedItem: any, 21 | title: string, 22 | items: DropdownItem[], 23 | } 24 | 25 | export default function DropdownMenu({title, selectedItem, setSelectedItem, items}: DropdownMenuProps) { 26 | return( 27 |
28 |
29 | 30 | {({open}) => ( 31 | <> 32 | {title} 33 |
34 | 35 | 46 | {selectedItem?.label || ""} 47 | 48 | 50 | 51 | 52 | 64 | 65 | {items.map((item) => { 66 | const selected = item.key === selectedItem.key; 67 | return( 72 | {({ active }) => ( 73 |
77 | 83 | {item.label} 84 | 85 |
86 | )} 87 |
88 | )})} 89 |
90 |
91 |
92 | 93 | )} 94 |
95 |
96 |
97 | ) 98 | } -------------------------------------------------------------------------------- /examples/frontend/src/components/Grid.tsx: -------------------------------------------------------------------------------- 1 | import {classNames} from "@utils"; 2 | 3 | interface GridProps { 4 | className?: string, 5 | rows?: number, 6 | cols?: number, 7 | gapX?: number, 8 | gapY?: number, 9 | children: JSX.Element | JSX.Element[], 10 | } 11 | 12 | export function Grid({ 13 | className="", 14 | rows=6, 15 | cols=6, 16 | gapX=1, 17 | gapY=1, 18 | children 19 | }: GridProps) { 20 | return(
30 | {children} 31 |
) 32 | } -------------------------------------------------------------------------------- /examples/frontend/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | margin: 0; 7 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 8 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 9 | sans-serif; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | code { 15 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 16 | monospace; 17 | } 18 | -------------------------------------------------------------------------------- /examples/frontend/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {createRoot} from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | import { MetaMaskProvider } from "metamask-react"; 8 | 9 | createRoot(document.getElementById('root')).render( 10 | 11 | 12 | 13 | 14 | , 15 | ); 16 | 17 | // If you want to start measuring performance in your app, pass a function 18 | // to log results (for example: reportWebVitals(console.log)) 19 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 20 | reportWebVitals(); 21 | -------------------------------------------------------------------------------- /examples/frontend/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/frontend/src/pages/bridge/components/AddLiquidity.tsx: -------------------------------------------------------------------------------- 1 | import {useConnectedMetaMask} from "metamask-react"; 2 | 3 | import { 4 | type Token, 5 | Tokens, 6 | ChainId, 7 | SwapPools 8 | } from "@synapseprotocol/sdk"; 9 | 10 | import { 11 | useAddLiquidity, 12 | usePoolTokenApproval, 13 | useCalculateAddLiquidity, 14 | useChainStableswapLPToken 15 | } from "@synapseprotocol/sdk"; 16 | 17 | import {Grid} from "@components/Grid"; 18 | import Button from "@components/Button"; 19 | 20 | import { 21 | ApproveButton, 22 | ExecuteButton, 23 | RowBreak, 24 | ColBreak, 25 | DataRow, 26 | LOADING, 27 | LOADING_COLOR, NeedsApprovalCol 28 | } from "./VariousComponents"; 29 | 30 | import {useEffect, useState} from "react"; 31 | import {MetamaskStatus} from "@utils"; 32 | import {formatEther} from "@ethersproject/units"; 33 | import { 34 | BigNumber, 35 | type BigNumberish 36 | } from "@ethersproject/bignumber"; 37 | 38 | interface BaseProps { 39 | ethereum: any; 40 | chainId: number; 41 | status: string; 42 | } 43 | 44 | interface AddLiquiditySingleTokenProps extends BaseProps { 45 | lpToken: SwapPools.SwapPoolToken; 46 | liquidityToken: Token; 47 | liquidityAmount: BigNumberish; 48 | } 49 | 50 | 51 | export default function AddLiquidity(props) { 52 | const {ethereum, chainId: cid, status} = useConnectedMetaMask(); 53 | const chainId = status === MetamaskStatus.CONNECTED ? BigNumber.from(cid).toNumber() : ChainId.ETH; 54 | 55 | const [stableswapPool] = useChainStableswapLPToken(ethereum, chainId); 56 | 57 | const [liquidityAmountsMap, setLiquidityAmountsMap] = useState(null); 58 | 59 | const addLiquidityAmount = "55"; 60 | const deadline = Math.round((new Date().getTime() / 1000) + 60 * 10); 61 | 62 | useEffect(() => { 63 | if (stableswapPool && !liquidityAmountsMap) { 64 | const amountsMap = stableswapPool.liquidityAmountsMap(); 65 | Object.keys(amountsMap).forEach(k => amountsMap[k] = addLiquidityAmount) 66 | setLiquidityAmountsMap(amountsMap); 67 | } 68 | }, [stableswapPool]) 69 | 70 | const [calculateAddLiquidity, addLiquidityEstimate] = useCalculateAddLiquidity({ 71 | ethereum, 72 | chainId, 73 | lpToken: stableswapPool, 74 | amounts: liquidityAmountsMap 75 | }); 76 | 77 | if (liquidityAmountsMap) { 78 | calculateAddLiquidity(); 79 | } 80 | 81 | const [addLiquidity, addLiquidityTx] = useAddLiquidity({ 82 | ethereum, 83 | chainId, 84 | deadline, 85 | lpToken: stableswapPool, 86 | amounts: liquidityAmountsMap, 87 | minToMint: addLiquidityEstimate 88 | }); 89 | 90 | let baseProps: BaseProps; 91 | 92 | if (stableswapPool && liquidityAmountsMap) { 93 | baseProps = { 94 | ethereum, 95 | chainId, 96 | status 97 | }; 98 | 99 | return ( 100 |
101 | 102 | 103 | {/**/} 104 | 105 | 106 |
{stableswapPool.poolTokens.map((liquidityToken) => { 107 | const tokenSymbol = liquidityToken.symbol; 108 | const liquidityAmount = liquidityAmountsMap[`${tokenSymbol}`]; 109 | 110 | const componentProps: AddLiquiditySingleTokenProps = { 111 | ...baseProps, 112 | lpToken: stableswapPool, 113 | liquidityToken, 114 | liquidityAmount 115 | }; 116 | 117 | return ( 118 | 119 | 120 | 121 | ) 122 | })}
123 |
124 |
125 | ) 126 | } 127 | 128 | 129 | return ( 130 |
{LOADING}
131 | ) 132 | } 133 | 134 | function AddLiquiditySingleToken(props: AddLiquiditySingleTokenProps) { 135 | const { 136 | ethereum, 137 | chainId, 138 | lpToken, 139 | liquidityToken, 140 | liquidityAmount 141 | } = props; 142 | 143 | const { 144 | needsApprove, 145 | allowance: swapPoolSpendAllowance, 146 | execApprove, 147 | approveTx, 148 | approveStatus 149 | } = usePoolTokenApproval({ 150 | ethereum, 151 | chainId, 152 | lpToken, 153 | token: liquidityToken, 154 | amount: liquidityAmount 155 | }); 156 | 157 | return ( 158 | 159 | 160 | {/**/} 161 | 162 | 163 | 164 | ) 165 | } 166 | 167 | function EstimatedLPTokenCol(args: {addLiquidityEstimate, lpToken}) { 168 | const {addLiquidityEstimate, lpToken} = args; 169 | 170 | const [formattedEstimate, setFormattedEstimate] = useState(LOADING); 171 | const [textColor, setTextColor] = useState(LOADING_COLOR); 172 | 173 | useEffect(() => { 174 | if (addLiquidityEstimate !== null && formattedEstimate === LOADING) { 175 | const amtEther = formatEther(addLiquidityEstimate); 176 | 177 | setFormattedEstimate(amtEther.toString()); 178 | } 179 | }, [addLiquidityEstimate]) 180 | 181 | if (!lpToken) { 182 | return ( 183 | 184 |

Estimated LP Tokens received

185 | {formattedEstimate} 186 |
187 | ) 188 | } 189 | 190 | return ( 191 | 192 |

Estimated LP Tokens received

193 | {formattedEstimate} {lpToken.symbol} 194 |
195 | ) 196 | } -------------------------------------------------------------------------------- /examples/frontend/src/pages/bridge/components/BridgeSwap.tsx: -------------------------------------------------------------------------------- 1 | import {useConnectedMetaMask} from "metamask-react"; 2 | 3 | import { 4 | Tokens, 5 | ChainId 6 | } from "@synapseprotocol/sdk"; 7 | 8 | import { 9 | useExecuteBridgeSwap, 10 | useBridgeSwapApproval, 11 | useCalculateBridgeSwapOutput 12 | } from "@synapseprotocol/sdk"; 13 | 14 | import {Grid} from "@components/Grid"; 15 | import Button from "@components/Button"; 16 | 17 | import { 18 | ColBreak, 19 | DataRow, 20 | NeedsApprovalCol, 21 | ApproveButton, 22 | LOADING, 23 | LOADING_COLOR 24 | } from "./VariousComponents"; 25 | 26 | import {useEffect, useState} from "react"; 27 | import {MetamaskStatus} from "@utils"; 28 | import {BigNumber} from "@ethersproject/bignumber"; 29 | import {formatEther} from "@ethersproject/units"; 30 | 31 | 32 | export default function BridgeSwap(props) { 33 | const {ethereum, chainId: cid, status} = useConnectedMetaMask(); 34 | 35 | const chainId = status === MetamaskStatus.CONNECTED ? BigNumber.from(cid).toNumber() : ChainId.ETH; 36 | 37 | const 38 | tokenFrom = Tokens.JEWEL, 39 | tokenTo = Tokens.JEWEL, 40 | amountFrom = tokenFrom.etherToWei("8", chainId), 41 | chainIdTo = ChainId.AVALANCHE; 42 | 43 | const [calculateBridgeSwap, bridgeSwapEstimate] = useCalculateBridgeSwapOutput({ 44 | ethereum, 45 | chainId, 46 | tokenFrom, 47 | tokenTo, 48 | amountFrom, 49 | chainIdTo 50 | }); 51 | 52 | const { 53 | needsApprove, 54 | allowance: bridgeSpendAllowance, 55 | execApprove, 56 | approveTx, 57 | approveStatus 58 | } = useBridgeSwapApproval({ 59 | ethereum, 60 | chainId, 61 | token: tokenFrom, 62 | amount: amountFrom 63 | }); 64 | 65 | const [executeBridgeSwap, bridgeSwapTx] = useExecuteBridgeSwap({ 66 | ethereum, 67 | chainId, 68 | tokenFrom, 69 | tokenTo, 70 | amountFrom, 71 | amountTo: bridgeSwapEstimate?.amountToReceive ?? BigNumber.from(0), 72 | chainIdTo 73 | }); 74 | 75 | if (!bridgeSwapEstimate) { 76 | calculateBridgeSwap(); 77 | } 78 | 79 | return ( 80 |
81 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 |
99 | ) 100 | } 101 | 102 | 103 | 104 | function SwapHeader(args: {tokenFrom, tokenTo, chainId, chainIdTo}) { 105 | const headerStr: string = `${args.tokenFrom.symbol} (${args.chainId}) - ${args.tokenTo.symbol} (${args.chainIdTo})` 106 | 107 | return (

{headerStr}

) 108 | } 109 | 110 | function EstimatedOutputCol(args: {tokenTo, bridgeSwapEstimate}) { 111 | const {tokenTo, bridgeSwapEstimate} = args; 112 | 113 | const [formattedEstimate, setFormattedEstimate] = useState(LOADING); 114 | const [textColor, setTextColor] = useState(LOADING_COLOR); 115 | 116 | useEffect(() => { 117 | if (bridgeSwapEstimate !== null && formattedEstimate === LOADING) { 118 | const amt = bridgeSwapEstimate.amountToReceive; 119 | const amtEther = formatEther(amt); 120 | 121 | setFormattedEstimate(amtEther.toString()); 122 | } 123 | }, [bridgeSwapEstimate]) 124 | 125 | return ( 126 | 127 |

Estimated output

128 | {formattedEstimate} {tokenTo.symbol} 129 |
130 | ) 131 | } 132 | 133 | function BridgeFeeCol(args: {tokenFrom, bridgeSwapEstimate}) { 134 | const {tokenFrom, bridgeSwapEstimate} = args; 135 | 136 | const [formattedEstimate, setFormattedEstimate] = useState(LOADING); 137 | const [textColor, setTextColor] = useState(LOADING_COLOR); 138 | 139 | useEffect(() => { 140 | if (bridgeSwapEstimate !== null && formattedEstimate === LOADING) { 141 | const amt = bridgeSwapEstimate.bridgeFee; 142 | const amtEther = formatEther(amt); 143 | 144 | setFormattedEstimate(amtEther.toString()); 145 | setTextColor("text-indigo-700") 146 | } 147 | }, [bridgeSwapEstimate]) 148 | 149 | return ( 150 | 151 |

Bridge fee

152 | {formattedEstimate} {tokenFrom.symbol} 153 |
154 | ) 155 | } 156 | 157 | function BridgeButton(args: {executeBridgeSwap}) { 158 | const {executeBridgeSwap} = args; 159 | 160 | return ( 161 | 162 |