├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── README.md │ ├── build.yml │ ├── lint.yml │ ├── release-alpha.yml │ ├── release.yml │ └── test.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CHANGELOG.md ├── README.md ├── artifacts ├── build-info │ └── d18b3085ce11cc0c382cfc3f94a279f7.json └── contracts │ ├── AdminMultisigBase.sol │ ├── AdminMultisigBase.dbg.json │ └── AdminMultisigBase.json │ ├── AxelarGateway.sol │ ├── AxelarGateway.dbg.json │ └── AxelarGateway.json │ ├── AxelarGatewayProxy.sol │ ├── AxelarGatewayProxy.dbg.json │ └── AxelarGatewayProxy.json │ ├── BurnableMintableCappedERC20.sol │ ├── BurnableMintableCappedERC20.dbg.json │ └── BurnableMintableCappedERC20.json │ ├── DepositHandler.sol │ ├── DepositHandler.dbg.json │ └── DepositHandler.json │ ├── ECDSA.sol │ ├── ECDSA.dbg.json │ └── ECDSA.json │ ├── ERC20.sol │ ├── ERC20.dbg.json │ └── ERC20.json │ ├── ERC20Permit.sol │ ├── ERC20Permit.dbg.json │ └── ERC20Permit.json │ ├── EternalStorage.sol │ ├── EternalStorage.dbg.json │ └── EternalStorage.json │ ├── MintableCappedERC20.sol │ ├── MintableCappedERC20.dbg.json │ └── MintableCappedERC20.json │ ├── Ownable.sol │ ├── Ownable.dbg.json │ └── Ownable.json │ ├── TokenDeployer.sol │ ├── TokenDeployer.dbg.json │ └── TokenDeployer.json │ ├── auth │ └── AxelarAuthWeighted.sol │ │ ├── AxelarAuthWeighted.dbg.json │ │ └── AxelarAuthWeighted.json │ ├── deposit-service │ ├── AxelarDepositService.sol │ │ ├── AxelarDepositService.dbg.json │ │ └── AxelarDepositService.json │ ├── AxelarDepositServiceProxy.sol │ │ ├── AxelarDepositServiceProxy.dbg.json │ │ └── AxelarDepositServiceProxy.json │ ├── DepositReceiver.sol │ │ ├── DepositReceiver.dbg.json │ │ └── DepositReceiver.json │ ├── DepositServiceBase.sol │ │ ├── DepositServiceBase.dbg.json │ │ └── DepositServiceBase.json │ └── ReceiverImplementation.sol │ │ ├── ReceiverImplementation.dbg.json │ │ └── ReceiverImplementation.json │ ├── gas-service │ ├── AxelarGasService.sol │ │ ├── AxelarGasService.dbg.json │ │ └── AxelarGasService.json │ └── AxelarGasServiceProxy.sol │ │ ├── AxelarGasServiceProxy.dbg.json │ │ └── AxelarGasServiceProxy.json │ ├── interfaces │ ├── IAxelarAuth.sol │ │ ├── IAxelarAuth.dbg.json │ │ └── IAxelarAuth.json │ ├── IAxelarAuthWeighted.sol │ │ ├── IAxelarAuthWeighted.dbg.json │ │ └── IAxelarAuthWeighted.json │ ├── IAxelarDepositService.sol │ │ ├── IAxelarDepositService.dbg.json │ │ └── IAxelarDepositService.json │ ├── IAxelarExecutable.sol │ │ ├── IAxelarExecutable.dbg.json │ │ └── IAxelarExecutable.json │ ├── IAxelarForecallable.sol │ │ ├── IAxelarForecallable.dbg.json │ │ └── IAxelarForecallable.json │ ├── IAxelarGasService.sol │ │ ├── IAxelarGasService.dbg.json │ │ └── IAxelarGasService.json │ ├── IAxelarGateway.sol │ │ ├── IAxelarGateway.dbg.json │ │ └── IAxelarGateway.json │ ├── IBurnableMintableCappedERC20.sol │ │ ├── IBurnableMintableCappedERC20.dbg.json │ │ └── IBurnableMintableCappedERC20.json │ ├── IDepositServiceBase.sol │ │ ├── IDepositServiceBase.dbg.json │ │ └── IDepositServiceBase.json │ ├── IERC20.sol │ │ ├── IERC20.dbg.json │ │ └── IERC20.json │ ├── IERC20Burn.sol │ │ ├── IERC20Burn.dbg.json │ │ └── IERC20Burn.json │ ├── IERC20BurnFrom.sol │ │ ├── IERC20BurnFrom.dbg.json │ │ └── IERC20BurnFrom.json │ ├── IERC20Permit.sol │ │ ├── IERC20Permit.dbg.json │ │ └── IERC20Permit.json │ ├── IMintableCappedERC20.sol │ │ ├── IMintableCappedERC20.dbg.json │ │ └── IMintableCappedERC20.json │ ├── IOwnable.sol │ │ ├── IOwnable.dbg.json │ │ └── IOwnable.json │ ├── ITokenDeployer.sol │ │ ├── ITokenDeployer.dbg.json │ │ └── ITokenDeployer.json │ ├── IUpgradable.sol │ │ ├── IUpgradable.dbg.json │ │ └── IUpgradable.json │ └── IWETH9.sol │ │ ├── IWETH9.dbg.json │ │ └── IWETH9.json │ ├── test │ ├── TestWeth.sol │ │ ├── TestWeth.dbg.json │ │ └── TestWeth.json │ └── gmp │ │ ├── DestinationChainSwapExecutable.sol │ │ ├── DestinationChainSwapExecutable.dbg.json │ │ └── DestinationChainSwapExecutable.json │ │ ├── DestinationChainSwapForecallable.sol │ │ ├── DestinationChainSwapForecallable.dbg.json │ │ └── DestinationChainSwapForecallable.json │ │ ├── DestinationChainTokenSwapper.sol │ │ ├── DestinationChainTokenSwapper.dbg.json │ │ └── DestinationChainTokenSwapper.json │ │ └── SourceChainSwapCaller.sol │ │ ├── SourceChainSwapCaller.dbg.json │ │ └── SourceChainSwapCaller.json │ └── util │ ├── BytesStringUtil.sol │ ├── Bytes32ToString.dbg.json │ ├── Bytes32ToString.json │ ├── StringToBytes32.dbg.json │ └── StringToBytes32.json │ ├── Proxy.sol │ ├── Proxy.dbg.json │ └── Proxy.json │ └── Upgradable.sol │ ├── Upgradable.dbg.json │ └── Upgradable.json ├── package.json ├── pnpm-lock.yaml ├── scripts └── postinstall.js ├── sdk-diagram.png ├── src ├── assets │ ├── index.ts │ ├── test │ │ └── loadAssets.spec.ts │ └── types │ │ └── index.ts ├── chains │ ├── index.ts │ ├── supported-chains-list.ts │ ├── test │ │ └── loadChains.spec.ts │ └── types │ │ └── index.ts ├── constants │ ├── EvmChain.ts │ ├── GasToken.ts │ └── index.ts ├── global.d.ts ├── index.ts ├── libs │ ├── AxelarAssetTransfer.ts │ ├── AxelarGateway.ts │ ├── AxelarQueryAPI.ts │ ├── AxelarQueryClient │ │ ├── index.ts │ │ └── types │ │ │ └── index.ts │ ├── AxelarSigningClient │ │ ├── aminomessages │ │ │ └── index.ts │ │ ├── const │ │ │ └── index.ts │ │ ├── index.ts │ │ └── types │ │ │ ├── AxelarnetTxTypes.ts │ │ │ ├── EvmTxTypes.ts │ │ │ ├── MultisigTxTypes.ts │ │ │ └── NexusTxTypes.ts │ ├── BigNumberUtils.ts │ ├── GatewayTx.ts │ ├── TransactionRecoveryApi │ │ ├── AxelarDepositRecoveryAPI.ts │ │ ├── AxelarGMPRecoveryAPI.ts │ │ ├── AxelarRecoveryApi.ts │ │ ├── AxelarTransferAPI.ts │ │ ├── client │ │ │ ├── AxelarRpcClient.ts │ │ │ ├── EVMClient │ │ │ │ └── index.ts │ │ │ └── helpers │ │ │ │ ├── cosmos.ts │ │ │ │ └── retryRpc.ts │ │ ├── constants │ │ │ ├── chain │ │ │ │ ├── index.ts │ │ │ │ ├── mainnet.ts │ │ │ │ └── testnet.ts │ │ │ ├── cosmosGasReceiverOptions.ts │ │ │ ├── error.ts │ │ │ └── s3.ts │ │ ├── helpers │ │ │ ├── axelarHelper.ts │ │ │ ├── contractCallHelper.ts │ │ │ ├── contractEventHelper.ts │ │ │ ├── getCommandId.ts │ │ │ ├── index.ts │ │ │ ├── mappers.ts │ │ │ ├── stellarHelper.ts │ │ │ └── xrplHelper.ts │ │ ├── index.ts │ │ └── interface │ │ │ └── index.ts │ ├── abi │ │ ├── IAxelarExecutable.ts │ │ └── erc20Abi.json │ ├── fee │ │ ├── getL1Fee.spec.ts │ │ ├── getL1Fee.ts │ │ └── types.ts │ ├── index.ts │ ├── test │ │ ├── AxelarAssetTransfer.spec.ts │ │ ├── AxelarGateway.spec.ts │ │ ├── AxelarQueryAPI.spec.ts │ │ ├── AxelarQueryClient.spec.ts │ │ ├── AxelarSigningClient.spec.ts │ │ ├── TransactionRecoveryAPI │ │ │ ├── AxelarDepositRecoveryAPI.spec.ts │ │ │ ├── AxelarGMPRecoveryAPI.spec.ts │ │ │ ├── AxelarRecoveryAPI.spec.ts │ │ │ ├── AxelarTransferAPI.spec.ts │ │ │ ├── EncodingTests.spec.ts │ │ │ └── helper │ │ │ │ ├── contractCallHelper.spec.ts │ │ │ │ └── contractEventHelper.spec.ts │ │ ├── abi │ │ │ ├── DistributionExecutable.json │ │ │ ├── DistributionExecutableGasToken.json │ │ │ └── TestToken.json │ │ ├── stubs │ │ │ └── index.ts │ │ └── testUtils │ │ │ └── localChain.ts │ └── types │ │ └── index.ts ├── services │ ├── RestService.ts │ ├── SocketService.ts │ ├── index.ts │ ├── test │ │ └── RestService.spec.ts │ └── types │ │ └── index.ts └── utils │ ├── index.ts │ ├── retry.ts │ ├── sleep.ts │ ├── test │ └── validateDestinationAddress.spec.ts │ ├── validateChain.ts │ ├── validateDestinationAddress.ts │ └── wallet.ts ├── test ├── e2e │ ├── data │ │ └── index.ts │ ├── mainnet │ │ └── deposit-address.e2e-spec.ts │ ├── testnet │ │ ├── deposit-address.e2e-spec.ts │ │ ├── native-assets.e2e-spec.ts │ │ └── query-transaction-status.e2e-spec.ts │ └── vitest.e2e.config.ts └── integration │ ├── asset-wrap.integration-spec.ts │ ├── deposit-address │ ├── evm-cosmos.integration-spec.ts │ ├── evm-evm.integration-spec.ts │ └── validations.integration-spec.ts │ ├── parts │ ├── 00.deposit-address-single.spec.ts │ ├── 01.deposit-address.spec.ts │ ├── 02.rest-error.spec.ts │ └── 03.goerli-link.spec.ts │ ├── unwrap-native-asset │ └── unwrap-native-asset.integration-spec.ts │ ├── vitest.integration.config.ts │ └── wrap-native-asset │ └── wrap-native-asset.integration-spec.ts ├── tsconfig.json └── vitest.config.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | *.js 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 4 | "parser": "@typescript-eslint/parser", 5 | "parserOptions": { 6 | "project": "tsconfig.json", 7 | "warnOnUnsupportedTypeScriptVersion": false, 8 | "sourceType": "module" 9 | }, 10 | "plugins": ["@typescript-eslint/eslint-plugin", "prettier"], 11 | "env": { 12 | "node": true 13 | }, 14 | "ignorePatterns": ["hardhat.config.ts"], 15 | "rules": { 16 | "prettier/prettier": "error", 17 | "@typescript-eslint/interface-name-prefix": "off", 18 | "@typescript-eslint/explicit-function-return-type": "off", 19 | "@typescript-eslint/explicit-module-boundary-types": "off", 20 | "@typescript-eslint/no-explicit-any": "off" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/README.md: -------------------------------------------------------------------------------- 1 | # Workflows 2 | 3 | ## Lint 4 | 5 | Run linter using https://github.com/wearerequired/lint-action 6 | 7 | **Trigger events**: `push to a pull request branch` 8 | 9 | **Effect**: Reports lint result in the pull request 10 | 11 | ## Test 12 | 13 | Run tests 14 | 15 | **Trigger events**: `push to a pull request branch` 16 | 17 | **Effect**: Reports test result in the pull request 18 | 19 | ## Release 20 | 21 | Bump version and publish to npm. 22 | 23 | **Trigger events**: `push to main`, `merge a pull request to main` 24 | 25 | **Effect**: Bump the version based on the commit message -> commit and push updated version in `package.json` -> add tag -> publish to npm 26 | 27 | | Keyword | Action | Example version changes | 28 | | ---------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------ | 29 | | time to party | Increases **major** version -> commit & push -> tag new version -> publish to npm | 0.6.6 -> 1.0.0 | 30 | | force bump minor | Increases **minor** version -> commit & push -> tag new version -> publish to npm | 0.6.6 -> 0.7.0 | 31 | | pre-alpha | Increases **alpha** version -> commit & push -> tag new version -> publish to npm | 0.6.6 -> 0.6.7-alpha.0, 0.6.7-alpha.0 -> 0.6.7-alpha.1 | 32 | | \* | Increases **patch** version -> commit & push -> tag new version -> publish to npm | 0.6.6 -> 0.6.7, 0.6.7-alpha.3 -> 0.6.8 | 33 | 34 | Note that we may not want to increase major version soon, so the keyword to do that is kind of funny. 35 | 36 | ## Release Alpha (Haven't tested yet) 37 | 38 | Bump alpha version in specified branch and publish it to npm 39 | 40 | **Trigger events**: Manually trigger in [Actions](https://github.com/axelarnetwork/axelarjs-sdk/actions). 41 | 42 | **Effect**: Bump the alpha version -> commit and push updated version in `package.json` -> publish to npm 43 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: "Build" 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | name: "Build Package" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v3 15 | 16 | - name: Install Node.js 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: 18 20 | 21 | - name: Install pnpm 22 | uses: pnpm/action-setup@v2 23 | id: pnpm-install 24 | with: 25 | version: 8 26 | run_install: false 27 | 28 | - name: Get pnpm store directory 29 | id: pnpm-cache 30 | shell: bash 31 | run: | 32 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT 33 | 34 | - name: Setup pnpm cache 35 | uses: actions/cache@v3 36 | with: 37 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} 38 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 39 | restore-keys: | 40 | ${{ runner.os }}-pnpm-store- 41 | 42 | - name: Install dependencies 43 | run: pnpm install 44 | 45 | - name: Build 46 | run: pnpm build 47 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | # Down scope as necessary via https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token 9 | permissions: 10 | checks: write 11 | contents: write 12 | 13 | jobs: 14 | run-linters: 15 | name: Run linters 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v3 21 | 22 | - name: Install Node.js 23 | uses: actions/setup-node@v3 24 | with: 25 | node-version: 18 26 | 27 | - name: Install pnpm 28 | uses: pnpm/action-setup@v2 29 | id: pnpm-install 30 | with: 31 | version: 8 32 | run_install: false 33 | 34 | - name: Get pnpm store directory 35 | id: pnpm-cache 36 | shell: bash 37 | run: | 38 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT 39 | 40 | - name: Setup pnpm cache 41 | uses: actions/cache@v3 42 | with: 43 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} 44 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 45 | restore-keys: | 46 | ${{ runner.os }}-pnpm-store- 47 | 48 | - name: Install dependencies 49 | run: pnpm install 50 | 51 | - name: Run linters 52 | uses: wearerequired/lint-action@v2 53 | with: 54 | eslint: true 55 | eslint_extensions: "ts" 56 | prettier_extensions: "ts" 57 | -------------------------------------------------------------------------------- /.github/workflows/release-alpha.yml: -------------------------------------------------------------------------------- 1 | name: "Release Alpha" 2 | 3 | on: 4 | workflow_dispatch: {} 5 | 6 | jobs: 7 | publish-npm: 8 | name: "Publish npm" 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v3 13 | with: 14 | fetch-depth: 0 15 | ref: ${{ needs.bump-version.outputs.commit-sha }} 16 | 17 | - name: Install Node.js 18 | uses: actions/setup-node@v3 19 | with: 20 | node-version: 18 21 | registry-url: "https://registry.npmjs.org" 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v2 25 | id: pnpm-install 26 | with: 27 | version: 8 28 | run_install: false 29 | 30 | - name: Get pnpm store directory 31 | id: pnpm-cache 32 | shell: bash 33 | run: | 34 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT 35 | 36 | - name: Setup pnpm cache 37 | uses: actions/cache@v3 38 | with: 39 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} 40 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 41 | restore-keys: | 42 | ${{ runner.os }}-pnpm-store- 43 | 44 | - name: Install dependencies 45 | run: pnpm install 46 | 47 | - name: Build 48 | run: pnpm build 49 | 50 | - name: Publish to npm 51 | run: npm publish --tag alpha 52 | env: 53 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 54 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Release" 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [published] 7 | 8 | jobs: 9 | publish-npm: 10 | name: "Publish to NPM" 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | ref: ${{ needs.bump-version.outputs.newTag }} 18 | 19 | - name: Install Node.js 20 | uses: actions/setup-node@v3 21 | with: 22 | node-version: 18 23 | registry-url: "https://registry.npmjs.org" 24 | 25 | - name: Install pnpm 26 | uses: pnpm/action-setup@v2 27 | id: pnpm-install 28 | with: 29 | version: 8 30 | run_install: false 31 | 32 | - name: Get pnpm store directory 33 | id: pnpm-cache 34 | shell: bash 35 | run: | 36 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT 37 | 38 | - name: Setup pnpm cache 39 | uses: actions/cache@v3 40 | with: 41 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} 42 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 43 | restore-keys: | 44 | ${{ runner.os }}-pnpm-store- 45 | 46 | - name: Install dependencies 47 | run: pnpm install 48 | 49 | - name: Build 50 | run: pnpm build 51 | 52 | - name: Publish to npm 53 | run: npm publish 54 | env: 55 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 56 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | run-linters: 10 | name: Run tests 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v3 15 | 16 | - name: Install Node.js 17 | uses: actions/setup-node@v3 18 | with: 19 | node-version: 18 20 | 21 | - name: Install pnpm 22 | uses: pnpm/action-setup@v2 23 | id: pnpm-install 24 | with: 25 | version: 8 26 | run_install: false 27 | 28 | - name: Get pnpm store directory 29 | id: pnpm-cache 30 | shell: bash 31 | run: | 32 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT 33 | 34 | - name: Setup pnpm cache 35 | uses: actions/cache@v3 36 | with: 37 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} 38 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 39 | restore-keys: | 40 | ${{ runner.os }}-pnpm-store- 41 | 42 | - name: Install dependencies 43 | run: pnpm install 44 | 45 | - name: Run tests 46 | run: pnpm test 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | \dist 2 | \node_modules 3 | *.iml 4 | *.idea 5 | *.DS_store 6 | cache 7 | 8 | # lockfiles that shouldn't be tracked since we're using pnpm 9 | package-lock.json 10 | yarn.lock 11 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | *.html 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "printWidth": 100, 4 | "tabWidth": 2, 5 | "semi": true, 6 | "singleQuote": false 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Axelar SDK 2 | 3 | ## Overview 4 | 5 | The Axelar SDK is a Node.js library that includes a collection of APIs and query tools. It is essentially a wrapper around most common cross-chain functionalities that will help you building cross-chain apps. 6 | 7 | The package can be installed into your dApp as a project dependency with: 8 | 9 | ```bash 10 | # npm 11 | npm i @axelar-network/axelarjs-sdk 12 | 13 | # or yarn 14 | yarn add @axelar-network/axelarjs-sdk 15 | ``` 16 | 17 | For full SDK docs, please visit: https://docs.axelar.dev/dev/axelarjs-sdk/intro 18 | 19 | ## Development 20 | 21 | When you develop make sure that you have the [_eslint plugin_](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) installed. 22 | -------------------------------------------------------------------------------- /artifacts/contracts/AdminMultisigBase.sol/AdminMultisigBase.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/AxelarGateway.sol/AxelarGateway.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/AxelarGatewayProxy.sol/AxelarGatewayProxy.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/BurnableMintableCappedERC20.sol/BurnableMintableCappedERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/DepositHandler.sol/DepositHandler.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/DepositHandler.sol/DepositHandler.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "DepositHandler", 4 | "sourceName": "contracts/DepositHandler.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "IsLocked", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "NotContract", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [ 18 | { 19 | "internalType": "address", 20 | "name": "etherDestination", 21 | "type": "address" 22 | } 23 | ], 24 | "name": "destroy", 25 | "outputs": [], 26 | "stateMutability": "nonpayable", 27 | "type": "function" 28 | }, 29 | { 30 | "inputs": [ 31 | { 32 | "internalType": "address", 33 | "name": "callee", 34 | "type": "address" 35 | }, 36 | { 37 | "internalType": "bytes", 38 | "name": "data", 39 | "type": "bytes" 40 | } 41 | ], 42 | "name": "execute", 43 | "outputs": [ 44 | { 45 | "internalType": "bool", 46 | "name": "success", 47 | "type": "bool" 48 | }, 49 | { 50 | "internalType": "bytes", 51 | "name": "returnData", 52 | "type": "bytes" 53 | } 54 | ], 55 | "stateMutability": "nonpayable", 56 | "type": "function" 57 | } 58 | ], 59 | "bytecode": "0x6080604052600160005534801561001557600080fd5b50610324806100256000396000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033", 60 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033", 61 | "linkReferences": {}, 62 | "deployedLinkReferences": {} 63 | } 64 | -------------------------------------------------------------------------------- /artifacts/contracts/ECDSA.sol/ECDSA.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/ECDSA.sol/ECDSA.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "ECDSA", 4 | "sourceName": "contracts/ECDSA.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidS", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "InvalidSignature", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [], 18 | "name": "InvalidSignatureLength", 19 | "type": "error" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "InvalidV", 24 | "type": "error" 25 | } 26 | ], 27 | "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a0647c9bbd174dd4ecae7a0d05fc5c36f08c23a3e3a446b39785d56c1528d7964736f6c63430008090033", 28 | "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a0647c9bbd174dd4ecae7a0d05fc5c36f08c23a3e3a446b39785d56c1528d7964736f6c63430008090033", 29 | "linkReferences": {}, 30 | "deployedLinkReferences": {} 31 | } 32 | -------------------------------------------------------------------------------- /artifacts/contracts/ERC20.sol/ERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/ERC20Permit.sol/ERC20Permit.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/EternalStorage.sol/EternalStorage.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/MintableCappedERC20.sol/MintableCappedERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/Ownable.sol/Ownable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/Ownable.sol/Ownable.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Ownable", 4 | "sourceName": "contracts/Ownable.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidOwner", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "NotOwner", 14 | "type": "error" 15 | }, 16 | { 17 | "anonymous": false, 18 | "inputs": [ 19 | { 20 | "indexed": true, 21 | "internalType": "address", 22 | "name": "previousOwner", 23 | "type": "address" 24 | }, 25 | { 26 | "indexed": true, 27 | "internalType": "address", 28 | "name": "newOwner", 29 | "type": "address" 30 | } 31 | ], 32 | "name": "OwnershipTransferred", 33 | "type": "event" 34 | }, 35 | { 36 | "inputs": [], 37 | "name": "owner", 38 | "outputs": [ 39 | { 40 | "internalType": "address", 41 | "name": "", 42 | "type": "address" 43 | } 44 | ], 45 | "stateMutability": "view", 46 | "type": "function" 47 | }, 48 | { 49 | "inputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "newOwner", 53 | "type": "address" 54 | } 55 | ], 56 | "name": "transferOwnership", 57 | "outputs": [], 58 | "stateMutability": "nonpayable", 59 | "type": "function" 60 | } 61 | ], 62 | "bytecode": "0x", 63 | "deployedBytecode": "0x", 64 | "linkReferences": {}, 65 | "deployedLinkReferences": {} 66 | } 67 | -------------------------------------------------------------------------------- /artifacts/contracts/TokenDeployer.sol/TokenDeployer.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/auth/AxelarAuthWeighted.sol/AxelarAuthWeighted.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/deposit-service/AxelarDepositService.sol/AxelarDepositService.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/deposit-service/AxelarDepositServiceProxy.sol/AxelarDepositServiceProxy.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/deposit-service/DepositReceiver.sol/DepositReceiver.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/deposit-service/DepositReceiver.sol/DepositReceiver.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "DepositReceiver", 4 | "sourceName": "contracts/deposit-service/DepositReceiver.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "bytes", 10 | "name": "delegateData", 11 | "type": "bytes" 12 | }, 13 | { 14 | "internalType": "address", 15 | "name": "refundAddress", 16 | "type": "address" 17 | } 18 | ], 19 | "stateMutability": "nonpayable", 20 | "type": "constructor" 21 | }, 22 | { 23 | "stateMutability": "payable", 24 | "type": "receive" 25 | } 26 | ], 27 | "bytecode": "0x608060405234801561001057600080fd5b5060405161028f38038061028f83398101604081905261002f91610191565b6000336001600160a01b031663112e335c6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561006c57600080fd5b505af1158015610080573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100a49190610250565b6001600160a01b0316836040516100bb9190610272565b600060405180830381855af49150503d80600081146100f6576040519150601f19603f3d011682016040523d82523d6000602084013e6100fb565b606091505b5050905080610111576040513d806000833e8082fd5b6001600160a01b038216610123573391505b816001600160a01b0316ff5b634e487b7160e01b600052604160045260246000fd5b60005b83811015610160578181015183820152602001610148565b8381111561016f576000848401525b50505050565b80516001600160a01b038116811461018c57600080fd5b919050565b600080604083850312156101a457600080fd5b82516001600160401b03808211156101bb57600080fd5b818501915085601f8301126101cf57600080fd5b8151818111156101e1576101e161012f565b604051601f8201601f19908116603f011681019083821181831017156102095761020961012f565b8160405282815288602084870101111561022257600080fd5b610233836020830160208801610145565b809650505050505061024760208401610175565b90509250929050565b60006020828403121561026257600080fd5b61026b82610175565b9392505050565b60008251610284818460208701610145565b919091019291505056fe", 28 | "deployedBytecode": "0x608060405236600a57005b600080fdfea2646970667358221220647cec8bfe1585268ceed8d37cf1f8698e1ca3f1de0e4ed43c2c287253f936ef64736f6c63430008090033", 29 | "linkReferences": {}, 30 | "deployedLinkReferences": {} 31 | } 32 | -------------------------------------------------------------------------------- /artifacts/contracts/deposit-service/DepositServiceBase.sol/DepositServiceBase.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/deposit-service/ReceiverImplementation.sol/ReceiverImplementation.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/gas-service/AxelarGasService.sol/AxelarGasService.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/gas-service/AxelarGasServiceProxy.sol/AxelarGasServiceProxy.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarAuth.sol/IAxelarAuth.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarAuth.sol/IAxelarAuth.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IAxelarAuth", 4 | "sourceName": "contracts/interfaces/IAxelarAuth.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidOwner", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "NotOwner", 14 | "type": "error" 15 | }, 16 | { 17 | "anonymous": false, 18 | "inputs": [ 19 | { 20 | "indexed": true, 21 | "internalType": "address", 22 | "name": "previousOwner", 23 | "type": "address" 24 | }, 25 | { 26 | "indexed": true, 27 | "internalType": "address", 28 | "name": "newOwner", 29 | "type": "address" 30 | } 31 | ], 32 | "name": "OwnershipTransferred", 33 | "type": "event" 34 | }, 35 | { 36 | "inputs": [], 37 | "name": "owner", 38 | "outputs": [ 39 | { 40 | "internalType": "address", 41 | "name": "", 42 | "type": "address" 43 | } 44 | ], 45 | "stateMutability": "view", 46 | "type": "function" 47 | }, 48 | { 49 | "inputs": [ 50 | { 51 | "internalType": "bytes", 52 | "name": "params", 53 | "type": "bytes" 54 | } 55 | ], 56 | "name": "transferOperatorship", 57 | "outputs": [], 58 | "stateMutability": "nonpayable", 59 | "type": "function" 60 | }, 61 | { 62 | "inputs": [ 63 | { 64 | "internalType": "address", 65 | "name": "newOwner", 66 | "type": "address" 67 | } 68 | ], 69 | "name": "transferOwnership", 70 | "outputs": [], 71 | "stateMutability": "nonpayable", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "bytes32", 78 | "name": "messageHash", 79 | "type": "bytes32" 80 | }, 81 | { 82 | "internalType": "bytes", 83 | "name": "proof", 84 | "type": "bytes" 85 | } 86 | ], 87 | "name": "validateProof", 88 | "outputs": [ 89 | { 90 | "internalType": "bool", 91 | "name": "currentOperators", 92 | "type": "bool" 93 | } 94 | ], 95 | "stateMutability": "nonpayable", 96 | "type": "function" 97 | } 98 | ], 99 | "bytecode": "0x", 100 | "deployedBytecode": "0x", 101 | "linkReferences": {}, 102 | "deployedLinkReferences": {} 103 | } 104 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarAuthWeighted.sol/IAxelarAuthWeighted.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarAuthWeighted.sol/IAxelarAuthWeighted.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IAxelarAuthWeighted", 4 | "sourceName": "contracts/interfaces/IAxelarAuthWeighted.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "DuplicateOperators", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "InvalidOperators", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [], 18 | "name": "InvalidOwner", 19 | "type": "error" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "InvalidThreshold", 24 | "type": "error" 25 | }, 26 | { 27 | "inputs": [], 28 | "name": "InvalidWeights", 29 | "type": "error" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "LowSignaturesWeight", 34 | "type": "error" 35 | }, 36 | { 37 | "inputs": [], 38 | "name": "MalformedSigners", 39 | "type": "error" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "NotOwner", 44 | "type": "error" 45 | }, 46 | { 47 | "anonymous": false, 48 | "inputs": [ 49 | { 50 | "indexed": false, 51 | "internalType": "address[]", 52 | "name": "newOperators", 53 | "type": "address[]" 54 | }, 55 | { 56 | "indexed": false, 57 | "internalType": "uint256[]", 58 | "name": "newWeights", 59 | "type": "uint256[]" 60 | }, 61 | { 62 | "indexed": false, 63 | "internalType": "uint256", 64 | "name": "newThreshold", 65 | "type": "uint256" 66 | } 67 | ], 68 | "name": "OperatorshipTransferred", 69 | "type": "event" 70 | }, 71 | { 72 | "anonymous": false, 73 | "inputs": [ 74 | { 75 | "indexed": true, 76 | "internalType": "address", 77 | "name": "previousOwner", 78 | "type": "address" 79 | }, 80 | { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "newOwner", 84 | "type": "address" 85 | } 86 | ], 87 | "name": "OwnershipTransferred", 88 | "type": "event" 89 | }, 90 | { 91 | "inputs": [], 92 | "name": "currentEpoch", 93 | "outputs": [ 94 | { 95 | "internalType": "uint256", 96 | "name": "", 97 | "type": "uint256" 98 | } 99 | ], 100 | "stateMutability": "view", 101 | "type": "function" 102 | }, 103 | { 104 | "inputs": [ 105 | { 106 | "internalType": "bytes32", 107 | "name": "hash", 108 | "type": "bytes32" 109 | } 110 | ], 111 | "name": "epochForHash", 112 | "outputs": [ 113 | { 114 | "internalType": "uint256", 115 | "name": "", 116 | "type": "uint256" 117 | } 118 | ], 119 | "stateMutability": "view", 120 | "type": "function" 121 | }, 122 | { 123 | "inputs": [ 124 | { 125 | "internalType": "uint256", 126 | "name": "epoch", 127 | "type": "uint256" 128 | } 129 | ], 130 | "name": "hashForEpoch", 131 | "outputs": [ 132 | { 133 | "internalType": "bytes32", 134 | "name": "", 135 | "type": "bytes32" 136 | } 137 | ], 138 | "stateMutability": "view", 139 | "type": "function" 140 | }, 141 | { 142 | "inputs": [], 143 | "name": "owner", 144 | "outputs": [ 145 | { 146 | "internalType": "address", 147 | "name": "", 148 | "type": "address" 149 | } 150 | ], 151 | "stateMutability": "view", 152 | "type": "function" 153 | }, 154 | { 155 | "inputs": [ 156 | { 157 | "internalType": "bytes", 158 | "name": "params", 159 | "type": "bytes" 160 | } 161 | ], 162 | "name": "transferOperatorship", 163 | "outputs": [], 164 | "stateMutability": "nonpayable", 165 | "type": "function" 166 | }, 167 | { 168 | "inputs": [ 169 | { 170 | "internalType": "address", 171 | "name": "newOwner", 172 | "type": "address" 173 | } 174 | ], 175 | "name": "transferOwnership", 176 | "outputs": [], 177 | "stateMutability": "nonpayable", 178 | "type": "function" 179 | }, 180 | { 181 | "inputs": [ 182 | { 183 | "internalType": "bytes32", 184 | "name": "messageHash", 185 | "type": "bytes32" 186 | }, 187 | { 188 | "internalType": "bytes", 189 | "name": "proof", 190 | "type": "bytes" 191 | } 192 | ], 193 | "name": "validateProof", 194 | "outputs": [ 195 | { 196 | "internalType": "bool", 197 | "name": "currentOperators", 198 | "type": "bool" 199 | } 200 | ], 201 | "stateMutability": "nonpayable", 202 | "type": "function" 203 | } 204 | ], 205 | "bytecode": "0x", 206 | "deployedBytecode": "0x", 207 | "linkReferences": {}, 208 | "deployedLinkReferences": {} 209 | } 210 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarDepositService.sol/IAxelarDepositService.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarExecutable.sol/IAxelarExecutable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarExecutable.sol/IAxelarExecutable.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IAxelarExecutable", 4 | "sourceName": "contracts/interfaces/IAxelarExecutable.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "NotApprovedByGateway", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [ 13 | { 14 | "internalType": "bytes32", 15 | "name": "commandId", 16 | "type": "bytes32" 17 | }, 18 | { 19 | "internalType": "string", 20 | "name": "sourceChain", 21 | "type": "string" 22 | }, 23 | { 24 | "internalType": "string", 25 | "name": "sourceAddress", 26 | "type": "string" 27 | }, 28 | { 29 | "internalType": "bytes", 30 | "name": "payload", 31 | "type": "bytes" 32 | } 33 | ], 34 | "name": "execute", 35 | "outputs": [], 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "inputs": [ 41 | { 42 | "internalType": "bytes32", 43 | "name": "commandId", 44 | "type": "bytes32" 45 | }, 46 | { 47 | "internalType": "string", 48 | "name": "sourceChain", 49 | "type": "string" 50 | }, 51 | { 52 | "internalType": "string", 53 | "name": "sourceAddress", 54 | "type": "string" 55 | }, 56 | { 57 | "internalType": "bytes", 58 | "name": "payload", 59 | "type": "bytes" 60 | }, 61 | { 62 | "internalType": "string", 63 | "name": "tokenSymbol", 64 | "type": "string" 65 | }, 66 | { 67 | "internalType": "uint256", 68 | "name": "amount", 69 | "type": "uint256" 70 | } 71 | ], 72 | "name": "executeWithToken", 73 | "outputs": [], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | }, 77 | { 78 | "inputs": [], 79 | "name": "gateway", 80 | "outputs": [ 81 | { 82 | "internalType": "contract IAxelarGateway", 83 | "name": "", 84 | "type": "address" 85 | } 86 | ], 87 | "stateMutability": "view", 88 | "type": "function" 89 | } 90 | ], 91 | "bytecode": "0x", 92 | "deployedBytecode": "0x", 93 | "linkReferences": {}, 94 | "deployedLinkReferences": {} 95 | } 96 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarForecallable.sol/IAxelarForecallable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarForecallable.sol/IAxelarForecallable.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IAxelarForecallable", 4 | "sourceName": "contracts/interfaces/IAxelarForecallable.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "AlreadyForecalled", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "NotApprovedByGateway", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [], 18 | "name": "TransferFailed", 19 | "type": "error" 20 | }, 21 | { 22 | "inputs": [ 23 | { 24 | "internalType": "uint256", 25 | "name": "amount", 26 | "type": "uint256" 27 | }, 28 | { 29 | "internalType": "bytes", 30 | "name": "", 31 | "type": "bytes" 32 | } 33 | ], 34 | "name": "amountPostFee", 35 | "outputs": [ 36 | { 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "stateMutability": "nonpayable", 43 | "type": "function" 44 | }, 45 | { 46 | "inputs": [ 47 | { 48 | "internalType": "bytes32", 49 | "name": "commandId", 50 | "type": "bytes32" 51 | }, 52 | { 53 | "internalType": "string", 54 | "name": "sourceChain", 55 | "type": "string" 56 | }, 57 | { 58 | "internalType": "string", 59 | "name": "sourceAddress", 60 | "type": "string" 61 | }, 62 | { 63 | "internalType": "bytes", 64 | "name": "payload", 65 | "type": "bytes" 66 | } 67 | ], 68 | "name": "execute", 69 | "outputs": [], 70 | "stateMutability": "nonpayable", 71 | "type": "function" 72 | }, 73 | { 74 | "inputs": [ 75 | { 76 | "internalType": "bytes32", 77 | "name": "commandId", 78 | "type": "bytes32" 79 | }, 80 | { 81 | "internalType": "string", 82 | "name": "sourceChain", 83 | "type": "string" 84 | }, 85 | { 86 | "internalType": "string", 87 | "name": "sourceAddress", 88 | "type": "string" 89 | }, 90 | { 91 | "internalType": "bytes", 92 | "name": "payload", 93 | "type": "bytes" 94 | }, 95 | { 96 | "internalType": "string", 97 | "name": "tokenSymbol", 98 | "type": "string" 99 | }, 100 | { 101 | "internalType": "uint256", 102 | "name": "amount", 103 | "type": "uint256" 104 | } 105 | ], 106 | "name": "executeWithToken", 107 | "outputs": [], 108 | "stateMutability": "nonpayable", 109 | "type": "function" 110 | }, 111 | { 112 | "inputs": [ 113 | { 114 | "internalType": "string", 115 | "name": "sourceChain", 116 | "type": "string" 117 | }, 118 | { 119 | "internalType": "string", 120 | "name": "sourceAddress", 121 | "type": "string" 122 | }, 123 | { 124 | "internalType": "bytes", 125 | "name": "payload", 126 | "type": "bytes" 127 | }, 128 | { 129 | "internalType": "address", 130 | "name": "forecaller", 131 | "type": "address" 132 | } 133 | ], 134 | "name": "forecall", 135 | "outputs": [], 136 | "stateMutability": "nonpayable", 137 | "type": "function" 138 | }, 139 | { 140 | "inputs": [ 141 | { 142 | "internalType": "string", 143 | "name": "sourceChain", 144 | "type": "string" 145 | }, 146 | { 147 | "internalType": "string", 148 | "name": "sourceAddress", 149 | "type": "string" 150 | }, 151 | { 152 | "internalType": "bytes", 153 | "name": "payload", 154 | "type": "bytes" 155 | }, 156 | { 157 | "internalType": "string", 158 | "name": "tokenSymbol", 159 | "type": "string" 160 | }, 161 | { 162 | "internalType": "uint256", 163 | "name": "amount", 164 | "type": "uint256" 165 | }, 166 | { 167 | "internalType": "address", 168 | "name": "forecaller", 169 | "type": "address" 170 | } 171 | ], 172 | "name": "forecallWithToken", 173 | "outputs": [], 174 | "stateMutability": "nonpayable", 175 | "type": "function" 176 | }, 177 | { 178 | "inputs": [], 179 | "name": "gateway", 180 | "outputs": [ 181 | { 182 | "internalType": "contract IAxelarGateway", 183 | "name": "", 184 | "type": "address" 185 | } 186 | ], 187 | "stateMutability": "view", 188 | "type": "function" 189 | } 190 | ], 191 | "bytecode": "0x", 192 | "deployedBytecode": "0x", 193 | "linkReferences": {}, 194 | "deployedLinkReferences": {} 195 | } 196 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarGasService.sol/IAxelarGasService.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IAxelarGateway.sol/IAxelarGateway.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IBurnableMintableCappedERC20.sol/IBurnableMintableCappedERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IDepositServiceBase.sol/IDepositServiceBase.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IDepositServiceBase.sol/IDepositServiceBase.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IDepositServiceBase", 4 | "sourceName": "contracts/interfaces/IDepositServiceBase.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidAddress", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "InvalidSymbol", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [], 18 | "name": "NativeTransferFailed", 19 | "type": "error" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "NothingDeposited", 24 | "type": "error" 25 | }, 26 | { 27 | "inputs": [], 28 | "name": "TokenApproveFailed", 29 | "type": "error" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "TokenTransferFailed", 34 | "type": "error" 35 | }, 36 | { 37 | "inputs": [], 38 | "name": "UnwrapFailed", 39 | "type": "error" 40 | }, 41 | { 42 | "inputs": [], 43 | "name": "WrapFailed", 44 | "type": "error" 45 | }, 46 | { 47 | "inputs": [], 48 | "name": "gateway", 49 | "outputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "", 53 | "type": "address" 54 | } 55 | ], 56 | "stateMutability": "nonpayable", 57 | "type": "function" 58 | }, 59 | { 60 | "inputs": [], 61 | "name": "wrappedSymbol", 62 | "outputs": [ 63 | { 64 | "internalType": "string", 65 | "name": "", 66 | "type": "string" 67 | } 68 | ], 69 | "stateMutability": "nonpayable", 70 | "type": "function" 71 | }, 72 | { 73 | "inputs": [], 74 | "name": "wrappedToken", 75 | "outputs": [ 76 | { 77 | "internalType": "address", 78 | "name": "", 79 | "type": "address" 80 | } 81 | ], 82 | "stateMutability": "nonpayable", 83 | "type": "function" 84 | } 85 | ], 86 | "bytecode": "0x", 87 | "deployedBytecode": "0x", 88 | "linkReferences": {}, 89 | "deployedLinkReferences": {} 90 | } 91 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20.sol/IERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20.sol/IERC20.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC20", 4 | "sourceName": "contracts/interfaces/IERC20.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidAccount", 9 | "type": "error" 10 | }, 11 | { 12 | "anonymous": false, 13 | "inputs": [ 14 | { 15 | "indexed": true, 16 | "internalType": "address", 17 | "name": "owner", 18 | "type": "address" 19 | }, 20 | { 21 | "indexed": true, 22 | "internalType": "address", 23 | "name": "spender", 24 | "type": "address" 25 | }, 26 | { 27 | "indexed": false, 28 | "internalType": "uint256", 29 | "name": "value", 30 | "type": "uint256" 31 | } 32 | ], 33 | "name": "Approval", 34 | "type": "event" 35 | }, 36 | { 37 | "anonymous": false, 38 | "inputs": [ 39 | { 40 | "indexed": true, 41 | "internalType": "address", 42 | "name": "from", 43 | "type": "address" 44 | }, 45 | { 46 | "indexed": true, 47 | "internalType": "address", 48 | "name": "to", 49 | "type": "address" 50 | }, 51 | { 52 | "indexed": false, 53 | "internalType": "uint256", 54 | "name": "value", 55 | "type": "uint256" 56 | } 57 | ], 58 | "name": "Transfer", 59 | "type": "event" 60 | }, 61 | { 62 | "inputs": [ 63 | { 64 | "internalType": "address", 65 | "name": "owner", 66 | "type": "address" 67 | }, 68 | { 69 | "internalType": "address", 70 | "name": "spender", 71 | "type": "address" 72 | } 73 | ], 74 | "name": "allowance", 75 | "outputs": [ 76 | { 77 | "internalType": "uint256", 78 | "name": "", 79 | "type": "uint256" 80 | } 81 | ], 82 | "stateMutability": "view", 83 | "type": "function" 84 | }, 85 | { 86 | "inputs": [ 87 | { 88 | "internalType": "address", 89 | "name": "spender", 90 | "type": "address" 91 | }, 92 | { 93 | "internalType": "uint256", 94 | "name": "amount", 95 | "type": "uint256" 96 | } 97 | ], 98 | "name": "approve", 99 | "outputs": [ 100 | { 101 | "internalType": "bool", 102 | "name": "", 103 | "type": "bool" 104 | } 105 | ], 106 | "stateMutability": "nonpayable", 107 | "type": "function" 108 | }, 109 | { 110 | "inputs": [ 111 | { 112 | "internalType": "address", 113 | "name": "account", 114 | "type": "address" 115 | } 116 | ], 117 | "name": "balanceOf", 118 | "outputs": [ 119 | { 120 | "internalType": "uint256", 121 | "name": "", 122 | "type": "uint256" 123 | } 124 | ], 125 | "stateMutability": "view", 126 | "type": "function" 127 | }, 128 | { 129 | "inputs": [], 130 | "name": "totalSupply", 131 | "outputs": [ 132 | { 133 | "internalType": "uint256", 134 | "name": "", 135 | "type": "uint256" 136 | } 137 | ], 138 | "stateMutability": "view", 139 | "type": "function" 140 | }, 141 | { 142 | "inputs": [ 143 | { 144 | "internalType": "address", 145 | "name": "recipient", 146 | "type": "address" 147 | }, 148 | { 149 | "internalType": "uint256", 150 | "name": "amount", 151 | "type": "uint256" 152 | } 153 | ], 154 | "name": "transfer", 155 | "outputs": [ 156 | { 157 | "internalType": "bool", 158 | "name": "", 159 | "type": "bool" 160 | } 161 | ], 162 | "stateMutability": "nonpayable", 163 | "type": "function" 164 | }, 165 | { 166 | "inputs": [ 167 | { 168 | "internalType": "address", 169 | "name": "sender", 170 | "type": "address" 171 | }, 172 | { 173 | "internalType": "address", 174 | "name": "recipient", 175 | "type": "address" 176 | }, 177 | { 178 | "internalType": "uint256", 179 | "name": "amount", 180 | "type": "uint256" 181 | } 182 | ], 183 | "name": "transferFrom", 184 | "outputs": [ 185 | { 186 | "internalType": "bool", 187 | "name": "", 188 | "type": "bool" 189 | } 190 | ], 191 | "stateMutability": "nonpayable", 192 | "type": "function" 193 | } 194 | ], 195 | "bytecode": "0x", 196 | "deployedBytecode": "0x", 197 | "linkReferences": {}, 198 | "deployedLinkReferences": {} 199 | } 200 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20Burn.sol/IERC20Burn.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20Burn.sol/IERC20Burn.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC20Burn", 4 | "sourceName": "contracts/interfaces/IERC20Burn.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "bytes32", 10 | "name": "salt", 11 | "type": "bytes32" 12 | } 13 | ], 14 | "name": "burn", 15 | "outputs": [], 16 | "stateMutability": "nonpayable", 17 | "type": "function" 18 | } 19 | ], 20 | "bytecode": "0x", 21 | "deployedBytecode": "0x", 22 | "linkReferences": {}, 23 | "deployedLinkReferences": {} 24 | } 25 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20BurnFrom.sol/IERC20BurnFrom.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20BurnFrom.sol/IERC20BurnFrom.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC20BurnFrom", 4 | "sourceName": "contracts/interfaces/IERC20BurnFrom.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "address", 10 | "name": "account", 11 | "type": "address" 12 | }, 13 | { 14 | "internalType": "uint256", 15 | "name": "amount", 16 | "type": "uint256" 17 | } 18 | ], 19 | "name": "burnFrom", 20 | "outputs": [], 21 | "stateMutability": "nonpayable", 22 | "type": "function" 23 | } 24 | ], 25 | "bytecode": "0x", 26 | "deployedBytecode": "0x", 27 | "linkReferences": {}, 28 | "deployedLinkReferences": {} 29 | } 30 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20Permit.sol/IERC20Permit.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IERC20Permit.sol/IERC20Permit.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IERC20Permit", 4 | "sourceName": "contracts/interfaces/IERC20Permit.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "DOMAIN_SEPARATOR", 9 | "outputs": [ 10 | { 11 | "internalType": "bytes32", 12 | "name": "", 13 | "type": "bytes32" 14 | } 15 | ], 16 | "stateMutability": "view", 17 | "type": "function" 18 | }, 19 | { 20 | "inputs": [ 21 | { 22 | "internalType": "address", 23 | "name": "account", 24 | "type": "address" 25 | } 26 | ], 27 | "name": "nonces", 28 | "outputs": [ 29 | { 30 | "internalType": "uint256", 31 | "name": "", 32 | "type": "uint256" 33 | } 34 | ], 35 | "stateMutability": "view", 36 | "type": "function" 37 | }, 38 | { 39 | "inputs": [ 40 | { 41 | "internalType": "address", 42 | "name": "issuer", 43 | "type": "address" 44 | }, 45 | { 46 | "internalType": "address", 47 | "name": "spender", 48 | "type": "address" 49 | }, 50 | { 51 | "internalType": "uint256", 52 | "name": "value", 53 | "type": "uint256" 54 | }, 55 | { 56 | "internalType": "uint256", 57 | "name": "deadline", 58 | "type": "uint256" 59 | }, 60 | { 61 | "internalType": "uint8", 62 | "name": "v", 63 | "type": "uint8" 64 | }, 65 | { 66 | "internalType": "bytes32", 67 | "name": "r", 68 | "type": "bytes32" 69 | }, 70 | { 71 | "internalType": "bytes32", 72 | "name": "s", 73 | "type": "bytes32" 74 | } 75 | ], 76 | "name": "permit", 77 | "outputs": [], 78 | "stateMutability": "nonpayable", 79 | "type": "function" 80 | } 81 | ], 82 | "bytecode": "0x", 83 | "deployedBytecode": "0x", 84 | "linkReferences": {}, 85 | "deployedLinkReferences": {} 86 | } 87 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IMintableCappedERC20.sol/IMintableCappedERC20.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IOwnable.sol/IOwnable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IOwnable.sol/IOwnable.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IOwnable", 4 | "sourceName": "contracts/interfaces/IOwnable.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidOwner", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "NotOwner", 14 | "type": "error" 15 | }, 16 | { 17 | "anonymous": false, 18 | "inputs": [ 19 | { 20 | "indexed": true, 21 | "internalType": "address", 22 | "name": "previousOwner", 23 | "type": "address" 24 | }, 25 | { 26 | "indexed": true, 27 | "internalType": "address", 28 | "name": "newOwner", 29 | "type": "address" 30 | } 31 | ], 32 | "name": "OwnershipTransferred", 33 | "type": "event" 34 | }, 35 | { 36 | "inputs": [], 37 | "name": "owner", 38 | "outputs": [ 39 | { 40 | "internalType": "address", 41 | "name": "", 42 | "type": "address" 43 | } 44 | ], 45 | "stateMutability": "view", 46 | "type": "function" 47 | }, 48 | { 49 | "inputs": [ 50 | { 51 | "internalType": "address", 52 | "name": "newOwner", 53 | "type": "address" 54 | } 55 | ], 56 | "name": "transferOwnership", 57 | "outputs": [], 58 | "stateMutability": "nonpayable", 59 | "type": "function" 60 | } 61 | ], 62 | "bytecode": "0x", 63 | "deployedBytecode": "0x", 64 | "linkReferences": {}, 65 | "deployedLinkReferences": {} 66 | } 67 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/ITokenDeployer.sol/ITokenDeployer.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/ITokenDeployer.sol/ITokenDeployer.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "ITokenDeployer", 4 | "sourceName": "contracts/interfaces/ITokenDeployer.sol", 5 | "abi": [ 6 | { 7 | "inputs": [ 8 | { 9 | "internalType": "string", 10 | "name": "name", 11 | "type": "string" 12 | }, 13 | { 14 | "internalType": "string", 15 | "name": "symbol", 16 | "type": "string" 17 | }, 18 | { 19 | "internalType": "uint8", 20 | "name": "decimals", 21 | "type": "uint8" 22 | }, 23 | { 24 | "internalType": "uint256", 25 | "name": "cap", 26 | "type": "uint256" 27 | }, 28 | { 29 | "internalType": "bytes32", 30 | "name": "salt", 31 | "type": "bytes32" 32 | } 33 | ], 34 | "name": "deployToken", 35 | "outputs": [ 36 | { 37 | "internalType": "address", 38 | "name": "tokenAddress", 39 | "type": "address" 40 | } 41 | ], 42 | "stateMutability": "nonpayable", 43 | "type": "function" 44 | } 45 | ], 46 | "bytecode": "0x", 47 | "deployedBytecode": "0x", 48 | "linkReferences": {}, 49 | "deployedLinkReferences": {} 50 | } 51 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IUpgradable.sol/IUpgradable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IUpgradable.sol/IUpgradable.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "IUpgradable", 4 | "sourceName": "contracts/interfaces/IUpgradable.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidCodeHash", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "InvalidImplementation", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [], 18 | "name": "InvalidOwner", 19 | "type": "error" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "NotOwner", 24 | "type": "error" 25 | }, 26 | { 27 | "inputs": [], 28 | "name": "NotProxy", 29 | "type": "error" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "SetupFailed", 34 | "type": "error" 35 | }, 36 | { 37 | "anonymous": false, 38 | "inputs": [ 39 | { 40 | "indexed": true, 41 | "internalType": "address", 42 | "name": "newOwner", 43 | "type": "address" 44 | } 45 | ], 46 | "name": "OwnershipTransferred", 47 | "type": "event" 48 | }, 49 | { 50 | "anonymous": false, 51 | "inputs": [ 52 | { 53 | "indexed": true, 54 | "internalType": "address", 55 | "name": "newImplementation", 56 | "type": "address" 57 | } 58 | ], 59 | "name": "Upgraded", 60 | "type": "event" 61 | }, 62 | { 63 | "inputs": [], 64 | "name": "contractId", 65 | "outputs": [ 66 | { 67 | "internalType": "bytes32", 68 | "name": "", 69 | "type": "bytes32" 70 | } 71 | ], 72 | "stateMutability": "pure", 73 | "type": "function" 74 | }, 75 | { 76 | "inputs": [], 77 | "name": "implementation", 78 | "outputs": [ 79 | { 80 | "internalType": "address", 81 | "name": "", 82 | "type": "address" 83 | } 84 | ], 85 | "stateMutability": "view", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [], 90 | "name": "owner", 91 | "outputs": [ 92 | { 93 | "internalType": "address", 94 | "name": "", 95 | "type": "address" 96 | } 97 | ], 98 | "stateMutability": "view", 99 | "type": "function" 100 | }, 101 | { 102 | "inputs": [ 103 | { 104 | "internalType": "bytes", 105 | "name": "data", 106 | "type": "bytes" 107 | } 108 | ], 109 | "name": "setup", 110 | "outputs": [], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "address", 118 | "name": "newImplementation", 119 | "type": "address" 120 | }, 121 | { 122 | "internalType": "bytes32", 123 | "name": "newImplementationCodeHash", 124 | "type": "bytes32" 125 | }, 126 | { 127 | "internalType": "bytes", 128 | "name": "params", 129 | "type": "bytes" 130 | } 131 | ], 132 | "name": "upgrade", 133 | "outputs": [], 134 | "stateMutability": "nonpayable", 135 | "type": "function" 136 | } 137 | ], 138 | "bytecode": "0x", 139 | "deployedBytecode": "0x", 140 | "linkReferences": {}, 141 | "deployedLinkReferences": {} 142 | } 143 | -------------------------------------------------------------------------------- /artifacts/contracts/interfaces/IWETH9.sol/IWETH9.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/test/TestWeth.sol/TestWeth.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/test/gmp/DestinationChainSwapExecutable.sol/DestinationChainSwapExecutable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/test/gmp/DestinationChainSwapForecallable.sol/DestinationChainSwapForecallable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/test/gmp/DestinationChainTokenSwapper.sol/DestinationChainTokenSwapper.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/test/gmp/SourceChainSwapCaller.sol/SourceChainSwapCaller.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/util/BytesStringUtil.sol/Bytes32ToString.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/util/BytesStringUtil.sol/Bytes32ToString.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Bytes32ToString", 4 | "sourceName": "contracts/util/BytesStringUtil.sol", 5 | "abi": [], 6 | "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220266f7ebfe28f7e58ce427fbf729a624548854177388bd6a0a000d3f56b7a32c464736f6c63430008090033", 7 | "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220266f7ebfe28f7e58ce427fbf729a624548854177388bd6a0a000d3f56b7a32c464736f6c63430008090033", 8 | "linkReferences": {}, 9 | "deployedLinkReferences": {} 10 | } 11 | -------------------------------------------------------------------------------- /artifacts/contracts/util/BytesStringUtil.sol/StringToBytes32.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/util/BytesStringUtil.sol/StringToBytes32.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "StringToBytes32", 4 | "sourceName": "contracts/util/BytesStringUtil.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidStringLength", 9 | "type": "error" 10 | } 11 | ], 12 | "bytecode": "0x60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208e9bf9e0c9b8d64870f94f46439a3a1ac5de0bc9a46808cc3a5e5ad1a1008b5064736f6c63430008090033", 13 | "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208e9bf9e0c9b8d64870f94f46439a3a1ac5de0bc9a46808cc3a5e5ad1a1008b5064736f6c63430008090033", 14 | "linkReferences": {}, 15 | "deployedLinkReferences": {} 16 | } 17 | -------------------------------------------------------------------------------- /artifacts/contracts/util/Proxy.sol/Proxy.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/util/Upgradable.sol/Upgradable.dbg.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-dbg-1", 3 | "buildInfo": "../../../build-info/d18b3085ce11cc0c382cfc3f94a279f7.json" 4 | } 5 | -------------------------------------------------------------------------------- /artifacts/contracts/util/Upgradable.sol/Upgradable.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Upgradable", 4 | "sourceName": "contracts/util/Upgradable.sol", 5 | "abi": [ 6 | { 7 | "inputs": [], 8 | "name": "InvalidCodeHash", 9 | "type": "error" 10 | }, 11 | { 12 | "inputs": [], 13 | "name": "InvalidImplementation", 14 | "type": "error" 15 | }, 16 | { 17 | "inputs": [], 18 | "name": "InvalidOwner", 19 | "type": "error" 20 | }, 21 | { 22 | "inputs": [], 23 | "name": "NotOwner", 24 | "type": "error" 25 | }, 26 | { 27 | "inputs": [], 28 | "name": "NotProxy", 29 | "type": "error" 30 | }, 31 | { 32 | "inputs": [], 33 | "name": "SetupFailed", 34 | "type": "error" 35 | }, 36 | { 37 | "anonymous": false, 38 | "inputs": [ 39 | { 40 | "indexed": true, 41 | "internalType": "address", 42 | "name": "newOwner", 43 | "type": "address" 44 | } 45 | ], 46 | "name": "OwnershipTransferred", 47 | "type": "event" 48 | }, 49 | { 50 | "anonymous": false, 51 | "inputs": [ 52 | { 53 | "indexed": true, 54 | "internalType": "address", 55 | "name": "newImplementation", 56 | "type": "address" 57 | } 58 | ], 59 | "name": "Upgraded", 60 | "type": "event" 61 | }, 62 | { 63 | "inputs": [], 64 | "name": "contractId", 65 | "outputs": [ 66 | { 67 | "internalType": "bytes32", 68 | "name": "", 69 | "type": "bytes32" 70 | } 71 | ], 72 | "stateMutability": "pure", 73 | "type": "function" 74 | }, 75 | { 76 | "inputs": [], 77 | "name": "implementation", 78 | "outputs": [ 79 | { 80 | "internalType": "address", 81 | "name": "implementation_", 82 | "type": "address" 83 | } 84 | ], 85 | "stateMutability": "view", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [], 90 | "name": "owner", 91 | "outputs": [ 92 | { 93 | "internalType": "address", 94 | "name": "owner_", 95 | "type": "address" 96 | } 97 | ], 98 | "stateMutability": "view", 99 | "type": "function" 100 | }, 101 | { 102 | "inputs": [ 103 | { 104 | "internalType": "bytes", 105 | "name": "data", 106 | "type": "bytes" 107 | } 108 | ], 109 | "name": "setup", 110 | "outputs": [], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "address", 118 | "name": "newOwner", 119 | "type": "address" 120 | } 121 | ], 122 | "name": "transferOwnership", 123 | "outputs": [], 124 | "stateMutability": "nonpayable", 125 | "type": "function" 126 | }, 127 | { 128 | "inputs": [ 129 | { 130 | "internalType": "address", 131 | "name": "newImplementation", 132 | "type": "address" 133 | }, 134 | { 135 | "internalType": "bytes32", 136 | "name": "newImplementationCodeHash", 137 | "type": "bytes32" 138 | }, 139 | { 140 | "internalType": "bytes", 141 | "name": "params", 142 | "type": "bytes" 143 | } 144 | ], 145 | "name": "upgrade", 146 | "outputs": [], 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | } 150 | ], 151 | "bytecode": "0x", 152 | "deployedBytecode": "0x", 153 | "linkReferences": {}, 154 | "deployedLinkReferences": {} 155 | } 156 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@axelar-network/axelarjs-sdk", 3 | "version": "0.17.5-alpha.2", 4 | "description": "The JavaScript SDK for Axelar Network", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/axelarnetwork/axelarjs-sdk" 8 | }, 9 | "main": "dist/src/index.js", 10 | "types": "dist/src/index.d.ts", 11 | "files": [ 12 | "dist", 13 | "!dist/src/libs/test", 14 | "!dist/test", 15 | "scripts" 16 | ], 17 | "scripts": { 18 | "build": "rimraf dist && tsc", 19 | "compile-axelar-cgp-solidity": "cd node_modules/@axelar-network/axelar-cgp-solidity && npm install && npx hardhat compile && cp -R artifacts ../../../artifacts && npm uninstall *", 20 | "dev:tsc": "tsc --watch -p .", 21 | "dev:serve": "nodemon -e js -w dist dist/index.js", 22 | "dev": "run-p dev:*", 23 | "test": "vitest run", 24 | "test:watch": "vitest", 25 | "test:e2e": "vitest run --config test/e2e/vitest.e2e.config.ts", 26 | "test:integration": "vitest run --config test/integration/vitest.integration.config.ts", 27 | "lint": "eslint . --ext .ts", 28 | "lint:fix": "eslint . --ext .ts --fix", 29 | "format": "prettier --write \"./**/*.{ts,json}\"", 30 | "postinstall": "node scripts/postinstall.js" 31 | }, 32 | "keywords": [ 33 | "axelar", 34 | "blockchain", 35 | "sdk", 36 | "cryptocurrency", 37 | "interoperability", 38 | "smart-contracts", 39 | "cross-chain" 40 | ], 41 | "author": "Axelar Network", 42 | "license": "MIT", 43 | "dependencies": { 44 | "@axelar-network/axelar-cgp-solidity": "^6.3.0", 45 | "@axelar-network/axelarjs-types": "^1.2.1", 46 | "@cosmjs/json-rpc": "^0.30.1", 47 | "@cosmjs/stargate": "0.31.0-alpha.1", 48 | "@ethersproject/abstract-provider": "^5.7.0", 49 | "@ethersproject/networks": "^5.7.1", 50 | "@ethersproject/providers": "^5.7.2", 51 | "@mysten/sui": "^1.14.2", 52 | "@stellar/stellar-sdk": "^13.0.0", 53 | "@types/uuid": "^8.3.1", 54 | "bech32": "^2.0.0", 55 | "clone-deep": "^4.0.1", 56 | "cross-fetch": "^3.1.5", 57 | "ethers": "^5.7.2", 58 | "socket.io-client": "^4.6.1", 59 | "standard-http-error": "^2.0.1", 60 | "string-similarity-js": "^2.1.4", 61 | "uuid": "^8.3.2", 62 | "ws": "^8.13.0", 63 | "xrpl": "4.2.5" 64 | }, 65 | "devDependencies": { 66 | "@axelar-network/axelar-local-dev": "1.0.2", 67 | "@babel/preset-env": "^7.16.4", 68 | "@babel/preset-typescript": "^7.16.0", 69 | "@cosmjs/encoding": "^0.30.1", 70 | "@cosmjs/proto-signing": "0.31.0-alpha.1", 71 | "@cosmjs/tendermint-rpc": "0.31.0-alpha.1", 72 | "@ethersproject/abi": "^5.7.0", 73 | "@types/clone-deep": "^4.0.1", 74 | "@types/standard-http-error": "^2.0.1", 75 | "@typescript-eslint/eslint-plugin": "^5.39.0", 76 | "@typescript-eslint/parser": "^5.30.0", 77 | "chalk": "^4.1.2", 78 | "cosmjs-types": "^0.8.0", 79 | "eslint": "^8.24.0", 80 | "eslint-config-prettier": "^8.8.0", 81 | "eslint-config-standard-with-typescript": "^23.0.0", 82 | "eslint-plugin-import": "^2.26.0", 83 | "eslint-plugin-n": "^15.3.0", 84 | "eslint-plugin-prettier": "^4.2.1", 85 | "eslint-plugin-promise": "^6.0.1", 86 | "ganache": "^7.8.0", 87 | "long": "^5.2.3", 88 | "nodemon": "^2.0.22", 89 | "npm-run-all": "^4.1.5", 90 | "package-json": "^8.1.1", 91 | "prettier": "2.8.8", 92 | "rimraf": "^5.0.1", 93 | "strip-ansi": "^6.0.0", 94 | "ts-node": "^10.9.1", 95 | "typescript": "^5.6.3", 96 | "vitest": "^0.32.0" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs/promises"); 2 | 3 | const pad = (n = 0) => " ".repeat(n); 4 | 5 | /** 6 | * 7 | * @param {string[]} lines 8 | */ 9 | async function renderBox(lines = [], color = (str) => str) { 10 | const { default: stripAnsi } = await import("strip-ansi"); 11 | const maxLineLength = lines.reduce((max, line) => Math.max(max, stripAnsi(line).length), 0); 12 | 13 | const maxLength = maxLineLength + 2; 14 | 15 | const [tr, tl, br, bl, h, v] = [ 16 | color("╗"), 17 | color("╔"), 18 | color("╝"), 19 | color("╚"), 20 | color("═"), 21 | color("║"), 22 | ]; 23 | 24 | const border = h.repeat(maxLength); 25 | 26 | console.log(` 27 | ${tl}${border}${tr} 28 | ${lines 29 | .map((line) => { 30 | const [short, long] = [maxLength, stripAnsi(line).length].sort(); 31 | 32 | const padding = long === short ? 0 : long - short - 2; 33 | 34 | return `${v} ${line}${pad(Math.max(padding, 0))} ${v}`; 35 | }) 36 | .join("\n")} 37 | ${bl}${border}${br} 38 | `); 39 | } 40 | 41 | const PACKAGE_LOCK_FILES = ["yarn.lock", "package-lock.json", "pnpm-lock.yaml"]; 42 | 43 | /** 44 | * inferPackageManager - infer package manager 45 | * @returns {Promise<"yarn" | "npm" | "pnpm">} 46 | */ 47 | async function inferPackageManager() { 48 | const [hasYarnLock, hasPackageLock, hasPnpmLock] = await Promise.all( 49 | PACKAGE_LOCK_FILES.map((file) => 50 | fs 51 | .readFile(file, "utf8") 52 | .then(Boolean) 53 | .catch(() => false) 54 | ) 55 | ); 56 | 57 | if (hasYarnLock) return "yarn"; 58 | if (hasPackageLock) return "npm"; 59 | if (hasPnpmLock) return "pnpm"; 60 | 61 | return "npm"; 62 | } 63 | 64 | async function main() { 65 | try { 66 | const { version, name } = await fs.readFile("./package.json", "utf-8").then(JSON.parse); 67 | 68 | // use async import to avoid esm / cjs interop issues 69 | const { default: packageJson } = await import("package-json"); 70 | const { default: chalk } = await import("chalk"); 71 | 72 | // check for latest version on npm 73 | const { version: latest } = await packageJson(name, { 74 | version: "latest", 75 | }); 76 | 77 | if (version == latest) { 78 | console.log(`[${name}@${version}] Awesome! you're on the latest version 🎉`); 79 | // nothing to see here 80 | return; 81 | } 82 | 83 | const releaseUrl = `https://github.com/axelarnetwork/axelarjs-sdk/releases/tag/v${latest}`; 84 | const changelogUrl = `https://github.com/axelarnetwork/axelarjs-sdk/blob/v${latest}/CHANGELOG.md`; 85 | 86 | const updateLine = chalk.bold( 87 | `📦 Update available! ${chalk.red(version)} → ${chalk.green(latest)}` 88 | ); 89 | 90 | const AXELARJS_TAG = [ 91 | " .__ __", 92 | "_____ ___ ___ ____ | | _____ _______ |__| ______", 93 | "\\__ \\ \\ \\/ // __ \\| | \\__ \\\\_ __ \\| |/ ___/", 94 | " / __ \\_> <\\ ___/| |__/ __ \\| | \\/| |\\___ \\", 95 | "(____ /__/\\_ \\\\___ >____(____ /__/\\__| /____ >", 96 | " \\/ \\/ \\/ \\/ \\______| \\/", 97 | ]; 98 | 99 | const packageManager = await inferPackageManager(); 100 | 101 | const installCommands = { 102 | npm: `npm i ${name}@latest`, 103 | yarn: `yarn add ${name}@latest`, 104 | pnpm: `pnpm add ${name}@latest`, 105 | }; 106 | 107 | await renderBox( 108 | [ 109 | ...AXELARJS_TAG.map((x) => chalk.bold.green(pad(9).concat(x))), 110 | "", 111 | `${pad(20)}${chalk.bold.yellow(name)}`, 112 | "", 113 | `${pad(16)}${updateLine}`, 114 | "", 115 | `${pad(6)}Run ${chalk.bgGray(installCommands[packageManager])} to update!`, 116 | "", 117 | "Find out more about this release:", 118 | "", 119 | `${chalk.cyan(changelogUrl)}`, 120 | `${chalk.cyan(releaseUrl)}`, 121 | "", 122 | ], 123 | chalk.bold.yellow 124 | ); 125 | } catch (error) { 126 | console.log("Failed to check for updates.", error?.message); 127 | } 128 | } 129 | 130 | main().catch(console.error); 131 | -------------------------------------------------------------------------------- /sdk-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axelarnetwork/axelarjs-sdk/f84c8a21ad9685091002e24cac7001ed1cdac774/sdk-diagram.png -------------------------------------------------------------------------------- /src/assets/index.ts: -------------------------------------------------------------------------------- 1 | import fetch from "cross-fetch"; 2 | import { AssetConfig, LoadAssetConfig } from "./types"; 3 | import { Environment } from "../libs"; 4 | 5 | const urlMap: Record = { 6 | "devnet-amplifier": "https://axelar-testnet.s3.us-east-2.amazonaws.com/devnet-asset-config.json", 7 | testnet: "https://axelar-testnet.s3.us-east-2.amazonaws.com/testnet-asset-config.json", 8 | mainnet: "https://axelar-mainnet.s3.us-east-2.amazonaws.com/mainnet-asset-config.json", 9 | }; 10 | const assetMap: Record = { 11 | "devnet-amplifier": null, 12 | testnet: null, 13 | mainnet: null, 14 | }; 15 | 16 | export async function loadAssets(config: LoadAssetConfig): Promise { 17 | if (assetMap[config.environment]) return Object.values(assetMap[config.environment]); 18 | 19 | assetMap[config.environment] = await execGet(urlMap[config.environment]); 20 | 21 | return Object.values(assetMap[config.environment]); 22 | } 23 | 24 | async function execGet(url: string) { 25 | return fetch(url, { 26 | method: "GET", 27 | headers: { "Content-Type": "application/json" }, 28 | }) 29 | .then((res) => res.json()) 30 | .catch((error) => { 31 | console.log({ error }); 32 | throw error; 33 | }); 34 | } 35 | -------------------------------------------------------------------------------- /src/assets/test/loadAssets.spec.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from "../../libs"; 2 | import { loadAssets } from ".."; 3 | 4 | const mock = { 5 | loadAssets: loadAssets, 6 | }; 7 | 8 | describe("loadAssets()", () => { 9 | beforeEach(() => { 10 | vitest.clearAllMocks(); 11 | vitest.spyOn(mock, "loadAssets"); 12 | }); 13 | 14 | describe("when loadAssets is called with known env, but not mainnet", () => { 15 | beforeEach(() => { 16 | mock.loadAssets({ 17 | environment: Environment.TESTNET, 18 | }); 19 | }); 20 | 21 | test("then it should call loadAssets", () => { 22 | expect(mock.loadAssets).toHaveBeenCalledWith({ environment: Environment.TESTNET }); 23 | }); 24 | 25 | // test("then it should return assets", () => { 26 | // expect(mock.loadAssets).toHaveReturnedWith(Object.values(testnet)); 27 | // }); 28 | }); 29 | 30 | describe("when loadAssets is called with mainnet", () => { 31 | beforeEach(() => { 32 | mock.loadAssets({ 33 | environment: Environment.MAINNET, 34 | }); 35 | }); 36 | 37 | test("then it should call loadAssets", () => { 38 | expect(mock.loadAssets).toHaveBeenCalledWith({ environment: Environment.MAINNET }); 39 | }); 40 | 41 | // test("then it should return assets", () => { 42 | // expect(mock.loadAssets).toHaveReturnedWith(Object.values(mainnet)); 43 | // }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /src/assets/types/index.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from "../../libs"; 2 | 3 | export interface AssetInfo { 4 | assetSymbol?: string; 5 | assetName?: string; 6 | assetAddress?: string; 7 | common_key?: string; 8 | fullDenomPath?: string; 9 | fullySupported?: boolean; 10 | native_chain?: string; 11 | minDepositAmt?: number; 12 | decimals?: number; 13 | ibcDenom?: string; 14 | tokenAddress?: string; 15 | } 16 | 17 | export interface AssetInfoForChain extends AssetInfo { 18 | minDepositAmt: number; 19 | } 20 | 21 | export interface AssetConfig { 22 | id: string; 23 | common_key: { [env: string]: string }; 24 | native_chain: string; 25 | fully_supported: boolean; 26 | decimals: number; 27 | chain_aliases: { [key: string]: AssetInfoForChain }; 28 | wrapped_erc20: string; 29 | is_gas_token: boolean; 30 | } 31 | 32 | export type LoadAssetConfig = { 33 | environment: Environment; 34 | }; 35 | -------------------------------------------------------------------------------- /src/chains/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./supported-chains-list"; 2 | 3 | import fetch from "cross-fetch"; 4 | import { loadAssets } from "../assets"; 5 | import { AssetConfig, AssetInfo } from "../assets/types"; 6 | import { ChainInfo, LoadChainConfig } from "./types"; 7 | import cloneDeep from "clone-deep"; 8 | import { Environment } from "../libs"; 9 | 10 | export async function loadChains(config: LoadChainConfig) { 11 | const allAssets = await loadAssets(config); 12 | const _environment = config.environment as Environment; 13 | 14 | const rawChains: ChainInfo[] = await importChains({ environment: _environment }); 15 | 16 | /*push assets to supported chains*/ 17 | rawChains.forEach((chainInfo) => { 18 | const filteredAssetList: AssetConfig[] = allAssets.filter( 19 | ({ chain_aliases }) => 20 | Object.keys(chain_aliases).indexOf(chainInfo.chainName.toLowerCase()) > -1 21 | ); 22 | 23 | const assetsList: AssetInfo[] = []; 24 | 25 | filteredAssetList.forEach((asset) => { 26 | const assetToPush: AssetInfo = cloneDeep( 27 | asset.chain_aliases[chainInfo.chainName.toLowerCase()] 28 | ); 29 | assetToPush.common_key = asset.common_key[_environment]; 30 | assetToPush.native_chain = asset.native_chain; 31 | assetToPush.decimals = asset.decimals; 32 | assetToPush.fullySupported = asset.fully_supported; 33 | assetsList.push(assetToPush); 34 | }); 35 | 36 | chainInfo.assets = assetsList; 37 | }); 38 | 39 | return rawChains; 40 | } 41 | 42 | const s3UrlMap: Record = { 43 | "devnet-amplifier": 44 | "https://axelar-devnets.s3.us-east-2.amazonaws.com/configs/devnet-amplifier-config-1.0.x.json", 45 | testnet: "https://axelar-testnet.s3.us-east-2.amazonaws.com/configs/testnet-config-1.x.json", 46 | mainnet: "https://axelar-mainnet.s3.us-east-2.amazonaws.com/configs/mainnet-config-1.x.json", 47 | }; 48 | 49 | const urlMap: Record = { 50 | "devnet-amplifier": "https://static.npty.online/axelar/devnet-amplifier-chain-config.json", 51 | testnet: "https://axelar-testnet.s3.us-east-2.amazonaws.com/testnet-chain-config.json", 52 | mainnet: "https://axelar-mainnet.s3.us-east-2.amazonaws.com/mainnet-chain-config.json", 53 | }; 54 | const chainMap: Record = { 55 | "devnet-amplifier": null, 56 | testnet: null, 57 | mainnet: null, 58 | }; 59 | 60 | const s3Map: Record = { 61 | "devnet-amplifier": null, 62 | testnet: null, 63 | mainnet: null, 64 | }; 65 | 66 | export async function importS3Config(environment: Environment): Promise { 67 | if (s3Map[environment]) return s3Map[environment]; 68 | 69 | s3Map[environment] = await execGet(s3UrlMap[environment]); 70 | 71 | return s3Map[environment]; 72 | } 73 | 74 | export async function importChains(config: LoadChainConfig): Promise { 75 | if (chainMap[config.environment]) return Object.values(chainMap[config.environment]); 76 | 77 | chainMap[config.environment] = await execGet(urlMap[config.environment]); 78 | 79 | return Object.values(chainMap[config.environment]); 80 | } 81 | 82 | async function execGet(url: string) { 83 | return fetch(url, { 84 | method: "GET", 85 | headers: { 86 | "Content-Type": "application/json", 87 | }, 88 | }) 89 | .then((res) => res.json()) 90 | .catch((error) => { 91 | throw error; 92 | }); 93 | } 94 | -------------------------------------------------------------------------------- /src/chains/supported-chains-list.ts: -------------------------------------------------------------------------------- 1 | export const CHAINS = { 2 | TESTNET: { 3 | ACRE: "acre", 4 | ARBITRUM_SEPOLIA: "arbitrum-sepolia", 5 | AURA: "aura", 6 | AURORA: "aurora", 7 | AXELAR: "Axelarnet", 8 | AVALANCHE: "Avalanche", 9 | BINANCE: "binance", 10 | BNBCHAIN: "binance", 11 | BURNT: "burnt-2", 12 | CELESTIA: "celestia", 13 | CELO: "celo", 14 | CENTRIFUGE: "centrifuge-2", 15 | COMDEX: "comdex-2", 16 | EVMOS: "evmos", 17 | FANTOM: "Fantom", 18 | FETCH: "fetch", 19 | FILECOIN: "filecoin-2", 20 | FRAXTAL: "fraxtal", 21 | HAQQ: "haqq", 22 | HERO: "hero", 23 | HIGHRISE: "highrise", 24 | IMMUTABLE: "immutable", 25 | IMPACTHUB: "impacthub", 26 | KAVA: "kava", 27 | KUJIRA: "kujira", 28 | LINEA: "linea", 29 | MIGALOO: "migaloo", 30 | MOONBEAM: "Moonbeam", 31 | NEUTRON: "neutron", 32 | ODIN: "odin", 33 | OSMOSIS: "osmosis-7", 34 | PERSISTENCE: "persistence", 35 | POLYGON: "Polygon", 36 | POLYGON_SEPOLIA: "polygon-sepolia", 37 | POLYGONZKEVM: "polygon-zkevm", 38 | PROVENANCE: "provenance", 39 | SEPOLIA: "ethereum-sepolia", 40 | SCROLL: "scroll", 41 | SECRETSNIP: "secret-snip-2", 42 | SEI: "sei-2", 43 | TERITORI: "teritori", 44 | TERRA: "terra-3", 45 | XPLA: "xpla", 46 | BLAST_SEPOLIA: "blast-sepolia", 47 | OPTIMISM_SEPOLIA: "optimism-sepolia", 48 | MANTLE_SEPOLIA: "mantle-sepolia", 49 | BASE_SEPOLIA: "base-sepolia", 50 | LINEA_SEPOLIA: "linea-sepolia", 51 | }, 52 | MAINNET: { 53 | ACRE: "acre", 54 | AGORIC: "agoric", 55 | ARBITRUM: "arbitrum", 56 | ARCHWAY: "archway", 57 | ASSETMANTLE: "assetmantle", 58 | AURA: "aura", 59 | AVALANCHE: "Avalanche", 60 | AXELAR: "Axelarnet", 61 | BASE: "base", 62 | BINANCE: "binance", 63 | BLAST: "blast", 64 | BNBCHAIN: "binance", 65 | CARBON: "carbon", 66 | CELESTIA: "celestia", 67 | CELO: "celo", 68 | CENTRIFUGE: "centrifuge", 69 | COMDEX: "comdex", 70 | COSMOSHUB: "cosmoshub", 71 | CRESCENT: "crescent", 72 | EMONEY: "e-money", 73 | ETHEREUM: "Ethereum", 74 | EVMOS: "evmos", 75 | FANTOM: "Fantom", 76 | FETCH: "fetch", 77 | FILECOIN: "filecoin", 78 | FRAXTAL: "fraxtal", 79 | HAQQ: "haqq", 80 | IMMUTABLE: "immutable", 81 | INJECTIVE: "injective", 82 | IXO: "ixo", 83 | JUNO: "juno", 84 | KAVA: "kava", 85 | KI: "ki", 86 | KUJIRA: "kujira", 87 | LINEA: "linea", 88 | MANTLE: "mantle", 89 | MIGALOO: "migaloo", 90 | MOONBEAM: "Moonbeam", 91 | NEUTRON: "neutron", 92 | OPTIMISM: "optimism", 93 | OSMOSIS: "osmosis", 94 | PERSISTENCE: "persistence", 95 | POLYGON: "Polygon", 96 | POLYGONZKEVM: "polygon-zkevm", 97 | PROVENANCE: "provenance", 98 | REBUS: "rebus", 99 | REGEN: "regen", 100 | SCROLL: "scroll", 101 | SECRET: "secret", 102 | SECRETSNIP: "secret-snip", 103 | SEI: "sei", 104 | SOMMELIER: "sommelier", 105 | STARGAZE: "stargaze", 106 | STRIDE: "stride", 107 | TERITORI: "teritori", 108 | TERRACLASSIC: "terra", 109 | TERRA: "terra-2", 110 | UMEE: "umee", 111 | XPLA: "xpla", 112 | }, 113 | }; 114 | -------------------------------------------------------------------------------- /src/chains/test/loadChains.spec.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from "../../libs"; 2 | import { loadChains } from ".."; 3 | 4 | const mock = { 5 | loadChains: loadChains, 6 | }; 7 | 8 | describe("loadChains()", () => { 9 | beforeEach(() => { 10 | vitest.clearAllMocks(); 11 | vitest.spyOn(mock, "loadChains"); 12 | }); 13 | 14 | describe("when loadChains is called with known env, but not mainnet", () => { 15 | beforeEach(() => { 16 | mock.loadChains({ 17 | environment: Environment.TESTNET, 18 | }); 19 | }); 20 | 21 | test("then it should call loadChains", () => { 22 | expect(mock.loadChains).toHaveBeenCalledWith({ environment: Environment.TESTNET }); 23 | }); 24 | 25 | test("then it should return assets", () => { 26 | expect(mock.loadChains).toHaveReturned(); 27 | }); 28 | }); 29 | 30 | describe("when loadChains is called with mainnet", () => { 31 | beforeEach(() => { 32 | mock.loadChains({ 33 | environment: Environment.MAINNET, 34 | }); 35 | }); 36 | 37 | test("then it should call loadChains", () => { 38 | expect(mock.loadChains).toHaveBeenCalledWith({ environment: "mainnet" }); 39 | }); 40 | 41 | test("then it should return assets", () => { 42 | expect(mock.loadChains).toHaveReturned(); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /src/chains/types/index.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from "../../libs"; 2 | import { AssetInfo } from "../../assets/types"; 3 | 4 | import { SourceOrDestination } from "../../services/types"; 5 | 6 | export interface Chain { 7 | chainInfo: ChainInfo; 8 | validateAddress: (destinationAddress: string) => boolean; 9 | } 10 | 11 | export interface AssetAndChainInfo { 12 | assetInfo: AssetInfoResponse; 13 | sourceChainInfo: ChainInfo; 14 | destinationChainInfo: ChainInfo; 15 | } 16 | 17 | export interface ChainInfo { 18 | id: string; 19 | assets: AssetInfo[]; 20 | chainSymbol: string; 21 | chainName: string; 22 | fullySupported: boolean; 23 | estimatedWaitTime: number; 24 | txFeeInPercent: number; 25 | module: "axelarnet" | "evm"; 26 | confirmLevel?: number; 27 | rpc: string[]; 28 | chainIdentifier: { 29 | "devnet-amplifier": string; 30 | testnet: string; 31 | mainnet: string; 32 | }; 33 | nativeAsset: string[]; 34 | addressPrefix: string; 35 | channelIdToAxelar?: string; 36 | } 37 | 38 | export interface AssetTransferObject { 39 | sourceChainInfo: ChainInfo; 40 | destinationChainInfo: ChainInfo; 41 | selectedSourceAsset: AssetInfo; 42 | selectedDestinationAsset: AssetInfo; 43 | signature: string; 44 | publicAddr: string; 45 | transactionTraceId?: string; 46 | } 47 | 48 | export interface AssetInfoWithTrace extends AssetInfo { 49 | traceId: string; 50 | assetInfo: AssetInfo; 51 | } 52 | 53 | export interface AssetInfoResponse extends AssetInfo { 54 | sourceOrDestChain: SourceOrDestination; 55 | traceId: string; 56 | } 57 | 58 | export enum LinkType { 59 | EVM = "/axelar.evm.v1beta1.LinkRequest", 60 | COS = "/axelar.axelarnet.v1beta1.LinkRequest", 61 | } 62 | 63 | export interface LinkRequestBody { 64 | "@type": LinkType; 65 | recipient_addr: string; 66 | recipient_chain: string; 67 | } 68 | 69 | export interface EVMLinkRequestBody extends LinkRequestBody { 70 | chain: string; //source chain 71 | asset: string; 72 | } 73 | 74 | export interface COSLinkRequestBody extends LinkRequestBody { 75 | asset: string; 76 | } 77 | 78 | // for connections from ui >> bridge server 79 | export enum SocketListenerTypes { 80 | /*axelarnet listener for deposit event*/ 81 | LINK = "LINK", 82 | WAIT_FOR_DEPOSIT = "WAIT_FOR_DEPOSIT", 83 | DEPOSIT_CONFIRMED = "DEPOSIT_CONFIRMED", 84 | } 85 | 86 | export interface SocketListenerTopic { 87 | topic: SocketListenerTypes; 88 | } 89 | 90 | export type LoadChainConfig = { 91 | environment: Environment; 92 | }; 93 | -------------------------------------------------------------------------------- /src/constants/EvmChain.ts: -------------------------------------------------------------------------------- 1 | export enum EvmChain { 2 | ETHEREUM = "ethereum", 3 | AVALANCHE = "avalanche", 4 | FANTOM = "fantom", 5 | POLYGON = "polygon", 6 | POLYGON_ZKEVM = "polygon-zkevm", 7 | MOONBEAM = "moonbeam", 8 | AURORA = "aurora", 9 | BINANCE = "binance", 10 | BNBCHAIN = "binance", 11 | ARBITRUM = "arbitrum", 12 | ARBITRUM_SEPOLIA = "arbitrum-sepolia", 13 | CELO = "celo", 14 | KAVA = "kava", 15 | BASE = "base", 16 | FILECOIN = "filecoin", 17 | OPTIMISM = "optimism", 18 | LINEA = "linea", 19 | MANTLE = "mantle", 20 | SCROLL = "scroll", 21 | SEPOLIA = "ethereum-sepolia", 22 | IMMUTABLE = "immutable", 23 | CENTRIFUGE_TESTNET = "centrifuge-2", 24 | CENTRIFUGE = "centrifuge", 25 | FRAXTAL = "fraxtal", 26 | BLAST_SEPOLIA = "blast-sepolia", 27 | OPTIMISM_SEPOLIA = "optimism-sepolia", 28 | MANTLE_SEPOLIA = "mantle-sepolia", 29 | BASE_SEPOLIA = "base-sepolia", 30 | BLAST = "blast", 31 | POLYGON_SEPOLIA = "polygon-sepolia", 32 | LINEA_SEPOLIA = "linea-sepolia", 33 | } 34 | -------------------------------------------------------------------------------- /src/constants/GasToken.ts: -------------------------------------------------------------------------------- 1 | import { EvmChain } from "./EvmChain"; 2 | 3 | // Includes all supported native tokens and stablecoins (i.e. for fees) 4 | 5 | export enum GasToken { 6 | ETH = "ETH", 7 | AVAX = "AVAX", 8 | GLMR = "GLMR", 9 | FTM = "FTM", 10 | MATIC = "MATIC", 11 | USDC = "USDC", 12 | aUSDC = "aUSDC", 13 | axlUSDC = "axlUSDC", 14 | AURORA = "aETH", 15 | BINANCE = "BNB", 16 | BNBCHAIN = "BNB", 17 | CELO = "CELO", 18 | KAVA = "KAVA", 19 | BASE = "ETH", 20 | FILECOIN = "FIL", 21 | OSMO = "OSMO", 22 | AXL = "AXL", 23 | POLYGON_ZKEVM = "ETH", 24 | MANTLE = "MNT", 25 | SCROLL = "ETH", 26 | IMMUTABLE = "IMX", 27 | SEPOLIA = "ETH", 28 | ARBITRUM_SEPOLIA = "ETH", 29 | CENTRIFUGE = "CFG", 30 | FRAXTAL = "frxETH", 31 | BLAST_SEPOLIA = "ETH", 32 | OPTIMISM_SEPOLIA = "ETH", 33 | MANTLE_SEPOLIA = "ETH", 34 | BASE_SEPOLIA = "ETH", 35 | BLAST = "ETH", 36 | LINEA_SEPOLIA = "ETH", 37 | } 38 | 39 | export const nativeGasTokenSymbol: Record> = { 40 | testnet: { 41 | [EvmChain.AVALANCHE]: GasToken.AVAX, 42 | [EvmChain.MOONBEAM]: GasToken.GLMR, 43 | [EvmChain.POLYGON]: GasToken.MATIC, 44 | "ethereum-2": GasToken.ETH, 45 | [EvmChain.FANTOM]: GasToken.FTM, 46 | [EvmChain.AURORA]: GasToken.AURORA, 47 | [EvmChain.BINANCE]: GasToken.BINANCE, 48 | [EvmChain.ARBITRUM]: GasToken.ETH, 49 | [EvmChain.CELO]: GasToken.CELO, 50 | [EvmChain.KAVA]: GasToken.KAVA, 51 | [EvmChain.BASE]: GasToken.BASE, 52 | "filecoin-2": GasToken.FILECOIN, 53 | [EvmChain.OPTIMISM]: GasToken.ETH, 54 | [EvmChain.LINEA]: GasToken.ETH, 55 | [EvmChain.POLYGON_ZKEVM]: GasToken.POLYGON_ZKEVM, 56 | [EvmChain.MANTLE]: GasToken.MANTLE, 57 | [EvmChain.SCROLL]: GasToken.SCROLL, 58 | [EvmChain.SEPOLIA]: GasToken.SEPOLIA, 59 | [EvmChain.IMMUTABLE]: GasToken.IMMUTABLE, 60 | [EvmChain.ARBITRUM_SEPOLIA]: GasToken.ARBITRUM_SEPOLIA, 61 | [EvmChain.CENTRIFUGE_TESTNET]: GasToken.CENTRIFUGE, 62 | [EvmChain.FRAXTAL]: GasToken.FRAXTAL, 63 | [EvmChain.BLAST_SEPOLIA]: GasToken.BLAST_SEPOLIA, 64 | [EvmChain.MANTLE_SEPOLIA]: GasToken.MANTLE_SEPOLIA, 65 | [EvmChain.BASE_SEPOLIA]: GasToken.BASE_SEPOLIA, 66 | [EvmChain.OPTIMISM_SEPOLIA]: GasToken.OPTIMISM_SEPOLIA, 67 | }, 68 | mainnet: { 69 | [EvmChain.AVALANCHE]: GasToken.AVAX, 70 | [EvmChain.MOONBEAM]: GasToken.GLMR, 71 | [EvmChain.POLYGON]: GasToken.MATIC, 72 | [EvmChain.ETHEREUM]: GasToken.ETH, 73 | [EvmChain.FANTOM]: GasToken.FTM, 74 | [EvmChain.AURORA]: GasToken.AURORA, 75 | [EvmChain.BINANCE]: GasToken.BINANCE, 76 | [EvmChain.ARBITRUM]: GasToken.ETH, 77 | [EvmChain.CELO]: GasToken.CELO, 78 | [EvmChain.KAVA]: GasToken.KAVA, 79 | [EvmChain.BASE]: GasToken.BASE, 80 | [EvmChain.FILECOIN]: GasToken.FILECOIN, 81 | [EvmChain.OPTIMISM]: GasToken.ETH, 82 | [EvmChain.LINEA]: GasToken.ETH, 83 | [EvmChain.POLYGON_ZKEVM]: GasToken.POLYGON_ZKEVM, 84 | [EvmChain.MANTLE]: GasToken.MANTLE, 85 | [EvmChain.SCROLL]: GasToken.SCROLL, 86 | [EvmChain.CENTRIFUGE]: GasToken.CENTRIFUGE, 87 | [EvmChain.FRAXTAL]: GasToken.FRAXTAL, 88 | [EvmChain.BLAST]: GasToken.BLAST, 89 | }, 90 | }; 91 | 92 | export const DEFAULT_ESTIMATED_GAS = 700000; 93 | -------------------------------------------------------------------------------- /src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare type Nullable = T | undefined; 2 | 3 | interface Window { 4 | ethereum: any; 5 | } 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./assets"; 2 | export * from "./chains"; 3 | export * from "./constants"; 4 | export * from "./libs"; 5 | export * from "./utils"; 6 | export * from "./assets/types"; 7 | export * from "./chains/types"; 8 | export * from "./services/types"; 9 | -------------------------------------------------------------------------------- /src/libs/AxelarQueryClient/index.ts: -------------------------------------------------------------------------------- 1 | import { QueryClient } from "@cosmjs/stargate"; 2 | import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; 3 | import { EnvironmentConfigs, getConfigs } from "../../constants"; 4 | import { AxelarQueryClientConfig } from "../types"; 5 | import { AxelarQueryService, setupQueryExtension } from "./types/index"; 6 | 7 | export type AxelarQueryClientType = QueryClient & AxelarQueryService; 8 | 9 | export class AxelarQueryClient extends QueryClient { 10 | static async initOrGetAxelarQueryClient(config: AxelarQueryClientConfig) { 11 | const { axelarRpcUrl, environment } = config; 12 | const links: EnvironmentConfigs = getConfigs(environment); 13 | const rpc: string = axelarRpcUrl || links.axelarRpcUrl; 14 | return QueryClient.withExtensions(await Tendermint34Client.connect(rpc), setupQueryExtension); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/libs/AxelarQueryClient/types/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | QueryService as EvmQS, 3 | QueryServiceClientImpl as EVMQSCI, 4 | } from "@axelar-network/axelarjs-types/axelar/evm/v1beta1/service"; 5 | import { 6 | QueryService as AxelarnetQS, 7 | QueryServiceClientImpl as AxelarnetQSCI, 8 | } from "@axelar-network/axelarjs-types/axelar/axelarnet/v1beta1/service"; 9 | import { 10 | QueryService as NexusQS, 11 | QueryServiceClientImpl as NexusQSCI, 12 | } from "@axelar-network/axelarjs-types/axelar/nexus/v1beta1/service"; 13 | import { 14 | QueryService as TSSQS, 15 | QueryServiceClientImpl as TSSQSCI, 16 | } from "@axelar-network/axelarjs-types/axelar/tss/v1beta1/service"; 17 | import { 18 | QueryService as MultisigQS, 19 | QueryServiceClientImpl as MultisigQSCI, 20 | } from "@axelar-network/axelarjs-types/axelar/multisig/v1beta1/service"; 21 | import { QueryClient, createProtobufRpcClient } from "@cosmjs/stargate"; 22 | 23 | export interface AxelarQueryService { 24 | readonly evm: EvmQS; 25 | readonly axelarnet: AxelarnetQS; 26 | readonly nexus: NexusQS; 27 | readonly tss: TSSQS; 28 | readonly multisig: MultisigQS; 29 | } 30 | 31 | export function setupQueryExtension(base: QueryClient): AxelarQueryService { 32 | const client = createProtobufRpcClient(base); 33 | return { 34 | evm: new EVMQSCI(client), 35 | axelarnet: new AxelarnetQSCI(client), 36 | nexus: new NexusQSCI(client), 37 | tss: new TSSQSCI(client), 38 | multisig: new MultisigQSCI(client), 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/aminomessages/index.ts: -------------------------------------------------------------------------------- 1 | import { AminoConverters } from "@cosmjs/stargate"; 2 | import { toBech32 } from "@cosmjs/encoding"; 3 | import { toAccAddress } from "@cosmjs/stargate/build/queryclient/utils"; 4 | 5 | import { AXELAR_PREFIX } from "../const"; 6 | 7 | import Long from "long"; 8 | 9 | export const createAxelarAminoConverters = (): AminoConverters => ({ 10 | // nexus module 11 | "/axelar.nexus.v1beta1.SetTransferRateLimitRequest": { 12 | aminoType: "nexus/SetTransferRateLimit", 13 | toAmino: ({ sender, chain, limit: { amount, denom }, window: { seconds, nanos } }) => ({ 14 | sender: toBech32(AXELAR_PREFIX, sender), 15 | chain, 16 | window: Long.fromValue(seconds).multiply(1000000000).add(nanos).toString(), 17 | limit: { 18 | amount, 19 | denom, 20 | }, 21 | }), 22 | fromAmino: ({ sender, chain, limit: { amount, denom }, window }) => ({ 23 | sender: toAccAddress(sender), 24 | chain, 25 | window: { 26 | seconds: Long.fromNumber(Number(window) / 1000000000), 27 | nanos: Number(window) % 1000000000, 28 | }, 29 | 30 | limit: { 31 | amount, 32 | denom, 33 | }, 34 | }), 35 | }, 36 | "/axelar.nexus.v1beta1.ActivateChainRequest": { 37 | aminoType: "nexus/ActivateChain", 38 | toAmino: ({ sender, chains }) => ({ 39 | sender: toBech32(AXELAR_PREFIX, sender), 40 | chains, 41 | }), 42 | fromAmino: ({ sender, chains }) => ({ 43 | sender: toAccAddress(sender), 44 | chains, 45 | }), 46 | }, 47 | "/axelar.nexus.v1beta1.DeactivateChainRequest": { 48 | aminoType: "nexus/DeactivateChain", 49 | toAmino: ({ sender, chains }) => ({ 50 | sender: toBech32(AXELAR_PREFIX, sender), 51 | chains, 52 | }), 53 | fromAmino: ({ sender, chains }) => ({ 54 | sender: toAccAddress(sender), 55 | chains, 56 | }), 57 | }, 58 | }); 59 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/const/index.ts: -------------------------------------------------------------------------------- 1 | import { StdFee } from "@cosmjs/stargate"; 2 | 3 | export const AXELAR_PREFIX = "axelar"; 4 | 5 | export const STANDARD_FEE: StdFee = { 6 | amount: [ 7 | { 8 | denom: "uaxl", 9 | amount: "1000", 10 | }, 11 | ], 12 | gas: "5000000", 13 | }; 14 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/index.ts: -------------------------------------------------------------------------------- 1 | import { EnvironmentConfigs, getConfigs } from "../../constants"; 2 | import { RestService } from "../../services"; 3 | import { AxelarSigningClientConfig } from "../types"; 4 | import { 5 | SigningStargateClientOptions, 6 | SigningStargateClient, 7 | DeliverTxResponse, 8 | StdFee, 9 | SignerData, 10 | AminoTypes, 11 | } from "@cosmjs/stargate"; 12 | import { 13 | DirectSecp256k1HdWallet as Wallet, 14 | EncodeObject, 15 | OfflineSigner, 16 | Registry, 17 | } from "@cosmjs/proto-signing"; 18 | import { registerMultisigTxTypes } from "./types/MultisigTxTypes"; 19 | import { registerAxelarnetTxTypes } from "./types/AxelarnetTxTypes"; 20 | import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; 21 | import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx"; 22 | import { registerEvmTxTypes } from "./types/EvmTxTypes"; 23 | import { registerNexusTxTypes } from "./types/NexusTxTypes"; 24 | import { createAxelarAminoConverters } from "./aminomessages"; 25 | 26 | interface IAxelarSigningClient extends SigningStargateClient { 27 | signThenBroadcast( 28 | messages: readonly EncodeObject[], 29 | fee: number | StdFee | "auto", 30 | memo?: string 31 | ): Promise; 32 | signAndGetTxBytes( 33 | messages: readonly EncodeObject[], 34 | fee: StdFee, 35 | memo: string, 36 | explicitSignerData?: SignerData 37 | ): Promise; 38 | } 39 | 40 | export class AxelarSigningClient extends SigningStargateClient implements IAxelarSigningClient { 41 | readonly rpcApi: RestService; 42 | readonly axelarRpcUrl: string; 43 | readonly signerAddress: string; 44 | protected signerClient: SigningStargateClient; 45 | 46 | public constructor( 47 | tendermintClient: Tendermint34Client, 48 | signer: OfflineSigner, 49 | signerAddress: string, 50 | options: SigningStargateClientOptions 51 | ) { 52 | super(tendermintClient, signer, options); 53 | this.signerAddress = signerAddress; 54 | } 55 | 56 | static async initOrGetAxelarSigningClient(config: AxelarSigningClientConfig) { 57 | const { axelarRpcUrl, environment, options, cosmosBasedWalletDetails: walletDetails } = config; 58 | const links: EnvironmentConfigs = getConfigs(environment); 59 | const rpc: string = axelarRpcUrl || links.axelarRpcUrl; 60 | const tmClient = await Tendermint34Client.connect(rpc); 61 | const prefix = "axelar"; 62 | 63 | let wallet; 64 | if (walletDetails.mnemonic) 65 | wallet = await Wallet.fromMnemonic(walletDetails.mnemonic, { prefix }); 66 | else if (walletDetails.offlineSigner) wallet = walletDetails.offlineSigner; 67 | else throw "you need to pass in either a wallet mnemonic string or offline signer"; 68 | 69 | const [account] = await wallet.getAccounts(); 70 | 71 | const registry = options.registry || new Registry(); 72 | registerMultisigTxTypes(registry); 73 | registerAxelarnetTxTypes(registry); 74 | registerEvmTxTypes(registry); 75 | registerNexusTxTypes(registry); 76 | const aminoTypes = options.aminoTypes || new AminoTypes(createAxelarAminoConverters()); 77 | const newOpts = { ...options, registry, aminoTypes }; 78 | 79 | return new AxelarSigningClient(tmClient, wallet, account.address, newOpts); 80 | } 81 | 82 | public signThenBroadcast( 83 | messages: readonly EncodeObject[], 84 | fee: number | StdFee | "auto", 85 | memo?: string 86 | ): Promise { 87 | return super.signAndBroadcast(this.signerAddress, messages, fee, memo); 88 | } 89 | 90 | public async signAndGetTxBytes( 91 | messages: readonly EncodeObject[], 92 | fee: StdFee, 93 | memo: string, 94 | explicitSignerData?: SignerData 95 | ): Promise { 96 | const txRaw = await super.sign(this.signerAddress, messages, fee, memo, explicitSignerData); 97 | return TxRaw.encode(txRaw).finish(); 98 | } 99 | } 100 | 101 | export * from "./const"; 102 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/types/AxelarnetTxTypes.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CallContractRequest, 3 | ConfirmDepositRequest, 4 | ExecutePendingTransfersRequest, 5 | RegisterIBCPathRequest, 6 | AddCosmosBasedChainRequest, 7 | LinkRequest, 8 | RegisterAssetRequest, 9 | RouteIBCTransfersRequest, 10 | RegisterFeeCollectorRequest, 11 | RouteMessageRequest, 12 | protobufPackage, 13 | } from "@axelar-network/axelarjs-types/axelar/axelarnet/v1beta1/tx"; 14 | import { Registry } from "@cosmjs/proto-signing"; 15 | 16 | const TxTypeUrlMap = { 17 | AxelarnetLinkRequest: `/${protobufPackage}.LinkRequest`, 18 | AxelarnetCallContractRequest: `/${protobufPackage}.CallContractRequest`, 19 | AxelarnetConfirmDepositRequest: `/${protobufPackage}.ConfirmDepositRequest`, 20 | AxelarnetExecutePendingTransfersRequest: `/${protobufPackage}.ExecutePendingTransfersRequest`, 21 | AxelarnetRegisterIBCPathRequest: `/${protobufPackage}.RegisterIBCPathRequest`, 22 | AxelarnetAddCosmosBasedChainRequest: `/${protobufPackage}.AddCosmosBasedChainRequest`, 23 | AxelarnetRegisterAssetRequest: `/${protobufPackage}.RegisterAssetRequest`, 24 | AxelarnetRouteIBCTransfersRequest: `/${protobufPackage}.RouteIBCTransfersRequest`, 25 | AxelarnetRegisterFeeCollectorRequest: `/${protobufPackage}.RegisterFeeCollectorRequest`, 26 | AxelarnetRouteMessageRequest: `/${protobufPackage}.RouteMessageRequest`, 27 | }; 28 | 29 | export const registerAxelarnetTxTypes = (registry: Registry) => { 30 | registry.register(TxTypeUrlMap.AxelarnetLinkRequest, LinkRequest); 31 | registry.register(TxTypeUrlMap.AxelarnetCallContractRequest, CallContractRequest); 32 | registry.register(TxTypeUrlMap.AxelarnetConfirmDepositRequest, ConfirmDepositRequest); 33 | registry.register( 34 | TxTypeUrlMap.AxelarnetExecutePendingTransfersRequest, 35 | ExecutePendingTransfersRequest 36 | ); 37 | registry.register(TxTypeUrlMap.AxelarnetRegisterIBCPathRequest, RegisterIBCPathRequest); 38 | registry.register(TxTypeUrlMap.AxelarnetAddCosmosBasedChainRequest, AddCosmosBasedChainRequest); 39 | registry.register(TxTypeUrlMap.AxelarnetRegisterAssetRequest, RegisterAssetRequest); 40 | registry.register(TxTypeUrlMap.AxelarnetRouteIBCTransfersRequest, RouteIBCTransfersRequest); 41 | registry.register(TxTypeUrlMap.AxelarnetRegisterFeeCollectorRequest, RegisterFeeCollectorRequest); 42 | registry.register(TxTypeUrlMap.AxelarnetRouteMessageRequest, RouteMessageRequest); 43 | }; 44 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/types/EvmTxTypes.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SetGatewayRequest, 3 | ConfirmGatewayTxsRequest, 4 | ConfirmGatewayTxRequest, 5 | ConfirmDepositRequest, 6 | ConfirmTokenRequest, 7 | ConfirmTransferKeyRequest, 8 | LinkRequest, 9 | CreateBurnTokensRequest, 10 | CreateDeployTokenRequest, 11 | CreatePendingTransfersRequest, 12 | CreateTransferOperatorshipRequest, 13 | CreateTransferOwnershipRequest, 14 | SignCommandsRequest, 15 | AddChainRequest, 16 | RetryFailedEventRequest, 17 | protobufPackage, 18 | } from "@axelar-network/axelarjs-types/axelar/evm/v1beta1/tx"; 19 | import { Registry } from "@cosmjs/proto-signing"; 20 | 21 | const TxTypeUrlMap = { 22 | EvmLinkRequest: `/${protobufPackage}.LinkRequest`, 23 | EvmSetGatewayRequest: `/${protobufPackage}.SetGatewayRequest`, 24 | EvmConfirmGatewayTxsRequest: `/${protobufPackage}.ConfirmGatewayTxsRequest`, 25 | EvmConfirmGatewayTxRequest: `/${protobufPackage}.ConfirmGatewayTxRequest`, 26 | EvmConfirmDepositRequest: `/${protobufPackage}.ConfirmDepositRequest`, 27 | EvmConfirmTokenRequest: `/${protobufPackage}.ConfirmTokenRequest`, 28 | EvmConfirmTransferKeyRequest: `/${protobufPackage}.ConfirmTransferKeyRequest`, 29 | EvmCreateBurnTokensRequest: `/${protobufPackage}.CreateBurnTokensRequest`, 30 | EvmCreateDeployTokenRequest: `/${protobufPackage}.CreateDeployTokenRequest`, 31 | EvmCreatePendingTransfersRequest: `/${protobufPackage}.CreatePendingTransfersRequest`, 32 | EvmCreateTransferOperatorshipRequest: `/${protobufPackage}.CreateTransferOperatorshipRequest`, 33 | EvmCreateTransferOwnershipRequest: `/${protobufPackage}.CreateTransferOwnershipRequest`, 34 | EvmSignCommandsRequest: `/${protobufPackage}.SignCommandsRequest`, 35 | EvmAddChainRequest: `/${protobufPackage}.AddChainRequest`, 36 | EvmRetryFailedEventRequest: `/${protobufPackage}.RetryFailedEventRequest`, 37 | }; 38 | 39 | export const registerEvmTxTypes = (registry: Registry) => { 40 | registry.register(TxTypeUrlMap.EvmLinkRequest, LinkRequest); 41 | registry.register(TxTypeUrlMap.EvmSetGatewayRequest, SetGatewayRequest); 42 | registry.register(TxTypeUrlMap.EvmConfirmGatewayTxsRequest, ConfirmGatewayTxsRequest); 43 | registry.register(TxTypeUrlMap.EvmConfirmGatewayTxRequest, ConfirmGatewayTxRequest); 44 | registry.register(TxTypeUrlMap.EvmConfirmDepositRequest, ConfirmDepositRequest); 45 | registry.register(TxTypeUrlMap.EvmConfirmTokenRequest, ConfirmTokenRequest); 46 | registry.register(TxTypeUrlMap.EvmConfirmTransferKeyRequest, ConfirmTransferKeyRequest); 47 | registry.register(TxTypeUrlMap.EvmCreateBurnTokensRequest, CreateBurnTokensRequest); 48 | registry.register(TxTypeUrlMap.EvmCreateDeployTokenRequest, CreateDeployTokenRequest); 49 | registry.register(TxTypeUrlMap.EvmCreatePendingTransfersRequest, CreatePendingTransfersRequest); 50 | registry.register( 51 | TxTypeUrlMap.EvmCreateTransferOperatorshipRequest, 52 | CreateTransferOperatorshipRequest 53 | ); 54 | registry.register(TxTypeUrlMap.EvmCreateTransferOwnershipRequest, CreateTransferOwnershipRequest); 55 | registry.register(TxTypeUrlMap.EvmSignCommandsRequest, SignCommandsRequest); 56 | registry.register(TxTypeUrlMap.EvmAddChainRequest, AddChainRequest); 57 | registry.register(TxTypeUrlMap.EvmRetryFailedEventRequest, RetryFailedEventRequest); 58 | }; 59 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/types/MultisigTxTypes.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StartKeygenRequest, 3 | SubmitPubKeyRequest, 4 | SubmitSignatureRequest, 5 | RotateKeyRequest, 6 | KeygenOptInRequest, 7 | KeygenOptOutRequest, 8 | protobufPackage, 9 | } from "@axelar-network/axelarjs-types/axelar/multisig/v1beta1/tx"; 10 | import { Registry } from "@cosmjs/proto-signing"; 11 | 12 | const TxTypeUrlMap = { 13 | MultisigStartKeygenRequest: `/${protobufPackage}.StartKeygenRequest`, 14 | MultisigKeygenOptInRequest: `/${protobufPackage}.KeygenOptInRequest`, 15 | MultisigKeygenOptOutRequest: `/${protobufPackage}.KeygenOptOutRequest`, 16 | MultisigRotateKeyRequest: `/${protobufPackage}.RotateKeyRequest`, 17 | MultisigSubmitPubKeyRequest: `/${protobufPackage}.SubmitPubKeyRequest`, 18 | MultisigSubmitSignatureRequest: `/${protobufPackage}.SubmitSignatureRequest`, 19 | }; 20 | 21 | export const registerMultisigTxTypes = (registry: Registry) => { 22 | registry.register(TxTypeUrlMap.MultisigStartKeygenRequest, StartKeygenRequest); 23 | registry.register(TxTypeUrlMap.MultisigKeygenOptInRequest, KeygenOptInRequest); 24 | registry.register(TxTypeUrlMap.MultisigKeygenOptOutRequest, KeygenOptOutRequest); 25 | registry.register(TxTypeUrlMap.MultisigRotateKeyRequest, RotateKeyRequest); 26 | registry.register(TxTypeUrlMap.MultisigSubmitPubKeyRequest, SubmitPubKeyRequest); 27 | registry.register(TxTypeUrlMap.MultisigSubmitSignatureRequest, SubmitSignatureRequest); 28 | }; 29 | -------------------------------------------------------------------------------- /src/libs/AxelarSigningClient/types/NexusTxTypes.ts: -------------------------------------------------------------------------------- 1 | import { 2 | RegisterChainMaintainerRequest, 3 | DeregisterChainMaintainerRequest, 4 | ActivateChainRequest, 5 | DeactivateChainRequest, 6 | RegisterAssetFeeRequest, 7 | SetTransferRateLimitRequest, 8 | protobufPackage, 9 | } from "@axelar-network/axelarjs-types/axelar/nexus/v1beta1/tx"; 10 | 11 | import { Registry } from "@cosmjs/proto-signing"; 12 | 13 | const TxTypeUrlMap = { 14 | RegisterChainMaintainerRequest: `/${protobufPackage}.RegisterChainMaintainerRequest`, 15 | DeregisterChainMaintainerRequest: `/${protobufPackage}.DeregisterChainMaintainerRequest`, 16 | ActivateChainRequest: `/${protobufPackage}.ActivateChainRequest`, 17 | DeactivateChainRequest: `/${protobufPackage}.DeactivateChainRequest`, 18 | RegisterAssetFeeRequest: `/${protobufPackage}.RegisterAssetFeeRequest`, 19 | SetTransferRateLimitRequest: `/${protobufPackage}.SetTransferRateLimitRequest`, 20 | }; 21 | 22 | export const registerNexusTxTypes = (registry: Registry) => { 23 | registry.register(TxTypeUrlMap.RegisterChainMaintainerRequest, RegisterChainMaintainerRequest); 24 | registry.register( 25 | TxTypeUrlMap.DeregisterChainMaintainerRequest, 26 | DeregisterChainMaintainerRequest 27 | ); 28 | registry.register(TxTypeUrlMap.ActivateChainRequest, ActivateChainRequest); 29 | registry.register(TxTypeUrlMap.DeactivateChainRequest, DeactivateChainRequest); 30 | registry.register(TxTypeUrlMap.RegisterAssetFeeRequest, RegisterAssetFeeRequest); 31 | registry.register(TxTypeUrlMap.SetTransferRateLimitRequest, SetTransferRateLimitRequest); 32 | }; 33 | -------------------------------------------------------------------------------- /src/libs/BigNumberUtils.ts: -------------------------------------------------------------------------------- 1 | import { BigNumber } from "ethers"; 2 | import { parseUnits } from "ethers/lib/utils"; 3 | 4 | export class BigNumberUtils { 5 | public static multiplyToGetWei(bn: BigNumber | string, number: string, units: number): BigNumber { 6 | if (number.toString().split(".")[1].length <= units) { 7 | return BigNumber.from(bn).mul(parseUnits(number, units)); 8 | } else { 9 | const multiplier = Math.pow(10, units); 10 | return BigNumber.from(bn) 11 | .mul(parseUnits((Number(number) * multiplier).toFixed(units), units)) 12 | .div(multiplier); 13 | } 14 | } 15 | 16 | public static divideToGetWei(bn: BigNumber | string, number: string, units: number): BigNumber { 17 | return BigNumber.from(bn).div(parseUnits(number, units)); 18 | } 19 | 20 | public static convertTokenAmount( 21 | ethAmount: BigNumber, 22 | sourceDecimals: number, 23 | targetDecimals: number 24 | ) { 25 | return ethAmount.mul(parseUnits("1", targetDecimals)).div(parseUnits("1", sourceDecimals)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/libs/GatewayTx.ts: -------------------------------------------------------------------------------- 1 | import { Provider, TransactionRequest } from "@ethersproject/abstract-provider"; 2 | import { ethers, Signer, UnsignedTransaction } from "ethers"; 3 | import { TxOption } from "./types"; 4 | 5 | export class GatewayTx { 6 | public txRequest: TransactionRequest; 7 | private provider: Provider; 8 | 9 | constructor(unsignedTx: UnsignedTransaction, provider: ethers.providers.Provider) { 10 | this.txRequest = { 11 | to: unsignedTx.to, 12 | data: unsignedTx.data, 13 | value: unsignedTx.value, 14 | }; 15 | this.provider = provider; 16 | } 17 | 18 | send(signer: Signer, txOption?: TxOption) { 19 | const txRequest = { 20 | ...this.txRequest, 21 | ...txOption, 22 | }; 23 | 24 | return signer.connect(this.provider).sendTransaction(txRequest); 25 | } 26 | 27 | estimateGas() { 28 | return this.provider.estimateGas(this.txRequest); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/AxelarDepositRecoveryAPI.ts: -------------------------------------------------------------------------------- 1 | import { AxelarRecoveryAPIConfig } from "../types"; 2 | import { AxelarRecoveryApi } from "./AxelarRecoveryApi"; 3 | import { ConfirmDepositRequest } from "./interface"; 4 | import { broadcastCosmosTxBytes } from "./client/helpers/cosmos"; 5 | import { loadChains } from "../../chains"; 6 | import { ChainInfo } from "../../chains/types"; 7 | import { 8 | parseConfirmDepositCosmosResponse, 9 | parseConfirmDepositEvmResponse, 10 | } from "./helpers/axelarHelper"; 11 | import { throwIfInvalidChainIds } from "../../utils"; 12 | 13 | export class AxelarDepositRecoveryAPI extends AxelarRecoveryApi { 14 | public constructor(config: AxelarRecoveryAPIConfig) { 15 | super(config); 16 | } 17 | 18 | public async confirmDeposit(params: ConfirmDepositRequest) { 19 | await throwIfInvalidChainIds([params.from], this.environment); 20 | 21 | const chain: ChainInfo = ( 22 | await loadChains({ 23 | environment: this.environment, 24 | }) 25 | ).find((chainInfo) => chainInfo.id.toLowerCase() === params.from.toLowerCase()) as ChainInfo; 26 | if (!chain) throw new Error("cannot find chain" + params.from); 27 | 28 | const txBytes = await this.execRecoveryUrlFetch("/confirm_deposit_tx", { 29 | ...params, 30 | sourceChain: chain.chainIdentifier[this.environment], 31 | module: chain.module, 32 | }); 33 | 34 | const tx = await broadcastCosmosTxBytes(txBytes, this.axelarRpcUrl); 35 | 36 | if (chain.module === "evm") { 37 | return parseConfirmDepositEvmResponse(tx); 38 | } else { 39 | return parseConfirmDepositCosmosResponse(tx); 40 | } 41 | } 42 | 43 | public async routeIBCTransfers() { 44 | const txBytes = await this.execRecoveryUrlFetch("/route_ibc_transfers", { 45 | module: "axelarnet", 46 | }); 47 | 48 | return broadcastCosmosTxBytes(txBytes, this.axelarRpcUrl); 49 | } 50 | } 51 | 52 | /** 53 | * 54 | * TERRA >> AVALANCHE 55 | 56 | echo $KEYRING_PASSWORD | axelard tx axelarnet link avalanche 0x74Ccd7d9F1F40417C6F7fD1151429a2c44c34e6d uusd --from validator 57 | 58 | terrad tx ibc-transfer transfer transfer channel-45 axelar1p69uywznqhd5lrfsa3f0297gnjs7h8vn3qk3awcuhdeu7sxs8dzqkqpm2s --packet-timeout-timestamp 0 5000000uusd --gas-prices 0.15uusd --from ctt_devnet_terra -y -b block 59 | 60 | —> return tx hash: EB2819BD7D43154775FC2BCB1A553363BB509BE866DDE4F29E38F048B8F890CE 61 | 62 | echo $KEYRING_PASSWORD | axelard tx axelarnet confirm-deposit ibc/6F4968A73F90CF7DE6394BF937D6DF7C7D162D74D839C13F53B41157D315E05F axelar1mevnl2qax5ncxe4fguc6weua4j9wlv5ttj298pw6j62u0804uvtqm036cx --from validator 63 | 64 | echo $KEYRING_PASSWORD | axelard tx evm create-pending-transfers avalanche --from validator --gas auto --gas-adjustment 1.2 && echo $KEYRING_PASSWORD | axelard tx evm sign-commands avalanche --from validator --gas auto --gas-adjustment 1.2 65 | 66 | —> get batched command ID: ed04477f0ed591357e8302227db484bd9e7a4684f27715c15e38fcec957bcb5b 67 | 68 | axelard q evm batched-commands avalanche 85daabb34e185ab14e1d91686c96822b00feb25874b4af5f5c936f4c7781abe4 69 | 70 | axelard q evm gateway-address avalanche 71 | 72 | */ 73 | 74 | /** 75 | * ETHEREUM >> TERRA 76 | 77 | axelard tx evm link ethereum terra terra1d5umjr4j0k8c8qtd500mzw2f99kptqqxw2rzph uusd --from validator 78 | 79 | BURNER ETHEREUM ADDR: 0xC74137D1a1Bd05BD06FE2239D9F01eC420AF817e 80 | (NOW DO STUFF ON ETHEREUM) 81 | 82 | txId from ropsten: 0xb6916d034510fef318dff8ac2ec84a45a67e0c061c9d774eed1bdde05a30d1ed 83 | 84 | echo $KEYRING_PASSWORD | axelard tx evm confirm-erc20-deposit ethereum 0xb7b5b570c92d6bbb302428158ed121a492d476c4c28871d586318f22e0afb99f 1598000000 0x62253325aee3b7f43358b3cfcb974589e6109e38 --from validator 85 | 86 | echo $KEYRING_PASSWORD | axelard tx axelarnet execute-pending-transfers --from validator --gas auto --gas-adjustment 1.2 87 | */ 88 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/AxelarTransferAPI.ts: -------------------------------------------------------------------------------- 1 | import { getConfigs } from "../../constants"; 2 | import { 3 | AxelarTransferAPIConfig, 4 | QueryTransferOptions, 5 | QueryTransferResponse, 6 | QueryTransferStatus, 7 | } from "../types"; 8 | import { RestService } from "../../services"; 9 | 10 | export class AxelarTransferApi { 11 | private axelarCrosschainUrl: string; 12 | private axelarnscanUrl: string; 13 | readonly axelarCrosschainApi: RestService; 14 | 15 | public constructor(config: AxelarTransferAPIConfig) { 16 | const environment = config.environment; 17 | const links = getConfigs(environment); 18 | this.axelarCrosschainUrl = links.axelarCrosschainApiUrl; 19 | this.axelarnscanUrl = links.axelarscanUrl; 20 | this.axelarCrosschainApi = new RestService(this.axelarCrosschainUrl); 21 | } 22 | 23 | public async queryTransferStatus( 24 | txHash: string, 25 | options?: QueryTransferOptions 26 | ): Promise { 27 | const response = await this.axelarCrosschainApi 28 | .post("/transfers-status", { 29 | txHash, 30 | ...options, 31 | }) 32 | .catch(() => undefined); 33 | 34 | if (!response) { 35 | return { 36 | success: false, 37 | error: "Axelar Transfer API is not available", 38 | }; 39 | } 40 | if (response.length === 0) { 41 | return { 42 | success: false, 43 | error: "No transfer found", 44 | }; 45 | } 46 | 47 | const transfer = response[0]; 48 | return { 49 | success: true, 50 | data: { 51 | id: transfer.source.id, 52 | status: transfer.status as QueryTransferStatus, 53 | type: transfer.source.type, 54 | amount: transfer.source.amount, 55 | fee: transfer.source.fee, 56 | denom: transfer.source.denom, 57 | senderChain: transfer.source.sender_chain, 58 | senderAddress: transfer.source.sender_address, 59 | recipientChain: transfer.source.recipient_chain, 60 | recipientAddress: transfer.source.recipient_address, 61 | blockExplorerUrl: `${this.axelarnscanUrl}/transfer/${transfer.source.id}`, 62 | blockHeight: transfer.source.height, 63 | }, 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/client/AxelarRpcClient.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from "@cosmjs/tendermint-rpc"; 2 | import { JsonRpcRequest } from "@cosmjs/json-rpc"; 3 | import { retryRpc } from "./helpers/retryRpc"; 4 | import { createRPCClient } from "./helpers/cosmos"; 5 | import { Environment } from "../../types"; 6 | import { getConfigs } from "../../../constants"; 7 | export default class AxelarRpcClient { 8 | private client: HttpClient; 9 | subscribed: boolean; 10 | 11 | private constructor(environment: Environment) { 12 | const rpcUrl: string = getConfigs(environment).axelarRpcUrl; 13 | this.client = createRPCClient(rpcUrl); 14 | } 15 | 16 | static getOrCreate(environment: Environment) { 17 | return new AxelarRpcClient(environment); 18 | } 19 | 20 | query(request: JsonRpcRequest, msToRetries = 3000, maxRetries = 3) { 21 | const retryFunc = () => 22 | this.client.execute(request).then((response) => { 23 | if (request.method === "tx_search") { 24 | return response.result.txs; 25 | } else { 26 | return response.result; 27 | } 28 | }); 29 | const errorHandler = (err: Error) => { 30 | console.log(err); 31 | }; 32 | return retryRpc(retryFunc, errorHandler, msToRetries, maxRetries); 33 | } 34 | 35 | unsubscribe() { 36 | this.client.disconnect(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/client/EVMClient/index.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { TransactionRequest } from "@ethersproject/providers"; 3 | import { EVMClientConfig } from "../../../../libs/types"; 4 | 5 | export default class EVMClient { 6 | private provider: ethers.providers.JsonRpcProvider; 7 | private signer: ethers.providers.JsonRpcSigner | ethers.Wallet; 8 | 9 | constructor(config: EVMClientConfig) { 10 | const { rpcUrl, networkOptions, evmWalletDetails } = config; 11 | const { privateKey, useWindowEthereum, provider } = evmWalletDetails; 12 | if (provider) { 13 | this.provider = provider; 14 | } else { 15 | this.provider = 16 | useWindowEthereum && typeof window !== "undefined" && window?.ethereum 17 | ? new ethers.providers.Web3Provider(window.ethereum, networkOptions) 18 | : provider || new ethers.providers.JsonRpcProvider(rpcUrl, networkOptions); 19 | } 20 | this.signer = privateKey 21 | ? new ethers.Wallet(privateKey).connect(this.provider) 22 | : this.provider.getSigner(); 23 | } 24 | 25 | public getSigner() { 26 | return this.signer; 27 | } 28 | 29 | public async broadcastToGateway(gatewayAddress: string, opts: TransactionRequest) { 30 | const { data, maxFeePerGas, maxPriorityFeePerGas } = opts; 31 | const txRequest: TransactionRequest = { 32 | ...opts, 33 | to: gatewayAddress, 34 | data: `0x${data}`, 35 | maxPriorityFeePerGas: maxPriorityFeePerGas || ethers.utils.parseUnits("30", "gwei"), 36 | maxFeePerGas: maxFeePerGas || ethers.utils.parseUnits("60", "gwei"), 37 | }; 38 | await this.signer.estimateGas(txRequest); 39 | const tx = await this.signer.sendTransaction(txRequest); 40 | await tx.wait(1); 41 | return tx; 42 | } 43 | 44 | public buildUnsignedTx(gatewayAddress: string, opts: TransactionRequest): TransactionRequest { 45 | const { data, maxFeePerGas, maxPriorityFeePerGas } = opts; 46 | const txRequest: TransactionRequest = { 47 | ...opts, 48 | to: gatewayAddress, 49 | data: `0x${data}`, 50 | maxPriorityFeePerGas: maxPriorityFeePerGas || ethers.utils.parseUnits("30", "gwei"), 51 | maxFeePerGas: maxFeePerGas || ethers.utils.parseUnits("60", "gwei"), 52 | }; 53 | return txRequest; 54 | } 55 | 56 | public async broadcastSignedTx(signedTx: string): Promise { 57 | return this.provider.sendTransaction(signedTx); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/client/helpers/cosmos.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from "@cosmjs/tendermint-rpc"; 2 | import { DeliverTxResponse, StargateClient } from "@cosmjs/stargate"; 3 | import { fromBase64 } from "@cosmjs/encoding"; 4 | import { AxelarTxResponse } from "../../../types"; 5 | 6 | export function createRPCClient(rpcUrl: string) { 7 | return new HttpClient(rpcUrl); 8 | } 9 | 10 | export async function broadcastCosmosTx( 11 | base64Tx: string, 12 | rpcUrl: string 13 | ): Promise { 14 | const txBytes = fromBase64(base64Tx); 15 | const cosmjs = await StargateClient.connect(rpcUrl); 16 | return cosmjs.broadcastTx(txBytes).then(convertToAxelarTxResponse); 17 | } 18 | 19 | export async function broadcastCosmosTxBytes( 20 | txBytes: Uint8Array, 21 | rpcUrl: string 22 | ): Promise { 23 | const cosmjs = await StargateClient.connect(rpcUrl); 24 | return cosmjs.broadcastTx(txBytes).then(convertToAxelarTxResponse); 25 | } 26 | 27 | function convertToAxelarTxResponse(response: DeliverTxResponse): AxelarTxResponse { 28 | return { 29 | ...response, 30 | rawLog: response.rawLog || "[]", 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/client/helpers/retryRpc.ts: -------------------------------------------------------------------------------- 1 | export async function retryRpc( 2 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 3 | retryFunc: () => Promise, 4 | errorHandler?: (e: any) => void, 5 | msToRetry = 5000, 6 | maxRetries = 5, 7 | count = 0 8 | ): Promise { 9 | try { 10 | if (count >= maxRetries) return null; 11 | const response = await retryFunc(); 12 | return response; 13 | } catch (e) { 14 | errorHandler && errorHandler(e); 15 | await wait(msToRetry); 16 | return retryRpc(retryFunc, errorHandler, msToRetry, maxRetries, count + 1); 17 | } 18 | } 19 | 20 | export function wait(ms: number) { 21 | return new Promise((resolve) => { 22 | setTimeout(resolve, ms); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/constants/chain/index.ts: -------------------------------------------------------------------------------- 1 | import { rpcMap as testnetRpcMap, networkInfo as testnetNetworkInfo } from "./testnet"; 2 | import { rpcMap as mainnetRpcMap, networkInfo as mainnetNetworkInfo } from "./mainnet"; 3 | 4 | export type RPCInfoType = Record>; 5 | const rpc: RPCInfoType = { 6 | devnet: { 7 | rpcMap: testnetRpcMap, 8 | networkInfo: testnetNetworkInfo, 9 | }, 10 | testnet: { 11 | rpcMap: testnetRpcMap, 12 | networkInfo: testnetNetworkInfo, 13 | }, 14 | mainnet: { 15 | rpcMap: mainnetRpcMap, 16 | networkInfo: mainnetNetworkInfo, 17 | }, 18 | }; 19 | export default rpc; 20 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/constants/chain/mainnet.ts: -------------------------------------------------------------------------------- 1 | import { EvmChain } from "../../../../constants/EvmChain"; 2 | import { Network } from "@ethersproject/networks"; 3 | 4 | export const rpcMap: Partial> = { 5 | [EvmChain.FANTOM]: "https://rpc.ftm.tools", 6 | [EvmChain.POLYGON]: "https://polygon-rpc.com", 7 | [EvmChain.MOONBEAM]: "https://rpc.api.moonbeam.network", 8 | [EvmChain.AVALANCHE]: "https://api.avax.network/ext/bc/C/rpc", 9 | [EvmChain.ETHEREUM]: "https://ethereum.publicnode.com", 10 | [EvmChain.AURORA]: "https://mainnet.aurora.dev", 11 | [EvmChain.BINANCE]: "https://bsc-dataseed.binance.org", 12 | [EvmChain.ARBITRUM]: "https://arb1.arbitrum.io/rpc", 13 | [EvmChain.CELO]: "https://forno.celo.org", 14 | [EvmChain.KAVA]: "https://evm.kava.io", 15 | [EvmChain.FILECOIN]: "https://api.node.glif.io/rpc/v1", 16 | [EvmChain.OPTIMISM]: "https://optimism-mainnet.public.blastapi.io", 17 | [EvmChain.BASE]: "https://developer-access-mainnet.base.org", 18 | [EvmChain.LINEA]: "https://rpc.linea.build", 19 | [EvmChain.POLYGON_ZKEVM]: "https://zkevm.polygonscan.com", 20 | [EvmChain.MANTLE]: "https://rpc.mantle.xyz", 21 | [EvmChain.SCROLL]: "https://rpc.scroll.io", 22 | [EvmChain.CENTRIFUGE]: "https://fullnode.parachain.centrifuge.io", 23 | [EvmChain.IMMUTABLE]: "https://rpc.immutable.com", 24 | [EvmChain.FRAXTAL]: "https://rpc.frax.com", 25 | [EvmChain.BLAST]: "https://rpc.blast.io", 26 | }; 27 | 28 | export const networkInfo: Partial> = { 29 | [EvmChain.FANTOM]: { 30 | chainId: 250, 31 | name: EvmChain.FANTOM, 32 | }, 33 | [EvmChain.BASE]: { 34 | chainId: 8453, 35 | name: EvmChain.BASE, 36 | }, 37 | [EvmChain.FILECOIN]: { 38 | chainId: 314, 39 | name: EvmChain.FILECOIN, 40 | }, 41 | [EvmChain.POLYGON]: { 42 | chainId: 137, 43 | name: EvmChain.POLYGON, 44 | }, 45 | [EvmChain.MOONBEAM]: { 46 | chainId: 1284, 47 | name: EvmChain.MOONBEAM, 48 | }, 49 | [EvmChain.AVALANCHE]: { 50 | chainId: 43114, 51 | name: EvmChain.AVALANCHE, 52 | }, 53 | [EvmChain.ETHEREUM]: { 54 | chainId: 1, 55 | name: EvmChain.ETHEREUM, 56 | }, 57 | [EvmChain.AURORA]: { 58 | chainId: 1313161554, 59 | name: EvmChain.AURORA, 60 | }, 61 | [EvmChain.BINANCE]: { 62 | chainId: 56, 63 | name: EvmChain.BINANCE, 64 | }, 65 | [EvmChain.ARBITRUM]: { 66 | chainId: 42161, 67 | name: EvmChain.ARBITRUM, 68 | }, 69 | [EvmChain.CELO]: { 70 | chainId: 42220, 71 | name: EvmChain.CELO, 72 | }, 73 | [EvmChain.KAVA]: { 74 | chainId: 2222, 75 | name: EvmChain.KAVA, 76 | }, 77 | [EvmChain.OPTIMISM]: { 78 | chainId: 10, 79 | name: EvmChain.OPTIMISM, 80 | }, 81 | [EvmChain.LINEA]: { 82 | chainId: 59144, 83 | name: EvmChain.LINEA, 84 | }, 85 | [EvmChain.POLYGON_ZKEVM]: { 86 | chainId: 1101, 87 | name: EvmChain.POLYGON_ZKEVM, 88 | }, 89 | [EvmChain.MANTLE]: { 90 | chainId: 5000, 91 | name: EvmChain.MANTLE, 92 | }, 93 | [EvmChain.SCROLL]: { 94 | chainId: 534352, 95 | name: EvmChain.SCROLL, 96 | }, 97 | [EvmChain.CENTRIFUGE]: { 98 | chainId: 2031, 99 | name: EvmChain.CENTRIFUGE, 100 | }, 101 | [EvmChain.IMMUTABLE]: { 102 | chainId: 13371, 103 | name: EvmChain.IMMUTABLE, 104 | }, 105 | [EvmChain.FRAXTAL]: { 106 | chainId: 252, 107 | name: EvmChain.FRAXTAL, 108 | }, 109 | [EvmChain.BLAST]: { 110 | chainId: 81457, 111 | name: EvmChain.BLAST, 112 | }, 113 | }; 114 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/constants/chain/testnet.ts: -------------------------------------------------------------------------------- 1 | import { EvmChain } from "../../../../constants/EvmChain"; 2 | import { Network } from "@ethersproject/networks"; 3 | 4 | export const rpcMap: Record = { 5 | [EvmChain.FANTOM]: "https://rpc.testnet.fantom.network", 6 | [EvmChain.POLYGON]: "https://polygon-mumbai-bor-rpc.publicnode.com", 7 | [EvmChain.MOONBEAM]: "https://rpc.api.moonbase.moonbeam.network", 8 | [EvmChain.AVALANCHE]: "https://api.avax-test.network/ext/bc/C/rpc", 9 | [EvmChain.AURORA]: "https://testnet.aurora.dev", 10 | [EvmChain.BINANCE]: "https://data-seed-prebsc-1-s1.binance.org:8545", 11 | [EvmChain.CELO]: "https://alfajores-forno.celo-testnet.org", 12 | [EvmChain.KAVA]: "https://evm.testnet.kava.io", 13 | "filecoin-2": "https://rpc.ankr.com/filecoin_testnet", 14 | [EvmChain.POLYGON_ZKEVM]: "https://testnet-zkevm.polygonscan.com", 15 | [EvmChain.SCROLL]: "https://sepolia-rpc.scroll.io", 16 | [EvmChain.IMMUTABLE]: "https://rpc.testnet.immutable.com", 17 | [EvmChain.SEPOLIA]: "https://1rpc.io/sepolia", 18 | [EvmChain.ARBITRUM_SEPOLIA]: "https://sepolia-rollup.arbitrum.io/rpc", 19 | [EvmChain.CENTRIFUGE_TESTNET]: 20 | "https://node-7118620155331796992.gx.onfinality.io/jsonrpc?apikey=00538f2d-6297-44e3-8812-4b9d579524b2", 21 | [EvmChain.FRAXTAL]: "https://rpc.testnet.frax.com", 22 | [EvmChain.BLAST_SEPOLIA]: "https://sepolia.blast.io", 23 | [EvmChain.BASE_SEPOLIA]: "https://sepolia.base.org", 24 | [EvmChain.OPTIMISM_SEPOLIA]: "https://sepolia.optimism.io", 25 | [EvmChain.MANTLE_SEPOLIA]: "https://rpc.sepolia.mantle.xyz", 26 | [EvmChain.POLYGON_SEPOLIA]: "https://rpc-amoy.polygon.technology", 27 | [EvmChain.LINEA_SEPOLIA]: "https://rpc.sepolia.linea.build", 28 | }; 29 | 30 | export const networkInfo: Record = { 31 | [EvmChain.FANTOM]: { 32 | chainId: 4002, 33 | name: EvmChain.FANTOM, 34 | }, 35 | [EvmChain.POLYGON]: { 36 | chainId: 80001, 37 | name: EvmChain.POLYGON, 38 | }, 39 | [EvmChain.POLYGON_ZKEVM]: { 40 | chainId: 1442, 41 | name: EvmChain.POLYGON_ZKEVM, 42 | }, 43 | [EvmChain.MOONBEAM]: { 44 | chainId: 1287, 45 | name: EvmChain.MOONBEAM, 46 | }, 47 | [EvmChain.AVALANCHE]: { 48 | chainId: 43113, 49 | name: EvmChain.AVALANCHE, 50 | }, 51 | [EvmChain.AURORA]: { 52 | chainId: 1313161555, 53 | name: EvmChain.AURORA, 54 | }, 55 | [EvmChain.BINANCE]: { 56 | chainId: 97, 57 | name: EvmChain.BINANCE, 58 | }, 59 | [EvmChain.CELO]: { 60 | chainId: 44787, 61 | name: EvmChain.CELO, 62 | }, 63 | [EvmChain.KAVA]: { 64 | chainId: 2221, 65 | name: EvmChain.KAVA, 66 | }, 67 | "filecoin-2": { 68 | chainId: 314159, 69 | name: EvmChain.FILECOIN, 70 | }, 71 | [EvmChain.LINEA]: { 72 | chainId: 59140, 73 | name: EvmChain.LINEA, 74 | }, 75 | [EvmChain.SCROLL]: { 76 | chainId: 534351, 77 | name: EvmChain.SCROLL, 78 | }, 79 | [EvmChain.SEPOLIA]: { 80 | chainId: 11155111, 81 | name: EvmChain.SEPOLIA, 82 | }, 83 | [EvmChain.ARBITRUM_SEPOLIA]: { 84 | chainId: 421614, 85 | name: EvmChain.ARBITRUM_SEPOLIA, 86 | }, 87 | [EvmChain.CENTRIFUGE_TESTNET]: { 88 | chainId: 2090, 89 | name: "centrifuge", 90 | }, 91 | [EvmChain.IMMUTABLE]: { 92 | chainId: 13473, 93 | name: EvmChain.IMMUTABLE, 94 | }, 95 | [EvmChain.FRAXTAL]: { 96 | chainId: 2522, 97 | name: EvmChain.FRAXTAL, 98 | }, 99 | [EvmChain.BASE_SEPOLIA]: { 100 | chainId: 84532, 101 | name: EvmChain.BASE_SEPOLIA, 102 | }, 103 | [EvmChain.BLAST_SEPOLIA]: { 104 | chainId: 168587773, 105 | name: EvmChain.BLAST_SEPOLIA, 106 | }, 107 | [EvmChain.MANTLE_SEPOLIA]: { 108 | chainId: 5003, 109 | name: EvmChain.MANTLE_SEPOLIA, 110 | }, 111 | [EvmChain.OPTIMISM_SEPOLIA]: { 112 | chainId: 11155420, 113 | name: EvmChain.OPTIMISM_SEPOLIA, 114 | }, 115 | [EvmChain.POLYGON_SEPOLIA]: { 116 | chainId: 80002, 117 | name: EvmChain.POLYGON_SEPOLIA, 118 | }, 119 | [EvmChain.LINEA_SEPOLIA]: { 120 | chainId: 59141, 121 | name: EvmChain.LINEA_SEPOLIA, 122 | }, 123 | }; 124 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/constants/cosmosGasReceiverOptions.ts: -------------------------------------------------------------------------------- 1 | export const COSMOS_GAS_RECEIVER_OPTIONS = { 2 | "devnet-amplifier": "axelar1zl3rxpp70lmte2xr6c4lgske2fyuj3hupcsvcd", 3 | testnet: "axelar1zl3rxpp70lmte2xr6c4lgske2fyuj3hupcsvcd", 4 | mainnet: "axelar1aythygn6z5thymj6tmzfwekzh05ewg3l7d6y89", 5 | } as const; 6 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/constants/error.ts: -------------------------------------------------------------------------------- 1 | import { EvmChain } from "../../../constants/EvmChain"; 2 | import { ExecuteParams } from "../AxelarRecoveryApi"; 3 | 4 | const metamaskErrorMsg = (e: any) => e.data?.message; 5 | 6 | const ethersErrorMsg = (e: any) => e.error?.reason; 7 | 8 | const generalErrorMsg = (e: any) => e.message; 9 | 10 | export const ErrorMsg = (e: any) => ethersErrorMsg(e) || metamaskErrorMsg(e) || generalErrorMsg(e); 11 | 12 | export const InvalidTransactionError = (chain: EvmChain | string) => ({ 13 | success: false, 14 | error: `Couldn't find a transaction on ${chain}`, 15 | }); 16 | 17 | export const NotGMPTransactionError = () => ({ 18 | success: false, 19 | error: "Not GMP transaction", 20 | }); 21 | 22 | export const AlreadyExecutedError = () => ({ 23 | success: false, 24 | error: "Already executed", 25 | }); 26 | 27 | export const GasPriceAPIError = () => ({ 28 | success: false, 29 | error: "Couldn't query the gas price", 30 | }); 31 | 32 | export const AlreadyPaidGasFeeError = () => ({ 33 | success: false, 34 | error: "Already paid sufficient gas fee", 35 | }); 36 | 37 | export const ContractCallError = (e: any) => ({ 38 | success: false, 39 | error: ErrorMsg(e), 40 | }); 41 | 42 | export const InvalidGasTokenError = () => ({ 43 | success: false, 44 | error: "Invalid gas token address", 45 | }); 46 | 47 | export const UnsupportedGasTokenError = (gasTokenAddress: string) => ({ 48 | success: false, 49 | error: `Token address ${gasTokenAddress} is not supported`, 50 | }); 51 | 52 | export const NotApprovedError = () => ({ 53 | success: false, 54 | error: "Transaction has not approved yet", 55 | }); 56 | 57 | export const GMPQueryError = () => ({ 58 | success: false, 59 | error: "Couldn't query the transaction details", 60 | }); 61 | 62 | export const ExecutionRevertedError = (params: ExecuteParams) => { 63 | const { 64 | commandId, 65 | sourceChain, 66 | sourceAddress, 67 | payload, 68 | symbol, 69 | amount, 70 | isContractCallWithToken, 71 | } = params; 72 | const functionName = isContractCallWithToken ? "executeWithToken" : "execute"; 73 | return { 74 | success: false, 75 | error: `Transaction execution was reverted. Please check the implementation of the destination contract's ${functionName} function.`, 76 | data: { 77 | functionName, 78 | args: { 79 | commandId, 80 | sourceChain, 81 | sourceAddress, 82 | payload, 83 | symbol, 84 | amount, 85 | }, 86 | }, 87 | }; 88 | }; 89 | 90 | export const InsufficientFundsError = (params: ExecuteParams) => { 91 | const { 92 | commandId, 93 | sourceChain, 94 | sourceAddress, 95 | payload, 96 | symbol, 97 | amount, 98 | isContractCallWithToken, 99 | } = params; 100 | const functionName = isContractCallWithToken ? "executeWithToken" : "execute"; 101 | return { 102 | success: false, 103 | error: "Insufficient funds to pay for transaction gas cost", 104 | data: { 105 | functionName, 106 | args: { 107 | commandId, 108 | sourceChain, 109 | sourceAddress, 110 | payload, 111 | symbol, 112 | amount, 113 | }, 114 | }, 115 | }; 116 | }; 117 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/constants/s3.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | mainnet: "https://axelar-mainnet.s3.us-east-2.amazonaws.com/mainnet-config.json", 3 | testnet: "https://axelar-testnet.s3.us-east-2.amazonaws.com/testnet-config.json", 4 | "devnet-amplifier": "https://axelar-testnet.s3.us-east-2.amazonaws.com/testnet-config.json", //same as testnet for now 5 | }; 6 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/helpers/contractCallHelper.ts: -------------------------------------------------------------------------------- 1 | import { Contract, ContractReceipt, ContractTransaction } from "ethers"; 2 | import { ExecuteParams } from "../AxelarRecoveryApi"; 3 | 4 | export enum CALL_EXECUTE_ERROR { 5 | REVERT = "REVERT", 6 | INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS", 7 | } 8 | 9 | export async function callExecute( 10 | params: ExecuteParams, 11 | contract: Contract, 12 | gasLimitBuffer = 0 13 | ): Promise { 14 | const { 15 | commandId, 16 | isContractCallWithToken, 17 | payload, 18 | sourceAddress, 19 | sourceChain, 20 | amount, 21 | symbol, 22 | } = params; 23 | 24 | let txReceipt: ContractReceipt | undefined; 25 | if (isContractCallWithToken) { 26 | // Checking if the destination contract call reverted 27 | const estimatedGas = await contract.estimateGas 28 | .executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount) 29 | .catch(() => undefined); 30 | if (!estimatedGas) throw new Error(CALL_EXECUTE_ERROR.REVERT); 31 | 32 | txReceipt = contract 33 | .executeWithToken(commandId, sourceChain, sourceAddress, payload, symbol, amount, { 34 | gasLimit: estimatedGas.add(gasLimitBuffer), 35 | }) 36 | .then((tx: ContractTransaction) => tx.wait()) 37 | .catch(() => undefined); 38 | } else { 39 | // Checking if the destination contract call reverted 40 | const estimatedGas = await contract.estimateGas 41 | .execute(commandId, sourceChain, sourceAddress, payload) 42 | .catch(() => undefined); 43 | if (!estimatedGas) throw new Error(CALL_EXECUTE_ERROR.REVERT); 44 | 45 | txReceipt = contract 46 | .execute(commandId, sourceChain, sourceAddress, payload, { 47 | gasLimit: estimatedGas.add(gasLimitBuffer), 48 | }) 49 | .then((tx: ContractTransaction) => tx.wait()) 50 | .catch(() => undefined); 51 | } 52 | 53 | if (!txReceipt) throw new Error(CALL_EXECUTE_ERROR.INSUFFICIENT_FUNDS); 54 | return txReceipt; 55 | } 56 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/helpers/getCommandId.ts: -------------------------------------------------------------------------------- 1 | import { arrayify, concat, hexlify, hexZeroPad, keccak256 } from "ethers/lib/utils"; 2 | 3 | const stringToCharcodeArray = (text: string) => Array.from(text, (char) => char.charCodeAt(0)); 4 | 5 | // This function is specifically designed for use with EVM-based chains. Its behavior may not be as expected if used with Cosmos-based chains or other types of chains. 6 | export const getCommandId = (messageId: string, sourceEventIndex: number, chainId: number) => { 7 | if (messageId.includes("-")) { 8 | return keccak256(concat([stringToCharcodeArray(messageId), hexlify(chainId)])); 9 | } else { 10 | return keccak256( 11 | concat([ 12 | messageId, 13 | arrayify(hexZeroPad(hexlify(sourceEventIndex), 8)).reverse(), 14 | hexlify(chainId), 15 | ]) 16 | ); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./axelarHelper"; 2 | export * from "./contractEventHelper"; 3 | export * from "./contractCallHelper"; 4 | export * from "./getCommandId"; 5 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/helpers/mappers.ts: -------------------------------------------------------------------------------- 1 | import { BatchedCommandsResponse } from "@axelar-network/axelarjs-types/axelar/evm/v1beta1/query"; 2 | import { BatchedCommandsStatus } from "@axelar-network/axelarjs-types/axelar/evm/v1beta1/types"; 3 | import { BatchedCommandsAxelarscanResponse } from "../AxelarRecoveryApi"; 4 | 5 | /** 6 | * core returns a number response that's typed to an enum: 7 | "export declare enum BatchedCommandsStatus { 8 | BATCHED_COMMANDS_STATUS_UNSPECIFIED = 0, 9 | BATCHED_COMMANDS_STATUS_SIGNING = 1, 10 | BATCHED_COMMANDS_STATUS_ABORTED = 2, 11 | BATCHED_COMMANDS_STATUS_SIGNED = 3, 12 | UNRECOGNIZED = -1 13 | }" 14 | * axelarscan response has the actual text response, so this method retrieves the text 15 | * sample input: 3 16 | * expected output: BATCHED_COMMANDS_STATUS_SIGNED 17 | */ 18 | const getStatusKey = (obj: any, value: BatchedCommandsStatus): string => { 19 | const keyIndex = Object.values(obj).indexOf(value); 20 | return Object.keys(obj)[keyIndex]; 21 | }; 22 | 23 | export const mapIntoAxelarscanResponseType = ( 24 | input: BatchedCommandsResponse, 25 | chainId: string 26 | ): BatchedCommandsAxelarscanResponse => ({ 27 | ...input, 28 | key_id: input.keyId, 29 | execute_data: input.executeData, 30 | prev_batched_commands_id: input.prevBatchedCommandsId, 31 | command_ids: input.commandIds, 32 | batch_id: input.id, 33 | chain: chainId, 34 | status: getStatusKey(BatchedCommandsStatus, input.status), 35 | }); 36 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/helpers/stellarHelper.ts: -------------------------------------------------------------------------------- 1 | import { nativeToScVal, Address } from "@stellar/stellar-sdk"; 2 | 3 | export function tokenToScVal(tokenAddress: string, tokenAmount: string) { 4 | return nativeToScVal( 5 | { 6 | address: Address.fromString(tokenAddress), 7 | amount: tokenAmount, 8 | }, 9 | { 10 | type: { 11 | address: ["symbol", "address"], 12 | amount: ["symbol", "i128"], 13 | }, 14 | } 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/helpers/xrplHelper.ts: -------------------------------------------------------------------------------- 1 | import { xrpToDrops } from "xrpl"; 2 | 3 | export function parseToken(token: string, amount: string) { 4 | if (token === "XRP") { 5 | return xrpToDrops(amount).toString(); 6 | } else { 7 | const [currency, issuer] = token.split("."); 8 | return { 9 | currency, 10 | issuer, 11 | value: amount, 12 | }; 13 | } 14 | } 15 | 16 | export function hex(value: string) { 17 | return Buffer.from(value).toString("hex"); 18 | } 19 | 20 | export function convertRpcUrltoWssUrl(rpcUrl: string) { 21 | const url = new URL(rpcUrl); 22 | url.protocol = "wss:"; 23 | url.port = ""; // Remove port 24 | return url.toString(); 25 | } 26 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AxelarDepositRecoveryAPI"; 2 | export * from "./AxelarGMPRecoveryAPI"; 3 | export * from "./constants/error"; 4 | export * from "./AxelarRecoveryApi"; 5 | export * from "./AxelarTransferAPI"; 6 | -------------------------------------------------------------------------------- /src/libs/TransactionRecoveryApi/interface/index.ts: -------------------------------------------------------------------------------- 1 | import { BigNumberish } from "ethers"; 2 | 3 | export interface AxelarResponse { 4 | status: boolean; 5 | data: T; 6 | error: string | null; 7 | } 8 | 9 | export enum RetryErrorRecovery { 10 | REFETCH = "refetch", 11 | REBROADCAST = "rebroadcast", 12 | SKIP = "skip", 13 | } 14 | 15 | export interface AxelarRetryResponse extends AxelarResponse { 16 | retry?: RetryErrorRecovery; 17 | } 18 | 19 | export interface ConfirmDepositResponse { 20 | hash: string; 21 | chain: string; 22 | amount: BigNumberish; 23 | depositTxHash?: string | null; 24 | depositAddress: string; 25 | depositToken: string; 26 | height: number; 27 | commandId?: string; 28 | } 29 | 30 | export interface ConfirmDepositRequest { 31 | hash: string; 32 | from: string; //chain name 33 | depositAddress: string; 34 | denom: string; //asset common key 35 | } 36 | -------------------------------------------------------------------------------- /src/libs/abi/IAxelarExecutable.ts: -------------------------------------------------------------------------------- 1 | export const IAxelarExecutable = { 2 | _format: "hh-sol-artifact-1", 3 | contractName: "IAxelarExecutable", 4 | sourceName: "contracts/interfaces/IAxelarExecutable.sol", 5 | abi: [ 6 | { 7 | inputs: [], 8 | name: "NotApprovedByGateway", 9 | type: "error", 10 | }, 11 | { 12 | inputs: [ 13 | { 14 | internalType: "bytes32", 15 | name: "commandId", 16 | type: "bytes32", 17 | }, 18 | { 19 | internalType: "string", 20 | name: "sourceChain", 21 | type: "string", 22 | }, 23 | { 24 | internalType: "string", 25 | name: "sourceAddress", 26 | type: "string", 27 | }, 28 | { 29 | internalType: "bytes", 30 | name: "payload", 31 | type: "bytes", 32 | }, 33 | ], 34 | name: "execute", 35 | outputs: [], 36 | stateMutability: "nonpayable", 37 | type: "function", 38 | }, 39 | { 40 | inputs: [ 41 | { 42 | internalType: "bytes32", 43 | name: "commandId", 44 | type: "bytes32", 45 | }, 46 | { 47 | internalType: "string", 48 | name: "sourceChain", 49 | type: "string", 50 | }, 51 | { 52 | internalType: "string", 53 | name: "sourceAddress", 54 | type: "string", 55 | }, 56 | { 57 | internalType: "bytes", 58 | name: "payload", 59 | type: "bytes", 60 | }, 61 | { 62 | internalType: "string", 63 | name: "tokenSymbol", 64 | type: "string", 65 | }, 66 | { 67 | internalType: "uint256", 68 | name: "amount", 69 | type: "uint256", 70 | }, 71 | ], 72 | name: "executeWithToken", 73 | outputs: [], 74 | stateMutability: "nonpayable", 75 | type: "function", 76 | }, 77 | { 78 | inputs: [], 79 | name: "gateway", 80 | outputs: [ 81 | { 82 | internalType: "contract IAxelarGateway", 83 | name: "", 84 | type: "address", 85 | }, 86 | ], 87 | stateMutability: "view", 88 | type: "function", 89 | }, 90 | ], 91 | bytecode: "0x", 92 | deployedBytecode: "0x", 93 | linkReferences: {}, 94 | deployedLinkReferences: {}, 95 | }; 96 | 97 | export default IAxelarExecutable; 98 | -------------------------------------------------------------------------------- /src/libs/abi/erc20Abi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "name", 6 | "outputs": [ 7 | { 8 | "name": "", 9 | "type": "string" 10 | } 11 | ], 12 | "payable": false, 13 | "stateMutability": "view", 14 | "type": "function" 15 | }, 16 | { 17 | "constant": false, 18 | "inputs": [ 19 | { 20 | "name": "_spender", 21 | "type": "address" 22 | }, 23 | { 24 | "name": "_value", 25 | "type": "uint256" 26 | } 27 | ], 28 | "name": "approve", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "bool" 33 | } 34 | ], 35 | "payable": false, 36 | "stateMutability": "nonpayable", 37 | "type": "function" 38 | }, 39 | { 40 | "constant": true, 41 | "inputs": [], 42 | "name": "totalSupply", 43 | "outputs": [ 44 | { 45 | "name": "", 46 | "type": "uint256" 47 | } 48 | ], 49 | "payable": false, 50 | "stateMutability": "view", 51 | "type": "function" 52 | }, 53 | { 54 | "constant": false, 55 | "inputs": [ 56 | { 57 | "name": "_from", 58 | "type": "address" 59 | }, 60 | { 61 | "name": "_to", 62 | "type": "address" 63 | }, 64 | { 65 | "name": "_value", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "transferFrom", 70 | "outputs": [ 71 | { 72 | "name": "", 73 | "type": "bool" 74 | } 75 | ], 76 | "payable": false, 77 | "stateMutability": "nonpayable", 78 | "type": "function" 79 | }, 80 | { 81 | "constant": true, 82 | "inputs": [], 83 | "name": "decimals", 84 | "outputs": [ 85 | { 86 | "name": "", 87 | "type": "uint8" 88 | } 89 | ], 90 | "payable": false, 91 | "stateMutability": "view", 92 | "type": "function" 93 | }, 94 | { 95 | "constant": true, 96 | "inputs": [ 97 | { 98 | "name": "_owner", 99 | "type": "address" 100 | } 101 | ], 102 | "name": "balanceOf", 103 | "outputs": [ 104 | { 105 | "name": "balance", 106 | "type": "uint256" 107 | } 108 | ], 109 | "payable": false, 110 | "stateMutability": "view", 111 | "type": "function" 112 | }, 113 | { 114 | "constant": true, 115 | "inputs": [], 116 | "name": "symbol", 117 | "outputs": [ 118 | { 119 | "name": "", 120 | "type": "string" 121 | } 122 | ], 123 | "payable": false, 124 | "stateMutability": "view", 125 | "type": "function" 126 | }, 127 | { 128 | "constant": false, 129 | "inputs": [ 130 | { 131 | "name": "_to", 132 | "type": "address" 133 | }, 134 | { 135 | "name": "_value", 136 | "type": "uint256" 137 | } 138 | ], 139 | "name": "transfer", 140 | "outputs": [ 141 | { 142 | "name": "", 143 | "type": "bool" 144 | } 145 | ], 146 | "payable": false, 147 | "stateMutability": "nonpayable", 148 | "type": "function" 149 | }, 150 | { 151 | "constant": true, 152 | "inputs": [ 153 | { 154 | "name": "_owner", 155 | "type": "address" 156 | }, 157 | { 158 | "name": "_spender", 159 | "type": "address" 160 | } 161 | ], 162 | "name": "allowance", 163 | "outputs": [ 164 | { 165 | "name": "", 166 | "type": "uint256" 167 | } 168 | ], 169 | "payable": false, 170 | "stateMutability": "view", 171 | "type": "function" 172 | }, 173 | { 174 | "payable": true, 175 | "stateMutability": "payable", 176 | "type": "fallback" 177 | }, 178 | { 179 | "anonymous": false, 180 | "inputs": [ 181 | { 182 | "indexed": true, 183 | "name": "owner", 184 | "type": "address" 185 | }, 186 | { 187 | "indexed": true, 188 | "name": "spender", 189 | "type": "address" 190 | }, 191 | { 192 | "indexed": false, 193 | "name": "value", 194 | "type": "uint256" 195 | } 196 | ], 197 | "name": "Approval", 198 | "type": "event" 199 | }, 200 | { 201 | "anonymous": false, 202 | "inputs": [ 203 | { 204 | "indexed": true, 205 | "name": "from", 206 | "type": "address" 207 | }, 208 | { 209 | "indexed": true, 210 | "name": "to", 211 | "type": "address" 212 | }, 213 | { 214 | "indexed": false, 215 | "name": "value", 216 | "type": "uint256" 217 | } 218 | ], 219 | "name": "Transfer", 220 | "type": "event" 221 | } 222 | ] 223 | -------------------------------------------------------------------------------- /src/libs/fee/getL1Fee.spec.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import { rpcMap } from "../TransactionRecoveryApi/constants/chain/mainnet"; 3 | import { Environment, EstimateL1FeeParams } from "../types"; 4 | import { getL1FeeForL2 } from "./getL1Fee"; 5 | import { AxelarQueryAPI } from "../AxelarQueryAPI"; 6 | import { DEFAULT_L1_EXECUTE_DATA } from "../../constants"; 7 | 8 | const env = Environment.MAINNET; 9 | 10 | async function getL1Fee(srcChain: string, destChain: string) { 11 | const queryAPI = new AxelarQueryAPI({ environment: env }); 12 | 13 | const { destToken, l2_type } = await queryAPI.getNativeGasBaseFee(srcChain, destChain); 14 | 15 | const params: EstimateL1FeeParams = { 16 | executeData: DEFAULT_L1_EXECUTE_DATA, 17 | destChain, 18 | l1GasPrice: destToken.l1_gas_price_in_units!, 19 | l1GasOracleAddress: destToken.l1_gas_oracle_address, 20 | l2Type: l2_type, 21 | }; 22 | 23 | const provider = new ethers.providers.JsonRpcProvider(rpcMap[destChain]); 24 | const fee = await getL1FeeForL2(provider, params); 25 | 26 | return fee; 27 | } 28 | 29 | describe("getL1Fee", () => { 30 | it("query l1 fee for l2 chains should work", async () => { 31 | const srcChain = "ethereum"; 32 | const destChainsThatShouldIncludeL1Fees = ["optimism", "blast", "fraxtal", "base", "scroll"]; 33 | 34 | const l1FeeQueries = destChainsThatShouldIncludeL1Fees.map((destChain) => 35 | getL1Fee(srcChain, destChain) 36 | ); 37 | 38 | const fees = await Promise.all(l1FeeQueries); 39 | 40 | expect(fees.length).toBe(destChainsThatShouldIncludeL1Fees.length); 41 | expect(fees.every((fee) => fee.gt(0))).toBe(true); 42 | 43 | const destChainsThatShouldNotIncludeL1Fees = ["mantle", "arbitrum"]; 44 | 45 | const ZeroL1FeeQueries = destChainsThatShouldNotIncludeL1Fees.map((destChain) => 46 | getL1Fee(srcChain, destChain) 47 | ); 48 | 49 | const fees2 = await Promise.all(ZeroL1FeeQueries); 50 | 51 | expect(fees2.length).toBe(destChainsThatShouldNotIncludeL1Fees.length); 52 | expect(fees2.every((fee) => fee.eq(0))).toBe(true); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /src/libs/fee/getL1Fee.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unsafe-return */ 2 | 3 | import { BigNumber, ethers } from "ethers"; 4 | import { EstimateL1FeeParams } from "../types"; 5 | 6 | const ABI = { 7 | Optimism: ["function getL1Fee(bytes executeData) view returns (uint256)"], 8 | }; 9 | 10 | /** 11 | * Get the estimated L1 fee for a given L2 chain. 12 | * @param env The environment to use. Either "mainnet" or "testnet". 13 | * @param chain The destination L2 chain. 14 | * @param params The parameters to use for the estimation. 15 | * @returns The estimated L1 fee. 16 | */ 17 | export function getL1FeeForL2( 18 | provider: ethers.providers.JsonRpcProvider, 19 | params: EstimateL1FeeParams 20 | ): Promise { 21 | const { l1GasOracleAddress } = params; 22 | 23 | const _l1GasOracleAddress = l1GasOracleAddress || "0x420000000000000000000000000000000000000F"; 24 | 25 | switch (params.l2Type) { 26 | case "op": 27 | return getOptimismL1Fee(provider, { 28 | ...params, 29 | l1GasOracleAddress: _l1GasOracleAddress, 30 | }); 31 | // RPC clients for Arbitrum and Mantle include both L1 and L2 components in gasLimit. 32 | case "mantle": 33 | case "arb": 34 | default: 35 | return Promise.resolve(BigNumber.from(0)); 36 | } 37 | } 38 | 39 | async function getOptimismL1Fee( 40 | provider: ethers.providers.Provider, 41 | estimateL1FeeParams: EstimateL1FeeParams 42 | ) { 43 | const { executeData, l1GasOracleAddress } = estimateL1FeeParams; 44 | 45 | const contract = new ethers.Contract(l1GasOracleAddress as string, ABI.Optimism, provider); 46 | return contract.getL1Fee(executeData); 47 | } 48 | -------------------------------------------------------------------------------- /src/libs/fee/types.ts: -------------------------------------------------------------------------------- 1 | export type L2Chain = "optimism" | "arbitrum" | "mantle" | "base" | "scroll"; 2 | -------------------------------------------------------------------------------- /src/libs/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AxelarAssetTransfer"; 2 | export * from "./AxelarGateway"; 3 | export * from "./AxelarQueryAPI"; 4 | export * from "./AxelarSigningClient"; 5 | export * from "./AxelarQueryClient"; 6 | export * from "./TransactionRecoveryApi"; 7 | export * from "./GatewayTx"; 8 | export * from "./types"; 9 | -------------------------------------------------------------------------------- /src/libs/test/AxelarQueryClient.spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarQueryClientConfig, Environment } from "../types"; 2 | import { AxelarQueryClient, AxelarQueryClientType } from "../AxelarQueryClient"; 3 | import { 4 | BatchedCommandsRequest, 5 | BatchedCommandsResponse, 6 | } from "@axelar-network/axelarjs-types/axelar/evm/v1beta1/query"; 7 | import { 8 | FeeInfoRequest, 9 | FeeInfoResponse, 10 | } from "@axelar-network/axelarjs-types/axelar/nexus/v1beta1/query"; 11 | import { 12 | PendingIBCTransferCountRequest, 13 | PendingIBCTransferCountResponse, 14 | } from "@axelar-network/axelarjs-types/axelar/axelarnet/v1beta1/query"; 15 | 16 | describe("AxelarQueryClient", () => { 17 | const config: AxelarQueryClientConfig = { environment: Environment.TESTNET }; 18 | 19 | beforeEach(() => { 20 | vitest.clearAllMocks(); 21 | }); 22 | 23 | describe("Axelar queries", () => { 24 | test("It should be able to query the evm module", async () => { 25 | const api: AxelarQueryClientType = await AxelarQueryClient.initOrGetAxelarQueryClient(config); 26 | const params: BatchedCommandsRequest = { chain: "avalanche", id: "" }; 27 | const result: BatchedCommandsResponse = await api.evm.BatchedCommands(params); 28 | 29 | expect(result).toBeDefined(); 30 | expect(result.commandIds).toBeDefined(); 31 | expect(result.executeData).toBeDefined(); 32 | expect(result.prevBatchedCommandsId).toBeDefined(); 33 | expect(result.id).toBeDefined(); 34 | expect(result.data).toBeDefined(); 35 | expect(result.status).toBeDefined(); 36 | expect(result.keyId).toBeDefined(); 37 | }, 60000); 38 | 39 | test("It should be able to query the nexus module", async () => { 40 | const api: AxelarQueryClientType = await AxelarQueryClient.initOrGetAxelarQueryClient(config); 41 | const params: FeeInfoRequest = { chain: "avalanche", asset: "wavax-wei" }; 42 | const result: FeeInfoResponse = await api.nexus.FeeInfo(params); 43 | 44 | expect(result).toBeDefined(); 45 | expect(result.feeInfo?.asset).toBeDefined(); 46 | expect(result.feeInfo?.chain).toEqual("avalanche"); 47 | expect(result.feeInfo?.feeRate).toBeDefined(); 48 | }, 60000); 49 | 50 | test("It should be able to query the axelarnet module", async () => { 51 | const api: AxelarQueryClientType = await AxelarQueryClient.initOrGetAxelarQueryClient(config); 52 | const params: PendingIBCTransferCountRequest = { chain: "osmosis-3" }; 53 | const result: PendingIBCTransferCountResponse = await api.axelarnet.PendingIBCTransferCount( 54 | params 55 | ); 56 | 57 | expect(result).toBeDefined(); 58 | expect(result.transfersByChain).toBeDefined(); 59 | }, 60000); 60 | 61 | // test("It should be able to query the tss module", async () => { 62 | 63 | // const api: AxelarQueryClientType = await AxelarQueryClient.initOrGetAxelarQueryClient(config); 64 | // const params: NextKeyIDRequest = { chain: "avalanche", keyRole: 1 }; 65 | // const result: NextKeyIDResponse = await api.tss.NextKeyID(params); 66 | 67 | // expect(result).toBeDefined(); 68 | // expect(result.keyId).toBeDefined(); 69 | 70 | // }, 60000); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /src/libs/test/TransactionRecoveryAPI/AxelarDepositRecoveryAPI.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AxelarRetryResponse, 3 | ConfirmDepositRequest, 4 | ConfirmDepositResponse, 5 | } from "../../TransactionRecoveryApi/interface"; 6 | import { AxelarDepositRecoveryAPI } from "../../TransactionRecoveryApi/AxelarDepositRecoveryAPI"; 7 | import { Environment } from "../../types"; 8 | 9 | describe.skip("AxelarDepositRecoveryAPI", () => { 10 | const api = new AxelarDepositRecoveryAPI({ environment: Environment.TESTNET }); 11 | 12 | beforeEach(() => { 13 | vitest.clearAllMocks(); 14 | }); 15 | 16 | describe.skip("confirmDeposit", () => { 17 | test("It should confirm a deposit", async () => { 18 | const testParamsAxelarnet: ConfirmDepositRequest = { 19 | hash: "FD6F3C9E63A8A0F47092418CCF3A70D52642B77B940FB6D2BE5A797D7AA97BEB", 20 | from: "Osmosis", 21 | depositAddress: "axelar192mp2cv2s0hayv6fwgjl64zs72hl97zcxjwcg6g8nkdkjxq89dps0yt6gc", 22 | denom: "wavax-wei", 23 | }; 24 | // const testParamsEvm: ConfirmDepositRequest = { 25 | // hash: "0xaea3b215c6a79a47b31f85253f788e928b37a9fe2cfad8484cc6b2a65226d32c", 26 | // from: "Avalanche", 27 | // depositAddress: "0xe74e43b70bc841011288aa510456fd942596a685", 28 | // amount: "2000000", 29 | // signature: "", // this won't be used because single signer 30 | // token: "uusd" 31 | // } 32 | const confirmation: AxelarRetryResponse = await api.confirmDeposit( 33 | testParamsAxelarnet 34 | ); 35 | console.log("confirmation", confirmation); 36 | expect(confirmation).toBeTruthy(); 37 | // expect(confirmation?.status).toBeTruthy(); 38 | // expect(confirmation?.data).toBeTruthy(); 39 | // expect(confirmation?.data?.hash).toBeTruthy(); 40 | // expect(confirmation?.data?.depositTxHash).toEqual(testParamsAxelarnet.hash); 41 | // expect(confirmation?.data?.depositAddress.toLowerCase()).toEqual(testParamsAxelarnet.depositAddress.toLowerCase()); 42 | // expect(confirmation?.data?.chain).toEqual(testParamsAxelarnet.from); 43 | // expect(confirmation?.data?.amount).toEqual(testParams.amount); 44 | }, 60000); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /src/libs/test/TransactionRecoveryAPI/AxelarTransferAPI.spec.ts: -------------------------------------------------------------------------------- 1 | import { getConfigs } from "../../../constants"; 2 | import { AxelarTransferApi } from "../../TransactionRecoveryApi"; 3 | import { Environment } from "../../types"; 4 | import { transferResponseExecutedStub } from "../stubs"; 5 | 6 | describe("AxelarTransferApi", () => { 7 | const api = new AxelarTransferApi({ environment: Environment.TESTNET }); 8 | 9 | it("should return error given the transfer api could not be reached", async () => { 10 | vitest.spyOn(api.axelarCrosschainApi, "post").mockRejectedValueOnce(undefined); 11 | const response = await api.queryTransferStatus("0x123"); 12 | expect(response.success).toBe(false); 13 | expect(response.error).toBe("Axelar Transfer API is not available"); 14 | }); 15 | 16 | it("should return error when no transfer is found", async () => { 17 | vitest.spyOn(api.axelarCrosschainApi, "post").mockResolvedValueOnce([]); 18 | const response = await api.queryTransferStatus("0x123"); 19 | expect(response.success).toBe(false); 20 | expect(response.error).toBe("No transfer found"); 21 | }); 22 | 23 | it("should query transfer status successfully when given tx hash is valid", async () => { 24 | const mockResponse = transferResponseExecutedStub(); 25 | vitest.spyOn(api.axelarCrosschainApi, "post").mockResolvedValueOnce(mockResponse); 26 | const response = await api.queryTransferStatus( 27 | "6D1B1CD4B754280461BD7AD43B4838BBD8A467AA346B7584052025F83B5EB90F" 28 | ); 29 | expect(response.success).toBe(true); 30 | expect(response.data).toEqual({ 31 | id: mockResponse[0].source.id, 32 | status: mockResponse[0].status, 33 | type: mockResponse[0].source.type, 34 | amount: mockResponse[0].source.amount, 35 | fee: mockResponse[0].source.fee, 36 | denom: mockResponse[0].source.denom, 37 | senderChain: mockResponse[0].source.sender_chain, 38 | senderAddress: mockResponse[0].source.sender_address, 39 | recipientChain: mockResponse[0].source.recipient_chain, 40 | recipientAddress: mockResponse[0].source.recipient_address, 41 | blockHeight: mockResponse[0].source.height, 42 | blockExplorerUrl: `${getConfigs(Environment.TESTNET).axelarscanUrl}/transfer/${ 43 | mockResponse[0].source.id 44 | }`, 45 | }); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /src/libs/test/TransactionRecoveryAPI/EncodingTests.spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarGMPRecoveryAPI } from "../../TransactionRecoveryApi/AxelarGMPRecoveryAPI"; 2 | import { Environment, EvmWalletDetails } from "../../types"; 3 | import { EvmChain } from "../../../constants/EvmChain"; 4 | import { utils } from "@axelar-network/axelar-local-dev"; 5 | 6 | describe("AxelarDepositRecoveryAPI", () => { 7 | const { setLogger } = utils; 8 | setLogger(() => null); 9 | 10 | let evmWalletDetails: EvmWalletDetails; 11 | beforeEach(() => { 12 | vitest.clearAllMocks(); 13 | evmWalletDetails = { 14 | privateKey: "", 15 | useWindowEthereum: false, 16 | }; 17 | }); 18 | 19 | describe("manual relay", () => { 20 | const api = new AxelarGMPRecoveryAPI({ environment: Environment.TESTNET }); 21 | test("It should create a command ID from a tx hash and event index", async () => { 22 | const txHash = "0x0a83f6bff1697bb1f72ee60713427e802f32571f042abfa7c6278024f440e861"; 23 | const res = await api.manualRelayToDestChain(txHash, undefined, undefined, evmWalletDetails); 24 | expect(res).toBeTruthy(); 25 | }, 120000); 26 | }); 27 | 28 | describe.skip("creating command ID", () => { 29 | const api = new AxelarGMPRecoveryAPI({ environment: Environment.TESTNET }); 30 | test("It should create a command ID from a tx hash and event index", async () => { 31 | const txHash = "0x2c9083bebd1f82b86b7b0d3298885f90767b584742df9ec3a9c9f15872a1fff9"; 32 | const eventIndex = await api.getEventIndex("ethereum-2" as EvmChain, txHash); 33 | const res = await api.getCidFromSrcTxHash(EvmChain.MOONBEAM, txHash, eventIndex as number); 34 | expect(res).toEqual("58c46960e6483f61bf206d1bd1819917d2b009f58d7050e05b4be1d13247b4ed"); 35 | }, 60000); 36 | }); 37 | describe.skip("checking event status", () => { 38 | const api = new AxelarGMPRecoveryAPI({ environment: Environment.TESTNET }); 39 | test("fetching event status", async () => { 40 | const txHash = "0xa290f800f2089535a0abb013cea9cb26e1cdb3f2a2f2a8dcef2f149eb7a4d3be"; 41 | const event = await api.getEvmEvent(EvmChain.MOONBEAM, EvmChain.POLYGON, txHash, undefined); 42 | console.log("event", event); 43 | const res = await api.isEVMEventCompleted(event.eventResponse); 44 | expect(res).toBeTruthy(); 45 | }, 60000); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /src/libs/test/testUtils/localChain.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import ganache from "ganache"; 3 | import rpcInfo from "../../TransactionRecoveryApi/constants/chain"; 4 | import { EvmChain } from "../../../constants/EvmChain"; 5 | 6 | export interface ForkOptions { 7 | impersonateAccounts: string[]; 8 | defaultBalance?: number; 9 | blockNumber?: number; 10 | } 11 | 12 | export function fork( 13 | evmChain: EvmChain, 14 | options: ForkOptions = { 15 | impersonateAccounts: [], 16 | defaultBalance: 1000, 17 | } 18 | ) { 19 | const ganacheProvider = ganache.provider({ 20 | wallet: { 21 | unlockedAccounts: options.impersonateAccounts, 22 | defaultBalance: options.defaultBalance, 23 | }, 24 | fork: { 25 | url: rpcInfo.testnet.rpcMap[evmChain], 26 | blockNumber: options?.blockNumber, 27 | }, 28 | chain: { 29 | vmErrorsOnRPCResponse: true, 30 | }, 31 | logging: { 32 | quiet: true, 33 | }, 34 | }); 35 | 36 | return new ethers.providers.Web3Provider(ganacheProvider as any); 37 | } 38 | -------------------------------------------------------------------------------- /src/services/RestService.ts: -------------------------------------------------------------------------------- 1 | import fetch from "cross-fetch"; 2 | import HttpError from "standard-http-error"; 3 | 4 | export class RestService { 5 | constructor(private host: string) {} 6 | 7 | post(url: string, body: any, traceId?: string) { 8 | const requestOptions = { 9 | method: "POST", 10 | headers: { 11 | "Content-Type": "application/json", 12 | "x-trace-id": traceId || "none", 13 | }, 14 | body: JSON.stringify(body), 15 | }; 16 | 17 | return this.execRest(url, requestOptions); 18 | } 19 | 20 | get(url: string, traceId?: string) { 21 | const requestOptions = { 22 | method: "GET", 23 | headers: { 24 | "Content-Type": "application/json", 25 | "x-trace-id": traceId || "none", 26 | }, 27 | }; 28 | 29 | return this.execRest(url, requestOptions); 30 | } 31 | 32 | async execRest(endpoint: string, requestOptions: any) { 33 | return fetch(this.host + endpoint, requestOptions) 34 | .then((response) => { 35 | if (!response.ok) throw response; 36 | return response; 37 | }) 38 | .then((response) => response.json()) 39 | .catch(async (err) => { 40 | let msg; 41 | try { 42 | msg = await err.json(); 43 | } catch (_) { 44 | msg = await err.text(); 45 | } 46 | const error = new HttpError( 47 | err.status, 48 | msg?.message || Object.keys(msg).length > 0 ? msg : err.statusText 49 | ); 50 | throw error; 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/services/SocketService.ts: -------------------------------------------------------------------------------- 1 | import { io, Socket } from "socket.io-client"; 2 | import { loadChains } from "../chains"; 3 | import { ChainInfo } from "../chains/types"; 4 | import { Environment } from "../libs"; 5 | 6 | export class SocketService { 7 | private socket: Socket; 8 | private resourceUrl: string; 9 | private testMode = false; 10 | private supportedChains: ChainInfo[]; 11 | private environment: Environment; 12 | 13 | constructor(resourceUrl: string, environment: Environment, testMode = false) { 14 | this.resourceUrl = resourceUrl; 15 | this.environment = environment; 16 | this.testMode = testMode; 17 | } 18 | 19 | public async createSocket() { 20 | if (this.testMode) { 21 | this.socket = io(this.resourceUrl, { 22 | reconnectionDelay: 0, 23 | forceNew: true, 24 | transports: ["websocket"], 25 | extraHeaders: { 26 | "User-Agent": 27 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0", 28 | }, 29 | }); 30 | } else { 31 | this.socket = io(this.resourceUrl, { 32 | transports: ["websocket"], 33 | reconnectionDelayMax: 10000, 34 | extraHeaders: { 35 | "User-Agent": 36 | "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0", 37 | }, 38 | }); 39 | this.supportedChains = await loadChains({ environment: this.environment }); 40 | } 41 | 42 | return new Promise((resolve) => { 43 | this.socket.on("connect", () => { 44 | resolve(true); 45 | }); 46 | }); 47 | } 48 | 49 | public async joinRoomAndWaitForEvent( 50 | roomId: string, 51 | sourceChain: string, 52 | destinationChain: string, 53 | destinationAddress: string 54 | ): Promise { 55 | await this.createSocket(); 56 | 57 | return new Promise((resolve) => { 58 | const ms = 1.8e6; //30 minutes 59 | const timeout = setTimeout(() => { 60 | this.socket.off("bridge-event"); 61 | this.disconnect(); 62 | }, ms); 63 | this.socket.emit("room:join", roomId); 64 | this.socket.on("bridge-event", (data: any) => { 65 | const attributes = data.Attributes; 66 | const sourceChainConfig: ChainInfo = this.supportedChains.find( 67 | (chain) => 68 | chain.chainIdentifier[this.environment].toLowerCase() === sourceChain.toLowerCase() 69 | ) as ChainInfo; 70 | const destChainConfig: ChainInfo = this.supportedChains.find( 71 | (chain) => 72 | chain.chainIdentifier[this.environment].toLowerCase() === destinationChain.toLowerCase() 73 | ) as ChainInfo; 74 | const sourceChainIsAxelarnet = sourceChainConfig?.module === "axelarnet"; 75 | const destChainIsAxelar = destinationChain.toLowerCase() === "axelar"; 76 | const sourceChainMatch = 77 | sourceChainIsAxelarnet || 78 | attributes.sourceChain.toLowerCase() === sourceChain.toLowerCase(); 79 | const destChainMatch = 80 | attributes.destinationChain.toLowerCase() === 81 | (destChainIsAxelar ? "axelarnet" : destChainConfig.chainIdentifier[this.environment]); 82 | const destAddressMatch = attributes.destinationAddress === destinationAddress; 83 | 84 | if (sourceChainMatch && destChainMatch && destAddressMatch) { 85 | clearTimeout(timeout); 86 | this.socket.off("bridge-event"); 87 | this.disconnect(); 88 | resolve(data); 89 | } 90 | }); 91 | }); 92 | } 93 | 94 | public disconnect() { 95 | this.socket.disconnect(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./RestService"; 2 | export * from "./SocketService"; 3 | -------------------------------------------------------------------------------- /src/services/test/RestService.spec.ts: -------------------------------------------------------------------------------- 1 | import fetch from "cross-fetch"; 2 | import HttpError from "standard-http-error"; 3 | import { Mock } from "vitest"; 4 | 5 | import { RestService } from "../RestService"; 6 | 7 | const mockedFetch = fetch as Mock; 8 | 9 | vitest.mock("cross-fetch", () => { 10 | // Mock the default export 11 | return { 12 | __esModule: true, 13 | default: vitest.fn(), 14 | }; 15 | }); 16 | 17 | describe("RestService", () => { 18 | const host = "http://localhost:3000"; 19 | const api = new RestService(host); 20 | 21 | beforeEach(() => { 22 | vitest.clearAllMocks(); 23 | }); 24 | 25 | describe("execRest()", () => { 26 | describe("when error", () => { 27 | describe("when text response", () => { 28 | beforeAll(() => { 29 | mockedFetch.mockRejectedValue({ 30 | status: 400, 31 | text: () => "hello world", 32 | }); 33 | }); 34 | 35 | it("should throw error", async () => { 36 | const error = new HttpError(400, "hello world"); 37 | expect(api.get("/")).rejects.toThrow(error); 38 | }); 39 | }); 40 | 41 | describe("when json response", () => { 42 | beforeAll(() => { 43 | mockedFetch.mockRejectedValue({ 44 | status: 403, 45 | json: () => ({ 46 | message: "Forbidden", 47 | }), 48 | }); 49 | }); 50 | 51 | it("should return error", async () => { 52 | const error = new HttpError(403, "Forbidden"); 53 | expect(api.get("/")).rejects.toThrow(error); 54 | }); 55 | }); 56 | }); 57 | 58 | describe("when success", () => { 59 | let res: any; 60 | beforeAll(async () => { 61 | mockedFetch.mockResolvedValue({ 62 | status: 200, 63 | ok: true, 64 | json: () => ({ foo: "bar" }), 65 | }); 66 | 67 | res = await api.get("/"); 68 | }); 69 | it("should return json", () => { 70 | expect(res.foo).toEqual("bar"); 71 | }); 72 | }); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /src/services/types/index.ts: -------------------------------------------------------------------------------- 1 | // TODO: all miscellaneous topics go here for now 2 | 3 | export const TRANSFER_RESULT = "socket-transfer-result"; 4 | 5 | // POST REQUEST CONSTS 6 | export const CLIENT_API_POST_TRANSFER_ASSET = "/transfer-assets"; 7 | export const CLIENT_API_GET_OTC = "/otc"; 8 | export const CLIENT_API_GET_FEE = "/chain/fee"; 9 | 10 | export interface SocketOptions { 11 | reconnectionDelayMax: number; 12 | auth: { token: string }; 13 | query: { [key: string]: string }; 14 | } 15 | 16 | export interface CallbackStatus { 17 | successCb: any; 18 | failCb: any; 19 | } 20 | 21 | export type StatusResponse = (...args: any[]) => void; 22 | 23 | export type SourceOrDestination = "source" | "destination"; 24 | 25 | export interface OTC { 26 | otc: string; 27 | validationMsg: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./validateDestinationAddress"; 2 | export * from "./wallet"; 3 | export * from "./sleep"; 4 | export * from "./retry"; 5 | export * from "./validateChain"; 6 | -------------------------------------------------------------------------------- /src/utils/retry.ts: -------------------------------------------------------------------------------- 1 | export async function retry(fn: () => Promise, maxRetries = 5, delay = 3000): Promise { 2 | let error: any; 3 | 4 | for (let i = 0; i < maxRetries; i++) { 5 | try { 6 | return await fn(); 7 | } catch (e) { 8 | error = e; 9 | await new Promise((resolve) => setTimeout(resolve, delay)); 10 | } 11 | } 12 | 13 | throw error; 14 | } 15 | -------------------------------------------------------------------------------- /src/utils/sleep.ts: -------------------------------------------------------------------------------- 1 | export function sleep(seconds: number) { 2 | return new Promise((resolve) => setTimeout(resolve, seconds * 1000)); 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/validateChain.ts: -------------------------------------------------------------------------------- 1 | import { stringSimilarity } from "string-similarity-js"; 2 | import { importS3Config, loadChains } from "../chains"; 3 | import { Environment } from "../libs"; 4 | 5 | export async function validateChainIdentifierOld( 6 | chainIdentifier: string, 7 | environment: Environment 8 | ) { 9 | const chains = await loadChains({ 10 | environment, 11 | }); 12 | const chainIdentifiers = chains.map((chain) => chain.chainIdentifier[environment]); 13 | 14 | const foundChain = chainIdentifiers.find( 15 | (identifier: string) => identifier === chainIdentifier.toLowerCase() 16 | ); 17 | 18 | return { 19 | foundChain: !!foundChain, 20 | bestMatch: foundChain ? false : findSimilarInArray(chainIdentifiers, chainIdentifier), 21 | }; 22 | } 23 | 24 | export async function validateChainIdentifier(chainIdentifier: string, environment: Environment) { 25 | const s3 = await importS3Config(environment); 26 | 27 | if (!s3 || !s3.chains) 28 | return { 29 | foundChain: false, 30 | bestMatch: false, 31 | }; 32 | 33 | const chainIdentifiers = Object.keys(s3.chains); 34 | const axelarIdentifier = s3["axelar"]?.axelarId || "axelar"; 35 | chainIdentifiers.push(axelarIdentifier); 36 | 37 | const foundChain = chainIdentifiers.find( 38 | (identifier: string) => identifier === chainIdentifier.toLowerCase() 39 | ); 40 | 41 | return { 42 | foundChain: !!foundChain, 43 | bestMatch: foundChain ? false : findSimilarInArray(chainIdentifiers, chainIdentifier), 44 | }; 45 | } 46 | 47 | function findSimilarInArray(array: Array, wordsToFind: string) { 48 | let bestMatch = array[0]; 49 | let bestScore = 0; 50 | 51 | for (const i in array) { 52 | const score = stringSimilarity(array[i], wordsToFind); 53 | if (score >= bestScore) { 54 | bestScore = score; 55 | bestMatch = array[i]; 56 | } 57 | } 58 | 59 | return bestMatch; 60 | } 61 | 62 | export async function throwIfInvalidChainIds(chains: string[], environment: Environment) { 63 | const validations = await Promise.all( 64 | chains.map((chain) => validateChainIdentifier(chain, environment)) 65 | ); 66 | 67 | for (let i = 0; i < validations.length; i++) { 68 | if (!validations[i].foundChain) { 69 | throw new Error( 70 | `Invalid chain identifier for ${chains[i]}. Did you mean ${validations[i].bestMatch}?` 71 | ); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/utils/validateDestinationAddress.ts: -------------------------------------------------------------------------------- 1 | import { Environment } from "../libs"; 2 | import { loadChains } from "../chains"; 3 | import { isAddress } from "ethers/lib/utils"; 4 | import { bech32 } from "bech32"; 5 | 6 | export async function validateDestinationAddressByChainSymbol( 7 | chainSymbol: string, 8 | destinationAddress: string, 9 | environment: Environment 10 | ) { 11 | const chains = await loadChains({ 12 | environment, 13 | }); 14 | 15 | const targetChain = chains.find( 16 | (chainInfo) => chainInfo.chainSymbol.toLowerCase() === chainSymbol.toLowerCase() 17 | ); 18 | 19 | return targetChain?.module === "evm" 20 | ? isAddress(destinationAddress) 21 | : destinationAddress && 22 | targetChain?.addressPrefix && 23 | checkPrefix(destinationAddress, targetChain?.addressPrefix); 24 | } 25 | 26 | export async function validateDestinationAddressByChainName( 27 | chainIdentifier: string, 28 | destinationAddress: string, 29 | environment: Environment 30 | ) { 31 | const chains = await loadChains({ 32 | environment, 33 | }); 34 | 35 | const targetChain = chains.find( 36 | (chainInfo) => chainInfo.chainIdentifier[environment] === chainIdentifier.toLowerCase() 37 | ); 38 | 39 | return targetChain?.module === "evm" 40 | ? isAddress(destinationAddress) 41 | : destinationAddress && 42 | targetChain?.addressPrefix && 43 | checkPrefix(destinationAddress, targetChain?.addressPrefix); 44 | } 45 | 46 | const checkPrefix = (address: string, addressPrefix: string): boolean => { 47 | if (!address) return false; 48 | 49 | try { 50 | return bech32.decode(address).prefix === addressPrefix; 51 | } catch (e) { 52 | return false; 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /src/utils/wallet.ts: -------------------------------------------------------------------------------- 1 | import { ethers, Wallet } from "ethers"; 2 | 3 | export function createWallet() { 4 | if (globalThis.sessionStorage) { 5 | const mnemonic = globalThis.sessionStorage.getItem("axelar-wallet"); 6 | if (mnemonic) { 7 | const wallet = ethers.Wallet.fromMnemonic(mnemonic); 8 | return wallet; 9 | } else { 10 | const wallet = ethers.Wallet.createRandom(); 11 | globalThis.sessionStorage.setItem("axelar-wallet", wallet._mnemonic().phrase); 12 | return wallet; 13 | } 14 | } else { 15 | const wallet = ethers.Wallet.createRandom(); 16 | return wallet; 17 | } 18 | } 19 | 20 | export function signOtc(wallet: Wallet, message: string) { 21 | return wallet.signMessage(message); 22 | } 23 | 24 | const _exports = { 25 | createWallet, 26 | signOtc, 27 | }; 28 | 29 | export default _exports; 30 | -------------------------------------------------------------------------------- /test/e2e/data/index.ts: -------------------------------------------------------------------------------- 1 | import { AssetTransferObject } from "../../../src"; 2 | 3 | export const getTransferPayload = ( 4 | sig: string, 5 | publicAddress: string, 6 | destAddress: string 7 | ): AssetTransferObject => { 8 | return { 9 | signature: sig, 10 | publicAddr: publicAddress, 11 | sourceChainInfo: { 12 | id: "terra-3", 13 | chainSymbol: "Terra", 14 | assets: [], 15 | rpc: [], 16 | chainName: "Terra", 17 | estimatedWaitTime: 5, 18 | fullySupported: true, 19 | txFeeInPercent: 0.1, 20 | module: "axelarnet", 21 | chainIdentifier: { 22 | "devnet-amplifier": "terra", 23 | testnet: "terra", 24 | mainnet: "terra", 25 | }, 26 | nativeAsset: [], 27 | addressPrefix: "terra", 28 | }, 29 | selectedSourceAsset: { 30 | assetSymbol: "UST", 31 | assetName: "UST", 32 | minDepositAmt: 0.05, 33 | common_key: "uusd", 34 | native_chain: "terra", 35 | decimals: 6, 36 | fullySupported: true, 37 | }, 38 | destinationChainInfo: { 39 | id: "avalanche", 40 | chainSymbol: "AVAX", 41 | assets: [], 42 | rpc: [], 43 | chainName: "Avalanche", 44 | estimatedWaitTime: 5, 45 | fullySupported: true, 46 | txFeeInPercent: 0.1, 47 | module: "evm", 48 | confirmLevel: 12, 49 | chainIdentifier: { 50 | "devnet-amplifier": "avalanche", 51 | testnet: "avalanche", 52 | mainnet: "avalanche", 53 | }, 54 | nativeAsset: ["wavax-wei"], 55 | addressPrefix: "", 56 | }, 57 | selectedDestinationAsset: { 58 | assetAddress: destAddress, 59 | assetSymbol: "UST", 60 | common_key: "uusd", 61 | }, 62 | transactionTraceId: "0x", 63 | }; 64 | }; 65 | -------------------------------------------------------------------------------- /test/e2e/mainnet/deposit-address.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, Environment } from "../../../src"; 2 | 3 | describe( 4 | "[MAINNET] - Deposit Address E2E", 5 | () => { 6 | let transferSdk: AxelarAssetTransfer; 7 | 8 | beforeAll(() => { 9 | transferSdk = new AxelarAssetTransfer({ 10 | environment: Environment.MAINNET, 11 | }); 12 | }); 13 | 14 | it("init", () => { 15 | expect(transferSdk).toBeDefined(); 16 | }); 17 | 18 | describe("AxelarAssetTransfer.getDepositAddress()", () => { 19 | describe("evm -> evm", () => { 20 | describe("moonbeam -> avalanche", () => { 21 | let address: string; 22 | beforeAll(async () => { 23 | address = await transferSdk.getDepositAddress( 24 | "moonbeam", 25 | "avalanche", 26 | "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2", 27 | "uusdc" 28 | ); 29 | }); 30 | 31 | it("should return deposit address", () => { 32 | expect(typeof address).toBe("string"); 33 | expect(address.length).toBeGreaterThan(0); 34 | }); 35 | }); 36 | describe("avalanche -> moonbeam", () => { 37 | let address: string; 38 | beforeAll(async () => { 39 | address = await transferSdk.getDepositAddress( 40 | "avalanche", 41 | "moonbeam", 42 | "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2", 43 | "uusdc" 44 | ); 45 | }); 46 | 47 | it("should return deposit address", () => { 48 | expect(typeof address).toBe("string"); 49 | expect(address.length).toBeGreaterThan(0); 50 | }); 51 | }); 52 | }); 53 | }); 54 | }, 55 | { 56 | timeout: 60000, 57 | } 58 | ); 59 | -------------------------------------------------------------------------------- /test/e2e/testnet/deposit-address.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, Environment } from "../../../src"; 2 | 3 | describe( 4 | "[TESTNET] - Deposit Address E2E", 5 | () => { 6 | let transferSdk: AxelarAssetTransfer; 7 | 8 | beforeAll(() => { 9 | transferSdk = new AxelarAssetTransfer({ 10 | environment: Environment.TESTNET, 11 | }); 12 | }); 13 | 14 | it("init", () => { 15 | expect(transferSdk).toBeDefined(); 16 | }); 17 | 18 | describe("AxelarAssetTransfer.getDepositAddress()", () => { 19 | describe("evm -> evm", () => { 20 | describe("moonbeam -> avalanche", () => { 21 | let address: string; 22 | beforeAll(async () => { 23 | address = await transferSdk.getDepositAddress( 24 | "moonbeam", 25 | "avalanche", 26 | "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2", 27 | "uausdc" 28 | ); 29 | }); 30 | 31 | it("should return deposit address", () => { 32 | expect(typeof address).toBe("string"); 33 | expect(address.length).toBeGreaterThan(0); 34 | }); 35 | }); 36 | describe("avalanche -> moonbeam", () => { 37 | let address: string; 38 | beforeAll(async () => { 39 | address = await transferSdk.getDepositAddress( 40 | "avalanche", 41 | "moonbeam", 42 | "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2", 43 | "uausdc" 44 | ); 45 | }); 46 | 47 | it("should return deposit address", () => { 48 | expect(typeof address).toBe("string"); 49 | expect(address.length).toBeGreaterThan(0); 50 | }); 51 | }); 52 | }); 53 | }); 54 | }, 55 | { 56 | timeout: 60000, 57 | } 58 | ); 59 | -------------------------------------------------------------------------------- /test/e2e/testnet/native-assets.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, Environment } from "../../../src"; 2 | 3 | describe( 4 | "AxelarAssetTransfer", 5 | () => { 6 | let sdk: AxelarAssetTransfer; 7 | 8 | beforeAll(() => { 9 | sdk = new AxelarAssetTransfer({ 10 | environment: Environment.TESTNET, 11 | }); 12 | }); 13 | 14 | describe("getDepositAddressForNativeWrap()", () => { 15 | let address: string; 16 | beforeAll(async () => { 17 | address = await sdk.getDepositAddressForNativeWrap( 18 | "avalanche", 19 | "ethereum-2", 20 | "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2" 21 | ); 22 | }); 23 | 24 | it("should get native deposit address", () => { 25 | expect(address).toBeTruthy(); 26 | console.log({ 27 | address, 28 | }); 29 | }); 30 | }); 31 | 32 | describe("getDepositAddressForNativeUnwrap()", () => { 33 | let depositAddress: string; 34 | beforeAll(async () => { 35 | const result = await sdk.getDepositAddressForNativeUnwrap( 36 | "moonbeam", 37 | "avalanche", 38 | "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2" 39 | ); 40 | depositAddress = result; 41 | }); 42 | 43 | it("should get native deposit address", () => { 44 | expect(depositAddress).toBeTruthy(); 45 | }); 46 | }); 47 | }, 48 | { 49 | timeout: 20000, 50 | } 51 | ); 52 | -------------------------------------------------------------------------------- /test/e2e/testnet/query-transaction-status.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarRecoveryApi, Environment } from "../../../src"; 2 | 3 | describe( 4 | "Query Transaction Status", 5 | () => { 6 | let sdk: AxelarRecoveryApi; 7 | 8 | beforeAll(() => { 9 | sdk = new AxelarRecoveryApi({ 10 | environment: Environment.TESTNET, 11 | }); 12 | }); 13 | 14 | it("should include timeSpent", async () => { 15 | // the sample tx hashes are from the testnet 16 | // it contains all finalized statuses to ensure the `timeSpent` is always included. 17 | const sampleTxHashes = [ 18 | "0xd563e708d99da0c7d7cdd613183d6a45f21dd0e1237cd5568551861f3bf3767a", // failed 19 | "0x085ad5106880b7a4ecf9ea3ecba3e5637aa6acdeac7158080aa65033aa5731d9", // executed 20 | ]; 21 | const response = await Promise.all( 22 | sampleTxHashes.map((hash) => sdk.queryTransactionStatus(hash)) 23 | ); 24 | const timeSpents = response.map((result) => result.timeSpent); 25 | for (const timeSpent of timeSpents) { 26 | expect(timeSpent).toBeDefined(); 27 | expect(timeSpent?.total).toBeDefined(); 28 | } 29 | }); 30 | }, 31 | { 32 | timeout: 20000, 33 | } 34 | ); 35 | -------------------------------------------------------------------------------- /test/e2e/vitest.e2e.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | 3 | export default defineConfig({ 4 | test: { 5 | testTimeout: 300000, 6 | environment: "node", 7 | root: "test/e2e", 8 | include: ["**/*.e2e-spec.ts"], 9 | globals: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/asset-wrap.integration-spec.ts: -------------------------------------------------------------------------------- 1 | import { EvmChain } from "../../src/constants/EvmChain"; 2 | import { AxelarAssetTransfer, Environment } from "../../src"; 3 | 4 | describe( 5 | "Asset Wrap", 6 | () => { 7 | const axelarAssetTransfer = new AxelarAssetTransfer({ 8 | environment: Environment.TESTNET, 9 | }); 10 | 11 | test("bootstrap", () => { 12 | expect(axelarAssetTransfer).toBeDefined(); 13 | }); 14 | 15 | describe("getDepositAddressForNativeWrap()", () => { 16 | let result: any; 17 | 18 | beforeAll(async () => { 19 | result = await axelarAssetTransfer.getDepositAddressForNativeWrap( 20 | "ethereum-2", 21 | EvmChain.MOONBEAM, 22 | "0xa411977dd24F1547065C6630E468a43275cB4d7f", 23 | "" 24 | ); 25 | }); 26 | 27 | it("should generate unique deposit addresses", () => { 28 | console.log({ result }); 29 | }); 30 | }); 31 | }, 32 | { 33 | timeout: 20000, 34 | } 35 | ); 36 | -------------------------------------------------------------------------------- /test/integration/deposit-address/evm-cosmos.integration-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, CHAINS, Environment } from "../../../src"; 2 | 3 | const sdk = new AxelarAssetTransfer({ 4 | environment: Environment.MAINNET, 5 | }); 6 | const cosmosAddress = "terra1u8xlzsfuxe0lv6u2ws2zymrnnlc9pmyynu7pym"; 7 | const evmAsset = "uusdc"; 8 | 9 | describe( 10 | "EVM - COSMOS", 11 | () => { 12 | describe("getDepositAddress()", () => { 13 | let depositAddress: string; 14 | 15 | beforeAll(async () => { 16 | depositAddress = await sdk.getDepositAddress( 17 | CHAINS.MAINNET.AVALANCHE, 18 | CHAINS.MAINNET.TERRA, 19 | cosmosAddress, 20 | evmAsset 21 | ); 22 | }); 23 | 24 | describe("when called", () => { 25 | it("should return deposit address", () => { 26 | expect(depositAddress?.length).toBeGreaterThan(0); 27 | }); 28 | }); 29 | }); 30 | }, 31 | { 32 | timeout: 20000, 33 | } 34 | ); 35 | -------------------------------------------------------------------------------- /test/integration/deposit-address/evm-evm.integration-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, CHAINS, Environment } from "../../../src"; 2 | 3 | const sdk = new AxelarAssetTransfer({ 4 | environment: Environment.TESTNET, 5 | }); 6 | const evmAddress = "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2"; 7 | const evmAsset = "uausdc"; 8 | 9 | describe( 10 | "EVM - EVM", 11 | () => { 12 | describe("getDepositAddress()", () => { 13 | let depositAddress: string; 14 | 15 | beforeAll(async () => { 16 | depositAddress = await sdk.getDepositAddress( 17 | CHAINS.TESTNET.AVALANCHE, 18 | CHAINS.TESTNET.SEPOLIA, 19 | evmAddress, 20 | evmAsset 21 | ); 22 | }); 23 | 24 | describe("when called", () => { 25 | it("should return deposit address", () => { 26 | expect(depositAddress?.length).toBeGreaterThan(0); 27 | }); 28 | }); 29 | }); 30 | }, 31 | { 32 | timeout: 20000, 33 | } 34 | ); 35 | -------------------------------------------------------------------------------- /test/integration/deposit-address/validations.integration-spec.ts: -------------------------------------------------------------------------------- 1 | import { CHAINS, Environment, throwIfInvalidChainIds } from "../../../src"; 2 | 3 | vitest.setConfig({ 4 | testTimeout: 20000, 5 | }); 6 | 7 | describe("Validations - Testnet", () => { 8 | const environment = Environment.TESTNET; 9 | describe("validateChainIdentifiers()", () => { 10 | describe("when called", () => { 11 | it("should validate chain identifiers", () => { 12 | expect( 13 | throwIfInvalidChainIds([CHAINS.TESTNET.AVALANCHE, CHAINS.TESTNET.SEPOLIA], environment) 14 | ).resolves.toBeUndefined(); 15 | }); 16 | }); 17 | 18 | describe("when wrong identifier", () => { 19 | it("should throw error", () => { 20 | expect( 21 | throwIfInvalidChainIds([CHAINS.TESTNET.AVALANCHE, "ethereum"], environment) 22 | ).rejects.toThrow("Invalid chain identifier for ethereum. Did you mean ethereum-2?"); 23 | }); 24 | 25 | it("should throw error", () => { 26 | expect( 27 | throwIfInvalidChainIds(["osmosis", CHAINS.TESTNET.AVALANCHE], environment) 28 | ).rejects.toThrow("Invalid chain identifier for osmosis. Did you mean osmosis-4?"); 29 | }); 30 | 31 | it("should throw error", () => { 32 | expect( 33 | throwIfInvalidChainIds([CHAINS.TESTNET.OSMOSIS, "terra"], environment) 34 | ).rejects.toThrow("Invalid chain identifier for terra. Did you mean terra-3?"); 35 | }); 36 | }); 37 | }); 38 | }); 39 | 40 | describe("Validations - Mainnet", () => { 41 | const environment = Environment.MAINNET; 42 | describe("validateChainIdentifiers()", () => { 43 | describe("when called", () => { 44 | it("should validate chain identifiers", () => { 45 | expect( 46 | throwIfInvalidChainIds([CHAINS.MAINNET.AVALANCHE, CHAINS.MAINNET.ETHEREUM], environment) 47 | ).resolves.toBeUndefined(); 48 | }); 49 | }); 50 | 51 | describe("when wrong identifier", () => { 52 | it("should throw error", () => { 53 | expect( 54 | throwIfInvalidChainIds([CHAINS.MAINNET.AVALANCHE, "ethereum-2"], environment) 55 | ).rejects.toThrow("Invalid chain identifier for ethereum-2. Did you mean ethereum?"); 56 | }); 57 | 58 | it("should throw error", () => { 59 | expect( 60 | throwIfInvalidChainIds([CHAINS.MAINNET.OSMOSIS, "terra"], environment) 61 | ).rejects.toThrow("Invalid chain identifier for terra. Did you mean terra-2?"); 62 | }); 63 | }); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /test/integration/parts/00.deposit-address-single.spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, Environment } from "../../../src"; 2 | 3 | /** 4 | * This test helps to check that a unique deposit address is generated for parallel requests 5 | * if the source chain is different but that the destination chain is the same 6 | */ 7 | 8 | describe( 9 | "Single Deposit Address Generation", 10 | () => { 11 | const axelarAssetTransfer = new AxelarAssetTransfer({ 12 | environment: Environment.TESTNET, 13 | }); 14 | 15 | test("bootstrap", () => { 16 | expect(axelarAssetTransfer).toBeDefined(); 17 | }); 18 | 19 | describe("deposit address generation", () => { 20 | let result: string; 21 | 22 | beforeAll(async () => { 23 | result = await axelarAssetTransfer.getDepositAddress( 24 | "avalanche", 25 | "moonbeam", 26 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 27 | "uausdc" 28 | ); 29 | }); 30 | 31 | it("should generate unique deposit addresses", () => { 32 | expect(typeof result).toBe("string"); 33 | expect(result.length).toBeGreaterThan(1); 34 | }); 35 | }); 36 | }, 37 | { 38 | timeout: 20000, 39 | } 40 | ); 41 | -------------------------------------------------------------------------------- /test/integration/parts/01.deposit-address.spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, CHAINS, Environment } from "../../../src"; 2 | 3 | /** 4 | * This test helps to check that a unique deposit address is generated for parallel requests 5 | * if the source chain is different but that the destination chain is the same 6 | */ 7 | 8 | describe( 9 | "Parallel Deposit Address Generation", 10 | () => { 11 | let axelarAssetTransferTestnet: any; 12 | let axelarAssetTransferMainnet: any; 13 | 14 | beforeAll(() => { 15 | axelarAssetTransferTestnet = new AxelarAssetTransfer({ 16 | environment: Environment.TESTNET, 17 | }); 18 | axelarAssetTransferMainnet = new AxelarAssetTransfer({ 19 | environment: Environment.MAINNET, 20 | }); 21 | }); 22 | 23 | test("bootstrap", () => { 24 | expect(axelarAssetTransferTestnet).toBeDefined(); 25 | }); 26 | 27 | describe("deposit address generation", () => { 28 | it("should generate unique deposit addresses", async () => { 29 | const results = await Promise.all([ 30 | axelarAssetTransferTestnet.getDepositAddress( 31 | CHAINS.TESTNET.AVALANCHE, 32 | CHAINS.TESTNET.MOONBEAM, 33 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 34 | "uausdc" 35 | ), 36 | axelarAssetTransferTestnet.getDepositAddress( 37 | CHAINS.TESTNET.FANTOM, 38 | CHAINS.TESTNET.MOONBEAM, 39 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 40 | "uausdc" 41 | ), 42 | axelarAssetTransferTestnet.getDepositAddress( 43 | CHAINS.TESTNET.OSMOSIS, 44 | CHAINS.TESTNET.MOONBEAM, 45 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 46 | "uausdc" 47 | ), 48 | axelarAssetTransferTestnet.getDepositAddress( 49 | CHAINS.TESTNET.SEPOLIA, 50 | CHAINS.TESTNET.MOONBEAM, 51 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 52 | "uausdc" 53 | ), 54 | axelarAssetTransferTestnet.getDepositAddress( 55 | CHAINS.TESTNET.MOONBEAM, 56 | CHAINS.TESTNET.OSMOSIS, 57 | "osmo1x3z2vepjd7fhe30epncxjrk0lehq7xdqe8ltsn", 58 | "uausdc" 59 | ), 60 | ]); 61 | expect(results.length).toBe(5); 62 | expect(results[0]).not.toEqual(results[1]); 63 | }); 64 | 65 | it.skip("should be able to generate deposit addresses when the source chain is cosmos-based chain", async () => { 66 | const results = await Promise.all([ 67 | axelarAssetTransferMainnet.getDepositAddress( 68 | CHAINS.TESTNET.TERRA, 69 | CHAINS.TESTNET.MOONBEAM, 70 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 71 | "uusdc" 72 | ), 73 | axelarAssetTransferMainnet.getDepositAddress( 74 | CHAINS.TESTNET.AXELAR, 75 | CHAINS.TESTNET.OSMOSIS, 76 | "osmo1x3z2vepjd7fhe30epncxjrk0lehq7xdqe8ltsn", 77 | "uusdc" 78 | ), 79 | axelarAssetTransferMainnet.getDepositAddress( 80 | CHAINS.TESTNET.OSMOSIS, 81 | CHAINS.TESTNET.AXELAR, 82 | "axelar1dn9534a72h733m8andex5ufklql3hfsv8gdsrc", 83 | "uusdc" 84 | ), 85 | ]); 86 | console.log(results); 87 | expect(results.length).toBe(3); 88 | }); 89 | }); 90 | }, 91 | { 92 | timeout: 30000, 93 | } 94 | ); 95 | -------------------------------------------------------------------------------- /test/integration/parts/02.rest-error.spec.ts: -------------------------------------------------------------------------------- 1 | import { RestService } from "../../../src/services"; 2 | 3 | describe("RestService", () => { 4 | let rest: RestService; 5 | 6 | beforeAll(() => { 7 | rest = new RestService("https://jsonplaceholder.typicode.com"); 8 | }); 9 | 10 | test("init", () => { 11 | expect(rest).toBeDefined(); 12 | }); 13 | 14 | describe("execRest()", () => { 15 | describe("when called", () => { 16 | let response: any; 17 | beforeAll(async () => { 18 | response = await rest.execRest("/posts", { 19 | method: "POST", 20 | headers: { 21 | "Content-Type": "application/json", 22 | }, 23 | }); 24 | }); 25 | it("should return response", () => { 26 | expect(response).toBeTruthy(); 27 | }); 28 | }); 29 | 30 | describe("when error", () => { 31 | let error: any; 32 | beforeAll(async () => { 33 | await rest 34 | .execRest("/postzzz", { 35 | method: "POST", 36 | headers: { 37 | "Content-Type": "application/json", 38 | }, 39 | }) 40 | .catch((_error) => { 41 | error = _error; 42 | }); 43 | }); 44 | it("should return response", () => { 45 | expect(error.message).toBe("Not Found"); 46 | }); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /test/integration/parts/03.goerli-link.spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, CHAINS, Environment } from "../../../src"; 2 | 3 | describe( 4 | "Single Deposit Address Generation", 5 | () => { 6 | const axelarAssetTransfer = new AxelarAssetTransfer({ 7 | environment: Environment.TESTNET, 8 | // overwriteResourceUrl: "http://localhost:4000", 9 | }); 10 | 11 | test("bootstrap", () => { 12 | expect(axelarAssetTransfer).toBeDefined(); 13 | }); 14 | 15 | describe("deposit address generation", () => { 16 | let result: string; 17 | 18 | beforeAll(async () => { 19 | result = await axelarAssetTransfer.getDepositAddress( 20 | CHAINS.TESTNET.OSMOSIS, 21 | CHAINS.TESTNET.AVALANCHE, 22 | "0xB8Cd93C83A974649D76B1c19f311f639e62272BC", 23 | "uausdc" 24 | ); 25 | }); 26 | 27 | it("should generate unique deposit addresses", () => { 28 | expect(typeof result).toBe("string"); 29 | expect(result.length).toBeGreaterThan(1); 30 | }); 31 | }); 32 | }, 33 | { 34 | timeout: 20000, 35 | } 36 | ); 37 | -------------------------------------------------------------------------------- /test/integration/unwrap-native-asset/unwrap-native-asset.integration-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, CHAINS, Environment } from "../../../src"; 2 | 3 | const sdk = new AxelarAssetTransfer({ 4 | environment: Environment.TESTNET, 5 | }); 6 | const evmAddress = "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2"; 7 | 8 | describe( 9 | "Unwrap Native Asset", 10 | () => { 11 | describe("getDepositAddressForNativeWrap()", () => { 12 | let depositAddress: string; 13 | 14 | beforeAll(async () => { 15 | const result = await sdk.getDepositAddressForNativeUnwrap( 16 | CHAINS.TESTNET.AVALANCHE, 17 | CHAINS.TESTNET.FANTOM, 18 | evmAddress 19 | ); 20 | depositAddress = result; 21 | }); 22 | 23 | describe("when called", () => { 24 | it("should return deposit address", () => { 25 | expect(depositAddress).toBeTruthy(); 26 | }); 27 | }); 28 | }); 29 | }, 30 | { 31 | timeout: 20000, 32 | } 33 | ); 34 | -------------------------------------------------------------------------------- /test/integration/vitest.integration.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | 3 | export default defineConfig({ 4 | test: { 5 | testTimeout: 300000, 6 | environment: "node", 7 | root: "test/integration", 8 | globals: true, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /test/integration/wrap-native-asset/wrap-native-asset.integration-spec.ts: -------------------------------------------------------------------------------- 1 | import { AxelarAssetTransfer, CHAINS, Environment } from "../../../src"; 2 | 3 | const sdk = new AxelarAssetTransfer({ 4 | environment: Environment.TESTNET, 5 | }); 6 | const evmAddress = "0xA57ADCE1d2fE72949E4308867D894CD7E7DE0ef2"; 7 | 8 | describe( 9 | "Wrap Native Asset", 10 | () => { 11 | describe("getDepositAddressForNativeWrap()", () => { 12 | let depositAddress: string; 13 | 14 | beforeAll(async () => { 15 | depositAddress = await sdk.getDepositAddressForNativeWrap( 16 | CHAINS.TESTNET.AVALANCHE, 17 | CHAINS.TESTNET.SEPOLIA, 18 | evmAddress 19 | ); 20 | }); 21 | 22 | describe("when called", () => { 23 | it("should return deposit address", () => { 24 | expect(depositAddress?.length).toBeGreaterThan(0); 25 | }); 26 | }); 27 | }); 28 | }, 29 | { 30 | timeout: 20000, 31 | } 32 | ); 33 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Language and Environment */ 4 | "target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 5 | "lib": [ 6 | "es2015", 7 | "dom" 8 | ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, 9 | 10 | /* Modules */ 11 | "module": "commonjs" /* Specify what module code is generated. */, 12 | 13 | /* Emit */ 14 | "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, 15 | "declarationMap": true /* Create sourcemaps for d.ts files. */, 16 | "sourceMap": true /* Create source map files for emitted JavaScript files. */, 17 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 18 | "baseUrl": "./", 19 | /* Interop Constraints */ 20 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 21 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 22 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */, 23 | "resolveJsonModule": true, 24 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 25 | 26 | /* Type Checking */ 27 | "strict": true /* Enable all strict type-checking options. */, 28 | "strictNullChecks": true /* When type checking, take into account `null` and `undefined`. */, 29 | "strictPropertyInitialization": false, 30 | 31 | /* Completeness */ 32 | "skipDefaultLibCheck": true /* Skip type checking .d.ts files that are included with TypeScript. */, 33 | "skipLibCheck": true /* Skip type checking all .d.ts files. */, 34 | 35 | "types": ["vitest/globals"] 36 | }, 37 | "include": ["src", "test"], 38 | "exclude": ["node_modules", "dist"], 39 | "files": ["src/global.d.ts", "vitest.config.ts"] 40 | } 41 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | 3 | export default defineConfig({ 4 | test: { 5 | testTimeout: 300000, 6 | environment: "node", 7 | root: "src", 8 | globals: true, 9 | }, 10 | }); 11 | --------------------------------------------------------------------------------