├── keys.txt ├── public ├── galex_w_1.png ├── galex_w_2.png └── galex_w_3.png ├── package.json ├── tsconfig.json ├── .gitignore ├── README.md ├── utils ├── utils.ts └── cli.ts ├── config.ts ├── module ├── geetest.ts └── index.ts ├── claim.ts ├── index.ts └── pnpm-lock.yaml /keys.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/galex_w_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moset5820/script_galxe/HEAD/public/galex_w_1.png -------------------------------------------------------------------------------- /public/galex_w_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moset5820/script_galxe/HEAD/public/galex_w_2.png -------------------------------------------------------------------------------- /public/galex_w_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moset5820/script_galxe/HEAD/public/galex_w_3.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "swc": "node -r @swc-node/register", 4 | "task": "node -r @swc-node/register index.ts" 5 | }, 6 | "dependencies": { 7 | "axios": "^1.4.0", 8 | "ethers": "^5", 9 | "keccak": "^3.0.3" 10 | }, 11 | "devDependencies": { 12 | "@swc-node/register": "^1.6.5", 13 | "@types/node": "^20.3.1", 14 | "typescript": "^5.1.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "ts-node": { 3 | "swc": true 4 | }, 5 | "compilerOptions": { 6 | "esModuleInterop": true, 7 | "resolveJsonModule": true, 8 | "moduleResolution": "node", 9 | "baseUrl": ".", 10 | "paths": { 11 | "@/*": ["./*"] 12 | } 13 | }, 14 | "include": ["**/*.ts", "**/*.cjs", "**/*.mjs", "global.d.ts"], 15 | "exclude": ["node_modules"] 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | next-env.d.ts 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | .pnpm-debug.log* 28 | 29 | # local env files 30 | # do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables 31 | .env 32 | .env*.local 33 | 34 | # vercel 35 | .vercel 36 | 37 | # typescript 38 | *.tsbuildinfo 39 | urls.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Galex 相关脚本 2 | 3 | - 包含任务 `claim` 脚本 4 | - 包含破解 `geetest` 脚本 5 | - 包含获取银河 `passport widget url` 脚本 `pnpm task -a passport` 6 | - 包含银河护照NFT `claim` 脚本 `pnpm task -a claimp` 7 | - 后续计划加入更多galex功能脚本 8 | - 绑定twitter 9 | - 绑定邮箱 10 | - 手动触发verify 11 | - 完成附加任务(无需强制校验任务) 12 | - 问卷类任务提交 13 | - 获取奥德赛总积分 14 | 15 | ## 🤲 拜托 16 | 17 | - 🥹 关注本人推特 [@0x3lang](https://twitter.com/0x3lang),会不定期开源脚本 18 | 19 | > 请自行检查代码,和项目依赖,风险自担,可以自行修改。 20 | 21 | ## 环境 22 | 23 | - Nodejs [lts](https://nodejs.org/en/download), 👉[教程戳这里](https://www.liaoxuefeng.com/wiki/1022910821149312/1023025597810528) 24 | 25 | ## 安装依赖 26 | 27 | ```bash 28 | npm install # 安装依赖 29 | ``` 30 | 31 | ## 配置变量 32 | 33 | 调整 `config.ts` 文件的三个配置: 34 | 35 | - campaignId: 例如 https://galxe.com/Linea/campaign/GCw91UQDkQ, campaignId就是 `GCw91UQDkQ` 36 | 37 | - passportPwd: 银河护照领取需要配置密码,这个要符合银河密码要求,否则会报错 38 | 39 | - w: geetest验证参数,运行前记得更新(一天一次即可),获取方式见下图 40 | 41 | ### 获取w参数 42 | 43 | 打开个人设置页面 https://galxe.com/accountSetting?tab=Account 44 | ![geetest_1](./public/galex_w_1.png) 45 | ![geetest_2](./public/galex_w_2.png) 46 | ![geetest_3](./public/galex_w_3.png) 47 | 48 | ## 运行 49 | 50 | `keys.txt` 放私钥,一行一个 51 | 52 | ```bash 53 | npm run task -a claim 54 | ``` 55 | 56 | 支持并发运行,例如: 57 | 58 | ```bash 59 | npm run task -a claim -b 10 # 例如100个私钥,分十份并发跑,节省时间,但是会降低容错 60 | ``` 61 | -------------------------------------------------------------------------------- /utils/utils.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from "fs"; 2 | import { setTimeout as _sleep } from 'node:timers/promises'; 3 | 4 | /** 生成固定长度的字符串 */ 5 | export const randomString = (len: number) => { 6 | const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 7 | const maxPos = chars.length; 8 | let str = ''; 9 | for (let i = 0; i < len; i++) { 10 | str += chars.charAt(Math.floor(Math.random() * maxPos)); 11 | } 12 | return str; 13 | } 14 | 15 | export const randomLetterString = (len: number) => { 16 | const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 17 | const maxPos = chars.length; 18 | let str = ''; 19 | for (let i = 0; i < len; i++) { 20 | str += chars.charAt(Math.floor(Math.random() * maxPos)); 21 | } 22 | return str; 23 | } 24 | 25 | // 获取txt文件内容,移除空行和制表符并转换为数组 26 | export function getTxtContent(path: string) { 27 | const str = readFileSync(path, 'utf-8'); 28 | return str.split(/[(\r\n)\r\n]+/).filter(el => el); 29 | } 30 | 31 | /** 循环执行直到任务成功 */ 32 | export function loop(task) { 33 | return new Promise(async (resolve) => { 34 | while (true) { 35 | try { 36 | await task(); 37 | resolve(true) 38 | break; 39 | } catch (error) { 40 | console.log(`[loop] ${error?.reason || error?.message}`) 41 | } 42 | } 43 | }) 44 | } -------------------------------------------------------------------------------- /config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | // 参考readme.md 教程 3 | w: 'f9615680f1e40a4648b1794a7d976ade75c6933f182a031fe3b94990ef473a5b98fc5f7ce13f0ceb83d5cc3cf4d1a8dd9b5be8200183d450a864eba38604d8092d5a67c7b0b9663b8cd2ec426abbd80fecde19b6ddc8e4108d2a7ed7e74179253752295ff99730635cd66b2e57c4054f1ca9aad01541affca54a1543a76b9b4eb56da787e94b6abe0526d29682c4e04a08d8d8be6d091e868d246985e96cd9fbdea0d24bd2afd3de76f0d5065b211204828f46d31a9b4b68b0fe39f03f5016b95723b367262d0f41d040a3944b897c0a4b86fcd59b4cf6b4a323d426049752c251169df200f679834e5dca12ae1728ee3cc980f5ce07fa3153bfe8186d8ec1d88016d5eb3e1029f8103a984678d5b0e44674e3e32ba9c5db6d9873be719107c2f05dc9596e677551b47d374f327c266ccfb548156f68708ed6cf6806eb4890436c1d1597593d64ce36d3aa64cc2b47e42aec078013afcccd966a827ca90aa7ed3bf5afa00f7264033b95784bb7d728a92ab550c65e1b151b548bd55bd326f3c64a20aaec0c879f3bbe5a819c1fba30b955680a478c68b0f02631e6261ae035a4b34e8de29a8dd72a1fecaf1159a6a2af0d63c5315a05e226258dbfb91717debb04e05e620b594508d6f48dbc1cb98a9c481cdc3cdaba1ee049701a7713b253750c00b11957bb5eb1cc3d29891dbe28281eae9d662caadea69ebd726083efec40ef9747644442308e35263adb495be7077ab2b66a5902c7df7c5739bc6c1b1c2c', 4 | // 从网址获取 campaignId 5 | // 例如 https://galxe.com/Linea/campaign/GCw91UQDkQ,campaignId就是 GCw91UQDkQ 6 | campaignId: '', 7 | // 银河护照设置密码, 非领取任务可不填 8 | // 必须混合使用字母、数字和符号。支持符号:~!@#$%^&*.= 最少8位 9 | passportPwd: 'z2316180100~' 10 | } -------------------------------------------------------------------------------- /utils/cli.ts: -------------------------------------------------------------------------------- 1 | import { parseArgs } from "node:util"; 2 | import { getTxtContent } from "./utils"; 3 | import path from "node:path"; 4 | 5 | type CallbackFn = (p: { 6 | action: string, 7 | startIdx: number, 8 | endIdx: number, 9 | pks: string[], 10 | }) => Promise; 11 | 12 | export const cli = async (cb: CallbackFn, run = true) => { 13 | if (!run) return; 14 | const { 15 | values: { action, batch }, 16 | } = parseArgs({ 17 | options: { 18 | /** 执行动作 */ 19 | action: { 20 | type: "string", 21 | short: "a", 22 | default: '', 23 | }, 24 | /** 任务并行切割分组 */ 25 | batch: { 26 | type: "string", 27 | short: "b", 28 | default: '', 29 | }, 30 | }, 31 | }); 32 | 33 | const keys = getTxtContent(path.resolve(__dirname, '../keys.txt')).filter(Boolean) as string[]; 34 | const [startIdx, endIdx] = [0, keys.length - 1]; 35 | // 将startIdx和endIdx的区间分成slice份 36 | const s = batch || 1; 37 | const sliceSize = Math.ceil((endIdx - startIdx + 1) / +s); 38 | const fns = []; 39 | for (let i = 0; i < +s; i++) { 40 | const start = startIdx + i * sliceSize; 41 | let end = startIdx + (i + 1) * sliceSize - 1; 42 | end = end >= endIdx ? endIdx : end; 43 | fns.push(async () => { 44 | await cb?.({ 45 | action, pks: keys, startIdx: start, endIdx: end 46 | }); 47 | }) 48 | } 49 | console.time('total'); 50 | await Promise.all(fns.map(fn => fn())); 51 | console.timeEnd('total'); 52 | } -------------------------------------------------------------------------------- /module/geetest.ts: -------------------------------------------------------------------------------- 1 | import { randomUUID } from "crypto"; 2 | import axios from "axios"; 3 | import cfg from '../config'; 4 | 5 | export const getGeetestV4Captcha = async (params: { 6 | captcha_id: string; 7 | lang?: string; 8 | proxy?: any; 9 | }) => { 10 | try { 11 | const challenge = randomUUID(); 12 | const client_type = 'web'; 13 | let callback = 'geetest_' + Date.now(); 14 | let query = new URLSearchParams({ 15 | captcha_id: params.captcha_id, 16 | challenge, 17 | client_type, 18 | lang: params.lang || 'zh-cn', 19 | callback, 20 | }) 21 | let url = `https://gcaptcha4.geetest.com/load?${query.toString()}`; 22 | let res = await axios.get(url, { 23 | proxy: params.proxy, 24 | }); 25 | let text = res.data; 26 | let json = JSON.parse(text.slice(callback.length + 1, -1))['data']; 27 | query = new URLSearchParams({ 28 | lot_number: json.lot_number, 29 | payload: json.payload, 30 | process_token: json.process_token, 31 | payload_protocol: json.payload_protocol, 32 | pt: json.pt, 33 | callback: 'geetest_' + Date.now(), 34 | w: cfg.w, 35 | captcha_id: params.captcha_id, 36 | client_type, 37 | }); 38 | url = `https://gcaptcha4.geetest.com/verify?${query.toString()}`; 39 | res = await axios.get(url, { 40 | proxy: params.proxy, 41 | }); 42 | text = res.data; 43 | json = JSON.parse(text.slice(callback.length + 1, -1)); 44 | json = json['data']['seccode'] 45 | return { 46 | captchaOutput: json.captcha_output, 47 | genTime: json.gen_time, 48 | lotNumber: json.lot_number, 49 | passToken: json.pass_token, 50 | }; 51 | } catch (error) { 52 | console.log('getGeetestV4Captcha error', error); 53 | } 54 | } -------------------------------------------------------------------------------- /claim.ts: -------------------------------------------------------------------------------- 1 | import crypto from 'crypto'; 2 | import { ethers } from 'ethers'; 3 | import { Galex } from './module'; 4 | const createKeccakHash = require('keccak'); 5 | 6 | const bscProvider = new ethers.providers.JsonRpcProvider('https://bsc-dataseed.binance.org/'); 7 | 8 | function encryptPassportData(data: any, password: string) { 9 | var e = JSON.stringify(JSON.parse(data)); 10 | var n = createKeccakHash('keccak256').update(password).digest() 11 | var o = crypto.randomBytes(12) 12 | var r = crypto.createCipheriv("aes-256-gcm", n, o) 13 | var c = r.update(e); 14 | r.final("base64"); 15 | return "0x" + Buffer.concat([o, c, r.getAuthTag()]).toString("hex") 16 | } 17 | 18 | export const claimPassport = async (wallet: ethers.Wallet, password: string) => { 19 | const account = new Galex({ privateKey: wallet.privateKey }) 20 | 21 | let { addressInfo } = await account.basicUserInfo(); 22 | 23 | if (addressInfo.passport.status === 'ISSUED_NOT_MINTED' && !addressInfo.passport.id) { 24 | console.log(`[${wallet.address}] ${addressInfo.passport.status} 无法Mint Passport`) 25 | return 26 | } 27 | 28 | if (addressInfo.passport.status === 'PENDING_PREPARE' || addressInfo.passport.status === 'PENDING_SAVE') { 29 | let signature = await wallet.signMessage(`prepare_address_passport:${wallet.address.toLocaleLowerCase()}`); 30 | const { preparePassport } = await account.preparePassport({ signature }); 31 | signature = await wallet.signMessage(`save_address_passport:${wallet.address.toLocaleLowerCase()}`); 32 | const cipher = encryptPassportData(preparePassport.data, password) 33 | await account.savePassport({ cipher, signature }); 34 | } 35 | 36 | ;({ addressInfo } = await account.basicUserInfo()); 37 | 38 | if (!addressInfo.passport.id) { 39 | console.log(`[${wallet.address}] kyc认证未通过, 无法Mint Passport`) 40 | return 41 | } 42 | 43 | // 获取mint信息 44 | const { prepareParticipate } = await account.getPrepareParticipate({ 45 | signature: '', 46 | campaignID: 'GCfBiUt5ye', 47 | chain: 'BSC', 48 | mintCount: 1, 49 | }) 50 | 51 | const { mintFuncInfo, allow, signature } = prepareParticipate; 52 | 53 | if (!mintFuncInfo || !allow) { 54 | return console.log(`[${wallet.address}] 领取NFT/获取签名信息失败, ${prepareParticipate.disallowReason}}`) 55 | } 56 | 57 | const abi = ['function claim(uint256, address, uint256, uint256, bytes) payable'] 58 | const ca = '0x2D18f2d27D50C9b4013DEBA3D54f60996bD8847E'; 59 | const signer = wallet.connect(bscProvider); 60 | const contract = new ethers.Contract(ca, abi, signer) 61 | const balance = await bscProvider.getBalance(wallet.address); 62 | const value = ethers.utils.parseEther('0.025'); 63 | if (balance.lt(value)) { 64 | return console.log(`[${wallet.address}] Mint NFT失败: 余额不足`) 65 | } 66 | console.log(`[${wallet.address}] 开始领取NFT...`) 67 | const tx = await contract.claim( 68 | mintFuncInfo.powahs[0], 69 | mintFuncInfo.nftCoreAddress, 70 | mintFuncInfo.verifyIDs[0], 71 | mintFuncInfo.powahs[0], 72 | signature, 73 | { 74 | value, 75 | gasPrice: ethers.utils.parseUnits('1', 'wei'), 76 | } 77 | ) 78 | const reicept = await tx.wait(); 79 | console.log(`[${wallet.address}] 成功领取NFT tx: ${reicept.transactionHash}`) 80 | } -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Galex - A tool for galex campaign action 3 | * 4 | * Author @3lang3 2023-06-21 5 | * Github: https://github.com/3lang3 6 | */ 7 | import fs from 'fs/promises'; 8 | import { ethers } from "ethers"; 9 | import { cli } from "./utils/cli"; 10 | import { Galex } from "./module"; 11 | import cfg from "./config"; 12 | import { loop } from "./utils/utils"; 13 | import { claimPassport } from './claim'; 14 | 15 | // 领取任务积分 16 | const claim = async (wallet: ethers.Wallet) => { 17 | await loop(async () => { 18 | const account = new Galex({ privateKey: wallet.privateKey }); 19 | const r = await account.getPrepareParticipate({ 20 | campaignID: cfg.campaignId, 21 | chain: 'ETHEREUM', 22 | }); 23 | if (r.prepareParticipate?.disallowReason) { 24 | console.log(`领取失败: ${r.prepareParticipate?.disallowReason}`); 25 | return; 26 | } 27 | if (r.prepareParticipate?.loyaltyPointsTxResp?.TotalClaimedPoints) { 28 | console.log(`成功领取 ${r.prepareParticipate?.loyaltyPointsTxResp?.TotalClaimedPoints} 分`); 29 | } 30 | }) 31 | }; 32 | 33 | // 获取widget containerId 34 | function containerId() { 35 | return "persona-widget-" + new Array(16).fill(void 0).map((function () { 36 | return Math.floor(35 * Math.random()).toString(35) 37 | } 38 | )).join("") 39 | } 40 | 41 | // 获取widget url 42 | const getPassportUrl = async (wallet: ethers.Wallet) => { 43 | let data = ''; 44 | await loop(async () => { 45 | const account = new Galex({ privateKey: wallet.privateKey }); 46 | const signature = await wallet.signMessage(`get_or_create_address_inquiry:${wallet.address.toLocaleLowerCase()}`) 47 | const { getOrCreateInquiryByAddress } = await account.getOrCreateInquiryByAddress({ signature }); 48 | if (getOrCreateInquiryByAddress.status === 'Approved') { 49 | data = 'Approved'; 50 | return; 51 | } 52 | const { sessionToken, inquiryID } = getOrCreateInquiryByAddress.personaInquiry 53 | if (!sessionToken) throw Error('sessionToken is null, retry') 54 | data = `https://withpersona.com/widget?client-version=4.7.1&container-id=${containerId()}&flow-type=embedded&environment=production&iframe-origin=https%3A%2F%2Fgalxe.com&inquiry-id=${inquiryID}&session-token=${sessionToken}` 55 | }) 56 | // 将url存入 urls.txt 文件 57 | await fs.appendFile('urls.txt', `[${wallet.address}] ${data}\n`); 58 | } 59 | 60 | cli(async ({ action, pks, startIdx, endIdx }) => { 61 | for (let k = startIdx; k <= endIdx; k++) { 62 | const pk = pks[k]; 63 | const wallet = new ethers.Wallet(pk); 64 | try { 65 | if (action === 'claim') { 66 | if (!cfg.campaignId || !cfg.w) { 67 | console.error( 68 | "❌ 请在config.ts中配置对应参数", 69 | ); 70 | process.exit(1); 71 | } 72 | console.log(`[${action}] ${wallet.address} 开始执行claim`) 73 | await claim(wallet); 74 | console.log(`[${action}] ${wallet.address} claim执行完毕`) 75 | } 76 | 77 | if (action === 'passport') { 78 | console.log(`[${action}] ${wallet.address} 开始获取passport url`) 79 | await getPassportUrl(wallet); 80 | console.log(`[${action}] ${wallet.address} passport url获取完毕`) 81 | } 82 | 83 | if (action === 'claimp') { 84 | if (!cfg.passportPwd || !cfg.w) { 85 | console.error( 86 | "❌ 请在config.ts中配置passportPwd和w参数", 87 | ); 88 | process.exit(1); 89 | } 90 | await claimPassport(wallet, cfg.passportPwd); 91 | } 92 | 93 | } catch (error) { 94 | console.log(error?.reason || error?.message) 95 | } 96 | } 97 | }); 98 | -------------------------------------------------------------------------------- /module/index.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { ethers } from "ethers"; 3 | import { getGeetestV4Captcha } from "./geetest"; 4 | import { randomString } from "@/utils/utils"; 5 | 6 | type Captcha = Awaited> 7 | 8 | // 登录 9 | const signInQuery = (p: { address: string; message: string; signature: string }) => ({ "operationName": "SignIn", "variables": { "input": p }, "query": "mutation SignIn($input: Auth) {\n signin(input: $input)\n}\n" }) 10 | 11 | // Claim 12 | const prepareParticipateQuery = (p: { address: string; campaignID: string; chain: string; mintCount?: number; signature?: string; captcha: Captcha }) => ({ "operationName": "PrepareParticipate", "variables": { "input": { mintCount: 1, signature: '', ...p } }, "query": "mutation PrepareParticipate($input: PrepareParticipateInput!) {\n prepareParticipate(input: $input) {\n allow\n disallowReason\n signature\n nonce\n mintFuncInfo {\n funcName\n nftCoreAddress\n verifyIDs\n powahs\n cap\n __typename\n }\n extLinkResp {\n success\n data\n error\n __typename\n }\n metaTxResp {\n metaSig2\n autoTaskUrl\n metaSpaceAddr\n forwarderAddr\n metaTxHash\n reqQueueing\n __typename\n }\n solanaTxResp {\n mint\n updateAuthority\n explorerUrl\n signedTx\n verifyID\n __typename\n }\n aptosTxResp {\n signatureExpiredAt\n tokenName\n __typename\n }\n tokenRewardCampaignTxResp {\n signatureExpiredAt\n verifyID\n __typename\n }\n loyaltyPointsTxResp {\n TotalClaimedPoints\n __typename\n }\n __typename\n }\n}\n" }) 13 | 14 | const getOrCreateInquiryByAddress = (p: { address: string; signature: string }) => ({ "operationName": "GetOrCreateInquiryByAddress", "variables": { "input": { "address": p.address.toLocaleLowerCase(), "signature": p.signature } }, "query": "mutation GetOrCreateInquiryByAddress($input: GetOrCreateInquiryByAddressInput!) {\n getOrCreateInquiryByAddress(input: $input) {\n status\n vendor\n personaInquiry {\n inquiryID\n sessionToken\n declinedReason\n __typename\n }\n __typename\n }\n}\n" }) 15 | 16 | const preparePassport = (p: { address: string; signature: string }) => ({ "operationName": "PreparePassport", "variables": { "input": p }, "query": "mutation PreparePassport($input: PreparePassportInput!) {\n preparePassport(input: $input) {\n data\n __typename\n }\n}\n" }) 17 | const savePassport = (p: { address: string; signature: string; cipher: string }) => ({ "operationName": "SavePassport", "variables": { "input": p }, "query": "mutation SavePassport($input: SavePassportInput!) {\n savePassport(input: $input) {\n id\n encrytionAlgorithm\n cipher\n __typename\n }\n}\n" }) 18 | const basicUserInfo = (p: { address: string; }) => ({ "operationName": "BasicUserInfo", "variables": { "address": p.address, "listSpaceInput": { "first": 30 } }, "query": "query BasicUserInfo($address: String!, $listSpaceInput: ListSpaceInput!) {\n addressInfo(address: $address) {\n id\n username\n address\n hasEmail\n avatar\n solanaAddress\n aptosAddress\n seiAddress\n hasEvmAddress\n hasSolanaAddress\n hasAptosAddress\n hasTwitter\n hasGithub\n hasDiscord\n hasTelegram\n displayEmail\n displayTwitter\n displayGithub\n displayDiscord\n displayTelegram\n email\n twitterUserID\n twitterUserName\n githubUserID\n githubUserName\n passport {\n status\n pendingRedactAt\n id\n __typename\n }\n isVerifiedTwitterOauth2\n isVerifiedDiscordOauth2\n displayNamePref\n discordUserID\n discordUserName\n telegramUserID\n telegramUserName\n subscriptions\n isWhitelisted\n isInvited\n isAdmin\n passportPendingRedactAt\n spaces(input: $listSpaceInput) {\n list {\n ...SpaceBasicFrag\n __typename\n }\n __typename\n }\n __typename\n }\n}\n\nfragment SpaceBasicFrag on Space {\n id\n name\n info\n thumbnail\n alias\n links\n isVerified\n status\n followersCount\n __typename\n}\n" }) 19 | 20 | export class Galex { 21 | public req: ReturnType; 22 | public wallet: ethers.Wallet; 23 | public token: string; 24 | public proxy: any; 25 | public captcha_id = '244bcb8b9846215df5af4c624a750db4' 26 | 27 | constructor(options: { privateKey: string; token?: string; proxy?: any }) { 28 | this.wallet = new ethers.Wallet(options.privateKey); 29 | this.proxy = options.proxy; 30 | this.req = axios.create({ 31 | baseURL: 'https://graphigo.prd.galaxy.eco', 32 | proxy: options.proxy, 33 | headers: { 34 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36', 35 | 'origin': 'https://galxe.co', 36 | "accept-language": ":zh-CN,zh;q=0.9", 37 | } 38 | }) 39 | 40 | if (options.token) { 41 | this.updateToken(options.token) 42 | } 43 | } 44 | 45 | private updateToken(token: string) { 46 | this.token = token; 47 | this.req.interceptors.request.use(cfg => { 48 | cfg.headers['authorization'] = token 49 | return cfg; 50 | }) 51 | } 52 | 53 | async login() { 54 | const address = this.wallet.address; 55 | if (this.token) return this.token; 56 | const nonce = randomString(17); 57 | const issuedAt = new Date().toISOString(); 58 | const expiredAt = new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(); 59 | const message = `galxe.com wants you to sign in with your Ethereum account:\n${address}\n\nSign in with Ethereum to the app.\n\nURI: https://galxe.com\nVersion: 1\nChain ID: 1\nNonce: ${nonce}\nIssued At: ${issuedAt}\nExpiration Time: ${expiredAt}`; 60 | const signature = await this.wallet.signMessage(message) 61 | const res = await this.req.post('/query', signInQuery({ address, message, signature })) 62 | const token = res.data.data.signin as string; 63 | this.updateToken(token); 64 | return token; 65 | } 66 | 67 | async getPrepareParticipate(p: { campaignID: string; chain: string; mintCount?: number; signature?: string }) { 68 | if (!this.token) { 69 | await this.login() 70 | } 71 | const address = this.wallet.address; 72 | const { ...rest } = p; 73 | const captcha = await getGeetestV4Captcha({ 74 | captcha_id: this.captcha_id, 75 | proxy: this.proxy, 76 | }) 77 | const res = await this.req.post('/query', prepareParticipateQuery({ address, captcha, ...rest })) 78 | return res.data.data 79 | } 80 | 81 | async getOrCreateInquiryByAddress(p: { signature: string }) { 82 | if (!this.token) { 83 | await this.login() 84 | } 85 | const address = this.wallet.address; 86 | const res = await this.req.post('/query', getOrCreateInquiryByAddress({ address, ...p })) 87 | return res.data.data 88 | } 89 | 90 | async preparePassport(p: { signature: string }) { 91 | if (!this.token) { 92 | await this.login() 93 | } 94 | const address = this.wallet.address; 95 | const res = await this.req.post('/query', preparePassport({ address, ...p })) 96 | return res.data.data 97 | } 98 | async savePassport(p: { cipher: string; signature: string; }) { 99 | if (!this.token) { 100 | await this.login() 101 | } 102 | const address = this.wallet.address; 103 | const res = await this.req.post('/query', savePassport({ address, ...p })) 104 | return res.data.data 105 | } 106 | async basicUserInfo() { 107 | if (!this.token) { 108 | await this.login() 109 | } 110 | const address = this.wallet.address; 111 | const res = await this.req.post('/query', basicUserInfo({ address })) 112 | return res.data.data 113 | } 114 | } -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | axios: 9 | specifier: ^1.4.0 10 | version: 1.4.0 11 | ethers: 12 | specifier: ^5 13 | version: 5.7.2 14 | keccak: 15 | specifier: ^3.0.3 16 | version: 3.0.3 17 | 18 | devDependencies: 19 | '@swc-node/register': 20 | specifier: ^1.6.5 21 | version: 1.6.5(@swc/core@1.3.65)(typescript@5.1.3) 22 | '@types/node': 23 | specifier: ^20.3.1 24 | version: 20.3.1 25 | typescript: 26 | specifier: ^5.1.3 27 | version: 5.1.3 28 | 29 | packages: 30 | 31 | /@ethersproject/abi@5.7.0: 32 | resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} 33 | dependencies: 34 | '@ethersproject/address': 5.7.0 35 | '@ethersproject/bignumber': 5.7.0 36 | '@ethersproject/bytes': 5.7.0 37 | '@ethersproject/constants': 5.7.0 38 | '@ethersproject/hash': 5.7.0 39 | '@ethersproject/keccak256': 5.7.0 40 | '@ethersproject/logger': 5.7.0 41 | '@ethersproject/properties': 5.7.0 42 | '@ethersproject/strings': 5.7.0 43 | dev: false 44 | 45 | /@ethersproject/abstract-provider@5.7.0: 46 | resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} 47 | dependencies: 48 | '@ethersproject/bignumber': 5.7.0 49 | '@ethersproject/bytes': 5.7.0 50 | '@ethersproject/logger': 5.7.0 51 | '@ethersproject/networks': 5.7.1 52 | '@ethersproject/properties': 5.7.0 53 | '@ethersproject/transactions': 5.7.0 54 | '@ethersproject/web': 5.7.1 55 | dev: false 56 | 57 | /@ethersproject/abstract-signer@5.7.0: 58 | resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} 59 | dependencies: 60 | '@ethersproject/abstract-provider': 5.7.0 61 | '@ethersproject/bignumber': 5.7.0 62 | '@ethersproject/bytes': 5.7.0 63 | '@ethersproject/logger': 5.7.0 64 | '@ethersproject/properties': 5.7.0 65 | dev: false 66 | 67 | /@ethersproject/address@5.7.0: 68 | resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} 69 | dependencies: 70 | '@ethersproject/bignumber': 5.7.0 71 | '@ethersproject/bytes': 5.7.0 72 | '@ethersproject/keccak256': 5.7.0 73 | '@ethersproject/logger': 5.7.0 74 | '@ethersproject/rlp': 5.7.0 75 | dev: false 76 | 77 | /@ethersproject/base64@5.7.0: 78 | resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} 79 | dependencies: 80 | '@ethersproject/bytes': 5.7.0 81 | dev: false 82 | 83 | /@ethersproject/basex@5.7.0: 84 | resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} 85 | dependencies: 86 | '@ethersproject/bytes': 5.7.0 87 | '@ethersproject/properties': 5.7.0 88 | dev: false 89 | 90 | /@ethersproject/bignumber@5.7.0: 91 | resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} 92 | dependencies: 93 | '@ethersproject/bytes': 5.7.0 94 | '@ethersproject/logger': 5.7.0 95 | bn.js: 5.2.1 96 | dev: false 97 | 98 | /@ethersproject/bytes@5.7.0: 99 | resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} 100 | dependencies: 101 | '@ethersproject/logger': 5.7.0 102 | dev: false 103 | 104 | /@ethersproject/constants@5.7.0: 105 | resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} 106 | dependencies: 107 | '@ethersproject/bignumber': 5.7.0 108 | dev: false 109 | 110 | /@ethersproject/contracts@5.7.0: 111 | resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} 112 | dependencies: 113 | '@ethersproject/abi': 5.7.0 114 | '@ethersproject/abstract-provider': 5.7.0 115 | '@ethersproject/abstract-signer': 5.7.0 116 | '@ethersproject/address': 5.7.0 117 | '@ethersproject/bignumber': 5.7.0 118 | '@ethersproject/bytes': 5.7.0 119 | '@ethersproject/constants': 5.7.0 120 | '@ethersproject/logger': 5.7.0 121 | '@ethersproject/properties': 5.7.0 122 | '@ethersproject/transactions': 5.7.0 123 | dev: false 124 | 125 | /@ethersproject/hash@5.7.0: 126 | resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} 127 | dependencies: 128 | '@ethersproject/abstract-signer': 5.7.0 129 | '@ethersproject/address': 5.7.0 130 | '@ethersproject/base64': 5.7.0 131 | '@ethersproject/bignumber': 5.7.0 132 | '@ethersproject/bytes': 5.7.0 133 | '@ethersproject/keccak256': 5.7.0 134 | '@ethersproject/logger': 5.7.0 135 | '@ethersproject/properties': 5.7.0 136 | '@ethersproject/strings': 5.7.0 137 | dev: false 138 | 139 | /@ethersproject/hdnode@5.7.0: 140 | resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} 141 | dependencies: 142 | '@ethersproject/abstract-signer': 5.7.0 143 | '@ethersproject/basex': 5.7.0 144 | '@ethersproject/bignumber': 5.7.0 145 | '@ethersproject/bytes': 5.7.0 146 | '@ethersproject/logger': 5.7.0 147 | '@ethersproject/pbkdf2': 5.7.0 148 | '@ethersproject/properties': 5.7.0 149 | '@ethersproject/sha2': 5.7.0 150 | '@ethersproject/signing-key': 5.7.0 151 | '@ethersproject/strings': 5.7.0 152 | '@ethersproject/transactions': 5.7.0 153 | '@ethersproject/wordlists': 5.7.0 154 | dev: false 155 | 156 | /@ethersproject/json-wallets@5.7.0: 157 | resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} 158 | dependencies: 159 | '@ethersproject/abstract-signer': 5.7.0 160 | '@ethersproject/address': 5.7.0 161 | '@ethersproject/bytes': 5.7.0 162 | '@ethersproject/hdnode': 5.7.0 163 | '@ethersproject/keccak256': 5.7.0 164 | '@ethersproject/logger': 5.7.0 165 | '@ethersproject/pbkdf2': 5.7.0 166 | '@ethersproject/properties': 5.7.0 167 | '@ethersproject/random': 5.7.0 168 | '@ethersproject/strings': 5.7.0 169 | '@ethersproject/transactions': 5.7.0 170 | aes-js: 3.0.0 171 | scrypt-js: 3.0.1 172 | dev: false 173 | 174 | /@ethersproject/keccak256@5.7.0: 175 | resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} 176 | dependencies: 177 | '@ethersproject/bytes': 5.7.0 178 | js-sha3: 0.8.0 179 | dev: false 180 | 181 | /@ethersproject/logger@5.7.0: 182 | resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} 183 | dev: false 184 | 185 | /@ethersproject/networks@5.7.1: 186 | resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} 187 | dependencies: 188 | '@ethersproject/logger': 5.7.0 189 | dev: false 190 | 191 | /@ethersproject/pbkdf2@5.7.0: 192 | resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} 193 | dependencies: 194 | '@ethersproject/bytes': 5.7.0 195 | '@ethersproject/sha2': 5.7.0 196 | dev: false 197 | 198 | /@ethersproject/properties@5.7.0: 199 | resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} 200 | dependencies: 201 | '@ethersproject/logger': 5.7.0 202 | dev: false 203 | 204 | /@ethersproject/providers@5.7.2: 205 | resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==} 206 | dependencies: 207 | '@ethersproject/abstract-provider': 5.7.0 208 | '@ethersproject/abstract-signer': 5.7.0 209 | '@ethersproject/address': 5.7.0 210 | '@ethersproject/base64': 5.7.0 211 | '@ethersproject/basex': 5.7.0 212 | '@ethersproject/bignumber': 5.7.0 213 | '@ethersproject/bytes': 5.7.0 214 | '@ethersproject/constants': 5.7.0 215 | '@ethersproject/hash': 5.7.0 216 | '@ethersproject/logger': 5.7.0 217 | '@ethersproject/networks': 5.7.1 218 | '@ethersproject/properties': 5.7.0 219 | '@ethersproject/random': 5.7.0 220 | '@ethersproject/rlp': 5.7.0 221 | '@ethersproject/sha2': 5.7.0 222 | '@ethersproject/strings': 5.7.0 223 | '@ethersproject/transactions': 5.7.0 224 | '@ethersproject/web': 5.7.1 225 | bech32: 1.1.4 226 | ws: 7.4.6 227 | transitivePeerDependencies: 228 | - bufferutil 229 | - utf-8-validate 230 | dev: false 231 | 232 | /@ethersproject/random@5.7.0: 233 | resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} 234 | dependencies: 235 | '@ethersproject/bytes': 5.7.0 236 | '@ethersproject/logger': 5.7.0 237 | dev: false 238 | 239 | /@ethersproject/rlp@5.7.0: 240 | resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} 241 | dependencies: 242 | '@ethersproject/bytes': 5.7.0 243 | '@ethersproject/logger': 5.7.0 244 | dev: false 245 | 246 | /@ethersproject/sha2@5.7.0: 247 | resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} 248 | dependencies: 249 | '@ethersproject/bytes': 5.7.0 250 | '@ethersproject/logger': 5.7.0 251 | hash.js: 1.1.7 252 | dev: false 253 | 254 | /@ethersproject/signing-key@5.7.0: 255 | resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} 256 | dependencies: 257 | '@ethersproject/bytes': 5.7.0 258 | '@ethersproject/logger': 5.7.0 259 | '@ethersproject/properties': 5.7.0 260 | bn.js: 5.2.1 261 | elliptic: 6.5.4 262 | hash.js: 1.1.7 263 | dev: false 264 | 265 | /@ethersproject/solidity@5.7.0: 266 | resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} 267 | dependencies: 268 | '@ethersproject/bignumber': 5.7.0 269 | '@ethersproject/bytes': 5.7.0 270 | '@ethersproject/keccak256': 5.7.0 271 | '@ethersproject/logger': 5.7.0 272 | '@ethersproject/sha2': 5.7.0 273 | '@ethersproject/strings': 5.7.0 274 | dev: false 275 | 276 | /@ethersproject/strings@5.7.0: 277 | resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} 278 | dependencies: 279 | '@ethersproject/bytes': 5.7.0 280 | '@ethersproject/constants': 5.7.0 281 | '@ethersproject/logger': 5.7.0 282 | dev: false 283 | 284 | /@ethersproject/transactions@5.7.0: 285 | resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} 286 | dependencies: 287 | '@ethersproject/address': 5.7.0 288 | '@ethersproject/bignumber': 5.7.0 289 | '@ethersproject/bytes': 5.7.0 290 | '@ethersproject/constants': 5.7.0 291 | '@ethersproject/keccak256': 5.7.0 292 | '@ethersproject/logger': 5.7.0 293 | '@ethersproject/properties': 5.7.0 294 | '@ethersproject/rlp': 5.7.0 295 | '@ethersproject/signing-key': 5.7.0 296 | dev: false 297 | 298 | /@ethersproject/units@5.7.0: 299 | resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} 300 | dependencies: 301 | '@ethersproject/bignumber': 5.7.0 302 | '@ethersproject/constants': 5.7.0 303 | '@ethersproject/logger': 5.7.0 304 | dev: false 305 | 306 | /@ethersproject/wallet@5.7.0: 307 | resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} 308 | dependencies: 309 | '@ethersproject/abstract-provider': 5.7.0 310 | '@ethersproject/abstract-signer': 5.7.0 311 | '@ethersproject/address': 5.7.0 312 | '@ethersproject/bignumber': 5.7.0 313 | '@ethersproject/bytes': 5.7.0 314 | '@ethersproject/hash': 5.7.0 315 | '@ethersproject/hdnode': 5.7.0 316 | '@ethersproject/json-wallets': 5.7.0 317 | '@ethersproject/keccak256': 5.7.0 318 | '@ethersproject/logger': 5.7.0 319 | '@ethersproject/properties': 5.7.0 320 | '@ethersproject/random': 5.7.0 321 | '@ethersproject/signing-key': 5.7.0 322 | '@ethersproject/transactions': 5.7.0 323 | '@ethersproject/wordlists': 5.7.0 324 | dev: false 325 | 326 | /@ethersproject/web@5.7.1: 327 | resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} 328 | dependencies: 329 | '@ethersproject/base64': 5.7.0 330 | '@ethersproject/bytes': 5.7.0 331 | '@ethersproject/logger': 5.7.0 332 | '@ethersproject/properties': 5.7.0 333 | '@ethersproject/strings': 5.7.0 334 | dev: false 335 | 336 | /@ethersproject/wordlists@5.7.0: 337 | resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} 338 | dependencies: 339 | '@ethersproject/bytes': 5.7.0 340 | '@ethersproject/hash': 5.7.0 341 | '@ethersproject/logger': 5.7.0 342 | '@ethersproject/properties': 5.7.0 343 | '@ethersproject/strings': 5.7.0 344 | dev: false 345 | 346 | /@swc-node/core@1.10.3(@swc/core@1.3.65): 347 | resolution: {integrity: sha512-8rpv1DXzsQjN/C8ZXuaTSmJ4M/lRr6geUlbOQ861DLC+sKWcEEvxRjK9cXQ28GserHuEcFDA3wlF9rD1YD0x+Q==} 348 | engines: {node: '>= 10'} 349 | peerDependencies: 350 | '@swc/core': '>= 1.3' 351 | dependencies: 352 | '@swc/core': 1.3.65 353 | dev: true 354 | 355 | /@swc-node/register@1.6.5(@swc/core@1.3.65)(typescript@5.1.3): 356 | resolution: {integrity: sha512-yMxXlzthI0aMadYYKDhx7xvtjljB1qoD8Tv0djqSJ1ttTkoDxg6MhG5A5pIahiUT2neVrkWb9lCavoUwXAe/zQ==} 357 | peerDependencies: 358 | '@swc/core': '>= 1.3' 359 | typescript: '>= 4.3' 360 | dependencies: 361 | '@swc-node/core': 1.10.3(@swc/core@1.3.65) 362 | '@swc-node/sourcemap-support': 0.3.0 363 | '@swc/core': 1.3.65 364 | colorette: 2.0.20 365 | debug: 4.3.4 366 | pirates: 4.0.5 367 | tslib: 2.5.3 368 | typescript: 5.1.3 369 | transitivePeerDependencies: 370 | - supports-color 371 | dev: true 372 | 373 | /@swc-node/sourcemap-support@0.3.0: 374 | resolution: {integrity: sha512-gqBJSmJMWomZFxlppaKea7NeAqFrDrrS0RMt24No92M3nJWcyI9YKGEQKl+EyJqZ5gh6w1s0cTklMHMzRwA1NA==} 375 | dependencies: 376 | source-map-support: 0.5.21 377 | tslib: 2.5.3 378 | dev: true 379 | 380 | /@swc/core-darwin-arm64@1.3.65: 381 | resolution: {integrity: sha512-fQIXZgr7CD/+1ADqrVbz/gHvSoIMmggHvPzguQjV8FggBuS9Efm1D1ZrdUSqptggKvuLLHMZf+49tENq8NWWcg==} 382 | engines: {node: '>=10'} 383 | cpu: [arm64] 384 | os: [darwin] 385 | requiresBuild: true 386 | dev: true 387 | optional: true 388 | 389 | /@swc/core-darwin-x64@1.3.65: 390 | resolution: {integrity: sha512-kGuWP7OP9mwOiIcJpEVa+ydC3Wxf0fPQ1MK0hUIPFcR6tAUEdOvdAuCzP6U20RX/JbbgwfI/Qq6ugT7VL6omgg==} 391 | engines: {node: '>=10'} 392 | cpu: [x64] 393 | os: [darwin] 394 | requiresBuild: true 395 | dev: true 396 | optional: true 397 | 398 | /@swc/core-linux-arm-gnueabihf@1.3.65: 399 | resolution: {integrity: sha512-Bjbzldp8n4mWSdAvBt4VuLiHlfFM5pyftjJvJnmSY4H1IzbxkByyT60OHOedcIPRiZveD8NJzUJqutqrgTmtLg==} 400 | engines: {node: '>=10'} 401 | cpu: [arm] 402 | os: [linux] 403 | requiresBuild: true 404 | dev: true 405 | optional: true 406 | 407 | /@swc/core-linux-arm64-gnu@1.3.65: 408 | resolution: {integrity: sha512-GmxtcCymeQqEqT9n5mo857koRsUbEwmuijrBA4OeD5KOPW9gqAmUxr+ZgwgYHwyJ3CiN+UbK8uEqPsL6UVQmLg==} 409 | engines: {node: '>=10'} 410 | cpu: [arm64] 411 | os: [linux] 412 | requiresBuild: true 413 | dev: true 414 | optional: true 415 | 416 | /@swc/core-linux-arm64-musl@1.3.65: 417 | resolution: {integrity: sha512-yv9jP3gbfMsYrqswT2MwK5Q1+avSwRXAKo+LYUknTeoLQNNlukDfqSLHajNq23XrVDRP4B3Pjn7kaqjxRcihbg==} 418 | engines: {node: '>=10'} 419 | cpu: [arm64] 420 | os: [linux] 421 | requiresBuild: true 422 | dev: true 423 | optional: true 424 | 425 | /@swc/core-linux-x64-gnu@1.3.65: 426 | resolution: {integrity: sha512-GQkwysEPTlAOQ3jiTiedObzh6pBaf9RLaQqpGdCp+iKze9+BR+STBP0IIKhZDMPG/nWWNhrYFD/VMQxRoYPjfw==} 427 | engines: {node: '>=10'} 428 | cpu: [x64] 429 | os: [linux] 430 | requiresBuild: true 431 | dev: true 432 | optional: true 433 | 434 | /@swc/core-linux-x64-musl@1.3.65: 435 | resolution: {integrity: sha512-ETzhOhtDluYFK4x73OTM9gVTMyzGd2WeWGlCu3WoT1EPPUwCqQpcAqI3TfEcP1ljFDG0pPkpYzVpwNf8yjQElg==} 436 | engines: {node: '>=10'} 437 | cpu: [x64] 438 | os: [linux] 439 | requiresBuild: true 440 | dev: true 441 | optional: true 442 | 443 | /@swc/core-win32-arm64-msvc@1.3.65: 444 | resolution: {integrity: sha512-3weD0I6F8bggN0KOnbZkvYC1PBrT5wrvohpvtgijRsODxjoWwztozjawJxF3rqgVqlSI/+nA+JkrN48e2cxJjQ==} 445 | engines: {node: '>=10'} 446 | cpu: [arm64] 447 | os: [win32] 448 | requiresBuild: true 449 | dev: true 450 | optional: true 451 | 452 | /@swc/core-win32-ia32-msvc@1.3.65: 453 | resolution: {integrity: sha512-i6c3D7E9Ca41HteW3+hn1OKQfjIabc2P0p1mJRXBkn+igwb+Ba6gXJc7NqhrlF8uZsDhhcGZTsAqBBtfcfTuHQ==} 454 | engines: {node: '>=10'} 455 | cpu: [ia32] 456 | os: [win32] 457 | requiresBuild: true 458 | dev: true 459 | optional: true 460 | 461 | /@swc/core-win32-x64-msvc@1.3.65: 462 | resolution: {integrity: sha512-tQ9hEDtwPZxQ2sYb2n8ypfmdMjobKAf6VSnChteLMktofU7o562op5pLS6D6QCP2AtL3lcwe1piTCgIhk4vmjA==} 463 | engines: {node: '>=10'} 464 | cpu: [x64] 465 | os: [win32] 466 | requiresBuild: true 467 | dev: true 468 | optional: true 469 | 470 | /@swc/core@1.3.65: 471 | resolution: {integrity: sha512-d5iDiKWf12FBo6h9Fro2pcnLK6HSPbyZ7A1U5iFNpRRx8XEd4uGdKtf5NoXJ3GDLQDLXnNSLA82Cl6SfrJ1lyw==} 472 | engines: {node: '>=10'} 473 | requiresBuild: true 474 | peerDependencies: 475 | '@swc/helpers': ^0.5.0 476 | peerDependenciesMeta: 477 | '@swc/helpers': 478 | optional: true 479 | optionalDependencies: 480 | '@swc/core-darwin-arm64': 1.3.65 481 | '@swc/core-darwin-x64': 1.3.65 482 | '@swc/core-linux-arm-gnueabihf': 1.3.65 483 | '@swc/core-linux-arm64-gnu': 1.3.65 484 | '@swc/core-linux-arm64-musl': 1.3.65 485 | '@swc/core-linux-x64-gnu': 1.3.65 486 | '@swc/core-linux-x64-musl': 1.3.65 487 | '@swc/core-win32-arm64-msvc': 1.3.65 488 | '@swc/core-win32-ia32-msvc': 1.3.65 489 | '@swc/core-win32-x64-msvc': 1.3.65 490 | dev: true 491 | 492 | /@types/node@20.3.1: 493 | resolution: {integrity: sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==} 494 | dev: true 495 | 496 | /aes-js@3.0.0: 497 | resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} 498 | dev: false 499 | 500 | /asynckit@0.4.0: 501 | resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} 502 | dev: false 503 | 504 | /axios@1.4.0: 505 | resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} 506 | dependencies: 507 | follow-redirects: 1.15.2 508 | form-data: 4.0.0 509 | proxy-from-env: 1.1.0 510 | transitivePeerDependencies: 511 | - debug 512 | dev: false 513 | 514 | /bech32@1.1.4: 515 | resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} 516 | dev: false 517 | 518 | /bn.js@4.12.0: 519 | resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} 520 | dev: false 521 | 522 | /bn.js@5.2.1: 523 | resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} 524 | dev: false 525 | 526 | /brorand@1.1.0: 527 | resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} 528 | dev: false 529 | 530 | /buffer-from@1.1.2: 531 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 532 | dev: true 533 | 534 | /colorette@2.0.20: 535 | resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} 536 | dev: true 537 | 538 | /combined-stream@1.0.8: 539 | resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} 540 | engines: {node: '>= 0.8'} 541 | dependencies: 542 | delayed-stream: 1.0.0 543 | dev: false 544 | 545 | /debug@4.3.4: 546 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 547 | engines: {node: '>=6.0'} 548 | peerDependencies: 549 | supports-color: '*' 550 | peerDependenciesMeta: 551 | supports-color: 552 | optional: true 553 | dependencies: 554 | ms: 2.1.2 555 | dev: true 556 | 557 | /delayed-stream@1.0.0: 558 | resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} 559 | engines: {node: '>=0.4.0'} 560 | dev: false 561 | 562 | /elliptic@6.5.4: 563 | resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} 564 | dependencies: 565 | bn.js: 4.12.0 566 | brorand: 1.1.0 567 | hash.js: 1.1.7 568 | hmac-drbg: 1.0.1 569 | inherits: 2.0.4 570 | minimalistic-assert: 1.0.1 571 | minimalistic-crypto-utils: 1.0.1 572 | dev: false 573 | 574 | /ethers@5.7.2: 575 | resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==} 576 | dependencies: 577 | '@ethersproject/abi': 5.7.0 578 | '@ethersproject/abstract-provider': 5.7.0 579 | '@ethersproject/abstract-signer': 5.7.0 580 | '@ethersproject/address': 5.7.0 581 | '@ethersproject/base64': 5.7.0 582 | '@ethersproject/basex': 5.7.0 583 | '@ethersproject/bignumber': 5.7.0 584 | '@ethersproject/bytes': 5.7.0 585 | '@ethersproject/constants': 5.7.0 586 | '@ethersproject/contracts': 5.7.0 587 | '@ethersproject/hash': 5.7.0 588 | '@ethersproject/hdnode': 5.7.0 589 | '@ethersproject/json-wallets': 5.7.0 590 | '@ethersproject/keccak256': 5.7.0 591 | '@ethersproject/logger': 5.7.0 592 | '@ethersproject/networks': 5.7.1 593 | '@ethersproject/pbkdf2': 5.7.0 594 | '@ethersproject/properties': 5.7.0 595 | '@ethersproject/providers': 5.7.2 596 | '@ethersproject/random': 5.7.0 597 | '@ethersproject/rlp': 5.7.0 598 | '@ethersproject/sha2': 5.7.0 599 | '@ethersproject/signing-key': 5.7.0 600 | '@ethersproject/solidity': 5.7.0 601 | '@ethersproject/strings': 5.7.0 602 | '@ethersproject/transactions': 5.7.0 603 | '@ethersproject/units': 5.7.0 604 | '@ethersproject/wallet': 5.7.0 605 | '@ethersproject/web': 5.7.1 606 | '@ethersproject/wordlists': 5.7.0 607 | transitivePeerDependencies: 608 | - bufferutil 609 | - utf-8-validate 610 | dev: false 611 | 612 | /follow-redirects@1.15.2: 613 | resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} 614 | engines: {node: '>=4.0'} 615 | peerDependencies: 616 | debug: '*' 617 | peerDependenciesMeta: 618 | debug: 619 | optional: true 620 | dev: false 621 | 622 | /form-data@4.0.0: 623 | resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} 624 | engines: {node: '>= 6'} 625 | dependencies: 626 | asynckit: 0.4.0 627 | combined-stream: 1.0.8 628 | mime-types: 2.1.35 629 | dev: false 630 | 631 | /hash.js@1.1.7: 632 | resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} 633 | dependencies: 634 | inherits: 2.0.4 635 | minimalistic-assert: 1.0.1 636 | dev: false 637 | 638 | /hmac-drbg@1.0.1: 639 | resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} 640 | dependencies: 641 | hash.js: 1.1.7 642 | minimalistic-assert: 1.0.1 643 | minimalistic-crypto-utils: 1.0.1 644 | dev: false 645 | 646 | /inherits@2.0.4: 647 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 648 | dev: false 649 | 650 | /js-sha3@0.8.0: 651 | resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} 652 | dev: false 653 | 654 | /keccak@3.0.3: 655 | resolution: {integrity: sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==} 656 | engines: {node: '>=10.0.0'} 657 | requiresBuild: true 658 | dependencies: 659 | node-addon-api: 2.0.2 660 | node-gyp-build: 4.6.0 661 | readable-stream: 3.6.2 662 | dev: false 663 | 664 | /mime-db@1.52.0: 665 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 666 | engines: {node: '>= 0.6'} 667 | dev: false 668 | 669 | /mime-types@2.1.35: 670 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 671 | engines: {node: '>= 0.6'} 672 | dependencies: 673 | mime-db: 1.52.0 674 | dev: false 675 | 676 | /minimalistic-assert@1.0.1: 677 | resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} 678 | dev: false 679 | 680 | /minimalistic-crypto-utils@1.0.1: 681 | resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} 682 | dev: false 683 | 684 | /ms@2.1.2: 685 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 686 | dev: true 687 | 688 | /node-addon-api@2.0.2: 689 | resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} 690 | dev: false 691 | 692 | /node-gyp-build@4.6.0: 693 | resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} 694 | hasBin: true 695 | dev: false 696 | 697 | /pirates@4.0.5: 698 | resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} 699 | engines: {node: '>= 6'} 700 | dev: true 701 | 702 | /proxy-from-env@1.1.0: 703 | resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} 704 | dev: false 705 | 706 | /readable-stream@3.6.2: 707 | resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} 708 | engines: {node: '>= 6'} 709 | dependencies: 710 | inherits: 2.0.4 711 | string_decoder: 1.3.0 712 | util-deprecate: 1.0.2 713 | dev: false 714 | 715 | /safe-buffer@5.2.1: 716 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 717 | dev: false 718 | 719 | /scrypt-js@3.0.1: 720 | resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} 721 | dev: false 722 | 723 | /source-map-support@0.5.21: 724 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 725 | dependencies: 726 | buffer-from: 1.1.2 727 | source-map: 0.6.1 728 | dev: true 729 | 730 | /source-map@0.6.1: 731 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 732 | engines: {node: '>=0.10.0'} 733 | dev: true 734 | 735 | /string_decoder@1.3.0: 736 | resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 737 | dependencies: 738 | safe-buffer: 5.2.1 739 | dev: false 740 | 741 | /tslib@2.5.3: 742 | resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} 743 | dev: true 744 | 745 | /typescript@5.1.3: 746 | resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==} 747 | engines: {node: '>=14.17'} 748 | hasBin: true 749 | dev: true 750 | 751 | /util-deprecate@1.0.2: 752 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 753 | dev: false 754 | 755 | /ws@7.4.6: 756 | resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} 757 | engines: {node: '>=8.3.0'} 758 | peerDependencies: 759 | bufferutil: ^4.0.1 760 | utf-8-validate: ^5.0.2 761 | peerDependenciesMeta: 762 | bufferutil: 763 | optional: true 764 | utf-8-validate: 765 | optional: true 766 | dev: false 767 | --------------------------------------------------------------------------------