diff --git a/.addresses b/.addresses deleted file mode 100644 index 65e337e..0000000 --- a/.addresses +++ /dev/null @@ -1,44 +0,0 @@ -# my wallet -https://bscscan.com/address/0x38d7aA9F656444Ce2F4fC7A0703550E7A15D8b7F -https://app.zerion.io/0x38d7aa9f656444ce2f4fc7a0703550e7a15d8b7f/overview -https://zapper.fi/dashboard - -# @bakeryswap -BakeryRouter: 0xcde540d7eafe93ac5fe6233bee57e1270d3e330f -BakeryFactory: 0x01bf7c66c6bd861915cdaae475042d3c4bae16a7 -DOGGY: 0x74926b3d118a63f6958922d3dc05eb9c6e6e00c6 -BAKE: 0xe02df9e3e622debdd69fb838bb799e3f168902c5 - -# @pancakeswap -PancakeRouter(v2): 0x10ed43c718714eb63d5aa57b78b54704e256024e -PancakeFactory(v2): 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73 - -WBNB: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c -BUSD: 0xe9e7cea3dedca5984780bafc599bd69add087d56 -USDT(BUSD-T): 0x55d398326f99059ff775485246999027b3197955 - -BSCPAD: 0x5a3010d4d8d3b5fb49f8b6e57fb9e48063f16700 -TRONPAD: 0x1bf7aedec439d6bfe38f8f9b20cf3dc99e3571c4 -MOZ: 0xe4b22193d68f18f8e8eb3a26f4d64cb6d4573022 -BOBO: 0x36d2c8be20b02c94936602776893004cee62d5bd -JACKR: 0x32c2bdea6eb916019e37c90650f7914a23beb33b -LQT: 0xbd2c43da85d007b0b3cd856fd55c299578d832bc -INVEST: 0x853A8Ab1c365ea54719EB13A54d6B22F1fBe7FEb -NFTB: 0xde3dbbe30cfa9f437b293294d1fd64b26045c71a -THOREUM: 0x580dE58c1BD593A43DaDcF0A739d504621817c05 - -# @pangolin -PangolinRouter: 0xe54ca86531e17ef3616d22ca28b0d458b6c89106 -PangolinFactory: 0xefa94de7a4656d787667c749f7e1223d71e9fd88 - -WAVAX: 0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7 -PNG: 0x60781c2586d68229fde47564546784ab3faca982 -OSIR: 0x4db1a96ee90a4fb08e0489f55bfaf5f5af294a13 -aSHIB: 0x85df51751cf97292511215f4eb8f75b22caee190 - -# @uniswap - -# @dxsale -PING(sonar): 0x550188f0be51705DCb072D910D3bdd0Aa8929040 -CELON: 0xd91C1CA199c1cb5c73fD0F87c81a3a1E2DFd5948 -NMoon: 0x0d50719a4DDc4F4Bfe661F755c942B100B381df4 diff --git a/.env b/.env deleted file mode 100644 index 8e7ae02..0000000 --- a/.env +++ /dev/null @@ -1,35 +0,0 @@ -DEBUG=0 - -# USDT(BUSD-T): 0x55d398326f99059ff775485246999027b3197955 -# BUSD: 0xe9e7cea3dedca5984780bafc599bd69add087d56 -# WBNB: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c -ADDRESS_FROM="xxx" -ADDRESS_TO="xxx" - -AMOUNT="50" - -# 連続実行用 for multiple buy limit amounts -MULTIPLE_AMOUNT="1" - -# veryhigh - limit: 10000000, price: 100~300gwei (max: 0.01~0.03bnb $3.5~10) -# high - limit: 10000000, price: 50gwei (max: 0.005bnb $1.7) -# mid - limit: 10000000, price: 10gwei (max: 0.001bnb $0.35) -# low - limit: 10000000, price: 5gwei (max: 0.0005bnb $0.17) -# test - limit: 170000, price: 5gwei -TRADE_GAS_LIMIT=10000000 -TRADE_GAS_PRICE="5" - -# high - limit: 500000, price: 50gwei -# mid - limit: 300000, price: 25gwei -# low - limit: 250000, price: 5gwei -APPROVE_GAS_LIMIT=250000 -APPROVE_GAS_PRICE="10" - -SLIPPAGE=90 -DEADLINE_MIN=25 - -# input notification api endpoint (optional) -WEBHOOK_URL="xxx" - -# input your wallet address (required) -PRIVATE_KEY="xxx" diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..cdc6fa2 --- /dev/null +++ b/.env.example @@ -0,0 +1,49 @@ +# .env.example をコピーして .env を作成してください (.env は git 管理外) +# cp .env.example .env +# Bun は実行時にカレントディレクトリの .env を自動で読み込みます。 + +# 利用する DEX プリセット (env/.env を読み込む): pancake | bakery | pangolin +DEX=pancake + +# swap 元トークン (買い: これで払う / 売り: これを受け取る) +# BUSD: 0xe9e7cea3dedca5984780bafc599bd69add087d56 +# USDT(BUSD-T): 0x55d398326f99059ff775485246999027b3197955 +# WBNB: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c +ADDRESS_FROM="" +# swap 先トークン (狙うトークン) +ADDRESS_TO="" + +# 1 回の購入で使う ADDRESS_FROM の数量 (小数可) +AMOUNT="50" +# buy:multiple で 1 回あたりに使う数量 (購入上限があるトークン向け) +MULTIPLE_AMOUNT="1" + +# 取引期限 (分) +DEADLINE_MIN=25 + +# 売買のガス設定 (price は gwei) +# veryhigh: limit 10000000 / price 100~300 +# high: limit 10000000 / price 50 +# mid: limit 10000000 / price 10 +# low: limit 10000000 / price 5 +# test: limit 170000 / price 5 +TRADE_GAS_LIMIT=10000000 +TRADE_GAS_PRICE="5" + +# approve のガス設定 (price は gwei) +# high: 500000 / 50, mid: 300000 / 25, low: 250000 / 5 +APPROVE_GAS_LIMIT=250000 +APPROVE_GAS_PRICE="10" + +# subscribe:pair-created で検出したいシンボル (カンマ区切り, 正規表現可) +WATCH_SYMBOLS="" + +# 約定通知用の Slack 互換 Webhook (任意) +WEBHOOK_URL="" + +# 1 にするとトランザクションを送信せず内容だけ表示する +DRY_RUN=0 + +# ウォレットの秘密鍵 (必須) +# ⚠️ bot 専用の新規ウォレットを使い、必要最小限の資金だけ入れてください +PRIVATE_KEY="" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a317e02 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,17 @@ +version: 2 +updates: + - package-ecosystem: bun + directory: / + schedule: + interval: weekly + # 公開直後のバージョンは提案しない (乗っ取り版が削除されるまでの猶予) + cooldown: + default-days: 7 + open-pull-requests-limit: 5 + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7401eca --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + +permissions: + contents: read + +jobs: + check: + runs-on: ubuntu-latest + steps: + # サードパーティ Action もサプライチェーンの一部なので、タグではなくコミット SHA で固定することを推奨 + # (Dependabot / Renovate で SHA の更新 PR を受け取れる) + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + # lockfile どおりに入れる。lifecycle script は Bun の既定で実行されない + - run: bun ci + + - name: Audit dependencies + run: bun audit + + - name: Typecheck + run: bun run typecheck + + - name: Bundle check (import / syntax errors) + run: bun build src/commands/**/*.ts --target=bun --outdir=/tmp/bun-build-check diff --git a/.gitignore b/.gitignore index 895873f..227774e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,12 @@ node_modules .history +.DS_Store + +# secrets +.env +.env.* +!.env.example +env/*.local.env + +# survey outputs (contains wallet addresses) +data/survey/outputs/ diff --git a/.node-version b/.node-version deleted file mode 100644 index 75fca90..0000000 --- a/.node-version +++ /dev/null @@ -1,2 +0,0 @@ -14.9.0 - diff --git a/README.md b/README.md index 92b8cad..e588d4f 100644 --- a/README.md +++ b/README.md @@ -1,171 +1,159 @@ -DeFi用のトレーディングbotです。 -流動性追加のタイミングで素早くトークンを購入できます。 +# defi_sniper -下記の機能があります↓ -- ハニーポット対策に事前に少額での売買が可能か検証 -- 購入上限額があるトークン対策として直前に成功したトランザクションの内容をコピーして連続で購入 (限度額設定も可能) -- pancake(BSC), pangolin(AVAX C-Chain)などに対応 (仕組みは大体同じため取引所などのアドレスを変えれば流用可能) -- BitQueryのAPIを叩いて特定walletのトランザクションを追跡 +[![CI](https://github.com/tkc310/defi_sniper/actions/workflows/ci.yml/badge.svg)](https://github.com/tkc310/defi_sniper/actions/workflows/ci.yml) +![Bun](https://img.shields.io/badge/runtime-Bun%20%E2%89%A5%201.3-f9f1e1?logo=bun&logoColor=black) +![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white) +![ethers](https://img.shields.io/badge/ethers-v6%20(pinned)-2535a0) +![runtime deps](https://img.shields.io/badge/runtime%20deps-1-brightgreen) +![chains](https://img.shields.io/badge/chains-BSC%20%7C%20Avalanche-f0b90b) + +Uniswap V2 互換 DEX 向けのトレーディング bot です。流動性追加のタイミングで素早くトークンを購入できます。 +Node.js / npm / tsc のセットアップは不要で、**Bun だけで動きます**。 + +> [!WARNING] +> 利用しなくなったため公開しているコードです。現在も優位性があるかは分かりません。**利用は自己責任**でお願いします。 +> 無償公開のため、利用方法に関する問い合わせは受け付けていません。 + +## 機能 + +- **スナイプ** — `PairCreated` / `Mint` を検知した瞬間に購入 +- **購入上限トークン対策** — 直前に成功した他人の Swap をコピーして同じ数量を注文 (`snipe:swap-trace`) / 少額ずつ連続購入 (`buy:multiple`) +- **ハニーポット対策** — 少額で売買できるか事前に確認する運用を想定 (`buy` → `approve:sell` → `sell`) +- **マルチチェーン** — PancakeSwap / BakerySwap (BSC)、Pangolin (Avalanche C-Chain)。Router / Factory のアドレスを変えれば他の V2 フォークにも流用可 +- **調査** — BitQuery API で初動購入ウォレットを追跡 -利用しなくなったため草を生やす目的でコードを公開します。 -以前使っていましたが現在も優位性があるかは分かりませんので、利用は自己責任でお願いします。 -また、無償で公開しているためツールの利用方法に関する問い合わせは受け付けていません。 +## セットアップ ---- - -This is a trading bot for DeFi. -You can quickly buy tokens when liquidity is added. - -The following functions are available↓ -- Verify whether it is possible to buy and sell small amounts in advance for honeypot measures -- Purchase of tokens with a purchase limit by copying the contents of the last successful transaction (limits can also be set) -- Support for pancake(BSC), pangolin(AVAX C-Chain), etc. (The mechanism is almost the same, so it can be used by changing the address of other exchanges, etc.) - Track specific wallet transactions by hitting BitQuery's API - -I am publishing the code for the purpose of growing grass since I no longer use it. -I used to use this tool, but I am not sure if it is still superior, so please use it at your own risk. -Also, I do not accept inquiries about how to use the tool because I am releasing it for free. - -## Environments - -- Node.js: 14.9.0 -- npm: 6.14.8 - -We have only tested this on macOS 10.14.6 (mojave), but it should work fine on any environment that can run the above version of Node.js. - -## Setup - -### 1. install node.js +```sh +# 1. Bun をインストール (https://bun.com) +curl -fsSL https://bun.com/install | bash -``` -$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -$ brew install nodenv -$ nodenv init -$ echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile -$ echo 'eval "$(nodenv init -)"' >> ~/.bash_profile -$ source ~/.bash_profile -$ nodenv install 14.9.0 +# 2. 依存をインストール (bun.lock どおりに入る。下記「セキュリティ」参照) +bun install +# ※ bun.lock がまだ無い場合のみ、初回だけ以下で生成してコミットする +# bun install --no-frozen-lockfile && git add bun.lock + +# 3. 設定ファイルを作成して編集 +cp .env.example .env ``` -### 2. npm install +`.env` の主な項目 (全項目は [`.env.example`](.env.example) を参照): -``` -$ npm install -``` +| 変数 | 説明 | +| --- | --- | +| `DEX` | `pancake` \| `bakery` \| `pangolin`。`env/.env` のプリセットを読み込む | +| `ADDRESS_FROM` | 支払いに使うトークン (例: BUSD, WBNB) | +| `ADDRESS_TO` | 購入したいトークン | +| `AMOUNT` | 1 回の購入で使う `ADDRESS_FROM` の数量 | +| `TRADE_GAS_LIMIT` / `TRADE_GAS_PRICE` | 売買のガス (price は gwei) | +| `PRIVATE_KEY` | bot 用ウォレットの秘密鍵 | +| `WS_RPC_URL` | 設定すると WebSocket で購読し、検知が速くなる (API キー入り URL はここに書く) | +| `DRY_RUN` | `1` でトランザクションを送信せず内容だけ表示 | -### 3. setting secret variables +Router / Factory / RPC などのチェーン固有の値は [`env/`](env) のプリセットにあります。各種アドレスは [`docs/addresses.md`](docs/addresses.md) にまとめています。 -``` -$ touch .env -$ vi .env (edit the .env) -``` +## 使い方 -```.env -# address of the token to be swapped (selling goes the other way) -# address of the swap source (ex. BUSD) -ADDRESS_FROM="0xe9e7cea3dedca5984780bafc599bd69add087d56" -# address of swap to -ADDRESS_TO="0x08037036451c768465369431da5c671ad9b37dbc" - -# advanced settings for ordering -AMOUNT=100 -SLIPPAGE=90 -DEADLINE_MIN=5 -TRADE_GAS_LIMIT=500000 -TRADE_GAS_PRICE=50 -APPROVE_GAS_LIMIT=300000 -APPROVE_GAS_PRICE=25 - -# private key of your wallet address -PRIVATE_KEY="" -# slack, discord, line etc webhook url (option) -WEBHOOK_URL="" -# for debugging (fixed to 0) -DEBUG=0 -``` +| コマンド | 内容 | +| --- | --- | +| `bun run snipe:pair-created` | **基本はこれ。** 対象トークンの `PairCreated` を検知したら購入 | +| `bun run snipe:mint` | 既存ペアへの流動性追加 (`Mint`) で購入。BSCPAD 等のローンチパッド IDO や、`PairCreated` が出ない BakerySwap 向け | +| `bun run snipe:swap-trace` | 最初の他人の Swap を見て、購入上限があればその数量で exactOut 注文 | +| `bun run buy` | 任意のタイミングで `AMOUNT` 分購入 | +| `bun run buy:multiple` | `MULTIPLE_AMOUNT` ずつ指定回数購入 | +| `bun run sell` | 保有量の指定 % を売却 (`bun run sell --fee-on-transfer` でデフレトークン用メソッド) | +| `bun run approve:buy` | 購入に使う `ADDRESS_FROM` を Router に approve (DEX ごとに初回のみ) | +| `bun run approve:sell` | 購入した `ADDRESS_TO` を Router に approve (売却前に必要) | +| `bun run subscribe:pair-created` | `PairCreated` を表示するだけ。`WATCH_SYMBOLS` で未公開トークンを捜索 | +| `bun run subscribe:mint` / `subscribe:swap` | 対象ペアのイベントを表示するだけ | +| `bun run survey:tx` | BitQuery で初動購入ウォレットを取得し `data/survey/outputs/` に保存 | +| `bun run survey:find-wallets` | 上記出力を突き合わせ、複数トークンで初動購入しているウォレットを抽出 | +| `bun run survey:wallet-tx` | `data/survey/targets.json` のウォレットが公開前にトークンを受け取った回数を集計 | -## Usage (editing) +単発で DEX を切り替える場合は `DEX=pangolin bun run buy` のように環境変数で上書きできます。 +survey 系は `.env` に `BITQUERY_API_KEY` を、`env/survey.env` に対象を設定してください (BitQuery v1 GraphQL API を使用しているため、現在も使えるかは未確認です)。 -Use different bots for different purposes. +## 基本的な流れ -### snipe +1. フェアローンチ予定のトークンのコントラクトアドレスを事前に調べる +2. `https://poocoin.app/tokens/
` などでチャートを開いておく +3. `.env` の `ADDRESS_TO` に設定する +4. その DEX で初めて買う場合は `bun run approve:buy` +5. ローンチ予定の 5〜10 分前に `bun run snipe:pair-created` を起動して待機 +6. 購入できたら `bun run approve:sell` +7. 任意のタイミングで `bun run sell` (多くの bot が 5 分過ぎに動くため、3〜4 分後が良いことが多かった) -This is used when you want to trigger a purchase for additional liquidity. -Basically, use `snipe/buyPairCreated.js`. +## セキュリティ -``` -$ node snipe/buyPairCreated.js -``` +### 秘密鍵 -For IDO via launchpad agents such as BSCPAD, use `snipe/buyMint.js`. -barkeyswap also uses `snipe/buyMint.js` since the `PairCreated` event may not be issued. +- **bot 専用の新規ウォレット**を作り、必要最小限の資金だけ入れてください。メインウォレットの鍵は絶対に使わないでください +- `approve` は速度優先で無制限 (MaxUint256) 許可を行います。使い終わったら [revoke.cash](https://revoke.cash) などで取り消せます +- `.env` は `.gitignore` 済みです。RPC プロバイダの API キーも `env/*.env` ではなく `.env` に書いてください -``` -$ node snipe/buyMint.js -``` +### サプライチェーン攻撃への対策 -### manual +暗号資産を扱うパッケージは、秘密鍵やウォレットを盗む目的のサプライチェーン攻撃の主要な標的になっています。 -Use this option when you want to place an order at an arbitrary time. -Buy allows you to set the amount, while sell sells all the tokens you own. -Note that approve is required before placing a sell order. +- 2024 年 12 月、公式の `@solana/web3.js` が乗っ取られ、秘密鍵を外部へ送信するバックドア入りのバージョンが数時間公開されました ([The Hacker News](https://thehackernews.com/2024/12/researchers-uncover-backdoor-in-solanas.html), [The Register](https://www.theregister.com/2024/12/05/solana_javascript_sdk_compromised/)) +- 2025 年 3 月、`ethers-provider2` などの悪性パッケージが、ローカルにインストール済みの正規の `ethers` のファイルを書き換えてリバースシェルを仕込む手口が報告されました。悪性パッケージを消しても改ざんされた `ethers` は残ります ([The Hacker News](https://thehackernews.com/2025/03/malicious-npm-package-modifies-local.html), [ReversingLabs](https://reversinglabs.com/blog/malicious-npm-patch-delivers-reverse-shell)) +- 2025 年 9 月、`chalk` や `debug` など週 20 億 DL 規模の定番パッケージがメンテナのフィッシング被害で乗っ取られ、ブラウザ上の暗号資産の送金先を書き換えるコードが混入しました ([The Hacker News](https://thehackernews.com/2025/09/20-popular-npm-packages-with-2-billion.html)) +- 同月以降、npm トークンや認証情報を盗んで自己増殖するワーム「Shai-Hulud」が数百パッケージに広がり、11 月には第 2 波も確認されています ([Infosecurity Magazine](https://www.infosecurity-magazine.com/news/supply-chain-worm-hundreds-npm/), [InfoWorld](https://www.infoworld.com/article/4095604/new-shai-hulud-worm-spreading-through-npm-github-2.html)) -``` -$ node manual/buy.js -``` +このリポジトリでは以下の対策をしています。 -``` -$ node manual/sell.js -``` - -``` -$ node manual/buyApprove.js -``` +| 対策 | 内容 | +| --- | --- | +| 依存の最小化 | 旧版の `web3` / `node-fetch` / `dotenv` / `@pancakeswap-libs/sdk` を削除し、実行時依存は `ethers` のみ。`fetch` / `.env` 読込 / 入力プロンプトは Bun 組み込み機能で代替 | +| バージョン完全固定 | `package.json` は `^` なしで固定、`bunfig.toml` の `exact = true` で今後の `bun add` も固定 | +| lockfile 固定 | `bunfig.toml` の `frozenLockfile = true` と CI の `bun ci` で、`bun.lock` と異なるバージョンは入らない | +| 公開直後のバージョンを拒否 | `minimumReleaseAge` で公開から 7 日未満のバージョンをインストールしない。乗っ取り版は多くが数時間〜数日で削除されるため、その期間を避ける | +| install script を実行しない | Bun は既定で依存パッケージの lifecycle script (postinstall 等) を実行しない。`trustedDependencies` は空のまま維持する | +| 継続監視 | CI で `bun audit`、Dependabot も 7 日のクールダウン付きで更新 PR を作成 | -``` -$ node manual/sellApprove.js -``` +運用時の注意: -### subscribe +- **タイポスクワッティングに注意** — `ethers-provider2` のような「それっぽい名前」のパッケージを追加しない。追加前に npm のページで公開者・DL 数・リポジトリを確認する +- **`trustedDependencies` に追加しない** — install script が必要なパッケージは本プロジェクトには不要です +- **更新は差分を見てから** — 依存を上げるときは `bun outdated` で確認し、リリースノートと `bun.lock` の差分をレビューする。急ぎでなければクールダウン期間を待つ +- **鍵を持つマシンを分ける** — 可能なら bot の実行環境は開発用マシンと分け、秘密鍵を置くマシンで不要なパッケージをインストールしない -This is used when you want to detect only the addition of liquidity without placing an order. -Assumed to be used for researching new markets (DEX) and launchpad projects. +参考: [Bun — bun install (minimumReleaseAge / trustedDependencies / frozenLockfile)](https://bun.com/docs/pm/cli/install) -``` -$ node subscribe/pairCreated.js -``` +## ディレクトリ構成 ``` -$ node subscribe/mint.js +src/ + commands/ + snipe/ # イベント検知 → 自動購入 + manual/ # 手動売買・approve + subscribe/ # イベント監視のみ + survey/ # BitQuery によるウォレット調査 + lib/ # 設定読込・コントラクト・swap などの共通処理 +env/ # DEX ごとのプリセット (Router / Factory / RPC) +data/survey/ # survey の入力 (targets.json) と出力 (outputs/, git 管理外) +docs/ # アドレスメモ ``` -## Basic flow - -1. Research the contract address of the token to be fair-launched in advance. -2. Prepare poocoin and other charts using the addresses you have researched. - https://poocoin.app/tokens/
-3. Enter the contract address in the .env file -4. Start the Snipe bot 5~10 minutes before the scheduled launch and wait. +## 開発 -You need to approve the token for purchase for the first time in the relevant DEX. - -``` -$ node manual/buyApprove.js -``` - -``` -$ node snipe/buyPairCreated.js +```sh +bun run typecheck # tsc --noEmit +bun run deps:check # bun audit && bun outdated ``` -5. If you succeed in purchasing it, APPROVE it. +--- -``` -$ node manual/sellApprove.js -``` +## English -6. Sell at any time (Mostly, 3~4 minutes is optimal) +A sniping / trading bot for Uniswap V2 compatible DEXes (PancakeSwap, BakerySwap, Pangolin). It buys a token right when liquidity is added. Runs on **Bun only** — no Node.js, npm or tsc setup required. +```sh +bun install +cp .env.example .env # edit it +bun run snipe:pair-created ``` -$ node manual/sell.js -``` -Because many bots are triggered a little over 5 minutes ago. +See the command table above for all scripts. This code is published as-is since I no longer use it; use it at your own risk. No support is provided. + +The only runtime dependency is `ethers` (exact-pinned). Installs are locked to `bun.lock`, versions younger than 7 days are rejected (`minimumReleaseAge`), and dependency lifecycle scripts are never run — see the Security section above for the supply-chain incidents that motivated this. diff --git a/buckup/backup.js b/buckup/backup.js deleted file mode 100644 index 03e56d7..0000000 --- a/buckup/backup.js +++ /dev/null @@ -1,202 +0,0 @@ -const ethers = require('ethers'); - - - - -// ------------------------------------------------------------------------------------- -// ----------- VARIABLES --------------------------------------------------------------- -// ------------------------------------------------------------------------------------- - -const address_of_Input_Token = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56"; // Contract Address of Token with which you will buy (ex. BUSD) -const address_of_Output_Token = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; // Contract Address of the token you want to snipe -const amount_to_be_used_to_buy = "1"; // Amount of the Input Token (1 WBNB) -const slippage_percent = "16"; // Slippage in percents -const pancake_router_address = "0x10ed43c718714eb63d5aa57b78b54704e256024e"; // Pancake Router Address: v2: 0x10ed43c718714eb63d5aa57b78b54704e256024e v1: 0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F -const pancake_factory_address = '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73'; // Pancake Factory Address -const privateKey = "private-key"; // Private Key of Sender/Receiver Address - - - -const {ChainId, Token, TokenAmount, Fetcher, Pair, Route, Trade, TradeType, Percent} = -require('@pancakeswap-libs/sdk'); -const Web3 = require('web3'); -const {JsonRpcProvider} = require("@ethersproject/providers"); -require("dotenv").config(); -const provider = new JsonRpcProvider('https://bsc-dataseed1.binance.org/'); -const web3 = new Web3('ANKR API WEBSOCKET LINK'); -const { address: admin } = web3.eth.accounts.wallet.add(privateKey); -console.log(`--------- Modules Loaded --------`); - -// CL-I - -const InputTokenAddr = web3.utils.toChecksumAddress(address_of_Input_Token); -const OutputTokenAddr = web3.utils.toChecksumAddress(address_of_Output_Token); -const InputTokenAmount = amount_to_be_used_to_buy; -const Slipage = slippage_percent; -const PANCAKE_ROUTER = pancake_router_address; -const ONE_ETH_IN_WEI = web3.utils.toBN(web3.utils.toWei('1')); -const tradeAmount = ONE_ETH_IN_WEI.div(web3.utils.toBN('1000')); - -const wallet = new ethers.Wallet(privateKey); - -const signer = wallet.connect(provider); -console.log(`--------- CL-I Loaded --------`); -const factory = new ethers.Contract( - pancake_factory_address, - ['event PairCreated(address indexed token0, address indexed token1, address pair, uint)'], - signer - ); - -var detected_and_bought = "0"; - -factory.on('PairCreated', async (token0, token1, pairAddress) => { - if (detected_and_bought == "0"){ - console.log(`------------------------------------------------------------`); - console.log(` - New pair detected - Scanning for Token - ================= - Token 1 Address : ${token0} - Token 2 Address: ${token1} - `); - - // Check if the new pair is the one looked for - let tokenIn, tokenOut; - if(token0 == OutputTokenAddr && token1 == InputTokenAddr) { - console.log(`Only first token of Pair is the token expected`); - tokenIn = token1; - tokenOut = token0; - detected_and_bought = "1"; - } - - else if(token1 == OutputTokenAddr && token0 == InputTokenAddr) { - console.log(`Only second token of Pair is the token expected`); - tokenIn = token0; - tokenOut = token1; - detected_and_bought = "1"; - } - - //The quote currency is not WBNB - else if(typeof tokenIn === 'undefined') { - console.log(`No token of the pair is the token expected`); - console.log(`------------------------------------------------------------`); - return; - } - - - await Swap(tokenIn, tokenOut); - } - else if (detected_and_bought == "1") { - await Swap(InputTokenAddr, OutputTokenAddr); - } else if (detected_and_bought == "2") { - console.log("Your Token was bought!"); - process.exit(1); - } - - - -}) - - -const Swap = async (tokenIn, tokenOut) => { - const [INPUT_TOKEN, OUTPUT_TOKEN] = await Promise.all( - [tokenIn, tokenOut].map(tokenAddress => ( - new Token( - ChainId.MAINNET, - tokenAddress, - 18 - ) - ))); - - const ONE_ETH_IN_WEI = web3.utils.toBN(web3.utils.toWei('1'));//BN->(BIG NUMBER) || toWei -> Converts any ether value value into wei. - const tradeAmount = ONE_ETH_IN_WEI.div(web3.utils.toBN('100'));//tradeAmount = ONE_ETH_IN_WEI/1000 - - const pair = await Fetcher.fetchPairData(INPUT_TOKEN, OUTPUT_TOKEN, provider); - - const route = await new Route([pair], INPUT_TOKEN); - - const trade = await new Trade(route, new TokenAmount(INPUT_TOKEN, tradeAmount), TradeType.EXACT_INPUT); - - const slippageTolerance = new Percent(Slipage, '100'); // - - - const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw; - - const path = [INPUT_TOKEN.address, OUTPUT_TOKEN.address]; - - const to = admin; - - const deadline = Math.floor(Date.now() / 1000) + 60 * 20; - console.log("Connecting to Pancakeswap......"); - // Create Pancakeswap ethers Contract - const pancakeswap = new ethers.Contract( - - PANCAKE_ROUTER, - - ['function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'], - - signer - - ); - console.log("<<<<<------- Connected to Pancakeswap -------->>>>>"); - - - //Allow input token - - if(true) - - { - - console.log(`Approving on Pancakeswap......`); - - let abi = ["function approve(address _spender, uint256 _value) public returns (bool success)"]; - console.log(`...`); - let contract = new ethers.Contract(INPUT_TOKEN.address, abi, signer); - console.log(`...`); - let aproveResponse = await contract.approve(PANCAKE_ROUTER, ethers.utils.parseUnits('1000.0', 18), {gasLimit: 100000, gasPrice: 5e9}); - console.log(`...`); - - console.log(`<<<<<------- Approved on Pancakeswap -------->>>>>`); - } - - if(true) - - { - - console.log(`Creating Transaction`); - - var amountInParam = ethers.utils.parseUnits(InputTokenAmount, 18); - - var amountOutMinParam = ethers.utils.parseUnits(web3.utils.fromWei(amountOutMin.toString()), 18); - - - - const tx = await pancakeswap.swapExactTokensForTokens( - - amountInParam, - - amountOutMinParam, - - path, - - to, - - deadline, - - { gasLimit: ethers.utils.hexlify(300000), gasPrice: ethers.utils.parseUnits("9", "gwei") } - - ); - - console.log(`Tx-hash: ${tx.hash}`) - - const receipt = await tx.wait(); - detected_and_bought = "2"; - console.log(`Tx was mined in block: ${receipt.blockNumber}`); - process.exit(1) - } - - } - - process.on('unhandledRejection', (error, promise) => { - console.log('-------------------------------- Rejected, review your BNB balance for fees or contact bot-support, retrying... -------------------'); - }); - diff --git a/buckup/backup2.js b/buckup/backup2.js deleted file mode 100644 index 59c8658..0000000 --- a/buckup/backup2.js +++ /dev/null @@ -1,118 +0,0 @@ -require("dotenv").config(); -const { - ADDRESS_FROM, - ADDRESS_TO, - ADDRESS_FACTORY, - AMOUNT, - PRIVATE_KEY, - WS_RPC_URL, -} = process.env; -const ethers = require('ethers'); -const Web3 = require('web3'); -const swap = require("./lib/swap"); - -const exec = async () => { - const web3 = new Web3(WS_RPC_URL); - const provider = new ethers.providers.WebSocketProvider(WS_RPC_URL); - const wallet = new ethers.Wallet(PRIVATE_KEY); - const signature = wallet.connect(provider); - const { address: walletAddress } = web3.eth.accounts.wallet.add(PRIVATE_KEY); - - const tokenAddressFrom = web3.utils.toChecksumAddress(ADDRESS_FROM); - const tokenAddressTo = web3.utils.toChecksumAddress(ADDRESS_TO); - const amountIn = ethers.utils.parseUnits(AMOUNT, 18); - - const factory = new ethers.Contract( - ADDRESS_FACTORY, - ['event PairCreated(address indexed token0, address indexed token1, address pair, uint)'], - signature - ); - const contract = new ethers.Contract( - tokenAddressFrom, - [ - 'function approve(address spender, uint256 amount) external returns (bool)', - 'function balanceOf(address tokenOwner) public view returns (uint balance)', - ], - signature - ); - - // waiting, created, completed - let boughtStatus = "waiting"; - - console.log('Start subscribe pair create...'); - factory.on('PairCreated', async (token0, token1, pairAddress) => { - switch (boughtStatus) { - case "waiting": - console.log(` - ------------------------------------------------------------ - New pair detected - Scanning for Token - ================= - Token 1 Address : ${token0} - Token 2 Address: ${token1} - PairAddress: ${pairAddress} - `); - - // Check if the new pair is the one looked for - let tokenFrom, tokenTo; - if (token0 === tokenAddressTo && token1 === tokenAddressFrom) { - console.log(`Only first token of Pair is the token expected`); - tokenFrom = token1; - tokenTo = token0; - boughtStatus = "created"; - } - - else if (token1 === tokenAddressTo && token0 === tokenAddressFrom) { - console.log(`Only second token of Pair is the token expected`); - tokenFrom = token0; - tokenTo = token1; - boughtStatus = "created"; - } - - //The quote currency is not WBNB - else if (typeof tokenFrom === 'undefined') { - console.log(` - No token of the pair is the token expected - ------------------------------------------------------------ - `); - - // loop out - return; - } - - await approve(contract, amountIn); - await swap({ - tokenFrom, - tokenTo, - amountIn, - walletAddress, - signature - }); - boughtStatus = "completed"; - process.exit(1); - case "created": - await approve(contract, amountIn); - await swap({ - tokenFrom: tokenAddressFrom, - tokenTo: tokenAddressTo, - amountIn, - walletAddress, - signature - }); - boughtStatus = "completed"; - process.exit(1); - case "completed": - console.log("Your Token was bought!"); - process.exit(1); - } - }); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..d7c183a --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,12 @@ +# サプライチェーン攻撃対策の設定 (詳細は README の「セキュリティ」節) +[install] +# bun.lock と package.json の不一致を許さない (勝手にバージョンが動かない) +frozenLockfile = true + +# 公開から 7 日経っていないバージョンはインストールしない。 +# 乗っ取られたメンテナアカウントから公開された悪性バージョンは +# 多くが数時間〜数日で検知・削除されるため、その期間を避ける。 +minimumReleaseAge = 604800 # seconds (7 days) + +# `bun add` 時に ^ を付けず完全固定で package.json に書き込む +exact = true diff --git a/constants/abi.js b/constants/abi.js deleted file mode 100644 index 0e1d862..0000000 --- a/constants/abi.js +++ /dev/null @@ -1,17 +0,0 @@ -exports.FACTORY = [ - 'event PairCreated(address indexed token0, address indexed token1, address pair, uint)', - 'function getPair(address tokenA, address tokenB) external view returns (address pair)', -]; - -exports.ROUTER = [ - 'function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)', - 'function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)', - 'function swapTokensForExactTokens(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)', - 'function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external', -]; - -exports.PARE = [ - 'event Mint(address indexed sender, uint amount0, uint amount1)', - 'event Swap(address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to)', - 'function symbol() external pure returns (string memory)', -]; diff --git a/data/survey/targets.json b/data/survey/targets.json new file mode 100644 index 0000000..ef83037 --- /dev/null +++ b/data/survey/targets.json @@ -0,0 +1,22 @@ +{ + "wallets": [ + "0x9e395036f4e718a9e96bbcb00a8f52a291d14403" + ], + "tokens": [ + { "address": "0x54d35d08f9b57c822f6705c3efda9f6d75b2bc85", "published": "2021-06-15 19:00:00" }, + { "address": "0xe77fb3251034d373af1823f7c6a0ea60ba548513", "published": "2021-06-15 13:00:00" }, + { "address": "0xa2b3358bd06a0f6e5c4ca9cd9a5e28b0958e1b7c", "published": "2021-06-14 20:00:00" }, + { "address": "0xed58bf7357352ca270e4879cea7050b1d9b2e09d", "published": "2021-06-14 13:00:00" }, + { "address": "0x7b49f40fcbedea840c443c78153c3b9af9a52d1d", "published": "2021-06-13 16:00:00" }, + { "address": "0xb73dcbe3ca246df608ecf456307dbe7accb91cde", "published": "2021-06-12 19:00:00" }, + { "address": "0x0da2e6ca58a6446cb9a82eaa064abb944462355e", "published": "2021-06-11 19:00:00" }, + { "address": "0x69cf9714a95576adaa52ebef2b14a6b92b024835", "published": "2021-06-11 13:00:00" }, + { "address": "0x97246af443dcc6fc6358407c203805ab57944708", "published": "2021-06-11 13:00:00" }, + { "address": "0x97246af443dcc6fc6358407c203805ab57944708", "published": "2021-06-09 19:00:00" }, + { "address": "0x7b49F40FcbEdEa840C443C78153c3B9Af9a52d1D", "published": "2021-06-08 19:00:00" }, + { "address": "0xd7ad445ef192e037ed37f7b743dec68f2a11e463", "published": "2021-06-08 14:00:00" }, + { "address": "0x88E6FC8A5f9933A136b7DB63b4Ae555152487562", "published": "2021-06-07 19:30:00" }, + { "address": "0xf313e2114ef908922913bf2efcf47d61b83e9e51", "published": "2021-06-07 19:00:00" }, + { "address": "0x7faebfc975ef277d29c75feadff6dab03e0fa09f", "published": "2021-06-07 14:00:00" } + ] +} diff --git a/debug/1.js b/debug/1.js deleted file mode 100644 index efb2b0b..0000000 --- a/debug/1.js +++ /dev/null @@ -1,13 +0,0 @@ -const { Worker } = require('worker_threads'); -const readUserInput = require('../lib/readUserInput'); - -const exec = async () => { - const execCount = await readUserInput('Input to exec count: '); - - [...Array(execCount)].forEach(() => { - // 並列実行 - const worker = new Worker('./debug/4.js'); - }); -}; - -exec(); diff --git a/debug/2.js b/debug/2.js deleted file mode 100644 index a291b7e..0000000 --- a/debug/2.js +++ /dev/null @@ -1,125 +0,0 @@ -require("dotenv").config(); -const { - ChainId, Token, TokenAmount, Fetcher, Pair, Route, Trade, TradeType, Percent -} = require('@pancakeswap-libs/sdk'); -const ethers = require('ethers'); -const fetch = require("node-fetch"); - -const { - AMOUNT, - SLIPPAGE, - DEADLINE_MIN, - PRIVATE_KEY, - ADDRESS_ROUTER -} = process.env; - -module.exports = async (args) => { - const { - tokenFrom, - tokenTo, - amountIn, - walletAddress, - signature, - web3, - provider - } = args; - - const [INPUT_TOKEN, OUTPUT_TOKEN] = await Promise.all( - [tokenFrom, tokenTo].map(tokenAddress => ( - new Token(ChainId.MAINNET, tokenAddress, 18) - ))); - - console.log({ - INPUT_TOKEN, - OUTPUT_TOKEN, - amountIn - }); - - const router = new ethers.Contract( - ADDRESS_ROUTER, - [ - 'function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)', - 'function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)' - ], - signature - ); - - // const ONE_ETH_IN_WEI = web3.utils.toBN(web3.utils.toWei('1'));//BN->(BIG NUMBER) || toWei -> Converts any ether value value into wei. - // const tradeAmount = ONE_ETH_IN_WEI.div(web3.utils.toBN('100'));//tradeAmount = ONE_ETH_IN_WEI/1000 - // const pair = await Fetcher.fetchPairData(INPUT_TOKEN, OUTPUT_TOKEN, provider); - // const route = await new Route([pair], INPUT_TOKEN); - // const trade = await new Trade(route, new TokenAmount(INPUT_TOKEN, tradeAmount), TradeType.EXACT_INPUT); - // const slippageTolerance = new Percent(Slipage, '100'); - // const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw; - // const amountOutMin = ethers.utils.parseUnits(web3.utils.fromWei(amountOutMin.toString()), 18); - // const amounts = await router.getAmountsOut(amountIn, [tokenFrom, tokenTo]); - // const slippage = SLIPPAGE / 10; - // const amountOutMin = amounts[1].div(slippage); - const amountOutMin = ethers.utils.parseUnits("100", 18); - const deadline = Math.floor(Date.now() / 1000) + 60 * DEADLINE_MIN; - - const contract = new ethers.Contract( - tokenFrom, - [ - "function name() view returns (string)", - "function symbol() view returns (string)", - 'function approve(address _spender, uint256 _value) public returns (bool success)', - 'function balanceOf(address) public view returns (uint)', - 'function _maxTxAmount() public view returns (uint256)', - ], - signature - ); - - const divNumber = await readUserInput("Input to sell division number (1 to 100%, 2 to 50%): "); - const balance = await contract.balanceOf(walletAddress); - const divedBalance = balance.div(divNumber); - const name = await contract.name(); - const symbol = await contract.symbol(); - - console.log({ - amountIn_int: parseInt(amountIn._hex, 16), - amountIn, - amountOutMin: parseInt(amountOutMin._hex, 16), - amounts: { - busd: parseInt(amounts[0]._hex, 16), - usdt: parseInt(amounts[1]._hex, 16), - }, - deadline, - // gasPrice, - tokenFrom, - tokenTo, - balance_int: parseInt(balance._hex, 16), - balance, - divedBalance, - walletAddress, - name, - symbol, - }); -}; - -async function readUserInput(question) { - const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout - }); - - return new Promise((resolve, reject) => { - readline.question(question, (answer) => { - const ret = parseInt(answer, 10); - if (isNaN(ret)) { - throw("数値を入力してください"); - } - resolve(ret); - readline.close(); - }); - }); -} - -async function getGasPrice(speed) { - if (speed != 'standard' && speed != 'fast' && speed != 'fastest') - throw new Error("InvalidArgumentException"); - return await fetch('https://www.etherchain.org/api/gasPriceOracle', { method: 'get' }) - .then(res => res.json()) - .then(json => json[speed].toString()); -} - diff --git a/debug/3.js b/debug/3.js deleted file mode 100644 index 533d8e3..0000000 --- a/debug/3.js +++ /dev/null @@ -1,40 +0,0 @@ -const initializer = require('../lib/initializer'); - -const exec = async () => { - const data = await initializer({ type: 'Mint' }); - const { ADDRESS_ROUTER } = process.env; - - const router = new data.ethers.Contract( - ADDRESS_ROUTER, - [ - 'function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)', - ], - data.signature - ); - - const amountIn = data.ethers.utils.parseUnits('0.025', 18); - const from = '0xe9e7cea3dedca5984780bafc599bd69add087d56'; - const to = '0x002d8563759f5e1eaf8784181f3973288f6856e4'; - - const amounts = await router.getAmountsOut( - amountIn, - [ - from, - data.tokenAddressBase, - to, - ] - ); - - console.log({ - test: data.ethers.utils.parseUnits("1", 18), - test2: amountIn, - amounts, - amountsP: [ - parseInt(amounts[0], 10), - parseInt(amounts[1], 10), - parseInt(amounts[2], 10), - ] - }); -}; - -exec(); diff --git a/debug/4.js b/debug/4.js deleted file mode 100644 index 5e33bd4..0000000 --- a/debug/4.js +++ /dev/null @@ -1,7 +0,0 @@ -const { - threadId, -} = require("worker_threads"); - -console.log({ - threadId, -}); diff --git a/docs/addresses.md b/docs/addresses.md new file mode 100644 index 0000000..4b5d6dd --- /dev/null +++ b/docs/addresses.md @@ -0,0 +1,60 @@ +# コントラクトアドレス メモ + +2021 年当時のメモです。利用前に必ずエクスプローラで最新の状態を確認してください。 + +## PancakeSwap (BSC) + +| 名前 | アドレス | +| --- | --- | +| PancakeRouter v2 | `0x10ed43c718714eb63d5aa57b78b54704e256024e` | +| PancakeFactory v2 | `0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73` | +| WBNB | `0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c` | +| BUSD | `0xe9e7cea3dedca5984780bafc599bd69add087d56` | +| USDT (BUSD-T) | `0x55d398326f99059ff775485246999027b3197955` | + +## BakerySwap (BSC) + +| 名前 | アドレス | +| --- | --- | +| BakeryRouter | `0xcde540d7eafe93ac5fe6233bee57e1270d3e330f` | +| BakeryFactory | `0x01bf7c66c6bd861915cdaae475042d3c4bae16a7` | +| BAKE | `0xe02df9e3e622debdd69fb838bb799e3f168902c5` | +| DOGGY | `0x74926b3d118a63f6958922d3dc05eb9c6e6e00c6` | + +## Pangolin (Avalanche C-Chain) + +| 名前 | アドレス | +| --- | --- | +| PangolinRouter | `0xe54ca86531e17ef3616d22ca28b0d458b6c89106` | +| PangolinFactory | `0xefa94de7a4656d787667c749f7e1223d71e9fd88` | +| WAVAX | `0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7` | +| PNG | `0x60781c2586d68229fde47564546784ab3faca982` | + +## ローンチパッド / 過去に追っていたトークン (BSC) + +| 名前 | アドレス | +| --- | --- | +| BSCPAD | `0x5a3010d4d8d3b5fb49f8b6e57fb9e48063f16700` | +| TRONPAD | `0x1bf7aedec439d6bfe38f8f9b20cf3dc99e3571c4` | +| MOZ | `0xe4b22193d68f18f8e8eb3a26f4d64cb6d4573022` | +| BOBO | `0x36d2c8be20b02c94936602776893004cee62d5bd` | +| JACKR | `0x32c2bdea6eb916019e37c90650f7914a23beb33b` | +| LQT | `0xbd2c43da85d007b0b3cd856fd55c299578d832bc` | +| INVEST | `0x853A8Ab1c365ea54719EB13A54d6B22F1fBe7FEb` | +| NFTB | `0xde3dbbe30cfa9f437b293294d1fd64b26045c71a` | +| THOREUM | `0x580dE58c1BD593A43DaDcF0A739d504621817c05` | + +## DxSale + +| 名前 | アドレス | +| --- | --- | +| PING (sonar) | `0x550188f0be51705DCb072D910D3bdd0Aa8929040` | +| CELON | `0xd91C1CA199c1cb5c73fD0F87c81a3a1E2DFd5948` | +| NMoon | `0x0d50719a4DDc4F4Bfe661F755c942B100B381df4` | + +## Avalanche トークン + +| 名前 | アドレス | +| --- | --- | +| OSIR | `0x4db1a96ee90a4fb08e0489f55bfaf5f5af294a13` | +| aSHIB | `0x85df51751cf97292511215f4eb8f75b22caee190` | diff --git a/env/.bakery b/env/.bakery deleted file mode 100644 index 61bdad3..0000000 --- a/env/.bakery +++ /dev/null @@ -1,19 +0,0 @@ -# Router Address (DEX address) -ADDRESS_ROUTER="0xcde540d7eafe93ac5fe6233bee57e1270d3e330f" - -# Factory Address (create of tx for add liquidity) -ADDRESS_FACTORY="0x01bf7c66c6bd861915cdaae475042d3c4bae16a7" - -# Liquidity Pair Token Address (WBNB) -# FIXED: BAKE, DOGGY? -# Until it's clear, it's better to detect it with SWAP -ADDRESS_BASE="0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" - -# WebSocket RPC providor endpoint (detected fast) -# - BSC@getblock: wss://bsc.getblock.io/mainnet/?api_key=xxx -WS_RPC_URL="xxx" - -# RPC providor endpoint -# - BSC: https://bsc-dataseed1.binance.org/ @see https://bscscan.com/apis#rpc -# - BSC@bigblock: bsc.getblock.io/mainnet/?api_key=051b9f92-f141-4aa7-a7f8-97368c90cad9 -RPC_URL="https://bsc-dataseed1.binance.org/" diff --git a/env/.dxsale b/env/.dxsale deleted file mode 100644 index e69de29..0000000 diff --git a/env/.pancake b/env/.pancake deleted file mode 100644 index 18b9cc0..0000000 --- a/env/.pancake +++ /dev/null @@ -1,20 +0,0 @@ -# Router Address (DEX address) -# - Pancake v1: 0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F -# - Pancake v2: 0x10ed43c718714eb63d5aa57b78b54704e256024e -ADDRESS_ROUTER="0x10ed43c718714eb63d5aa57b78b54704e256024e" - -# Factory Address (create of tx for add liquidity) -ADDRESS_FACTORY="0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73" - -# WBNB: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c -ADDRESS_BASE="0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" - -# WebSocket RPC providor endpoint (detected fast) -# - BSC@getblock: wss://bsc.getblock.io/mainnet/?api_key=xxx -# - wss://bsc-ws-node.nariox.org:443 -WS_RPC_URL="xxx" - -# RPC providor endpoint -# - BSC: https://bsc-dataseed1.binance.org/ @see https://bscscan.com/apis#rpc -# - BSC@bigblock: bsc.getblock.io/mainnet/?api_key=xxx -RPC_URL="https://bsc-dataseed1.binance.org/" diff --git a/env/.survey b/env/.survey deleted file mode 100644 index 29ad52e..0000000 --- a/env/.survey +++ /dev/null @@ -1,11 +0,0 @@ -# input bitquery secret -API_KEY_BITQUERY="xxx" -TOKEN="xxx" -DATE_FROM="2021-06-06T14:00:00+00:00" -DATE_TO="2021-06-07T14:35:00+00:00" - -# tx.js -FILENAME_SUFFIX="CATFRIES" - -# walletTx.js -DATE_FROM_WALLET_TX="2021-05-01" diff --git a/env/bakery.env b/env/bakery.env new file mode 100644 index 0000000..07ddd5f --- /dev/null +++ b/env/bakery.env @@ -0,0 +1,11 @@ +# BakerySwap (BSC) +ADDRESS_ROUTER="0xcde540d7eafe93ac5fe6233bee57e1270d3e330f" +ADDRESS_FACTORY="0x01bf7c66c6bd861915cdaae475042d3c4bae16a7" +# 流動性ペアの基軸トークン (WBNB) +# BAKE / DOGGY ペアの可能性もあるため、不明な場合は Swap で検知する方が良い +ADDRESS_BASE="0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" + +EXPLORER_URL="https://bscscan.com" + +RPC_URL="https://bsc-dataseed1.binance.org/" +# WS_RPC_URL="wss://..." diff --git a/env/pancake.env b/env/pancake.env new file mode 100644 index 0000000..8ca5532 --- /dev/null +++ b/env/pancake.env @@ -0,0 +1,14 @@ +# PancakeSwap v2 (BSC) +# Router: v1 0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F / v2 0x10ed43c718714eb63d5aa57b78b54704e256024e +ADDRESS_ROUTER="0x10ed43c718714eb63d5aa57b78b54704e256024e" +ADDRESS_FACTORY="0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73" +# 流動性ペアの基軸トークン (WBNB) +ADDRESS_BASE="0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" + +EXPLORER_URL="https://bscscan.com" + +# HTTP RPC +RPC_URL="https://bsc-dataseed1.binance.org/" +# WebSocket RPC (設定するとこちらが優先され、イベント検知が速くなる) +# API キーを含む URL はこのファイルではなく .env に書くこと +# WS_RPC_URL="wss://..." diff --git a/env/.pangolin b/env/pangolin.env similarity index 58% rename from env/.pangolin rename to env/pangolin.env index aa51e39..7131971 100644 --- a/env/.pangolin +++ b/env/pangolin.env @@ -1,14 +1,10 @@ -# Router Address (DEX address) +# Pangolin (Avalanche C-Chain) ADDRESS_ROUTER="0xe54ca86531e17ef3616d22ca28b0d458b6c89106" - -# Factory Address (create of tx for add liquidity) ADDRESS_FACTORY="0xefa94de7a4656d787667c749f7e1223d71e9fd88" - -# Liquidity Pair Token Address (WAVAX) +# 流動性ペアの基軸トークン (WAVAX) ADDRESS_BASE="0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7" -# WebSocket RPC providor endpoint (detected fast) -# WS_RPC_URL="wss://api.avax.network/ext/bc/C/ws" +EXPLORER_URL="https://snowtrace.io" -# RPC providor endpoint RPC_URL="https://api.avax.network/ext/bc/C/rpc" +# WS_RPC_URL="wss://api.avax.network/ext/bc/C/ws" diff --git a/env/survey.env b/env/survey.env new file mode 100644 index 0000000..98a118a --- /dev/null +++ b/env/survey.env @@ -0,0 +1,11 @@ +# survey:* 用の設定。API キーは .env に BITQUERY_API_KEY として書くこと + +# survey:tx — 対象トークンと期間 +SURVEY_TOKEN="" +SURVEY_DATE_FROM="2021-06-06T14:00:00+00:00" +SURVEY_DATE_TO="2021-06-07T14:35:00+00:00" +# 出力ファイル名 data/survey/outputs/tx_survey_.json +SURVEY_OUTPUT_SUFFIX="CATFRIES" + +# survey:wallet-tx — この日付以降の受取を集計 (対象は data/survey/targets.json) +SURVEY_WALLET_TX_SINCE="2021-05-01" diff --git a/lib/buyAmountIn.js b/lib/buyAmountIn.js deleted file mode 100644 index 0eff4c2..0000000 --- a/lib/buyAmountIn.js +++ /dev/null @@ -1,15 +0,0 @@ -const initializer = require("./initializer"); -const swap = require('./swap'); - -module.exports = async function buyAmountIn() { - const data = await initializer({ type: 'MultipleBuy' }); - - await swap({ - tokenFrom: data.tokenAddressFrom, - tokenTo: data.tokenAddressTo, - tokenBase: data.tokenAddressBase, - amountIn: data.amountIn, - walletAddress: data.walletAddress, - signature: data.signature, - }); -}; diff --git a/lib/initializer.js b/lib/initializer.js deleted file mode 100644 index 4c8719f..0000000 --- a/lib/initializer.js +++ /dev/null @@ -1,74 +0,0 @@ -const ABI = require('../constants/abi'); -const loadEnv = require('../lib/loadEnv'); -const ethers = require('ethers'); -const Web3 = require('web3'); - -module.exports = async function initializer(args) { - loadEnv(); - - const { - ADDRESS_FROM, - ADDRESS_TO, - ADDRESS_BASE, - ADDRESS_FACTORY, - AMOUNT, - MULTIPLE_AMOUNT, - PRIVATE_KEY, - WS_RPC_URL, - RPC_URL, - } = process.env; - - // type: ManualBuy | MultipleBuy | ManualSell | Approve | Mint | Swap | PairCreated - const { type } = args; - - const isHttp = WS_RPC_URL === undefined; - const rpc = isHttp ? RPC_URL : WS_RPC_URL; - - const web3 = new Web3(rpc); - const provider = isHttp ? - new ethers.providers.JsonRpcProvider(RPC_URL) : - new ethers.providers.WebSocketProvider(WS_RPC_URL); - - const wallet = new ethers.Wallet(PRIVATE_KEY); - const signature = wallet.connect(provider); - const { address: walletAddress } = web3.eth.accounts.wallet.add(PRIVATE_KEY); - - const from = type === 'ManualSell' ? ADDRESS_TO : ADDRESS_FROM; - const to = type === 'ManualSell' ? ADDRESS_FROM : ADDRESS_TO; - const tokenAddressFrom = web3.utils.toChecksumAddress(from); - const tokenAddressTo = web3.utils.toChecksumAddress(to); - const tokenAddressBase = web3.utils.toChecksumAddress(ADDRESS_BASE); - const amount = type === 'MultipleBuy' ? MULTIPLE_AMOUNT : AMOUNT; - const amountIn = ethers.utils.parseUnits(amount, 18); - - let factory = null; - if (!['ManualBuy', 'ManualSell', 'MultipleBuy'].includes(type)) { - factory = new ethers.Contract( - ADDRESS_FACTORY, - ABI.FACTORY, - signature - ); - } - - let pair = null; - if (['Swap', 'Mint'].includes(type)) { - const pairAddress = await factory.getPair(tokenAddressBase, tokenAddressTo); - pair = new ethers.Contract( - pairAddress, - ABI.PARE, - signature - ); - } - - return { - signature, - walletAddress, - tokenAddressFrom, - tokenAddressTo, - tokenAddressBase, - amountIn, - ethers, - factory, - pair, - } -} diff --git a/lib/loadEnv.js b/lib/loadEnv.js deleted file mode 100644 index 3cc6ece..0000000 --- a/lib/loadEnv.js +++ /dev/null @@ -1,8 +0,0 @@ -const dotenv = require("dotenv"); - -module.exports = function loadEnv(fileName = 'pancake') { - dotenv.config(); - dotenv.config({ path: `./env/.${fileName}` }); - - console.log(`--- load env ${fileName} ---`); -} diff --git a/lib/readUserInput.js b/lib/readUserInput.js deleted file mode 100644 index be4a4a0..0000000 --- a/lib/readUserInput.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = async function readUserInput(question) { - const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout - }); - - return new Promise(resolve => { - readline.question(question, (answer) => { - const ret = parseInt(answer, 10); - if (isNaN(ret)) { - throw("数値を入力してください"); - } else if (ret < 1) { - throw("1~100の数値を入力してください"); - } - resolve(ret); - readline.close(); - }); - }); -} diff --git a/lib/slackAlert.js b/lib/slackAlert.js deleted file mode 100644 index c8c0563..0000000 --- a/lib/slackAlert.js +++ /dev/null @@ -1,26 +0,0 @@ -const loadEnv = require('../lib/loadEnv'); -const fetch = require('node-fetch'); - -async function slackAlert(message) { - loadEnv(); - - const { - WEBHOOK_URL - } = process.env; - - const options = { - method : "post", - contentType : "application/json", - body: JSON.stringify( - { - text: message, - link_names: 1 - } - ) - }; - - // @ts-ignore - await fetch(WEBHOOK_URL, options); -} - -module.exports = slackAlert; diff --git a/lib/swap.js b/lib/swap.js deleted file mode 100644 index 2f6817d..0000000 --- a/lib/swap.js +++ /dev/null @@ -1,107 +0,0 @@ -const ABI = require('../constants/abi'); -const loadEnv = require('../lib/loadEnv'); -const ethers = require('ethers'); - -module.exports = async function swap(args) { - loadEnv(); - - const { - DEADLINE_MIN, - ADDRESS_ROUTER, - TRADE_GAS_LIMIT, - TRADE_GAS_PRICE, - DEBUG, - } = process.env; - - const { - tokenFrom, - tokenTo, - tokenBase, - amountIn, - walletAddress, - signature, - // option - swapMethod, - amountOut, - amountInMax, - } = args; - - console.log("Connecting to DEX router..."); - const router = new ethers.Contract( - ADDRESS_ROUTER, - ABI.ROUTER, - signature - ); - console.log("Connected to DEX router"); - - // ignore slippage - const amountOutMin = 0; - const deadline = Math.floor(Date.now() / 1000) + 60 * DEADLINE_MIN; - let path = [tokenFrom, tokenTo]; - // case tokenBase is not wbnb - if (![tokenFrom, tokenTo].includes(tokenBase)) { - path = [tokenFrom, tokenBase, tokenTo]; - } - - console.log(`Creating Transaction`); - if (!!parseInt(DEBUG)) { - console.log("--- debug swap ---"); - console.log({ - tokenTo, - tokenFrom, - }); - } else { - let tx = null; - if (swapMethod === 'swapTokensForExactTokens') { - // @see https://uniswap.org/docs/v2/smart-contracts/router02/#swaptokensforexacttokens - // swap先トークンの購入数を指定 - tx = await router.swapTokensForExactTokens( - amountOut, - amountInMax, - path, - walletAddress, - deadline, - { - gasLimit: ethers.utils.hexlify(parseInt(TRADE_GAS_LIMIT)), - gasPrice: ethers.utils.parseUnits(TRADE_GAS_PRICE, "gwei") - } - ); - } - // else if (swapMethod === 'swapExactTokensForTokensSupportingFeeOnTransferTokens') { - // // トークンによっては使えない (トークンが消失する) - // // @see: https://uniswap.org/docs/v2/smart-contracts/router02/#swapexacttokensfortokenssupportingfeeontransfertokens - // // デフレトークン用の売却メソッド - // tx = await router.swapExactTokensForTokensSupportingFeeOnTransferTokens( - // amountIn, - // amountOutMin, - // // 2要素のみ受け付けるためwbnbで固定 - // [tokenFrom, tokenBase], - // walletAddress, - // deadline, - // { - // gasLimit: ethers.utils.hexlify(parseInt(TRADE_GAS_LIMIT)), - // gasPrice: ethers.utils.parseUnits(TRADE_GAS_PRICE, "gwei") - // } - // ); - // } - else { - // @see https://uniswap.org/docs/v2/smart-contracts/router02/#swapexacttokensfortokens - // swap元トークンの購入数を指定 (通常ver) - tx = await router.swapExactTokensForTokens( - amountIn, - amountOutMin, - path, - walletAddress, - deadline, - { - gasLimit: ethers.utils.hexlify(parseInt(TRADE_GAS_LIMIT)), - gasPrice: ethers.utils.parseUnits(TRADE_GAS_PRICE, "gwei") - } - ); - } - console.log(`Tx-hash: https://bscscan.com/tx/${tx.hash}`); - const receipt = await tx.wait(); - console.log('Order Success 🎉🎉🎉'); - console.log(`Tx was mined in block: ${receipt.blockNumber}`); - } -} diff --git a/manual/buy.js b/manual/buy.js deleted file mode 100644 index 4a001c6..0000000 --- a/manual/buy.js +++ /dev/null @@ -1,26 +0,0 @@ -const initializer = require("../lib/initializer"); -const swap = require('../lib/swap'); - -const exec = async () => { - const data = await initializer({ type: 'ManualBuy' }); - - await swap({ - tokenFrom: data.tokenAddressFrom, - tokenTo: data.tokenAddressTo, - tokenBase: data.tokenAddressBase, - amountIn: data.amountIn, - walletAddress: data.walletAddress, - signature: data.signature, - }); - process.exit(1); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/manual/buyMultiple.js b/manual/buyMultiple.js deleted file mode 100644 index 7246d00..0000000 --- a/manual/buyMultiple.js +++ /dev/null @@ -1,23 +0,0 @@ -const buy = require('../lib/buyAmountIn.js'); -const readUserInput = require('../lib/readUserInput'); - -const exec = async () => { - const execCount = await readUserInput('Input to exec count: '); - - let left = execCount; - while (left > 0) { - await buy(); - left--; - } - process.exit(1); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/manual/sell.js b/manual/sell.js deleted file mode 100755 index 94e064f..0000000 --- a/manual/sell.js +++ /dev/null @@ -1,49 +0,0 @@ -const initializer = require("../lib/initializer"); -const swap = require('../lib/swap'); -const readUserInput = require('../lib/readUserInput'); - -const exec = async () => { - const data = await initializer({ type: 'ManualSell' }); - - const contract = new data.ethers.Contract( - data.tokenAddressFrom, - [ - // 'function approve(address spender, uint256 amount) external returns (bool)', - 'function balanceOf(address tokenOwner) public view returns (uint balance)', - ], - data.signature - ); - const divPer = await readUserInput('Input to sell per (1~100): '); - const divNumber = Math.floor(100 / divPer); - const balance = await contract.balanceOf(data.walletAddress); - const divedBalance = balance.div(divNumber); - // デフレトークン用のメソッド (通常トークンも同様に利用できる) - const swapMethod = 'swapExactTokensForTokensSupportingFeeOnTransferTokens'; - - console.log({ - amount: parseInt(divedBalance, 10) * 1e-18, - }); - - // approveは事前にしておく - // await approve(contract, divedBalance); - await swap({ - tokenFrom: data.tokenAddressFrom, - tokenTo: data.tokenAddressTo, - tokenBase: data.tokenAddressBase, - amountIn: divedBalance, - walletAddress: data.walletAddress, - signature: data.signature, - swapMethod, - }); - process.exit(1); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/manual/sellApprove.js b/manual/sellApprove.js deleted file mode 100644 index 8ed2f03..0000000 --- a/manual/sellApprove.js +++ /dev/null @@ -1,52 +0,0 @@ -const initializer = require("../lib/initializer"); - -const exec = async () => { - const data = await initializer({ type: 'Approve' }); - - const { - ADDRESS_ROUTER, - APPROVE_GAS_LIMIT, - APPROVE_GAS_PRICE, - DEBUG, - } = process.env; - - const contract = new data.ethers.Contract( - data.tokenAddressTo, - [ - 'function approve(address spender, uint256 amount) external returns (bool)', - ], - data.signature - ); - - console.log(`Approving on router...`); - if (!!parseInt(DEBUG)) { - console.log("debug approve"); - console.log({ - tokenAddressTo: data.tokenAddressTo - }); - } else { - const tx = await contract.approve( - ADDRESS_ROUTER, - data.ethers.constants.MaxUint256, - { - gasLimit: data.ethers.utils.hexlify(parseInt(APPROVE_GAS_LIMIT)), - gasPrice: data.ethers.utils.parseUnits(APPROVE_GAS_PRICE, "gwei") - } - ); - console.log(`Tx-hash: https://bscscan.com/tx/${tx.hash}`); - await tx.wait(); - console.log(`Approve Success 🎉🎉🎉`); - } - - process.exit(1); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/package-lock.json b/package-lock.json deleted file mode 100755 index c0235fd..0000000 --- a/package-lock.json +++ /dev/null @@ -1,3248 +0,0 @@ -{ - "name": "348-pancakeswap-trading-bot", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@ethersproject/abi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.2.0.tgz", - "integrity": "sha512-24ExfHa0VbIOUHbB36b6lCVmWkaIVmrd9/m8MICtmSsRKzlugWqUD0B8g0zrRylXNxAOc3V6T4xKJ8jEDSvp3w==", - "requires": { - "@ethersproject/address": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/constants": "^5.2.0", - "@ethersproject/hash": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/strings": "^5.2.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.2.0.tgz", - "integrity": "sha512-Xi7Pt+CulRijc/vskBGIaYMEhafKjoNx8y4RNj/dnSpXHXScOJUSTtypqGBUngZddRbcwZGbHwEr6DZoKZwIZA==", - "requires": { - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/networks": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/transactions": "^5.2.0", - "@ethersproject/web": "^5.2.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.2.0.tgz", - "integrity": "sha512-JTXzLUrtoxpOEq1ecH86U7tstkEa9POKAGbGBb+gicbjGgzYYkLR4/LD83SX2/JNWvtYyY8t5errt5ehiy1gxQ==", - "requires": { - "@ethersproject/abstract-provider": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0" - } - }, - "@ethersproject/address": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.2.0.tgz", - "integrity": "sha512-2YfZlalWefOEfnr/CdqKRrgMgbKidYc+zG4/ilxSdcryZSux3eBU5/5btAT/hSiaHipUjd8UrWK8esCBHU6QNQ==", - "requires": { - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/rlp": "^5.2.0" - } - }, - "@ethersproject/base64": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.2.0.tgz", - "integrity": "sha512-D9wOvRE90QBI+yFsKMv0hnANiMzf40Xicq9JZbV9XYzh7srImmwmMcReU2wHjOs9FtEgSJo51Tt+sI1dKPYKDg==", - "requires": { - "@ethersproject/bytes": "^5.2.0" - } - }, - "@ethersproject/basex": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.2.0.tgz", - "integrity": "sha512-Oo7oX7BmaHLY/8ZsOLI5W0mrSwPBb1iboosN17jfK/4vGAtKjAInDai9I72CzN4NRJaMN5FkFLoPYywGqgGHlg==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/properties": "^5.2.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.2.0.tgz", - "integrity": "sha512-+MNQTxwV7GEiA4NH/i51UqQ+lY36O0rxPdV+0qzjFSySiyBlJpLk6aaa4UTvKmYWlI7YKZm6vuyCENeYn7qAOw==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "bn.js": "^4.4.0" - } - }, - "@ethersproject/bytes": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.2.0.tgz", - "integrity": "sha512-O1CRpvJDnRTB47vvW8vyqojUZxVookb4LJv/s06TotriU3Xje5WFvlvXJu1yTchtxTz9BbvJw0lFXKpyO6Dn7w==", - "requires": { - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/constants": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.2.0.tgz", - "integrity": "sha512-p+34YG0KbHS20NGdE+Ic0M6egzd7cDvcfoO9RpaAgyAYm3V5gJVqL7UynS87yCt6O6Nlx6wRFboPiM5ctAr+jA==", - "requires": { - "@ethersproject/bignumber": "^5.2.0" - } - }, - "@ethersproject/contracts": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.2.0.tgz", - "integrity": "sha512-/2fg5tWPG6Z4pciEWpwGji3ggGA5j0ChVNF7NTmkOhvFrrJuWnRpzbvYA00nz8tBDNCOV3cwub5zfWRpgwYEJQ==", - "requires": { - "@ethersproject/abi": "^5.2.0", - "@ethersproject/abstract-provider": "^5.2.0", - "@ethersproject/abstract-signer": "^5.2.0", - "@ethersproject/address": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/constants": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/transactions": "^5.2.0" - } - }, - "@ethersproject/hash": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.2.0.tgz", - "integrity": "sha512-wEGry2HFFSssFiNEkFWMzj1vpdFv4rQlkBp41UfL6J58zKGNycoAWimokITDMk8p7548MKr27h48QfERnNKkRw==", - "requires": { - "@ethersproject/abstract-signer": "^5.2.0", - "@ethersproject/address": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/strings": "^5.2.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.2.0.tgz", - "integrity": "sha512-ffq2JrW5AftCmfWZ8DxpdWdw/x06Yn+e9wrWHLpj8If1+w87W4LbTMRUaUmO1DUSN8H8g/6kMUKCTJPVuxsuOw==", - "requires": { - "@ethersproject/abstract-signer": "^5.2.0", - "@ethersproject/basex": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/pbkdf2": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/sha2": "^5.2.0", - "@ethersproject/signing-key": "^5.2.0", - "@ethersproject/strings": "^5.2.0", - "@ethersproject/transactions": "^5.2.0", - "@ethersproject/wordlists": "^5.2.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.2.0.tgz", - "integrity": "sha512-iWxSm9XiugEtaehYD6w1ImmXeatjcGcrQvffZVJHH1UqV4FckDzrOYnZBRHPQRYlnhNVrGTld1+S0Cu4MB8gdw==", - "requires": { - "@ethersproject/abstract-signer": "^5.2.0", - "@ethersproject/address": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/hdnode": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/pbkdf2": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/random": "^5.2.0", - "@ethersproject/strings": "^5.2.0", - "@ethersproject/transactions": "^5.2.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.2.0.tgz", - "integrity": "sha512-LqyxTwVANga5Y3L1yo184czW6b3PibabN8xyE/eOulQLLfXNrHHhwrOTpOhoVRWCICVCD/5SjQfwqTrczjS7jQ==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "js-sha3": "0.5.7" - } - }, - "@ethersproject/logger": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.2.0.tgz", - "integrity": "sha512-dPZ6/E3YiArgG8dI/spGkaRDry7YZpCntf4gm/c6SI8Mbqiihd7q3nuLN5VvDap/0K3xm3RE1AIUOcUwwh2ezQ==" - }, - "@ethersproject/networks": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.2.0.tgz", - "integrity": "sha512-q+htMgq7wQoEnjlkdHM6t1sktKxNbEB/F6DQBPNwru7KpQ1R0n0UTIXJB8Rb7lSnvjqcAQ40X3iVqm94NJfYDw==", - "requires": { - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.2.0.tgz", - "integrity": "sha512-qKOoO6yir/qnAgg6OP3U4gRuZ6jl9P7xwggRu/spVfnuaR+wa490AatWLqB1WOXKf6JFjm5yOaT/T5fCICQVdQ==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/sha2": "^5.2.0" - } - }, - "@ethersproject/properties": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.2.0.tgz", - "integrity": "sha512-oNFkzcoGwXXV+/Yp/MLcDLrL/2i360XIy2YN9yRZJPnIbLwjroFNLiRzLs6PyPw1D09Xs8OcPR1/nHv6xDKE2A==", - "requires": { - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/providers": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.2.0.tgz", - "integrity": "sha512-Yf/ZUqCrVr+jR0SHA9GuNZs4R1xnV9Ibnh1TlOa0ZzI6o+Qf8bEyE550k9bYI4zk2f9x9baX2RRs6BJY7Jz/WA==", - "requires": { - "@ethersproject/abstract-provider": "^5.2.0", - "@ethersproject/abstract-signer": "^5.2.0", - "@ethersproject/address": "^5.2.0", - "@ethersproject/basex": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/constants": "^5.2.0", - "@ethersproject/hash": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/networks": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/random": "^5.2.0", - "@ethersproject/rlp": "^5.2.0", - "@ethersproject/sha2": "^5.2.0", - "@ethersproject/strings": "^5.2.0", - "@ethersproject/transactions": "^5.2.0", - "@ethersproject/web": "^5.2.0", - "bech32": "1.1.4", - "ws": "7.2.3" - } - }, - "@ethersproject/random": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.2.0.tgz", - "integrity": "sha512-7Nd3qjivBGlDCGDuGYjPi8CXdtVhRZ7NeyBXoJgtnJBwn1S01ahrbMeOUVmRVWrFM0YiSEPEGo7i4xEu2gRPcg==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/rlp": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.2.0.tgz", - "integrity": "sha512-RqGsELtPWxcFhOOhSr0lQ2hBNT9tBE08WK0tb6VQbCk97EpqkbgP8yXED9PZlWMiRGchJTw6S+ExzK62XMX/fw==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/sha2": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.2.0.tgz", - "integrity": "sha512-Wqqptfn0PRO2mvmpktPW1HOLrrCyGtxhVQxO1ZyePoGrcEOurhICOlIvkTogoX4Q928D3Z9XtSSCUbdOJUF2kg==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "hash.js": "1.1.3" - }, - "dependencies": { - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" - } - } - } - }, - "@ethersproject/signing-key": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.2.0.tgz", - "integrity": "sha512-9A+dVSkrVAPuhJnWqLWV/NkKi/KB4iagTKEuojfuApUfeIHEhpwQ0Jx3cBimk7qWISSSKdgiAmIqpvVtZ5FEkg==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "bn.js": "^4.4.0", - "elliptic": "6.5.4" - } - }, - "@ethersproject/solidity": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.2.0.tgz", - "integrity": "sha512-EEFlNyEnONW3CWF8UGWPcqxJUHiaIoofO7itGwO/2gvGpnwlL+WUV+GmQoHNxmn+QJeOHspnZuh6NOVrJL6H1g==", - "requires": { - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/sha2": "^5.2.0", - "@ethersproject/strings": "^5.2.0" - } - }, - "@ethersproject/strings": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.2.0.tgz", - "integrity": "sha512-RmjX800wRYKgrzo2ZCSlA8OCQYyq4+M46VgjSVDVyYkLZctBXC3epqlppDA24R7eo856KNbXqezZsMnHT+sSuA==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/constants": "^5.2.0", - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/transactions": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.2.0.tgz", - "integrity": "sha512-QrGbhGYsouNNclUp3tWMbckMsuXJTOsA56kT3BuRrLlXJcUH7myIihajXdSfKcyJsvHJPrGZP+U3TKh+sLzZtg==", - "requires": { - "@ethersproject/address": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/constants": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/rlp": "^5.2.0", - "@ethersproject/signing-key": "^5.2.0" - } - }, - "@ethersproject/units": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.2.0.tgz", - "integrity": "sha512-yrwlyomXcBBHp5oSrLxlLkyHN7dVu3PO7hMbQXc00h388zU4TF3o/PAIUhh+x695wgJ19Fa8YgUWCab3a1RDwA==", - "requires": { - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/constants": "^5.2.0", - "@ethersproject/logger": "^5.2.0" - } - }, - "@ethersproject/wallet": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.2.0.tgz", - "integrity": "sha512-uPdjZwUmAJLo1+ybR/G/rL9pv/NEcCqOsjn6RJFvG7RmwP2kS1v5C+F+ysgx2W/PxBIVT+2IEsfXLbBz8s/6Rg==", - "requires": { - "@ethersproject/abstract-provider": "^5.2.0", - "@ethersproject/abstract-signer": "^5.2.0", - "@ethersproject/address": "^5.2.0", - "@ethersproject/bignumber": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/hash": "^5.2.0", - "@ethersproject/hdnode": "^5.2.0", - "@ethersproject/json-wallets": "^5.2.0", - "@ethersproject/keccak256": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/random": "^5.2.0", - "@ethersproject/signing-key": "^5.2.0", - "@ethersproject/transactions": "^5.2.0", - "@ethersproject/wordlists": "^5.2.0" - } - }, - "@ethersproject/web": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.2.0.tgz", - "integrity": "sha512-mYb9qxGlOBFR2pR6t1CZczuqqX6r8RQGn7MtwrBciMex3cvA/qs+wbmcDgl+/OZY0Pco/ih6WHQRnVi+4sBeCQ==", - "requires": { - "@ethersproject/base64": "^5.2.0", - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/strings": "^5.2.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.2.0.tgz", - "integrity": "sha512-/7TG5r/Zm8Wd9WhoqQ4QnntgMkIfIZ8QVrpU81muiChLD26XLOgmyiqKPL7K058uYt7UZ0wzbXjxyCYadU3xFQ==", - "requires": { - "@ethersproject/bytes": "^5.2.0", - "@ethersproject/hash": "^5.2.0", - "@ethersproject/logger": "^5.2.0", - "@ethersproject/properties": "^5.2.0", - "@ethersproject/strings": "^5.2.0" - } - }, - "@pancakeswap-libs/sdk": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@pancakeswap-libs/sdk/-/sdk-1.0.1.tgz", - "integrity": "sha512-N4EZlAD0PD7lgVEE8jOufUPRNBvcR3STSjBC9QVwoKmmH1czEY9lu8/SySecKchZtSi66qAfsrghkdXo8tnJsg==", - "requires": { - "@uniswap/v2-core": "^1.0.0", - "big.js": "^5.2.2", - "decimal.js-light": "^2.5.0", - "jsbi": "^3.1.1", - "tiny-invariant": "^1.1.0", - "tiny-warning": "^1.0.3", - "toformat": "^2.0.0" - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "12.20.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", - "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-QMg+9v0bbNJ2peLuHRWxzmy0HRJIG6gFZNhaRSp7S3ggSbCCxiqQB2/ybvhXyhHOCequpNkrx7OavNhrWOsW0A==", - "requires": { - "@types/node": "*" - } - }, - "@uniswap/v2-core": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@uniswap/v2-core/-/v2-core-1.0.1.tgz", - "integrity": "sha512-MtybtkUPSyysqLY2U210NBDeCHX+ltHt3oADGdjqoThZaFRDKwM6k1Nb3F0A3hk5hwuQvytFWhrWHOEq6nVJ8Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "available-typed-arrays": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz", - "integrity": "sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "base-x": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", - "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - } - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "bufferutil": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz", - "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==", - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "cids": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", - "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "requires": { - "buffer": "^5.5.0", - "class-is": "^1.1.0", - "multibase": "~0.6.0", - "multicodec": "^1.0.0", - "multihashes": "~0.4.15" - }, - "dependencies": { - "multicodec": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", - "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "requires": { - "buffer": "^5.6.0", - "varint": "^5.0.0" - } - } - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-hash": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", - "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "requires": { - "cids": "^0.7.1", - "multicodec": "^0.5.5", - "multihashes": "^0.4.15" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decimal.js-light": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "es-abstract": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.2.tgz", - "integrity": "sha512-byRiNIQXE6HWNySaU6JohoNXzYgbBjztwFnBLUTiJmWXjaU9bSq3urQLUlNLQ292tc+gc07zYZXNZjaOoAX3sw==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eth-ens-namehash": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", - "integrity": "sha1-IprEbsqG1S4MmR58sq74P/D2i88=", - "requires": { - "idna-uts46-hx": "^2.3.1", - "js-sha3": "^0.5.7" - } - }, - "eth-lib": { - "version": "0.1.29", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", - "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "nano-json-stream-parser": "^0.1.2", - "servify": "^0.1.12", - "ws": "^3.0.0", - "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "ethereum-bloom-filters": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.9.tgz", - "integrity": "sha512-GiK/RQkAkcVaEdxKVkPcG07PQ5vD7v2MFSHgZmBJSfMzNRHimntdBithsHAT89tAXnIpzVDWt8iaCD1DvkaxGg==", - "requires": { - "js-sha3": "^0.8.0" - }, - "dependencies": { - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - } - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-common": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz", - "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==" - }, - "ethereumjs-tx": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", - "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", - "requires": { - "ethereumjs-common": "^1.5.0", - "ethereumjs-util": "^6.0.0" - } - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "ethers": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.2.0.tgz", - "integrity": "sha512-HqFGU2Qab0mAg3y1eHKVMXS4i1gTObMY0/4+x4LiO72NHhJL3Z795gnqyivmwG1J8e5NLSlRSfyIR7TL0Hw3ig==", - "requires": { - "@ethersproject/abi": "5.2.0", - "@ethersproject/abstract-provider": "5.2.0", - "@ethersproject/abstract-signer": "5.2.0", - "@ethersproject/address": "5.2.0", - "@ethersproject/base64": "5.2.0", - "@ethersproject/basex": "5.2.0", - "@ethersproject/bignumber": "5.2.0", - "@ethersproject/bytes": "5.2.0", - "@ethersproject/constants": "5.2.0", - "@ethersproject/contracts": "5.2.0", - "@ethersproject/hash": "5.2.0", - "@ethersproject/hdnode": "5.2.0", - "@ethersproject/json-wallets": "5.2.0", - "@ethersproject/keccak256": "5.2.0", - "@ethersproject/logger": "5.2.0", - "@ethersproject/networks": "5.2.0", - "@ethersproject/pbkdf2": "5.2.0", - "@ethersproject/properties": "5.2.0", - "@ethersproject/providers": "5.2.0", - "@ethersproject/random": "5.2.0", - "@ethersproject/rlp": "5.2.0", - "@ethersproject/sha2": "5.2.0", - "@ethersproject/signing-key": "5.2.0", - "@ethersproject/solidity": "5.2.0", - "@ethersproject/strings": "5.2.0", - "@ethersproject/transactions": "5.2.0", - "@ethersproject/units": "5.2.0", - "@ethersproject/wallet": "5.2.0", - "@ethersproject/web": "5.2.0", - "@ethersproject/wordlists": "5.2.0" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "requires": { - "minipass": "^2.6.0" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - } - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idna-uts46-hx": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", - "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", - "requires": { - "punycode": "2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" - } - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "is-generator-function": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", - "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==" - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" - }, - "is-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", - "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.5.tgz", - "integrity": "sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.0-next.2", - "foreach": "^2.0.5", - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" - }, - "jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "requires": { - "json-buffer": "3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==" - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", - "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multibase": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", - "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - }, - "multicodec": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", - "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "requires": { - "varint": "^5.0.0" - } - }, - "multihashes": { - "version": "0.4.21", - "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", - "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "requires": { - "buffer": "^5.5.0", - "multibase": "^0.7.0", - "varint": "^5.0.0" - }, - "dependencies": { - "multibase": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", - "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "requires": { - "base-x": "^3.0.8", - "buffer": "^5.5.0" - } - } - } - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "oboe": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", - "integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=", - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "^1.0.0" - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-headers": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", - "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" - }, - "query-string": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - } - } - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", - "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", - "requires": { - "bn.js": "^4.11.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "swarm-js": { - "version": "0.1.40", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", - "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "eth-lib": "^0.1.26", - "fs-extra": "^4.0.2", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar": "^4.0.2", - "xhr-request": "^1.0.1" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "^1.0.1" - } - } - } - }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "tiny-invariant": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", - "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" - }, - "toformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/toformat/-/toformat-2.0.0.tgz", - "integrity": "sha512-03SWBVop6nU8bpyZCx7SodpYznbZF5R4ljwNLBcTQzKOD9xuihRo/psX58llS1BMFhhAI08H3luot5GoXJz2pQ==" - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "requires": { - "prepend-http": "^2.0.0" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, - "utf-8-validate": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.5.tgz", - "integrity": "sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ==", - "requires": { - "node-gyp-build": "^4.2.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "util": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.3.tgz", - "integrity": "sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "varint": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.3.6.tgz", - "integrity": "sha512-jEpPhnL6GDteifdVh7ulzlPrtVQeA30V9vnki9liYlUvLV82ZM7BNOQJiuzlDePuE+jZETZSP/0G/JlUVt6pOA==", - "requires": { - "web3-bzz": "1.3.6", - "web3-core": "1.3.6", - "web3-eth": "1.3.6", - "web3-eth-personal": "1.3.6", - "web3-net": "1.3.6", - "web3-shh": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-bzz": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.3.6.tgz", - "integrity": "sha512-ibHdx1wkseujFejrtY7ZyC0QxQ4ATXjzcNUpaLrvM6AEae8prUiyT/OloG9FWDgFD2CPLwzKwfSQezYQlANNlw==", - "requires": { - "@types/node": "^12.12.6", - "got": "9.6.0", - "swarm-js": "^0.1.40", - "underscore": "1.12.1" - } - }, - "web3-core": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.3.6.tgz", - "integrity": "sha512-gkLDM4T1Sc0T+HZIwxrNrwPg0IfWI0oABSglP2X5ZbBAYVUeEATA0o92LWV8BeF+okvKXLK1Fek/p6axwM/h3Q==", - "requires": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.3.6", - "web3-core-method": "1.3.6", - "web3-core-requestmanager": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-core-helpers": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.3.6.tgz", - "integrity": "sha512-nhtjA2ZbkppjlxTSwG0Ttu6FcPkVu1rCN5IFAOVpF/L0SEt+jy+O5l90+cjDq0jAYvlBwUwnbh2mR9hwDEJCNA==", - "requires": { - "underscore": "1.12.1", - "web3-eth-iban": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-core-method": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.3.6.tgz", - "integrity": "sha512-RyegqVGxn0cyYW5yzAwkPlsSEynkdPiegd7RxgB4ak1eKk2Cv1q2x4C7D2sZjeeCEF+q6fOkVmo2OZNqS2iQxg==", - "requires": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "underscore": "1.12.1", - "web3-core-helpers": "1.3.6", - "web3-core-promievent": "1.3.6", - "web3-core-subscriptions": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-core-promievent": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.3.6.tgz", - "integrity": "sha512-Z+QzfyYDTXD5wJmZO5wwnRO8bAAHEItT1XNSPVb4J1CToV/I/SbF7CuF8Uzh2jns0Cm1109o666H7StFFvzVKw==", - "requires": { - "eventemitter3": "4.0.4" - } - }, - "web3-core-requestmanager": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.3.6.tgz", - "integrity": "sha512-2rIaeuqeo7QN1Eex7aXP0ZqeteJEPWXYFS/M3r3LXMiV8R4STQBKE+//dnHJXoo2ctzEB5cgd+7NaJM8S3gPyA==", - "requires": { - "underscore": "1.12.1", - "util": "^0.12.0", - "web3-core-helpers": "1.3.6", - "web3-providers-http": "1.3.6", - "web3-providers-ipc": "1.3.6", - "web3-providers-ws": "1.3.6" - } - }, - "web3-core-subscriptions": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.3.6.tgz", - "integrity": "sha512-wi9Z9X5X75OKvxAg42GGIf81ttbNR2TxzkAsp1g+nnp5K8mBwgZvXrIsDuj7Z7gx72Y45mWJADCWjk/2vqNu8g==", - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.12.1", - "web3-core-helpers": "1.3.6" - } - }, - "web3-eth": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.3.6.tgz", - "integrity": "sha512-9+rnywRRpyX3C4hfsAQXPQh6vHh9XzQkgLxo3gyeXfbhbShUoq2gFVuy42vsRs//6JlsKdyZS7Z3hHPHz2wreA==", - "requires": { - "underscore": "1.12.1", - "web3-core": "1.3.6", - "web3-core-helpers": "1.3.6", - "web3-core-method": "1.3.6", - "web3-core-subscriptions": "1.3.6", - "web3-eth-abi": "1.3.6", - "web3-eth-accounts": "1.3.6", - "web3-eth-contract": "1.3.6", - "web3-eth-ens": "1.3.6", - "web3-eth-iban": "1.3.6", - "web3-eth-personal": "1.3.6", - "web3-net": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-eth-abi": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.3.6.tgz", - "integrity": "sha512-Or5cRnZu6WzgScpmbkvC6bfNxR26hqiKK4i8sMPFeTUABQcb/FU3pBj7huBLYbp9dH+P5W79D2MqwbWwjj9DoQ==", - "requires": { - "@ethersproject/abi": "5.0.7", - "underscore": "1.12.1", - "web3-utils": "1.3.6" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - } - } - }, - "web3-eth-accounts": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.3.6.tgz", - "integrity": "sha512-Ilr0hG6ONbCdSlVKffasCmNwftD5HsNpwyQASevocIQwHdTlvlwO0tb3oGYuajbKOaDzNTwXfz25bttAEoFCGA==", - "requires": { - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-common": "^1.3.2", - "ethereumjs-tx": "^2.1.1", - "scrypt-js": "^3.0.1", - "underscore": "1.12.1", - "uuid": "3.3.2", - "web3-core": "1.3.6", - "web3-core-helpers": "1.3.6", - "web3-core-method": "1.3.6", - "web3-utils": "1.3.6" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - } - } - }, - "web3-eth-contract": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.3.6.tgz", - "integrity": "sha512-8gDaRrLF2HCg+YEZN1ov0zN35vmtPnGf3h1DxmJQK5Wm2lRMLomz9rsWsuvig3UJMHqZAQKD7tOl3ocJocQsmA==", - "requires": { - "@types/bn.js": "^4.11.5", - "underscore": "1.12.1", - "web3-core": "1.3.6", - "web3-core-helpers": "1.3.6", - "web3-core-method": "1.3.6", - "web3-core-promievent": "1.3.6", - "web3-core-subscriptions": "1.3.6", - "web3-eth-abi": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-eth-ens": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.3.6.tgz", - "integrity": "sha512-n27HNj7lpSkRxTgSx+Zo7cmKAgyg2ElFilaFlUu/X2CNH23lXfcPm2bWssivH9z0ndhg0OyR4AYFZqPaqDHkJA==", - "requires": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "underscore": "1.12.1", - "web3-core": "1.3.6", - "web3-core-helpers": "1.3.6", - "web3-core-promievent": "1.3.6", - "web3-eth-abi": "1.3.6", - "web3-eth-contract": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-eth-iban": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.3.6.tgz", - "integrity": "sha512-nfMQaaLA/zsg5W4Oy/EJQbs8rSs1vBAX6b/35xzjYoutXlpHMQadujDx2RerTKhSHqFXSJeQAfE+2f6mdhYkRQ==", - "requires": { - "bn.js": "^4.11.9", - "web3-utils": "1.3.6" - } - }, - "web3-eth-personal": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.3.6.tgz", - "integrity": "sha512-pOHU0+/h1RFRYoh1ehYBehRbcKWP4OSzd4F7mDljhHngv6W8ewMHrAN8O1ol9uysN2MuCdRE19qkRg5eNgvzFQ==", - "requires": { - "@types/node": "^12.12.6", - "web3-core": "1.3.6", - "web3-core-helpers": "1.3.6", - "web3-core-method": "1.3.6", - "web3-net": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-net": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.3.6.tgz", - "integrity": "sha512-KhzU3wMQY/YYjyMiQzbaLPt2kut88Ncx2iqjy3nw28vRux3gVX0WOCk9EL/KVJBiAA/fK7VklTXvgy9dZnnipw==", - "requires": { - "web3-core": "1.3.6", - "web3-core-method": "1.3.6", - "web3-utils": "1.3.6" - } - }, - "web3-providers-http": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.3.6.tgz", - "integrity": "sha512-OQkT32O1A06dISIdazpGLveZcOXhEo5cEX6QyiSQkiPk/cjzDrXMw4SKZOGQbbS1+0Vjizm1Hrp7O8Vp2D1M5Q==", - "requires": { - "web3-core-helpers": "1.3.6", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.3.6.tgz", - "integrity": "sha512-+TVsSd2sSVvVgHG4s6FXwwYPPT91boKKcRuEFXqEfAbUC5t52XOgmyc2LNiD9LzPhed65FbV4LqICpeYGUvSwA==", - "requires": { - "oboe": "2.1.5", - "underscore": "1.12.1", - "web3-core-helpers": "1.3.6" - } - }, - "web3-providers-ws": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.3.6.tgz", - "integrity": "sha512-bk7MnJf5or0Re2zKyhR3L3CjGululLCHXx4vlbc/drnaTARUVvi559OI5uLytc/1k5HKUUyENAxLvetz2G1dnQ==", - "requires": { - "eventemitter3": "4.0.4", - "underscore": "1.12.1", - "web3-core-helpers": "1.3.6", - "websocket": "^1.0.32" - } - }, - "web3-shh": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.3.6.tgz", - "integrity": "sha512-9zRo415O0iBslxBnmu9OzYjNErzLnzOsy+IOvSpIreLYbbAw0XkDWxv3SfcpKnTIWIACBR4AYMIxmmyi5iB3jw==", - "requires": { - "web3-core": "1.3.6", - "web3-core-method": "1.3.6", - "web3-core-subscriptions": "1.3.6", - "web3-net": "1.3.6" - } - }, - "web3-utils": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.6.tgz", - "integrity": "sha512-hHatFaQpkQgjGVER17gNx8u1qMyaXFZtM0y0XLGH1bzsjMPlkMPLRcYOrZ00rOPfTEuYFOdrpGOqZXVmGrMZRg==", - "requires": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "underscore": "1.12.1", - "utf8": "3.0.0" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - } - } - }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", - "requires": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.4.tgz", - "integrity": "sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==", - "requires": { - "available-typed-arrays": "^1.0.2", - "call-bind": "^1.0.0", - "es-abstract": "^1.18.0-next.1", - "foreach": "^2.0.5", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.1", - "is-typed-array": "^1.1.3" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", - "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "buffer-to-arraybuffer": "^0.0.5", - "object-assign": "^4.1.1", - "query-string": "^5.0.1", - "simple-get": "^2.7.0", - "timed-out": "^4.0.1", - "url-set-query": "^1.0.0", - "xhr": "^2.0.4" - } - }, - "xhr-request-promise": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", - "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", - "requires": { - "xhr-request": "^1.1.0" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } -} diff --git a/package.json b/package.json old mode 100755 new mode 100644 index b094138..3b52610 --- a/package.json +++ b/package.json @@ -1,22 +1,36 @@ { - "name": "348-pancakeswap-trading-bot", - "version": "1.0.0", - "description": "", - "main": "script.js", - "directories": { - "test": "test" + "name": "defi-sniper", + "version": "2.0.0", + "description": "Uniswap V2 系 DEX 向けのスナイピング/手動売買 bot (Bun + TypeScript)", + "private": true, + "type": "module", + "engines": { + "bun": ">=1.3.0" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "snipe:pair-created": "bun src/commands/snipe/pair-created.ts", + "snipe:mint": "bun src/commands/snipe/mint.ts", + "snipe:swap-trace": "bun src/commands/snipe/swap-trace.ts", + "buy": "bun src/commands/manual/buy.ts", + "buy:multiple": "bun src/commands/manual/buy-multiple.ts", + "sell": "bun src/commands/manual/sell.ts", + "approve:buy": "bun src/commands/manual/approve.ts buy", + "approve:sell": "bun src/commands/manual/approve.ts sell", + "subscribe:pair-created": "bun src/commands/subscribe/pair-created.ts", + "subscribe:mint": "bun src/commands/subscribe/mint.ts", + "subscribe:swap": "bun src/commands/subscribe/swap.ts", + "survey:tx": "bun src/commands/survey/tx.ts", + "survey:wallet-tx": "bun src/commands/survey/wallet-tx.ts", + "survey:find-wallets": "bun src/commands/survey/find-wallets.ts", + "typecheck": "tsc --noEmit", + "deps:check": "bun audit && bun outdated" }, - "keywords": [], - "author": "", - "license": "ISC", "dependencies": { - "@pancakeswap-libs/sdk": "^1.0.1", - "dotenv": "^10.0.0", - "ethers": "^5.2.0", - "node-fetch": "^2.6.1", - "web3": "^1.3.6" - } + "ethers": "6.15.0" + }, + "devDependencies": { + "@types/bun": "1.3.0", + "typescript": "5.9.3" + }, + "trustedDependencies": [] } diff --git a/snipe/buyMint.js b/snipe/buyMint.js deleted file mode 100644 index 6c6e59b..0000000 --- a/snipe/buyMint.js +++ /dev/null @@ -1,49 +0,0 @@ -const initializer = require("../lib/initializer"); -const swap = require("../lib/swap"); - -const exec = async () => { - const data = await initializer({ type: 'Mint' }); - const { - DEBUG, - } = process.env; - - let detected = false; - - if (!!parseInt(DEBUG)) { - console.log("--- debug buyMint ---"); - console.log({ - tokenAddressTo: data.tokenAddressTo, - }); - process.exit(1); - } - - console.log('Start subscribe pair mint...'); - data.pair.on('Mint', async (_sender, _amount0, _amount1) => { - if (detected) { - console.log("Second mint event detected"); - return; - } - detected = true; - - console.log('💡💡💡💡💡💡💡💡💡 Got event pair mint 💡💡💡💡💡💡💡💡💡'); - - await swap({ - tokenFrom: data.tokenAddressFrom, - tokenTo: data.tokenAddressTo, - tokenBase: data.tokenAddressBase, - amountIn: data.amountIn, - walletAddress: data.walletAddress, - signature: data.signature, - }); - }); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/snipe/buyPairCreated.js b/snipe/buyPairCreated.js deleted file mode 100644 index 53a84e7..0000000 --- a/snipe/buyPairCreated.js +++ /dev/null @@ -1,76 +0,0 @@ -const initializer = require("../lib/initializer"); -const swap = require("../lib/swap"); - -const exec = async () => { - const data = await initializer({ type: 'PairCreated' }); - - const { - DEBUG, - } = process.env; - - // waiting, detected, completed - let boughtStatus = "waiting"; - - if (!!parseInt(DEBUG)) { - console.log("--- debug buyPairCreated ---"); - console.log({ - tokenAddressTo: data.tokenAddressTo, - }); - process.exit(1); - } - - const swapWrap = async () => { - await swap({ - tokenFrom: data.tokenAddressFrom, - tokenTo: data.tokenAddressTo, - tokenBase: data.tokenAddressBase, - amountIn: data.amountIn, - walletAddress: data.walletAddress, - signature: data.signature, - }); - boughtStatus = "completed"; - process.exit(1); - }; - - console.log('Start subscribe pair create...'); - data.factory.on('PairCreated', async (token0, token1, _pairAddress) => { - switch (boughtStatus) { - case "waiting": - const isMatched = [token0, token1].some(item => item === data.tokenAddressTo); - const createdToken = [token0, token1].filter((item) => item === data.tokenAddressBase)[0]; - - if (isMatched) { - boughtStatus = "detected"; -console.log(`========================================== -New pair detected - 💡💡💡💡💡 Matched 💡💡💡💡💡 ------------------------------------------- -Token: https://bscscan.com/token/${createdToken}`); - } else { -console.log(`========================================== -New pair detected - No Matched ------------------------------------------- -Token: https://bscscan.com/token/${createdToken}`); - return; - } - - await swapWrap(); - break; - case "detected": - await swapWrap(); - break; - case "completed": - console.log("Your Token was bought!"); - process.exit(1); - } - }); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/snipe/buySwapTrace.js b/snipe/buySwapTrace.js deleted file mode 100644 index d69ef08..0000000 --- a/snipe/buySwapTrace.js +++ /dev/null @@ -1,117 +0,0 @@ -const initializer = require("../lib/initializer"); -const swap = require("../lib/swap"); -const ABI = require('../constants/abi'); - -/* - * 購入上限がある場合に利用する - */ -const exec = async () => { - const data = await initializer({ type: 'Swap' }); - const { - AMOUNT, - ADDRESS_ROUTER, - DEBUG, - } = process.env; - - if (!!parseInt(DEBUG)) { - console.log("--- debug buySwapTrace ---"); - console.log({ - tokenAddressTo: data.tokenAddressTo, - }); - process.exit(1); - } - - console.log("Connecting to DEX router..."); - const router = new data.ethers.Contract( - ADDRESS_ROUTER, - ABI.ROUTER, - data.signature - ); - console.log("Connected to DEX router"); - - const isBaseWBNB = data.tokenAddressFrom === data.tokenAddressBase; - // bignum e.g. 0x3635c9adc5dea00000 - let amountWBNBHex = 0; - if (isBaseWBNB) { - amountWBNBHex = data.amountIn; - } else { - // wbnbの価格に変換 - const path = [ - data.tokenAddressFrom, - data.tokenAddressBase, - ]; - const amounts = await router.getAmountsOut(AMOUNT, path); - amountWBNBHex = amounts[1]; - } - - console.log('Start subscribe pair swap...'); - - let detected = false; - data.pair.on('Swap', async ( - _sender, - _amount0In, - amount1In, - amount0Out, - _amount1Out, - _to, - ) => { - if (detected) { - // console.log("Second mint event detected"); - return; - } - detected = true; - - console.log('💡💡💡💡💡💡💡💡💡 Got event pair swap 💡💡💡💡💡💡💡💡💡'); - - const logAmountOutHex = amount0Out; - // WBNBを想定しているがBUSDなどの場合もあるため注意 (未対応) - const logAmountInHex = amount1In; - - // swapログの方が指定したamountより小さいか - const isTransferLimitOver = logAmountInHex < amountWBNBHex; - // 小さい場合はswap先トークン数を指定して取引 - const swapMethod = isTransferLimitOver ? - 'swapTokensForExactTokens' : - 'swapExactTokensForTokens'; - - await swap({ - tokenFrom: data.tokenAddressFrom, - tokenTo: data.tokenAddressTo, - tokenBase: data.tokenAddressBase, - walletAddress: data.walletAddress, - signature: data.signature, - swapMethod, - amountIn: isTransferLimitOver ? 0 : data.amountIn, - amountOut: isTransferLimitOver ? logAmountOutHex : 0, - amountInMax: isTransferLimitOver ? data.amountIn : 0, - }); - - if (isTransferLimitOver) { - const amountOutE18 = parseInt(logAmountOutHex, 10); - const amountInMaxE18 = parseInt(data.amountIn, 10); - const amountOut = amountOutE18 * 1e-18; - const amountInMax = amountInMaxE18 * 1e-18; - console.log(`⚡️⚡️⚡️limit order⚡️⚡️⚡️`); - console.log({ - amountOutE18, - amountInMaxE18, - amountOut, - amountInMax, - }); - } - - // ひとまず一回で終了 - // TODO: AMOUNTがなくなるまで繰り返せるようにする - process.exit(1); - }); -}; - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); - -exec(); diff --git a/src/commands/manual/approve.ts b/src/commands/manual/approve.ts new file mode 100644 index 0000000..1c36c58 --- /dev/null +++ b/src/commands/manual/approve.ts @@ -0,0 +1,37 @@ +/** + * Router にトークンの使用を許可する。 + * bun run approve:buy … 購入に使う ADDRESS_FROM を approve (DEX ごとに初回のみ) + * bun run approve:sell … 売却する ADDRESS_TO を approve (購入後に実行) + * + * ⚠️ 速度優先で無制限 (MaxUint256) の approve を行う。bot 専用ウォレットで使うこと。 + */ +import { MaxUint256, parseUnits } from "ethers"; +import { runOnce } from "../../lib/cli.ts"; +import { createTradeContext, erc20, type Side } from "../../lib/context.ts"; + +runOnce(async () => { + const side = process.argv[2] as Side | undefined; + if (side !== "buy" && side !== "sell") { + throw new Error("使い方: bun src/commands/manual/approve.ts "); + } + + const ctx = await createTradeContext({ side }); + const token = erc20(ctx.tokenIn, ctx.wallet); + const spender = ctx.chain.router; + + if (ctx.trade.dryRun) { + console.log("--- DRY_RUN: approve は送信しません ---"); + console.log({ token: ctx.tokenIn, spender }); + return; + } + + console.log(`Approving ${ctx.explorer.token(ctx.tokenIn)} for router ${spender} ...`); + const tx = await token.getFunction("approve")(spender, MaxUint256, { + gasLimit: ctx.trade.approveGasLimit, + gasPrice: parseUnits(ctx.trade.approveGasPriceGwei, "gwei"), + }); + console.log(`Tx: ${ctx.explorer.tx(tx.hash)}`); + const receipt = await tx.wait(); + if (!receipt || receipt.status !== 1) throw new Error("approve が失敗しました"); + console.log("Approve Success 🎉🎉🎉"); +}); diff --git a/src/commands/manual/buy-multiple.ts b/src/commands/manual/buy-multiple.ts new file mode 100644 index 0000000..3774b13 --- /dev/null +++ b/src/commands/manual/buy-multiple.ts @@ -0,0 +1,14 @@ +/** MULTIPLE_AMOUNT ずつ、入力した回数だけ連続で購入する (購入上限があるトークン向け) */ +import { promptInt, runOnce } from "../../lib/cli.ts"; +import { createTradeContext } from "../../lib/context.ts"; +import { swap } from "../../lib/swap.ts"; + +runOnce(async () => { + const count = promptInt("Input exec count:", { min: 1, max: 1000 }); + const ctx = await createTradeContext({ side: "buy", amount: "multiple" }); + + for (let i = 1; i <= count; i++) { + console.log(`--- ${i} / ${count} ---`); + await swap(ctx, { mode: "exactIn", amountIn: ctx.amountIn }); + } +}); diff --git a/src/commands/manual/buy.ts b/src/commands/manual/buy.ts new file mode 100644 index 0000000..def62b0 --- /dev/null +++ b/src/commands/manual/buy.ts @@ -0,0 +1,9 @@ +/** AMOUNT 分の ADDRESS_FROM で ADDRESS_TO を購入する */ +import { runOnce } from "../../lib/cli.ts"; +import { createTradeContext } from "../../lib/context.ts"; +import { swap } from "../../lib/swap.ts"; + +runOnce(async () => { + const ctx = await createTradeContext({ side: "buy" }); + await swap(ctx, { mode: "exactIn", amountIn: ctx.amountIn }); +}); diff --git a/src/commands/manual/sell.ts b/src/commands/manual/sell.ts new file mode 100644 index 0000000..233bb1d --- /dev/null +++ b/src/commands/manual/sell.ts @@ -0,0 +1,24 @@ +/** + * 保有している ADDRESS_TO を指定した割合だけ売却する。事前に `bun run approve:sell` が必要。 + * + * `--fee-on-transfer` を付けるとデフレトークン用のメソッドで売却する + * (トークンによっては使えないので注意)。 + */ +import { formatUnits } from "ethers"; +import { promptInt, runOnce } from "../../lib/cli.ts"; +import { createTradeContext, erc20 } from "../../lib/context.ts"; +import { swap } from "../../lib/swap.ts"; + +runOnce(async () => { + const feeOnTransfer = process.argv.includes("--fee-on-transfer"); + const ctx = await createTradeContext({ side: "sell" }); + + const balance: bigint = await erc20(ctx.tokenIn, ctx.provider).getFunction("balanceOf")(ctx.wallet.address); + if (balance === 0n) throw new Error("売却するトークンを保有していません"); + + const percent = promptInt("Input sell percent (1~100):", { min: 1, max: 100 }); + const amountIn = (balance * BigInt(percent)) / 100n; + console.log({ balance: formatUnits(balance, ctx.decimalsIn), sell: formatUnits(amountIn, ctx.decimalsIn) }); + + await swap(ctx, { mode: feeOnTransfer ? "exactInFeeOnTransfer" : "exactIn", amountIn }); +}); diff --git a/src/commands/snipe/mint.ts b/src/commands/snipe/mint.ts new file mode 100644 index 0000000..bdc3680 --- /dev/null +++ b/src/commands/snipe/mint.ts @@ -0,0 +1,27 @@ +/** + * 既存ペアへの流動性追加 (Mint) を検知したら即購入する。 + * BSCPAD などのローンチパッド経由の IDO や、PairCreated が発行されない DEX (BakerySwap 等) 向け。 + */ +import { runForever } from "../../lib/cli.ts"; +import { createTradeContext, getPairContract } from "../../lib/context.ts"; +import { swap } from "../../lib/swap.ts"; + +runForever(async () => { + const ctx = await createTradeContext({ side: "buy" }); + const pair = await getPairContract(ctx, ctx.tokenOut); + + let bought = false; + + console.log(`Waiting Mint on pair ${ctx.explorer.address(await pair.getAddress())} ...`); + await pair.on("Mint", async () => { + if (bought) { + console.log("Second mint event detected (ignored)"); + return; + } + bought = true; + console.log("💡💡💡 Got pair Mint event 💡💡💡"); + + await swap(ctx, { mode: "exactIn", amountIn: ctx.amountIn }); + process.exit(0); + }); +}); diff --git a/src/commands/snipe/pair-created.ts b/src/commands/snipe/pair-created.ts new file mode 100644 index 0000000..6523e1b --- /dev/null +++ b/src/commands/snipe/pair-created.ts @@ -0,0 +1,37 @@ +/** + * PairCreated (流動性ペア作成) を検知したら即購入する。基本はこれを使う。 + */ +import { runForever } from "../../lib/cli.ts"; +import { createTradeContext, sameAddress } from "../../lib/context.ts"; +import { swap } from "../../lib/swap.ts"; + +runForever(async () => { + const ctx = await createTradeContext({ side: "buy" }); + const target = ctx.tokenOut; + + // 二重購入を防ぐため、一度マッチしたら以降のイベントは無視する + let state: "waiting" | "buying" = "waiting"; + + console.log(`Waiting PairCreated for ${ctx.explorer.token(target)} ...`); + await ctx.factory.on("PairCreated", async (token0: string, token1: string, pair: string) => { + if (state !== "waiting") return; + + const created = sameAddress(token0, ctx.chain.base) ? token1 : token0; + const matched = sameAddress(created, target); + console.log( + [ + "==========================================", + `New pair detected - ${matched ? "💡💡💡 Matched 💡💡💡" : "No Match"}`, + "------------------------------------------", + `Token: ${ctx.explorer.token(created)}`, + `Pair: ${ctx.explorer.address(pair)}`, + ].join("\n"), + ); + if (!matched) return; + + state = "buying"; + await swap(ctx, { mode: "exactIn", amountIn: ctx.amountIn }); + console.log("Your token was bought!"); + process.exit(0); + }); +}); diff --git a/src/commands/snipe/swap-trace.ts b/src/commands/snipe/swap-trace.ts new file mode 100644 index 0000000..9b1ccb0 --- /dev/null +++ b/src/commands/snipe/swap-trace.ts @@ -0,0 +1,56 @@ +/** + * 購入上限があるトークン向け。 + * 最初に成功した他人の Swap を検知し、その購入額が自分の AMOUNT より小さければ + * 「上限がある」とみなして同じ受取数量を exactOut で注文する。 + */ +import { formatUnits } from "ethers"; +import { runForever } from "../../lib/cli.ts"; +import { createTradeContext, getPairContract, sameAddress } from "../../lib/context.ts"; +import { swap } from "../../lib/swap.ts"; + +runForever(async () => { + const ctx = await createTradeContext({ side: "buy" }); + const pair = await getPairContract(ctx, ctx.tokenOut); + const baseIsToken0 = sameAddress(await pair.getFunction("token0")(), ctx.chain.base); + + // 自分の購入額を基軸トークン (WBNB 等) 建てに換算しておく + let myAmountInBase = ctx.amountIn; + if (!sameAddress(ctx.tokenIn, ctx.chain.base)) { + const amounts: bigint[] = await ctx.router.getFunction("getAmountsOut")(ctx.amountIn, [ + ctx.tokenIn, + ctx.chain.base, + ]); + myAmountInBase = amounts[1] ?? 0n; + } + + let detected = false; + + console.log(`Waiting first Swap on pair ${ctx.explorer.address(await pair.getAddress())} ...`); + await pair.on( + "Swap", + async (_sender: string, amount0In: bigint, amount1In: bigint, amount0Out: bigint, amount1Out: bigint) => { + const baseIn = baseIsToken0 ? amount0In : amount1In; + const targetOut = baseIsToken0 ? amount1Out : amount0Out; + // 売り方向の Swap は無視 + if (detected || baseIn === 0n) return; + detected = true; + console.log("💡💡💡 Got pair Swap event 💡💡💡"); + + const limited = baseIn < myAmountInBase; + if (limited) { + console.log("⚡️⚡️⚡️ limit order ⚡️⚡️⚡️"); + console.log({ + observedBaseIn: formatUnits(baseIn, 18), + myAmountInBase: formatUnits(myAmountInBase, 18), + amountOut: targetOut.toString(), + }); + await swap(ctx, { mode: "exactOut", amountOut: targetOut, amountInMax: ctx.amountIn }); + } else { + await swap(ctx, { mode: "exactIn", amountIn: ctx.amountIn }); + } + + // TODO: AMOUNT を使い切るまで繰り返す + process.exit(0); + }, + ); +}); diff --git a/src/commands/subscribe/mint.ts b/src/commands/subscribe/mint.ts new file mode 100644 index 0000000..0c194a9 --- /dev/null +++ b/src/commands/subscribe/mint.ts @@ -0,0 +1,17 @@ +/** ADDRESS_TO のペアへの流動性追加 (Mint) を監視して表示するだけ (注文しない) */ +import { getAddress, type ContractEventPayload } from "ethers"; +import { runForever } from "../../lib/cli.ts"; +import { createReadContext, getPairContract } from "../../lib/context.ts"; +import { required } from "../../lib/env.ts"; + +runForever(async () => { + const ctx = createReadContext(); + const pair = await getPairContract(ctx, getAddress(required("ADDRESS_TO"))); + + console.log("Subscribing pair Mint ..."); + await pair.on("Mint", (sender: string, amount0: bigint, amount1: bigint, event: ContractEventPayload) => { + console.log("💡💡💡 Got pair Mint event 💡💡💡"); + console.log({ sender, amount0, amount1 }); + console.log(`Tx: ${ctx.explorer.tx(event.log.transactionHash)}`); + }); +}); diff --git a/src/commands/subscribe/pair-created.ts b/src/commands/subscribe/pair-created.ts new file mode 100644 index 0000000..06f8e2a --- /dev/null +++ b/src/commands/subscribe/pair-created.ts @@ -0,0 +1,35 @@ +/** + * PairCreated を監視して新規トークンを表示するだけ (注文しない)。新しい DEX やローンチパッドの調査用。 + * - WATCH_SYMBOLS に一致するシンボル (未公開コントラクトアドレスの捜索用) + * - ADDRESS_TO と一致するアドレス + * を検知すると強調表示する。 + */ +import { getAddress } from "ethers"; +import { runForever } from "../../lib/cli.ts"; +import { createReadContext, erc20, sameAddress } from "../../lib/context.ts"; +import { list, optional } from "../../lib/env.ts"; + +runForever(async () => { + const ctx = createReadContext(); + const watchSymbols = list("WATCH_SYMBOLS").map((s) => new RegExp(s, "i")); + const targetRaw = optional("ADDRESS_TO"); + const target = targetRaw ? getAddress(targetRaw) : undefined; + + console.log("Subscribing PairCreated ..."); + await ctx.factory.on("PairCreated", async (token0: string, token1: string) => { + const created = sameAddress(token0, ctx.chain.base) ? token1 : token0; + const token = erc20(created, ctx.provider); + const [name, symbol] = await Promise.all([ + token.getFunction("name")().catch(() => "?"), + token.getFunction("symbol")().catch(() => "?"), + ]); + console.log(`name: ${String(name).trim()} - symbol: ${String(symbol).trim()}`); + + if (watchSymbols.some((re) => re.test(String(symbol)))) { + console.log(`💡💡💡 Probably matched symbol: ${symbol}\n${ctx.explorer.token(created)}`); + } + if (target && sameAddress(created, target)) { + console.log(`💡💡💡 Matched address\n${ctx.explorer.token(created)}`); + } + }); +}); diff --git a/src/commands/subscribe/swap.ts b/src/commands/subscribe/swap.ts new file mode 100644 index 0000000..4a12d83 --- /dev/null +++ b/src/commands/subscribe/swap.ts @@ -0,0 +1,28 @@ +/** ADDRESS_TO のペアの Swap を監視して表示するだけ (注文しない) */ +import { getAddress, type ContractEventPayload } from "ethers"; +import { runForever } from "../../lib/cli.ts"; +import { createReadContext, getPairContract } from "../../lib/context.ts"; +import { required } from "../../lib/env.ts"; + +runForever(async () => { + const ctx = createReadContext(); + const pair = await getPairContract(ctx, getAddress(required("ADDRESS_TO"))); + + console.log("Subscribing pair Swap ..."); + await pair.on( + "Swap", + ( + sender: string, + amount0In: bigint, + amount1In: bigint, + amount0Out: bigint, + amount1Out: bigint, + to: string, + event: ContractEventPayload, + ) => { + console.log("💡💡💡 Got pair Swap event 💡💡💡"); + console.log({ sender, amount0In, amount1In, amount0Out, amount1Out, to }); + console.log(`Tx: ${ctx.explorer.tx(event.log.transactionHash)}`); + }, + ); +}); diff --git a/src/commands/survey/find-wallets.ts b/src/commands/survey/find-wallets.ts new file mode 100644 index 0000000..6da3ed9 --- /dev/null +++ b/src/commands/survey/find-wallets.ts @@ -0,0 +1,32 @@ +/** + * survey:tx の出力 (data/survey/outputs/tx_survey_*.json) を突き合わせ、 + * 複数のトークンで初動購入しているウォレット (= 他の bot / インサイダー候補) を抽出する。 + */ +import { readdir } from "node:fs/promises"; +import { resolve } from "node:path"; +import { SURVEY_OUTPUT_DIR, type SurveyTx } from "../../lib/bitquery.ts"; +import { runOnce } from "../../lib/cli.ts"; + +runOnce(async () => { + const files = (await readdir(SURVEY_OUTPUT_DIR)).filter((f) => /^tx_survey_.+\.json$/.test(f)); + if (files.length === 0) throw new Error(`${SURVEY_OUTPUT_DIR} に survey:tx の出力がありません`); + + // wallet -> 出現したシンボル + const hits = new Map>(); + for (const file of files) { + const symbol = file.replace(/^tx_survey_/, "").replace(/\.json$/, ""); + const txs = (await Bun.file(resolve(SURVEY_OUTPUT_DIR, file)).json()) as SurveyTx[]; + for (const { wallet } of txs) { + const key = wallet.toLowerCase(); + hits.set(key, (hits.get(key) ?? new Set()).add(symbol)); + } + } + + const repeated = [...hits] + .filter(([, symbols]) => symbols.size > 1) + .sort((a, b) => b[1].size - a[1].size) + .map(([wallet, symbols]) => ({ wallet, count: symbols.size, symbols: [...symbols] })); + + console.table(repeated); + console.log(`files: ${files.length}, wallets appearing in 2+ tokens: ${repeated.length}`); +}); diff --git a/src/commands/survey/tx.ts b/src/commands/survey/tx.ts new file mode 100644 index 0000000..f963235 --- /dev/null +++ b/src/commands/survey/tx.ts @@ -0,0 +1,52 @@ +/** + * 指定トークンへの transferFrom 呼び出しを時系列順に取得し、 + * 初動で買っているウォレットを data/survey/outputs/tx_survey_.json に保存する。 + */ +import { mkdir } from "node:fs/promises"; +import { resolve } from "node:path"; +import { SURVEY_OUTPUT_DIR, bitquery, loadSurveyEnv, type SurveyTx } from "../../lib/bitquery.ts"; +import { runOnce } from "../../lib/cli.ts"; +import { required } from "../../lib/env.ts"; + +type Response = { + ethereum: { + smartContractCalls: { + block: { timestamp: { time: string } }; + transaction: { hash: string; txFrom: { address: string } }; + }[]; + }; +}; + +runOnce(async () => { + loadSurveyEnv(); + const token = required("SURVEY_TOKEN"); + const since = required("SURVEY_DATE_FROM"); + const till = required("SURVEY_DATE_TO"); + const suffix = required("SURVEY_OUTPUT_SUFFIX"); + + const data = await bitquery(`query { + ethereum(network: bsc) { + smartContractCalls( + options: {asc: "block.timestamp.time", limit: 50} + date: {since: "${since}", till: "${till}"} + smartContractAddress: {is: "${token}"} + smartContractMethod: {is: "transferFrom"} + ) { + block { timestamp { time(format: "%Y-%m-%d %H:%M:%S") } } + transaction { hash txFrom { address } } + } + } + }`); + + const outputs: SurveyTx[] = data.ethereum.smartContractCalls.map((call) => ({ + timestamp: call.block.timestamp.time, + tx: call.transaction.hash, + wallet: call.transaction.txFrom.address, + })); + console.log(outputs); + + await mkdir(SURVEY_OUTPUT_DIR, { recursive: true }); + const path = resolve(SURVEY_OUTPUT_DIR, `tx_survey_${suffix}.json`); + await Bun.write(path, JSON.stringify(outputs, null, 2)); + console.log(`--- saved: ${path} ---`); +}); diff --git a/src/commands/survey/wallet-tx.ts b/src/commands/survey/wallet-tx.ts new file mode 100644 index 0000000..913e78b --- /dev/null +++ b/src/commands/survey/wallet-tx.ts @@ -0,0 +1,57 @@ +/** + * data/survey/targets.json に列挙したウォレットが、各トークンの公開時刻より前に + * そのトークンを受け取っていた回数を数える (インサイダー判定の目安)。 + */ +import { SURVEY_TARGETS_FILE, bitquery, loadSurveyEnv } from "../../lib/bitquery.ts"; +import { runOnce } from "../../lib/cli.ts"; +import { required } from "../../lib/env.ts"; + +type Targets = { + wallets: string[]; + tokens: { address: string; published: string }[]; +}; + +type Response = { + ethereum: { + transfers: { block: { timestamp: { time: string } }; transaction: { hash: string }; amount: number }[]; + }; +}; + +runOnce(async () => { + loadSurveyEnv(); + const since = required("SURVEY_WALLET_TX_SINCE"); + const targets = (await Bun.file(SURVEY_TARGETS_FILE).json()) as Targets; + + const results: { wallet: string; earlyReceives: number }[] = []; + + for (const wallet of targets.wallets) { + let earlyReceives = 0; + for (const token of targets.tokens) { + const data = await bitquery(`query { + ethereum(network: bsc) { + transfers( + options: {desc: "block.timestamp.time"} + date: {since: "${since}", till: null} + amount: {gt: 0} + receiver: {is: "${wallet}"} + currency: {is: "${token.address}"} + ) { + block { timestamp { time(format: "%Y-%m-%d %H:%M:%S") } } + transaction { hash } + amount + } + } + }`); + + for (const tx of data.ethereum.transfers) { + const early = tx.block.timestamp.time <= token.published; + if (early) earlyReceives++; + console.log({ token: token.address, tx: tx.block.timestamp.time, published: token.published, early }); + } + } + console.log({ wallet, earlyReceives }); + results.push({ wallet, earlyReceives }); + } + + console.table(results); +}); diff --git a/src/lib/abi.ts b/src/lib/abi.ts new file mode 100644 index 0000000..d3af5fe --- /dev/null +++ b/src/lib/abi.ts @@ -0,0 +1,30 @@ +/** Uniswap V2 互換コントラクトの human-readable ABI */ + +export const FACTORY_ABI = [ + "event PairCreated(address indexed token0, address indexed token1, address pair, uint)", + "function getPair(address tokenA, address tokenB) external view returns (address pair)", +] as const; + +export const ROUTER_ABI = [ + "function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)", + "function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)", + "function swapTokensForExactTokens(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)", + "function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external", +] as const; + +export const PAIR_ABI = [ + "event Mint(address indexed sender, uint amount0, uint amount1)", + "event Swap(address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to)", + "function token0() external view returns (address)", + "function token1() external view returns (address)", + "function symbol() external pure returns (string memory)", +] as const; + +export const ERC20_ABI = [ + "function name() view returns (string)", + "function symbol() view returns (string)", + "function decimals() view returns (uint8)", + "function balanceOf(address owner) view returns (uint256)", + "function allowance(address owner, address spender) view returns (uint256)", + "function approve(address spender, uint256 amount) returns (bool)", +] as const; diff --git a/src/lib/bitquery.ts b/src/lib/bitquery.ts new file mode 100644 index 0000000..7779718 --- /dev/null +++ b/src/lib/bitquery.ts @@ -0,0 +1,39 @@ +/** + * BitQuery GraphQL (v1) クライアント。 + * @see https://graphql.bitquery.io/ide + */ +import { resolve } from "node:path"; +import { ROOT_DIR, loadPreset, required } from "./env.ts"; + +const ENDPOINT = "https://graphql.bitquery.io/"; + +export const SURVEY_OUTPUT_DIR = resolve(ROOT_DIR, "data/survey/outputs"); +export const SURVEY_TARGETS_FILE = resolve(ROOT_DIR, "data/survey/targets.json"); + +export function loadSurveyEnv(): void { + loadPreset("survey"); +} + +export async function bitquery(query: string): Promise { + const res = await fetch(ENDPOINT, { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-API-KEY": required("BITQUERY_API_KEY"), + }, + body: JSON.stringify({ query }), + }); + if (!res.ok) throw new Error(`BitQuery HTTP ${res.status}: ${await res.text()}`); + const json = (await res.json()) as { data?: T; errors?: unknown }; + if (json.errors || !json.data) { + throw new Error(`BitQuery error: ${JSON.stringify(json.errors ?? json)}`); + } + return json.data; +} + +/** survey 出力ファイル 1 行分 */ +export type SurveyTx = { + timestamp: string; + tx: string; + wallet: string; +}; diff --git a/src/lib/cli.ts b/src/lib/cli.ts new file mode 100644 index 0000000..3d5d8a4 --- /dev/null +++ b/src/lib/cli.ts @@ -0,0 +1,43 @@ +/** コマンドのエントリポイント共通処理 */ + +function formatError(error: unknown): string { + if (error instanceof Error) { + // ethers のエラーは shortMessage の方が読みやすい + const short = (error as { shortMessage?: string }).shortMessage; + return short ?? error.message; + } + return String(error); +} + +function fail(error: unknown): never { + console.error("--- Failed ---\n", formatError(error)); + process.exit(1); +} + +process.on("unhandledRejection", fail); + +/** + * 一度きりのコマンド。完了したら終了コード 0 で終了する。 + */ +export function runOnce(fn: () => Promise): void { + fn().then(() => process.exit(0), fail); +} + +/** + * イベント購読などで常駐するコマンド。fn はリスナー登録後に resolve すればよく、 + * 終了は fn 内で process.exit() を呼ぶか Ctrl+C で行う。 + */ +export function runForever(fn: () => Promise): void { + fn().catch(fail); +} + +/** 数値入力を受け付ける (Bun 組み込みの prompt を利用) */ +export function promptInt(question: string, range: { min: number; max: number }): number { + for (;;) { + const answer = prompt(question); + if (answer === null) throw new Error("入力がキャンセルされました"); + const value = Number.parseInt(answer, 10); + if (!Number.isNaN(value) && value >= range.min && value <= range.max) return value; + console.log(`${range.min}〜${range.max} の数値を入力してください`); + } +} diff --git a/src/lib/config.ts b/src/lib/config.ts new file mode 100644 index 0000000..d6aa046 --- /dev/null +++ b/src/lib/config.ts @@ -0,0 +1,70 @@ +import { getAddress } from "ethers"; +import { flag, int, loadPreset, optional, required } from "./env.ts"; + +export const DEX_PRESETS = ["pancake", "bakery", "pangolin"] as const; +export type DexPreset = (typeof DEX_PRESETS)[number]; + +export type ChainConfig = { + dex: DexPreset; + rpcUrl: string; + wsRpcUrl?: string; + explorerUrl: string; + router: string; + factory: string; + base: string; +}; + +export type TradeConfig = { + addressFrom: string; + addressTo: string; + amount: string; + multipleAmount: string; + deadlineMin: number; + tradeGasLimit: bigint; + tradeGasPriceGwei: string; + approveGasLimit: bigint; + approveGasPriceGwei: string; + privateKey: string; + webhookUrl?: string; + /** true のときトランザクションを送信しない (旧 DEBUG=1 も互換で受け付ける) */ + dryRun: boolean; +}; + +function resolveDex(): DexPreset { + const dex = (optional("DEX") ?? "pancake") as DexPreset; + if (!DEX_PRESETS.includes(dex)) { + throw new Error(`DEX は ${DEX_PRESETS.join(" | ")} のいずれかを指定してください: ${dex}`); + } + return dex; +} + +export function loadChainConfig(): ChainConfig { + const dex = resolveDex(); + loadPreset(dex); + return { + dex, + rpcUrl: required("RPC_URL"), + wsRpcUrl: optional("WS_RPC_URL"), + explorerUrl: (optional("EXPLORER_URL") ?? "https://bscscan.com").replace(/\/$/, ""), + router: getAddress(required("ADDRESS_ROUTER")), + factory: getAddress(required("ADDRESS_FACTORY")), + base: getAddress(required("ADDRESS_BASE")), + }; +} + +export function loadTradeConfig(): TradeConfig { + return { + addressFrom: getAddress(required("ADDRESS_FROM")), + addressTo: getAddress(required("ADDRESS_TO")), + amount: required("AMOUNT"), + multipleAmount: optional("MULTIPLE_AMOUNT") ?? "1", + deadlineMin: int("DEADLINE_MIN", 5), + tradeGasLimit: BigInt(int("TRADE_GAS_LIMIT", 500_000)), + tradeGasPriceGwei: optional("TRADE_GAS_PRICE") ?? "5", + approveGasLimit: BigInt(int("APPROVE_GAS_LIMIT", 300_000)), + approveGasPriceGwei: optional("APPROVE_GAS_PRICE") ?? "5", + privateKey: required("PRIVATE_KEY"), + webhookUrl: optional("WEBHOOK_URL"), + dryRun: flag("DRY_RUN") || flag("DEBUG"), + }; +} diff --git a/src/lib/context.ts b/src/lib/context.ts new file mode 100644 index 0000000..2a5bb58 --- /dev/null +++ b/src/lib/context.ts @@ -0,0 +1,109 @@ +import { + Contract, + JsonRpcProvider, + Wallet, + WebSocketProvider, + ZeroAddress, + parseUnits, + type ContractRunner, + type Provider, +} from "ethers"; +import { ERC20_ABI, FACTORY_ABI, PAIR_ABI, ROUTER_ABI } from "./abi.ts"; +import { loadChainConfig, loadTradeConfig, type ChainConfig, type TradeConfig } from "./config.ts"; + +export type Explorer = { + tx: (hash: string) => string; + token: (address: string) => string; + address: (address: string) => string; +}; + +export type ReadContext = { + chain: ChainConfig; + provider: Provider; + factory: Contract; + explorer: Explorer; +}; + +export type Side = "buy" | "sell"; + +export type TradeContext = ReadContext & { + trade: TradeConfig; + wallet: Wallet; + router: Contract; + /** 支払う側のトークン (buy: ADDRESS_FROM / sell: ADDRESS_TO) */ + tokenIn: string; + /** 受け取る側のトークン (buy: ADDRESS_TO / sell: ADDRESS_FROM) */ + tokenOut: string; + decimalsIn: number; + /** AMOUNT (または MULTIPLE_AMOUNT) を tokenIn の decimals で変換した値 */ + amountIn: bigint; +}; + +export const sameAddress = (a: string, b: string): boolean => a.toLowerCase() === b.toLowerCase(); + +export const erc20 = (address: string, runner: ContractRunner): Contract => + new Contract(address, ERC20_ABI, runner); + +function createProvider(chain: ChainConfig): Provider { + // WebSocket の方がイベント検知が速いので、設定されていれば優先する + return chain.wsRpcUrl ? new WebSocketProvider(chain.wsRpcUrl) : new JsonRpcProvider(chain.rpcUrl); +} + +function createExplorer(baseUrl: string): Explorer { + return { + tx: (hash) => `${baseUrl}/tx/${hash}`, + token: (address) => `${baseUrl}/token/${address}`, + address: (address) => `${baseUrl}/address/${address}`, + }; +} + +/** 監視系コマンド用。秘密鍵を必要としない */ +export function createReadContext(): ReadContext { + const chain = loadChainConfig(); + const provider = createProvider(chain); + return { + chain, + provider, + factory: new Contract(chain.factory, FACTORY_ABI, provider), + explorer: createExplorer(chain.explorerUrl), + }; +} + +export async function createTradeContext(options: { + side: Side; + /** "multiple" のとき MULTIPLE_AMOUNT を使う */ + amount?: "single" | "multiple"; +}): Promise { + const read = createReadContext(); + const trade = loadTradeConfig(); + const wallet = new Wallet(trade.privateKey, read.provider); + + const [tokenIn, tokenOut] = + options.side === "buy" ? [trade.addressFrom, trade.addressTo] : [trade.addressTo, trade.addressFrom]; + + const decimalsIn = Number(await erc20(tokenIn, read.provider).getFunction("decimals")()); + const amountText = options.amount === "multiple" ? trade.multipleAmount : trade.amount; + + return { + ...read, + factory: read.factory.connect(wallet) as Contract, + trade, + wallet, + router: new Contract(read.chain.router, ROUTER_ABI, wallet), + tokenIn, + tokenOut, + decimalsIn, + amountIn: parseUnits(amountText, decimalsIn), + }; +} + +/** 基軸トークンと対象トークンのペアコントラクトを取得する。ペア未作成ならエラー */ +export async function getPairContract(ctx: ReadContext, token: string): Promise { + const pairAddress: string = await ctx.factory.getFunction("getPair")(ctx.chain.base, token); + if (sameAddress(pairAddress, ZeroAddress)) { + throw new Error( + `ペアがまだ存在しません (${ctx.chain.base} / ${token})。PairCreated を待つ場合は snipe:pair-created を使ってください`, + ); + } + return new Contract(pairAddress, PAIR_ABI, ctx.provider); +} diff --git a/src/lib/env.ts b/src/lib/env.ts new file mode 100644 index 0000000..057074b --- /dev/null +++ b/src/lib/env.ts @@ -0,0 +1,89 @@ +/** + * 環境変数の読み込み。 + * + * - `.env` は Bun が自動で読み込む (dotenv 不要) + * - `env/.env` のプリセットを追加で読み込む (既存の値は上書きしない) + * + * 依存を増やさないため、プリセットのパースは最小限の自前実装にしている。 + */ +import { existsSync, readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +const ROOT = resolve(import.meta.dir, "../.."); + +const loaded = new Set(); + +/** `KEY=value` / `KEY="value"` / コメント行 のみをサポートする簡易パーサ */ +export function parseEnvFile(text: string): Record { + const result: Record = {}; + for (const rawLine of text.split(/\r?\n/)) { + const line = rawLine.trim(); + if (!line || line.startsWith("#")) continue; + const match = line.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/); + if (!match) continue; + const [, key, rest] = match as [string, string, string]; + let value = rest.trim(); + const quote = value[0]; + if ((quote === '"' || quote === "'") && value.lastIndexOf(quote) > 0) { + value = value.slice(1, value.lastIndexOf(quote)); + } else { + value = value.replace(/\s+#.*$/, ""); + } + result[key] = value; + } + return result; +} + +/** env/.env を読み込む。プロセス環境・.env の値が優先される */ +export function loadPreset(name: string): void { + if (loaded.has(name)) return; + const path = resolve(ROOT, "env", `${name}.env`); + if (!existsSync(path)) { + throw new Error(`プリセットが見つかりません: env/${name}.env`); + } + for (const [key, value] of Object.entries(parseEnvFile(readFileSync(path, "utf8")))) { + if (process.env[key] === undefined || process.env[key] === "") { + process.env[key] = value; + } + } + loaded.add(name); + console.log(`--- loaded preset: env/${name}.env ---`); +} + +export function optional(key: string): string | undefined { + const value = process.env[key]?.trim(); + return value ? value : undefined; +} + +export function required(key: string): string { + const value = optional(key); + if (value === undefined || value === "xxx") { + throw new Error(`環境変数 ${key} が設定されていません (.env を確認してください)`); + } + return value; +} + +export function int(key: string, fallback?: number): number { + const raw = optional(key); + if (raw === undefined) { + if (fallback !== undefined) return fallback; + throw new Error(`環境変数 ${key} が設定されていません`); + } + const value = Number.parseInt(raw, 10); + if (Number.isNaN(value)) throw new Error(`環境変数 ${key} は整数で指定してください: ${raw}`); + return value; +} + +export function flag(key: string): boolean { + const raw = optional(key); + return raw !== undefined && !["0", "false", "no"].includes(raw.toLowerCase()); +} + +export function list(key: string): string[] { + return (optional(key) ?? "") + .split(",") + .map((s) => s.trim()) + .filter(Boolean); +} + +export const ROOT_DIR = ROOT; diff --git a/src/lib/notify.ts b/src/lib/notify.ts new file mode 100644 index 0000000..c083683 --- /dev/null +++ b/src/lib/notify.ts @@ -0,0 +1,14 @@ +/** Slack 互換 Webhook に通知する。未設定なら何もしない。失敗しても処理は止めない */ +export async function notify(webhookUrl: string | undefined, text: string): Promise { + if (!webhookUrl) return; + try { + const res = await fetch(webhookUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ text, link_names: 1 }), + }); + if (!res.ok) console.warn(`webhook 通知に失敗しました: HTTP ${res.status}`); + } catch (error) { + console.warn("webhook 通知に失敗しました:", error); + } +} diff --git a/src/lib/swap.ts b/src/lib/swap.ts new file mode 100644 index 0000000..fcb46b8 --- /dev/null +++ b/src/lib/swap.ts @@ -0,0 +1,85 @@ +import { formatUnits, parseUnits, type ContractTransactionResponse } from "ethers"; +import { sameAddress, type TradeContext } from "./context.ts"; +import { notify } from "./notify.ts"; + +/** + * - exactIn: 支払う数量を指定 (swapExactTokensForTokens) + * - exactOut: 受け取る数量を指定 (swapTokensForExactTokens) — 購入上限があるトークン向け + * - exactInFeeOnTransfer: 送金手数料付き (デフレ) トークン向け。トークンによっては使えないので注意 + */ +export type SwapOrder = + | { mode: "exactIn"; amountIn: bigint; amountOutMin?: bigint } + | { mode: "exactOut"; amountOut: bigint; amountInMax: bigint } + | { mode: "exactInFeeOnTransfer"; amountIn: bigint; amountOutMin?: bigint }; + +/** tokenIn / tokenOut のどちらも基軸トークンでなければ基軸トークンを経由する */ +export function buildPath(tokenIn: string, tokenOut: string, base: string): string[] { + const touchesBase = [tokenIn, tokenOut].some((t) => sameAddress(t, base)); + return touchesBase ? [tokenIn, tokenOut] : [tokenIn, base, tokenOut]; +} + +export async function swap(ctx: TradeContext, order: SwapOrder): Promise { + const { trade, router, wallet, explorer } = ctx; + const path = buildPath(ctx.tokenIn, ctx.tokenOut, ctx.chain.base); + const deadline = BigInt(Math.floor(Date.now() / 1000) + 60 * trade.deadlineMin); + const overrides = { + gasLimit: trade.tradeGasLimit, + gasPrice: parseUnits(trade.tradeGasPriceGwei, "gwei"), + }; + + if (trade.dryRun) { + console.log("--- DRY_RUN: swap は送信しません ---"); + console.log({ ...order, path, deadline, overrides }); + return; + } + + console.log(`Sending ${order.mode} swap...`); + // スナイプ用途なのでスリッページ保護はデフォルトで無効 (amountOutMin = 0) + let tx: ContractTransactionResponse; + switch (order.mode) { + case "exactIn": + tx = await router.getFunction("swapExactTokensForTokens")( + order.amountIn, + order.amountOutMin ?? 0n, + path, + wallet.address, + deadline, + overrides, + ); + break; + case "exactOut": + tx = await router.getFunction("swapTokensForExactTokens")( + order.amountOut, + order.amountInMax, + path, + wallet.address, + deadline, + overrides, + ); + break; + case "exactInFeeOnTransfer": + tx = await router.getFunction("swapExactTokensForTokensSupportingFeeOnTransferTokens")( + order.amountIn, + order.amountOutMin ?? 0n, + path, + wallet.address, + deadline, + overrides, + ); + break; + } + + console.log(`Tx: ${explorer.tx(tx.hash)}`); + const receipt = await tx.wait(); + if (!receipt || receipt.status !== 1) { + throw new Error(`swap が失敗しました: ${explorer.tx(tx.hash)}`); + } + console.log("Order Success 🎉🎉🎉"); + console.log(`Mined in block: ${receipt.blockNumber}`); + + const amountLabel = + order.mode === "exactOut" + ? `out=${order.amountOut} (max in ${formatUnits(order.amountInMax, ctx.decimalsIn)})` + : `in=${formatUnits(order.amountIn, ctx.decimalsIn)}`; + await notify(trade.webhookUrl, `✅ swap success (${order.mode}, ${amountLabel})\n${explorer.tx(tx.hash)}`); +} diff --git a/subscribe/mint.js b/subscribe/mint.js deleted file mode 100644 index e3fa122..0000000 --- a/subscribe/mint.js +++ /dev/null @@ -1,28 +0,0 @@ -const initializer = require('../lib/initializer'); - -const exec = async () => { - const data = await initializer({ type: 'Mint' }); - - const { - DEBUG, - } = process.env; - - if (!!parseInt(DEBUG)) { - console.log("--- debug Mint ---"); - console.log({ - tokenAddressTo: data.tokenAddressTo, - }); - process.exit(1); - } - - console.log('Start subscribe pair mint...'); - data.pair.on('Mint', async (address, _sender, _amount0, amount1) => { - -console.log(`💡💡💡💡💡💡💡💡💡 Got event pair mint 💡💡💡💡💡💡💡💡💡 -Tx: https://bscscan.com/tx/${amount1?.transactionHash} -Address(router): https://bscscan.com/address/${address}`); - - }); -}; - -exec(); diff --git a/subscribe/pairCreated.js b/subscribe/pairCreated.js deleted file mode 100644 index 8d1793b..0000000 --- a/subscribe/pairCreated.js +++ /dev/null @@ -1,78 +0,0 @@ -const initializer = require('../lib/initializer'); -const ethers = require('ethers'); - -// used to find unpublished contract addresses from symbols. -const SEARCH_TARGET_SYMBOLS = [ - 'SEARCH_TARGET_SYMBOLS', -]; - -const exec = async () => { - const data = await initializer({ type: 'PairCreated' }); - - const { - DEBUG, - } = process.env; - - if (!!parseInt(DEBUG)) { - console.log("--- debug PairCreated ---"); - console.log({ - tokenAddressTo: data.tokenAddressTo, - }); - process.exit(1); - } - - console.log('Start subscribe pair create...'); - data.factory.on('PairCreated', async (token0, token1, pairAddress) => { - let createdAddress = null; - if (token0 === data.tokenAddressBase) { - createdAddress = token1; - } else { - createdAddress = token0; - } - // ignore base token address (e.g. wbnb) - getInfo( - createdAddress, - data.tokenAddressTo, - data.signature - ); - }); -}; - -const getInfo = async ( - createdAddress, - targetAddress, - signature -) => { - const contract = new ethers.Contract( - createdAddress, - [ - 'function name() view returns (string)', - 'function symbol() view returns (string)', - ], - signature - ); - - const name = await contract.name(); - const symbol = await contract.symbol(); - - console.log(`name: ${name?.trim()} - symbol: ${symbol?.trim()}`); - - if (SEARCH_TARGET_SYMBOLS.some(item => !!symbol.match(item))) { -console.log(`---------- -💡💡💡💡💡 Probably Matched Symbol 💡💡💡💡💡 -Symbol: ${symbol?.trim()} -URL: https://bscscan.com/token/${createdAddress} -💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡 -----------`); - } - - if (createdAddress === targetAddress) { -console.log(`---------- -💡💡💡💡💡 Matched Address 💡💡💡💡💡 -URL: https://bscscan.com/token/${createdAddress} -💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡 -----------`); - } -}; - -exec(); diff --git a/subscribe/swap.js b/subscribe/swap.js deleted file mode 100644 index 045f3fe..0000000 --- a/subscribe/swap.js +++ /dev/null @@ -1,46 +0,0 @@ -const initializer = require('../lib/initializer'); - -const exec = async () => { - const data = await initializer({ type: 'Swap' }); - - const { - DEBUG, - } = process.env; - - if (!!parseInt(DEBUG)) { - console.log("--- debug Swap ---"); - console.log({ - tokenAddressTo: data.tokenAddressTo, - }); - process.exit(1); - } - - // let detectedLiquidity = false; - - console.log('Start subscribe pair swap...'); - data.pair.on('Swap', async ( - sender, - amount0In, - amount1In, - amount0Out, - amount1Out, - to, - ) => { - // if (detectedLiquidity) { - // return; - // } - // detectedLiquidity = true; - - console.log('💡💡💡💡💡💡💡💡💡 Got event pair swap 💡💡💡💡💡💡💡💡💡'); - console.log({ - sender, - amount0In, - amount1In, - amount0Out, - amount1Out, - to, - }); - }); -}; - -exec(); diff --git a/survey/findWallted.js b/survey/findWallted.js deleted file mode 100644 index b08a07c..0000000 --- a/survey/findWallted.js +++ /dev/null @@ -1,70 +0,0 @@ -const fs = require('fs').promises; -const fetch = require('node-fetch'); -const dotenv = require('dotenv'); - -dotenv.config({ path: `./env/.survey` }); -const { - API_KEY_BITQUERY, - TOKEN, - DATE_FROM, - DATE_TO, - FILENAME_SUFFIX, -} = process.env; - -const exec = async () => { - const symbols = [ - 'AS', 'ASTR', 'Bidenance_1', 'BIDENANCE', 'CATFRIES', - 'HS', 'MGIRLS', 'MM', 'MoonWeed', 'NewWorld', 'PQ', - 'SUELON', 'TR', 'WCUM', - ]; - const files = symbols.map((item) => { - return { - symbol: item, - path: `${__dirname}/outputs/tx_survey_${item}.json`, - }; - }); - - // { - // "timestamp": "2021-06-14 20:00:34", - // "tx": "xxx", - // "wallet": "xxx" - // } - - const symbolWallets = await getSymbolWallet(files); - - let allWallets = []; - symbolWallets.forEach((item) => { - allWallets = allWallets.concat(item.wallets); - }); - - const sameWallets = allWallets.filter((item, idx, self) => { - return ( - self.indexOf(item) === idx && - idx !== self.lastIndexOf(item) - ); - }); - - console.log({ - sameWallets, - count: sameWallets.length, - }); -}; - -exec(); - -async function getSymbolWallet(files) { - const symbolWallets = []; - - for (let file of files) { - const data = await fs.readFile(file.path, 'utf-8'); - const json = JSON.parse(data); - const wallets = json.map((tx) => tx.wallet); - - symbolWallets.push({ - symbol: file.symbol, - wallets: [...new Set(wallets)], - }); - } - - return symbolWallets; -} diff --git a/survey/tx.js b/survey/tx.js deleted file mode 100644 index 7cc5e3f..0000000 --- a/survey/tx.js +++ /dev/null @@ -1,95 +0,0 @@ -// @see: https://graphql.bitquery.io/ide# -// https://bitquery.io/blog/graphql-with-python-javascript-and-ruby - -const fs = require('fs'); -const fetch = require('node-fetch'); -const dotenv = require('dotenv'); - -dotenv.config({ path: `./env/.survey` }); -const { - API_KEY_BITQUERY, - TOKEN, - DATE_FROM, - DATE_TO, - FILENAME_SUFFIX, -} = process.env; - -const exec = async () => { - const query = getQuery(); - const url = "https://graphql.bitquery.io/"; - const opts = { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": API_KEY_BITQUERY - }, - body: JSON.stringify({ - query - }) - }; - - const response = await fetch(url, opts); - const result = await response.json(); - console.log(result); - - const txs = result.data.ethereum.smartContractCalls; - const outputs = txs.map((tx) => { - return { - timestamp: tx.block.timestamp.time, - tx: tx.transaction.hash, - wallet: tx.transaction.txFrom.address, - }; - }); - console.log(outputs); - - const filePath = `${__dirname}/outputs/tx_survey_${FILENAME_SUFFIX}.json` - fs.writeFile( - filePath, - JSON.stringify(outputs, null, ' '), - (error) => { - if (error) throw error; - console.log('--- done ---'); - } - ); -}; - -exec(); - -function getQuery() { - const limit = 50; - const network = "bsc"; - const dateFormat = "%Y-%m-%d %H:%M:%S"; - const contractMethod = "transferFrom"; - - return `query { - ethereum(network: ${network}) { - smartContractCalls( - options: {asc: "block.timestamp.time", limit: ${limit}} - date: {since: "${DATE_FROM}", till: "${DATE_TO}"} - smartContractAddress: {is: "${TOKEN}"} - smartContractMethod: {is: "${contractMethod}"} - ) { - block { - timestamp { - time(format: "${dateFormat}") - } - } - transaction { - hash - # wallet address - txFrom { - address - } - } - } - } - }`; -} - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); diff --git a/survey/walletTx.js b/survey/walletTx.js deleted file mode 100644 index 68482ed..0000000 --- a/survey/walletTx.js +++ /dev/null @@ -1,181 +0,0 @@ -// @see: https://graphql.bitquery.io/ide# -// https://bitquery.io/blog/graphql-with-python-javascript-and-ruby - -const fetch = require('node-fetch'); -const dotenv = require('dotenv'); - -dotenv.config({ path: `./env/.survey` }); -const { - API_KEY_BITQUERY, - DATE_FROM_WALLET_TX, -} = process.env; - -const exec = async () => { - const data = getData(); - - const results = []; - - for (let wallet of data.wallets) { - const walletInfo = { - wallet, - count: 0, - }; - - for (let token of data.tokens) { - const fetched = await getResult(token.address, wallet); - const txs = fetched?.data?.ethereum?.transfers; - if (txs?.length) { - txs.forEach((tx) => { - if (tx.block.timestamp.time <= token.published) { - walletInfo.count++; - } - console.log({ - tx: tx.block.timestamp.time, - published: token.published, - bool: tx.block.timestamp.time <= token.published, - }); - }); - } - } - - console.log(walletInfo); - results.push(walletInfo); - } - - console.log(results); -}; - -exec(); - -async function getResult(token, wallet) { - const query = getQuery(token, wallet); - const url = "https://graphql.bitquery.io/"; - const opts = { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": API_KEY_BITQUERY - }, - body: JSON.stringify({ - query - }) - }; - - const response = await fetch(url, opts); - const result = await response.json(); - - return result; -} - -function getQuery(token, wallet) { - const network = "bsc"; - const dateFormat = "%Y-%m-%d %H:%M:%S"; - - return `query { - ethereum(network: ${network}) { - transfers( - options: {desc: "block.timestamp.time"} - date: {since: "${DATE_FROM_WALLET_TX}", till: null} - amount: {gt: 0} - receiver: {is: "${wallet}"} - currency: {is: "${token}"} - ) { - block { - timestamp { - time(format: "${dateFormat}") - } - } - transaction { - hash - } - amount - } - } - }`; -} - -function getData() { - const tokens = [ - { - address: "0x54d35d08f9b57c822f6705c3efda9f6d75b2bc85", - published: "2021-06-15 19:00:00", - }, - { - address: "0xe77fb3251034d373af1823f7c6a0ea60ba548513", - published: "2021-06-15 13:00:00", - }, - { - address: "0xa2b3358bd06a0f6e5c4ca9cd9a5e28b0958e1b7c", - published: "2021-06-14 20:00:00", - }, - { - address: "0xed58bf7357352ca270e4879cea7050b1d9b2e09d", - published: "2021-06-14 13:00:00", - }, - { - address: "0x7b49f40fcbedea840c443c78153c3b9af9a52d1d", - published: "2021-06-13 16:00:00", - }, - { - address: "0xb73dcbe3ca246df608ecf456307dbe7accb91cde", - published: "2021-06-12 19:00:00", - }, - { - address: "0x0da2e6ca58a6446cb9a82eaa064abb944462355e", - published: "2021-06-11 19:00:00", - }, - { - address: "0x69cf9714a95576adaa52ebef2b14a6b92b024835", - published: "2021-06-11 13:00:00", - }, - { - address: "0x97246af443dcc6fc6358407c203805ab57944708", - published: "2021-06-11 13:00:00", - }, - { - address: "0x97246af443dcc6fc6358407c203805ab57944708", - published: "2021-06-09 19:00:00", - }, - { - address: "0x7b49F40FcbEdEa840C443C78153c3B9Af9a52d1D", - published: "2021-06-08 19:00:00", - }, - { - address: "0xd7ad445ef192e037ed37f7b743dec68f2a11e463", - published: "2021-06-08 14:00:00", - }, - { - address: "0x88E6FC8A5f9933A136b7DB63b4Ae555152487562", - published: "2021-06-07 19:30:00", - }, - { - address: "0xf313e2114ef908922913bf2efcf47d61b83e9e51", - published: "2021-06-07 19:00:00", - }, - { - address: "0x7faebfc975ef277d29c75feadff6dab03e0fa09f", - published: "2021-06-07 14:00:00", - }, - ]; - const wallets = [ - // "0xafdff19a145e10cb2cd2091e5da3d397ddee742b", - // "0xd7a87414a0fe4be90f4b2cc87eece6aaa4e96880", - // "0xf8ab6ed4f78037b98b27176c61c13f8e19dbc261", - // "0x925cfdbf4ff272ec17edfef5cd021629de333098", - "0x9e395036f4e718a9e96bbcb00a8f52a291d14403", - // "0xfd54d858ec3a645075b37ca834e6403f686981e7", - ]; - - return { - tokens, - wallets, - } -} - -process.on('unhandledRejection', (error, promise) => { - console.log( - '--- Failed ---\n', - error.message - ); - process.exit(1); -}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ab3ddb0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "types": ["bun"] + }, + "include": ["src"] +}