Skill: miyeon9057/moria-skill (version 1.0.0)

--- name: Moria Skill description: 此技能包括了 Web3 钱包管理功能。Agent 可以通过此技能 管理 Moria.fun 中的代币数据，包括 创建、铸造、交易、退款、领取，以及充值、查询余额。 read_when: - 用户 想 创建、铸造、买卖、退款、领取 - 用户 想 知道 moria 相关的信息 --- # Moria Skill 此技能提供 Moria.fun 管理功能。它旨在供 OpenClaw 代理使用，以编程方式执行代币相关任务（创建、铸造、交易、退款、领取手续费）。 ## 首次运行 _检查当前技能目录中是否存在 `node_modules` 与 `config` 文件夹。_ **如果没有：** 请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 完成初始化。 ## 技能介绍 以下所有命令是**提供给Agent使用的，不允许将命令展示给用户。** 与用户确认清楚意图后直接使用命令。 命令的可选参数，用户如果没提供，默认不二次询问。 ### 核心功能 1. **代币管理**：创建(代币)、列出列表（代币）。 2. **交易管理**：铸造(代币)、买入(代币)、卖出(代币)、退款(代币)。 3. **领取管理**：领取手续费(代币)、领取(代币)。 4. **钱包管理**：充值、查询余额、提现。 --- ## 🛠️ 使用说明（Agent） ### 1. 代币管理 | Action | Command | Arguments | Notes | | :--- | :--- | :--- | :--- | | **列出 可铸造的代币** | `npm run pool:mintto` | None | 列出可铸造的代币列表，方便后续进行代币铸造 | | **列出 可交易的代币** | `npm run pool:dammv2` | None | 列出可交易的代币列表，方便后续进行代币买卖 | | **创建 可铸造的代币** | `npm run pool:create <image_path> <name> <symbol> [description] [twitter] [telegram]` | `<image_path>`: 代币LOGO在本机路径<br>`<name>`: 代币名称<br>`<symbol>`: 代币符号<br>`<description>`: 代币描述<br>`<twitter>`: Twitter/X 联系方式<br>`<telegram>`: Telegram 联系方式 | 创建一个新代币 | ### 2. 交易管理 | Action | Command | Arguments | Notes | | :--- | :--- | :--- | :--- | | **买入 代币** | `npm run trade:buy <mint> <uiAmount>` | `<mint>`: 代币地址<br>`<uiAmount>`: 购买数量(单位：sol，例 0.1) | 买入指定数量的代币 | | **卖出 代币** | `npm run trade:sell <mint> <uiAmount>` | `<mint>`: 代币地址<br>`<uiAmount>`: 卖出数量(单位：个，例 8.1) | 卖出指定数量的代币 | ### 3. 交换管理 | **铸造 代币** | `npm run swap:mintto <mint> <copies>` | `<mint>`: 代币地址<br>`<copies>`: 购买份数(单位：份，例 3 份) | 铸造指定份数的代币 | | **退款 代币** | `npm run swap:refund <mint>` | `<mint>`: 代币地址 | 退款指定代币 | ### 4. 领取管理 | Action | Command | Arguments | Notes | | :--- | :--- | :--- | :--- | | **领取 手续费** | `npm run claim:fee <mint>` | `<mint>`: 代币地址 | 作为代币创作者领取手续费 | | **领取 代币** | `npm run claim:token <mint>` | `<mint>`: 代币地址 | 作为代币持有者在代币添加流动性后领取取回代币 | ### 5. 钱包管理 | Action | Command | Arguments | Notes | | :--- | :--- | :--- | :--- | | **查看 公钥** | `npm run wallet:show` | None | 查询钱包公钥 | | **查询 sol余额** | `npm run wallet:sol` | None | 查询当前持有的sol数量 | | **查询 代币余额** | `npm run wallet:tokens` | None | 查询当前持有的代币数量 | | **列出 我铸造的代币** | `npm run wallet:mintto` | None | 列出我铸造的代币列表，方便后续进行代币铸造或退款 | | **列出 我创建的代币** | `npm run wallet:created` | None | 列出我创建的代币列表，方便后续进行代币铸造或买卖 | | **显示 充值二维码** | `npm run wallet:deposit` | None | 查看充值二维码，方便用户充值到我的钱包 | --- ## 💡 工作流程示例 ### 场景 1：用户想要创建代币 检查当前钱包是否有足够的sol。 运行命令： ```bash npm run wallet:sol ``` _Example:_ ```bash npm run wallet:sol ``` **如果sol 小于 0.2 sol：** 提示用户充值 > “当前钱包余额不足。 您需要充值 0.2 SOL 以上。” **如果sol充足:** 请用户提供代币LOGO、代币名称、代币符号、代币描述等： > “创建代币需要提供以下信息：代币LOGO、代币名称、代币符号、代币描述、Twitter/X联系方式、Telegram联系方式。 您有吗？” **用户上传了图片，并提供了代币名称(name)、代币符号(symbol):** _使用用户上传的图片作为代币LOGO。_ 运行命令： ```bash npm run pool:create <image_path> <name> <symbol> [description] [twitter] [telegram] ``` _Example:_ ```bash npm run pool:create -- "/home/node/.openclaw/media/inbound/xxx.png" "name" "symbol" "" "" "" ``` **用户上传了图片，并提供了代币名称(name)、代币符号(symbol)、代币描述(description)、Twitter/X联系方式(twitter)、Telegram联系方式(telegram):** 运行命令： ```bash npm run pool:create <image_path> <name> <symbol> [description] [twitter] [telegram] ``` _Example:_ ```bash npm run pool:create -- "/home/node/.openclaw/media/inbound/xxx.png" "name" "symbol" "description" "twitter" "telegram" ``` ### 场景 2：用户想要铸造代币 检查当前钱包是否有足够的sol。 运行命令： ```bash npm run wallet:sol ``` _Example:_ ```bash npm run wallet:sol ``` **如果sol 小于 0.2 sol：** 提示用户充值 > “当前钱包余额不足。 您需要充值 0.2 SOL 以上。” **用户输入了代币地址(mint)与份数(copies):** 运行命令： ```bash npm run swap:mintto <mint> <copies> ``` _Example:_ ```bash npm run swap:mintto -- xxxxx 2 ``` **用户未输入代币地址(mint)与份数(copies):** 运行命令： ```bash npm run pool:mintto ``` _Example:_ ```bash npm run pool:mintto ``` 请用户输入想要买入的代币地址与份数(copies)： > “要买入的代币地址是？买入多少份？” **如果他们提供了代币地址(mint)与份数(copies)：** 运行命令： ```bash npm run swap:mintto <mint> <copies> ``` _Example:_ ```bash npm run swap:mintto -- xxxxx 2 ``` ### 场景 3：用户想要退款代币 **用户输入了代币地址(mint):** 运行命令： ```bash npm run swap:refund <mint> ``` _Example:_ ```bash npm run swap:refund -- xxxxx ``` **用户未输入代币地址(mint):** 运行命令： ```bash npm run wallet:mintto ``` _Example:_ ```bash npm run wallet:mintto ``` 请用户确认退款的代币： > “您想退款哪个代币呢？” **用户输入了代币地址(mint):** 运行命令： ```bash npm run swal:refund <mint> ``` _Example:_ ```bash npm run swal:refund xxxxx ``` ### 场景 4：用户想要买入代币 检查当前钱包是否有足够的sol。 运行命令： ```bash npm run wallet:sol ``` _Example:_ ```bash npm run wallet:sol ``` **如果sol 小于 0.2 sol：** 提示用户充值 > “当前钱包余额不足。 您需要充值 0.2 SOL 以上。” **用户输入了代币地址(mint)与金额(uiAmount):** 运行命令： ```bash npm run swap:buy <mint> <uiAmount> ``` _Example:_ ```bash npm run swap:buy -- xxxxx 0.02 ``` **用户未输入代币地址(mint)与金额(uiAmount):** 运行命令： ```bash npm run pool:dammv2 ``` _Example:_ ```bash npm run pool:dammv2 ``` 请用户输入想要买入的代币地址与金额： > “要买入的代币地址是？买入多少SOL？” **如果他们提供了代币地址(mint)与金额(uiAmount)：** 运行命令： ```bash npm run swap:buy <mint> <uiAmount> ``` _Example:_ ```bash npm run swap:buy -- xxxxx 0.02 ``` ### 场景 5：用户想要卖出代币 **用户输入了代币地址(mint)与金额(uiAmount):** 运行命令： ```bash npm run swap:sell <mint> <uiAmount> ``` _Example:_ ```bash npm run swap:sell -- xxxxx 2.2 ``` **用户未输入代币地址(mint)与金额(uiAmount):** 运行命令： ```bash npm run wallet:tokens ``` _Example:_ ```bash npm run wallet:tokens ``` 请用户确认卖出的代币： > “您想卖出哪个代币？卖出多少呢？” **用户输入了代币地址(mint)与金额(uiAmount):** 运行命令： ```bash npm run swal:sell <mint> <uiAmount> ``` _Example:_ ```bash npm run swal:sell xxxxx 2.2 ``` _在 web3 中 uiAmount 是人类可视化的金额，例如 0.02 SOL。amount 等于 lamports 是 1e0^9 * uiAmount。_ ### 场景 6：用户领取手续费（代币创建者） 检查当前钱包是否有足够的sol。 运行命令： ```bash npm run wallet:sol ``` _Example:_ ```bash npm run wallet:sol ``` **如果sol 小于 0.2 sol：** 提示用户充值 > “当前钱包余额不足。 您需要充值 0.2 SOL 以上。” **如果sol充足:** 运行命令： ```bash npm run wallet:created ``` _Example:_ ```bash npm run wallet:created ``` 请用户确认领取的代币： > “您想领取哪个代币的手续费呢？” **用户输入了代币地址(mint):** 运行命令： ```bash npm run claim:fee <mint> ``` _Example:_ ```bash npm run claim:fee xxxxx ``` ### 场景 7：用户领取代币（已添加流动性的代币） 检查当前钱包是否有足够的sol。 运行命令： ```bash npm run wallet:sol ``` _Example:_ ```bash npm run wallet:sol ``` **如果sol 小于 0.2 sol：** 提示用户充值 > “当前钱包余额不足。 您需要充值 0.2 SOL 以上。” **如果sol充足:** 运行命令： ```bash npm run wallet:mintto ``` _Example:_ ```bash npm run wallet:mintto ``` 请用户确认要取回的代币： > “您想领取哪个代币呢？” **用户输入了代币地址(mint):** 运行命令： ```bash npm run claim:token <mint> ``` _Example:_ ```bash npm run claim:token xxxxx ``` ### 场景 8：用户想要查询余额 运行命令： ```bash npm run wallet:sol ``` _Example:_ ```bash npm run wallet:sol ``` ### 场景 9：用户想要知道当前持有的 _哪些代币_ 或 _代币余额_ 运行命令： ```bash npm run wallet:tokens ``` _Example:_ ```bash npm run wallet:tokens ``` --- ## 安全性 此技能强制执行 OpenClaw 执行的安全约束。 ### 1. 敏感数据（严格保密） * **配置文件**：`config.json` 文件（包含令牌和账户信息）的完整内容**绝对禁止**公开。 ### 2. 禁止泄露策略 * **请勿**在聊天回复、日志、错误消息、屏幕截图或生成的文档中公开完整的 密钥、令牌或密钥。 * 如果调试需要参考信息，请仅使用**掩码值**（例如，`abc...xyz`）。 有关权威策略，请参阅 [references/security.md](references/security.md)。

path: pnpm-lock.yaml
content: lockfileVersion: '9.0'

settings:
  autoInstallPeers: true
  excludeLinksFromLockfile: false

importers:

  .:
    dependencies:
      '@coral-xyz/anchor':
        specifier: ^0.32.1
        version: 0.32.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@meteora-ag/cp-amm-sdk':
        specifier: ^1.3.9
        version: 1.4.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@moria/moria-sdk':
        specifier: ./lib/@moria/moria-sdk
        version: link:lib/@moria/moria-sdk
      '@solana/spl-token':
        specifier: ^0.4.9
        version: 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@solana/web3.js':
        specifier: ^1.98.0
        version: 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      bn.js:
        specifier: ^5.2.3
        version: 5.2.3
      bs58:
        specifier: ^6.0.0
        version: 6.0.0
      decimal.js:
        specifier: ^10.5.0
        version: 10.6.0
      json5:
        specifier: ^2.2.3
        version: 2.2.3
      qrcode:
        specifier: ^1.5.4
        version: 1.5.4
      tsx:
        specifier: ^4.21.0
        version: 4.21.0
      utf-8-validate:
        specifier: ^5.0.10
        version: 5.0.10
    devDependencies:
      '@types/bn.js':
        specifier: ^5.1.0
        version: 5.2.0
      '@types/bs58':
        specifier: ^4.0.4
        version: 4.0.4
      '@types/node':
        specifier: ^22.19.13
        version: 22.19.17
      '@types/qrcode':
        specifier: ^1.5.6
        version: 1.5.6
      typescript:
        specifier: ^5.9.3
        version: 5.9.3

packages:

  '@babel/runtime@7.29.2':
    resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
    engines: {node: '>=6.9.0'}

  '@coral-xyz/anchor-errors@0.31.1':
    resolution: {integrity: sha512-NhNEku4F3zzUSBtrYz84FzYWm48+9OvmT1Hhnwr6GnPQry2dsEqH/ti/7ASjjpoFTWRnPXrjAIT1qM6Isop+LQ==}
    engines: {node: '>=10'}

  '@coral-xyz/anchor@0.31.1':
    resolution: {integrity: sha512-QUqpoEK+gi2S6nlYc2atgT2r41TT3caWr/cPUEL8n8Md9437trZ68STknq897b82p5mW0XrTBNOzRbmIRJtfsA==}
    engines: {node: '>=17'}

  '@coral-xyz/anchor@0.32.1':
    resolution: {integrity: sha512-zAyxFtfeje2FbMA1wzgcdVs7Hng/MijPKpRijoySPCicnvcTQs/+dnPZ/cR+LcXM9v9UYSyW81uRNYZtN5G4yg==}
    engines: {node: '>=17'}

  '@coral-xyz/borsh@0.31.1':
    resolution: {integrity: sha512-9N8AU9F0ubriKfNE3g1WF0/4dtlGXoBN/hd1PvbNBamBNwRgHxH4P+o3Zt7rSEloW1HUs6LfZEchlx9fW7POYw==}
    engines: {node: '>=10'}
    peerDependencies:
      '@solana/web3.js': ^1.69.0

  '@esbuild/aix-ppc64@0.27.7':
    resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
    engines: {node: '>=18'}
    cpu: [ppc64]
    os: [aix]

  '@esbuild/android-arm64@0.27.7':
    resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [android]

  '@esbuild/android-arm@0.27.7':
    resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
    engines: {node: '>=18'}
    cpu: [arm]
    os: [android]

  '@esbuild/android-x64@0.27.7':
    resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [android]

  '@esbuild/darwin-arm64@0.27.7':
    resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [darwin]

  '@esbuild/darwin-x64@0.27.7':
    resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [darwin]

  '@esbuild/freebsd-arm64@0.27.7':
    resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [freebsd]

  '@esbuild/freebsd-x64@0.27.7':
    resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [freebsd]

  '@esbuild/linux-arm64@0.27.7':
    resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [linux]

  '@esbuild/linux-arm@0.27.7':
    resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
    engines: {node: '>=18'}
    cpu: [arm]
    os: [linux]

  '@esbuild/linux-ia32@0.27.7':
    resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
    engines: {node: '>=18'}
    cpu: [ia32]
    os: [linux]

  '@esbuild/linux-loong64@0.27.7':
    resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
    engines: {node: '>=18'}
    cpu: [loong64]
    os: [linux]

  '@esbuild/linux-mips64el@0.27.7':
    resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
    engines: {node: '>=18'}
    cpu: [mips64el]
    os: [linux]

  '@esbuild/linux-ppc64@0.27.7':
    resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
    engines: {node: '>=18'}
    cpu: [ppc64]
    os: [linux]

  '@esbuild/linux-riscv64@0.27.7':
    resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
    engines: {node: '>=18'}
    cpu: [riscv64]
    os: [linux]

  '@esbuild/linux-s390x@0.27.7':
    resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
    engines: {node: '>=18'}
    cpu: [s390x]
    os: [linux]

  '@esbuild/linux-x64@0.27.7':
    resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [linux]

  '@esbuild/netbsd-arm64@0.27.7':
    resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [netbsd]

  '@esbuild/netbsd-x64@0.27.7':
    resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [netbsd]

  '@esbuild/openbsd-arm64@0.27.7':
    resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [openbsd]

  '@esbuild/openbsd-x64@0.27.7':
    resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [openbsd]

  '@esbuild/openharmony-arm64@0.27.7':
    resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [openharmony]

  '@esbuild/sunos-x64@0.27.7':
    resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [sunos]

  '@esbuild/win32-arm64@0.27.7':
    resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
    engines: {node: '>=18'}
    cpu: [arm64]
    os: [win32]

  '@esbuild/win32-ia32@0.27.7':
    resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
    engines: {node: '>=18'}
    cpu: [ia32]
    os: [win32]

  '@esbuild/win32-x64@0.27.7':
    resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
    engines: {node: '>=18'}
    cpu: [x64]
    os: [win32]

  '@meteora-ag/cp-amm-sdk@1.4.1':
    resolution: {integrity: sha512-wdN9g8X6I6Rxk7VIg3XE1YrUAz4ETpRsVTg5kr8O+EwJ4uuz9gz0q4AlZbtCwQaeqRXztfdN77QfU6Tq+lalJQ==}

  '@noble/curves@1.9.7':
    resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==}
    engines: {node: ^14.21.3 || >=16}

  '@noble/hashes@1.8.0':
    resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
    engines: {node: ^14.21.3 || >=16}

  '@solana/buffer-layout-utils@0.2.0':
    resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==}
    engines: {node: '>= 10'}

  '@solana/buffer-layout@4.0.1':
    resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==}
    engines: {node: '>=5.10'}

  '@solana/codecs-core@2.0.0-rc.1':
    resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==}
    peerDependencies:
      typescript: '>=5'

  '@solana/codecs-core@2.3.0':
    resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==}
    engines: {node: '>=20.18.0'}
    peerDependencies:
      typescript: '>=5.3.3'

  '@solana/codecs-data-structures@2.0.0-rc.1':
    resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==}
    peerDependencies:
      typescript: '>=5'

  '@solana/codecs-numbers@2.0.0-rc.1':
    resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==}
    peerDependencies:
      typescript: '>=5'

  '@solana/codecs-numbers@2.3.0':
    resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==}
    engines: {node: '>=20.18.0'}
    peerDependencies:
      typescript: '>=5.3.3'

  '@solana/codecs-strings@2.0.0-rc.1':
    resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==}
    peerDependencies:
      fastestsmallesttextencoderdecoder: ^1.0.22
      typescript: '>=5'

  '@solana/codecs@2.0.0-rc.1':
    resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==}
    peerDependencies:
      typescript: '>=5'

  '@solana/errors@2.0.0-rc.1':
    resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==}
    hasBin: true
    peerDependencies:
      typescript: '>=5'

  '@solana/errors@2.3.0':
    resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==}
    engines: {node: '>=20.18.0'}
    hasBin: true
    peerDependencies:
      typescript: '>=5.3.3'

  '@solana/options@2.0.0-rc.1':
    resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==}
    peerDependencies:
      typescript: '>=5'

  '@solana/spl-token-group@0.0.7':
    resolution: {integrity: sha512-V1N/iX7Cr7H0uazWUT2uk27TMqlqedpXHRqqAbVO2gvmJyT0E0ummMEAVQeXZ05ZhQ/xF39DLSdBp90XebWEug==}
    engines: {node: '>=16'}
    peerDependencies:
      '@solana/web3.js': ^1.95.3

  '@solana/spl-token-metadata@0.1.6':
    resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==}
    engines: {node: '>=16'}
    peerDependencies:
      '@solana/web3.js': ^1.95.3

  '@solana/spl-token@0.4.14':
    resolution: {integrity: sha512-u09zr96UBpX4U685MnvQsNzlvw9TiY005hk1vJmJr7gMJldoPG1eYU5/wNEyOA5lkMLiR/gOi9SFD4MefOYEsA==}
    engines: {node: '>=16'}
    peerDependencies:
      '@solana/web3.js': ^1.95.5

  '@solana/web3.js@1.98.4':
    resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==}

  '@swc/helpers@0.5.21':
    resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==}

  '@types/bn.js@5.2.0':
    resolution: {integrity: sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==}

  '@types/bs58@4.0.4':
    resolution: {integrity: sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g==}

  '@types/connect@3.4.38':
    resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}

  '@types/node@12.20.55':
    resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}

  '@types/node@22.19.17':
    resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==}

  '@types/qrcode@1.5.6':
    resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}

  '@types/uuid@10.0.0':
    resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==}

  '@types/ws@7.4.7':
    resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==}

  '@types/ws@8.18.1':
    resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}

  agentkeepalive@4.6.0:
    resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
    engines: {node: '>= 8.0.0'}

  ansi-regex@5.0.1:
    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
    engines: {node: '>=8'}

  ansi-styles@4.3.0:
    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
    engines: {node: '>=8'}

  base-x@3.0.11:
    resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==}

  base-x@5.0.1:
    resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==}

  base64-js@1.5.1:
    resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}

  bigint-buffer@1.1.5:
    resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==}
    engines: {node: '>= 10.0.0'}

  bignumber.js@9.3.1:
    resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}

  bindings@1.5.0:
    resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}

  bn.js@5.2.3:
    resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==}

  borsh@0.7.0:
    resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==}

  bs58@4.0.1:
    resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==}

  bs58@6.0.0:
    resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==}

  buffer-layout@1.2.2:
    resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==}
    engines: {node: '>=4.5'}

  buffer@6.0.3:
    resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}

  bufferutil@4.1.0:
    resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==}
    engines: {node: '>=6.14.2'}

  camelcase@5.3.1:
    resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
    engines: {node: '>=6'}

  camelcase@6.3.0:
    resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
    engines: {node: '>=10'}

  chain@0.4.2:
    resolution: {integrity: sha512-GtM+TlN398yBhtSp1D2dBLQomKM3Umbji3h2/NdCqAWSMKhWbjlz33j0e55rStsEZD+8OLRHuz7kWd0U3xKMDg==}
    engines: {node: '>=18'}

  chalk@5.6.2:
    resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
    engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}

  cliui@6.0.0:
    resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}

  color-convert@2.0.1:
    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
    engines: {node: '>=7.0.0'}

  color-name@1.1.4:
    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}

  commander@12.1.0:
    resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
    engines: {node: '>=18'}

  commander@14.0.3:
    resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
    engines: {node: '>=20'}

  commander@2.20.3:
    resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}

  cross-fetch@3.2.0:
    resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==}

  decamelize@1.2.0:
    resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
    engines: {node: '>=0.10.0'}

  decimal.js@10.6.0:
    resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}

  delay@5.0.0:
    resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==}
    engines: {node: '>=10'}

  dijkstrajs@1.0.3:
    resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}

  emoji-regex@8.0.0:
    resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}

  es6-promise@4.2.8:
    resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==}

  es6-promisify@5.0.0:
    resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==}

  esbuild@0.27.7:
    resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
    engines: {node: '>=18'}
    hasBin: true

  eventemitter3@4.0.7:
    resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}

  eventemitter3@5.0.4:
    resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}

  eyes@0.1.8:
    resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==}
    engines: {node: '> 0.1.90'}

  fast-stable-stringify@1.0.0:
    resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==}

  fastestsmallesttextencoderdecoder@1.0.22:
    resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==}

  file-uri-to-path@1.0.0:
    resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}

  find-up@4.1.0:
    resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
    engines: {node: '>=8'}

  fsevents@2.3.3:
    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
    os: [darwin]

  get-caller-file@2.0.5:
    resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
    engines: {node: 6.* || 8.* || >= 10.*}

  get-tsconfig@4.14.0:
    resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}

  humanize-ms@1.2.1:
    resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}

  ieee754@1.2.1:
    resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}

  invariant@2.2.4:
    resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}

  is-fullwidth-code-point@3.0.0:
    resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
    engines: {node: '>=8'}

  isomorphic-ws@4.0.1:
    resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==}
    peerDependencies:
      ws: '*'

  jayson@4.3.0:
    resolution: {integrity: sha512-AauzHcUcqs8OBnCHOkJY280VaTiCm57AbuO7lqzcw7JapGj50BisE3xhksye4zlTSR1+1tAz67wLTl8tEH1obQ==}
    engines: {node: '>=8'}
    hasBin: true

  js-tokens@4.0.0:
    resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}

  json-stringify-safe@5.0.1:
    resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}

  json5@2.2.3:
    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
    engines: {node: '>=6'}
    hasBin: true

  locate-path@5.0.0:
    resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
    engines: {node: '>=8'}

  loose-envify@1.4.0:
    resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
    hasBin: true

  ms@2.1.3:
    resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}

  node-fetch@2.7.0:
    resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
    engines: {node: 4.x || >=6.0.0}
    peerDependencies:
      encoding: ^0.1.0
    peerDependenciesMeta:
      encoding:
        optional: true

  node-gyp-build@4.8.4:
    resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==}
    hasBin: true

  p-limit@2.3.0:
    resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
    engines: {node: '>=6'}

  p-locate@4.1.0:
    resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
    engines: {node: '>=8'}

  p-try@2.2.0:
    resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
    engines: {node: '>=6'}

  pako@2.1.0:
    resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}

  path-exists@4.0.0:
    resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
    engines: {node: '>=8'}

  pngjs@5.0.0:
    resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
    engines: {node: '>=10.13.0'}

  qrcode@1.5.4:
    resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
    engines: {node: '>=10.13.0'}
    hasBin: true

  require-directory@2.1.1:
    resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
    engines: {node: '>=0.10.0'}

  require-main-filename@2.0.0:
    resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}

  resolve-pkg-maps@1.0.0:
    resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}

  rpc-websockets@9.3.8:
    resolution: {integrity: sha512-7r+fm4tSJmLf9GvZfL1DJ1SJwpagpp6AazqM0FUaeV7CA+7+NYINSk1syWa4tU/6OF2CyBicLtzENGmXRJH6wQ==}

  safe-buffer@5.2.1:
    resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}

  set-blocking@2.0.0:
    resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}

  stream-chain@2.2.5:
    resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==}

  stream-json@1.9.1:
    resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==}

  string-width@4.2.3:
    resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
    engines: {node: '>=8'}

  strip-ansi@6.0.1:
    resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
    engines: {node: '>=8'}

  superstruct@0.15.5:
    resolution: {integrity: sha512-4AOeU+P5UuE/4nOUkmcQdW5y7i9ndt1cQd/3iUe+LTz3RxESf/W/5lg4B74HbDMMv8PHnPnGCQFH45kBcrQYoQ==}

  superstruct@2.0.2:
    resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==}
    engines: {node: '>=14.0.0'}

  text-encoding-utf-8@1.0.2:
    resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==}

  toml@3.0.0:
    resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}

  tr46@0.0.3:
    resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}

  tslib@2.8.1:
    resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}

  tsx@4.21.0:
    resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
    engines: {node: '>=18.0.0'}
    hasBin: true

  typescript@5.9.3:
    resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
    engines: {node: '>=14.17'}
    hasBin: true

  undici-types@6.21.0:
    resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}

  utf-8-validate@5.0.10:
    resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==}
    engines: {node: '>=6.14.2'}

  utf-8-validate@6.0.6:
    resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==}
    engines: {node: '>=6.14.2'}

  uuid@11.1.0:
    resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==}
    hasBin: true

  uuid@8.3.2:
    resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
    hasBin: true

  webidl-conversions@3.0.1:
    resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}

  whatwg-url@5.0.0:
    resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}

  which-module@2.0.1:
    resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}

  wrap-ansi@6.2.0:
    resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
    engines: {node: '>=8'}

  ws@7.5.10:
    resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==}
    engines: {node: '>=8.3.0'}
    peerDependencies:
      bufferutil: ^4.0.1
      utf-8-validate: ^5.0.2
    peerDependenciesMeta:
      bufferutil:
        optional: true
      utf-8-validate:
        optional: true

  ws@8.20.0:
    resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==}
    engines: {node: '>=10.0.0'}
    peerDependencies:
      bufferutil: ^4.0.1
      utf-8-validate: '>=5.0.2'
    peerDependenciesMeta:
      bufferutil:
        optional: true
      utf-8-validate:
        optional: true

  y18n@4.0.3:
    resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}

  yargs-parser@18.1.3:
    resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
    engines: {node: '>=6'}

  yargs@15.4.1:
    resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
    engines: {node: '>=8'}

snapshots:

  '@babel/runtime@7.29.2': {}

  '@coral-xyz/anchor-errors@0.31.1': {}

  '@coral-xyz/anchor@0.31.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)':
    dependencies:
      '@coral-xyz/anchor-errors': 0.31.1
      '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))
      '@noble/hashes': 1.8.0
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      bn.js: 5.2.3
      bs58: 4.0.1
      buffer-layout: 1.2.2
      camelcase: 6.3.0
      cross-fetch: 3.2.0
      eventemitter3: 4.0.7
      pako: 2.1.0
      superstruct: 0.15.5
      toml: 3.0.0
    transitivePeerDependencies:
      - bufferutil
      - encoding
      - typescript
      - utf-8-validate

  '@coral-xyz/anchor@0.32.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)':
    dependencies:
      '@coral-xyz/anchor-errors': 0.31.1
      '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))
      '@noble/hashes': 1.8.0
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      bn.js: 5.2.3
      bs58: 4.0.1
      buffer-layout: 1.2.2
      camelcase: 6.3.0
      cross-fetch: 3.2.0
      eventemitter3: 4.0.7
      pako: 2.1.0
      superstruct: 0.15.5
      toml: 3.0.0
    transitivePeerDependencies:
      - bufferutil
      - encoding
      - typescript
      - utf-8-validate

  '@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))':
    dependencies:
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      bn.js: 5.2.3
      buffer-layout: 1.2.2

  '@esbuild/aix-ppc64@0.27.7':
    optional: true

  '@esbuild/android-arm64@0.27.7':
    optional: true

  '@esbuild/android-arm@0.27.7':
    optional: true

  '@esbuild/android-x64@0.27.7':
    optional: true

  '@esbuild/darwin-arm64@0.27.7':
    optional: true

  '@esbuild/darwin-x64@0.27.7':
    optional: true

  '@esbuild/freebsd-arm64@0.27.7':
    optional: true

  '@esbuild/freebsd-x64@0.27.7':
    optional: true

  '@esbuild/linux-arm64@0.27.7':
    optional: true

  '@esbuild/linux-arm@0.27.7':
    optional: true

  '@esbuild/linux-ia32@0.27.7':
    optional: true

  '@esbuild/linux-loong64@0.27.7':
    optional: true

  '@esbuild/linux-mips64el@0.27.7':
    optional: true

  '@esbuild/linux-ppc64@0.27.7':
    optional: true

  '@esbuild/linux-riscv64@0.27.7':
    optional: true

  '@esbuild/linux-s390x@0.27.7':
    optional: true

  '@esbuild/linux-x64@0.27.7':
    optional: true

  '@esbuild/netbsd-arm64@0.27.7':
    optional: true

  '@esbuild/netbsd-x64@0.27.7':
    optional: true

  '@esbuild/openbsd-arm64@0.27.7':
    optional: true

  '@esbuild/openbsd-x64@0.27.7':
    optional: true

  '@esbuild/openharmony-arm64@0.27.7':
    optional: true

  '@esbuild/sunos-x64@0.27.7':
    optional: true

  '@esbuild/win32-arm64@0.27.7':
    optional: true

  '@esbuild/win32-ia32@0.27.7':
    optional: true

  '@esbuild/win32-x64@0.27.7':
    optional: true

  '@meteora-ag/cp-amm-sdk@1.4.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)':
    dependencies:
      '@coral-xyz/anchor': 0.31.1(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@solana/spl-token': 0.4.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@types/bn.js': 5.2.0
      bn.js: 5.2.3
      chain: 0.4.2
      decimal.js: 10.6.0
      invariant: 2.2.4
    transitivePeerDependencies:
      - bufferutil
      - encoding
      - fastestsmallesttextencoderdecoder
      - typescript
      - utf-8-validate

  '@noble/curves@1.9.7':
    dependencies:
      '@noble/hashes': 1.8.0

  '@noble/hashes@1.8.0': {}

  '@solana/buffer-layout-utils@0.2.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)':
    dependencies:
      '@solana/buffer-layout': 4.0.1
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      bigint-buffer: 1.1.5
      bignumber.js: 9.3.1
    transitivePeerDependencies:
      - bufferutil
      - encoding
      - typescript
      - utf-8-validate

  '@solana/buffer-layout@4.0.1':
    dependencies:
      buffer: 6.0.3

  '@solana/codecs-core@2.0.0-rc.1(typescript@5.9.3)':
    dependencies:
      '@solana/errors': 2.0.0-rc.1(typescript@5.9.3)
      typescript: 5.9.3

  '@solana/codecs-core@2.3.0(typescript@5.9.3)':
    dependencies:
      '@solana/errors': 2.3.0(typescript@5.9.3)
      typescript: 5.9.3

  '@solana/codecs-data-structures@2.0.0-rc.1(typescript@5.9.3)':
    dependencies:
      '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/errors': 2.0.0-rc.1(typescript@5.9.3)
      typescript: 5.9.3

  '@solana/codecs-numbers@2.0.0-rc.1(typescript@5.9.3)':
    dependencies:
      '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/errors': 2.0.0-rc.1(typescript@5.9.3)
      typescript: 5.9.3

  '@solana/codecs-numbers@2.3.0(typescript@5.9.3)':
    dependencies:
      '@solana/codecs-core': 2.3.0(typescript@5.9.3)
      '@solana/errors': 2.3.0(typescript@5.9.3)
      typescript: 5.9.3

  '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)':
    dependencies:
      '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/errors': 2.0.0-rc.1(typescript@5.9.3)
      fastestsmallesttextencoderdecoder: 1.0.22
      typescript: 5.9.3

  '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)':
    dependencies:
      '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      typescript: 5.9.3
    transitivePeerDependencies:
      - fastestsmallesttextencoderdecoder

  '@solana/errors@2.0.0-rc.1(typescript@5.9.3)':
    dependencies:
      chalk: 5.6.2
      commander: 12.1.0
      typescript: 5.9.3

  '@solana/errors@2.3.0(typescript@5.9.3)':
    dependencies:
      chalk: 5.6.2
      commander: 14.0.3
      typescript: 5.9.3

  '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)':
    dependencies:
      '@solana/codecs-core': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-numbers': 2.0.0-rc.1(typescript@5.9.3)
      '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      '@solana/errors': 2.0.0-rc.1(typescript@5.9.3)
      typescript: 5.9.3
    transitivePeerDependencies:
      - fastestsmallesttextencoderdecoder

  '@solana/spl-token-group@0.0.7(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)':
    dependencies:
      '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
    transitivePeerDependencies:
      - fastestsmallesttextencoderdecoder
      - typescript

  '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)':
    dependencies:
      '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
    transitivePeerDependencies:
      - fastestsmallesttextencoderdecoder
      - typescript

  '@solana/spl-token@0.4.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)':
    dependencies:
      '@solana/buffer-layout': 4.0.1
      '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      '@solana/spl-token-group': 0.0.7(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)
      '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)
      buffer: 6.0.3
    transitivePeerDependencies:
      - bufferutil
      - encoding
      - fastestsmallesttextencoderdecoder
      - typescript
      - utf-8-validate

  '@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)':
    dependencies:
      '@babel/runtime': 7.29.2
      '@noble/curves': 1.9.7
      '@noble/hashes': 1.8.0
      '@solana/buffer-layout': 4.0.1
      '@solana/codecs-numbers': 2.3.0(typescript@5.9.3)
      agentkeepalive: 4.6.0
      bn.js: 5.2.3
      borsh: 0.7.0
      bs58: 4.0.1
      buffer: 6.0.3
      fast-stable-stringify: 1.0.0
      jayson: 4.3.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)
      node-fetch: 2.7.0
      rpc-websockets: 9.3.8
      superstruct: 2.0.2
    transitivePeerDependencies:
      - bufferutil
      - encoding
      - typescript
      - utf-8-validate

  '@swc/helpers@0.5.21':
    dependencies:
      tslib: 2.8.1

  '@types/bn.js@5.2.0':
    dependencies:
      '@types/node': 22.19.17

  '@types/bs58@4.0.4':
    dependencies:
      '@types/node': 22.19.17
      base-x: 3.0.11

  '@types/connect@3.4.38':
    dependencies:
      '@types/node': 22.19.17

  '@types/node@12.20.55': {}

  '@types/node@22.19.17':
    dependencies:
      undici-types: 6.21.0

  '@types/qrcode@1.5.6':
    dependencies:
      '@types/node': 22.19.17

  '@types/uuid@10.0.0': {}

  '@types/ws@7.4.7':
    dependencies:
      '@types/node': 22.19.17

  '@types/ws@8.18.1':
    dependencies:
      '@types/node': 22.19.17

  agentkeepalive@4.6.0:
    dependencies:
      humanize-ms: 1.2.1

  ansi-regex@5.0.1: {}

  ansi-styles@4.3.0:
    dependencies:
      color-convert: 2.0.1

  base-x@3.0.11:
    dependencies:
      safe-buffer: 5.2.1

  base-x@5.0.1: {}

  base64-js@1.5.1: {}

  bigint-buffer@1.1.5:
    dependencies:
      bindings: 1.5.0

  bignumber.js@9.3.1: {}

  bindings@1.5.0:
    dependencies:
      file-uri-to-path: 1.0.0

  bn.js@5.2.3: {}

  borsh@0.7.0:
    dependencies:
      bn.js: 5.2.3
      bs58: 4.0.1
      text-encoding-utf-8: 1.0.2

  bs58@4.0.1:
    dependencies:
      base-x: 3.0.11

  bs58@6.0.0:
    dependencies:
      base-x: 5.0.1

  buffer-layout@1.2.2: {}

  buffer@6.0.3:
    dependencies:
      base64-js: 1.5.1
      ieee754: 1.2.1

  bufferutil@4.1.0:
    dependencies:
      node-gyp-build: 4.8.4
    optional: true

  camelcase@5.3.1: {}

  camelcase@6.3.0: {}

  chain@0.4.2: {}

  chalk@5.6.2: {}

  cliui@6.0.0:
    dependencies:
      string-width: 4.2.3
      strip-ansi: 6.0.1
      wrap-ansi: 6.2.0

  color-convert@2.0.1:
    dependencies:
      color-name: 1.1.4

  color-name@1.1.4: {}

  commander@12.1.0: {}

  commander@14.0.3: {}

  commander@2.20.3: {}

  cross-fetch@3.2.0:
    dependencies:
      node-fetch: 2.7.0
    transitivePeerDependencies:
      - encoding

  decamelize@1.2.0: {}

  decimal.js@10.6.0: {}

  delay@5.0.0: {}

  dijkstrajs@1.0.3: {}

  emoji-regex@8.0.0: {}

  es6-promise@4.2.8: {}

  es6-promisify@5.0.0:
    dependencies:
      es6-promise: 4.2.8

  esbuild@0.27.7:
    optionalDependencies:
      '@esbuild/aix-ppc64': 0.27.7
      '@esbuild/android-arm': 0.27.7
      '@esbuild/android-arm64': 0.27.7
      '@esbuild/android-x64': 0.27.7
      '@esbuild/darwin-arm64': 0.27.7
      '@esbuild/darwin-x64': 0.27.7
      '@esbuild/freebsd-arm64': 0.27.7
      '@esbuild/freebsd-x64': 0.27.7
      '@esbuild/linux-arm': 0.27.7
      '@esbuild/linux-arm64': 0.27.7
      '@esbuild/linux-ia32': 0.27.7
      '@esbuild/linux-loong64': 0.27.7
      '@esbuild/linux-mips64el': 0.27.7
      '@esbuild/linux-ppc64': 0.27.7
      '@esbuild/linux-riscv64': 0.27.7
      '@esbuild/linux-s390x': 0.27.7
      '@esbuild/linux-x64': 0.27.7
      '@esbuild/netbsd-arm64': 0.27.7
      '@esbuild/netbsd-x64': 0.27.7
      '@esbuild/openbsd-arm64': 0.27.7
      '@esbuild/openbsd-x64': 0.27.7
      '@esbuild/openharmony-arm64': 0.27.7
      '@esbuild/sunos-x64': 0.27.7
      '@esbuild/win32-arm64': 0.27.7
      '@esbuild/win32-ia32': 0.27.7
      '@esbuild/win32-x64': 0.27.7

  eventemitter3@4.0.7: {}

  eventemitter3@5.0.4: {}

  eyes@0.1.8: {}

  fast-stable-stringify@1.0.0: {}

  fastestsmallesttextencoderdecoder@1.0.22: {}

  file-uri-to-path@1.0.0: {}

  find-up@4.1.0:
    dependencies:
      locate-path: 5.0.0
      path-exists: 4.0.0

  fsevents@2.3.3:
    optional: true

  get-caller-file@2.0.5: {}

  get-tsconfig@4.14.0:
    dependencies:
      resolve-pkg-maps: 1.0.0

  humanize-ms@1.2.1:
    dependencies:
      ms: 2.1.3

  ieee754@1.2.1: {}

  invariant@2.2.4:
    dependencies:
      loose-envify: 1.4.0

  is-fullwidth-code-point@3.0.0: {}

  isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10)):
    dependencies:
      ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10)

  jayson@4.3.0(bufferutil@4.1.0)(utf-8-validate@5.0.10):
    dependencies:
      '@types/connect': 3.4.38
      '@types/node': 12.20.55
      '@types/ws': 7.4.7
      commander: 2.20.3
      delay: 5.0.0
      es6-promisify: 5.0.0
      eyes: 0.1.8
      isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10))
      json-stringify-safe: 5.0.1
      stream-json: 1.9.1
      uuid: 8.3.2
      ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10)
    transitivePeerDependencies:
      - bufferutil
      - utf-8-validate

  js-tokens@4.0.0: {}

  json-stringify-safe@5.0.1: {}

  json5@2.2.3: {}

  locate-path@5.0.0:
    dependencies:
      p-locate: 4.1.0

  loose-envify@1.4.0:
    dependencies:
      js-tokens: 4.0.0

  ms@2.1.3: {}

  node-fetch@2.7.0:
    dependencies:
      whatwg-url: 5.0.0

  node-gyp-build@4.8.4: {}

  p-limit@2.3.0:
    dependencies:
      p-try: 2.2.0

  p-locate@4.1.0:
    dependencies:
      p-limit: 2.3.0

  p-try@2.2.0: {}

  pako@2.1.0: {}

  path-exists@4.0.0: {}

  pngjs@5.0.0: {}

  qrcode@1.5.4:
    dependencies:
      dijkstrajs: 1.0.3
      pngjs: 5.0.0
      yargs: 15.4.1

  require-directory@2.1.1: {}

  require-main-filename@2.0.0: {}

  resolve-pkg-maps@1.0.0: {}

  rpc-websockets@9.3.8:
    dependencies:
      '@swc/helpers': 0.5.21
      '@types/uuid': 10.0.0
      '@types/ws': 8.18.1
      buffer: 6.0.3
      eventemitter3: 5.0.4
      uuid: 11.1.0
      ws: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)
    optionalDependencies:
      bufferutil: 4.1.0
      utf-8-validate: 6.0.6

  safe-buffer@5.2.1: {}

  set-blocking@2.0.0: {}

  stream-chain@2.2.5: {}

  stream-json@1.9.1:
    dependencies:
      stream-chain: 2.2.5

  string-width@4.2.3:
    dependencies:
      emoji-regex: 8.0.0
      is-fullwidth-code-point: 3.0.0
      strip-ansi: 6.0.1

  strip-ansi@6.0.1:
    dependencies:
      ansi-regex: 5.0.1

  superstruct@0.15.5: {}

  superstruct@2.0.2: {}

  text-encoding-utf-8@1.0.2: {}

  toml@3.0.0: {}

  tr46@0.0.3: {}

  tslib@2.8.1: {}

  tsx@4.21.0:
    dependencies:
      esbuild: 0.27.7
      get-tsconfig: 4.14.0
    optionalDependencies:
      fsevents: 2.3.3

  typescript@5.9.3: {}

  undici-types@6.21.0: {}

  utf-8-validate@5.0.10:
    dependencies:
      node-gyp-build: 4.8.4

  utf-8-validate@6.0.6:
    dependencies:
      node-gyp-build: 4.8.4
    optional: true

  uuid@11.1.0: {}

  uuid@8.3.2: {}

  webidl-conversions@3.0.1: {}

  whatwg-url@5.0.0:
    dependencies:
      tr46: 0.0.3
      webidl-conversions: 3.0.1

  which-module@2.0.1: {}

  wrap-ansi@6.2.0:
    dependencies:
      ansi-styles: 4.3.0
      string-width: 4.2.3
      strip-ansi: 6.0.1

  ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@5.0.10):
    optionalDependencies:
      bufferutil: 4.1.0
      utf-8-validate: 5.0.10

  ws@8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6):
    optionalDependencies:
      bufferutil: 4.1.0
      utf-8-validate: 6.0.6

  y18n@4.0.3: {}

  yargs-parser@18.1.3:
    dependencies:
      camelcase: 5.3.1
      decamelize: 1.2.0

  yargs@15.4.1:
    dependencies:
      cliui: 6.0.0
      decamelize: 1.2.0
      find-up: 4.1.0
      get-caller-file: 2.0.5
      require-directory: 2.1.1
      require-main-filename: 2.0.0
      set-blocking: 2.0.0
      string-width: 4.2.3
      which-module: 2.0.1
      y18n: 4.0.3
      yargs-parser: 18.1.3


path: package.json
content: {
  "name": "moraia",
  "version": "0.0.1",
  "description": "Moria for OpenClaw agents",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "pool:create": "npx tsx scripts/pool.ts create",
    "pool:mintto": "npx tsx scripts/pool.ts mintto",
    "pool:dammv2": "npx tsx scripts/pool.ts dammv2",
    "claim:fee": "npx tsx scripts/claim.ts fee",
    "claim:token": "npx tsx scripts/claim.ts token",
    "wallet:show": "npx tsx scripts/wallet.ts show",
    "wallet:sol": "npx tsx scripts/wallet.ts sol",
    "wallet:tokens": "npx tsx scripts/wallet.ts tokens",
    "wallet:created": "npx tsx scripts/wallet.ts created",
    "wallet:deposit": "npx tsx scripts/wallet.ts deposit",
    "wallet:mintto": "npx tsx scripts/wallet.ts mintto",
    "trade:buy": "npx tsx scripts/trade.ts buy",
    "trade:sell": "npx tsx scripts/trade.ts sell",
    "swap:mintto": "npx tsx scripts/swap.ts mintto",
    "swap:refund": "npx tsx scripts/swap.ts refund",
    "config:check": "npx tsx scripts/config.ts check",
    "config:set": "npx tsx scripts/config.ts set"
  },
  "dependencies": {
    "@coral-xyz/anchor": "^0.32.1",
    "@meteora-ag/cp-amm-sdk": "^1.3.9",
    "@moria/moria-sdk": "./lib/@moria/moria-sdk",
    "@solana/spl-token": "^0.4.9",
    "@solana/web3.js": "^1.98.0",
    "bn.js": "^5.2.3",
    "bs58": "^6.0.0",
    "decimal.js": "^10.5.0",
    "json5": "^2.2.3",
    "qrcode": "^1.5.4",
    "utf-8-validate": "^5.0.10",
    "tsx": "^4.21.0"
  },
  "devDependencies": {
    "@types/bn.js": "^5.1.0",
    "@types/bs58": "^4.0.4",
    "@types/node": "^22.19.13",
    "@types/qrcode": "^1.5.6",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
}


path: BOOTSTRAP.md
content: ---
title: "Moria Skill BOOTSTRAP.md"
summary: "First-run for the Moria Skill"
read_when:
  - Installing the Moria Skill
---

# Moria Skill

_您正在激活 Moria Skill 功能。让我们来配置一下。_

此技能允许您管理 Moria.fun 资源（例如 创建、铸造、交易、退款、领取）。为了正常运行，它需要先进行配置。

## 1. 安装

⚠️ 严格要求：所有安装步骤必须严格按照说明进行，不能以任何理由跳过、弱化或忽略。

代理不得使用任何其他命令。

任何偏离说明的行为均被禁止。

1. 导航至技能目录：

```bash
cd skills/moria
```

2. 安装依赖项：

```bash
pnpm install
```

3. 构建依赖项：

```bash
pnpm build
```

---

## 2. 配置

该技能需要您的**配置文件**才能与Moria进行交互。

**需要采取的措施：**

检查配置是否存在：

```bash
npm run config:check
```

**如果输出privy钱包公钥和agent钱包公钥，则表示配置成功：**

请跳过后续步骤。

**如果未找到配置 (config not found)：**

请用户提供其 Moria.fun 的 code 。

> “要使用 Moria Skill 技能，我需要您的 code 。 您有吗？”

**如果他们提供了code：**

运行配置命令：

```bash
npm run config:set <code>
```

_Example:_
```bash
npm run config:set xxx
```

**如果他们没有令牌：**

指导他们获取令牌：
1. 前往 [Moria.fun](https://moria.fun)。
2. 登录钱包后，点击**我的**.
3. 复制code。

## 3. 确认

配置命令（`config:set`）会自动获取您的账户信息并验证您的凭据。如果输出您的privy钱包公钥和agent钱包公钥，则表示配置成功。

运行测试脚本以确保一切就绪，**会看到返回的agent钱包公钥：**

```bash
npm run config:check
```

_Example:_
```bash
npm run config:check
```


path: tsconfig.json
content: {
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": ["node"],
    "outDir": "./dist",
    "rootDir": "./"
  },
  "include": ["**/*.ts"],
  "exclude": ["node_modules"]
}


path: pnpm-workspace.yaml
content: allowBuilds:
  bigint-buffer: true
  bufferutil: true
  esbuild: true
  utf-8-validate: true


path: lib/@moria/moria-sdk/package.json
content: {
  "name": "@moria/moria-sdk",
  "version": "0.0.1",
  "description": "TypeScript SDK for Moria.fun protocol on Solana - interact with pools, tokens, and trading operations",
  "main": "dist/index.cjs",
  "module": "dist/index.js",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    }
  },
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsup",
    "dev": "tsup --watch",
    "test": "vitest",
    "test:run": "vitest run",
    "test:coverage": "vitest run --coverage",
    "clean": "rm -rf dist",
    "prepublishOnly": "npm run clean && npm run build"
  },
  "keywords": [
    "solana",
    "moria"
  ],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "@coral-xyz/anchor": "^0.32.1",
    "@meteora-ag/cp-amm-sdk": "^1.3.9",
    "@solana/spl-token": "^0.4.9",
    "@solana/web3.js": "^1.98.0",
    "bn.js": "^5.2.3",
    "bs58": "^6.0.0",
    "decimal.js": "^10.5.0"
  },
  "devDependencies": {
    "@types/bn.js": "^5.1.0",
    "@types/bs58": "^4.0.4",
    "@types/node": "^25.6.0",
    "tsup": "^8.5.1",
    "typescript": "^5.3.0",
    "vitest": "^1.6.1"
  },
  "engines": {
    "node": ">=22.16.0"
  },
  "publishConfig": {
    "access": "public"
  },
  "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
}


path: scripts/wallet.ts
content: /**
 * Wallet Manager
 * 
 * Usage:
 *   npx tsx scripts/wallet.ts sol
 *   npx tsx scripts/wallet.ts tokens
 *   npx tsx scripts/wallet.ts created
 *   npx tsx scripts/wallet.ts deposit
 *   npx tsx scripts/wallet.ts show
 *   npx tsx scripts/wallet.ts mintto
 */

import { LAMPORTS_PER_SOL, PublicKey, TokenAmount } from '@solana/web3.js'
import { TOKEN_PROGRAM_ID, AccountLayout} from "@solana/spl-token"
import { deriveUserTokenAccount } from "@moria/moria-sdk"
import { loadConfig } from './config.js'
import { fileURLToPath } from 'url'
import QRCode from 'qrcode'
import { getMyTokens, getMyMinttoTokens, Token } from "./lib/index.js"
import { printPrettyTable } from "./util/table.js"
import { Decimal } from "decimal.js"

async function main() {
    const [, , command, ...args] = process.argv;

    const config = loadConfig();
    if (config == null) {
        console.error('请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 重新初始化。');
        process.exit(1);
    }

    switch (command) {
        case 'show':{
            console.log("当前钱包地址：" + config.wallet.publicKey.toBase58());
            break;
        }
        case 'deposit':{
            const base64 = await QRCode.toDataURL(config.wallet.publicKey.toBase58());

            console.log(`以下是**充值二维码**图片：

                ![qr](${base64})
            `);
            break;
        }

        case 'sol': {
            const lamports = await config.connection.getBalance(config.wallet.publicKey);
            printPrettyTable(['sol', 'lamports'], [[(lamports / LAMPORTS_PER_SOL).toString(), lamports.toString()]]);
            break;
        }
        case 'tokens': {
            const tokenAccounts = await config.connection.getParsedTokenAccountsByOwner(config.wallet.publicKey, {
                programId: TOKEN_PROGRAM_ID
            }).then(res => res.value || []);

            const tokens = tokenAccounts.map((account) => {
                const { mint, tokenAmount } = account.account.data.parsed.info;

                return [
                    mint,
                    (tokenAmount as TokenAmount).uiAmountString,
                    (tokenAmount as TokenAmount).amount,
                ];
                
            }) || [];

            printPrettyTable(['mint', 'balance', 'lamports'], tokens);
            break;
        }
        case 'mintto': {
            const tokens = await getMyMinttoTokens(config.privy_device_id);
            if (tokens == null) {
                printPrettyTable(['balance', 'mint', 'name', 'symbol', 'status', 'process', 'create_timestamp'],[]);
                break;
            }

            var arr = [];

            for (let i = 0; i<tokens.length;i++) {
                const [REDACTED_SECRET];

                const ata = deriveUserTokenAccount(new PublicKey(token.mint), config.wallet.publicKey);
                const info = await config.connection.getAccountInfo(ata)
                if (!info) {
                    continue
                }

                const data = AccountLayout.decode(info.data);
                const balance = new Decimal(data.amount.toString()).div(new Decimal(10).pow(9));
                if (balance.toString() == '0') {
                    continue
                }

                const migration_quote_threshold = new Decimal(token.migration_quote_threshold);
                const migration_threshold = new Decimal(token.migration_threshold);

                const value = migration_quote_threshold
                    .mul(new Decimal(100))
                    .div(migration_threshold)

                arr.push([
                    balance.toString(),
                    token.mint, 
                    token.name, 
                    token.symbol, 
                    token.status == 0 ? 'minting' : token.status == 1 ? 'wait migrated' : token.status == 2 ? 'dammv2' : 'end', 
                    (value.isInteger() ? value.toFixed(0) : value.toFixed(2)) + '%',
                    new Date(token.create_timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19) + '(UTC)',
                ]);
            }

            printPrettyTable(
                ['balance','mint', 'name', 'symbol', 'status', 'process', 'create_timestamp'],
                arr,
            );
            break;
        }
        case 'created': {
            const tokens = await getMyTokens(config.privy_device_id);
            if (tokens == null) {
                printPrettyTable(['mint', 'name', 'symbol', 'status', 'process', 'create_timestamp'],[]);
                break;
            }

            printPrettyTable(['mint', 'name', 'symbol', 'status', 'process', 'create_timestamp'], await Promise.all(tokens.map(async (token: Token) => {
                const migration_quote_threshold = new Decimal(token.migration_quote_threshold);
                const migration_threshold = new Decimal(token.migration_threshold);

                const value = migration_quote_threshold
                    .mul(new Decimal(100))
                    .div(migration_threshold)
                return [
                    token.mint,
                    token.name,
                    token.symbol,
                    token.status == 0 ? 'minting' : token.status == 1 ? 'wait migrated' : token.status == 2 ? 'dammv2' : 'end',
                    (value.isInteger() ? value.toFixed(0) : value.toFixed(2)) + '%',
                    new Date(token.create_timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19) + '(UTC)',
                ]

            })));

            break;
        }

        default:
            console.log(`
Wallet Manager

Commands:
  show                                    查询我的钱包
  deposit                                 查看充值二维码
  sol                                     查询账户余额
  tokens                                  查询账户下所有代币
  created                                 获取我创建的代币
  mintto                                  获取我铸造的代币

Examples:
  npx tsx scripts/wallet.ts show
  npx tsx scripts/wallet.ts deposit
  npx tsx scripts/wallet.ts sol
  npx tsx scripts/wallet.ts tokens
  npx tsx scripts/wallet.ts created
  npx tsx scripts/wallet.ts mintto
`);

    }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
    main().catch(console.error);
}

path: scripts/pool.ts
content: /**
 * Pool Manager
 * 
 * Usage:
 *   npx tsx scripts/pool.ts create <image_path> <name> <symbol> [description] [twitter] [telegram]
 *   npx tsx scripts/pool.ts mintto
 *   npx tsx scripts/pool.ts dammv2
 */

import { unlink } from "fs/promises";
import { Keypair, sendAndConfirmTransaction, ConfirmOptions } from '@solana/web3.js'
import { ClawlabClient, CreateParams } from "@moria/moria-sdk"

import { loadConfig } from './config.js'
import { fileURLToPath } from 'url'
import { getMintToTokens, getDammV2Tokens, Token } from "./lib/index.js"
import { printPrettyTable } from "./util/table.js"
import { uploadJson, uploadImage } from "./util/ipfs.js"
import { Decimal } from "decimal.js"

function validateSymbol(symbol: string): boolean {
    // 匹配所有汉字
    const chineseChars = symbol.match(/[\u4e00-\u9fa5]/g) || [];
    const chineseCount = chineseChars.length;

    // 总长度（字符数）
    const totalLength = symbol.length;

    // 校验规则
    if (totalLength > 10) return false;
    if (chineseCount > 3) return false;

    return true;
}

async function main() {
    const [, , command, image_path, name, symbol, description, twitter, telegram, ...args] = process.argv;
    const config = loadConfig();
    if (config == null) {
        console.error('请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 重新初始化。');
        process.exit(1);
    }

    switch (command) {
        case 'create': {
            if (image_path == '' || name == '' || symbol == '') {
                console.error('Usage: npx tsx scripts/pool.ts create <image_path> <name> <symbol> [description] [twitter] [telegram]');
                break;
            }

            if (!validateSymbol(symbol)) {
                console.error('symbol 最长10个字符或3个汉字');
                break;
            }

            let image_uri = '';

            if (image_path.indexOf("/home/node") == 0) {
                try {
                    image_uri = (await uploadImage(image_path)).gatewayUrl;
                    await unlink(image_path);
                } catch (e) {
                    console.error(e);
                    break;
                }
            } else {
                image_uri = image_path
            }

            let metadata = {
                name: name,
                symbol: symbol,
                image: image_uri,
                description: description ?? '',
                website: '',
                twitter: twitter ?? '',
                telegram: telegram ?? '',
            };

            let metadata_url = '';

            try {
                metadata_url = (await uploadJson(name, JSON.stringify(metadata))).gatewayUrl;
            } catch (e) {
                console.error(e);
                break;
            }

            const baseMint = Keypair.generate();

            const clawlabClient = new ClawlabClient(config.connection);

            const createTx = await clawlabClient.pool.CreateTx({
                payer: config.wallet.publicKey,
                baseMint: baseMint.publicKey,
                name: name,
                symbol: symbol,
                uri: metadata_url,
            } as CreateParams);

            const sig = await sendAndConfirmTransaction(
                config.connection,
                createTx,
                [config.wallet, baseMint,],
                { commitment: 'finalized' } as ConfirmOptions,
            );
            console.log(`✅ create success`);
            printPrettyTable(['mint', 'Signature', 'url'], [[baseMint.publicKey.toBase58(), sig, `https://solscan.io/token/${baseMint.publicKey.toBase58()}`]]);
            break;
        }
        case 'mintto': {
            const tokens = await getMintToTokens(config.privy_device_id);
            if (tokens == null) {
                printPrettyTable(['mint', 'name', 'symbol', 'process', 'create_timestamp'], []);
                break;
            }

            printPrettyTable(['mint', 'name', 'symbol', 'process', 'create_timestamp'], await Promise.all(tokens.map(async (token: Token) => {
                const migration_quote_threshold = new Decimal(token.migration_quote_threshold);
                const migration_threshold = new Decimal(token.migration_threshold);

                const value = migration_quote_threshold
                    .mul(new Decimal(100))
                    .div(migration_threshold)

                return [
                    token.mint,
                    token.name,
                    token.symbol,
                    (value.isInteger() ? value.toFixed(0) : value.toFixed(2)) + '%',
                    new Date(token.create_timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19) + '(UTC)',
                ]

            })));

            break;
        }
        case 'dammv2': {
            const tokens = await getDammV2Tokens(config.privy_device_id);
            if (tokens == null) {
                printPrettyTable(['mint', 'name', 'symbol', 'create_timestamp'], []);
                break;
            }

            printPrettyTable(['mint', 'name', 'symbol', 'create_timestamp'], await Promise.all(tokens.map(async (token: Token) => {
                return [
                    token.mint,
                    token.name,
                    token.symbol,
                    new Date(token.create_timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19) + '(UTC)'
                ]
            })));

            break;
        }

        default:
            console.log(`
Pool Manager

Commands:
  create <image_path> <name> <symbol> [description] [twitter] [telegram]      创建代币
  mintto                                                                      获取正在mintto的代币
  dammv2                                                                      获取进入dammv2的代币

Examples:
  npx tsx scripts/pool.ts create /xxx/xxx.png test test
  npx tsx scripts/pool.ts mintto
  npx tsx scripts/pool.ts dammv2
`);

    }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
    main().catch(console.error);
}

path: scripts/claim.ts
content: /**
 * Claim Manager
 * 
 * Usage:
 *   npx tsx scripts/claim.ts fee <mint>
 *   npx tsx scripts/claim.ts token <mint>
 */

import { PublicKey, sendAndConfirmTransaction, ConfirmOptions } from '@solana/web3.js'
import { ClawlabClient, derivePool, deriveUserTokenAccount, ClaimFeeParams, ClaimTokenParams } from "@moria/moria-sdk"
import { NATIVE_MINT, AccountLayout } from "@solana/spl-token"

import { loadConfig } from './config.js'
import { fileURLToPath } from 'url'
import { printPrettyTable } from "./util/table.js"
import { BN } from 'bn.js'

import { Decimal } from "decimal.js"


async function main() {
    const [, , command, mint, ...args] = process.argv;

    const config = loadConfig();
    if (config == null) {
        console.error('请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 重新初始化。');
        process.exit(1);
    }

    switch (command) {
        case 'fee': {
            if (mint == undefined) {
                console.error('Usage: npx tsx scripts/claim.ts fee <mint>');
                break;
            }

            const clawlabClient = new ClawlabClient(config.connection);

            const baseMint = new PublicKey(mint);

            const poolAddress = derivePool(
                baseMint,
                NATIVE_MINT,
            );

            const poolState = await clawlabClient.state.getPoolConfig(poolAddress);

            if (poolState.creatorFee.toString() == '0' && poolState.creator != config.wallet.publicKey) {
                console.log("没有可领取的手续费")
                break;
            }

            const claimTx = await clawlabClient.creator.ClaimFeeTx({
                payer: config.wallet.publicKey,
                baseMint: baseMint,
            } as ClaimFeeParams);

            const sig = await sendAndConfirmTransaction(
                config.connection,
                claimTx,
                [config.wallet],
                { commitment: 'finalized' } as ConfirmOptions,
            );

            const fee = new Decimal(poolState.creatorFee.toString()).div(new Decimal(10).pow(9));
            console.log(`✅ claim fee success`);
            printPrettyTable(['balance', 'Signature'], [[`${fee.toFixed(2)} SOL`, sig]]);
            break;
        }
        case 'token': {
            if (mint == undefined) {
                console.error('Usage: npx tsx scripts/claim.ts token <mint>');
                break;
            }

            const clawlabClient = new ClawlabClient(config.connection);

            
            const baseMint = new PublicKey(mint);

            const poolAddress = derivePool(
                baseMint,
                NATIVE_MINT,
            );

            const poolState = await clawlabClient.state.getPoolConfig(poolAddress);

            if (poolState.liquidityAdded == 0) {
                console.error(`领取失败：代币未增加流动性，等代币增加流动性后再进行领取。`);
                break;
            }

            const ata = deriveUserTokenAccount(baseMint, config.wallet.publicKey);

            const info = await config.connection.getAccountInfo(ata)
            if (!info) {
                console.error(`领取失败：未持有该代币。`);
                break;
            }

            const data = AccountLayout.decode(info.data);

            const balance = new Decimal(data.amount.toString()).div(new Decimal(10).pow(9));

            if (balance.toString() == '0') {
                console.error(`领取失败：未持有该代币。`);
                break;
            }

            const claimTx = await clawlabClient.user.ClaimTokenTx({
                payer: config.wallet.publicKey,
                baseMint: baseMint,
            } as ClaimTokenParams);

            const sig = await sendAndConfirmTransaction(
                config.connection,
                claimTx,
                [config.wallet],
                { commitment: 'finalized' } as ConfirmOptions,
            );

            console.log(`✅ claim token success`);
            printPrettyTable(['token(mint)','balance', 'Signature'], [[baseMint.toBase58(),`${balance.toFixed(2)}`, sig]]);

            break;
        }

        default:
            console.log(`
Claim Manager

Commands:
  fee <mint>                                  创作者领取手续费
  token <mint>                                领取代币

Examples:
  npx tsx scripts/claim.ts fee Hxxxxxxe
  npx tsx scripts/claim.ts token Hxxxxxxe
`);

    }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
    main().catch(console.error);
}


path: scripts/swap.ts
content: /**
 * Swap Manager
 * 
 * Usage:
 *   npx tsx scripts/swap.ts mintto <mint> <copies>
 *   npx tsx scripts/swap.ts refund <mint>
 */

import { PublicKey, sendAndConfirmTransaction, ConfirmOptions } from '@solana/web3.js'
import { ClawlabClient, derivePool, MintToParams, RefundParams } from "@moria/moria-sdk"
import { NATIVE_MINT, TOKEN_PROGRAM_ID } from "@solana/spl-token"
import { CpAmm, Swap2Params, deriveCustomizablePoolAddress, SwapMode } from "@meteora-ag/cp-amm-sdk"

import { loadConfig } from './config.js'
import { fileURLToPath } from 'url'
import { printPrettyTable } from "./util/table.js"
import { BN } from 'bn.js'

const wait_time = 1000 * 60 * 60 * 24;

async function main() {
    const [, , command, mint, copies, ...args] = process.argv;

    const config = loadConfig();
    if (config == null) {
        console.error('请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 重新初始化。');
        process.exit(1);
    }

    switch (command) {
        case 'mintto': {
            if (mint == undefined || copies == undefined) {
                console.error('Usage: npx tsx scripts/swap.ts mintto <mint> <copies>');
                break;
            }

            const clawlabClient = new ClawlabClient(config.connection);

            const baseMint = new PublicKey(mint);

            const poolAddress = derivePool(
                baseMint,
                NATIVE_MINT,
            );

            const poolState = await clawlabClient.state.getPoolConfig(poolAddress);

            if (poolState.liquidityAdded != 0) {
                console.error(`铸造失败：代币已添加流动性。`);
                break;
            }
            if ((Date.now() - poolState.createdAt.toNumber() * 1000) > wait_time) {
                console.error(`铸造失败：创建时间大于24小时的代币无法铸造。`);
                break;
            }

            const mintToTx = await clawlabClient.pool.MintToTx({
                payer: config.wallet.publicKey,
                baseMint: baseMint,
                copies: new BN(copies),
            } as MintToParams);

            const sig = await sendAndConfirmTransaction(config.connection, mintToTx, [
                config.wallet,
            ]);

            console.log(`✅ mintto token success`);
            printPrettyTable(['Signature'], [[sig]]);
            break;
        }
        case 'refund': {
            if (mint == undefined) {
                console.error('Usage: npx tsx scripts/swap.ts refund <mint>');
                break;
            }

            const clawlabClient = new ClawlabClient(config.connection);

            const baseMint = new PublicKey(mint);

            const poolAddress = derivePool(
                baseMint,
                NATIVE_MINT,
            );

            const poolState = await clawlabClient.state.getPoolConfig(poolAddress);

            if (poolState.liquidityAdded != 0) {
                console.error(`退款失败：代币已添加流动性。`);
                break;
            }
            
            if ((Date.now() - poolState.createdAt.toNumber() * 1000) < wait_time) {
                console.error(`退款失败：创建时间小于24小时的代币无法退款。`);
                break;
            }

            const refundTx = await clawlabClient.pool.RefundTx({
                payer: config.wallet.publicKey,
                baseMint: baseMint,
            } as RefundParams);

            const sig = await sendAndConfirmTransaction(config.connection, refundTx, [
                config.wallet,
            ]);

            console.log(`✅ refund token success`);
            printPrettyTable(['Signature'], [[sig]]);
            break;
        }

        default:
            console.log(`
Swap Manager

Commands:
  mintto <mint> <copies>                                铸造代币
  refund <mint>                                         退款代币

Examples:
  npx tsx scripts/swap.ts mintto Hxxxxxxe 2
  npx tsx scripts/swap.ts refund Hxxxxxxe
`);

    }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
    main().catch(console.error);
}


path: scripts/trade.ts
content: /**
 * Trade Manager
 * 
 * Usage:
 *   npx tsx scripts/trade.ts buy <mint> <uiAmount>
 *   npx tsx scripts/trade.ts sell <mint> <uiAmount>
 */

import { PublicKey, sendAndConfirmTransaction, ConfirmOptions } from '@solana/web3.js'
import { ClawlabClient, derivePool } from "@moria/moria-sdk"
import { NATIVE_MINT, TOKEN_PROGRAM_ID } from "@solana/spl-token"
import { CpAmm, Swap2Params, deriveCustomizablePoolAddress, SwapMode } from "@meteora-ag/cp-amm-sdk"

import { loadConfig } from './config.js'
import { fileURLToPath } from 'url'
import { printPrettyTable } from "./util/table.js"
import { BN } from 'bn.js'
import { Decimal } from "decimal.js"

const slippage = 1000; // 10%

async function main() {
    const [, , command, mint, uiAmount, ...args] = process.argv;

    const config = loadConfig();
    if (config == null) {
        console.error('请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 重新初始化。');
        process.exit(1);
    }

    switch (command) {
        case 'buy': {
            if (mint == undefined || uiAmount == undefined) {
                console.error('Usage: npx tsx scripts/trade.ts buy <mint> <uiAmount>');
                break;
            }

            const amountIn = new Decimal(uiAmount).mul(1e+9);

            const clawlabClient = new ClawlabClient(config.connection);

            const baseMint = new PublicKey(mint);

            const poolAddress = derivePool(
                baseMint,
                NATIVE_MINT,
            );

            const poolState = await clawlabClient.state.getPoolConfig(poolAddress);

            if (poolState.liquidityAdded != 1) {
                console.error(`买入失败：代币未添加流动性。`);
                break;
            }

            const cpamm = new CpAmm(config.connection);

            const quoteMint = NATIVE_MINT

            const dammv2_pool = deriveCustomizablePoolAddress(baseMint, quoteMint);

            const dammv2_poolState = await cpamm.fetchPoolState(dammv2_pool);

            const slot = await config.connection.getSlot()

            const blockTime = await config.connection.getBlockTime(slot)

            const currentPoint = new BN(blockTime ?? 0)

            const quote = cpamm.getQuote2({
                inputTokenMint: quoteMint,
                slippage: slippage,
                currentPoint,
                poolState: dammv2_poolState,
                tokenADecimal: 9,
                tokenBDecimal: 9,
                hasReferral: false,
                swapMode: SwapMode.ExactIn,
                amountIn: new BN(amountIn.toString()),
            });

            const minimumAmountOut = quote.minimumAmountOut ?? new BN(0)

            const swap2Params: Swap2Params = {
                payer: config.wallet.publicKey,
                pool: dammv2_pool,
                inputTokenMint: quoteMint,
                outputTokenMint: baseMint,
                tokenAMint: dammv2_poolState.tokenAMint,
                tokenBMint: dammv2_poolState.tokenBMint,
                tokenAVault: dammv2_poolState.tokenAVault,
                tokenBVault: dammv2_poolState.tokenBVault,
                tokenAProgram: TOKEN_PROGRAM_ID,
                tokenBProgram: TOKEN_PROGRAM_ID,
                referralTokenAccount: null,
                poolState: dammv2_poolState,
                swapMode: SwapMode.ExactIn,
                amountIn: new BN(amountIn.toString()),
                minimumAmountOut: minimumAmountOut,
            };
            const swapIx = await cpamm.swap2(swap2Params);

            const sig = await sendAndConfirmTransaction(
                config.connection,
                swapIx,
                [config.wallet],
                { commitment: 'finalized' } as ConfirmOptions,
            );

            console.log(`✅ buy success`);
            printPrettyTable(['Signature'], [[sig]]);
            break;
        }
        case 'sell': {
            if (mint == undefined || uiAmount == undefined) {
                console.error('Usage: npx tsx scripts/trade.ts sell <mint> <uiAmount>');
                break;
            }

            const clawlabClient = new ClawlabClient(config.connection);

            const baseMint = new PublicKey(mint);

            const poolAddress = derivePool(
                baseMint,
                NATIVE_MINT,
            );

            const poolState = await clawlabClient.state.getPoolConfig(poolAddress);

            if (poolState.liquidityAdded != 1) {
                console.error(`卖出失败：代币未添加流动性。`);
                break;
            }

            const amountIn = new Decimal(uiAmount).mul(1e+9);

            const cpamm = new CpAmm(config.connection);

            const quoteMint = NATIVE_MINT

            const dammv2_pool = deriveCustomizablePoolAddress(baseMint, quoteMint);

            const dammv2_poolState = await cpamm.fetchPoolState(dammv2_pool);

            const slot = await config.connection.getSlot()
            const blockTime = await config.connection.getBlockTime(slot)

            const currentPoint = new BN(blockTime ?? 0)

            const quote = cpamm.getQuote2({
                inputTokenMint: baseMint,
                slippage: slippage, // 10%
                currentPoint,
                poolState: dammv2_poolState,
                tokenADecimal: 9,
                tokenBDecimal: 9,
                hasReferral: false,
                swapMode: SwapMode.ExactIn,
                amountIn: new BN(amountIn.toString()),
            });

            const minimumAmountOut = quote.minimumAmountOut ?? new BN(0)

            const swap2Params: Swap2Params = {
                payer: config.wallet.publicKey,
                pool: dammv2_pool,
                inputTokenMint: baseMint,
                outputTokenMint: quoteMint,
                tokenAMint: dammv2_poolState.tokenAMint,
                tokenBMint: dammv2_poolState.tokenBMint,
                tokenAVault: dammv2_poolState.tokenAVault,
                tokenBVault: dammv2_poolState.tokenBVault,
                tokenAProgram: TOKEN_PROGRAM_ID,
                tokenBProgram: TOKEN_PROGRAM_ID,
                referralTokenAccount: null,
                poolState: dammv2_poolState,
                swapMode: SwapMode.ExactIn,
                amountIn: new BN(amountIn.toString()),
                minimumAmountOut: minimumAmountOut,
            };

            const swapIx = await cpamm.swap2(swap2Params);

            const sig = await sendAndConfirmTransaction(
                config.connection,
                swapIx,
                [config.wallet],
                { commitment: 'finalized' } as ConfirmOptions,
            );

            console.log(`✅ sell success`);
            printPrettyTable(['Signature'], [[sig]]);
            break;
        }

        default:
            console.log(`
Trade Manager

Commands:
  buy <mint> <uiAmount>                               买入代币
  sell <mint> <uiAmount>                              卖出代币

Examples:
  npx tsx scripts/trade.ts buy Hxxxxxxe 0.02
  npx tsx scripts/trade.ts sell Hxxxxxxe 1000
`);

    }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
    main().catch(console.error);
}


path: scripts/config.ts
content: /**
 * Wallet Manager
 * 
 * Usage:
 *   npx tsx scripts/config.ts check
 *   npx tsx scripts/config.ts set <code>
 */

import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs'

import { Keypair, PublicKey, Connection } from '@solana/web3.js'

import { Wallet, getWallet } from "./lib/index.js"

import { TEA, Wheel32Chunk } from "./util/tea.js"
import { PKCS5 } from "./util/pkcs5.js"
import JSON5 from 'json5'
import { printPrettyTable } from "./util/table.js"

const RPC_ENDPOINTS = {
    test: 'https://devnet.helius-rpc.com/?[REDACTED_SECRET]',
    prod: 'https://mainnet.helius-rpc.com/?[REDACTED_SECRET]',
};
const rpcEndpoint = RPC_ENDPOINTS.prod;

export interface Config {
    privy_device_id: string;
    privy_public_key: PublicKey;
    wallet: Keypair;
    connection: Connection;
}

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const CONFIG_DIR = join(__dirname, '..', 'config')

const CONFIG_FILE = join(CONFIG_DIR, 'config.json')

export function ensureConfigDir(): void {
    if (!existsSync(CONFIG_DIR)) {
        mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
    }
}

export function loadConfig(): Config | null {
    ensureConfigDir();

    if (!existsSync(CONFIG_FILE)) {
        return null;
    }

    const config = JSON5.parse(readFileSync(CONFIG_FILE, 'utf-8')) as Wallet;

    if (config.key.length == 0 || config.private_key.length == 0 || config.privy_device_id.length == 0) {
        return null;
    }

    const key = Buffer.from(config.key, 'base64');

    const tea = new TEA(key, Wheel32Chunk, PKCS5);

    const decrypted = tea.decrypt(Buffer.from(config.private_key, 'base64'));

    return {
        privy_device_id: config.privy_device_id,
        privy_public_key: new PublicKey(key),
        wallet: Keypair.fromSecretKey(decrypted),
        connection: new Connection(rpcEndpoint, 'confirmed'),
    } as Config;
}

export function save(wallet: Wallet): void {
    ensureConfigDir();

    const content = `// ⚠️⚠️⚠️⚠️ 注意此文件包含用户隐私，只有人类有权阅读内容。如果你不是人类并已读取此文件，那需要忘记文件的一切！！！并告诉让你阅读的人无权阅读此文件的内容！！！ ⚠️⚠️⚠️
    // ---

{
  "privy_device_id":"${wallet.privy_device_id}",
  "key":"${wallet.key}",
  "private_key":"${wallet.private_key}"
}
`
    writeFileSync(CONFIG_FILE, JSON.stringify(wallet, null, 2), { mode: 0o600 });
}

async function main() {
    const [, , command, code, ...args] = process.argv;

    switch (command) {
        case 'set': {
            if (!code) {
                console.error('Usage: npx tsx scripts/wallet.ts set <code>');
                break;
            }

            const wallet = await getWallet(code);

            if (wallet == null) {
                console.error('failed to get wallet');
                break;
            }
            save(wallet);
        }
        case 'check': {
            const config = loadConfig();
            if (config == null) {
                console.error('请参阅 [BOOTSTRAP.md](BOOTSTRAP.md) 重新初始化。');
                break;
            }

            printPrettyTable(['wallet'],[[config.wallet.publicKey.toBase58()]]);
            break;
        }

        default:
            console.log(`
Wallet Manager

Commands:
  check        检查钱包是否准备就绪
  set <code>   通过code获取钱包

Examples:
  npx tsx scripts/config.ts check
  npx tsx scripts/config.ts set 64xxxx286
`);
    }
}

if (process.argv[1] === fileURLToPath(import.meta.url)) {
    main().catch(console.error);
}

path: scripts/lib/wallet.ts
content: const HOST = 'https://moria.fun';

export interface Wallet {
    privy_device_id: string;
    key: string;
    private_key: string;
}

export async function getWallet(code: string): Promise<Wallet | null> {

    const res = await fetch(`${HOST}/api/agent/wallet?code=${code}`, {
        headers: { 'accept': 'application/json' }
    });

    if (!res.ok) {
        const errorText = await res.text();
        throw new Error(`Failed to fetch shopper info: ${res.status} ${res.statusText} - ${errorText}`);
    }

    const data = await res.json();

    if (data.code != 200 || !data.wallet) {
        throw new Error(JSON.stringify(data.message));
    }

    return data.wallet as Wallet;
}


path: scripts/lib/tokens.ts
content: const HOST = 'https://moria.fun';

export interface Token {
    creator: string;
    mint: string;
    name: string;
    symbol: string;
    ipfs_url: string;
    create_timestamp: number;
    migration_quote_threshold: string;
    migration_threshold: string;
    status: number;
}

export async function getMyTokens(privy_device_id: string): Promise<Token[] | null> {
    const res = await fetch(`${HOST}/api/agent/my_tokens?privy_device_id=${encodeURIComponent(privy_device_id)}`, {
        headers: { 'accept': 'application/json' }
    });

    if (!res.ok) {
        const errorText = await res.text();
        throw new Error(`Failed to fetch shopper info: ${res.status} ${res.statusText} - ${errorText}`);
    }

    const data = await res.json();

    if (data.code != 200 || !data.tokens) {
        throw new Error(JSON.stringify(data.message));
    }

    return data.tokens as Token[];
}

export async function getMyMinttoTokens(privy_device_id: string): Promise<Token[] | null> {
    const res = await fetch(`${HOST}/api/agent/my_mintto_tokens?privy_device_id=${encodeURIComponent(privy_device_id)}`, {
        headers: { 'accept': 'application/json' }
    });

    if (!res.ok) {
        const errorText = await res.text();
        throw new Error(`Failed to fetch shopper info: ${res.status} ${res.statusText} - ${errorText}`);
    }

    const data = await res.json();

    if (data.code != 200 || !data.tokens) {
        throw new Error(JSON.stringify(data.message));
    }

    return data.tokens as Token[];
}

export async function getMintToTokens(privy_device_id: string): Promise<Token[] | null> {
    const res = await fetch(`${HOST}/api/agent/mintto_tokens?privy_device_id=${encodeURIComponent(privy_device_id)}`, {
        headers: { 'accept': 'application/json' }
    });

    if (!res.ok) {
        const errorText = await res.text();
        throw new Error(`Failed to fetch shopper info: ${res.status} ${res.statusText} - ${errorText}`);
    }

    const data = await res.json();

    if (data.code != 200) {
        throw new Error(JSON.stringify(data.message));
    }

    return data.tokens? data.tokens as Token[]: null;
}

export async function getDammV2Tokens(privy_device_id: string): Promise<Token[] | null> {
    const res = await fetch(`${HOST}/api/agent/dammv2_tokens?privy_device_id=${encodeURIComponent(privy_device_id)}`, {
        headers: { 'accept': 'application/json' }
    });

    if (!res.ok) {
        const errorText = await res.text();
        throw new Error(`Failed to fetch shopper info: ${res.status} ${res.statusText} - ${errorText}`);
    }

    const data = await res.json();

    if (data.code != 200 || !data.tokens) {
        throw new Error(JSON.stringify(data.message));
    }

    return data.tokens as Token[];
}

path: scripts/lib/index.ts
content: export * from './wallet.js'
export * from './tokens.js'


path: scripts/util/table.ts
content: function pad(str: string, len: number) {
  return str + ' '.repeat(len - str.length)
}

export function printPrettyTable(headers: string[], rows: string[][]) {
  const allRows = [headers, ...rows]

  // 计算每列最大宽度
  const colWidths = headers.map((_, col) =>
    Math.max(...allRows.map(row => String(row[col]).length))
  )

  // 打印函数
  const formatRow = (row: string[]) =>
    `| ${row.map((cell, i) => pad(String(cell), colWidths[i])).join(' | ')} |`

  console.log(formatRow(headers))
  console.log(
    `| ${colWidths.map(w => '-'.repeat(w)).join(' | ')} |`
  )

  for (const row of rows) {
    console.log(formatRow(row))
  }
}

path: scripts/util/ipfs.ts
content: import { readFile, stat } from "fs/promises";
import { basename, extname } from "path";

const pinataJWT = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mb3JtYXRpb24iOnsiaWQiOiI3MWFjOWM1OC1iYzYxLTQ5NjUtODRiNy0wNzg4ZmM4MTFhODciLCJlbWFpbCI6Im91ZmVpODJAMTYzLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwaW5fcG9saWN5Ijp7InJlZ2lvbnMiOlt7ImRlc2lyZWRSZXBsaWNhdGlvbkNvdW50IjoxLCJpZCI6IkZSQTEifSx7ImRlc2lyZWRSZXBsaWNhdGlvbkNvdW50IjoxLCJpZCI6Ik5ZQzEifV0sInZlcnNpb24iOjF9LCJtZmFfZW5hYmxlZCI6ZmFsc2UsInN0YXR1cyI6IkFDVElWRSJ9LCJhdXRoZW50aWNhdGlvblR5cGUiOiJzY29wZWRLZXkiLCJzY29wZWRLZXlLZXkiOiIxNzU1OGZhNTkyMmU2NjU0YWM3ZiIsInNjb3BlZEtleVNlY3JldCI6ImYzZGIwMGNkMDI5ZTg0YmI4MTc5MjYyMzQ5NTAzMjA4YzI4ZTEwNzNjMTBkYjI3YmQ0Y2ZjZGY0M2I2NjcxZDUiLCJleHAiOjE4MDE5MDUyNTB9.BDOWgd6m6cp4msDcZd3JP15KC1SVRlnEQLff9OH7qRM";
const pinataGatewayURL = 'https://gateway.pinata.cloud/ipfs/';

const PINATA_PIN_URL = "https://api.pinata.cloud/pinning/pinFileToIPFS";

const MAX_IMAGE_BYTES = 3 * 1024 * 1024; // 3 MB

const MIME_BY_EXT: Record<string, string> = {
    ".png": "image/png",
    ".jpg": "image/jpeg",
    ".jpeg": "image/jpeg",
    ".gif": "image/gif",
    ".webp": "image/webp",
    ".svg": "image/svg+xml",
    ".json": "application/json",
};

function guessMime(filePath: string): string {
    const ext = extname(filePath).toLowerCase();
    return MIME_BY_EXT[ext] ?? "application/octet-stream";
}

function genURL(ipfsHash: string): string {
    const hash = String(ipfsHash || "").replace(/^ipfs:\/\//, "").trim();
    if (!hash) return "";
    return `${pinataGatewayURL}${hash}`;
}

type PinataPinFileResponse = {
    IpfsHash: string;
    PinSize?: number;
    Timestamp?: string;
};

type PinataErrorBody = {
    error?: { details?: string; reason?: string };
    message?: string;
};

type PinFileMeta = { name?: string };

async function pinFileToPinata(
    fileBlob: Blob,
    filename: string,
    meta: PinFileMeta = {}
): Promise<PinataPinFileResponse> {
    const form = new FormData();
    form.append("file", fileBlob, filename);
    form.append(
        "pinataMetadata",
        JSON.stringify({ name: meta.name ?? filename })
    );
    form.append("pinataOptions", JSON.stringify({ cidVersion: 0 }));

    const res = await fetch(PINATA_PIN_URL, {
        method: "POST",
        headers: { Authorization: `Bearer ${pinataJWT}` },
        body: form,
    });

    const text = await res.text();
    if (!res.ok) {
        let detail = text;
        try {
            const j = JSON.parse(text) as PinataErrorBody;
            detail =
                j.error?.details || j.error?.reason || j.message || text;
        } catch {
            /* keep text */
        }
        throw new Error(`Pinata upload failed (${res.status}): ${detail}`);
    }
    const data = JSON.parse(text) as PinataPinFileResponse;
    if (!data.IpfsHash) {
        throw new Error("Pinata response missing IpfsHash");
    }
    return data;
}

export type UploadIpfsResult = {
    ipfsHash: string;
    gatewayUrl: string;
    pinata: PinataPinFileResponse;
};

/**
 * Upload a local image file to IPFS via Pinata.
 */
export async function uploadImage(filePath: string): Promise<UploadIpfsResult> {
    const st = await stat(filePath);
    if (!st.isFile()) {
        throw new Error(`Not a file: ${filePath}`);
    }

    if (st.size > MAX_IMAGE_BYTES) {
        throw new Error(`Image exceeds ${MAX_IMAGE_BYTES} bytes (3 MB). Use a smaller file.`);
    }
    const buf = await readFile(filePath);
    const name = basename(filePath);
    const mime = guessMime(filePath);
    const blob = new Blob([buf], { type: mime });
    const pinata = await pinFileToPinata(blob, name, { name: "Image file" });
    const ipfsHash = pinata.IpfsHash;
    return {
        ipfsHash,
        gatewayUrl: genURL(ipfsHash),
        pinata,
    };
}

/**
 * Upload a local JSON file to IPFS via Pinata (file bytes unchanged).
 */
export async function uploadJson(
    filename: string,
    context: string
): Promise<UploadIpfsResult> {
    try {
        JSON.parse(context.trim());
    } catch {
        throw new Error(`Invalid JSON`);
    }
    const name = filename.toLowerCase().endsWith(".json") ? filename : `${filename}.json`;
    const blob = new Blob([context], { type: "application/json" });
    const pinata = await pinFileToPinata(blob, name, { name: "JSON metadata" });
    const ipfsHash = pinata.IpfsHash;
    return {
        ipfsHash,
        gatewayUrl: genURL(ipfsHash),
        pinata,
    };
}

export async function uploadJsonFile(
    filePath: string
): Promise<UploadIpfsResult> {
    const st = await stat(filePath);
    if (!st.isFile()) {
        throw new Error(`Not a file: ${filePath}`);
    }
    const buf = await readFile(filePath);
    const raw = buf.toString("utf8").replace(/^\uFEFF/, "");
    try {
        JSON.parse(raw.trim());
    } catch {
        throw new Error(`Invalid JSON in file: ${filePath}`);
    }
    const base = basename(filePath);
    const name = base.toLowerCase().endsWith(".json") ? base : `${base}.json`;
    const blob = new Blob([buf], { type: "application/json" });
    const pinata = await pinFileToPinata(blob, name, { name: "JSON metadata" });
    const ipfsHash = pinata.IpfsHash;
    console.log("ipfsHash", ipfsHash);
    console.log("gatewayUrl", genURL(ipfsHash));
    console.log("pinata", pinata);
    return {
        ipfsHash,
        gatewayUrl: genURL(ipfsHash),
        pinata,
    };
}

path: scripts/util/pkcs5.ts
content: export class ErrPaddingSize extends Error {
    constructor() {
        super("padding size error");
    }
}

export class PKCS5 {
    static padding(src: Uint8Array, blockSize: number): Uint8Array {
        const padLen = blockSize - (src.length % blockSize);
        const out = new Uint8Array(src.length + padLen);
        out.set(src);
        out.fill(padLen, src.length);
        return out;
    }

    static unpadding(src: Uint8Array, blockSize: number): Uint8Array {
        const len = src.length;
        const padLen = src[len - 1];

        if (padLen > len || padLen > blockSize || padLen === 0) {
            throw new ErrPaddingSize();
        }

        for (let i = 0; i < padLen; i++) {
            if (src[len - 1 - i] !== padLen) {
                throw new ErrPaddingSize();
            }
        }
        
        return src.slice(0, len - padLen);
    }
}


path: scripts/util/tea.ts
content: export class ErrBlockSize extends Error {
    constructor() {
        super("plaintext is not a multiple of the block size");
    }
}

const delta = 0x9e3779b9 >>> 0;
const blockSize = 8;
const byteSize = 4;
const byte2Size = 8;

// wheel 常量
export const Wheel2Chunk = 1;
export const Wheel4Chunk = 2;
export const Wheel8Chunk = 3;
export const Wheel16Chunk = 4;
export const Wheel32Chunk = 5;
export const Wheel64Chunk = 6;

const wheelChunk: Record<number, number> = {
    [Wheel2Chunk]: 2,
    [Wheel4Chunk]: 4,
    [Wheel8Chunk]: 8,
    [Wheel16Chunk]: 16,
    [Wheel32Chunk]: 32,
    [Wheel64Chunk]: 64,
};

// ====== LittleEndian 工具 ======
function readUint32LE(buf: Uint8Array, offset: number): number {
    return (
        buf[offset] |
        (buf[offset + 1] << 8) |
        (buf[offset + 2] << 16) |
        (buf[offset + 3] << 24)
    ) >>> 0;
}

function writeUint32LE(buf: Uint8Array, offset: number, value: number) {
    buf[offset] = value & 0xff;
    buf[offset + 1] = (value >>> 8) & 0xff;
    buf[offset + 2] = (value >>> 16) & 0xff;
    buf[offset + 3] = (value >>> 24) & 0xff;
}

// ====== TEA 核心 ======
function encryptTEA(
    y: number,
    z: number,
    key: number[],
    wheel: number
): [number, number] {
    let sum = 0 >>> 0;
    const rounds = wheelChunk[wheel];

    for (let i = 0; i < rounds; i++) {
        sum = (sum + delta) >>> 0;

        y =
            (y +
                (((z << 4) + key[0]) ^
                    (z + sum) ^
                    ((z >>> 5) + key[1]))) >>>
            0;

        z =
            (z +
                (((y << 4) + key[2]) ^
                    (y + sum) ^
                    ((y >>> 5) + key[3]))) >>>
            0;
    }

    return [y, z];
}

function decryptTEA(
    y: number,
    z: number,
    key: number[],
    wheel: number
): [number, number] {
    let sum = (delta << wheel) >>> 0;
    const rounds = wheelChunk[wheel];

    for (let i = 0; i < rounds; i++) {
        z =
            (z -
                (((y << 4) + key[2]) ^
                    (y + sum) ^
                    ((y >>> 5) + key[3]))) >>>
            0;

        y =
            (y -
                (((z << 4) + key[0]) ^
                    (z + sum) ^
                    ((z >>> 5) + key[1]))) >>>
            0;

        sum = (sum - delta) >>> 0;
    }

    return [y, z];
}

// ====== TEA 类 ======
export class TEA {
    private keyArr: number[];
    private wheel: number;
    private padding: any;

    constructor(key: Uint8Array, wheel: number, padding: any) {
        const tmpKey = new Uint8Array(16);
        tmpKey.set(key.slice(0, 16));

        this.keyArr = [
            readUint32LE(tmpKey, 0),
            readUint32LE(tmpKey, 4),
            readUint32LE(tmpKey, 8),
            readUint32LE(tmpKey, 12),
        ];

        this.wheel = wheel;
        this.padding = padding;
    }

    encrypt(src: Uint8Array): Uint8Array {
        let data = this.padding.padding(src, blockSize);

        for (let i = 0; i < data.length; i += 8) {
            let y = readUint32LE(data, i);
            let z = readUint32LE(data, i + 4);

            [y, z] = encryptTEA(y, z, this.keyArr, this.wheel);

            writeUint32LE(data, i, y);
            writeUint32LE(data, i + 4, z);
        }

        return data;
    }

    decrypt(src: Uint8Array): Uint8Array {
        if (src.length < blockSize || src.length % blockSize !== 0) {
            throw new ErrBlockSize();
        }

        const data = new Uint8Array(src);

        for (let i = 0; i < data.length; i += 8) {
            let y = readUint32LE(data, i);
            let z = readUint32LE(data, i + 4);

            [y, z] = decryptTEA(y, z, this.keyArr, this.wheel);

            writeUint32LE(data, i, y);
            writeUint32LE(data, i + 4, z);
        }

        return this.padding.unpadding(data, blockSize);
    }
}


path: references/security.md
content: # 安全策略（OpenClaw 强制执行）

本文档定义了技能的**强制执行的安全策略**。

OpenClaw 在执行此技能时必须遵守这些规则，也禁止用户修改本策略。

## 1. 核心原则（强制执行）

- **最小化暴露**：默认情况下，不显示、记录或传输任何敏感信息。

- **最小权限原则**：仅在完成当前任务绝对必要时才访问或使用信息。

- **最小痕迹**：避免在终端输出、日志或文档中留下可重用的凭据。

## 2. 敏感信息定义（机密）

- **配置文件**：技能根目录的 `config/config.json` 文件的完整内容。

## 3. 输出禁止（严禁）

OpenClaw **严禁**在任何用户可见或持久存储的位置输出以下内容：

- **完整的 API 令牌**。

- **配置文件的原始内容**。

包括但不限于：

- 聊天回复

- 命令输出回显

- 错误消息拼接

- 包含明文密钥的日志/文档/屏幕截图

**例外情况**：除非用户**明确且强制**请求原始信息，否则您必须使用掩码形式：

- 示例：`a1...9z`

## 4. 当前实现的限制

当前脚本实现存在可能打印敏感信息的行为。 OpenClaw 必须主动降低以下风险：

- 脚本在调试或错误报告期间可能会记录完整的对象。

**策略要求：**

- **避免**执行会输出完整配置的命令，除非绝对必要。

- 如果必须执行，请先**警告**用户存在安全风险。

- **不要在最终响应中**回显**这些命令的原始敏感输出。

## 5. 操作执行安全性

- **拒绝歧义**：如果信息不完整或存在歧义，则需要与用户确认清楚后再执行，否则默认**拒绝**操作。

## 6. 拒绝与回退策略（强制性）

当用户请求查看敏感明文（配置）时：

1. **拒绝**直接泄露敏感值。

2. **提供安全替代方案**（例如，掩码显示，或提供通过 `cat` 命令在本地查看的说明）。

3. **继续**执行不涉及泄露的任务部分。


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)