├── src ├── index.class.ts ├── helper │ ├── stellarHelper.ts │ ├── solanaHelper.ts │ ├── ethereumHelper.ts │ ├── bitcoinHelper.ts │ └── cardanoHelper.ts ├── utils │ ├── globalType.ts │ ├── responses │ │ ├── ripple.ts │ │ └── stellar.ts │ ├── payloads │ │ ├── litecoin.ts │ │ ├── cardano.ts │ │ ├── tron.ts │ │ ├── ripple.ts │ │ ├── stellar.ts │ │ ├── bitcoin.ts │ │ ├── beacon.ts │ │ ├── solana.ts │ │ └── ethereum.ts │ ├── response.ts │ ├── utils.ts │ └── constant.ts ├── abi │ ├── index.ts │ ├── erc20.ts │ ├── erc1155.ts │ └── erc721.ts ├── lib │ └── @emurgo │ │ ├── cardano-message-signing-browser │ │ ├── emurgo_message_signing.js │ │ ├── emurgo_message_signing_bg.wasm │ │ ├── emurgo-message-signing-0.1.0.tgz │ │ ├── cardano_serialization_lib.js.flow │ │ ├── package.json │ │ └── emurgo_message_signing_bg.wasm.d.ts │ │ ├── cardano-multiplatform-lib-browser │ │ ├── cardano_multiplatform_lib.js │ │ ├── cardano_multiplatform_lib_bg.wasm │ │ └── package.json │ │ ├── cardano-message-signing-nodejs │ │ ├── emurgo-message-signing-0.1.0.tgz │ │ ├── emurgo_message_signing_bg.wasm │ │ ├── cardano_serialization_lib.js.flow │ │ └── package.json │ │ └── cardano-multiplatform-lib-nodejs │ │ ├── cardano_multiplatform_lib_bg.wasm │ │ └── package.json ├── wallet │ ├── common │ │ └── index.ts │ ├── hedera │ │ ├── index.ts │ │ └── HederaWallet.ts │ ├── index.ts │ ├── litecoin │ │ ├── index.ts │ │ └── LitecoinWallet.ts │ ├── tron │ │ ├── index.ts │ │ └── TronWallet.ts │ ├── stellar │ │ ├── index.ts │ │ └── StellarWallet.ts │ ├── binance │ │ ├── index.ts │ │ └── BinanceWallet.ts │ ├── cardano │ │ ├── index.ts │ │ └── CardanoWallet.ts │ ├── bitcoin │ │ ├── index.ts │ │ └── BitcoinWallet.ts │ ├── ripple │ │ ├── index.ts │ │ └── RippleWallet.ts │ ├── solana │ │ ├── index.ts │ │ └── SolanaWallet.ts │ └── ethereum │ │ ├── index.ts │ │ └── EthereumWallet.ts ├── index.ts ├── type │ ├── interface.ts │ └── type.ts ├── decs.d.ts ├── util_class │ └── ethereum │ │ └── index.ts ├── constant │ └── index.ts └── wallet_class │ ├── bitcoin │ └── index.ts │ └── ethereum │ └── index.ts ├── .npmignore ├── .gitignore ├── mocha.config.example.js ├── .babelrc ├── tsconfig.json ├── test ├── sample_data.ts └── wallet.test.ts ├── LICENSE ├── readme.md ├── package.json └── tsConfig.example.json /src/index.class.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test -------------------------------------------------------------------------------- /src/helper/stellarHelper.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | dist 5 | .vscode -------------------------------------------------------------------------------- /mocha.config.example.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | testTimeout: 500000, 3 | }; 4 | 5 | module.exports = config; 6 | -------------------------------------------------------------------------------- /src/utils/globalType.ts: -------------------------------------------------------------------------------- 1 | /*Global Interface*/ 2 | 3 | export interface AnyObject { 4 | [key: string]: any; 5 | } 6 | -------------------------------------------------------------------------------- /src/utils/responses/ripple.ts: -------------------------------------------------------------------------------- 1 | export interface BalanceResponse { 2 | currency: string; 3 | value: number | string; 4 | } -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", "@babel/preset-typescript" 4 | ] 5 | // "plugins": ["@babel/plugin-transform-modules-commonjs"] 6 | } -------------------------------------------------------------------------------- /src/abi/index.ts: -------------------------------------------------------------------------------- 1 | import erc20ABI from "./erc20"; 2 | import ecr721ABI from "./erc721"; 3 | import erc1155ABI from "./erc1155"; 4 | 5 | export { erc20ABI, ecr721ABI, erc1155ABI } -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-browser/emurgo_message_signing.js: -------------------------------------------------------------------------------- 1 | import * as wasm from "./emurgo_message_signing_bg.wasm"; 2 | export * from "./emurgo_message_signing_bg.js"; -------------------------------------------------------------------------------- /src/utils/payloads/litecoin.ts: -------------------------------------------------------------------------------- 1 | export interface CreateWalletPayload { 2 | derivePath?: string 3 | } 4 | 5 | export interface ImportWalletPayload { 6 | mnemonic: string 7 | } -------------------------------------------------------------------------------- /src/helper/solanaHelper.ts: -------------------------------------------------------------------------------- 1 | import * as solanaWeb3 from '@solana/web3.js'; 2 | 3 | export const provider = (rpcUrl: string) => { 4 | return new solanaWeb3.Connection(rpcUrl); 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-multiplatform-lib-browser/cardano_multiplatform_lib.js: -------------------------------------------------------------------------------- 1 | import * as wasm from "./cardano_multiplatform_lib_bg.wasm"; 2 | export * from "./cardano_multiplatform_lib_bg.js"; -------------------------------------------------------------------------------- /src/utils/responses/stellar.ts: -------------------------------------------------------------------------------- 1 | export interface BalanceResponse { 2 | balance: string; 3 | buying_liabilities: string; 4 | selling_liabilities: string; 5 | asset_type: string; 6 | } -------------------------------------------------------------------------------- /src/wallet/common/index.ts: -------------------------------------------------------------------------------- 1 | import * as bip39 from "bip39"; 2 | 3 | export const generateMnemonic = (): string => { 4 | const mnemonic: string = bip39.generateMnemonic() 5 | return mnemonic; 6 | }; -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-browser/emurgo_message_signing_bg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegenius2/multichain-wallet/HEAD/src/lib/@emurgo/cardano-message-signing-browser/emurgo_message_signing_bg.wasm -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-nodejs/emurgo-message-signing-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegenius2/multichain-wallet/HEAD/src/lib/@emurgo/cardano-message-signing-nodejs/emurgo-message-signing-0.1.0.tgz -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-nodejs/emurgo_message_signing_bg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegenius2/multichain-wallet/HEAD/src/lib/@emurgo/cardano-message-signing-nodejs/emurgo_message_signing_bg.wasm -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-browser/emurgo-message-signing-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegenius2/multichain-wallet/HEAD/src/lib/@emurgo/cardano-message-signing-browser/emurgo-message-signing-0.1.0.tgz -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-multiplatform-lib-browser/cardano_multiplatform_lib_bg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegenius2/multichain-wallet/HEAD/src/lib/@emurgo/cardano-multiplatform-lib-browser/cardano_multiplatform_lib_bg.wasm -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-multiplatform-lib-nodejs/cardano_multiplatform_lib_bg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codegenius2/multichain-wallet/HEAD/src/lib/@emurgo/cardano-multiplatform-lib-nodejs/cardano_multiplatform_lib_bg.wasm -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-browser/cardano_serialization_lib.js.flow: -------------------------------------------------------------------------------- 1 | /** 2 | * Flowtype definitions for cardano_serialization_lib 3 | * Generated by Flowgen from a Typescript Definition 4 | * Flowgen v1.11.0 5 | * @flow 6 | */ 7 | -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-nodejs/cardano_serialization_lib.js.flow: -------------------------------------------------------------------------------- 1 | /** 2 | * Flowtype definitions for cardano_serialization_lib 3 | * Generated by Flowgen from a Typescript Definition 4 | * Flowgen v1.11.0 5 | * @flow 6 | */ 7 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Ethereum, Solana, Bitcoin, Binance, Common, Stellar, Tron } from "./wallet"; 2 | 3 | export = ({ 4 | Ethereum, 5 | Solana, 6 | Bitcoin, 7 | Binance, 8 | Common, 9 | Tron, 10 | Stellar 11 | }); -------------------------------------------------------------------------------- /src/wallet/hedera/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './HederaWallet'; 2 | import { CREATE_WALLET } from '../../utils/constant'; 3 | 4 | /** 5 | * @return wallet response 6 | */ 7 | export async function createWallet() { 8 | const wallet = await Wallet[CREATE_WALLET](); 9 | return wallet; 10 | } -------------------------------------------------------------------------------- /src/wallet/index.ts: -------------------------------------------------------------------------------- 1 | export * as Ethereum from "./ethereum"; 2 | export * as Solana from "./solana"; 3 | export * as Bitcoin from "./bitcoin"; 4 | export * as Binance from "./binance"; 5 | export * as Ripple from "./ripple"; 6 | export * as Tron from "./tron"; 7 | export * as Common from "./common"; 8 | export * as Stellar from "./stellar"; -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emurgo-message-signing", 3 | "version": "0.1.0", 4 | "files": [ 5 | "emurgo_message_signing_bg.wasm", 6 | "emurgo_message_signing.js", 7 | "emurgo_message_signing.d.ts" 8 | ], 9 | "module": "emurgo_message_signing.js", 10 | "types": "emurgo_message_signing.d.ts", 11 | "sideEffects": false 12 | } -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emurgo-message-signing", 3 | "version": "0.1.0", 4 | "files": [ 5 | "emurgo_message_signing_bg.wasm", 6 | "emurgo_message_signing.js", 7 | "emurgo_message_signing_bg.js", 8 | "emurgo_message_signing.d.ts" 9 | ], 10 | "main": "emurgo_message_signing.js", 11 | "types": "emurgo_message_signing.d.ts" 12 | } -------------------------------------------------------------------------------- /src/type/interface.ts: -------------------------------------------------------------------------------- 1 | import type { BigNumber } from "ethers"; 2 | 3 | export interface EvmGasObject { 4 | low: number, 5 | average: number, 6 | fast: number, 7 | lowWei: BigNumber, 8 | averageWei: BigNumber, 9 | fastWei: BigNumber, 10 | lowEth: string; 11 | averageEth: string; 12 | fastEth: string; 13 | safeLowWaitMin: number; 14 | avgWaitMin: number; 15 | fastWaitMin: number 16 | } -------------------------------------------------------------------------------- /src/utils/payloads/cardano.ts: -------------------------------------------------------------------------------- 1 | export interface ImportWalletPayload { 2 | mnemonic: string, 3 | index?: number; 4 | } 5 | 6 | export interface GetBalancePayload { 7 | address: string, 8 | network?: 'mainnet' | 'testnet' | 'preprod' | 'preview' 9 | } 10 | 11 | export interface SendAdaPayload { 12 | paymentKey: any, 13 | fromAddress: string, 14 | toAddress: string, 15 | amount: number, 16 | network?: 'mainnet' | 'testnet' | 'preprod' | 'preview' 17 | } -------------------------------------------------------------------------------- /src/utils/payloads/tron.ts: -------------------------------------------------------------------------------- 1 | export interface BalancePayload { 2 | address: string; 3 | } 4 | 5 | export interface ImportWalletPayload { 6 | mnemonic: string; 7 | nonce?: string; 8 | } 9 | 10 | export interface ImportAccountPayload { 11 | privateKey: string; 12 | } 13 | 14 | export interface SendTrxPayload { 15 | privateKey: string; 16 | fromAddress: string; 17 | toAddress: string; 18 | amount: number 19 | } 20 | 21 | export interface GetTokenInfoPayload { 22 | contractAddress: string 23 | } -------------------------------------------------------------------------------- /src/utils/payloads/ripple.ts: -------------------------------------------------------------------------------- 1 | export interface ImportWalletPayload { 2 | secretKey: string; 3 | } 4 | 5 | export interface ImportAccountPayload { 6 | privateKey: string 7 | } 8 | 9 | export interface BalancesPayload { 10 | address: string; 11 | rpcUrl?: string; 12 | } 13 | 14 | export interface BalancePayload { 15 | address: string; 16 | rpcUrl?: string; 17 | } 18 | 19 | export interface TransferPayload { 20 | secretKey: string; 21 | senderAddress: string; 22 | recipientAddress: string; 23 | amount: number; 24 | rpcUrl?: string; 25 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "target": "ES5", 5 | "lib": ["DOM", "ES5"], 6 | "declaration": true, 7 | "outDir": "dist", 8 | "strict": true, 9 | "allowJs": true, 10 | "moduleResolution": "node", 11 | "baseUrl": ".", 12 | "rootDir": "src", 13 | "paths": { 14 | "*": ["src/*", "node_modules/*"], 15 | }, 16 | "typeRoots": ["./node_modules/@types"], 17 | "types": ["jest"], 18 | "esModuleInterop": true, 19 | "sourceMap": false 20 | }, 21 | "include": ["src/**/*", "decs.d.ts"], 22 | } -------------------------------------------------------------------------------- /src/utils/payloads/stellar.ts: -------------------------------------------------------------------------------- 1 | export interface ImportWalletPayload { 2 | mnemonic: string; 3 | } 4 | 5 | export interface ImportAccountPayload { 6 | privateKey: string; 7 | } 8 | 9 | export interface SendCoinPayload { 10 | privateKey: string; 11 | toAddress: string; 12 | amount: string; 13 | isTestnet?: boolean, 14 | activate?: boolean, 15 | } 16 | 17 | export interface GetBalancesPayload { 18 | publicKey: string; 19 | isTestnet?: boolean 20 | } 21 | 22 | export interface GetBalancePayload { 23 | publicKey: string; 24 | isTestnet?: boolean; 25 | } -------------------------------------------------------------------------------- /src/utils/response.ts: -------------------------------------------------------------------------------- 1 | interface IResponse { 2 | [key: string]: any; 3 | } 4 | 5 | interface IWalletResponse { 6 | address: string | unknown; 7 | privateKey: string; 8 | publicKey?: string; 9 | mnemonic?: string; 10 | nonce?: number; 11 | seed?: string; 12 | } 13 | 14 | type IBalanceResponse = number | string; 15 | 16 | export const response = (args: IResponse) => { 17 | return args; 18 | } 19 | 20 | export const walletResponse = (args: IWalletResponse) => { 21 | return args; 22 | } 23 | 24 | export const balanceResponse = (arg: IBalanceResponse) => { 25 | return arg; 26 | } -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-multiplatform-lib-nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cardano-multiplatform-lib", 3 | "collaborators": [ 4 | "dcSpark" 5 | ], 6 | "description": "Multiplatform SDK for core Cardano blockchain functionality", 7 | "version": "0.1.0", 8 | "license": "MIT", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/dcSpark/cardano-multiplatform-lib" 12 | }, 13 | "files": [ 14 | "cardano_multiplatform_lib_bg.wasm", 15 | "cardano_multiplatform_lib.js", 16 | "cardano_multiplatform_lib.d.ts" 17 | ], 18 | "main": "cardano_multiplatform_lib.js", 19 | "types": "cardano_multiplatform_lib.d.ts" 20 | } -------------------------------------------------------------------------------- /src/wallet/litecoin/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './LitecoinWallet' 2 | import { CREATE_WALLET, IMPORT_WALLET } from '../../utils/constant' 3 | import { ImportWalletPayload } from '../../utils/payloads/litecoin' 4 | 5 | /** 6 | * 7 | * @param args ? derive path 8 | * @returns litecoin wallet 9 | */ 10 | export async function createWallet() { 11 | const wallet = Wallet[CREATE_WALLET]() 12 | return wallet 13 | } 14 | 15 | /** 16 | * 17 | * @param args bip39 mnemonic 18 | * @returns litecoin wallet 19 | */ 20 | export async function importWallet(args: ImportWalletPayload) { 21 | const wallet = Wallet[IMPORT_WALLET](args.mnemonic) 22 | return wallet 23 | } -------------------------------------------------------------------------------- /src/utils/payloads/bitcoin.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface CreateWalletPayload { 3 | network: string; 4 | derivedPath?: string; 5 | } 6 | 7 | export interface ImportWalletPayload { 8 | network: string; 9 | mnemonic: string; 10 | derivedPath?: string; 11 | } 12 | 13 | export interface ImportAccountPayload { 14 | network: string; 15 | privateKey: string; 16 | derivedPath?: string; 17 | } 18 | 19 | export interface TransferPaload { 20 | network: string; 21 | senderPrivatekey: string; 22 | senderAddress: string; 23 | receiveAddress: string; 24 | amount: number; 25 | gasFee?: number; 26 | } 27 | 28 | export interface BalancePayload { 29 | address: string; 30 | } -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-multiplatform-lib-browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cardano-multiplatform-lib", 3 | "collaborators": [ 4 | "dcSpark" 5 | ], 6 | "description": "Multiplatform SDK for core Cardano blockchain functionality", 7 | "version": "0.1.0", 8 | "license": "MIT", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/dcSpark/cardano-multiplatform-lib" 12 | }, 13 | "files": [ 14 | "cardano_multiplatform_lib_bg.wasm", 15 | "cardano_multiplatform_lib.js", 16 | "cardano_multiplatform_lib_bg.js", 17 | "cardano_multiplatform_lib.d.ts" 18 | ], 19 | "module": "cardano_multiplatform_lib.js", 20 | "types": "cardano_multiplatform_lib.d.ts", 21 | "sideEffects": false 22 | } 23 | -------------------------------------------------------------------------------- /test/sample_data.ts: -------------------------------------------------------------------------------- 1 | const SAMPLE_DATA = { 2 | COMMON: { 3 | MNEMONIC: "gorilla ghost swing tourist deer wild purchase seek execute arrive office grow" 4 | }, 5 | ETHEREUM: { 6 | GOERLI_RPC: "https://goerli.infura.io/v3/60d0fc034847460da68aa4501df5fe57", 7 | ZERO_ADDRESS: "0x0000000000000000000000000000000000000000", 8 | SAMPLE_TOKEN_ADDRESS: "0xa8De46D005919aa6a8851C85E60f09884869c50a", 9 | SAMPLE_721_NFT_ADDRESS: "0x7EC3f3CE817F5A5CA3e285022573Df1b1B4DeF7d", 10 | SAMPLE_1155_NFT_ADDRESS: "0xA8bf99a3aDA507bCD0a8ce8982d3d94a4896440B" 11 | }, 12 | BITCOIN: { 13 | SAMPLE_ADDRESS: 'bc1qfgf0eukwjslus64vvcqt2l6t7e85hjp3e28lxp', 14 | TESTNET_ADDRESS: 'mnGd3ZgszE3BJNH6sxVcvJhNRz3qnXQgS7' 15 | } 16 | } 17 | 18 | export default SAMPLE_DATA -------------------------------------------------------------------------------- /src/decs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'ripple-wallet'; 2 | declare module '@faast/tron-payments'; 3 | declare module 'tronweb'; 4 | declare module 'ripple-bip32'; 5 | declare module 'stellar-hd-wallet'; 6 | declare module 'random-hash'; 7 | declare module 'litecore-lib'; 8 | declare module 'litecoin-bip84'; 9 | declare module 'react-native-bip39' 10 | // declare module 'ripple-wallet/lib/ripple_address'; 11 | declare type TronTransaction = typeof import('tronweb'); 12 | declare type TronWeb = typeof import('tronweb'); 13 | declare type TronWebTransaction = typeof import('tronweb'); 14 | declare type TronWebTransactionInfo = typeof import('tronweb'); 15 | declare type TronWebBlock = typeof import('tronweb'); 16 | declare type StellarHDWallet = typeof import('stellar-hd-wallet'); 17 | // declare type RippleBip32 = typeof import('ripple-bip32') -------------------------------------------------------------------------------- /src/helper/ethereumHelper.ts: -------------------------------------------------------------------------------- 1 | import { ethers } from "ethers"; 2 | import ERC721 from "../abi/erc721"; 3 | import { ERC721_INTERFACE_ID } from '../utils/constant'; 4 | 5 | export async function isContractAddress(rpcUrl: string, address: string) { 6 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 7 | try { 8 | const code = await provider.getCode(address); 9 | if (code !== '0x') 10 | return true; 11 | else 12 | return false; 13 | } catch { 14 | return false; 15 | } 16 | } 17 | 18 | export async function isNftContract(rpcUrl: string, address: string) { 19 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 20 | const contract = new ethers.Contract(address, ERC721, provider); 21 | 22 | try { 23 | const isNft = await contract.supportsInterface(ERC721_INTERFACE_ID); 24 | if(isNft) return true; 25 | else return false; 26 | } catch { 27 | return false; 28 | } 29 | } -------------------------------------------------------------------------------- /src/utils/payloads/beacon.ts: -------------------------------------------------------------------------------- 1 | export interface CreateWalletPayload { 2 | derivedPath?: string; 3 | } 4 | 5 | export interface ImportWalletPayload { 6 | mnemonic: string; 7 | } 8 | 9 | export interface ImportAccountPayload { 10 | privateKey: string; 11 | } 12 | 13 | export interface GetBalancePayload { 14 | rpcUrl: string; 15 | address: string; 16 | network: 'testnet' | 'mainnet'; 17 | } 18 | 19 | export interface SendBNBPayload { 20 | rpcUrl: string; 21 | privateKey: string; 22 | fromAddress: string; 23 | recipientAddress: string; 24 | amount: any; 25 | asset: string; 26 | network: 'testnet' | 'mainnet'; 27 | } 28 | 29 | export interface TokenTransferPayload { 30 | rpcUrl: string; 31 | privateKey: string; 32 | fromAddress: string; 33 | recipientAddress: string; 34 | amount: any; 35 | asset: string; 36 | network: 'testnet' | 'mainnet'; 37 | } 38 | 39 | export type AssetsPayload = [ 40 | { 41 | free: string; 42 | frozen: string; 43 | locked: string; 44 | symbol: string; 45 | } 46 | ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Chris Kennedy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/type/type.ts: -------------------------------------------------------------------------------- 1 | // Evm Types 2 | 3 | export type EvmWallet = { 4 | address: string, 5 | privateKey: string, 6 | mnemonic?: string, 7 | nonce?: number 8 | } 9 | 10 | export type EvmAccount = { 11 | address: string, 12 | privateKey: string 13 | } 14 | 15 | export type ERCTokenType = 'ERC20' | 'ERC721' | 'ERC1155' | undefined 16 | 17 | export type IsNFT = { 18 | isNFT: boolean, 19 | tokenType: ERCTokenType 20 | } 21 | 22 | export type EvmTokenDetail = { 23 | name: string, 24 | symbol: string, 25 | decimals: number, 26 | totalSupply: number, 27 | balance: number, 28 | isNft: boolean, 29 | tokenType: ERCTokenType 30 | } 31 | 32 | export type EvmTransaction = { 33 | to: string, 34 | from?: string, 35 | value?: number, 36 | data?: string, 37 | nonce?: number, 38 | gasLimit?: number, 39 | gasPrice?: number 40 | } 41 | 42 | // BTC Types 43 | 44 | export type BtcNetwork = "bitcoin" | "regtest" | "testnet" 45 | 46 | export type BtcWallet = { 47 | address: { 48 | p2pkh: string, 49 | bech32: string 50 | } 51 | privateKey: string, 52 | mnemonic: string 53 | } 54 | 55 | export type BtcAccount = { 56 | address: { 57 | p2pkh: string, 58 | bech32: string 59 | } 60 | privateKey: string 61 | } -------------------------------------------------------------------------------- /src/wallet/tron/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './TronWallet'; 2 | import { CREATE_WALLET, IMPORT_WALLET, IMPORT_ACCOUNT, GET_BALANCE, SEND_COIN, GET_TOKEN } from '../../utils/constant'; 3 | import { BalancePayload, ImportWalletPayload, ImportAccountPayload, SendTrxPayload, GetTokenInfoPayload } from '../../utils/payloads/tron'; 4 | 5 | export async function createWallet() { 6 | const wallet = await Wallet[CREATE_WALLET](); 7 | return wallet; 8 | } 9 | 10 | export async function importWallet(args: ImportWalletPayload) { 11 | const wallet = await Wallet[IMPORT_WALLET](args.mnemonic, args?.nonce) 12 | return wallet 13 | } 14 | 15 | export async function importAccount(args: ImportAccountPayload) { 16 | const wallet = await Wallet[IMPORT_ACCOUNT](args.privateKey) 17 | return wallet 18 | } 19 | 20 | export async function getBalance(args: BalancePayload) { 21 | const balance = await Wallet[GET_BALANCE](args.address); 22 | return balance; 23 | } 24 | 25 | export async function sendCoin(args: SendTrxPayload) { 26 | const result = await Wallet[SEND_COIN](args.privateKey, args.fromAddress, args.toAddress, args.amount) 27 | return result; 28 | } 29 | 30 | export async function getTokenInfo(args: GetTokenInfoPayload) { 31 | const token = await Wallet[GET_TOKEN](args.contractAddress) 32 | return token 33 | } -------------------------------------------------------------------------------- /src/utils/utils.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | import { ethers } from "ethers"; 4 | 5 | export const shuffleArray = (...arrayIn: any) => { 6 | const array = arrayIn.length === 1 && Array.isArray(arrayIn[0]) 7 | ? arrayIn[0] 8 | : arrayIn; 9 | for (let i = array.length - 1; i > 0; i--) { 10 | const j = Math.floor(Math.random() * (i + 1)); 11 | [array[i], array[j]] = [array[j], array[i]]; 12 | } 13 | return array; 14 | }; 15 | 16 | export const fallback = async (fallbacks: any) => { 17 | let firstError; 18 | for (const fn of fallbacks) { 19 | if (!fn) { 20 | continue; 21 | } 22 | try { 23 | return await fn(); 24 | } 25 | catch (error) { 26 | firstError = firstError || error; 27 | } 28 | } 29 | throw firstError || new Error("No result returned"); 30 | }; 31 | 32 | export const gweiToWei = (amount: string | number) => { 33 | const weiValue = ethers.utils.parseUnits(amount.toString(), 'gwei') 34 | return weiValue 35 | } 36 | 37 | export const gweiToEther = (amount: string | number) => { 38 | const weiValue = ethers.utils.parseUnits(amount.toString(), 'gwei') 39 | const etherValue = ethers.utils.formatEther(weiValue) 40 | 41 | return etherValue 42 | } 43 | 44 | export const weiToEther = (amount: string | number) => { 45 | const etherValue = ethers.utils.formatEther(amount.toString()) 46 | return etherValue 47 | } -------------------------------------------------------------------------------- /src/wallet/stellar/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './StellarWallet' 2 | import { 3 | CREATE_WALLET, 4 | IMPORT_WALLET, 5 | IMPORT_ACCOUNT, 6 | SEND_COIN, 7 | GET_BALANCES, 8 | GET_BALANCE 9 | } from '../../utils/constant' 10 | import { 11 | ImportWalletPayload, 12 | ImportAccountPayload, 13 | SendCoinPayload, 14 | GetBalancesPayload, 15 | GetBalancePayload 16 | } from '../../utils/payloads/stellar'; 17 | 18 | export async function createWallet() { 19 | const wallet = await Wallet[CREATE_WALLET](); 20 | return wallet 21 | } 22 | 23 | export async function importWallet(args: ImportWalletPayload) { 24 | const wallet = await Wallet[IMPORT_WALLET](args.mnemonic) 25 | return wallet 26 | } 27 | 28 | export async function importAccount(args: ImportAccountPayload) { 29 | const account = await Wallet[IMPORT_ACCOUNT](args.privateKey) 30 | return account 31 | } 32 | 33 | export async function sendCoin(args: SendCoinPayload) { 34 | const result = await Wallet[SEND_COIN](args.privateKey, args.toAddress, args.amount, args?.isTestnet, args?.activate) 35 | return result 36 | } 37 | 38 | export async function getBalances(args: GetBalancesPayload) { 39 | const balances = await Wallet[GET_BALANCES](args.publicKey, args?.isTestnet) 40 | return balances 41 | } 42 | 43 | export async function getBalance(args: GetBalancePayload) { 44 | const balance = await Wallet[GET_BALANCE](args.publicKey, args?.isTestnet) 45 | return balance 46 | } -------------------------------------------------------------------------------- /src/wallet/binance/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './BinanceWallet'; 2 | 3 | import { 4 | CREATE_WALLET, 5 | IMPORT_WALLET, 6 | IMPORT_ACCOUNT, 7 | GET_BALANCE, 8 | SEND_COIN, 9 | TRANSFER_TOKEN 10 | } from "../../utils/constant"; 11 | import { 12 | ImportWalletPayload, 13 | GetBalancePayload, 14 | SendBNBPayload, 15 | TokenTransferPayload, 16 | ImportAccountPayload 17 | } from "../../utils/payloads/beacon"; 18 | 19 | export function createWallet () { 20 | const wallet = Wallet[CREATE_WALLET](); 21 | return wallet; 22 | } 23 | 24 | export function importWallet(args: ImportWalletPayload) { 25 | const wallet = Wallet[IMPORT_WALLET](args.mnemonic); 26 | return wallet; 27 | } 28 | 29 | export function importAccount(args: ImportAccountPayload) { 30 | const wallet = Wallet[IMPORT_ACCOUNT](args.privateKey); 31 | return wallet; 32 | } 33 | 34 | export async function getBalance(args: GetBalancePayload) { 35 | const balance = await Wallet[GET_BALANCE](args.rpcUrl, args.address, args.network); 36 | return balance; 37 | } 38 | 39 | export async function sendCion(args: SendBNBPayload) { 40 | const tx = await Wallet[SEND_COIN](args.rpcUrl, args.privateKey, args.fromAddress, args.recipientAddress, args.amount, args.network); 41 | return tx; 42 | } 43 | 44 | export async function tokenTransfer(args: TokenTransferPayload) { 45 | const tx = await Wallet[TRANSFER_TOKEN](args.rpcUrl, args.privateKey, args.fromAddress, args.recipientAddress, args.amount, args.network, args.asset); 46 | return tx; 47 | } -------------------------------------------------------------------------------- /src/wallet/cardano/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './CardanoWallet' 2 | import { CREATE_WALLET, IMPORT_WALLET, GET_BALANCES, GET_BALANCE, SEND_COIN } from '../../utils/constant' 3 | import { ImportWalletPayload, GetBalancePayload, SendAdaPayload } from '../../utils/payloads/cardano'; 4 | 5 | /** 6 | * 7 | * @returns Cardano Shelley account wallet 8 | */ 9 | export async function createWallet() { 10 | const wallet = await Wallet[CREATE_WALLET](); 11 | return wallet 12 | } 13 | 14 | /** 15 | * 16 | * @param args account index 17 | * @returns Cardano Shelley account wallet 18 | */ 19 | export async function importWallet(args: ImportWalletPayload) { 20 | const wallet = await Wallet[IMPORT_WALLET](args.mnemonic, args?.index); 21 | return wallet 22 | } 23 | 24 | /** 25 | * 26 | * @param args payment_key_hash_bech32 | network ID 27 | * @returns account assets and balances 28 | */ 29 | export async function getBalances(args: GetBalancePayload) { 30 | const balances = await Wallet[GET_BALANCES](args.address, args?.network) 31 | return balances 32 | } 33 | 34 | /** 35 | * 36 | * @param args payment_key_hash_bech32 | network ID 37 | * @returns ADA asset of account 38 | */ 39 | export async function getBalance(args: GetBalancePayload) { 40 | const balance = await Wallet[GET_BALANCE](args.address, args?.network) 41 | return balance 42 | } 43 | 44 | /** 45 | * 46 | * @param args paymentkey | sender address | receiver address | ADA amount 47 | * @returns payment transaction hash 48 | */ 49 | export async function sendCoin(args: SendAdaPayload) { 50 | const result = await Wallet[SEND_COIN](args.paymentKey, args.fromAddress, args.toAddress, args.amount, args?.network) 51 | return result 52 | } -------------------------------------------------------------------------------- /src/utils/payloads/solana.ts: -------------------------------------------------------------------------------- 1 | export interface BalancePayload { 2 | rpcUrl: string; 3 | address: string; 4 | tokenAddress?: string; 5 | } 6 | 7 | export interface CreateWalletPayload { 8 | derivedPath?: string; 9 | } 10 | 11 | export interface ImportWalletPayload { 12 | derivedPath?: string; 13 | mnemonic: string; 14 | } 15 | 16 | export interface ImportAccountPayload { 17 | privateKey: string; 18 | } 19 | 20 | export interface TransferPayload { 21 | rpcUrl: string; 22 | privateKey: string; 23 | from: string; 24 | to: string; 25 | amount: number; 26 | } 27 | 28 | export interface TokenTransferPayload { 29 | rpcUrl: string; 30 | privateKey: string; 31 | tokenAddress: string; 32 | to: string; 33 | amount: number; 34 | } 35 | 36 | export interface TokenInfoPayload { 37 | rpcUrl: string; 38 | cluster?: 'mainnet-beta' | 'testnet' | 'devnet', 39 | addsress: string; 40 | } 41 | 42 | export interface TokenListPayload { 43 | cluster: 'mainnet-beta' | 'testnet' | 'devnet'; 44 | } 45 | 46 | export interface TransactionPayload { 47 | rpcUrl: string; 48 | hash: string; 49 | } 50 | 51 | export interface ISplTokenInfo { 52 | chainId: number; 53 | address: string; 54 | symbol: string; 55 | name: string; 56 | decimals: number; 57 | logoURI?: string; 58 | tags: string[]; 59 | extensions: any; 60 | } 61 | 62 | export interface ITokenInfo { 63 | name: string; 64 | symbol: string; 65 | address: string; 66 | decimals: number; 67 | logoUrl?: string; 68 | totalSupply: number; 69 | } 70 | 71 | export interface GetTokenListPayload { 72 | network?: string; 73 | cluster?: 'mainnet-beta' | 'testnet' | 'devnet' 74 | } -------------------------------------------------------------------------------- /src/wallet/bitcoin/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './BitcoinWallet'; 2 | 3 | import { 4 | CreateWalletPayload, 5 | ImportWalletPayload, 6 | ImportAccountPayload, 7 | BalancePayload, 8 | TransferPaload 9 | } from '../../utils/payloads/bitcoin'; 10 | 11 | import { 12 | CREATE_WALLET, 13 | IMPORT_WALLET, 14 | GET_BALANCE, 15 | SEND_COIN, 16 | IMPORT_ACCOUNT 17 | } from './../../utils/constant'; 18 | 19 | /** 20 | * 21 | * @param args 22 | * @returns BTC wallet 23 | */ 24 | export async function createWallet(args: CreateWalletPayload) { 25 | const wallet = await Wallet[CREATE_WALLET](args.network, args?.derivedPath); 26 | return wallet; 27 | } 28 | 29 | 30 | /** 31 | * 32 | * @param args 33 | * @returns BTC wallet 34 | */ 35 | export async function importWallet(args: ImportWalletPayload) { 36 | const wallet = await Wallet[IMPORT_WALLET](args.network, args.mnemonic, args?.derivedPath) 37 | return wallet; 38 | } 39 | 40 | /** 41 | * 42 | * @param args 43 | * @returns BTC wallet 44 | */ 45 | export async function importAccount(args: ImportAccountPayload) { 46 | const wallet = await Wallet[IMPORT_ACCOUNT](args.network, args.privateKey, args?.derivedPath) 47 | return wallet 48 | } 49 | 50 | /** 51 | * 52 | * @param args 53 | * @returns balance 54 | */ 55 | export async function getBalance(args: BalancePayload) { 56 | const balance = await Wallet[GET_BALANCE](args.address); 57 | return balance; 58 | } 59 | 60 | /** 61 | * 62 | * @param args 63 | * @returns Raw transaction 64 | */ 65 | export async function sendCoin(args: TransferPaload) { 66 | const tx = await Wallet[SEND_COIN](args.network, args.senderPrivatekey, args.senderAddress, args.receiveAddress, args.amount, args?.gasFee); 67 | 68 | return tx; 69 | } -------------------------------------------------------------------------------- /src/wallet/ripple/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './RippleWallet'; 2 | import { 3 | CREATE_WALLET, 4 | IMPORT_WALLET, 5 | IMPORT_ACCOUNT, 6 | GET_BALANCE, 7 | GET_BALANCES, 8 | SEND_COIN 9 | } from '../../utils/constant'; 10 | 11 | import { 12 | ImportWalletPayload, 13 | ImportAccountPayload, 14 | BalancePayload, 15 | BalancesPayload, 16 | TransferPayload 17 | } from '../../utils/payloads/ripple'; 18 | 19 | /** 20 | * 21 | * @returns Ripple Address account 22 | */ 23 | export async function createWallet() { 24 | const wallet = await Wallet[CREATE_WALLET](); 25 | return wallet; 26 | } 27 | 28 | /** 29 | * 30 | * @param args 31 | * @returns Ripple Address account 32 | */ 33 | export async function importWallet(args: ImportWalletPayload) { 34 | const wallet = await Wallet[IMPORT_WALLET](args.secretKey); 35 | return wallet; 36 | } 37 | 38 | export async function importAccount(args: ImportAccountPayload) { 39 | const wallet = await Wallet[IMPORT_ACCOUNT](args.privateKey) 40 | return wallet 41 | } 42 | 43 | /** 44 | * 45 | * @param args 46 | * @returns Xrp Transfer Transaction 47 | */ 48 | export async function sendCoin(args: TransferPayload) { 49 | const tx = await Wallet[SEND_COIN](args.secretKey, args.senderAddress, args.recipientAddress, args.amount, args?.rpcUrl); 50 | return tx; 51 | } 52 | 53 | /** 54 | * 55 | * @param args 56 | * @returns Assets Balances 57 | */ 58 | export async function getBalances(args: BalancesPayload) { 59 | const balances = await Wallet[GET_BALANCES](args.address, args?.rpcUrl); 60 | return balances; 61 | } 62 | 63 | /** 64 | * 65 | * @param args 66 | * @returns Native asset Balance 67 | */ 68 | export async function getBalance(args: BalancePayload) { 69 | const balance = await Wallet[GET_BALANCE](args.address, args?.rpcUrl); 70 | return balance 71 | } -------------------------------------------------------------------------------- /src/utils/payloads/ethereum.ts: -------------------------------------------------------------------------------- 1 | import type { BigNumber } from "ethers"; 2 | 3 | /*Global Interface*/ 4 | export interface AnyObject { 5 | [key: string]: any; 6 | } 7 | 8 | /*Ethereum Interface*/ 9 | export interface CreateWalletPayload { 10 | derivationPath?: string; 11 | nonce?: number; 12 | } 13 | 14 | export interface ImportWalletPayload { 15 | mnemonic: string; 16 | nonce: number; 17 | derivationPath?: string; 18 | } 19 | 20 | export interface CreateMasterSeedPayload { 21 | mnemonic: string; 22 | } 23 | 24 | export interface CreateAccountPayload { 25 | rootKey: any; 26 | nonce: number; 27 | } 28 | 29 | export interface ImportAccountPayload { 30 | privateKey: string; 31 | } 32 | 33 | export interface ProviderPayload { 34 | rpcUrl: string; 35 | address: string; 36 | } 37 | 38 | export interface BalancePayload { 39 | defaultProviderRpcUrl: string; 40 | address: string; 41 | } 42 | 43 | export interface GetTokenPayload { 44 | rpcUrl: string; 45 | tokenAddress: string; 46 | address: string; 47 | } 48 | 49 | export interface SendPayload { 50 | rpcUrl: string; 51 | privateKey: string; 52 | receiveAddress: string; 53 | amount: string; 54 | gasPrice?: any; 55 | gasLimit?: any; 56 | } 57 | 58 | export interface TokenApproveAndTransferPayload { 59 | rpcUrl: string; 60 | privateKey: string; 61 | receiveAddress: string; 62 | tokenAddress: string; 63 | amount: any; 64 | gasPrice?: any; 65 | gasLimit?: any; 66 | } 67 | 68 | export interface GasEstimationPayload { 69 | low: number; 70 | average: number; 71 | fast: number; 72 | lowWei: BigNumber; 73 | averageWei: BigNumber; 74 | fastWei: BigNumber; 75 | lowEth: string; 76 | averageEth: string; 77 | fastEth: string; 78 | safeLowWaitMin: number; 79 | avgWaitMin: number; 80 | fastWaitMin: number 81 | } -------------------------------------------------------------------------------- /src/wallet/hedera/HederaWallet.ts: -------------------------------------------------------------------------------- 1 | import Hethers from '@hethers/wallet' 2 | import Hedera from '@hashgraph/sdk' 3 | import * as bip39 from 'bip39' 4 | import axios from 'axios' 5 | import { CREATE_WALLET, GET_HEDERA_ACCOUNTID_ENDPOINT } from '../../utils/constant' 6 | import { AnyObject } from '../../utils/globalType' 7 | import { response } from '../../utils/response' 8 | 9 | const createWallet1 = async ( _isTestnet?: boolean ) => { 10 | 11 | const isTestnet = _isTestnet || false 12 | const client = isTestnet ? Hedera.Client.forTestnet() : Hedera.Client.forMainnet() 13 | const mnemonic = await Hedera.Mnemonic.generate12() 14 | const newAccountPrivateKey = await Hedera.PrivateKey.fromMnemonic(mnemonic) 15 | const newAccountPublicKey = newAccountPrivateKey.publicKey 16 | const transaction = await new Hedera.AccountCreateTransaction().setKey(newAccountPublicKey).setInitialBalance(new Hedera.Hbar(1000)); 17 | 18 | const txResponse = await transaction.execute(client) 19 | 20 | const receipt = await txResponse.getReceipt(client) 21 | 22 | const newAccountId = receipt.accountId; 23 | // const getReceipt = await newAccount.getReceipt(client) 24 | // const newAccountId = getReceipt.accountId 25 | // const accountId = new AccountId(0) 26 | // const wallet = new Wallet(accountId, newAccountPrivateKey) 27 | // const id = wallet.accountId 28 | // const accountId = await axios.get(`${GET_HEDERA_ACCOUNTID_ENDPOINT}${newAccountPublicKey}`) 29 | return response({ 30 | newAccountId 31 | }) 32 | } 33 | 34 | const createWallet = async (_isTestnet?: boolean) => { 35 | const isTestnet = _isTestnet || false 36 | const wallet = Hethers.Wallet.createRandom() 37 | 38 | return response({ 39 | mnemonic: wallet.mnemonic.phrase, 40 | alias: (await wallet.getAlias()) 41 | }) 42 | } 43 | 44 | const HederaWallet: AnyObject = { 45 | [CREATE_WALLET]: createWallet 46 | } 47 | 48 | export default HederaWallet; -------------------------------------------------------------------------------- /src/wallet/litecoin/LitecoinWallet.ts: -------------------------------------------------------------------------------- 1 | // import * as ecc from 'tiny-secp256k1'; 2 | import * as bip39 from 'bip39'; 3 | import * as bitcoin from 'bitcoinjs-lib'; 4 | import * as bip32 from 'bip32'; 5 | // import BIP32Factory from 'bip32'; 6 | import litecore from 'litecore-lib' 7 | 8 | 9 | import { CREATE_WALLET, IMPORT_WALLET, LITECOIN_DEFAULT, LITECOIN_NETWORK_PROTOTYPE } from "../../utils/constant"; 10 | import { AnyObject } from "../../utils/globalType"; 11 | import { response, walletResponse } from '../../utils/response'; 12 | 13 | const createWallet = () => { 14 | const path = LITECOIN_DEFAULT; 15 | 16 | const mnemonic = bip39.generateMnemonic(); 17 | 18 | const seed = bip39.mnemonicToSeedSync(mnemonic); 19 | // const bip32 = BIP32Factory(ecc); 20 | const root = bip32.fromSeed(seed, LITECOIN_NETWORK_PROTOTYPE); 21 | 22 | const account = root.derivePath(path); 23 | const node = account.derive(0); 24 | 25 | // const privateKey = new litecore.PrivateKey() 26 | // const address = privateKey.toAddress() 27 | 28 | const address = bitcoin.payments.p2pkh({ 29 | pubkey: node.publicKey, 30 | network: LITECOIN_NETWORK_PROTOTYPE 31 | }).address; 32 | 33 | return walletResponse({ 34 | privateKey: node.toWIF(), 35 | address: address, 36 | mnemonic: mnemonic 37 | }) 38 | } 39 | 40 | const importWallet = (mnemonic: string) => { 41 | const path = LITECOIN_DEFAULT; 42 | 43 | const seed = bip39.mnemonicToSeedSync(mnemonic); 44 | // const bip32 = BIP32Factory(ecc); 45 | const root = bip32.fromSeed(seed, LITECOIN_NETWORK_PROTOTYPE); 46 | 47 | const account = root.derivePath(path); 48 | const node = account.derive(0); 49 | 50 | const address = bitcoin.payments.p2pkh({ 51 | pubkey: node.publicKey, 52 | network: LITECOIN_NETWORK_PROTOTYPE 53 | }).address; 54 | 55 | return walletResponse({ 56 | address: address, 57 | privateKey: node.toWIF(), 58 | mnemonic: mnemonic 59 | }) 60 | } 61 | 62 | const LitecoinWallet: AnyObject = { 63 | [CREATE_WALLET]: createWallet, 64 | [IMPORT_WALLET]: importWallet 65 | } 66 | 67 | export default LitecoinWallet; -------------------------------------------------------------------------------- /src/wallet/solana/index.ts: -------------------------------------------------------------------------------- 1 | //Import Wallet 2 | import Wallet from './SolanaWallet'; 3 | 4 | //Import Actions 5 | import { 6 | CREATE_WALLET, 7 | IMPORT_WALLET, 8 | IMPORT_ACCOUNT, 9 | SEND_COIN, 10 | TRANSFER_TOKEN, 11 | GET_TOKEN, 12 | GET_TOKEN_LIST, 13 | GET_TRANSACTION, 14 | GET_BALANCE 15 | } from '../../utils/constant'; 16 | 17 | //Import Argument Payloads 18 | import { 19 | CreateWalletPayload, 20 | ImportWalletPayload, 21 | ImportAccountPayload, 22 | TransferPayload, 23 | TokenTransferPayload, 24 | TokenInfoPayload, 25 | TokenListPayload, 26 | TransactionPayload, 27 | BalancePayload 28 | } from '../../utils/payloads/solana'; 29 | 30 | /** 31 | * 32 | * @param args 33 | * @returns wallet 34 | */ 35 | export async function createWallet(args: CreateWalletPayload) { 36 | const wallet = await Wallet[CREATE_WALLET](args?.derivedPath); 37 | return wallet; 38 | } 39 | 40 | /** 41 | * 42 | * @param args 43 | * @returns wallet 44 | */ 45 | export async function importWallet(args: ImportWalletPayload) { 46 | const wallet = await Wallet[IMPORT_WALLET](args.mnemonic, args?.derivedPath); 47 | return wallet; 48 | } 49 | 50 | /** 51 | * 52 | * @param args 53 | * @returns account 54 | */ 55 | export async function importAccount(args: ImportAccountPayload) { 56 | const account = await Wallet[IMPORT_ACCOUNT](args.privateKey); 57 | return account; 58 | } 59 | 60 | /** 61 | * 62 | * @param args 63 | * @returns tx 64 | */ 65 | export async function sendCoin(args: TransferPayload) { 66 | const tx = await Wallet[SEND_COIN](args.rpcUrl, args.privateKey, args.from, args.to, args.amount); 67 | return tx; 68 | } 69 | 70 | /** 71 | * 72 | * @param args 73 | * @returns tx 74 | */ 75 | export async function transferToken(args: TokenTransferPayload) { 76 | const tx = await Wallet[TRANSFER_TOKEN](args.rpcUrl, args.privateKey, args.tokenAddress, args.to, args.amount); 77 | return tx; 78 | } 79 | 80 | /** 81 | * 82 | * @param args 83 | * @returns token info 84 | */ 85 | export async function getToken(args: TokenInfoPayload) { 86 | const token = await Wallet[GET_TOKEN](args.rpcUrl, args.cluster, args.addsress); 87 | return token; 88 | } 89 | 90 | /** 91 | * 92 | * @param args 93 | * @returns token list 94 | */ 95 | export async function getTokenList(args: TokenListPayload) { 96 | const tokenList = await Wallet[GET_TOKEN_LIST](args.cluster); 97 | return tokenList; 98 | } 99 | 100 | /** 101 | * 102 | * @param args 103 | * @returns tx 104 | */ 105 | export async function getTransaction(args: TransactionPayload) { 106 | const transaction = await Wallet[GET_TRANSACTION](args.rpcUrl, args.hash); 107 | return transaction; 108 | } 109 | 110 | 111 | /** 112 | * 113 | * @param args 114 | * @returns balance 115 | */ 116 | export async function getBalance(args: BalancePayload) { 117 | const balance = await Wallet[GET_BALANCE](args.rpcUrl, args.address, args.tokenAddress); 118 | return balance; 119 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 👷‍♂️🚧 This library is under construction 🚧👷‍♂️ 2 | ## multichain-wallet-sdk [multichain wallet development kit] 3 | 4 | ⚠ Old version package was deprecated from NPM. New one will be published. ⚠ 5 | 6 | ### installation 7 | ``` 8 | npm install vipay-multichain-wallet 9 | ``` 10 | ### import (es5) 11 | ```javascript 12 | const vipay = require('vipay-multichain-wallet'); 13 | ``` 14 | ### import (es6) 15 | ```javascript 16 | import vipay from 'vipay-multichain-wallet'; 17 | ``` 18 | 19 | ### Create Wallet (Phrase words) using `common` function 20 | ```javascript 21 | const mnemonic = vipay.Common.generateMnemonic(); 22 | console.log(mnemonic); //sea gulp tiger cup zoo ... 23 | ``` 24 | 25 | ### functions (ethereum) 26 | - Create Wallet 27 | - Recover wallet from phrase words 28 | - Import account from private key 29 | - Get ETH balance 30 | - Send ETH 31 | - Approve/Transfer Token 32 | 33 | ### usage (ethereum) 34 | ```javascript 35 | //Create Wallet 36 | const wallet = await vipay.Ethereum.createWallet({}); 37 | 38 | //Import Wallet 39 | const wallet = await vipay.Ethereum.importWallet({ 40 | mnemonic: 'sea glup tiger cup zoo ...', //phrase words 41 | }); 42 | 43 | //Import Account 44 | const account = await vipay.Ethereum.importAccount({ 45 | privateKey: '0x....' //private key 46 | }); 47 | 48 | //Get ETH balance 49 | const balance = await vipay.Ethereum.getBalance({ 50 | defaultProviderRpcUrl: 'https://https://bsc-dataseed1.defibit.io/', //this is bsc mainnet rpc url (put any ethereum network rpc url here) 51 | address: '0x...' 52 | }); 53 | 54 | //Send ETH 55 | const tx = await vipay.Ethereum.sendEther({ 56 | rpcUrl: 'https://....',// (pur rpc url here) 57 | privateKey: '0x....', 58 | receiveAddress: '0x...', 59 | amount: '0.1', //ETH amount 60 | gasPrice: 'xxx', //transaction gas fee 61 | gasLimit: 'xxx', //gas limit 62 | }); 63 | 64 | //Token Transfer 65 | const tx = await vipay.Ethereum.tokenTransfer({ 66 | rpcUrl: 'https://....',// (pur rpc url here) 67 | privateKey: '0x....', 68 | receiveAddress: '0x...', 69 | tokenAddress: '0x...', 70 | amount: '0.1', //Token amount 71 | gasPrice: 'xxx', //transaction gas fee 72 | gasLimit: 'xxx', //gas limit 73 | }); 74 | 75 | //Token Approve 76 | const tx = await vipay.Ethereum.tokenApprove({ 77 | rpcUrl: 'https://....',// (pur rpc url here) 78 | privateKey: '0x....', 79 | receiveAddress: '0x...', 80 | tokenAddress: '0x...', 81 | amount: '0.1', //Token amount 82 | gasPrice: 'xxx', //transaction gas fee 83 | gasLimit: 'xxx', //gas limit 84 | }) 85 | ``` 86 | 87 | ### functions (solana) 88 | - Create Wallet 89 | - Recover wallet from phrase words 90 | - Import account from private key 91 | - Send SOL token 92 | - Get token info 93 | - Get availale token list 94 | - Get balance 95 | - Get transaction 96 | 97 | ### usage (solana) 98 | ```javascript 99 | const wallet = await vipay.Solana.createWallet({}); 100 | 101 | const importWallet = await vipay.Solana.importWallet({ 102 | mnemonic: 'xxx'//mnemonic 103 | }) 104 | 105 | const importAccount = await vipay.Solana.importWallet({ 106 | privateKey: 'xxx' //privatekey 107 | }) 108 | 109 | const tx = await vipay.Solana.transfer({ 110 | rpcUrl: 'https://api.devnet.solana.com', //rpcurl 111 | privateKey: 'xxx', 112 | from: 'xxx', 113 | to: 'xxx', 114 | amount: 0.1 115 | }) 116 | 117 | // please refer library for more functions 118 | ``` 119 | 120 | ### More blockchains and networks will be added. 121 | 122 | ## Enjoy your work ~!!! 123 | -------------------------------------------------------------------------------- /src/wallet/binance/BinanceWallet.ts: -------------------------------------------------------------------------------- 1 | import { 2 | generateMnemonic, 3 | getPrivateKeyFromMnemonic, 4 | getPublicKeyFromPrivateKey, 5 | getAddressFromPublicKey 6 | } from "@binance-chain/javascript-sdk/lib/crypto"; 7 | 8 | import { BncClient } from "@binance-chain/javascript-sdk/lib/client"; 9 | 10 | import { response, walletResponse, balanceResponse } from '../../utils/response'; 11 | 12 | import { AnyObject } from "../../utils/globalType"; 13 | import { 14 | CREATE_WALLET, 15 | IMPORT_WALLET, 16 | IMPORT_ACCOUNT, 17 | GET_BALANCE, 18 | SEND_COIN, 19 | TRANSFER_TOKEN, 20 | } from "./../../utils/constant"; 21 | 22 | import { AssetsPayload } from "../../utils/payloads/beacon"; 23 | 24 | const createWallet = () => { 25 | const mnemonic = generateMnemonic(); 26 | const privateKey = getPrivateKeyFromMnemonic(mnemonic); 27 | const publicKey = getPublicKeyFromPrivateKey(privateKey); 28 | const address = getAddressFromPublicKey(publicKey, 'bnb'); 29 | 30 | return walletResponse({ 31 | mnemonic, 32 | privateKey, 33 | publicKey, 34 | address 35 | }) 36 | } 37 | 38 | const importWallet = (mnemonic: string) => { 39 | const privateKey = getPrivateKeyFromMnemonic(mnemonic); 40 | const publicKey = getPublicKeyFromPrivateKey(privateKey); 41 | const address = getAddressFromPublicKey(publicKey, 'bnb'); 42 | 43 | return walletResponse({ 44 | mnemonic, 45 | privateKey, 46 | publicKey, 47 | address 48 | }) 49 | } 50 | 51 | const importAccount = (privateKey: string) => { 52 | const publicKey = getPublicKeyFromPrivateKey(privateKey); 53 | const address = getAddressFromPublicKey(publicKey, 'bnb'); 54 | 55 | return walletResponse({ 56 | privateKey, 57 | publicKey, 58 | address 59 | }) 60 | } 61 | 62 | const getBalance = async (rpcUrl: string, address: string, network: 'testnet' | 'mainnet') => { 63 | const client = new BncClient(rpcUrl); 64 | client.chooseNetwork(network); 65 | const balance: AssetsPayload = await client.getBalance(address); 66 | 67 | if(balance.length <= 0 || balance == null || balance == undefined || !balance.filter(asset => asset.symbol === 'BNB')) { 68 | return balanceResponse(0) 69 | } else { 70 | return balanceResponse( balance.filter(asset => {return asset.symbol === 'BNB'})[0].free ) 71 | } 72 | } 73 | 74 | const sendBNB = async (rpcUrl: string, privateKey: string, fromAddress: string, recipientAddress: string, amount: any, network: 'testnet' | 'mainnet') => { 75 | const client = new BncClient(rpcUrl); 76 | client.chooseNetwork(network); 77 | client.setPrivateKey(privateKey); 78 | 79 | const tx = await client.transfer(fromAddress, recipientAddress, amount, 'BNB'); 80 | return response({ 81 | tx 82 | }) 83 | } 84 | 85 | const tokenTransfer = async (rpcUrl: string, privateKey: string, fromAddress: string, recipientAddress: string, amount: any, network: 'testnet' | 'mainnet', asset: string) => { 86 | const client = new BncClient(rpcUrl); 87 | client.chooseNetwork(network); 88 | client.setPrivateKey(privateKey); 89 | 90 | const tx = await client.transfer(fromAddress, recipientAddress, amount, asset); 91 | return response({ 92 | tx 93 | }) 94 | } 95 | 96 | const BeaconWallet: AnyObject = { 97 | [CREATE_WALLET]: createWallet, 98 | [IMPORT_WALLET]: importWallet, 99 | [IMPORT_ACCOUNT]: importAccount, 100 | [GET_BALANCE]: getBalance, 101 | [SEND_COIN]: sendBNB, 102 | [TRANSFER_TOKEN]: tokenTransfer 103 | } 104 | 105 | export default BeaconWallet; -------------------------------------------------------------------------------- /src/wallet/tron/TronWallet.ts: -------------------------------------------------------------------------------- 1 | import TronWeb from 'tronweb'; 2 | import * as bip39 from "bip39"; 3 | import * as bip32 from "bip32" 4 | // import { BIP32Factory } from "bip32"; 5 | // import * as ecc from "tiny-secp256k1"; 6 | 7 | import { 8 | TRON_DEFAULT, 9 | TRON_MAINNET, 10 | TRON_MAINNET_FULL_NODE, 11 | TRON_MAINNET_SOLIDITY_NODE, 12 | TRON_MAINNET_EVENT_SERVER, 13 | TRONGRID_API_KEY, 14 | TRON_SHASTA_TESTNET, 15 | CREATE_WALLET, 16 | IMPORT_WALLET, 17 | IMPORT_ACCOUNT, 18 | GET_BALANCE, 19 | SEND_COIN, 20 | GET_TOKEN 21 | } from "../../utils/constant"; 22 | import { AnyObject } from "../../utils/globalType"; 23 | import { response, walletResponse, balanceResponse } from "../../utils/response"; 24 | 25 | const createWallet = async (nonce?: number) => { 26 | // const bip32 = BIP32Factory(ecc); 27 | const mnemonic = bip39.generateMnemonic(); 28 | const seed = await bip39.mnemonicToSeed(mnemonic); 29 | const node = await bip32.fromSeed(seed); 30 | const child = await node.derivePath(`m/44'/195'/${nonce || 0}'`); 31 | const privateKeyBuf = child.privateKey; 32 | const privateKeyHex = privateKeyBuf?.toString("hex"); 33 | const privateKey = String(privateKeyHex); 34 | const address = TronWeb.address.fromPrivateKey(privateKey); 35 | 36 | return walletResponse({ 37 | mnemonic, 38 | privateKey, 39 | address, 40 | }); 41 | }; 42 | 43 | const importWallet = async (mnemonic: string, nonce?: string) => { 44 | 45 | // const bip32 = BIP32Factory(ecc); 46 | const seed = await bip39.mnemonicToSeed(mnemonic); 47 | const node = await bip32.fromSeed(seed); 48 | const child = await node.derivePath(`m/44'/195'/${nonce || 0}'`); 49 | const privateKeyBuf = child.privateKey; 50 | const privateKeyHex = privateKeyBuf?.toString("hex"); 51 | const privateKey = String(privateKeyHex); 52 | const address = TronWeb.address.fromPrivateKey(privateKey); 53 | 54 | return walletResponse({ 55 | mnemonic, 56 | privateKey, 57 | address, 58 | }); 59 | }; 60 | 61 | const importAccount = async (privateKey: string) => { 62 | 63 | const address = TronWeb.address.fromPrivateKey(privateKey); 64 | 65 | return walletResponse({ 66 | privateKey, 67 | address, 68 | }); 69 | }; 70 | 71 | const getBalance = async (address: string) => { 72 | const tronWeb = new TronWeb(TRON_MAINNET_FULL_NODE, TRON_MAINNET_SOLIDITY_NODE, TRON_MAINNET_EVENT_SERVER) 73 | 74 | const balance = await tronWeb.trx.getBalance(address) 75 | 76 | return balanceResponse(balance) 77 | }; 78 | 79 | const sendTrx = async (privateKey: string, fromAddress: string, toAddress: string, amount: number) => { 80 | const tronWeb = new TronWeb(TRON_MAINNET_FULL_NODE, TRON_MAINNET_SOLIDITY_NODE, TRON_MAINNET_EVENT_SERVER) 81 | const unsignedTx = await tronWeb.transactionBuilder.sendTrx(toAddress, amount, fromAddress) 82 | const signedTx = await tronWeb.trx.sign(unsignedTx, privateKey) 83 | const confirmed = await tronWeb.trx.sendRawTransaction(signedTx) 84 | 85 | return confirmed 86 | } 87 | 88 | const getTokenInfo = async(contractAddress: string) => { 89 | const tronWeb = new TronWeb(TRON_MAINNET_FULL_NODE, TRON_MAINNET_SOLIDITY_NODE, TRON_MAINNET_EVENT_SERVER) 90 | const tokenInfo = await tronWeb.trx.getTokenByID(contractAddress) 91 | 92 | return tokenInfo 93 | } 94 | 95 | const TronWallet: AnyObject = { 96 | [CREATE_WALLET]: createWallet, 97 | [IMPORT_WALLET]: importWallet, 98 | [IMPORT_ACCOUNT]: importAccount, 99 | [GET_BALANCE]: getBalance, 100 | [SEND_COIN]: sendTrx, 101 | [GET_TOKEN]: getTokenInfo 102 | }; 103 | 104 | export default TronWallet; -------------------------------------------------------------------------------- /src/wallet/ripple/RippleWallet.ts: -------------------------------------------------------------------------------- 1 | import * as rippleWallet from "ripple-wallet"; 2 | // import RippleAddress from "ripple-wallet/lib/ripple_address"; 3 | import { Wallet, Client } from "xrpl"; 4 | import * as xrpl from "xrpl"; 5 | import * as bip39 from 'bip39'; 6 | 7 | import { response, walletResponse, balanceResponse } from "./../../utils/response"; 8 | import { BalanceResponse } from "../../utils/responses/ripple"; 9 | import { AnyObject } from "../../utils/globalType"; 10 | 11 | import { 12 | CREATE_WALLET, 13 | IMPORT_WALLET, 14 | IMPORT_ACCOUNT, 15 | SEND_COIN, 16 | GET_BALANCE, 17 | GET_BALANCES, 18 | RIPPLE_NETWORK_RPC_URL_2, 19 | } from "../../utils/constant"; 20 | 21 | const createWallet = async () => { 22 | const mnemonic = bip39.generateMnemonic(); 23 | const wallet = await Wallet.fromMnemonic(mnemonic); 24 | // const wallet = rippleWallet.generate(); 25 | // const address = RippleAddress.fromPublicKey(wallet.publicKey); 26 | 27 | return walletResponse({ 28 | mnemonic, 29 | seed: wallet?.seed, 30 | privateKey: wallet.privateKey, 31 | address: wallet.address, 32 | }); 33 | }; 34 | 35 | const importWallet = async (mnemonic: string) => { 36 | // const seed = bip39.mnemonicToSeed(mnemonic); 37 | const wallet = await Wallet.fromMnemonic(mnemonic); 38 | // const address = RippleAddress.fromPublicKey(wallet.publicKey); 39 | 40 | return walletResponse({ 41 | address: wallet.address, 42 | seed: wallet?.seed, 43 | privateKey: wallet.privateKey, 44 | mnemonic, 45 | }); 46 | }; 47 | 48 | const importAccount = async (secretKey: string) => { 49 | const account = await Wallet.fromSeed(secretKey); 50 | return walletResponse({ 51 | address: account.address, 52 | privateKey: account.privateKey, 53 | publicKey: account.publicKey 54 | }); 55 | }; 56 | 57 | const getBalances = async (address: string, rpcUrl?: string) => { 58 | const client = new Client(rpcUrl || RIPPLE_NETWORK_RPC_URL_2); 59 | await client.connect(); 60 | 61 | const balances = await client.getBalances(address); 62 | 63 | return response(balances); 64 | }; 65 | 66 | const getBalance = async (address: string, rpcUrl?: string) => { 67 | const client = new Client(rpcUrl || RIPPLE_NETWORK_RPC_URL_2); 68 | await client.connect(); 69 | 70 | const balances = await client.getBalances(address); 71 | const balance = balances.filter((item: BalanceResponse) => item.currency === 'XRP')[0]['value'] 72 | 73 | return balanceResponse( balance ); 74 | }; 75 | 76 | const sendXrp = async ( 77 | secretKey: string, 78 | senderAddress: string, 79 | recipientAddress: string, 80 | amount: number, 81 | rpcUrl?: string 82 | ) => { 83 | const client = new Client(rpcUrl || RIPPLE_NETWORK_RPC_URL_2); 84 | await client.connect(); 85 | 86 | const wallet = await Wallet.fromSeed(secretKey); 87 | 88 | const prepared = await client.autofill({ 89 | TransactionType: "Payment", 90 | Account: senderAddress, 91 | Amount: xrpl.xrpToDrops(amount), 92 | Destination: recipientAddress, 93 | }); 94 | 95 | const signed = wallet.sign(prepared); 96 | 97 | const tx = await client.submitAndWait(signed.tx_blob); 98 | 99 | client.disconnect(); 100 | 101 | return response({ 102 | tx: tx.result.meta, 103 | }); 104 | }; 105 | 106 | const RippleWallet: AnyObject = { 107 | [CREATE_WALLET]: createWallet, 108 | [IMPORT_WALLET]: importWallet, 109 | [IMPORT_ACCOUNT]: importAccount, 110 | [GET_BALANCES]: getBalances, 111 | [GET_BALANCE]: getBalance, 112 | [SEND_COIN]: sendXrp, 113 | }; 114 | 115 | export default RippleWallet; 116 | -------------------------------------------------------------------------------- /src/util_class/ethereum/index.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | import { ethers } from "ethers" 3 | import { ETHER_GASSTATION_API } from "../../utils/constant" 4 | import { EvmGasObject } from "../../type/interface" 5 | 6 | class Util { 7 | /** 8 | * 9 | * @param amount 10 | * @returns {BigInt} 11 | */ 12 | static gweiToWei = (amount: string | number): BigInt => { 13 | const weiValue = ethers.parseUnits(amount.toString(), 'gwei') 14 | return weiValue 15 | } 16 | 17 | /** 18 | * 19 | * @param amount 20 | * @returns {String} 21 | */ 22 | static gweiToEther = (amount: string | number): string => { 23 | const weiValue = ethers.parseUnits(amount.toString(), 'gwei') 24 | const etherValue = ethers.formatEther(weiValue) 25 | 26 | return etherValue 27 | } 28 | 29 | /** 30 | * 31 | * @param amount 32 | * @returns {String} 33 | */ 34 | static weiToEther = (amount: string | number): string => { 35 | const etherValue = ethers.formatEther(amount.toString()) 36 | return etherValue 37 | } 38 | 39 | /** 40 | * 41 | * @returns {Promise} 42 | */ 43 | static getGas = async (): Promise => { 44 | try { 45 | const gasResponse = await axios.get(ETHER_GASSTATION_API) 46 | const estimatedGas = gasResponse.data 47 | 48 | const low = Number(estimatedGas.safeLow / 10) 49 | const average = Number(estimatedGas.average / 10) 50 | const fast = Number(estimatedGas.fast / 10) 51 | const lowWei = await this.gweiToWei(low) 52 | const averageWei = await this.gweiToWei(average) 53 | const fastWei = await this.gweiToWei(fast) 54 | const lowEth = await this.gweiToEther(low) 55 | const averageEth = await this.gweiToEther(average) 56 | const fastEth = await this.gweiToEther(fast) 57 | const safeLowWaitMin = estimatedGas.safeLowWait; 58 | const avgWaitMin = estimatedGas.avgWait; 59 | const fastWaitMin = estimatedGas.fastWait; 60 | 61 | return { 62 | low, 63 | average, 64 | fast, 65 | lowWei, 66 | averageWei, 67 | fastWei, 68 | lowEth, 69 | averageEth, 70 | fastEth, 71 | safeLowWaitMin, 72 | avgWaitMin, 73 | fastWaitMin 74 | } 75 | } 76 | catch (error) { 77 | throw error 78 | } 79 | } 80 | 81 | /** 82 | * 83 | * @param rpcURL 84 | * @returns {Promise} 85 | */ 86 | static getJsonRPCLatency = async (rpcURL: string): Promise => { 87 | try { 88 | const provider = new ethers.JsonRpcProvider(rpcURL) 89 | 90 | const before = Date.now() 91 | 92 | await provider.getBlock('latest') 93 | 94 | const after = Date.now() 95 | 96 | return after - before 97 | } 98 | catch(error) { 99 | throw error 100 | } 101 | } 102 | 103 | /** 104 | * 105 | * @param rpcURL 106 | * @returns {Promise} 107 | */ 108 | static getWebSocketRPCLatency = async (rpcURL: string): Promise => { 109 | try { 110 | const provider = new ethers.WebSocketProvider(rpcURL) 111 | 112 | const before = Date.now() 113 | 114 | await provider.getBlock('latest') 115 | 116 | const after = Date.now() 117 | 118 | return after - before 119 | } 120 | catch(error) { 121 | throw error 122 | } 123 | } 124 | } 125 | 126 | export default Util -------------------------------------------------------------------------------- /src/wallet/ethereum/index.ts: -------------------------------------------------------------------------------- 1 | import Wallet from './EthereumWallet'; 2 | //import payload type 3 | import { 4 | CreateWalletPayload, 5 | ImportWalletPayload, 6 | CreateMasterSeedPayload, 7 | CreateAccountPayload, 8 | ImportAccountPayload, 9 | BalancePayload, 10 | GetTokenPayload, 11 | SendPayload, 12 | TokenApproveAndTransferPayload 13 | } from '../../utils/payloads/ethereum'; 14 | 15 | //import Consts 16 | import { 17 | CREATE_WALLET, 18 | IMPORT_WALLET, 19 | CREATE_MASTERSEED, 20 | CREATE_ACCOUNT, 21 | IMPORT_ACCOUNT, 22 | GET_BALANCE, 23 | GET_TOKEN_BALANCE, 24 | GET_TOKEN, 25 | SEND_COIN, 26 | APPROVE_TOKEN, 27 | TRANSFER_TOKEN 28 | } from '../../utils/constant'; 29 | 30 | /** 31 | * 32 | * @description Create wallet 33 | * @param args 34 | * @returns Wallet 35 | */ 36 | export async function createWallet(args: CreateWalletPayload) { 37 | const wallet = await Wallet[CREATE_WALLET](args.derivationPath, args.nonce); 38 | return wallet; 39 | } 40 | 41 | /** 42 | * 43 | * @description Import wallet from mnemonic phrase words 44 | * @param args 45 | * @returns Imported Wallet 46 | */ 47 | export async function importWallet(args: ImportWalletPayload) { 48 | const wallet = await Wallet[IMPORT_WALLET](args.mnemonic, args.nonce, args.derivationPath,); 49 | return wallet; 50 | } 51 | 52 | 53 | /** 54 | * @description Create master seed private key 55 | * @param args 56 | * @returns Master Seed 57 | */ 58 | export async function createMasterSeed(args: CreateMasterSeedPayload) { 59 | const seed = await Wallet[CREATE_MASTERSEED](args.mnemonic); 60 | return seed; 61 | } 62 | 63 | /** 64 | * 65 | * @description Create Wallet from root private key 66 | * @param args 67 | * @returns Created Account 68 | */ 69 | export async function createAccount(args: CreateAccountPayload) { 70 | const account = await Wallet[CREATE_ACCOUNT](args.rootKey, args.nonce); 71 | return account; 72 | } 73 | 74 | /** 75 | * 76 | * @description Import Account from private key 77 | * @param args 78 | * @returns Import Account 79 | */ 80 | export async function importAccount(args: ImportAccountPayload) { 81 | const account = await Wallet[IMPORT_ACCOUNT](args.privateKey); 82 | return account; 83 | } 84 | 85 | /** 86 | * 87 | * @param args 88 | * @returns Balance of current account. 89 | */ 90 | export async function getBalance (args: BalancePayload) { 91 | const balance = await Wallet[GET_BALANCE](args.defaultProviderRpcUrl, args.address); 92 | return balance; 93 | } 94 | 95 | /** 96 | * 97 | * @param args 98 | * @returns Token balance 99 | */ 100 | export async function getTokenBalance (args: GetTokenPayload) { 101 | const balance = await Wallet[GET_TOKEN_BALANCE](args.tokenAddress, args.rpcUrl, args.address) 102 | return balance 103 | } 104 | 105 | /** 106 | * 107 | * @param args 108 | * @returns Token information 109 | */ 110 | export async function getToken (args: GetTokenPayload) { 111 | const token = await Wallet[GET_TOKEN](args.tokenAddress, args.rpcUrl, args.address); 112 | return token; 113 | } 114 | 115 | /** 116 | * 117 | * @param args 118 | * @returns transaction result 119 | */ 120 | export async function sendCoin(args: SendPayload) { 121 | const tx = await Wallet[SEND_COIN](args.rpcUrl, args.privateKey, args.receiveAddress, args.amount, args?.gasPrice, args?.gasLimit); 122 | return tx; 123 | } 124 | 125 | /** 126 | * 127 | * @param args 128 | * @returns transaction result 129 | */ 130 | export async function tokenApprove(args: TokenApproveAndTransferPayload) { 131 | const tx = await Wallet[APPROVE_TOKEN](args.rpcUrl, args.privateKey, args.receiveAddress, args.tokenAddress, args.amount, args.gasPrice, args.gasLimit); 132 | return tx; 133 | } 134 | 135 | /** 136 | * 137 | * @param args 138 | * @returns transaction result 139 | */ 140 | export async function tokenTransfer(args: TokenApproveAndTransferPayload) { 141 | const tx = await Wallet[TRANSFER_TOKEN](args.rpcUrl, args.privateKey, args.receiveAddress, args.tokenAddress, args.amount, args?.gasPrice, args?.gasLimit); 142 | return tx; 143 | } -------------------------------------------------------------------------------- /src/wallet/stellar/StellarWallet.ts: -------------------------------------------------------------------------------- 1 | import StellarSDK from 'stellar-sdk'; 2 | import StellarHDWallet from 'stellar-hd-wallet'; 3 | import axios from 'axios'; 4 | import { response, walletResponse } from '../../utils/response'; 5 | import { BalanceResponse } from '../../utils/responses/stellar'; 6 | import { 7 | STELLAR_TESTNET_API, 8 | CREATE_WALLET, 9 | IMPORT_WALLET, 10 | IMPORT_ACCOUNT, 11 | STELLAR_MAINNET_SERVER, 12 | STELLAR_TESTNET_SERVER, 13 | SEND_COIN, 14 | GET_BALANCES, 15 | GET_BALANCE 16 | } from '../../utils/constant'; 17 | import { AnyObject } from '../../utils/globalType'; 18 | 19 | const createWallet = async () => { 20 | const mnemonic = StellarHDWallet.generateMnemonic({entropyBits: 128}) 21 | const wallet = StellarHDWallet.fromMnemonic(mnemonic) 22 | 23 | return walletResponse({ 24 | privateKey: wallet.getSecret(0), 25 | address: wallet.getPublicKey(0), 26 | publicKey: wallet.getPublicKey(0), 27 | mnemonic: mnemonic 28 | }) 29 | } 30 | 31 | const importWallet = async (mnemonic: string) => { 32 | const wallet = StellarHDWallet.fromMnemonic(mnemonic) 33 | 34 | return walletResponse({ 35 | privateKey: wallet.getSecret(0), 36 | address: wallet.getPublicKey(0), 37 | publicKey: wallet.getPublicKey(0), 38 | mnemonic: mnemonic, 39 | }) 40 | } 41 | 42 | const importAccount = async (privateKey: string) => { 43 | const account = StellarSDK.Keypair.fromSecret(privateKey) 44 | return walletResponse( { 45 | address: account.publicKey(), 46 | privateKey: account.secret(), 47 | publicKey: account.publicKey(), 48 | } ) 49 | } 50 | 51 | const sendXLM = async (privateKey: string, toAddress: string, amount: string, isTestnet?:boolean, activate?: boolean) => { 52 | const _isTestnet = isTestnet || false; 53 | 54 | const server = new StellarSDK.Server( _isTestnet ? STELLAR_TESTNET_SERVER : STELLAR_MAINNET_SERVER) 55 | const senderAccount = StellarSDK.Keypair.fromSecret(privateKey) 56 | 57 | var transaction: any; 58 | 59 | // Activate account 60 | if(_isTestnet && activate) { 61 | try { 62 | // await axios.get(STELLAR_TESTNET_API + senderAccount.publicKey()) 63 | await axios.get(STELLAR_TESTNET_API + toAddress) 64 | } 65 | catch (_err) { 66 | return response({ 67 | Error: _err 68 | }) 69 | } 70 | } 71 | 72 | // Build transaction 73 | try { 74 | const [{ max_fee: { mode: fee },}, sender, ] = await Promise.all([ 75 | server.feeStats(), 76 | server.loadAccount(senderAccount.publicKey()), 77 | ]); 78 | 79 | transaction = new StellarSDK.TransactionBuilder(sender, { 80 | fee, 81 | networkPassphrase: _isTestnet ? StellarSDK.Networks.TESTNET : StellarSDK.Networks.MAINNET, 82 | }).addOperation( 83 | StellarSDK.Operation.payment({ 84 | destination: toAddress, 85 | asset: StellarSDK.Asset.native(), 86 | amount, 87 | }), 88 | ) 89 | .setTimeout(30) 90 | .build(); 91 | 92 | transaction.sign(senderAccount); 93 | } 94 | catch (_err) { 95 | return response({ 96 | Error: _err 97 | }) 98 | } 99 | 100 | // Cast transaction 101 | try { 102 | const transactionResult = await server.submitTransaction(transaction); 103 | return response( transactionResult ) 104 | } catch (_err) { 105 | return response({ 106 | Error: _err, 107 | }) 108 | } 109 | } 110 | 111 | const getBalances = async (publicKey: string, isTestnet?: boolean) => { 112 | const _isTestnet = isTestnet || false 113 | const server = new StellarSDK.Server( _isTestnet ? STELLAR_TESTNET_SERVER : STELLAR_MAINNET_SERVER) 114 | const account = await server.loadAccount(publicKey) 115 | const balances = account.balances; 116 | 117 | return response( balances ) 118 | } 119 | 120 | const getBalance = async (publicKey: string, isTestnet?: boolean) => { 121 | const _isTestnet = isTestnet || false 122 | const server = new StellarSDK.Server( _isTestnet ? STELLAR_TESTNET_SERVER : STELLAR_MAINNET_SERVER) 123 | const account = await server.loadAccount(publicKey) 124 | const balance = account.balances.filter((item:BalanceResponse) => item.asset_type === 'native')[0]['balance'] 125 | 126 | return walletResponse( balance ) 127 | } 128 | 129 | const StellarWallet: AnyObject = { 130 | [CREATE_WALLET]: createWallet, 131 | [IMPORT_WALLET]: importWallet, 132 | [IMPORT_ACCOUNT]: importAccount, 133 | [SEND_COIN]: sendXLM, 134 | [GET_BALANCES]: getBalances, 135 | [GET_BALANCE]: getBalance 136 | } 137 | 138 | export default StellarWallet -------------------------------------------------------------------------------- /src/wallet/bitcoin/BitcoinWallet.ts: -------------------------------------------------------------------------------- 1 | // import BIP32Factory from 'bip32'; 2 | import * as bip32 from 'bip32' 3 | import * as bip39 from 'bip39' 4 | import * as bitcoin from 'bitcoinjs-lib'; 5 | import { PrivateKey } from 'bitcore-lib'; 6 | 7 | import axios from 'axios'; 8 | import { fetchUTXOs } from '../../helper/bitcoinHelper'; 9 | 10 | import { response, walletResponse, balanceResponse } from '../../utils/response'; 11 | import { 12 | BITCOIN_DEFAULT, 13 | BTC_MAINNET, 14 | BTC_REGTEST, 15 | BTC_TESTNET, 16 | GET_BALANCE 17 | } from '../../utils/constant'; 18 | import { 19 | CREATE_WALLET, 20 | IMPORT_WALLET, 21 | IMPORT_ACCOUNT, 22 | SEND_COIN 23 | } from '../../utils/constant'; 24 | import { AnyObject } from '../../utils/globalType'; 25 | 26 | const createWallet = (_network: string, derivedPath?: string) => { 27 | 28 | let network; 29 | 30 | switch(_network) { 31 | case BTC_MAINNET: 32 | network = bitcoin.networks.bitcoin; 33 | break; 34 | case BTC_REGTEST: 35 | network = bitcoin.networks.regtest; 36 | break; 37 | case BTC_TESTNET: 38 | network = bitcoin.networks.testnet; 39 | break; 40 | default: 41 | network = bitcoin.networks.bitcoin; 42 | break; 43 | } 44 | 45 | const path = derivedPath || BITCOIN_DEFAULT; 46 | 47 | const mnemonic = bip39.generateMnemonic(); 48 | const seed = bip39.mnemonicToSeedSync(mnemonic); 49 | 50 | const root = bip32.fromSeed(seed, network); 51 | 52 | const account = root.derivePath(path); 53 | const node = account.derive(0); 54 | 55 | const address = bitcoin.payments.p2pkh({ 56 | pubkey: node.publicKey, 57 | network: network 58 | }).address; 59 | 60 | return walletResponse({ 61 | address: address, 62 | privateKey: node.toWIF(), 63 | mnemonic: mnemonic 64 | }) 65 | } 66 | 67 | const importWallet = async (_network: string, mnemonic: string, derivedPath?: string) => { 68 | let network; 69 | 70 | switch(_network) { 71 | case BTC_MAINNET: 72 | network = bitcoin.networks.bitcoin; 73 | break; 74 | case BTC_REGTEST: 75 | network = bitcoin.networks.regtest; 76 | break; 77 | case BTC_TESTNET: 78 | network = bitcoin.networks.testnet; 79 | break; 80 | default: 81 | network = bitcoin.networks.bitcoin; 82 | break; 83 | } 84 | 85 | const path = derivedPath || BITCOIN_DEFAULT; 86 | 87 | const seed = bip39.mnemonicToSeedSync(mnemonic); 88 | // const bip32 = BIP32Factory(ecc); 89 | const root = bip32.fromSeed(seed, network); 90 | 91 | const account = root.derivePath(path); 92 | const node = account.derive(0); 93 | 94 | const address = bitcoin.payments.p2pkh({ 95 | pubkey: node.publicKey, 96 | network: network 97 | }).address; 98 | 99 | return walletResponse({ 100 | address: address, 101 | privateKey: node.toWIF(), 102 | mnemonic: mnemonic 103 | }) 104 | } 105 | 106 | const importAccount = async (_network: string, _privateKey: string) => { 107 | let network; 108 | 109 | switch(_network) { 110 | case BTC_MAINNET: 111 | network = bitcoin.networks.bitcoin; 112 | break; 113 | case BTC_REGTEST: 114 | network = bitcoin.networks.regtest; 115 | break; 116 | case BTC_TESTNET: 117 | network = bitcoin.networks.testnet; 118 | break; 119 | default: 120 | network = bitcoin.networks.bitcoin; 121 | break; 122 | } 123 | 124 | const privateKey = new PrivateKey(_privateKey); 125 | 126 | const publicKey = privateKey.publicKey.toBuffer(); 127 | 128 | const address = bitcoin.payments.p2pkh({ 129 | pubkey: publicKey, 130 | network: network 131 | }).address; 132 | 133 | return walletResponse({ 134 | address: address, 135 | privateKey: _privateKey, 136 | }) 137 | } 138 | 139 | const getBalance = async (address: string) => { 140 | let balance; 141 | try { 142 | // balance = await axios.get(`https://blockchain.info/q/addressbalance/${address}`); 143 | balance = await axios.get(`https://blockstream.info/api/address/${address}/utxo`) 144 | } catch (err: any) { 145 | return new Error(err); 146 | } 147 | 148 | return balanceResponse( balance.data ) 149 | } 150 | 151 | const sendBtc = async (_network: string, senderPrivateKey: string, senderAddress: string, receiveAddress: string, amount: number, gasFee?: number) => { 152 | let network 153 | 154 | switch(_network) { 155 | case BTC_MAINNET: 156 | network = bitcoin.networks.bitcoin; 157 | break; 158 | case BTC_REGTEST: 159 | network = bitcoin.networks.regtest; 160 | break; 161 | case BTC_TESTNET: 162 | network = bitcoin.networks.testnet; 163 | break; 164 | default: 165 | network = bitcoin.networks.bitcoin; 166 | break; 167 | } 168 | 169 | const utxos = await fetchUTXOs(_network, senderAddress) 170 | 171 | return response({ 172 | provateKey: senderPrivateKey, 173 | network: _network, 174 | from: senderAddress, 175 | to: receiveAddress, 176 | amount: amount, 177 | fee: gasFee, 178 | utxos: utxos 179 | }) 180 | } 181 | 182 | const BitcoinWallet: AnyObject = { 183 | [CREATE_WALLET]: createWallet, 184 | [IMPORT_WALLET]: importWallet, 185 | [IMPORT_ACCOUNT]: importAccount, 186 | [GET_BALANCE]: getBalance, 187 | [SEND_COIN]: sendBtc 188 | } 189 | 190 | export default BitcoinWallet; -------------------------------------------------------------------------------- /src/abi/erc20.ts: -------------------------------------------------------------------------------- 1 | const erc20ABI = [ 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 | export default erc20ABI -------------------------------------------------------------------------------- /src/helper/bitcoinHelper.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import axios from "axios"; 3 | import { shuffleArray, fallback } from "../utils/utils"; 4 | import { AnyObject } from "../utils/globalType"; 5 | 6 | interface UTXO { 7 | readonly txHash: string; 8 | readonly vOut: number; 9 | readonly amount: number; 10 | readonly scriptPubKey?: string; 11 | readonly confirmations: number; 12 | } 13 | 14 | const sortUTXOs = (a: UTXO, b: UTXO) => { 15 | // Sort greater values first 16 | if (a.amount !== b.amount) { 17 | return b.amount - a.amount; 18 | } 19 | // Sort older UTXOs first 20 | if (a.confirmations !== b.confirmations) { 21 | return a.confirmations - b.confirmations; 22 | } 23 | return a.txHash <= b.txHash ? -1 : 1; 24 | }; 25 | 26 | const getAPIUrl = (testnet: string) => `https://blockstream.info/${testnet ? "testnet/" : ""}api`; 27 | 28 | const fetchTXs = async (network: string, address: string, confirmations: number = 0, limit = 25, offset = 0, onlyUnspent = false) => { 29 | const url = `https://api.blockchain.info/haskoin-store/${network}/address/${address}/transactions/full?limit=${limit}&offset=${offset}`; 30 | const response = (await axios.get(url)).data; 31 | let latestBlock; 32 | const received = []; 33 | for (const tx of response) { 34 | latestBlock = latestBlock || (await fetchLatestBlock(network)); 35 | const txConfirmations = tx.block && tx.block.height 36 | ? Math.max(latestBlock - tx.block.height + 1, 0) 37 | : 0; 38 | for (let i = 0; i < tx.outputs.length; i++) { 39 | const vout = tx.outputs[i]; 40 | if (vout.address === address && 41 | // If the onlyUnspent flag is true, check that the tx is unspent. 42 | (!onlyUnspent || vout.spent === false)) { 43 | received.push({ 44 | txHash: tx.txid, 45 | amount: vout.value, 46 | vOut: i, 47 | confirmations: txConfirmations, 48 | }); 49 | } 50 | } 51 | } 52 | return received 53 | .filter((utxo) => confirmations === 0 || utxo.confirmations >= confirmations) 54 | .sort(sortUTXOs); 55 | }; 56 | 57 | const fetchLatestBlock = async (network: string) => { 58 | const statsUrl = `https://api.blockchain.info/haskoin-store/${network}/block/best?notx=true`; 59 | const statsResponse = (await axios.get(statsUrl)).data; 60 | return statsResponse.height; 61 | }; 62 | 63 | const fetchUTXOsFromBlockchair = async (network: string, address: string, confirmations: number = 0) => { 64 | const url = `https://api.blockchair.com/${network}/dashboards/address/${address}?limit=0,100`; 65 | const response = (await axios.get(url)).data; 66 | let latestBlock = response.context.state; 67 | if (latestBlock === 0) { 68 | const statsUrl = `https://api.blockchair.com/${network}/stats`; 69 | const statsResponse = (await axios.get(statsUrl)).data; 70 | latestBlock = statsResponse.data.blocks - 1; 71 | } 72 | return response.data[address].utxo 73 | .map((utxo: AnyObject) => ({ 74 | txHash: utxo.transaction_hash, 75 | amount: utxo.value, 76 | vOut: utxo.index, 77 | confirmations: utxo.block_id === -1 ? 0 : latestBlock - utxo.block_id + 1, 78 | })) 79 | .filter((utxo: AnyObject) => confirmations === 0 || utxo.confirmations >= confirmations) 80 | .sort(sortUTXOs); 81 | }; 82 | 83 | const fetchUTXOsFromSochain = async (network: string, address: string, confirmations: number = 0) => { 84 | const url = `https://sochain.com/api/v2/get_tx_unspent/${network}/${address}/${confirmations}`; 85 | const response = await axios.get(url); 86 | return (response.data.data.txs.map((utxo: AnyObject) => ({ 87 | txHash: utxo.txid, 88 | amount: utxo.value, 89 | // scriptPubKey: utxo.script_hex, 90 | vOut: utxo.output_no, 91 | confirmations: utxo.confirmations, 92 | }))) 93 | .filter((utxo: AnyObject) => confirmations === 0 || utxo.confirmations >= confirmations) 94 | .sort(sortUTXOs); 95 | }; 96 | 97 | const fetchUTXOsFromBlockchain = async (network: string, address: string, confirmations: number = 0, limit = 25, offset = 0) => fetchTXs(network, address, confirmations, limit, offset, true); 98 | 99 | 100 | const fetchUTXOsFromBlockstream = async (network: string, address: string, confirmations: number = 0) => { 101 | const apiUrl = getAPIUrl(network); 102 | const response = await axios.get(`${apiUrl}/address/${address}/utxo`); 103 | const heightResponse = await axios.get(`${apiUrl}/blocks/tip/height`); 104 | return response.data 105 | .map((utxo: AnyObject) => ({ 106 | txHash: utxo.txid, 107 | amount: utxo.value, 108 | vOut: utxo.vout, 109 | confirmations: utxo.status.confirmed 110 | ? 1 + 111 | parseInt(heightResponse.data, 10) - 112 | utxo.status.block_height 113 | : 0, 114 | })) 115 | .filter((utxo: AnyObject) => confirmations === 0 || utxo.confirmations >= confirmations) 116 | .sort(sortUTXOs); 117 | }; 118 | 119 | export const fetchUTXOs = async (network: string, address: string, confirmation?: number) => { 120 | const _endpoints = [ 121 | ...[shuffleArray( 122 | (await fetchUTXOsFromBlockchair(network, address)), 123 | (await fetchUTXOsFromSochain(network, address)), 124 | (await fetchUTXOsFromBlockchain(network, address)), 125 | (await fetchUTXOsFromBlockstream(network, address)) 126 | ) || 127 | shuffleArray( 128 | (await fetchUTXOsFromBlockchair(network, address)) || 129 | (await fetchUTXOsFromSochain(network, address)) || 130 | (await fetchUTXOsFromBlockchain(network, address)) || 131 | (await fetchUTXOsFromBlockstream(network, address)) 132 | )] 133 | ] 134 | 135 | return _endpoints; 136 | } -------------------------------------------------------------------------------- /test/wallet.test.ts: -------------------------------------------------------------------------------- 1 | import EthereumWallet from '../src/wallet_class/ethereum' 2 | import BitcoinWallet from '../src/wallet_class/bitcoin' 3 | import SAMPLE_DATA from './sample_data' 4 | 5 | jest.setTimeout(50000) 6 | 7 | describe("Wallet Test", () => { 8 | describe("Ethereum Wallet Test", () => { 9 | let ethereumWallet: EthereumWallet; 10 | 11 | beforeAll(() => { 12 | ethereumWallet = new EthereumWallet(SAMPLE_DATA.ETHEREUM.GOERLI_RPC) 13 | }) 14 | 15 | it("Check Initial wallet data", () => { 16 | expect(typeof ethereumWallet.privateKey).toBe('string') 17 | expect(typeof ethereumWallet.address).toBe('string') 18 | expect(typeof ethereumWallet.chainId).toBe('number') 19 | }) 20 | 21 | it("createWallet()", () => { 22 | const wallet = ethereumWallet.createWallet() 23 | 24 | expect(typeof wallet.mnemonic).toBe('string') 25 | expect(typeof wallet.privateKey).toBe('string') 26 | expect(typeof wallet.address).toBe('string') 27 | expect(typeof wallet.nonce).toBe('number') 28 | }) 29 | 30 | it("recoverWallet()", () => { 31 | const wallet = ethereumWallet.recoverWallet(SAMPLE_DATA.COMMON.MNEMONIC) 32 | 33 | expect(typeof wallet.privateKey).toBe('string') 34 | expect(typeof wallet.address).toBe('string') 35 | expect(typeof wallet.mnemonic).toBe('string') 36 | expect(typeof wallet.nonce).toBe('number') 37 | }) 38 | 39 | it("createMasterSeedFromMnemonic()", async () => { 40 | const seed = await ethereumWallet.createMasterSeedFromMnemonic(SAMPLE_DATA.COMMON.MNEMONIC) 41 | 42 | expect(typeof seed).toBe('object') 43 | }) 44 | 45 | it("createAccount()", async () => { 46 | const seed = await ethereumWallet.createMasterSeedFromMnemonic(SAMPLE_DATA.COMMON.MNEMONIC) 47 | const account = await ethereumWallet.createAccount(seed, 0) 48 | 49 | expect(typeof account.privateKey).toBe('string') 50 | expect(typeof account.address).toBe('string') 51 | }) 52 | 53 | it("importAccount()", async () => { 54 | const seed = await ethereumWallet.createMasterSeedFromMnemonic(SAMPLE_DATA.COMMON.MNEMONIC) 55 | const account = await ethereumWallet.createAccount(seed, 0) 56 | const importedAccount = ethereumWallet.importAccount(account.privateKey) 57 | 58 | expect(account.address.toLowerCase()).toStrictEqual(importedAccount.address.toLowerCase()) 59 | }) 60 | 61 | it("getBalance()", async () => { 62 | const addressBalance = await ethereumWallet.getBalance(SAMPLE_DATA.ETHEREUM.ZERO_ADDRESS) 63 | const selfBalance = await ethereumWallet.getBalance() 64 | 65 | console.log(selfBalance) 66 | 67 | expect(typeof addressBalance).toBe('bigint') 68 | expect(typeof selfBalance).toBe('bigint') 69 | }) 70 | 71 | it("getToken()", () => {}) 72 | 73 | it("getTokenBalance()", () => {}) 74 | 75 | it("sendEther()", () => {}) 76 | 77 | it("tokenApprove()", () => {}) 78 | 79 | it("tokenTransfer()", () => {}) 80 | 81 | it("isContractAddress()", async () => { 82 | const isContractAddress_true = await ethereumWallet.isContractAddress(SAMPLE_DATA.ETHEREUM.SAMPLE_TOKEN_ADDRESS) 83 | const isContractAddress_false = await ethereumWallet.isContractAddress(SAMPLE_DATA.ETHEREUM.ZERO_ADDRESS) 84 | 85 | expect(isContractAddress_true).toBe(true) 86 | expect(isContractAddress_false).toBe(false) 87 | }) 88 | 89 | it("isERC721NFT()", async () => { 90 | const isERC721NFT_true = await ethereumWallet.isERC721NFT(SAMPLE_DATA.ETHEREUM.SAMPLE_721_NFT_ADDRESS) 91 | const isERC721NFT_false = await ethereumWallet.isERC721NFT(SAMPLE_DATA.ETHEREUM.SAMPLE_1155_NFT_ADDRESS) 92 | 93 | expect(isERC721NFT_true).toBe(true) 94 | expect(isERC721NFT_false).toBe(false) 95 | }) 96 | 97 | it("isERC1155NFT()", async () => { 98 | const isERC1155NFT_true = await ethereumWallet.isERC1155NFT(SAMPLE_DATA.ETHEREUM.SAMPLE_1155_NFT_ADDRESS) 99 | const isERC1155NFT_false = await ethereumWallet.isERC1155NFT(SAMPLE_DATA.ETHEREUM.SAMPLE_721_NFT_ADDRESS) 100 | 101 | expect(isERC1155NFT_true).toBe(true) 102 | expect(isERC1155NFT_false).toBe(false) 103 | }) 104 | }) 105 | 106 | describe("Bitcoin Wellet Test", () => { 107 | let bitcoinWallet: BitcoinWallet 108 | 109 | beforeAll(() => { 110 | bitcoinWallet = new BitcoinWallet() 111 | }) 112 | 113 | it("Check Initial wallet data", () => { 114 | expect(typeof bitcoinWallet.privateKey).toBe('string') 115 | expect(typeof bitcoinWallet.address).toBe('object') 116 | }) 117 | 118 | it("createWallet()", () => { 119 | const wallet = bitcoinWallet.createWallet('testnet') 120 | 121 | expect(typeof wallet.mnemonic).toBe('string') 122 | expect(typeof wallet.privateKey).toBe('string') 123 | expect(typeof wallet.address).toBe('object') 124 | }) 125 | 126 | it("recoverWallet()", async () => { 127 | const wallet = await bitcoinWallet.recoverWallet(SAMPLE_DATA.COMMON.MNEMONIC) 128 | 129 | expect(typeof wallet.mnemonic).toBe('string') 130 | expect(typeof wallet.privateKey).toBe('string') 131 | expect(typeof wallet.address).toBe('object') 132 | }) 133 | 134 | it("importAccount()", async () => { 135 | const recoveredWallet = await bitcoinWallet.recoverWallet(SAMPLE_DATA.COMMON.MNEMONIC, "regtest") 136 | const wallet = await bitcoinWallet.importAccount(recoveredWallet.privateKey, "testnet") 137 | 138 | expect(typeof wallet.privateKey).toBe('string') 139 | expect(typeof wallet.address).toBe('object') 140 | }) 141 | 142 | it("getBalance()", async () => { 143 | const balance = await bitcoinWallet.getBalance(SAMPLE_DATA.BITCOIN.TESTNET_ADDRESS, "testnet") 144 | 145 | console.log("balance", balance) 146 | // expect(typeof balance).toBe('number') 147 | }) 148 | 149 | it("sendBitcoin()", async () => { 150 | const utxos = await bitcoinWallet.sendBitcoin('', 0) 151 | 152 | console.log(utxos) 153 | }) 154 | }) 155 | }) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vipay-multichain-wallet", 3 | "version": "1.4.3", 4 | "description": "", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "files": [ 8 | "dist" 9 | ], 10 | "scripts": { 11 | "build": "tsc", 12 | "start": "tsdx watch", 13 | "test": "tsdx test" 14 | }, 15 | "keywords": [], 16 | "author": "Chris.Kennedy@theblockjet.ae", 17 | "license": "ISC", 18 | "dependencies": { 19 | "@airgap/beacon-sdk": "^3.1.3", 20 | "@babel/types": "^7.19.0", 21 | "@binance-chain/javascript-sdk": "^4.2.0", 22 | "@dcspark/cardano-multiplatform-lib-browser": "^3.1.1", 23 | "@dcspark/milkomeda-constants": "^0.4.0", 24 | "@ethersproject/shims": "^5.7.0", 25 | "@hashgraph/sdk": "^2.18.6", 26 | "@hethers/wallet": "^1.2.1", 27 | "@solana/buffer-layout": "^4.0.0", 28 | "@solana/spl-token": "^0.2.0", 29 | "@solana/web3.js": "^1.50.1", 30 | "@tradle/react-native-http": "^2.0.0", 31 | "@trustwallet/wallet-core": "^3.1.7", 32 | "@ts-bitcoin/core": "^2.2.0", 33 | "@types/bitcore-lib": "^0.15.3", 34 | "@types/hdkey": "^2.0.1", 35 | "@types/node-fetch": "^2.6.2", 36 | "@types/stellar-sdk": "^0.15.1", 37 | "assert": "^2.0.0", 38 | "axios": "^0.27.2", 39 | "bech32": "^2.0.0", 40 | "bech32-buffer": "^0.2.0", 41 | "bip173": "^1.1.4", 42 | "bip32": "^2.0.4", 43 | "bip39": "^3.0.4", 44 | "bip44": "0.0.1", 45 | "bitcoin-client": "^1.3.0", 46 | "bitcoin-core": "^4.1.0", 47 | "bitcoinjs-lib": "^6.0.2", 48 | "bitcore-explorers": "^1.0.1", 49 | "bitcore-lib": "^10.0.5", 50 | "bitcore-mnemonic": "^8.25.38", 51 | "bluebird": "^3.7.2", 52 | "browserify-zlib": "^0.1.4", 53 | "bs58": "^5.0.0", 54 | "buffer": "^4.9.1", 55 | "buffer-layout": "^1.2.2", 56 | "cardano-wallet": "^1.2.2", 57 | "cardano-wallet-js": "^1.4.0", 58 | "chai": "^4.3.6", 59 | "console-browserify": "^1.1.0", 60 | "constants-browserify": "^1.0.0", 61 | "crypto": "^1.0.1", 62 | "dns.js": "^1.0.1", 63 | "domain-browser": "^1.1.1", 64 | "ecpair": "^2.1.0", 65 | "ed25519-hd-key": "^1.3.0", 66 | "ethers": "^5.6.9", 67 | "events": "^1.0.0", 68 | "hdkey": "^2.0.1", 69 | "https-browserify": "0.0.1", 70 | "litecoin-bip84": "0.0.5", 71 | "litecore-lib": "^0.13.22", 72 | "lucid-cardano": "^0.7.9", 73 | "mnemonic-to-key-pair": "^1.0.0", 74 | "mnemonic-to-private-key": "^0.4.1", 75 | "mocha": "^10.2.0", 76 | "node-fetch": "^3.3.0", 77 | "punycode": "^1.2.4", 78 | "querystring-es3": "^0.2.1", 79 | "random-hash": "^4.0.1", 80 | "react-native-bip32-utils": "^0.9.3", 81 | "react-native-bip39": "^2.3.0", 82 | "react-native-bitcoinjs-lib": "^2.3.9", 83 | "react-native-crypto": "^2.2.0", 84 | "react-native-get-random-values": "^1.8.0", 85 | "react-native-os": "^1.0.1", 86 | "react-native-randombytes": "^3.0.0", 87 | "react-native-tcp": "^3.2.1", 88 | "react-native-udp": "^2.1.0", 89 | "readable-stream": "^1.0.33", 90 | "ripple-bip32": "^0.0.3", 91 | "ripple-keypairs": "^1.1.4", 92 | "ripple-lib": "^1.10.1", 93 | "ripple-wallet": "^2.0.0", 94 | "rn-nodeify": "^10.3.0", 95 | "safe-buffer": "^5.2.1", 96 | "send-crypto": "^0.2.37", 97 | "stellar-hd-wallet": "0.0.10", 98 | "stellar-sdk": "^10.4.0", 99 | "stream": "0.0.2", 100 | "stream-browserify": "^1.0.0", 101 | "string_decoder": "^0.10.31", 102 | "timers-browserify": "^1.0.1", 103 | "tiny-secp256k1": "^2.2.1", 104 | "tron-protocol-ts": "^1.0.5", 105 | "tron-wallet-hd": "^2.0.2", 106 | "tronweb": "^4.3.0", 107 | "tronweb-typings": "^1.0.1", 108 | "tsdx": "^0.14.1", 109 | "tslib": "^2.4.0", 110 | "tty-browserify": "0.0.0", 111 | "url": "^0.10.3", 112 | "util": "^0.10.4", 113 | "vm-browserify": "0.0.4", 114 | "xrpl": "^2.3.0" 115 | }, 116 | "devDependencies": { 117 | "@airgap/beacon-wallet": "^3.1.3", 118 | "@babel/cli": "^7.18.10", 119 | "@babel/core": "^7.18.13", 120 | "@babel/preset-env": "^7.18.10", 121 | "@babel/preset-typescript": "^7.18.6", 122 | "@types/jest": "^29.5.6", 123 | "esbuild": "^0.15.5", 124 | "jest": "^28.1.3", 125 | "simple-bitcoin-wallet": "0.0.9", 126 | "typescript": "^4.7.4", 127 | "webpack": "^5.74.0" 128 | }, 129 | "readme": "readme.md", 130 | "homepage": "https://github.com/cyber-storm-200712/multichain-wallet-sdk", 131 | "repository": { 132 | "url": "https://github.com/cyber-storm-200712/multichain-wallet-sdk" 133 | }, 134 | "react-native": { 135 | "zlib": "browserify-zlib", 136 | "console": "console-browserify", 137 | "constants": "constants-browserify", 138 | "crypto": "react-native-crypto", 139 | "dns": "dns.js", 140 | "net": "react-native-tcp", 141 | "domain": "domain-browser", 142 | "http": "@tradle/react-native-http", 143 | "https": "https-browserify", 144 | "os": "react-native-os", 145 | "path": "path-browserify", 146 | "querystring": "querystring-es3", 147 | "fs": "react-native-level-fs", 148 | "_stream_transform": "readable-stream/transform", 149 | "_stream_readable": "readable-stream/readable", 150 | "_stream_writable": "readable-stream/writable", 151 | "_stream_duplex": "readable-stream/duplex", 152 | "_stream_passthrough": "readable-stream/passthrough", 153 | "dgram": "react-native-udp", 154 | "stream": "stream-browserify", 155 | "timers": "timers-browserify", 156 | "tty": "tty-browserify", 157 | "vm": "vm-browserify", 158 | "tls": false 159 | }, 160 | "browser": { 161 | "zlib": "browserify-zlib", 162 | "console": "console-browserify", 163 | "constants": "constants-browserify", 164 | "crypto": "react-native-crypto", 165 | "dns": "dns.js", 166 | "net": "react-native-tcp", 167 | "domain": "domain-browser", 168 | "http": "@tradle/react-native-http", 169 | "https": "https-browserify", 170 | "os": "react-native-os", 171 | "path": "path-browserify", 172 | "querystring": "querystring-es3", 173 | "fs": "react-native-level-fs", 174 | "_stream_transform": "readable-stream/transform", 175 | "_stream_readable": "readable-stream/readable", 176 | "_stream_writable": "readable-stream/writable", 177 | "_stream_duplex": "readable-stream/duplex", 178 | "_stream_passthrough": "readable-stream/passthrough", 179 | "dgram": "react-native-udp", 180 | "stream": "stream-browserify", 181 | "timers": "timers-browserify", 182 | "tty": "tty-browserify", 183 | "vm": "vm-browserify", 184 | "tls": false 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/abi/erc1155.ts: -------------------------------------------------------------------------------- 1 | const erc1155ABI = [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "account", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "operator", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "bool", 20 | "name": "approved", 21 | "type": "bool" 22 | } 23 | ], 24 | "name": "ApprovalForAll", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "operator", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "from", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": true, 44 | "internalType": "address", 45 | "name": "to", 46 | "type": "address" 47 | }, 48 | { 49 | "indexed": false, 50 | "internalType": "uint256[]", 51 | "name": "ids", 52 | "type": "uint256[]" 53 | }, 54 | { 55 | "indexed": false, 56 | "internalType": "uint256[]", 57 | "name": "values", 58 | "type": "uint256[]" 59 | } 60 | ], 61 | "name": "TransferBatch", 62 | "type": "event" 63 | }, 64 | { 65 | "anonymous": false, 66 | "inputs": [ 67 | { 68 | "indexed": true, 69 | "internalType": "address", 70 | "name": "operator", 71 | "type": "address" 72 | }, 73 | { 74 | "indexed": true, 75 | "internalType": "address", 76 | "name": "from", 77 | "type": "address" 78 | }, 79 | { 80 | "indexed": true, 81 | "internalType": "address", 82 | "name": "to", 83 | "type": "address" 84 | }, 85 | { 86 | "indexed": false, 87 | "internalType": "uint256", 88 | "name": "id", 89 | "type": "uint256" 90 | }, 91 | { 92 | "indexed": false, 93 | "internalType": "uint256", 94 | "name": "value", 95 | "type": "uint256" 96 | } 97 | ], 98 | "name": "TransferSingle", 99 | "type": "event" 100 | }, 101 | { 102 | "anonymous": false, 103 | "inputs": [ 104 | { 105 | "indexed": false, 106 | "internalType": "string", 107 | "name": "value", 108 | "type": "string" 109 | }, 110 | { 111 | "indexed": true, 112 | "internalType": "uint256", 113 | "name": "id", 114 | "type": "uint256" 115 | } 116 | ], 117 | "name": "URI", 118 | "type": "event" 119 | }, 120 | { 121 | "inputs": [ 122 | { 123 | "internalType": "address", 124 | "name": "account", 125 | "type": "address" 126 | }, 127 | { 128 | "internalType": "uint256", 129 | "name": "id", 130 | "type": "uint256" 131 | } 132 | ], 133 | "name": "balanceOf", 134 | "outputs": [ 135 | { 136 | "internalType": "uint256", 137 | "name": "", 138 | "type": "uint256" 139 | } 140 | ], 141 | "stateMutability": "view", 142 | "type": "function" 143 | }, 144 | { 145 | "inputs": [ 146 | { 147 | "internalType": "address[]", 148 | "name": "accounts", 149 | "type": "address[]" 150 | }, 151 | { 152 | "internalType": "uint256[]", 153 | "name": "ids", 154 | "type": "uint256[]" 155 | } 156 | ], 157 | "name": "balanceOfBatch", 158 | "outputs": [ 159 | { 160 | "internalType": "uint256[]", 161 | "name": "", 162 | "type": "uint256[]" 163 | } 164 | ], 165 | "stateMutability": "view", 166 | "type": "function" 167 | }, 168 | { 169 | "inputs": [ 170 | { 171 | "internalType": "address", 172 | "name": "account", 173 | "type": "address" 174 | }, 175 | { 176 | "internalType": "address", 177 | "name": "operator", 178 | "type": "address" 179 | } 180 | ], 181 | "name": "isApprovedForAll", 182 | "outputs": [ 183 | { 184 | "internalType": "bool", 185 | "name": "", 186 | "type": "bool" 187 | } 188 | ], 189 | "stateMutability": "view", 190 | "type": "function" 191 | }, 192 | { 193 | "inputs": [ 194 | { 195 | "internalType": "address", 196 | "name": "from", 197 | "type": "address" 198 | }, 199 | { 200 | "internalType": "address", 201 | "name": "to", 202 | "type": "address" 203 | }, 204 | { 205 | "internalType": "uint256[]", 206 | "name": "ids", 207 | "type": "uint256[]" 208 | }, 209 | { 210 | "internalType": "uint256[]", 211 | "name": "amounts", 212 | "type": "uint256[]" 213 | }, 214 | { 215 | "internalType": "bytes", 216 | "name": "data", 217 | "type": "bytes" 218 | } 219 | ], 220 | "name": "safeBatchTransferFrom", 221 | "outputs": [], 222 | "stateMutability": "nonpayable", 223 | "type": "function" 224 | }, 225 | { 226 | "inputs": [ 227 | { 228 | "internalType": "address", 229 | "name": "from", 230 | "type": "address" 231 | }, 232 | { 233 | "internalType": "address", 234 | "name": "to", 235 | "type": "address" 236 | }, 237 | { 238 | "internalType": "uint256", 239 | "name": "id", 240 | "type": "uint256" 241 | }, 242 | { 243 | "internalType": "uint256", 244 | "name": "amount", 245 | "type": "uint256" 246 | }, 247 | { 248 | "internalType": "bytes", 249 | "name": "data", 250 | "type": "bytes" 251 | } 252 | ], 253 | "name": "safeTransferFrom", 254 | "outputs": [], 255 | "stateMutability": "nonpayable", 256 | "type": "function" 257 | }, 258 | { 259 | "inputs": [ 260 | { 261 | "internalType": "address", 262 | "name": "operator", 263 | "type": "address" 264 | }, 265 | { 266 | "internalType": "bool", 267 | "name": "approved", 268 | "type": "bool" 269 | } 270 | ], 271 | "name": "setApprovalForAll", 272 | "outputs": [], 273 | "stateMutability": "nonpayable", 274 | "type": "function" 275 | }, 276 | { 277 | "inputs": [ 278 | { 279 | "internalType": "bytes4", 280 | "name": "interfaceId", 281 | "type": "bytes4" 282 | } 283 | ], 284 | "name": "supportsInterface", 285 | "outputs": [ 286 | { 287 | "internalType": "bool", 288 | "name": "", 289 | "type": "bool" 290 | } 291 | ], 292 | "stateMutability": "view", 293 | "type": "function" 294 | }, 295 | { 296 | "inputs": [ 297 | { 298 | "internalType": "uint256", 299 | "name": "id", 300 | "type": "uint256" 301 | } 302 | ], 303 | "name": "uri", 304 | "outputs": [ 305 | { 306 | "internalType": "string", 307 | "name": "", 308 | "type": "string" 309 | } 310 | ], 311 | "stateMutability": "view", 312 | "type": "function" 313 | } 314 | ] 315 | 316 | export default erc1155ABI -------------------------------------------------------------------------------- /tsConfig.example.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ 8 | "module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | "lib": ["DOM","ESNext"], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ 13 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "./dist", /* Redirect output structure to the directory. */ 18 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | "noEmit": true, /* Do not emit outputs. */ 23 | "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true, /* Enable all strict type-checking options. */ 29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 43 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ 44 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ 45 | 46 | /* Module Resolution Options */ 47 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 48 | "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 49 | "paths": { 50 | "lib/*": [ 51 | "src/*" 52 | ] 53 | }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 54 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 55 | // "typeRoots": [], /* List of folders to include type definitions from. */ 56 | // "types": [], /* Type declaration files to be included in compilation. */ 57 | "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 58 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 59 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 60 | "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 61 | 62 | /* Source Map Options */ 63 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 64 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 65 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 66 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 67 | 68 | /* Experimental Options */ 69 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 70 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 71 | 72 | /* Advanced Options */ 73 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 74 | "forceConsistentCasingInFileNames": true , /* Disallow inconsistently-cased references to the same file. */ 75 | "resolveJsonModule": true 76 | }, 77 | "include": ["src", "types"] 78 | } 79 | -------------------------------------------------------------------------------- /src/helper/cardanoHelper.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { 3 | CARDANO_MAINNET_SERVER, 4 | CARDANO_TESTNET_SERVER, 5 | CARDANO_PREPROD_SERVER, 6 | CARDANO_PREVIEW_SERVER, 7 | BLOCK_FROST, 8 | ERRORS 9 | } from "../utils/constant"; 10 | import { milkomedaNetworks } from '@dcspark/milkomeda-constants' 11 | import Cardano from '../lib/@emurgo/cardano-multiplatform-lib-nodejs'; 12 | 13 | export const harden = (num: number) => { 14 | return 0x80000000 + num; 15 | }; 16 | 17 | export const delay = (millisecond: number) => { 18 | return new Promise(resolve => setTimeout(resolve, millisecond)) 19 | } 20 | 21 | export const provider = { 22 | api: { 23 | ipfs: 'https://ipfs.blockfrost.dev/ipfs', 24 | base: (node = CARDANO_MAINNET_SERVER) => node, 25 | key: (network?: 'mainnet' | 'testnet' | 'preprod' | 'preview') => ({ 26 | project_id: BLOCK_FROST[network || 'mainnet'], 27 | }), 28 | price: (currency = 'usd') => { 29 | axios.get(`https://api.coingecko.com/api/v3/simple/price?ids=cardano&vs_currencies=${currency}`) 30 | .then((res) => res.data) 31 | .then((res) => res['cardano'][currency]) 32 | } 33 | } 34 | } 35 | 36 | export const getNetwork = (network: 'mainnet' | 'testnet' | 'preprod' | 'preview'): { id: string, node: string } => { 37 | switch(network){ 38 | case 'mainnet': 39 | return { id: 'mainnet', node: CARDANO_MAINNET_SERVER } 40 | case 'testnet': 41 | return { id: 'testnet', node: CARDANO_TESTNET_SERVER } 42 | case 'preprod': 43 | return { id: 'preprod', node: CARDANO_PREPROD_SERVER } 44 | case 'preview': 45 | return { id: 'preview', node: CARDANO_PREVIEW_SERVER } 46 | default: 47 | return { id: 'mainnet', node: CARDANO_MAINNET_SERVER } 48 | } 49 | } 50 | 51 | export const blockfrostRequest = async (endpoint: string, network?: 'mainnet' | 'testnet' | 'preprod' | 'preview', headers?: any, body?: any, signal?: any) => { 52 | const _network_ = getNetwork(network || 'mainnet') 53 | 54 | let result: any; 55 | 56 | while(!result || result['status_code'] === 500) { 57 | if(result) { 58 | await delay(100) 59 | } 60 | const rawResult = await axios.request({ 61 | url: provider.api.base(_network_.node) + endpoint, 62 | headers: { 63 | ...provider.api.key(network), 64 | ...headers, 65 | 'Cache-Control': 'no-cache' 66 | }, 67 | method: body? 'POST' : 'GET', 68 | // body, 69 | params: body, 70 | data: body, 71 | signal, 72 | }); 73 | 74 | result = rawResult.data 75 | } 76 | 77 | return result 78 | } 79 | 80 | export const getBalanceExtended = async (paymentKeyHashBech32: string, network?: 'mainnet' | 'testnet' | 'preprod' | 'preview') => { 81 | const result = await blockfrostRequest(`/addresses/${paymentKeyHashBech32}/extended`, network || 'mainnet'); 82 | if (result.error) { 83 | if (result.status_code === 400) throw ERRORS.invalid_api_request; 84 | else if (result.status_code === 500) throw ERRORS.invalid_api_request; 85 | else if (result.status_code === 404) throw ERRORS.address_not_activated; 86 | else return []; 87 | } 88 | return result['amount']; 89 | }; 90 | 91 | export const getMilkomedaData = async (ethAddress: string, network?: 'mainnet' | 'testnet' | 'preprod' | 'preview') => { 92 | if(network === 'mainnet' || network === undefined || network === null) { 93 | const { isAllowed } = (await axios.get(`https://${milkomedaNetworks['c1-mainnet'].backendEndpoint}/v1/isAddressAllowed?address=${ethAddress}`)).data; 94 | 95 | const { ada, ttl_expiry, assets, current_address } = await (await axios.get(`https://${milkomedaNetworks['c1-mainnet'].backendEndpoint}/v1/stargate`)).data 96 | 97 | const protocolMagic = milkomedaNetworks['c1-mainnet'].protocolMagic 98 | 99 | return { 100 | isAllowed, 101 | assets: [], 102 | ada, 103 | current_address, 104 | protocolMagic, 105 | ttl: ttl_expiry 106 | } 107 | } 108 | else { 109 | const { isAllowed } = (await axios.get(`https://${milkomedaNetworks['c1-devnet'].backendEndpoint}/v1/isAddressAllowed?address=${ethAddress}`)).data; 110 | 111 | const { ada, ttl_expiry, assets, current_address } = await (await axios.get(`https://${milkomedaNetworks['c1-devnet'].backendEndpoint}/v1/stargate`)).data 112 | 113 | const protocolMagic = milkomedaNetworks['c1-devnet'].protocolMagic 114 | 115 | return { 116 | isAllowed, 117 | assets: [], 118 | ada, 119 | current_address, 120 | protocolMagic, 121 | ttl: ttl_expiry 122 | } 123 | } 124 | } 125 | 126 | export const getUtxos = async (address: string, network?: 'mainnet' | 'testnet' | 'preview' | 'preprod') => { 127 | let result: any[] = []; 128 | let page: number = 1; 129 | const limit: string = ''; 130 | 131 | while(true) { 132 | let pageResult: any = await blockfrostRequest(`/addresses/${address}/utxos?page=${page}${limit}`, network || 'mainnet') 133 | 134 | if(pageResult.error) { 135 | result = [] 136 | } 137 | 138 | result = result.concat(pageResult) 139 | if(pageResult.length <= 0) break; 140 | page++; 141 | } 142 | 143 | let converted = await Promise.all( 144 | result.map(async (utxo) => await utxoFromJson(utxo, address)) 145 | ) 146 | 147 | return result 148 | 149 | // return converted; 150 | } 151 | 152 | export const utxoFromJson = async (output: any, address: string) => { 153 | 154 | return Cardano.TransactionUnspentOutput.new( 155 | Cardano.TransactionInput.new( 156 | Cardano.TransactionHash.from_bytes( 157 | Buffer.from(output.tx_hash || output.txHash, 'hex') 158 | ), 159 | Cardano.BigNum.from_str( 160 | (output.output_index ?? output.txId).toString() 161 | ), 162 | ), 163 | Cardano.TransactionOutput.new( 164 | Cardano.Address.from_bech32(address), 165 | await assetsToValue(output.amount) 166 | ) 167 | ) 168 | } 169 | 170 | export const assetsToValue = async (assets: any) => { 171 | const multiAsset = Cardano.MultiAsset.new(); 172 | const lovelace = assets.find((asset: any) => asset.unit === 'lovelace'); 173 | const policies = [ 174 | assets 175 | .filter((asset: any) => asset.unit !== 'lovelace') 176 | .map((asset: any) => asset.unit.slice(0, 56)) 177 | ]; 178 | policies.forEach((policy) => { 179 | const policyAssets = assets.filter( 180 | (asset: any) => asset.unit.slice(0, 56) === policy 181 | ); 182 | const assetsValue = Cardano.Assets.new(); 183 | policyAssets.forEach((asset: any) => { 184 | assetsValue.insert( 185 | Cardano.AssetName.new(Buffer.from(asset.unit.slice(56), 'hex')), 186 | Cardano.BigNum.from_str(asset.quantity) 187 | ); 188 | }); 189 | multiAsset.insert( 190 | Cardano.ScriptHash.from_bytes(Buffer.from(policy, 'hex')), 191 | assetsValue 192 | ); 193 | }); 194 | const value = Cardano.Value.new( 195 | Cardano.BigNum.from_str(lovelace ? lovelace.quantity : '0') 196 | ); 197 | if (assets.length > 1 || !lovelace) value.set_multiasset(multiAsset); 198 | return value; 199 | }; -------------------------------------------------------------------------------- /src/utils/constant.ts: -------------------------------------------------------------------------------- 1 | // Network Names 2 | export const ETHEREUM: string = 'ETHEREUM'; 3 | export const SOLANA: string = 'SOLANA'; 4 | export const BITCOIN: string = 'BITCOIN'; 5 | export const RIPPLE: string = 'RIPPLE'; 6 | 7 | // Derived Path 8 | export const ETHEREUM_DEFAULT: string = "m/44'/60'/0'/0/"; 9 | export const SOLANA_DEFAULT: string = "m/44'/501'/0'/0'"; 10 | export const BITCOIN_DEFAULT: string = "m/44'/0'/0'/0"; 11 | export const BNB_BEACON_DEFAULT: string = "m/44'/714'/0'/0"; 12 | export const TRON_DEFAULT: string = "m/44'/195'/0/0"; 13 | export const LITECOIN_DEFAULT: string = "m/44'/2'/0'/0"; 14 | 15 | // Ethereum Contract Data 16 | export const ERC721_INTERFACE_ID = '0x80ac58cd'; 17 | export const ERC1155_INTERFACE_ID = '0xd9b67a26' 18 | 19 | // Solana network cluster 20 | export const MAINNET_BETA: string = 'mainnet-beta'; 21 | export const TESTNET: string = 'testnet'; 22 | export const DEVNET: string = 'devnet'; 23 | // Bitcoin network 24 | export const BTC_MAINNET = 'bitcoin'; 25 | export const BTC_REGTEST = 'regtest'; 26 | export const BTC_TESTNET = 'testnet'; 27 | 28 | // Network Prototype 29 | export const LITECOIN_NETWORK_PROTOTYPE = { 30 | messagePrefix: '\x19Litecoin Signed Message:\n', 31 | bech32: 'ltc', 32 | bip32: { 33 | public: 0x019da462, 34 | private: 0x019d9cfe, 35 | }, 36 | pubKeyHash: 0x30, 37 | scriptHash: 0x32, 38 | wif: 0xb0, 39 | } 40 | 41 | 42 | // Ether Gasstation 43 | export const ETHER_GASSTATION_APIKEY = '9218ce9ba793ff0339045d78a4161ad4b9c5d1ebad3158197514ac957d40' 44 | export const ETHER_GASSTATION_API: string = `https://ethgasstation.info/api/ethgasAPI.json?api-key=${ETHER_GASSTATION_APIKEY}` 45 | 46 | // Bitpay url 47 | export const BWS_INSTANCE_URL: string = 'https://bws.bitpay.com/bws/api' 48 | 49 | // Solana data API endpoint 50 | export const SOLANA_TOKENLIST_URI: string = 'https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json'; 51 | 52 | // hedera account id recover api endpoint 53 | export const GET_HEDERA_ACCOUNTID_ENDPOINT: string = 'https://mainnet-public.mirrornode.hedera.com/api/v1/accounts?accountpublickey='; 54 | 55 | // Actions 56 | export const CREATE_WALLET: string = 'CREATE_WALLET'; 57 | export const IMPORT_WALLET: string = 'IMPORT_WALLET'; 58 | export const CREATE_MASTERSEED: string = 'CREATE_MASTERSEED'; 59 | export const CREATE_ACCOUNT: string = 'CREATE_ACCOUNT'; 60 | export const IMPORT_ACCOUNT: string = 'IMPORT_ACCOUNT'; 61 | export const GET_BALANCE: string = 'GET_BALANCE'; 62 | export const GET_BALANCES: string = 'GET_BALANCES'; 63 | export const GET_TOKEN_BALANCE: string = 'GET_TOKEN_BALANCE'; 64 | export const GET_TOKEN: string = 'GET_TOKEN'; 65 | export const GET_TOKEN_LIST: string = 'GET_TOKEN_LIST'; 66 | export const SEND_COIN: string = 'SEND_COIN'; 67 | export const APPROVE_TOKEN: string = 'APPROVE_TOKEN'; 68 | export const TRANSFER_TOKEN: string = 'TRANSFER_TOKEN'; 69 | export const GET_TRANSACTION: string = 'GET_TRANSACTION'; 70 | export const GET_GAS: string = 'GET_GAS'; 71 | 72 | // Cardano Ada Handle 73 | export const ADA_HANDLE = { 74 | mainnet: 'f0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9a', 75 | testnet: '8d18d786e92776c824607fd8e193ec535c79dc61ea2405ddf3b09fe3', 76 | }; 77 | 78 | // Blockfrost API project ID 79 | export const BLOCK_FROST = { 80 | mainnet: 'mainnetQf8DQD9zDkg91gBo2R8xmEG2IxCaS9fU', 81 | testnet: '', 82 | preprod: '', 83 | preview: 'previewcGGHuIlBcwBsYE7PzkEC26AMCb0LztD0' 84 | } 85 | 86 | // Tron API key 87 | export const TRONGRID_API_KEY = { 88 | mainnet: 'f0b1e38e-7bee-485e-9d3f-69410bf30681', 89 | testnet: '6739be94-ee43-46af-9a62-690cf0947269', 90 | dappchain: 'a981e232-a995-4c81-9653-c85e4d05f599' 91 | } 92 | 93 | // RPC_ENDPOINTS 94 | 95 | ///////////////////////// 96 | //////FOR EVM CHAIN////// 97 | ///////////////////////// 98 | 99 | // Ethereum 100 | export const ETHERRUM_MAINNET_RPC_URL_1 = 'https://mainnet.infura.io/v3/'; 101 | export const ETHEREUM_MAINNET_RPC_URL_2 = 'https://rpc.ankr.com/eth/'; 102 | // Binance Smart Chain 103 | export const BINANCE_SMART_CHAIN_RPC_URL = 'https://bsc-dataseed2.binance.org'; 104 | // Polygon network 105 | export const POLYGON_MAINNET_RPC_URL = 'https://polygon-rpc.com'; 106 | // Fantom network 107 | export const FANTOM_OPERA_MAINNET_RPC_URL = 'https://rpc.ftm.tools'; 108 | // Abitrum network 109 | export const ARBITRUM_ONE_MAINNET_RPC_URL = 'https://arb-mainnet.g.alchemy.com/v2/TDx7fOwCQUo2nF4-kzxvyIAIGMrpBmnc'; 110 | // Cronos network 111 | export const CRONOS_MAINNET_RPC_URL = 'https://cronosrpc-1.xstaking.sg'; 112 | // Avalanch network 113 | export const AVALANCH_NETWORK_RPC_URL = 'https://1rpc.io/avax/c'; 114 | 115 | ///////////////////////// 116 | ///////S O L A N A/////// 117 | ///////////////////////// 118 | export const SOLANA_DEVNET_RPC_URL = 'https://api.devnet.solana.com/'; 119 | export const SOLANA_TESTNET_RPC_URL = 'https://api.testnet.solana.com/'; 120 | export const SOLANA_MAINNET_RPC_URL = 'https://api.mainnet-beta.solana.com'; 121 | 122 | ////////////////////////// 123 | ////////R I P P L E/////// 124 | ////////////////////////// 125 | export const RIPPLE_NETWORK_RPC_URL_1 = 'https://s1.ripple.com:51234/'; 126 | export const RIPPLE_NETWORK_RPC_URL_2 = 'wss://s1.ripple.com/'; 127 | 128 | export const RIPPLE_TESTNET_RPC_URL_1 = 'https://s.altnet.rippletest.net:51234/'; 129 | export const RIPPLE_TESTNET_RPC_URL_2 = 'wss://s.altnet.rippletest.net/'; 130 | 131 | export const RIPPLE_DEVNET_RPC_URL_1 = 'https://s.devnet.rippletest.net:51234/'; 132 | export const RIPPLE_DEVNET_RPC_URL_2 = 'wss://s.devnet.rippletest.net/'; 133 | 134 | /////////////////////////// 135 | //////////T R O N////////// 136 | /////////////////////////// 137 | export const TRON_MAINNET = 'https://api.trongrid.io'; 138 | export const TRON_SHASTA_TESTNET = 'https://api.shasta.trongrid.io'; 139 | export const TRON_NILE_TESTNET = 'https://nile.trongrid.io'; 140 | export const TRON_DAPPCHAIN = 'https://sun.tronex.io' 141 | 142 | export const TRON_MAINNET_FULL_NODE = 'https://api.trongrid.io' 143 | export const TRON_MAINNET_SOLIDITY_NODE = 'https://api.trongrid.io' 144 | export const TRON_MAINNET_EVENT_SERVER = 'https://api.trongrid.io' 145 | 146 | export const TRON_TESTNET_FULL_NODE = 'https://api.shasta.trongrid.io' 147 | export const TRON_TESTNET_SOLIDITY_NODE = 'https://api.shasta.trongrid.io' 148 | export const TRON_TESTNET_EVENT_SERVER = 'https://api.shasta.trongrid.io' 149 | 150 | export const TRON_DAPPCHAIN_FULL_NDOE = 'https://sun.tronex.io' 151 | export const TRON_DAPPCHAIN_SOLIDITY_NODE = 'https://sun.tronex.io' 152 | export const TRON_DAPPCHAIN_EVENT_SERVER = 'https://sun.tronex.io' 153 | 154 | 155 | /////////////////////////// 156 | ///////S T E L L A R/////// 157 | /////////////////////////// 158 | export const STELLAR_MAINNET_SERVER = 'https://horizon.stellar.org/' 159 | export const STELLAR_TESTNET_API = 'https://friendbot.stellar.org?addr=' 160 | export const STELLAR_TESTNET_SERVER = 'https://horizon-testnet.stellar.org/' 161 | 162 | 163 | //////////////////////////// 164 | ////////C A R D A N O/////// 165 | //////////////////////////// 166 | export const CARDANO_MAINNET_SERVER = 'https://cardano-mainnet.blockfrost.io/api/v0' 167 | export const CARDANO_TESTNET_SERVER = 'https://cardano-testnet.blockfrost.io/api/v0' 168 | export const CARDANO_PREVIEW_SERVER = 'https://cardano-preview.blockfrost.io/api/v0' 169 | export const CARDANO_PREPROD_SERVER = 'https://cardano-preprod.blockfrost.io/api/v0' 170 | 171 | // Errors 172 | export const ERRORS = { 173 | invalid_api_request: { 174 | message: 'INVALID_API_REQUEST', 175 | description: 'Invalid API request' 176 | }, 177 | address_not_activated: { 178 | message: 'ADDRESS_NOT_ACTIVATED', 179 | description: 'This address must be activated to use' 180 | } 181 | } -------------------------------------------------------------------------------- /src/constant/index.ts: -------------------------------------------------------------------------------- 1 | import { BtcNetwork } from "../type/type" 2 | 3 | // Network Names 4 | export const ETHEREUM: string = 'ETHEREUM'; 5 | export const SOLANA: string = 'SOLANA'; 6 | export const BITCOIN: string = 'BITCOIN'; 7 | export const RIPPLE: string = 'RIPPLE'; 8 | 9 | // Derived Path 10 | export const ETHEREUM_DEFAULT: string = "m/44'/60'/0'/0/"; 11 | export const SOLANA_DEFAULT: string = "m/44'/501'/0'/0'"; 12 | export const BITCOIN_DEFAULT: string = "m/44'/0'/0'/0"; 13 | export const BNB_BEACON_DEFAULT: string = "m/44'/714'/0'/0"; 14 | export const TRON_DEFAULT: string = "m/44'/195'/0/0"; 15 | export const LITECOIN_DEFAULT: string = "m/44'/2'/0'/0"; 16 | 17 | // Ethereum Contract Data 18 | export const ERC721_INTERFACE_ID = '0x80ac58cd'; 19 | export const ERC1155_INTERFACE_ID = '0xd9b67a26' 20 | 21 | // Solana network cluster 22 | export const MAINNET_BETA: string = 'mainnet-beta'; 23 | export const TESTNET: string = 'testnet'; 24 | export const DEVNET: string = 'devnet'; 25 | 26 | // Bitcoin network 27 | export const BTC_MAINNET: BtcNetwork = "bitcoin" 28 | export const BTC_REGTEST: BtcNetwork = "regtest" 29 | export const BTC_TESTNET: BtcNetwork = "testnet" 30 | 31 | // Network Prototype 32 | export const LITECOIN_NETWORK_PROTOTYPE = { 33 | messagePrefix: '\x19Litecoin Signed Message:\n', 34 | bech32: 'ltc', 35 | bip32: { 36 | public: 0x019da462, 37 | private: 0x019d9cfe, 38 | }, 39 | pubKeyHash: 0x30, 40 | scriptHash: 0x32, 41 | wif: 0xb0, 42 | } 43 | 44 | 45 | // Ether Gasstation 46 | export const ETHER_GASSTATION_APIKEY = '9218ce9ba793ff0339045d78a4161ad4b9c5d1ebad3158197514ac957d40' 47 | export const ETHER_GASSTATION_API: string = `https://ethgasstation.info/api/ethgasAPI.json?api-key=${ETHER_GASSTATION_APIKEY}` 48 | 49 | // Bitpay url 50 | export const BWS_INSTANCE_URL: string = 'https://bws.bitpay.com/bws/api' 51 | 52 | // Solana data API endpoint 53 | export const SOLANA_TOKENLIST_URI: string = 'https://raw.githubusercontent.com/solana-labs/token-list/main/src/tokens/solana.tokenlist.json'; 54 | 55 | // hedera account id recover api endpoint 56 | export const GET_HEDERA_ACCOUNTID_ENDPOINT: string = 'https://mainnet-public.mirrornode.hedera.com/api/v1/accounts?accountpublickey='; 57 | 58 | // Actions 59 | export const CREATE_WALLET: string = 'CREATE_WALLET'; 60 | export const IMPORT_WALLET: string = 'IMPORT_WALLET'; 61 | export const CREATE_MASTERSEED: string = 'CREATE_MASTERSEED'; 62 | export const CREATE_ACCOUNT: string = 'CREATE_ACCOUNT'; 63 | export const IMPORT_ACCOUNT: string = 'IMPORT_ACCOUNT'; 64 | export const GET_BALANCE: string = 'GET_BALANCE'; 65 | export const GET_BALANCES: string = 'GET_BALANCES'; 66 | export const GET_TOKEN_BALANCE: string = 'GET_TOKEN_BALANCE'; 67 | export const GET_TOKEN: string = 'GET_TOKEN'; 68 | export const GET_TOKEN_LIST: string = 'GET_TOKEN_LIST'; 69 | export const SEND_COIN: string = 'SEND_COIN'; 70 | export const APPROVE_TOKEN: string = 'APPROVE_TOKEN'; 71 | export const TRANSFER_TOKEN: string = 'TRANSFER_TOKEN'; 72 | export const GET_TRANSACTION: string = 'GET_TRANSACTION'; 73 | export const GET_GAS: string = 'GET_GAS'; 74 | 75 | // Cardano Ada Handle 76 | export const ADA_HANDLE = { 77 | mainnet: 'f0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9a', 78 | testnet: '8d18d786e92776c824607fd8e193ec535c79dc61ea2405ddf3b09fe3', 79 | }; 80 | 81 | // Blockfrost API project ID 82 | export const BLOCK_FROST = { 83 | mainnet: 'mainnetQf8DQD9zDkg91gBo2R8xmEG2IxCaS9fU', 84 | testnet: '', 85 | preprod: '', 86 | preview: 'previewcGGHuIlBcwBsYE7PzkEC26AMCb0LztD0' 87 | } 88 | 89 | // Tron API key 90 | export const TRONGRID_API_KEY = { 91 | mainnet: 'f0b1e38e-7bee-485e-9d3f-69410bf30681', 92 | testnet: '6739be94-ee43-46af-9a62-690cf0947269', 93 | dappchain: 'a981e232-a995-4c81-9653-c85e4d05f599' 94 | } 95 | 96 | // RPC_ENDPOINTS 97 | 98 | ///////////////////////// 99 | //////FOR EVM CHAIN////// 100 | ///////////////////////// 101 | 102 | // Ethereum 103 | export const ETHERRUM_MAINNET_RPC_URL_1 = 'https://mainnet.infura.io/v3/'; 104 | export const ETHEREUM_MAINNET_RPC_URL_2 = 'https://rpc.ankr.com/eth/'; 105 | // Binance Smart Chain 106 | export const BINANCE_SMART_CHAIN_RPC_URL = 'https://bsc-dataseed2.binance.org'; 107 | // Polygon network 108 | export const POLYGON_MAINNET_RPC_URL = 'https://polygon-rpc.com'; 109 | // Fantom network 110 | export const FANTOM_OPERA_MAINNET_RPC_URL = 'https://rpc.ftm.tools'; 111 | // Abitrum network 112 | export const ARBITRUM_ONE_MAINNET_RPC_URL = 'https://arb-mainnet.g.alchemy.com/v2/TDx7fOwCQUo2nF4-kzxvyIAIGMrpBmnc'; 113 | // Cronos network 114 | export const CRONOS_MAINNET_RPC_URL = 'https://cronosrpc-1.xstaking.sg'; 115 | // Avalanch network 116 | export const AVALANCH_NETWORK_RPC_URL = 'https://1rpc.io/avax/c'; 117 | 118 | ///////////////////////// 119 | ///////S O L A N A/////// 120 | ///////////////////////// 121 | export const SOLANA_DEVNET_RPC_URL = 'https://api.devnet.solana.com/'; 122 | export const SOLANA_TESTNET_RPC_URL = 'https://api.testnet.solana.com/'; 123 | export const SOLANA_MAINNET_RPC_URL = 'https://api.mainnet-beta.solana.com'; 124 | 125 | ////////////////////////// 126 | ////////R I P P L E/////// 127 | ////////////////////////// 128 | export const RIPPLE_NETWORK_RPC_URL_1 = 'https://s1.ripple.com:51234/'; 129 | export const RIPPLE_NETWORK_RPC_URL_2 = 'wss://s1.ripple.com/'; 130 | 131 | export const RIPPLE_TESTNET_RPC_URL_1 = 'https://s.altnet.rippletest.net:51234/'; 132 | export const RIPPLE_TESTNET_RPC_URL_2 = 'wss://s.altnet.rippletest.net/'; 133 | 134 | export const RIPPLE_DEVNET_RPC_URL_1 = 'https://s.devnet.rippletest.net:51234/'; 135 | export const RIPPLE_DEVNET_RPC_URL_2 = 'wss://s.devnet.rippletest.net/'; 136 | 137 | /////////////////////////// 138 | //////////T R O N////////// 139 | /////////////////////////// 140 | export const TRON_MAINNET = 'https://api.trongrid.io'; 141 | export const TRON_SHASTA_TESTNET = 'https://api.shasta.trongrid.io'; 142 | export const TRON_NILE_TESTNET = 'https://nile.trongrid.io'; 143 | export const TRON_DAPPCHAIN = 'https://sun.tronex.io' 144 | 145 | export const TRON_MAINNET_FULL_NODE = 'https://api.trongrid.io' 146 | export const TRON_MAINNET_SOLIDITY_NODE = 'https://api.trongrid.io' 147 | export const TRON_MAINNET_EVENT_SERVER = 'https://api.trongrid.io' 148 | 149 | export const TRON_TESTNET_FULL_NODE = 'https://api.shasta.trongrid.io' 150 | export const TRON_TESTNET_SOLIDITY_NODE = 'https://api.shasta.trongrid.io' 151 | export const TRON_TESTNET_EVENT_SERVER = 'https://api.shasta.trongrid.io' 152 | 153 | export const TRON_DAPPCHAIN_FULL_NDOE = 'https://sun.tronex.io' 154 | export const TRON_DAPPCHAIN_SOLIDITY_NODE = 'https://sun.tronex.io' 155 | export const TRON_DAPPCHAIN_EVENT_SERVER = 'https://sun.tronex.io' 156 | 157 | 158 | /////////////////////////// 159 | ///////S T E L L A R/////// 160 | /////////////////////////// 161 | export const STELLAR_MAINNET_SERVER = 'https://horizon.stellar.org/' 162 | export const STELLAR_TESTNET_API = 'https://friendbot.stellar.org?addr=' 163 | export const STELLAR_TESTNET_SERVER = 'https://horizon-testnet.stellar.org/' 164 | 165 | 166 | //////////////////////////// 167 | ////////C A R D A N O/////// 168 | //////////////////////////// 169 | export const CARDANO_MAINNET_SERVER = 'https://cardano-mainnet.blockfrost.io/api/v0' 170 | export const CARDANO_TESTNET_SERVER = 'https://cardano-testnet.blockfrost.io/api/v0' 171 | export const CARDANO_PREVIEW_SERVER = 'https://cardano-preview.blockfrost.io/api/v0' 172 | export const CARDANO_PREPROD_SERVER = 'https://cardano-preprod.blockfrost.io/api/v0' 173 | 174 | // Errors 175 | export const ERRORS = { 176 | invalid_api_request: { 177 | message: 'INVALID_API_REQUEST', 178 | description: 'Invalid API request' 179 | }, 180 | address_not_activated: { 181 | message: 'ADDRESS_NOT_ACTIVATED', 182 | description: 'This address must be activated to use' 183 | } 184 | } -------------------------------------------------------------------------------- /src/wallet_class/bitcoin/index.ts: -------------------------------------------------------------------------------- 1 | import * as bip39 from 'bip39' 2 | import * as bip32 from 'bip32' 3 | import * as bitcoin from 'bitcoinjs-lib' 4 | import { PrivateKey } from 'bitcore-lib'; 5 | 6 | import axios, { AxiosResponse } from 'axios'; 7 | 8 | import { fetchUTXOs } from '../../helper/bitcoinHelper'; 9 | 10 | import { BtcNetwork, BtcWallet, BtcAccount } from "../../type/type" 11 | import { BITCOIN_DEFAULT, BTC_MAINNET, BTC_REGTEST, BTC_TESTNET } from "../../constant"; 12 | 13 | class BitCoinWallet { 14 | 15 | privateKey: string 16 | address: { p2pkh: string, bech32: string } 17 | 18 | /** 19 | * 20 | * @param privateKey 21 | * @param network 22 | */ 23 | constructor(privateKey?: string, network?: BtcNetwork) { 24 | if (privateKey) { 25 | const _tempWallet = this.importAccount(privateKey, network || BTC_MAINNET) 26 | 27 | this.privateKey = _tempWallet.privateKey 28 | this.address = _tempWallet.address 29 | } 30 | else { 31 | const _tempWallet = this.createWallet(network || BTC_MAINNET) 32 | 33 | this.privateKey = _tempWallet.privateKey 34 | this.address = _tempWallet.address 35 | } 36 | } 37 | 38 | /** 39 | * 40 | * @param network 41 | * @param derivedPath 42 | * @returns {BtcWallet} 43 | */ 44 | createWallet = (network?: BtcNetwork, derivedPath?: string): BtcWallet => { 45 | let btcNetwork; 46 | 47 | const currentNetwork = network || BTC_MAINNET 48 | 49 | switch (currentNetwork) { 50 | case BTC_MAINNET: 51 | btcNetwork = bitcoin.networks.bitcoin; 52 | break; 53 | case BTC_REGTEST: 54 | btcNetwork = bitcoin.networks.regtest; 55 | break; 56 | case BTC_TESTNET: 57 | btcNetwork = bitcoin.networks.testnet; 58 | break; 59 | default: 60 | btcNetwork = bitcoin.networks.bitcoin; 61 | break; 62 | } 63 | 64 | const path = derivedPath || BITCOIN_DEFAULT; 65 | 66 | const mnemonic = bip39.generateMnemonic(); 67 | const seed = bip39.mnemonicToSeedSync(mnemonic); 68 | 69 | const root = bip32.fromSeed(seed, btcNetwork); 70 | 71 | const account = root.derivePath(path); 72 | const node = account.derive(0); 73 | 74 | const publicKeyP2pkh = bitcoin.payments.p2pkh({ 75 | pubkey: node.publicKey, 76 | network: btcNetwork 77 | }).address || ''; 78 | 79 | const publicKeyBech32 = bitcoin.payments.p2wpkh({ 80 | pubkey: node.publicKey, 81 | network: btcNetwork 82 | }).address || '' 83 | 84 | return { 85 | address: { 86 | p2pkh: publicKeyP2pkh, 87 | bech32: publicKeyBech32 88 | }, 89 | privateKey: node.toWIF(), 90 | mnemonic: mnemonic 91 | } 92 | } 93 | 94 | /** 95 | * 96 | * @param mnemonic 97 | * @param network 98 | * @param derivedPath 99 | * @returns {BtcWallet} 100 | */ 101 | recoverWallet = (mnemonic: string, network?: BtcNetwork, derivedPath?: string): BtcWallet => { 102 | let btcNetwork; 103 | 104 | const currentNetwork = network || BTC_MAINNET 105 | 106 | switch (currentNetwork) { 107 | case BTC_MAINNET: 108 | btcNetwork = bitcoin.networks.bitcoin; 109 | break; 110 | case BTC_REGTEST: 111 | btcNetwork = bitcoin.networks.regtest; 112 | break; 113 | case BTC_TESTNET: 114 | btcNetwork = bitcoin.networks.testnet; 115 | break; 116 | default: 117 | btcNetwork = bitcoin.networks.bitcoin; 118 | break; 119 | } 120 | 121 | const path = derivedPath || BITCOIN_DEFAULT; 122 | 123 | const seed = bip39.mnemonicToSeedSync(mnemonic); 124 | // const bip32 = BIP32Factory(ecc); 125 | const root = bip32.fromSeed(seed, btcNetwork); 126 | 127 | const account = root.derivePath(path); 128 | const node = account.derive(0); 129 | 130 | const publicKeyP2pkh = bitcoin.payments.p2pkh({ 131 | pubkey: node.publicKey, 132 | network: btcNetwork 133 | }).address || ''; 134 | 135 | const publicKeyBech32 = bitcoin.payments.p2wpkh({ 136 | pubkey: node.publicKey, 137 | network: btcNetwork 138 | }).address || '' 139 | 140 | return { 141 | address: { 142 | p2pkh: publicKeyP2pkh, 143 | bech32: publicKeyBech32 144 | }, 145 | privateKey: node.toWIF(), 146 | mnemonic: mnemonic 147 | } 148 | } 149 | 150 | /** 151 | * 152 | * @param network 153 | * @param privateKey 154 | * @returns {BtcAccount} 155 | */ 156 | importAccount = (privateKey: string, network?: BtcNetwork): BtcAccount => { 157 | let btcNetwork; 158 | 159 | const currentNetwork = network || BTC_MAINNET 160 | 161 | switch (currentNetwork) { 162 | case BTC_MAINNET: 163 | btcNetwork = bitcoin.networks.bitcoin; 164 | break; 165 | case BTC_REGTEST: 166 | btcNetwork = bitcoin.networks.regtest; 167 | break; 168 | case BTC_TESTNET: 169 | btcNetwork = bitcoin.networks.testnet; 170 | break; 171 | default: 172 | btcNetwork = bitcoin.networks.bitcoin; 173 | break; 174 | } 175 | 176 | const privateKeyObj = new PrivateKey(privateKey); 177 | 178 | const publicKeyBuffer = privateKeyObj.publicKey.toBuffer(); 179 | 180 | const publicKeyP2Pkh = bitcoin.payments.p2pkh({ 181 | pubkey: publicKeyBuffer, 182 | network: btcNetwork 183 | }).address || ''; 184 | 185 | const publicKeyBech32 = bitcoin.payments.p2wpkh({ 186 | pubkey: publicKeyBuffer, 187 | network: btcNetwork 188 | }).address || '' 189 | 190 | return { 191 | address: { 192 | p2pkh: publicKeyP2Pkh, 193 | bech32: publicKeyBech32 194 | }, 195 | privateKey: privateKey, 196 | } 197 | } 198 | 199 | /** 200 | * 201 | * @param address 202 | * @returns {Number} 203 | */ 204 | getBalance = async (address: string, network?: BtcNetwork): Promise => { 205 | try { 206 | let response: AxiosResponse 207 | 208 | switch (network) { 209 | case "bitcoin": 210 | response = await axios.get(`https://blockchain.info/q/addressbalance/${address}/`) 211 | break; 212 | case "testnet": 213 | response = await axios.get(`https://blockstream.info/testnet/api/address/${address}/utxo`) 214 | break; 215 | case "regtest": 216 | response = await axios.get(`https://blockstream.info/testnet/api/address/${address}/utxo`) 217 | break; 218 | default: 219 | response = await axios.get(`https://blockchain.info/q/addressbalance/${address}/`) 220 | break; 221 | } 222 | 223 | return response.data 224 | } catch (error) { 225 | throw error 226 | } 227 | } 228 | 229 | /** 230 | * 231 | * @param receiverAddress 232 | * @param amount 233 | * @returns {any} 234 | */ 235 | sendBitcoin = async (receiverAddress: string, amount: number, network?: BtcNetwork): Promise => { 236 | try { 237 | let btcNetwork; 238 | 239 | const currentNetwork = network || BTC_MAINNET 240 | 241 | switch (currentNetwork) { 242 | case BTC_MAINNET: 243 | btcNetwork = bitcoin.networks.bitcoin; 244 | break; 245 | case BTC_REGTEST: 246 | btcNetwork = bitcoin.networks.regtest; 247 | break; 248 | case BTC_TESTNET: 249 | btcNetwork = bitcoin.networks.testnet; 250 | break; 251 | default: 252 | btcNetwork = bitcoin.networks.bitcoin; 253 | break; 254 | } 255 | 256 | const response = await axios.get(`https://blockchain.info/unspent?active=${this.address.bech32}`) 257 | const utxos_1 = response.data.unspent_outputs 258 | 259 | return utxos_1 260 | } 261 | catch (error) { 262 | throw error 263 | } 264 | } 265 | } 266 | 267 | export default BitCoinWallet -------------------------------------------------------------------------------- /src/wallet/solana/SolanaWallet.ts: -------------------------------------------------------------------------------- 1 | import { provider } from "../../helper/solanaHelper"; 2 | import * as solanaWeb3 from "@solana/web3.js"; 3 | import { 4 | getOrCreateAssociatedTokenAccount, 5 | transfer as transferToken, 6 | getMint 7 | } from "@solana/spl-token"; 8 | import * as bs58 from 'bs58'; 9 | import * as bip39 from 'bip39'; 10 | import { derivePath } from "ed25519-hd-key"; 11 | // @ts-ignore 12 | import * as BufferLayout from 'buffer-layout'; 13 | 14 | import { 15 | CREATE_WALLET, 16 | IMPORT_WALLET, 17 | IMPORT_ACCOUNT, 18 | SEND_COIN, 19 | TRANSFER_TOKEN, 20 | GET_TOKEN, 21 | GET_TRANSACTION, 22 | GET_TOKEN_LIST, 23 | GET_BALANCE, 24 | GET_BALANCES 25 | } from "../../utils/constant"; 26 | import { 27 | ISplTokenInfo, 28 | ITokenInfo 29 | } from "../../utils/payloads/solana"; 30 | import { AnyObject } from "../../utils/globalType"; 31 | import { SOLANA_DEFAULT } from "../../utils/constant"; 32 | import { SOLANA_TOKENLIST_URI } from "../../utils/constant"; 33 | import { response, walletResponse, balanceResponse } from "../../utils/response"; 34 | import axios from "axios"; 35 | 36 | export const ACCOUNT_LAYOUT = BufferLayout.struct([ 37 | BufferLayout.blob(32, 'mint'), 38 | BufferLayout.blob(32, 'owner'), 39 | BufferLayout.nu64('amount'), 40 | BufferLayout.blob(93) 41 | ]) 42 | 43 | export const chainId = { 44 | 'mainnet-beta': 101, 45 | testnet: 102, 46 | devnet: 103, 47 | }; 48 | 49 | const getConnection = (rpcUrl: string) => { 50 | const connection = provider(rpcUrl); 51 | return connection; 52 | } 53 | 54 | const getBalance = async (rpcUrl: string, address: string, tokenAddress?: string) => { 55 | const connection = getConnection(rpcUrl); 56 | 57 | try { 58 | let balance; 59 | if (tokenAddress) { 60 | const account = await connection.getTokenAccountsByOwner( 61 | new solanaWeb3.PublicKey(address), 62 | { 63 | mint: new solanaWeb3.PublicKey(tokenAddress) 64 | } 65 | ); 66 | 67 | balance = account.value.length > 0 ? ACCOUNT_LAYOUT.decode(account.value[0].account.data).amount : 0; 68 | return balanceResponse( balance ); 69 | } 70 | const publicKey = new solanaWeb3.PublicKey(address); 71 | balance = await connection.getBalance(publicKey); 72 | 73 | return balanceResponse( balance ); 74 | } catch (err) { 75 | throw err; 76 | } 77 | } 78 | 79 | const createWallet = async (derivedPath?: string) => { 80 | const path = derivedPath || SOLANA_DEFAULT; 81 | 82 | const mnemonic = bip39.generateMnemonic(); 83 | const seed = await bip39.mnemonicToSeed(mnemonic); 84 | const derivedSeed = derivePath(path, (seed as unknown) as string).key; 85 | 86 | const keyPair = solanaWeb3.Keypair.fromSeed(derivedSeed); 87 | 88 | return walletResponse({ 89 | address: keyPair.publicKey.toBase58(), 90 | privateKey: bs58.encode(keyPair.secretKey), 91 | mnemonic 92 | }) 93 | } 94 | 95 | const importWallet = async (mnemonic: string, derivedPath: string) => { 96 | const path = derivedPath || SOLANA_DEFAULT; 97 | const seed = await bip39.mnemonicToSeed(mnemonic); 98 | const derivedSeed = derivePath(path, (seed as unknown) as string).key; 99 | const keyPair = solanaWeb3.Keypair.fromSeed(derivedSeed); 100 | 101 | return walletResponse({ 102 | address: keyPair.publicKey.toBase58(), 103 | privateKey: bs58.encode(keyPair.secretKey), 104 | mnemonic 105 | }) 106 | } 107 | 108 | const getKeyPairFromPrivateKey = (privateKey: string) => { 109 | const secretKey = bs58.decode(privateKey); 110 | const keyPair = solanaWeb3.Keypair.fromSecretKey(secretKey, { skipValidation: true }); 111 | 112 | return keyPair; 113 | } 114 | 115 | const importAccount = async (privateKey: string) => { 116 | const secretKey = bs58.decode(privateKey); 117 | const keyPair = solanaWeb3.Keypair.fromSecretKey(secretKey, { skipValidation: true }); 118 | 119 | return walletResponse({ 120 | address: keyPair.publicKey.toBase58(), 121 | privateKey: privateKey 122 | }) 123 | } 124 | 125 | const sendSol = async (rpcUrl: string, privateKey: string, from: string, to: string, amount: number) => { 126 | 127 | const connection = getConnection(rpcUrl); 128 | const keyPair = getKeyPairFromPrivateKey(privateKey); 129 | 130 | const fromPub = new solanaWeb3.PublicKey(from); 131 | const toPub = new solanaWeb3.PublicKey(to); 132 | 133 | const transaction = new solanaWeb3.Transaction().add( 134 | solanaWeb3.SystemProgram.transfer({ 135 | fromPubkey: fromPub, 136 | toPubkey: toPub, 137 | lamports: solanaWeb3.LAMPORTS_PER_SOL * amount 138 | }) 139 | ) 140 | 141 | const signature = await solanaWeb3.sendAndConfirmTransaction( 142 | connection, 143 | transaction, 144 | [keyPair] 145 | ) 146 | 147 | const tx = await connection.getTransaction(signature); 148 | 149 | return response({ 150 | ...tx 151 | }) 152 | } 153 | 154 | const tokenTransfer = async (rpcUrl: string, privateKey: string, tokenAddress: string, to: string, amount: number) => { 155 | const connection = getConnection(rpcUrl); 156 | 157 | try { 158 | const recipient = new solanaWeb3.PublicKey(to); 159 | let secretKey; 160 | let signature; 161 | 162 | if (privateKey.split(',').length > 1) { 163 | secretKey = new Uint8Array(privateKey.split(',') as any); 164 | } else { 165 | secretKey = bs58.decode(privateKey); 166 | } 167 | 168 | const from = solanaWeb3.Keypair.fromSecretKey(secretKey, { 169 | skipValidation: true, 170 | }); 171 | 172 | if (tokenAddress) { 173 | // Get token mint 174 | 175 | const mint = await getMint( 176 | connection, 177 | new solanaWeb3.PublicKey(tokenAddress) 178 | ); 179 | 180 | // Get the token account of the from address, and if it does not exist, create it 181 | const fromTokenAccount = await getOrCreateAssociatedTokenAccount( 182 | connection, 183 | from, 184 | mint.address, 185 | from.publicKey 186 | ); 187 | 188 | // Get the token account of the recipient address, and if it does not exist, create it 189 | const recipientTokenAccount = await getOrCreateAssociatedTokenAccount( 190 | connection, 191 | from, 192 | mint.address, 193 | recipient 194 | ); 195 | 196 | signature = await transferToken( 197 | connection, 198 | from, 199 | fromTokenAccount.address, 200 | recipientTokenAccount.address, 201 | from.publicKey, 202 | solanaWeb3.LAMPORTS_PER_SOL * amount 203 | ); 204 | } else { 205 | const transaction = new solanaWeb3.Transaction().add( 206 | solanaWeb3.SystemProgram.transfer({ 207 | fromPubkey: from.publicKey, 208 | toPubkey: recipient, 209 | lamports: solanaWeb3.LAMPORTS_PER_SOL * amount, 210 | }) 211 | ); 212 | 213 | // Sign transaction, broadcast, and confirm 214 | signature = await solanaWeb3.sendAndConfirmTransaction( 215 | connection, 216 | transaction, 217 | [from] 218 | ); 219 | } 220 | 221 | const tx = await connection.getTransaction(signature); 222 | 223 | return response({ 224 | ...tx, 225 | }); 226 | } catch (error) { 227 | throw error; 228 | } 229 | } 230 | 231 | const getTokenInfo = async (rpcUrl: string, cluster: 'mainnet-beta' | 'testnet' | 'devnet', address: string) => { 232 | try { 233 | const connection = getConnection(rpcUrl); 234 | const tokenList = await getTokenList(cluster!); 235 | const token = tokenList.find(token => token.address === address); 236 | 237 | if (token) { 238 | const data: ITokenInfo = { 239 | name: token.name, 240 | symbol: token.symbol, 241 | address: token.address, 242 | decimals: token.decimals, 243 | logoUrl: token.logoURI, 244 | totalSupply: 0 245 | } 246 | 247 | const totalSupply = await connection.getTokenSupply( 248 | new solanaWeb3.PublicKey(data.address) 249 | ); 250 | data.totalSupply = totalSupply.value.uiAmount!; 251 | 252 | return response({ ...data }); 253 | } 254 | return; 255 | } catch (err) { 256 | throw err; 257 | } 258 | } 259 | 260 | const getTokenList = async (cluster: 'mainnet-beta' | 'testnet' | 'devnet'): Promise => { 261 | const response = await axios.get(SOLANA_TOKENLIST_URI); 262 | if (response.data && response.data.tokens) { 263 | return response.data.tokens.filter( 264 | (data: ISplTokenInfo) => data.chainId === chainId[cluster] 265 | ); 266 | } 267 | return []; 268 | } 269 | 270 | const getTransaction = async (rpcUrl: string, hash: string) => { 271 | const connection = getConnection(rpcUrl); 272 | 273 | try { 274 | const tx = await connection.getTransaction(hash); 275 | return response({ 276 | ...tx 277 | }); 278 | } catch (err) { 279 | throw err; 280 | } 281 | } 282 | 283 | const SolanaWallet: AnyObject = { 284 | [CREATE_WALLET]: createWallet, 285 | [IMPORT_WALLET]: importWallet, 286 | [IMPORT_ACCOUNT]: importAccount, 287 | [SEND_COIN]: sendSol, 288 | [TRANSFER_TOKEN]: tokenTransfer, 289 | [GET_TOKEN]: getTokenInfo, 290 | [GET_TOKEN_LIST]: getTokenList, 291 | [GET_TRANSACTION]: getTransaction, 292 | [GET_BALANCE]: getBalance 293 | } 294 | 295 | export default SolanaWallet; -------------------------------------------------------------------------------- /src/wallet/cardano/CardanoWallet.ts: -------------------------------------------------------------------------------- 1 | import {Buffer} from 'buffer' 2 | import CardanoWalletLib from 'cardano-wallet' 3 | import { Bip32PrivateKey, Seed, ShelleyWallet, WalletServer } from 'cardano-wallet-js' 4 | import Cardano from '../../lib/@emurgo/cardano-multiplatform-lib-nodejs'; 5 | import * as bip39 from 'bip39'; 6 | 7 | import { CREATE_WALLET, IMPORT_WALLET, GET_BALANCES, GET_BALANCE, SEND_COIN, ERRORS } from '../../utils/constant' 8 | import { AnyObject } from '../../utils/globalType' 9 | import { response, walletResponse, balanceResponse } from '../../utils/response'; 10 | import { harden, getBalanceExtended, blockfrostRequest, getUtxos } from '../../helper/cardanoHelper'; 11 | 12 | const createWallet = async () => { 13 | const mnemonic = bip39.generateMnemonic() 14 | const entropy = bip39.mnemonicToEntropy(mnemonic) 15 | const rootKey = Cardano.Bip32PrivateKey.from_bip39_entropy(Buffer.from(entropy, 'hex'), Buffer.from('')) 16 | 17 | const rootKeyBytes = rootKey.as_bytes() 18 | 19 | const accountKey = Cardano.Bip32PrivateKey.from_bytes(rootKeyBytes).derive(harden(1852)).derive(harden(1815)).derive(harden(0)) 20 | const paymentKey = accountKey.derive(0).derive(0).to_raw_key() 21 | const stakeKey = accountKey.derive(2).derive(0).to_raw_key() 22 | 23 | const publicKey = Buffer.from(accountKey.to_public().as_bytes()).toString('hex') 24 | const paymentPubKey = paymentKey.to_public() 25 | const stakePubkey = stakeKey.to_public() 26 | 27 | const paymentKeyHash = Buffer.from(paymentPubKey.hash().to_bytes()).toString('hex') 28 | const paymentKeyHashBech32 = paymentPubKey.hash().to_bech32('addr_vkh') 29 | 30 | const stakeKeyHash = Buffer.from(stakePubkey.hash().to_bytes()).toString('hex') 31 | 32 | const paymentAddrMainnet = Cardano.BaseAddress.new( 33 | Cardano.NetworkInfo.mainnet().network_id(), 34 | Cardano.StakeCredential.from_keyhash(paymentPubKey.hash()), 35 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 36 | ).to_address().to_bech32() 37 | 38 | const rewardAddrMainnet = Cardano.RewardAddress.new( 39 | Cardano.NetworkInfo.mainnet().network_id(), 40 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 41 | ).to_address().to_bech32() 42 | 43 | const paymentAddrTestnet = Cardano.BaseAddress.new( 44 | Cardano.NetworkInfo.testnet().network_id(), 45 | Cardano.StakeCredential.from_keyhash(paymentPubKey.hash()), 46 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 47 | ).to_address().to_bech32() 48 | 49 | const rewardAddrTestnet = Cardano.RewardAddress.new( 50 | Cardano.NetworkInfo.testnet().network_id(), 51 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 52 | ).to_address().to_bech32() 53 | 54 | return response({ 55 | mnemonic, 56 | address: paymentAddrMainnet, 57 | publicKey, 58 | privateKey: accountKey.to_bech32(), 59 | paymentKey, 60 | stakeKey, 61 | paymentKeyHash, 62 | stakeKeyHash, 63 | paymentKeyHashBech32, 64 | testnetAddress: paymentAddrTestnet 65 | }) 66 | } 67 | 68 | const importWallet = async (mnemonic: string, index?: number) => { 69 | const entropy = bip39.mnemonicToEntropy(mnemonic) 70 | const rootKey = Cardano.Bip32PrivateKey.from_bip39_entropy(Buffer.from(entropy, 'hex'), Buffer.from('')) 71 | 72 | const rootKeyBytes = rootKey.as_bytes() 73 | 74 | const accountKey = Cardano.Bip32PrivateKey.from_bytes(rootKeyBytes).derive(harden(1852)).derive(harden(1815)).derive(harden(0)) 75 | const paymentKey = accountKey.derive(0).derive(index || 0).to_raw_key() 76 | const stakeKey = accountKey.derive(2).derive(0).to_raw_key() 77 | 78 | const publicKey = Buffer.from(accountKey.to_public().as_bytes()).toString('hex') 79 | const paymentPubKey = paymentKey.to_public() 80 | const stakePubkey = stakeKey.to_public() 81 | 82 | const paymentKeyHash = Buffer.from(paymentPubKey.hash().to_bytes()).toString('hex') 83 | const paymentKeyHashBech32 = paymentPubKey.hash().to_bech32('addr_vkh') 84 | 85 | const stakeKeyHash = Buffer.from(stakePubkey.hash().to_bytes()).toString('hex') 86 | 87 | const paymentAddrMainnet = Cardano.BaseAddress.new( 88 | Cardano.NetworkInfo.mainnet().network_id(), 89 | Cardano.StakeCredential.from_keyhash(paymentPubKey.hash()), 90 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 91 | ).to_address().to_bech32() 92 | 93 | const rewardAddrMainnet = Cardano.RewardAddress.new( 94 | Cardano.NetworkInfo.mainnet().network_id(), 95 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 96 | ).to_address().to_bech32() 97 | 98 | const paymentAddrTestnet = Cardano.BaseAddress.new( 99 | Cardano.NetworkInfo.testnet().network_id(), 100 | Cardano.StakeCredential.from_keyhash(paymentPubKey.hash()), 101 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 102 | ).to_address().to_bech32() 103 | 104 | const rewardAddrTestnet = Cardano.RewardAddress.new( 105 | Cardano.NetworkInfo.testnet().network_id(), 106 | Cardano.StakeCredential.from_keyhash(stakePubkey.hash()) 107 | ).to_address().to_bech32() 108 | 109 | return response({ 110 | mnemonic, 111 | address: paymentAddrMainnet, 112 | publicKey, 113 | privateKey: accountKey.to_bech32(), 114 | paymentKey, 115 | stakeKey, 116 | paymentKeyHash, 117 | stakeKeyHash, 118 | paymentKeyHashBech32, 119 | testnetAddress: paymentAddrTestnet 120 | }) 121 | } 122 | 123 | const getBalances = async (address: string, network?: 'mainnet' | 'testnet' | 'preprod' | 'preview') => { 124 | const balances = await getBalanceExtended(address, network || 'mainnet') 125 | 126 | return response( balances ) 127 | } 128 | 129 | const getBalance = async (address: string, network?: 'mainnet' | 'testnet' | 'preprod' | 'preview') => { 130 | const balances: [object] = await getBalanceExtended(address, network || 'mainnet') 131 | const ada: any = balances.filter((asset: any) => asset['unit'] === 'lovelace') 132 | const safeAdaBalance: number = ada[0]['quantity'] / 10 ** ada[0]['decimals'] 133 | 134 | return balanceResponse( safeAdaBalance ) 135 | } 136 | 137 | const sendAda = async (paymentKey: any, fromAddress: string, toAddress: string, amount: number, network?: 'mainnet' | 'testnet' | 'preprod' | 'preview') => { 138 | const protocolParameters: any = await blockfrostRequest(`/epochs/latest/parameters`, network || 'mainnet'); 139 | const latest_block = await blockfrostRequest('/blocks/latest', network || 'mainnet'); 140 | 141 | const coinsPerUtxoWord: string = protocolParameters.coins_per_utxo_size.toString() 142 | const minFeeA: string = protocolParameters.min_fee_a.toString() 143 | const minFeeB: string = protocolParameters.min_fee_b.toString() 144 | const keyDeposit = protocolParameters.key_deposit 145 | const poolDeposit = protocolParameters.pool_deposit 146 | const maxTxSize = parseInt(protocolParameters.max_tx_size) 147 | const maxValueSize = protocolParameters.max_val_size 148 | const collateralPercentage = parseInt(protocolParameters.collateral_percent) 149 | const maxCollateralInput = parseInt(protocolParameters.max_collateral_inputs) 150 | const slot = parseInt(latest_block.slot) 151 | 152 | const transactionOutputs = Cardano.TransactionOutputs.new() 153 | transactionOutputs.add( 154 | Cardano.TransactionOutput.new(Cardano.Address.from_bech32(toAddress), Cardano.Value.new(Cardano.BigNum.from_str(amount.toString()))) 155 | ) 156 | 157 | const txBuilderConfig = Cardano.TransactionBuilderConfigBuilder.new().coins_per_utxo_byte(Cardano.BigNum.from_str(coinsPerUtxoWord)) 158 | .fee_algo( 159 | Cardano.LinearFee.new( 160 | Cardano.BigNum.from_str(minFeeA), 161 | Cardano.BigNum.from_str(minFeeB) 162 | ) 163 | ) 164 | .key_deposit(Cardano.BigNum.from_str(keyDeposit)) 165 | .pool_deposit(Cardano.BigNum.from_str(poolDeposit)) 166 | .max_tx_size(maxTxSize) 167 | .max_value_size(maxValueSize) 168 | .ex_unit_prices(Cardano.ExUnitPrices.from_float(0, 0)) 169 | .collateral_percentage(collateralPercentage) 170 | .max_collateral_inputs(maxCollateralInput) 171 | .build() 172 | 173 | const txBuilder = Cardano.TransactionBuilder.new(txBuilderConfig) 174 | txBuilder.add_output(transactionOutputs.get(0)) 175 | 176 | txBuilder.set_ttl(Cardano.BigNum.from_str((slot + (3600 * 6).toString()))) 177 | 178 | const utxos = await getUtxos(fromAddress, network) 179 | 180 | const utxosCore = Cardano.TransactionUnspentOutputs.new() 181 | utxos.forEach((utxo) => utxosCore.add(utxo)) 182 | 183 | txBuilder.add_inputs_from( 184 | utxosCore, 185 | Cardano.Address.from_bech32(fromAddress) 186 | ) 187 | 188 | txBuilder.balance(Cardano.Address.from_bech32(fromAddress)) 189 | 190 | const transaction = await txBuilder.construct() 191 | 192 | // Sign Tx 193 | const txWitnessSet = Cardano.TransactionWitnessSet.new() 194 | const vKeyWitnesses = Cardano.Vkeywitnesses.new() 195 | const txHash = Cardano.hash_transaction(transaction.body()) 196 | 197 | const vKey = Cardano.make_vkey_witness(txHash, paymentKey) 198 | vKeyWitnesses.add(vKey) 199 | txWitnessSet.set_vkeys(vKeyWitnesses) 200 | 201 | // Submmit Tx 202 | const txToSubmmit = Cardano.Transaction.new(transaction.body(), txWitnessSet, transaction.auxiliary_data()) 203 | 204 | const txHex = Buffer.from(String(txToSubmmit.to_bytes()), 'hex').toString('hex') 205 | 206 | const result: any = await blockfrostRequest(`tx/submit`, network || 'mainnet', { 'Content-Type': 'application/cbor' }, Buffer.from(txHex, 'hex')) 207 | 208 | if(result.error) { 209 | throw ERRORS.invalid_api_request 210 | } 211 | 212 | return result 213 | } 214 | 215 | const CardanoWallet: AnyObject = { 216 | [CREATE_WALLET]: createWallet, 217 | [IMPORT_WALLET]: importWallet, 218 | [GET_BALANCES]: getBalances, 219 | [GET_BALANCE]: getBalance, 220 | [SEND_COIN]: sendAda 221 | } 222 | 223 | export default CardanoWallet -------------------------------------------------------------------------------- /src/abi/erc721.ts: -------------------------------------------------------------------------------- 1 | const ecr721ABI = [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "owner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "approved", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "Approval", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "owner", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "operator", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "bool", 45 | "name": "approved", 46 | "type": "bool" 47 | } 48 | ], 49 | "name": "ApprovalForAll", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "from", 59 | "type": "address" 60 | }, 61 | { 62 | "indexed": true, 63 | "internalType": "address", 64 | "name": "to", 65 | "type": "address" 66 | }, 67 | { 68 | "indexed": true, 69 | "internalType": "uint256", 70 | "name": "tokenId", 71 | "type": "uint256" 72 | } 73 | ], 74 | "name": "Transfer", 75 | "type": "event" 76 | }, 77 | { 78 | "inputs": [ 79 | { 80 | "internalType": "address", 81 | "name": "to", 82 | "type": "address" 83 | }, 84 | { 85 | "internalType": "uint256", 86 | "name": "tokenId", 87 | "type": "uint256" 88 | } 89 | ], 90 | "name": "approve", 91 | "outputs": [], 92 | "stateMutability": "nonpayable", 93 | "type": "function" 94 | }, 95 | { 96 | "inputs": [ 97 | { 98 | "internalType": "address", 99 | "name": "owner", 100 | "type": "address" 101 | } 102 | ], 103 | "name": "balanceOf", 104 | "outputs": [ 105 | { 106 | "internalType": "uint256", 107 | "name": "balance", 108 | "type": "uint256" 109 | } 110 | ], 111 | "stateMutability": "view", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "uint256", 118 | "name": "tokenId", 119 | "type": "uint256" 120 | } 121 | ], 122 | "name": "getApproved", 123 | "outputs": [ 124 | { 125 | "internalType": "address", 126 | "name": "operator", 127 | "type": "address" 128 | } 129 | ], 130 | "stateMutability": "view", 131 | "type": "function" 132 | }, 133 | { 134 | "inputs": [ 135 | { 136 | "internalType": "address", 137 | "name": "owner", 138 | "type": "address" 139 | }, 140 | { 141 | "internalType": "address", 142 | "name": "operator", 143 | "type": "address" 144 | } 145 | ], 146 | "name": "isApprovedForAll", 147 | "outputs": [ 148 | { 149 | "internalType": "bool", 150 | "name": "", 151 | "type": "bool" 152 | } 153 | ], 154 | "stateMutability": "view", 155 | "type": "function" 156 | }, 157 | { 158 | "inputs": [], 159 | "name": "name", 160 | "outputs": [ 161 | { 162 | "internalType": "string", 163 | "name": "", 164 | "type": "string" 165 | } 166 | ], 167 | "stateMutability": "view", 168 | "type": "function" 169 | }, 170 | { 171 | "inputs": [ 172 | { 173 | "internalType": "uint256", 174 | "name": "tokenId", 175 | "type": "uint256" 176 | } 177 | ], 178 | "name": "ownerOf", 179 | "outputs": [ 180 | { 181 | "internalType": "address", 182 | "name": "owner", 183 | "type": "address" 184 | } 185 | ], 186 | "stateMutability": "view", 187 | "type": "function" 188 | }, 189 | { 190 | "inputs": [ 191 | { 192 | "internalType": "address", 193 | "name": "from", 194 | "type": "address" 195 | }, 196 | { 197 | "internalType": "address", 198 | "name": "to", 199 | "type": "address" 200 | }, 201 | { 202 | "internalType": "uint256", 203 | "name": "tokenId", 204 | "type": "uint256" 205 | } 206 | ], 207 | "name": "safeTransferFrom", 208 | "outputs": [], 209 | "stateMutability": "nonpayable", 210 | "type": "function" 211 | }, 212 | { 213 | "inputs": [ 214 | { 215 | "internalType": "address", 216 | "name": "from", 217 | "type": "address" 218 | }, 219 | { 220 | "internalType": "address", 221 | "name": "to", 222 | "type": "address" 223 | }, 224 | { 225 | "internalType": "uint256", 226 | "name": "tokenId", 227 | "type": "uint256" 228 | }, 229 | { 230 | "internalType": "bytes", 231 | "name": "data", 232 | "type": "bytes" 233 | } 234 | ], 235 | "name": "safeTransferFrom", 236 | "outputs": [], 237 | "stateMutability": "nonpayable", 238 | "type": "function" 239 | }, 240 | { 241 | "inputs": [ 242 | { 243 | "internalType": "address", 244 | "name": "operator", 245 | "type": "address" 246 | }, 247 | { 248 | "internalType": "bool", 249 | "name": "_approved", 250 | "type": "bool" 251 | } 252 | ], 253 | "name": "setApprovalForAll", 254 | "outputs": [], 255 | "stateMutability": "nonpayable", 256 | "type": "function" 257 | }, 258 | { 259 | "inputs": [ 260 | { 261 | "internalType": "bytes4", 262 | "name": "interfaceId", 263 | "type": "bytes4" 264 | } 265 | ], 266 | "name": "supportsInterface", 267 | "outputs": [ 268 | { 269 | "internalType": "bool", 270 | "name": "", 271 | "type": "bool" 272 | } 273 | ], 274 | "stateMutability": "view", 275 | "type": "function" 276 | }, 277 | { 278 | "inputs": [], 279 | "name": "symbol", 280 | "outputs": [ 281 | { 282 | "internalType": "string", 283 | "name": "", 284 | "type": "string" 285 | } 286 | ], 287 | "stateMutability": "view", 288 | "type": "function" 289 | }, 290 | { 291 | "inputs": [ 292 | { 293 | "internalType": "uint256", 294 | "name": "index", 295 | "type": "uint256" 296 | } 297 | ], 298 | "name": "tokenByIndex", 299 | "outputs": [ 300 | { 301 | "internalType": "uint256", 302 | "name": "", 303 | "type": "uint256" 304 | } 305 | ], 306 | "stateMutability": "view", 307 | "type": "function" 308 | }, 309 | { 310 | "inputs": [ 311 | { 312 | "internalType": "address", 313 | "name": "owner", 314 | "type": "address" 315 | }, 316 | { 317 | "internalType": "uint256", 318 | "name": "index", 319 | "type": "uint256" 320 | } 321 | ], 322 | "name": "tokenOfOwnerByIndex", 323 | "outputs": [ 324 | { 325 | "internalType": "uint256", 326 | "name": "tokenId", 327 | "type": "uint256" 328 | } 329 | ], 330 | "stateMutability": "view", 331 | "type": "function" 332 | }, 333 | { 334 | "inputs": [ 335 | { 336 | "internalType": "uint256", 337 | "name": "tokenId", 338 | "type": "uint256" 339 | } 340 | ], 341 | "name": "tokenURI", 342 | "outputs": [ 343 | { 344 | "internalType": "string", 345 | "name": "", 346 | "type": "string" 347 | } 348 | ], 349 | "stateMutability": "view", 350 | "type": "function" 351 | }, 352 | { 353 | "inputs": [], 354 | "name": "totalSupply", 355 | "outputs": [ 356 | { 357 | "internalType": "uint256", 358 | "name": "", 359 | "type": "uint256" 360 | } 361 | ], 362 | "stateMutability": "view", 363 | "type": "function" 364 | }, 365 | { 366 | "inputs": [ 367 | { 368 | "internalType": "address", 369 | "name": "from", 370 | "type": "address" 371 | }, 372 | { 373 | "internalType": "address", 374 | "name": "to", 375 | "type": "address" 376 | }, 377 | { 378 | "internalType": "uint256", 379 | "name": "tokenId", 380 | "type": "uint256" 381 | } 382 | ], 383 | "name": "transferFrom", 384 | "outputs": [], 385 | "stateMutability": "nonpayable", 386 | "type": "function" 387 | } 388 | ] 389 | 390 | export default ecr721ABI -------------------------------------------------------------------------------- /src/wallet/ethereum/EthereumWallet.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import axios from 'axios'; 3 | 4 | import { ethers } from 'ethers'; 5 | import { hdkey } from 'ethereumjs-wallet'; 6 | import { mnemonicToSeed } from 'bip39'; 7 | 8 | // import response format 9 | import { response, walletResponse, balanceResponse } from '../../utils/response'; 10 | // import constants 11 | import { ETHEREUM_DEFAULT } from '../../utils/constant'; 12 | // import actions 13 | import { 14 | CREATE_WALLET, 15 | IMPORT_WALLET, 16 | CREATE_MASTERSEED, 17 | CREATE_ACCOUNT, 18 | IMPORT_ACCOUNT, 19 | GET_BALANCE, 20 | GET_TOKEN_BALANCE, 21 | GET_TOKEN, 22 | SEND_COIN, 23 | APPROVE_TOKEN, 24 | TRANSFER_TOKEN, 25 | GET_GAS, 26 | ETHER_GASSTATION_API 27 | } from '../../utils/constant'; 28 | // import ineterface 29 | import { AnyObject } from '../../utils/globalType'; 30 | import { GasEstimationPayload } from 'utils/payloads/ethereum'; 31 | // import util functions 32 | import { 33 | isContractAddress, 34 | isNftContract 35 | } from '../../helper/ethereumHelper'; 36 | // import ABI 37 | import ERC20 from '../../abi/erc20'; 38 | import ERC721 from '../../abi/erc721'; 39 | 40 | import { weiToEther, gweiToEther, gweiToWei } from '../../utils/utils'; 41 | 42 | /** 43 | * 44 | * @param args 45 | * @description Create Ethereum wallet 46 | * @returns Created Wallet 47 | */ 48 | const createWallet = async (derivationPath?: string, nonce?: number) => { 49 | const path = derivationPath || ETHEREUM_DEFAULT; 50 | const index = nonce || Math.floor(Math.random() * 10); 51 | 52 | const wallet = ethers.Wallet.createRandom({ path: path + index }); 53 | 54 | return walletResponse({ 55 | address: wallet.address, 56 | privateKey: wallet.privateKey, 57 | mnemonic: wallet.mnemonic.phrase, 58 | nonce: index 59 | }) 60 | } 61 | 62 | /** 63 | * 64 | * @param mnemonic 65 | * @param derivationPath 66 | * @returns Imported Wallet 67 | */ 68 | const importWallet = async (mnemonic: string, nonce?: number, derivationPath?: string) => { 69 | const path = derivationPath || ETHEREUM_DEFAULT; 70 | 71 | const index = nonce || 0; 72 | 73 | const wallet = ethers.Wallet.fromMnemonic(mnemonic, path + index); 74 | 75 | return walletResponse({ 76 | address: wallet.address, 77 | privateKey: wallet.privateKey, 78 | mnemonic: wallet.mnemonic.phrase, 79 | nonce: index 80 | }) 81 | } 82 | 83 | const createMasterSeedFromMnemonic = async (mnemonic: string) => { 84 | const seed = await mnemonicToSeed(mnemonic); 85 | return seed; 86 | } 87 | 88 | /** 89 | * 90 | * @param rootKey 91 | * @returns New Account 92 | */ 93 | const createAccount = async (rootKey: any, nonce: number) => { 94 | const hdWallet = await hdkey.fromMasterSeed(rootKey); 95 | const wallet = hdWallet.derivePath(ETHEREUM_DEFAULT + nonce).getWallet(); 96 | const address = `0x${wallet.getAddress().toString('hex')}`; 97 | const privateKey = wallet.getPrivateKey().toString('hex'); 98 | 99 | return walletResponse({ 100 | address: address, 101 | privateKey: privateKey 102 | }); 103 | } 104 | 105 | /** 106 | * 107 | * @param privateKey 108 | * @returns Imported Account 109 | */ 110 | const importAccount = async (privateKey: string) => { 111 | 112 | const account = new ethers.Wallet(privateKey); 113 | 114 | return walletResponse({ 115 | address: account.address, 116 | privateKey: account.privateKey 117 | }) 118 | } 119 | 120 | /** 121 | * 122 | * @param rpcUrl 123 | * @param address 124 | * @returns Address and ETH balance 125 | */ 126 | const getBalance = async (rpcUrl: string, address: string) => { 127 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 128 | 129 | const balance = await provider.getBalance(address); 130 | return balanceResponse( parseInt(balance['_hex'], 16) ) 131 | } 132 | 133 | /** 134 | * 135 | * @param tokenAddress 136 | * @param rpcUrl 137 | * @param address 138 | * @returns Token info 139 | */ 140 | const getToken = async (tokenAddress: string, rpcUrl: string, address: string) => { 141 | const isContract = await isContractAddress(rpcUrl, tokenAddress); 142 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 143 | var contract: AnyObject; 144 | 145 | if (!isContract) { 146 | return false; 147 | } else { 148 | const isNft = await isNftContract(rpcUrl, tokenAddress); 149 | 150 | if (isNft) { 151 | contract = new ethers.Contract(tokenAddress, ERC721, provider); 152 | 153 | try { 154 | const [name, symbol, totalSupply, balance] = await Promise.all([ 155 | contract.name(), 156 | contract.symbol(), 157 | contract.totalSupply(), 158 | contract.balanceOf(address) 159 | ]); 160 | 161 | return response({ 162 | name: name, 163 | symbol: symbol, 164 | totalSupply: totalSupply, 165 | balance: balance, 166 | isNft: isNft 167 | }) 168 | } catch (err) { 169 | const [name, symbol, totalSupply, balance] = await Promise.all([ 170 | contract._name(), 171 | contract._symbol(), 172 | contract._totalSupply(), 173 | contract.balanceOf(address) 174 | ]); 175 | 176 | return response({ 177 | name: name, 178 | symbol: symbol, 179 | totalSupply: totalSupply, 180 | balance: balance, 181 | isNft: isNft 182 | }) 183 | } 184 | } else { 185 | contract = new ethers.Contract(tokenAddress, ERC20, provider); 186 | 187 | try { 188 | const [name, symbol, decimals, totalSupply, balance] = await Promise.all([ 189 | contract.name(), 190 | contract.symbol(), 191 | contract.decimals(), 192 | contract.totalSupply(), 193 | contract.balanceOf(address) 194 | ]); 195 | 196 | return response({ 197 | name: name, 198 | symbol: symbol, 199 | decimals: decimals, 200 | totalSupply: totalSupply, 201 | balance: balance, 202 | isNft: isNft 203 | }) 204 | } catch (err) { 205 | const [name, symbol, decimals, totalSupply, balance] = await Promise.all([ 206 | contract._name(), 207 | contract._symbol(), 208 | contract._decimals(), 209 | contract._totalSupply(), 210 | contract.balanceOf(address) 211 | ]); 212 | 213 | return response({ 214 | name: name, 215 | symbol: symbol, 216 | decimals: decimals, 217 | totalSupply: totalSupply, 218 | balance: balance, 219 | isNft: isNft 220 | }) 221 | } 222 | } 223 | } 224 | } 225 | 226 | /** 227 | * 228 | * @param tokenAddress 229 | * @param rpcUrl 230 | * @param address 231 | * @returns Token balance 232 | */ 233 | const getTokenBalance = async (tokenAddress: string, rpcUrl: string, address: string) => { 234 | try { 235 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl) 236 | const contract = new ethers.Contract(tokenAddress, ERC20, provider); 237 | 238 | const balance = await contract.balanceOf(address) 239 | 240 | return balanceResponse(balance) 241 | } 242 | catch (err) { 243 | throw response({err}) 244 | } 245 | } 246 | 247 | /** 248 | * 249 | * @param rpcUrl 250 | * @param privateKey 251 | * @param receiveAddress 252 | * @param amount 253 | * @returns transaction result 254 | */ 255 | const sendEther = async (rpcUrl: string, privateKey: string, receiveAddress: string, amount: string, gasPrice?: any, gasLimit?: any) => { 256 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 257 | const senderAccount = new ethers.Wallet(privateKey, provider); 258 | 259 | try { 260 | let tx; 261 | if(gasPrice && gasLimit) { 262 | tx = await senderAccount.sendTransaction({ 263 | to: receiveAddress, 264 | value: ethers.utils.parseEther(amount), 265 | gasPrice, 266 | gasLimit 267 | }) 268 | } 269 | else { 270 | tx = await senderAccount.sendTransaction({ 271 | to: receiveAddress, 272 | value: ethers.utils.parseEther(amount), 273 | }) 274 | } 275 | 276 | return response(tx); 277 | } 278 | catch (err) { 279 | throw response({err}) 280 | } 281 | } 282 | 283 | const tokenApprove = async (rpcUrl: string, privateKey: string, receiveAddress: string, tokenAddress: string, amount: string, gasPrice?: any, gasLimit?: any) => { 284 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 285 | const senderAccount = new ethers.Wallet(privateKey, provider); 286 | const contract = new ethers.Contract(tokenAddress, ERC20, provider); 287 | const signedContract = contract.connect(senderAccount); 288 | 289 | try { 290 | let tx; 291 | 292 | if(gasPrice && gasLimit) { 293 | tx = await signedContract.approve(receiveAddress, amount, { gasPrice: gasPrice, gasLimit: gasLimit }); 294 | } 295 | else { 296 | tx = await signedContract.approve(receiveAddress, amount); 297 | } 298 | 299 | return response(tx); 300 | } catch (err) { 301 | throw response({ err }); 302 | } 303 | } 304 | 305 | const tokenTransfer = async (rpcUrl: string, privateKey: string, receiveAddress: string, tokenAddress: string, amount: any, gasPrice?: any, gasLimit?: any) => { 306 | 307 | const provider = new ethers.providers.JsonRpcProvider(rpcUrl); 308 | const senderAccount = new ethers.Wallet(privateKey, provider); 309 | 310 | const contract = new ethers.Contract(tokenAddress, ERC20, provider); 311 | const signedContract = contract.connect(senderAccount); 312 | 313 | 314 | try { 315 | let tx; 316 | if(gasPrice && gasLimit) { 317 | tx = await signedContract.transfer(receiveAddress, amount, { gasPrice, gasLimit }); 318 | } 319 | else { 320 | tx = await signedContract.transfer(receiveAddress, amount); 321 | } 322 | return response(tx); 323 | } catch (err) { 324 | throw response({ err }); 325 | } 326 | } 327 | 328 | const getGas = async (): Promise => { 329 | try { 330 | const gasResponse = await axios.get(ETHER_GASSTATION_API) 331 | const estimatedGas = gasResponse.data 332 | 333 | const low = Number(estimatedGas.safeLow / 10) 334 | const average = Number(estimatedGas.average / 10) 335 | const fast = Number(estimatedGas.fast / 10) 336 | const lowWei = await gweiToWei(low) 337 | const averageWei = await gweiToWei(average) 338 | const fastWei = await gweiToWei(fast) 339 | const lowEth = await gweiToEther(low) 340 | const averageEth = await gweiToEther(average) 341 | const fastEth = await gweiToEther(fast) 342 | const safeLowWaitMin = estimatedGas.safeLowWait; 343 | const avgWaitMin = estimatedGas.avgWait; 344 | const fastWaitMin = estimatedGas.fastWait; 345 | 346 | return { 347 | low, 348 | average, 349 | fast, 350 | lowWei, 351 | averageWei, 352 | fastWei, 353 | lowEth, 354 | averageEth, 355 | fastEth, 356 | safeLowWaitMin, 357 | avgWaitMin, 358 | fastWaitMin 359 | } 360 | } 361 | catch (err) { 362 | throw response({err}) 363 | } 364 | } 365 | 366 | const EthereumWallet: AnyObject = { 367 | [CREATE_WALLET]: createWallet, 368 | [IMPORT_WALLET]: importWallet, 369 | [CREATE_ACCOUNT]: createAccount, 370 | [CREATE_MASTERSEED]: createMasterSeedFromMnemonic, 371 | [IMPORT_ACCOUNT]: importAccount, 372 | [GET_BALANCE]: getBalance, 373 | [GET_TOKEN_BALANCE]: getTokenBalance, 374 | [GET_TOKEN]: getToken, 375 | [SEND_COIN]: sendEther, 376 | [APPROVE_TOKEN]: tokenApprove, 377 | [TRANSFER_TOKEN]: tokenTransfer, 378 | [GET_GAS]: getGas 379 | } 380 | 381 | export default EthereumWallet; -------------------------------------------------------------------------------- /src/wallet_class/ethereum/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | // import core-packages 4 | import { Contract, ContractInterface, Interface, InterfaceAbi, ethers } from 'ethers'; 5 | import { hdkey } from 'ethereumjs-wallet'; 6 | import { mnemonicToSeed } from 'bip39'; 7 | 8 | // import constants 9 | import { 10 | ERC721_INTERFACE_ID, 11 | ERC1155_INTERFACE_ID, 12 | ETHEREUM_DEFAULT 13 | } from '../../constant'; 14 | // import ABI 15 | import { erc20ABI, ecr721ABI, erc1155ABI } from '../../abi' 16 | // import Util class 17 | import Util from '../../util_class/ethereum'; 18 | 19 | // import types 20 | import { EvmWallet, EvmAccount, EvmTokenDetail, ERCTokenType, IsNFT } from '../../type/type'; 21 | 22 | class EthereumWallet { 23 | // Network data 24 | provider: ethers.JsonRpcProvider 25 | chainId: number | BigInt = 0 26 | 27 | // Wallet main data 28 | privateKey: string 29 | address: string 30 | signer: ethers.Wallet 31 | 32 | // Utility helper library 33 | Util: Util = Util 34 | 35 | /** 36 | * 37 | * @param rpcUrl 38 | * @param privateKey 39 | */ 40 | constructor(rpcUrl: string, privateKey?: string) { 41 | this.provider = new ethers.JsonRpcProvider(rpcUrl) 42 | 43 | this.provider.getNetwork().then(network => { 44 | this.chainId = network.chainId 45 | }).catch(() => { 46 | this.chainId = 0 47 | }) 48 | 49 | if(privateKey) { 50 | this.signer = new ethers.Wallet(privateKey, this.provider) 51 | this.privateKey = privateKey 52 | this.address = this.signer.address 53 | } 54 | else { 55 | const _tempWallet = this.createWallet() 56 | this.signer = new ethers.Wallet(_tempWallet.privateKey, this.provider) 57 | this.privateKey = _tempWallet.privateKey 58 | this.address = _tempWallet.address 59 | } 60 | } 61 | 62 | /** 63 | * 64 | * @param derivationPath 65 | * @param nonce 66 | * @returns {EvmWallet} 67 | */ 68 | createWallet = (nonce?: number): EvmWallet => { 69 | const index = nonce || Math.floor(Math.random() * 10); 70 | 71 | const wallet = ethers.Wallet.createRandom(); 72 | 73 | return { 74 | address: wallet.address, 75 | privateKey: wallet.privateKey, 76 | mnemonic: wallet.mnemonic?.phrase, 77 | nonce: index 78 | } 79 | } 80 | 81 | /** 82 | * 83 | * @param mnemonic 84 | * @param nonce 85 | * @param derivationPath 86 | * @returns {EvmWallet} 87 | */ 88 | recoverWallet = (mnemonic: string, nonce?: number): EvmWallet => { 89 | 90 | const index = nonce || 0; 91 | 92 | const wallet = ethers.Wallet.fromPhrase(mnemonic); 93 | 94 | return { 95 | address: wallet.address, 96 | privateKey: wallet.privateKey, 97 | mnemonic: wallet.mnemonic?.phrase, 98 | nonce: index 99 | } 100 | } 101 | 102 | /** 103 | * 104 | * @param mnemonic 105 | * @returns {Promise} 106 | */ 107 | createMasterSeedFromMnemonic = async (mnemonic: string): Promise => { 108 | try { 109 | const seed = await mnemonicToSeed(mnemonic); 110 | return seed; 111 | } 112 | catch(error) { 113 | throw error 114 | } 115 | } 116 | 117 | /** 118 | * 119 | * @param rootSeed 120 | * @param nonce 121 | * @returns {Promise} 122 | */ 123 | createAccount = async (rootSeed: Buffer, nonce?: number): Promise => { 124 | try { 125 | const hdWallet = await hdkey.fromMasterSeed(rootSeed); 126 | const wallet = hdWallet.derivePath(ETHEREUM_DEFAULT + (nonce || 0)).getWallet(); 127 | const address = `0x${wallet.getAddress().toString('hex')}`; 128 | const privateKey = wallet.getPrivateKey().toString('hex'); 129 | 130 | return { 131 | address: address, 132 | privateKey: privateKey 133 | }; 134 | } 135 | catch(error) { 136 | throw error 137 | } 138 | } 139 | 140 | /** 141 | * 142 | * @param privateKey 143 | * @returns {EvmAccount} 144 | */ 145 | importAccount = (privateKey: string): EvmAccount => { 146 | const account = new ethers.Wallet(privateKey); 147 | 148 | return { 149 | address: account.address, 150 | privateKey: account.privateKey 151 | } 152 | } 153 | 154 | /** 155 | * 156 | * @param address 157 | * @returns {Promise} 158 | */ 159 | getBalance = async (address?: string): Promise => { 160 | const balance = await this.provider.getBalance(address || this.address); 161 | return balance 162 | } 163 | 164 | /** 165 | * 166 | * @param tokenAddress 167 | * @param address 168 | * @param tokenId 169 | * @returns {Promise} 170 | */ 171 | getToken = async (tokenAddress: string, address?: string, tokenId?: number): Promise => { 172 | const isContract = await this.isContractAddress(tokenAddress) 173 | let contract: ethers.Contract 174 | let tokenDetail: EvmTokenDetail 175 | 176 | if (!isContract) { 177 | tokenDetail = { 178 | name: '', 179 | symbol: '', 180 | decimals: 0, 181 | totalSupply: 0, 182 | balance: 0, 183 | isNft: false, 184 | tokenType: undefined 185 | } 186 | } 187 | else { 188 | const isNFT = await this.isNftContract(tokenAddress) 189 | if(isNFT.tokenType === 'ERC721') { 190 | contract = new ethers.Contract(tokenAddress, ecr721ABI, this.provider) 191 | 192 | try { 193 | const [name, symbol, decimals, totalSupply, balance] = await Promise.all([ 194 | contract.name(), 195 | contract.symbol(), 196 | contract.decimals(), 197 | contract.totalSupply(), 198 | contract.balanceOf(address || this.address) 199 | ]); 200 | 201 | tokenDetail = { 202 | name: name, 203 | symbol: symbol, 204 | decimals: decimals, 205 | totalSupply: totalSupply, 206 | balance: balance, 207 | isNft: isNFT.isNFT, 208 | tokenType: isNFT.tokenType 209 | } 210 | } catch (error) { 211 | throw error 212 | } 213 | } 214 | else if (isNFT.tokenType === 'ERC1155') { 215 | contract = new ethers.Contract(tokenAddress, erc1155ABI, this.provider) 216 | 217 | try { 218 | const [name, symbol, decimals, totalSupply, balance] = await Promise.all([ 219 | contract.name(), 220 | contract.symbol(), 221 | contract.decimals(), 222 | contract.totalSupply(), 223 | tokenId ? contract.balanceOf(address || this.address, tokenId) : () => { return 0 } 224 | ]); 225 | 226 | tokenDetail = { 227 | name: name, 228 | symbol: symbol, 229 | decimals: decimals, 230 | totalSupply: totalSupply, 231 | balance: balance, 232 | isNft: isNFT.isNFT, 233 | tokenType: isNFT.tokenType 234 | } 235 | } catch (error) { 236 | throw error 237 | } 238 | } 239 | else { 240 | contract = new ethers.Contract(tokenAddress, erc20ABI, this.provider) 241 | 242 | try { 243 | const [name, symbol, decimals, totalSupply, balance] = await Promise.all([ 244 | contract.name(), 245 | contract.symbol(), 246 | contract.decimals(), 247 | contract.totalSupply(), 248 | contract.balanceOf(address || this.address) 249 | ]); 250 | 251 | tokenDetail = { 252 | name: name, 253 | symbol: symbol, 254 | decimals: decimals, 255 | totalSupply: totalSupply, 256 | balance: balance, 257 | isNft: isNFT.isNFT, 258 | tokenType: isNFT.tokenType 259 | } 260 | } catch (error) { 261 | throw error 262 | } 263 | } 264 | } 265 | 266 | return tokenDetail 267 | } 268 | 269 | /** 270 | * 271 | * @param tokenAddress 272 | * @param address 273 | * @returns {Promise} 274 | */ 275 | getTokenBalance = async (tokenAddress: string, address?: string): Promise => { 276 | try { 277 | const contract = new ethers.Contract(tokenAddress, erc20ABI, this.provider); 278 | 279 | const balance = await contract.balanceOf(address || this.address) 280 | 281 | return balance 282 | } 283 | catch (error) { 284 | throw error 285 | } 286 | } 287 | 288 | /** 289 | * 290 | * @param receiveAddress 291 | * @param amount 292 | * @param gasPrice 293 | * @param gasLimit 294 | * @returns {Promise} 295 | */ 296 | sendEther = async (receiveAddress: string, amount: string, gasPrice?: any, gasLimit?: any): Promise => { 297 | try { 298 | let tx: ethers.TransactionResponse; 299 | 300 | if(gasPrice && gasLimit) { 301 | tx = await this.signer.sendTransaction({ 302 | to: receiveAddress, 303 | value: ethers.parseUnits(amount), 304 | gasPrice, 305 | gasLimit 306 | }) 307 | } 308 | else { 309 | tx = await this.signer.sendTransaction({ 310 | to: receiveAddress, 311 | value: ethers.parseEther(amount), 312 | }) 313 | } 314 | 315 | return tx; 316 | } 317 | catch (error) { 318 | throw error 319 | } 320 | } 321 | 322 | /** 323 | * 324 | * @param tokenAddress 325 | * @param receiveAddress 326 | * @param amount 327 | * @param gasPrice 328 | * @param gasLimit 329 | * @returns {Promise} 330 | */ 331 | tokenApprove = async (tokenAddress: string, amount: string, receiveAddress: string, gasPrice?: any, gasLimit?: any): Promise => { 332 | const contract = new ethers.Contract(tokenAddress, erc20ABI, this.signer); 333 | 334 | try { 335 | let tx: ethers.TransactionResponse; 336 | 337 | if(gasPrice && gasLimit) { 338 | tx = await contract.approve(receiveAddress, amount, { gasPrice: gasPrice, gasLimit: gasLimit }); 339 | } 340 | else { 341 | tx = await contract.approve(receiveAddress, amount); 342 | } 343 | 344 | return tx 345 | } catch (error) { 346 | throw error 347 | } 348 | } 349 | 350 | /** 351 | * 352 | * @param tokenAddress 353 | * @param amount 354 | * @param receiveAddress 355 | * @param gasPrice 356 | * @param gasLimit 357 | * @returns {Promise} 358 | */ 359 | tokenTransfer = async (tokenAddress: string, amount: any, receiveAddress: string, gasPrice?: any, gasLimit?: any): Promise => { 360 | const contract = new ethers.Contract(tokenAddress, erc20ABI, this.signer); 361 | 362 | try { 363 | let tx: ethers.TransactionResponse; 364 | if(gasPrice && gasLimit) { 365 | tx = await contract.transfer(receiveAddress, amount, { gasPrice, gasLimit }); 366 | } 367 | else { 368 | tx = await contract.transfer(receiveAddress, amount); 369 | } 370 | return tx 371 | } catch (error) { 372 | throw error 373 | } 374 | } 375 | 376 | /* util function */ 377 | 378 | /** 379 | * 380 | * @param address 381 | * @returns {Promise} 382 | */ 383 | isContractAddress = async (address: string): Promise => { 384 | try { 385 | const code = await this.provider.getCode(address); 386 | if (code !== '0x') 387 | return true; 388 | else 389 | return false; 390 | } catch { 391 | return false; 392 | } 393 | } 394 | 395 | /** 396 | * 397 | * @param address 398 | * @returns {Promise} 399 | */ 400 | isNftContract = async (address: string): Promise => { 401 | 402 | let isNFT: boolean 403 | let tokenType: ERCTokenType 404 | 405 | try { 406 | const isERC721NFT = await this.isERC721NFT(address) 407 | const isERC1155NFT = await this.isERC1155NFT(address) 408 | 409 | if(isERC721NFT) { 410 | isNFT = true 411 | tokenType = 'ERC721' 412 | } 413 | else if(isERC1155NFT) { 414 | isNFT = true 415 | tokenType = 'ERC1155' 416 | } 417 | else { 418 | isNFT = false 419 | tokenType = 'ERC20' 420 | } 421 | 422 | return { isNFT, tokenType } 423 | } 424 | catch(error) { 425 | throw error 426 | } 427 | } 428 | 429 | /** 430 | * 431 | * @param address 432 | * @returns {Promise} 433 | */ 434 | isERC721NFT = async (address: string): Promise => { 435 | const contract = new ethers.Contract(address, ecr721ABI, this.provider) 436 | 437 | try { 438 | const is721NFT = await contract.supportsInterface(ERC721_INTERFACE_ID); 439 | if(is721NFT) return true 440 | else return false 441 | } catch { 442 | return false; 443 | } 444 | } 445 | 446 | /** 447 | * 448 | * @param address 449 | * @returns {Promise} 450 | */ 451 | isERC1155NFT = async (address: string): Promise => { 452 | const contract = new ethers.Contract(address, erc1155ABI, this.provider) 453 | 454 | try { 455 | const is1155NFT = await contract.supportsInterface(ERC1155_INTERFACE_ID); 456 | if(is1155NFT) return true 457 | else return false 458 | } catch { 459 | return false; 460 | } 461 | } 462 | 463 | /** 464 | * 465 | * @param address 466 | * @param abi 467 | * @returns {Contract} 468 | */ 469 | getContract = (address: string, abi: Interface | InterfaceAbi): Contract => { 470 | const contract = new ethers.Contract(address, abi, this.provider) 471 | 472 | return contract 473 | } 474 | } 475 | 476 | export default EthereumWallet -------------------------------------------------------------------------------- /src/lib/@emurgo/cardano-message-signing-browser/emurgo_message_signing_bg.wasm.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | export const memory: WebAssembly.Memory; 4 | export function __wbg_protectedheadermap_free(a: number): void; 5 | export function protectedheadermap_to_bytes(a: number, b: number): void; 6 | export function protectedheadermap_from_bytes(a: number, b: number): number; 7 | export function protectedheadermap_new_empty(): number; 8 | export function protectedheadermap_new(a: number): number; 9 | export function protectedheadermap_deserialized_headers(a: number): number; 10 | export function __wbg_label_free(a: number): void; 11 | export function label_to_bytes(a: number, b: number): void; 12 | export function label_from_bytes(a: number, b: number): number; 13 | export function label_new_int(a: number): number; 14 | export function label_new_text(a: number, b: number): number; 15 | export function label_kind(a: number): number; 16 | export function label_as_int(a: number): number; 17 | export function label_as_text(a: number, b: number): void; 18 | export function label_from_algorithm_id(a: number): number; 19 | export function label_from_key_type(a: number): number; 20 | export function label_from_ec_key(a: number): number; 21 | export function label_from_curve_type(a: number): number; 22 | export function label_from_key_operation(a: number): number; 23 | export function __wbg_labels_free(a: number): void; 24 | export function labels_to_bytes(a: number, b: number): void; 25 | export function labels_from_bytes(a: number, b: number): number; 26 | export function labels_get(a: number, b: number): number; 27 | export function labels_add(a: number, b: number): void; 28 | export function __wbg_cosesignatures_free(a: number): void; 29 | export function cosesignatures_to_bytes(a: number, b: number): void; 30 | export function cosesignatures_from_bytes(a: number, b: number): number; 31 | export function cosesignatures_get(a: number, b: number): number; 32 | export function cosesignatures_add(a: number, b: number): void; 33 | export function countersignature_to_bytes(a: number, b: number): void; 34 | export function countersignature_from_bytes(a: number, b: number): number; 35 | export function countersignature_new_single(a: number): number; 36 | export function countersignature_new_multi(a: number): number; 37 | export function countersignature_signatures(a: number): number; 38 | export function __wbg_headermap_free(a: number): void; 39 | export function headermap_to_bytes(a: number, b: number): void; 40 | export function headermap_from_bytes(a: number, b: number): number; 41 | export function headermap_set_algorithm_id(a: number, b: number): void; 42 | export function headermap_algorithm_id(a: number): number; 43 | export function headermap_set_criticality(a: number, b: number): void; 44 | export function headermap_criticality(a: number): number; 45 | export function headermap_set_key_id(a: number, b: number, c: number): void; 46 | export function headermap_key_id(a: number, b: number): void; 47 | export function headermap_set_partial_init_vector(a: number, b: number, c: number): void; 48 | export function headermap_partial_init_vector(a: number, b: number): void; 49 | export function headermap_set_counter_signature(a: number, b: number): void; 50 | export function headermap_counter_signature(a: number): number; 51 | export function headermap_header(a: number, b: number): number; 52 | export function headermap_set_header(a: number, b: number, c: number): void; 53 | export function headermap_keys(a: number): number; 54 | export function headermap_new(): number; 55 | export function __wbg_headers_free(a: number): void; 56 | export function headers_to_bytes(a: number, b: number): void; 57 | export function headers_from_bytes(a: number, b: number): number; 58 | export function headers_protected(a: number): number; 59 | export function headers_unprotected(a: number): number; 60 | export function headers_new(a: number, b: number): number; 61 | export function __wbg_cosesignature_free(a: number): void; 62 | export function cosesignature_to_bytes(a: number, b: number): void; 63 | export function cosesignature_from_bytes(a: number, b: number): number; 64 | export function cosesignature_signature(a: number, b: number): void; 65 | export function cosesignature_new(a: number, b: number, c: number): number; 66 | export function __wbg_cosesign1_free(a: number): void; 67 | export function cosesign1_to_bytes(a: number, b: number): void; 68 | export function cosesign1_from_bytes(a: number, b: number): number; 69 | export function cosesign1_signature(a: number, b: number): void; 70 | export function cosesign1_signed_data(a: number, b: number, c: number, d: number, e: number): number; 71 | export function cosesign1_new(a: number, b: number, c: number, d: number, e: number): number; 72 | export function __wbg_cosesign_free(a: number): void; 73 | export function cosesign_to_bytes(a: number, b: number): void; 74 | export function cosesign_from_bytes(a: number, b: number): number; 75 | export function cosesign_signatures(a: number): number; 76 | export function cosesign_new(a: number, b: number, c: number, d: number): number; 77 | export function __wbg_signedmessage_free(a: number): void; 78 | export function signedmessage_to_bytes(a: number, b: number): void; 79 | export function signedmessage_from_bytes(a: number, b: number): number; 80 | export function signedmessage_new_cose_sign(a: number): number; 81 | export function signedmessage_new_cose_sign1(a: number): number; 82 | export function signedmessage_from_user_facing_encoding(a: number, b: number): number; 83 | export function signedmessage_to_user_facing_encoding(a: number, b: number): void; 84 | export function signedmessage_kind(a: number): number; 85 | export function signedmessage_as_cose_sign(a: number): number; 86 | export function signedmessage_as_cose_sign1(a: number): number; 87 | export function __wbg_sigstructure_free(a: number): void; 88 | export function sigstructure_to_bytes(a: number, b: number): void; 89 | export function sigstructure_from_bytes(a: number, b: number): number; 90 | export function sigstructure_context(a: number): number; 91 | export function sigstructure_body_protected(a: number): number; 92 | export function sigstructure_sign_protected(a: number): number; 93 | export function sigstructure_external_aad(a: number, b: number): void; 94 | export function sigstructure_payload(a: number, b: number): void; 95 | export function sigstructure_set_sign_protected(a: number, b: number): void; 96 | export function sigstructure_new(a: number, b: number, c: number, d: number, e: number, f: number): number; 97 | export function __wbg_coseencrypt0_free(a: number): void; 98 | export function coseencrypt0_to_bytes(a: number, b: number): void; 99 | export function coseencrypt0_from_bytes(a: number, b: number): number; 100 | export function coseencrypt0_headers(a: number): number; 101 | export function coseencrypt0_ciphertext(a: number, b: number): void; 102 | export function coseencrypt0_new(a: number, b: number, c: number): number; 103 | export function __wbg_passwordencryption_free(a: number): void; 104 | export function passwordencryption_to_bytes(a: number, b: number): void; 105 | export function passwordencryption_from_bytes(a: number, b: number): number; 106 | export function passwordencryption_new(a: number): number; 107 | export function __wbg_coserecipients_free(a: number): void; 108 | export function coserecipients_to_bytes(a: number, b: number): void; 109 | export function coserecipients_from_bytes(a: number, b: number): number; 110 | export function coserecipients_new(): number; 111 | export function coserecipients_len(a: number): number; 112 | export function coserecipients_get(a: number, b: number): number; 113 | export function coserecipients_add(a: number, b: number): void; 114 | export function __wbg_coseencrypt_free(a: number): void; 115 | export function coseencrypt_to_bytes(a: number, b: number): void; 116 | export function coseencrypt_from_bytes(a: number, b: number): number; 117 | export function coseencrypt_recipients(a: number): number; 118 | export function coseencrypt_new(a: number, b: number, c: number, d: number): number; 119 | export function coserecipient_to_bytes(a: number, b: number): void; 120 | export function coserecipient_from_bytes(a: number, b: number): number; 121 | export function __wbg_pubkeyencryption_free(a: number): void; 122 | export function pubkeyencryption_to_bytes(a: number, b: number): void; 123 | export function pubkeyencryption_from_bytes(a: number, b: number): number; 124 | export function pubkeyencryption_new(a: number): number; 125 | export function __wbg_cosekey_free(a: number): void; 126 | export function cosekey_to_bytes(a: number, b: number): void; 127 | export function cosekey_from_bytes(a: number, b: number): number; 128 | export function cosekey_set_key_type(a: number, b: number): void; 129 | export function cosekey_key_type(a: number): number; 130 | export function cosekey_set_key_id(a: number, b: number, c: number): void; 131 | export function cosekey_key_id(a: number, b: number): void; 132 | export function cosekey_set_algorithm_id(a: number, b: number): void; 133 | export function cosekey_algorithm_id(a: number): number; 134 | export function cosekey_set_key_ops(a: number, b: number): void; 135 | export function cosekey_key_ops(a: number): number; 136 | export function cosekey_set_base_init_vector(a: number, b: number, c: number): void; 137 | export function cosekey_base_init_vector(a: number, b: number): void; 138 | export function cosekey_header(a: number, b: number): number; 139 | export function cosekey_set_header(a: number, b: number, c: number): void; 140 | export function cosekey_new(a: number): number; 141 | export function labels_len(a: number): number; 142 | export function cosesignatures_len(a: number): number; 143 | export function cosesignature_headers(a: number): number; 144 | export function cosesign_headers(a: number): number; 145 | export function cosesign1_headers(a: number): number; 146 | export function coseencrypt_headers(a: number): number; 147 | export function coserecipient_headers(a: number): number; 148 | export function cosesign_payload(a: number, b: number): void; 149 | export function cosesign1_payload(a: number, b: number): void; 150 | export function coseencrypt_ciphertext(a: number, b: number): void; 151 | export function coserecipient_ciphertext(a: number, b: number): void; 152 | export function headermap_init_vector(a: number, b: number): void; 153 | export function headermap_set_init_vector(a: number, b: number, c: number): void; 154 | export function coserecipient_new(a: number, b: number, c: number): number; 155 | export function headermap_set_content_type(a: number, b: number): void; 156 | export function labels_new(): number; 157 | export function cosesignatures_new(): number; 158 | export function headermap_content_type(a: number): number; 159 | export function __wbg_countersignature_free(a: number): void; 160 | export function __wbg_coserecipient_free(a: number): void; 161 | export function __wbg_taggedcbor_free(a: number): void; 162 | export function taggedcbor_to_bytes(a: number, b: number): void; 163 | export function taggedcbor_from_bytes(a: number, b: number): number; 164 | export function taggedcbor_tag(a: number): number; 165 | export function taggedcbor_value(a: number): number; 166 | export function taggedcbor_new(a: number, b: number): number; 167 | export function __wbg_cborarray_free(a: number): void; 168 | export function cborarray_to_bytes(a: number, b: number): void; 169 | export function cborarray_from_bytes(a: number, b: number): number; 170 | export function cborarray_new(): number; 171 | export function cborarray_len(a: number): number; 172 | export function cborarray_get(a: number, b: number): number; 173 | export function cborarray_add(a: number, b: number): void; 174 | export function cborarray_set_definite_encoding(a: number, b: number): void; 175 | export function cborarray_is_definite(a: number): number; 176 | export function __wbg_cborobject_free(a: number): void; 177 | export function cborobject_to_bytes(a: number, b: number): void; 178 | export function cborobject_from_bytes(a: number, b: number): number; 179 | export function cborobject_new(): number; 180 | export function cborobject_len(a: number): number; 181 | export function cborobject_insert(a: number, b: number, c: number): number; 182 | export function cborobject_get(a: number, b: number): number; 183 | export function cborobject_keys(a: number): number; 184 | export function cborobject_set_definite_encoding(a: number, b: number): void; 185 | export function cborobject_is_definite(a: number): number; 186 | export function __wbg_cborspecial_free(a: number): void; 187 | export function cborspecial_to_bytes(a: number, b: number): void; 188 | export function cborspecial_from_bytes(a: number, b: number): number; 189 | export function cborspecial_new_bool(a: number): number; 190 | export function cborspecial_new_unassigned(a: number): number; 191 | export function cborspecial_new_break(): number; 192 | export function cborspecial_new_null(): number; 193 | export function cborspecial_new_undefined(): number; 194 | export function cborspecial_kind(a: number): number; 195 | export function cborspecial_as_bool(a: number): number; 196 | export function cborspecial_as_float(a: number, b: number): void; 197 | export function cborspecial_as_unassigned(a: number): number; 198 | export function __wbg_cborvalue_free(a: number): void; 199 | export function cborvalue_to_bytes(a: number, b: number): void; 200 | export function cborvalue_from_bytes(a: number, b: number): number; 201 | export function cborvalue_new_int(a: number): number; 202 | export function cborvalue_new_bytes(a: number, b: number): number; 203 | export function cborvalue_new_text(a: number, b: number): number; 204 | export function cborvalue_new_array(a: number): number; 205 | export function cborvalue_new_object(a: number): number; 206 | export function cborvalue_new_tagged(a: number): number; 207 | export function cborvalue_new_special(a: number): number; 208 | export function cborvalue_kind(a: number): number; 209 | export function cborvalue_as_int(a: number): number; 210 | export function cborvalue_as_bytes(a: number, b: number): void; 211 | export function cborvalue_as_text(a: number, b: number): void; 212 | export function cborvalue_as_array(a: number): number; 213 | export function cborvalue_as_object(a: number): number; 214 | export function cborvalue_as_tagged(a: number): number; 215 | export function cborvalue_as_special(a: number): number; 216 | export function __wbg_cosesign1builder_free(a: number): void; 217 | export function cosesign1builder_new(a: number, b: number, c: number, d: number): number; 218 | export function cosesign1builder_hash_payload(a: number): void; 219 | export function cosesign1builder_set_external_aad(a: number, b: number, c: number): void; 220 | export function cosesign1builder_make_data_to_sign(a: number): number; 221 | export function cosesign1builder_build(a: number, b: number, c: number): number; 222 | export function cosesignbuilder_new(a: number, b: number, c: number, d: number): number; 223 | export function cosesignbuilder_make_data_to_sign(a: number): number; 224 | export function cosesignbuilder_build(a: number, b: number): number; 225 | export function __wbg_eddsa25519key_free(a: number): void; 226 | export function eddsa25519key_new(a: number, b: number): number; 227 | export function eddsa25519key_set_private_key(a: number, b: number, c: number): void; 228 | export function eddsa25519key_is_for_signing(a: number): void; 229 | export function eddsa25519key_is_for_verifying(a: number): void; 230 | export function eddsa25519key_build(a: number): number; 231 | export function cosesignbuilder_set_external_aad(a: number, b: number, c: number): void; 232 | export function cosesignbuilder_hash_payload(a: number): void; 233 | export function __wbg_cosesignbuilder_free(a: number): void; 234 | export function __wbg_bignum_free(a: number): void; 235 | export function bignum_to_bytes(a: number, b: number): void; 236 | export function bignum_from_bytes(a: number, b: number): number; 237 | export function bignum_from_str(a: number, b: number): number; 238 | export function bignum_to_str(a: number, b: number): void; 239 | export function bignum_checked_mul(a: number, b: number): number; 240 | export function bignum_checked_add(a: number, b: number): number; 241 | export function bignum_checked_sub(a: number, b: number): number; 242 | export function __wbg_int_free(a: number): void; 243 | export function int_new(a: number): number; 244 | export function int_new_negative(a: number): number; 245 | export function int_new_i32(a: number): number; 246 | export function int_is_positive(a: number): number; 247 | export function int_as_positive(a: number): number; 248 | export function int_as_negative(a: number): number; 249 | export function int_as_i32(a: number, b: number): void; 250 | export function __wbindgen_malloc(a: number): number; 251 | export function __wbindgen_realloc(a: number, b: number, c: number): number; 252 | export function __wbindgen_add_to_stack_pointer(a: number): number; 253 | export function __wbindgen_free(a: number, b: number): void; 254 | --------------------------------------------------------------------------------